diff --git a/AUTHORS b/AUTHORS index 4ee5bc1..8777d2c 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -483,6 +483,7 @@ Jerry Lin <wahahab11@gmail.com> Jerry Zhang <zhj8407@gmail.com> Jesper Storm Bache <jsbache@gmail.com> +Jesper van den Ende <jespertheend@gmail.com> Jesse Miller <jesse@jmiller.biz> Jesus Sanchez-Palencia <jesus.sanchez-palencia.fernandez.fil@intel.com> Jiadong Chen <chenjiadong@huawei.com>
diff --git a/BUILD.gn b/BUILD.gn index 86878c8..aa2cb7b 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1157,6 +1157,7 @@ "//testing/xvfb.py", "//third_party/blink/tools/", "//third_party/blink/web_tests/VirtualTestSuites", + "//third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json", "//third_party/blink/web_tests/external/wpt/common/", "//third_party/blink/web_tests/external/wpt/resources/", "//third_party/blink/web_tests/resources/", @@ -1211,7 +1212,6 @@ "--seed", "4", "--debug-rwt-logging", - "--no-manifest-update", "--no-show-results", "--zero-tests-executed-ok", "--clobber-old-results", @@ -1221,18 +1221,6 @@ "100", ] - # generate manifest at build time - action("gen_manifest") { - script = "//third_party/blink/tools/gen_manifest.py" - - args = ["--out", "$root_build_dir/gen/"] - - outputs = [ - "$root_build_dir/gen/external/wpt/MANIFEST.json", - "$root_build_dir/gen/wpt_internal/MANIFEST.json" - ] - } - # https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_tests.md script_test("blink_web_tests") { run_under_python2 = true @@ -1240,10 +1228,7 @@ args = _common_web_test_args - data_deps = [ ":blink_web_tests_support_data", - ":gen_manifest" - ] - + data_deps = [ ":blink_web_tests_support_data" ] data = [ "//third_party/blink/perf_tests/", "//third_party/blink/web_tests/",
diff --git a/DEPS b/DEPS index 1932951..1e38bff 100644 --- a/DEPS +++ b/DEPS
@@ -222,11 +222,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'd0329b91bc1042c7d0372b68198ac03998c4a363', + 'skia_revision': 'f5bd4e4b9f6bd1b508dd5eb67129bfca528ef39b', # 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': '21fd10e120f8b593560b9766654aecf58738042a', + 'v8_revision': 'e1c59dfd37b6196f5b1156eb8b3808c471aa62e1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -234,15 +234,15 @@ # 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': '396518e015f33d23a1b816fad01689434518508b', + 'angle_revision': '17a4b6e7f6bd329953a46f9b2050670b0f27bfd0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '43d3e0cc9c06c650a225f1a6730f5e453b46ac1b', + 'swiftshader_revision': '65498c15ca60362b11673a023d326d60db1f6e9b', # 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': 'bd82b53735cdb83f6902494352847b9f13eac60e', + 'pdfium_revision': '8496d13f2daade3d96291c19a0fcfc408fcd128d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -269,7 +269,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'e7a4322ff001c20ddd1e107380961153b9c1763b', + 'nacl_revision': 'b695f311a8a7ede3b22f4f6b39d87fdab699d291', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -293,7 +293,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '2fff900ff7a59f0b8ce073534353d88f2b646f62', + 'catapult_revision': '71adf4f1715bfa1eba836afd1cdedd72ac73637d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -301,7 +301,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '07e1d04bf77968ab76727e525f132cf475160e5b', + 'devtools_frontend_revision': 'cbc2f8eb8ee6643651e5d045c711c7b9f38d4788', # 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. @@ -341,7 +341,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': '2f51bfc74a0aa441f29e3112b19804126997957e', + 'dawn_revision': '48de25e52a33098b8765ce3354d8cc50e86ad65a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -408,7 +408,7 @@ 'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7', # GN CIPD package version. - 'gn_version': 'git_revision:31f2bba8aafa8015ca5761100a21f17c2d741062', + 'gn_version': 'git_revision:24e2f7df92641de0351a96096fb2c490b2436bb8', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -738,7 +738,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '29574JKqBbhq5FiO3D4ydclUDICPzLTJGfyNc4k4ldYC', + 'version': '7rK3FRn0Lb5wAO4thkxAj_sMaGdwXTOhMCY4YUPpWrIC', }, ], 'condition': 'checkout_android', @@ -1117,7 +1117,7 @@ Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '18e09b9197a3b1d771c077c530d1a4ebad04c167', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'a0718d4f121727e30b8d52c7a189ebf5ab52421f', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'b9dfc58bf9b02ea0365509244aca13841322feb0', 'src/third_party/icu4j': { 'packages': [ @@ -1360,7 +1360,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '566975367c6371c305734403c653ed81bbd53519', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'cc178a3f172732fa9b107cda5281c98c1ac9fead', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1449,7 +1449,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'czR22wy3jcAfrw7l4ljto3qX6BpD2DSahnluWvqUockC' + 'version': 'QunhZeUueNJF63FP9uXIb-TVJNazpdKD5TQAi_D7ZLEC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1474,7 +1474,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'gXyBDv_fM87KnLcxvF5AGV5lwnm-JXIALYH8zrzdoaMC', + 'version': 'Nu_mvQJe34CotIXadFlA3w732CJ9EvQGuVs4udcZedAC', }, ], 'condition': 'checkout_android', @@ -1553,7 +1553,7 @@ 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '965b19a8636bbcd9617c1658cfe874a10cedb15d', - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@cda66075b3f4a9480101fc8264e209e904c0efad', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@388827e09d3753d16922479ec813f3ddb8d2fa52', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'f67d7fa397e83060b76a1ec53579116a0bbdff7a', @@ -1589,10 +1589,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '827cad9e402b63bbe38787456115bcb681a8a152', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '782277b9c5d41ecbdcba2941887cbcb9c365da10', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e2aeec9de7a742ae131b2f56fc22de6b17b8d0e1', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '5d70fe763d0882ae15c20ce2f01a5471dd55d3ec', + Var('webrtc_git') + '/src.git' + '@' + '2bbbd6686e44a87579d2df0020e907d2c4fd5090', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1653,7 +1653,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@94dba81f61f82f97fac7704febdba96f2027eaac', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a3e374223fdcc69220004307c21f17bd55e27fed', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc index 768f9375..de3b0de 100644 --- a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc +++ b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
@@ -208,6 +208,9 @@ SafeBrowsingAction action, bool reporting) { content::WebContents* web_contents = resource.web_contents_getter.Run(); + // |web_contents_getter| can return null after RenderFrameHost is destroyed. + if (!web_contents) + return; if (!reporting) { AwBrowserContext* browser_context =
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 23bc775..2ae28bf5 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1842,6 +1842,7 @@ "//ash/login/resources:resources_grit", "//ash/public/cpp/ambient/proto", "//ash/quick_pair", + "//ash/quick_pair/keyed_service", "//ash/services/recording", "//ash/services/recording/public/mojom", "//ash/system/machine_learning:user_settings_event_proto", @@ -1877,6 +1878,7 @@ "//chromeos/dbus/shill", "//chromeos/dbus/system_clock", "//chromeos/login/login_state", + "//chromeos/metrics", "//chromeos/network", "//chromeos/services/assistant/public/cpp", "//chromeos/services/assistant/public/mojom",
diff --git a/ash/app_list/model/app_list_item_list.cc b/ash/app_list/model/app_list_item_list.cc index 057a9c5..0617125 100644 --- a/ash/app_list/model/app_list_item_list.cc +++ b/ash/app_list/model/app_list_item_list.cc
@@ -48,10 +48,17 @@ void AppListItemList::MoveItem(size_t from_index, size_t to_index) { DCHECK_LT(from_index, item_count()); - // Speculative fix for crash, possibly due to single-item folders. - // https://crbug.com/937431 + // Speculative fix for crash, possibly due to single-item folders + // (see https://crbug.com/937431). + // A folder could have single item due to the following reasons: + // (1) The folder is allowed to contain only one item. Or + // (2) The app list sync is in progress. For example, when the app list is + // syncing two apps under the same folder, one app could be added to the + // folder before the other by a noticeable time interval. As a result, the + // folder contains one item temporarily. if (item_count() <= 1) return; + // Speculative fix for crash, possibly due |to_index| == item_count(). // Make |to_index| point to the last item. https://crbug.com/1166011 if (to_index >= item_count()) {
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 13547c6..c50769b 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2167,10 +2167,10 @@ No mobile networks set up </message> <message name="IDS_ASH_STATUS_TRAY_NO_MOBILE_DEVICES_FOUND" desc="The message to display in the network list when no mobile devices which can provide a tether hotspot have been discovered nearby."> - No mobile devices found. + No mobile devices found </message> <message name="IDS_ASH_STATUS_TRAY_ENABLING_MOBILE_ENABLES_BLUETOOTH" desc="The message to display in the mobile section of the network list when Bluetooth is off. If Bluetooth is off and mobile data is turned on, Bluetooth will also be turned on for the user to support this feature."> - Enabling mobile data will enable Bluetooth. + Enabling mobile data will enable Bluetooth </message> <message name="IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_DISABLED" desc="The message to display in the network list when mobile data is turned off."> Mobile data is turned off
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_ENABLING_MOBILE_ENABLES_BLUETOOTH.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_ENABLING_MOBILE_ENABLES_BLUETOOTH.png.sha1 new file mode 100644 index 0000000..52d34bd --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_ENABLING_MOBILE_ENABLES_BLUETOOTH.png.sha1
@@ -0,0 +1 @@ +dd6bd22b5b85d1226a3e3451aac7312e6f3315ad \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_NO_MOBILE_DEVICES_FOUND.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_NO_MOBILE_DEVICES_FOUND.png.sha1 new file mode 100644 index 0000000..299aaefa --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_NO_MOBILE_DEVICES_FOUND.png.sha1
@@ -0,0 +1 @@ +fef52e50d37eda910d26f55da26b4fe1b5447a99 \ No newline at end of file
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 85efe291..b06e378 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -121,6 +121,11 @@ const base::Feature kAssistMultiWord{"AssistMultiWord", base::FEATURE_DISABLED_BY_DEFAULT}; +// Controls whether to enable assistive multi word suggestions on an expanded +// list of surfaces. +const base::Feature kAssistMultiWordExpanded{"AssistMultiWordExpanded", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Controls whether to enable assistive personal information. const base::Feature kAssistPersonalInfo{"AssistPersonalInfo", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index c728e80..a2a442f 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -61,6 +61,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAssistAutoCorrect; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAssistEmojiEnhanced; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAssistMultiWord; +COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kAssistMultiWordExpanded; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAssistPersonalInfo; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAssistPersonalInfoAddress;
diff --git a/ash/metrics/DEPS b/ash/metrics/DEPS index d769769..5e26955 100644 --- a/ash/metrics/DEPS +++ b/ash/metrics/DEPS
@@ -1,3 +1,4 @@ include_rules = [ "+chromeos/login/login_state", + "+chromeos/metrics", ]
diff --git a/ash/metrics/login_unlock_throughput_recorder.h b/ash/metrics/login_unlock_throughput_recorder.h index 55b1d92..aeba869d 100644 --- a/ash/metrics/login_unlock_throughput_recorder.h +++ b/ash/metrics/login_unlock_throughput_recorder.h
@@ -5,13 +5,15 @@ #ifndef ASH_METRICS_LOGIN_UNLOCK_THROUGHPUT_RECORDER_H_ #define ASH_METRICS_LOGIN_UNLOCK_THROUGHPUT_RECORDER_H_ +#include "ash/ash_export.h" #include "ash/public/cpp/session/session_observer.h" #include "chromeos/login/login_state/login_state.h" namespace ash { -class LoginUnlockThroughputRecorder : public SessionObserver, - public chromeos::LoginState::Observer { +class ASH_EXPORT LoginUnlockThroughputRecorder + : public SessionObserver, + public chromeos::LoginState::Observer { public: LoginUnlockThroughputRecorder(); LoginUnlockThroughputRecorder(const LoginUnlockThroughputRecorder&) = delete;
diff --git a/ash/public/cpp/desks_helper.h b/ash/public/cpp/desks_helper.h index ad209d6..6c201b4 100644 --- a/ash/public/cpp/desks_helper.h +++ b/ash/public/cpp/desks_helper.h
@@ -46,10 +46,11 @@ // necessary information that can be used to create a same desk. virtual std::unique_ptr<DeskTemplate> CaptureActiveDeskAsTemplate() const = 0; - // Creates and activates a new desk for a template with name `desk_name`. Runs - // `callback` with true if creation was successful, false otherwise. + // Creates and activates a new desk for a template with name `template_name` + // or `template_name ({counter})` to resolve naming conflicts. Runs `callback` + // with true if creation was successful, false otherwise. virtual void CreateAndActivateNewDeskForTemplate( - const std::u16string& desk_name, + const std::u16string& template_name, base::OnceCallback<void(bool)> callback) = 0; protected:
diff --git a/ash/quick_pair/common/device.cc b/ash/quick_pair/common/device.cc index 90fa4e6..8e84c954 100644 --- a/ash/quick_pair/common/device.cc +++ b/ash/quick_pair/common/device.cc
@@ -16,7 +16,7 @@ address(std::move(address)), protocol(protocol) {} -std::ostream& operator<<(std::ostream& stream, Device device) { +std::ostream& operator<<(std::ostream& stream, const Device& device) { stream << "[Device: metadata_id=" << device.metadata_id << ", address=" << device.address << ", protocol=" << device.protocol << "]";
diff --git a/ash/quick_pair/common/device.h b/ash/quick_pair/common/device.h index 1174054..ea6ca83 100644 --- a/ash/quick_pair/common/device.h +++ b/ash/quick_pair/common/device.h
@@ -6,6 +6,7 @@ #define ASH_QUICK_PAIR_COMMON_DEVICE_H_ #include "ash/quick_pair/common/protocol.h" +#include "base/component_export.h" namespace ash { namespace quick_pair { @@ -15,7 +16,8 @@ // // Lower level components will use |protocol|, |metadata_id| and |address| to // fetch objects which contain more information. E.g. A Fast Pair component -// can use |metadata_id| to query the Service to receive a full metadata object. +// can use |metadata_id| to query the Service to receive a full metadata +// object. struct Device { Device(std::string metadata_id, std::string address, Protocol protocol); Device(const Device&) = delete; @@ -37,7 +39,8 @@ const Protocol protocol; }; -std::ostream& operator<<(std::ostream& stream, Device device); +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +std::ostream& operator<<(std::ostream& stream, const Device& device); } // namespace quick_pair } // namespace ash
diff --git a/ash/quick_pair/common/protocol.h b/ash/quick_pair/common/protocol.h index 3181e04..30b78da 100644 --- a/ash/quick_pair/common/protocol.h +++ b/ash/quick_pair/common/protocol.h
@@ -6,6 +6,7 @@ #define ASH_QUICK_PAIR_COMMON_PROTOCOL_H_ #include <ostream> +#include "base/component_export.h" namespace ash { namespace quick_pair { @@ -15,6 +16,7 @@ kFastPair = 0 }; +COMPONENT_EXPORT(QUICK_PAIR_COMMON) std::ostream& operator<<(std::ostream& stream, Protocol protocol); } // namespace quick_pair
diff --git a/ash/quick_pair/keyed_service/BUILD.gn b/ash/quick_pair/keyed_service/BUILD.gn index df70f4a..df4db0c 100644 --- a/ash/quick_pair/keyed_service/BUILD.gn +++ b/ash/quick_pair/keyed_service/BUILD.gn
@@ -18,6 +18,7 @@ deps = [ "//ash/quick_pair/common", "//ash/quick_pair/feature_status_tracker", + "//ash/quick_pair/scanning", "//base", "//components/keyed_service/core", ] @@ -31,6 +32,7 @@ deps = [ ":keyed_service", "//ash/quick_pair/feature_status_tracker:test_support", + "//ash/quick_pair/scanning:test_support", "//base/test:test_support", "//testing/gtest", ]
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator.cc b/ash/quick_pair/keyed_service/quick_pair_mediator.cc index 2faf79f9..782ed20 100644 --- a/ash/quick_pair/keyed_service/quick_pair_mediator.cc +++ b/ash/quick_pair/keyed_service/quick_pair_mediator.cc
@@ -6,15 +6,42 @@ #include <memory> +#include "ash/quick_pair/common/device.h" #include "ash/quick_pair/common/logging.h" #include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker.h" +#include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker_impl.h" +#include "ash/quick_pair/scanning/scanner_broker_impl.h" namespace ash { namespace quick_pair { -Mediator::Mediator(std::unique_ptr<FeatureStatusTracker> feature_status_tracker) - : feature_status_tracker_(std::move(feature_status_tracker)) { - observation_.Observe(feature_status_tracker_.get()); +namespace { + +Mediator::Factory* g_test_factory = nullptr; + +} + +// static +std::unique_ptr<Mediator> Mediator::Factory::Create() { + if (g_test_factory) + return g_test_factory->BuildInstance(); + + return std::make_unique<Mediator>( + std::make_unique<FeatureStatusTrackerImpl>(), + std::make_unique<ScannerBrokerImpl>()); +} + +// static +void Mediator::Factory::SetFactoryForTesting(Factory* factory) { + g_test_factory = factory; +} + +Mediator::Mediator(std::unique_ptr<FeatureStatusTracker> feature_status_tracker, + std::unique_ptr<ScannerBroker> scanner_broker) + : feature_status_tracker_(std::move(feature_status_tracker)), + scanner_broker_(std::move(scanner_broker)) { + feature_status_tracker_observation_.Observe(feature_status_tracker_.get()); + scanner_broker_observation_.Observe(scanner_broker_.get()); SetFastPairState(feature_status_tracker_->IsFastPairEnabled()); } @@ -25,8 +52,21 @@ SetFastPairState(is_enabled); } +void Mediator::OnDeviceFound(const Device& device) { + QP_LOG(INFO) << __func__ << ": " << device; +} + +void Mediator::OnDeviceLost(const Device& device) { + QP_LOG(INFO) << __func__ << ": " << device; +} + void Mediator::SetFastPairState(bool is_enabled) { - QP_LOG(INFO) << "Setting Fast Pair state, is_enabled: " << is_enabled; + QP_LOG(INFO) << __func__ << ": " << is_enabled; + + if (is_enabled) + scanner_broker_->StartScanning(Protocol::kFastPair); + else + scanner_broker_->StopScanning(Protocol::kFastPair); } } // namespace quick_pair
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator.h b/ash/quick_pair/keyed_service/quick_pair_mediator.h index b9ce003..20bb08e 100644 --- a/ash/quick_pair/keyed_service/quick_pair_mediator.h +++ b/ash/quick_pair/keyed_service/quick_pair_mediator.h
@@ -7,7 +7,9 @@ #include <memory> +#include "ash/quick_pair/common/device.h" #include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker.h" +#include "ash/quick_pair/scanning/scanner_broker.h" #include "base/scoped_observation.h" namespace ash { @@ -15,10 +17,21 @@ // Implements the Mediator design pattern for the components in the Quick Pair // system, e.g. the UI Broker, Scanning Broker and Pairing Broker. -class Mediator : public FeatureStatusTracker::Observer { +class Mediator : public FeatureStatusTracker::Observer, + public ScannerBroker::Observer { public: - explicit Mediator( - std::unique_ptr<FeatureStatusTracker> feature_status_tracker); + class Factory { + public: + static std::unique_ptr<Mediator> Create(); + static void SetFactoryForTesting(Factory* factory); + virtual ~Factory() = default; + + private: + virtual std::unique_ptr<Mediator> BuildInstance() = 0; + }; + + Mediator(std::unique_ptr<FeatureStatusTracker> feature_status_tracker, + std::unique_ptr<ScannerBroker> scanner_broker); Mediator(const Mediator&) = delete; Mediator& operator=(const Mediator&) = delete; ~Mediator() final; @@ -26,12 +39,20 @@ // QuickPairFeatureStatusTracker::Observer void OnFastPairEnabledChanged(bool is_enabled) override; + // SannerBroker::Observer + void OnDeviceFound(const Device& device) override; + void OnDeviceLost(const Device& device) override; + private: void SetFastPairState(bool is_enabled); std::unique_ptr<FeatureStatusTracker> feature_status_tracker_; + std::unique_ptr<ScannerBroker> scanner_broker_; + base::ScopedObservation<FeatureStatusTracker, FeatureStatusTracker::Observer> - observation_{this}; + feature_status_tracker_observation_{this}; + base::ScopedObservation<ScannerBroker, ScannerBroker::Observer> + scanner_broker_observation_{this}; }; } // namespace quick_pair
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator_unittest.cc b/ash/quick_pair/keyed_service/quick_pair_mediator_unittest.cc index 047e695f..9736d37 100644 --- a/ash/quick_pair/keyed_service/quick_pair_mediator_unittest.cc +++ b/ash/quick_pair/keyed_service/quick_pair_mediator_unittest.cc
@@ -6,8 +6,11 @@ #include <memory> +#include "ash/quick_pair/feature_status_tracker/fake_feature_status_tracker.h" #include "ash/quick_pair/feature_status_tracker/mock_quick_pair_feature_status_tracker.h" #include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker.h" +#include "ash/quick_pair/scanning/mock_scanner_broker.h" +#include "ash/quick_pair/scanning/scanner_broker.h" #include "testing/gtest/include/gtest/gtest.h" namespace ash { @@ -17,28 +20,40 @@ public: void SetUp() override { std::unique_ptr<FeatureStatusTracker> tracker = - std::make_unique<MockFeatureStatusTracker>(); + std::make_unique<FakeFeatureStatusTracker>(); feature_status_tracker_ = - static_cast<MockFeatureStatusTracker*>(tracker.get()); + static_cast<FakeFeatureStatusTracker*>(tracker.get()); - EXPECT_CALL(*feature_status_tracker_, AddObserver); - EXPECT_CALL(*feature_status_tracker_, IsFastPairEnabled); + std::unique_ptr<ScannerBroker> scanner_broker = + std::make_unique<MockScannerBroker>(); + mock_scanner_broker_ = + static_cast<MockScannerBroker*>(scanner_broker.get()); - mediator_ = std::make_unique<Mediator>(std::move(tracker)); + EXPECT_CALL(*mock_scanner_broker_, AddObserver); + + mediator_ = std::make_unique<Mediator>(std::move(tracker), + std::move(scanner_broker)); } void TearDown() override { - EXPECT_CALL(*feature_status_tracker_, RemoveObserver(mediator_.get())); + EXPECT_CALL(*mock_scanner_broker_, RemoveObserver(mediator_.get())); } protected: - MockFeatureStatusTracker* feature_status_tracker_; + FakeFeatureStatusTracker* feature_status_tracker_; + MockScannerBroker* mock_scanner_broker_; std::unique_ptr<Mediator> mediator_; }; -TEST_F(MediatorTest, SetupAndTeardownMakesExpectedCalls) { - // Blank test to explicitly test SetUp and TearDown. Can be removed once - // more tests are added which will test the same logic. +TEST_F(MediatorTest, TogglesScanningWhenFastPairEnabledChanges) { + EXPECT_CALL(*mock_scanner_broker_, StartScanning); + feature_status_tracker_->SetIsFastPairEnabled(true); + EXPECT_CALL(*mock_scanner_broker_, StopScanning); + feature_status_tracker_->SetIsFastPairEnabled(false); + EXPECT_CALL(*mock_scanner_broker_, StartScanning); + feature_status_tracker_->SetIsFastPairEnabled(true); + EXPECT_CALL(*mock_scanner_broker_, StopScanning); + feature_status_tracker_->SetIsFastPairEnabled(false); } } // namespace quick_pair
diff --git a/ash/quick_pair/scanning/BUILD.gn b/ash/quick_pair/scanning/BUILD.gn index c9dc424..0b7f2a61 100644 --- a/ash/quick_pair/scanning/BUILD.gn +++ b/ash/quick_pair/scanning/BUILD.gn
@@ -24,6 +24,23 @@ ] } +static_library("test_support") { + testonly = true + + sources = [ + "mock_scanner_broker.cc", + "mock_scanner_broker.h", + "scanner_broker.h", + ] + + deps = [ + "//ash/quick_pair/common", + "//base", + "//base/test:test_support", + "//testing/gtest", + ] +} + source_set("unit_tests") { testonly = true
diff --git a/ash/quick_pair/scanning/mock_scanner_broker.cc b/ash/quick_pair/scanning/mock_scanner_broker.cc new file mode 100644 index 0000000..461a668 --- /dev/null +++ b/ash/quick_pair/scanning/mock_scanner_broker.cc
@@ -0,0 +1,15 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/quick_pair/scanning/mock_scanner_broker.h" + +namespace ash { +namespace quick_pair { + +MockScannerBroker::MockScannerBroker() = default; + +MockScannerBroker::~MockScannerBroker() = default; + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/scanning/mock_scanner_broker.h b/ash/quick_pair/scanning/mock_scanner_broker.h new file mode 100644 index 0000000..39c0592 --- /dev/null +++ b/ash/quick_pair/scanning/mock_scanner_broker.h
@@ -0,0 +1,31 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_QUICK_PAIR_SCANNING_MOCK_SCANNER_BROKER_H_ +#define ASH_QUICK_PAIR_SCANNING_MOCK_SCANNER_BROKER_H_ + +#include "ash/quick_pair/common/protocol.h" +#include "ash/quick_pair/scanning/scanner_broker.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace ash { +namespace quick_pair { + +class MockScannerBroker : public ScannerBroker { + public: + MockScannerBroker(); + MockScannerBroker(const MockScannerBroker&) = delete; + MockScannerBroker& operator=(const MockScannerBroker&) = delete; + ~MockScannerBroker() override; + + MOCK_METHOD(void, AddObserver, (Observer*), (override)); + MOCK_METHOD(void, RemoveObserver, (Observer*), (override)); + MOCK_METHOD(void, StartScanning, (Protocol), (override)); + MOCK_METHOD(void, StopScanning, (Protocol), (override)); +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_SCANNING_MOCK_SCANNER_BROKER_H_
diff --git a/ash/quick_pair/scanning/scanner_broker.h b/ash/quick_pair/scanning/scanner_broker.h index 58cc30c..02d19f7 100644 --- a/ash/quick_pair/scanning/scanner_broker.h +++ b/ash/quick_pair/scanning/scanner_broker.h
@@ -6,7 +6,6 @@ #define ASH_QUICK_PAIR_SCANNING_SCANNER_BROKER_H_ #include "ash/quick_pair/common/device.h" -#include "ash/quick_pair/common/logging.h" #include "ash/quick_pair/common/protocol.h" #include "base/observer_list_types.h" @@ -21,10 +20,12 @@ public: class Observer : public base::CheckedObserver { public: - virtual void OnDeviceFound(const Device& device); - virtual void OnDeviceLost(const Device& device); + virtual void OnDeviceFound(const Device& device) = 0; + virtual void OnDeviceLost(const Device& device) = 0; }; + virtual ~ScannerBroker() = default; + virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; virtual void StartScanning(Protocol protocol) = 0;
diff --git a/ash/quick_pair/scanning/scanner_broker_impl.h b/ash/quick_pair/scanning/scanner_broker_impl.h index 72426b5..568c92a 100644 --- a/ash/quick_pair/scanning/scanner_broker_impl.h +++ b/ash/quick_pair/scanning/scanner_broker_impl.h
@@ -17,7 +17,7 @@ ScannerBrokerImpl(); ScannerBrokerImpl(const ScannerBrokerImpl&) = delete; ScannerBrokerImpl& operator=(const ScannerBrokerImpl&) = delete; - ~ScannerBrokerImpl(); + ~ScannerBrokerImpl() override; // ScannerBroker: void AddObserver(Observer* observer) override;
diff --git a/ash/quick_pair/ui/BUILD.gn b/ash/quick_pair/ui/BUILD.gn index d9b5b0f..e1ef15e 100644 --- a/ash/quick_pair/ui/BUILD.gn +++ b/ash/quick_pair/ui/BUILD.gn
@@ -13,10 +13,17 @@ defines = [ "IS_QUICK_PAIR_UI_IMPL" ] sources = [ + "actions.cc", + "actions.h", "fast_pair/fast_pair_image_decoder.cc", "fast_pair/fast_pair_image_decoder.h", "fast_pair/fast_pair_notification_controller.cc", "fast_pair/fast_pair_notification_controller.h", + "fast_pair/fast_pair_presenter.cc", + "fast_pair/fast_pair_presenter.h", + "ui_broker.h", + "ui_broker_impl.cc", + "ui_broker_impl.h", ] deps = [
diff --git a/ash/quick_pair/ui/actions.cc b/ash/quick_pair/ui/actions.cc new file mode 100644 index 0000000..3a6a12e --- /dev/null +++ b/ash/quick_pair/ui/actions.cc
@@ -0,0 +1,78 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/quick_pair/ui/actions.h" + +namespace ash { +namespace quick_pair { + +std::ostream& operator<<(std::ostream& stream, DiscoveryAction action) { + switch (action) { + case DiscoveryAction::kPairToDevice: + stream << "[Pair to device]"; + break; + case DiscoveryAction::kDismissedByUser: + stream << "[Dismissed by user]"; + break; + case DiscoveryAction::kDismissed: + stream << "[Dismissed]"; + break; + } + + return stream; +} + +std::ostream& operator<<(std::ostream& stream, AssociateAccountAction action) { + switch (action) { + case AssociateAccountAction::kAssoicateAccount: + stream << "[Associate account]"; + break; + case AssociateAccountAction::kDismissedByUser: + stream << "[Dismissed by user]"; + break; + case AssociateAccountAction::kDismissed: + stream << "[Dismissed]"; + break; + } + + return stream; +} + +std::ostream& operator<<(std::ostream& stream, CompanionAppAction action) { + switch (action) { + case CompanionAppAction::kDownloadAndLaunchApp: + stream << "[Download and launch app]"; + break; + case CompanionAppAction::kLaunchApp: + stream << "[Launch app]"; + break; + case CompanionAppAction::kDismissedByUser: + stream << "[Dismissed by user]"; + break; + case CompanionAppAction::kDismissed: + stream << "[Dismissed]"; + break; + } + + return stream; +} + +std::ostream& operator<<(std::ostream& stream, PairingFailedAction action) { + switch (action) { + case PairingFailedAction::kNavigateToSettings: + stream << "[Navigate to settings]"; + break; + case PairingFailedAction::kDismissedByUser: + stream << "[Dismissed by user]"; + break; + case PairingFailedAction::kDismissed: + stream << "[Dismissed]"; + break; + } + + return stream; +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/ui/actions.h b/ash/quick_pair/ui/actions.h new file mode 100644 index 0000000..7a72a10 --- /dev/null +++ b/ash/quick_pair/ui/actions.h
@@ -0,0 +1,46 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_QUICK_PAIR_UI_ACTIONS_H_ +#define ASH_QUICK_PAIR_UI_ACTIONS_H_ + +#include <ostream> + +namespace ash { +namespace quick_pair { + +enum class DiscoveryAction { + kPairToDevice = 0, + kDismissedByUser = 1, + kDismissed = 2 +}; + +enum class AssociateAccountAction { + kAssoicateAccount = 0, + kDismissedByUser = 1, + kDismissed = 2 +}; + +enum class CompanionAppAction { + kDownloadAndLaunchApp = 0, + kLaunchApp = 1, + kDismissedByUser = 2, + kDismissed = 3 +}; + +enum class PairingFailedAction { + kNavigateToSettings = 0, + kDismissedByUser = 1, + kDismissed = 2 +}; + +std::ostream& operator<<(std::ostream& stream, DiscoveryAction protocol); +std::ostream& operator<<(std::ostream& stream, AssociateAccountAction protocol); +std::ostream& operator<<(std::ostream& stream, CompanionAppAction protocol); +std::ostream& operator<<(std::ostream& stream, PairingFailedAction protocol); + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_UI_ACTIONS_H_
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h b/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h index b609c2d8..13fb74b7 100644 --- a/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h +++ b/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h
@@ -23,7 +23,6 @@ FastPairNotificationController& operator=( const FastPairNotificationController&) = delete; - private: // Creates and displays corresponding system notification. void ShowErrorNotification(const std::u16string& device_name, gfx::Image device_image,
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_presenter.cc b/ash/quick_pair/ui/fast_pair/fast_pair_presenter.cc new file mode 100644 index 0000000..caaf015a --- /dev/null +++ b/ash/quick_pair/ui/fast_pair/fast_pair_presenter.cc
@@ -0,0 +1,76 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/quick_pair/ui/fast_pair/fast_pair_presenter.h" + +#include <string> + +#include "ash/quick_pair/ui/actions.h" +#include "base/bind.h" +#include "base/callback.h" +#include "base/callback_helpers.h" +#include "base/strings/utf_string_conversions.h" + +namespace ash { +namespace quick_pair { + +FastPairPresenter::FastPairPresenter() = default; + +FastPairPresenter::~FastPairPresenter() = default; + +void FastPairPresenter::ShowDiscovery(const Device& device, + DiscoveryCallback callback) { + notification_controller_->ShowDiscoveryNotification( + base::ASCIIToUTF16(device.metadata_id), gfx::Image(), + base::BindOnce(&FastPairPresenter::OnDiscoveryClicked, + weak_pointer_factory_.GetWeakPtr(), std::move(callback)), + base::BindOnce(&FastPairPresenter::OnDiscoveryDismissed, + weak_pointer_factory_.GetWeakPtr(), std::move(callback))); +} + +void FastPairPresenter::OnDiscoveryClicked(DiscoveryCallback callback) { + std::move(callback).Run(DiscoveryAction::kPairToDevice); +} + +void FastPairPresenter::OnDiscoveryDismissed(DiscoveryCallback callback, + bool user_dismissed) { + std::move(callback).Run(user_dismissed ? DiscoveryAction::kDismissedByUser + : DiscoveryAction::kDismissed); +} + +void FastPairPresenter::ShowPairing(const Device& device) { + notification_controller_->ShowPairingNotification( + base::ASCIIToUTF16(device.metadata_id), gfx::Image(), base::DoNothing(), + base::DoNothing()); +} + +void FastPairPresenter::ShowPairingFailed(const Device& device, + PairingFailedCallback callback) { + notification_controller_->ShowErrorNotification( + base::ASCIIToUTF16(device.metadata_id), gfx::Image(), + base::BindOnce(&FastPairPresenter::OnNavigateToSettings, + weak_pointer_factory_.GetWeakPtr(), std::move(callback)), + base::BindOnce(&FastPairPresenter::OnPairingFailedDismissed, + weak_pointer_factory_.GetWeakPtr(), std::move(callback))); +} + +void FastPairPresenter::OnNavigateToSettings(PairingFailedCallback callback) { + std::move(callback).Run(PairingFailedAction::kNavigateToSettings); +} + +void FastPairPresenter::OnPairingFailedDismissed(PairingFailedCallback callback, + bool user_dimissed) { + std::move(callback).Run(user_dimissed ? PairingFailedAction::kDismissedByUser + : PairingFailedAction::kDismissed); +} + +void FastPairPresenter::ShowAssociateAccount( + const Device& device, + AssociateAccountCallback callback) {} + +void FastPairPresenter::ShowCompanionApp(const Device& device, + CompanionAppCallback callback) {} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_presenter.h b/ash/quick_pair/ui/fast_pair/fast_pair_presenter.h new file mode 100644 index 0000000..13fe722 --- /dev/null +++ b/ash/quick_pair/ui/fast_pair/fast_pair_presenter.h
@@ -0,0 +1,53 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_QUICK_PAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_ +#define ASH_QUICK_PAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_ + +#include <memory> +#include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/ui/actions.h" +#include "ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h" +#include "base/callback.h" +#include "base/memory/weak_ptr.h" + +namespace ash { +namespace quick_pair { + +using DiscoveryCallback = base::OnceCallback<void(DiscoveryAction)>; +using PairingFailedCallback = base::OnceCallback<void(PairingFailedAction)>; +using AssociateAccountCallback = + base::OnceCallback<void(AssociateAccountAction)>; +using CompanionAppCallback = base::OnceCallback<void(CompanionAppAction)>; + +class FastPairPresenter { + public: + FastPairPresenter(); + FastPairPresenter(const FastPairPresenter&) = delete; + FastPairPresenter& operator=(const FastPairPresenter&) = delete; + ~FastPairPresenter(); + + void ShowDiscovery(const Device& device, DiscoveryCallback callback); + void ShowPairing(const Device& device); + void ShowPairingFailed(const Device& device, PairingFailedCallback callback); + void ShowAssociateAccount(const Device& device, + AssociateAccountCallback callback); + void ShowCompanionApp(const Device& device, CompanionAppCallback callback); + + private: + void OnDiscoveryClicked(DiscoveryCallback action_callback); + void OnDiscoveryDismissed(DiscoveryCallback callback, bool user_dismissed); + + void OnNavigateToSettings(PairingFailedCallback callback); + void OnPairingFailedDismissed(PairingFailedCallback callback, + bool user_dismissed); + + std::unique_ptr<FastPairNotificationController> notification_controller_; + base::WeakPtrFactory<FastPairPresenter> weak_pointer_factory_{this}; +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_
diff --git a/ash/quick_pair/ui/ui_broker.h b/ash/quick_pair/ui/ui_broker.h new file mode 100644 index 0000000..451661ac --- /dev/null +++ b/ash/quick_pair/ui/ui_broker.h
@@ -0,0 +1,44 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_QUICK_PAIR_UI_UI_BROKER_H_ +#define ASH_QUICK_PAIR_UI_UI_BROKER_H_ + +#include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/ui/actions.h" +#include "base/observer_list_types.h" + +namespace ash { +namespace quick_pair { + +// The UIBroker is the entry point for the UI component in the Quick Pair +// system. It is responsible for brokering the 'show UI' calls to the correct +// Presenter implementation, and exposing user actions taken on that UI. +class UIBroker { + public: + class Observer : public base::CheckedObserver { + public: + virtual void OnDiscoveryAction(const Device& device, + DiscoveryAction action) = 0; + virtual void OnCompanionAppAction(const Device& device, + CompanionAppAction action) = 0; + virtual void OnPairingFailureAction(const Device& device, + PairingFailedAction action) = 0; + virtual void OnAssociateAccountAction(const Device& device, + AssociateAccountAction action) = 0; + }; + + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + virtual void ShowDiscovery(const Device& device) = 0; + virtual void ShowPairing(const Device& device) = 0; + virtual void ShowPairingFailed(const Device& device) = 0; + virtual void ShowAssociateAccount(const Device& device) = 0; + virtual void ShowCompanionApp(const Device& device) = 0; +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_UI_UI_BROKER_H_
diff --git a/ash/quick_pair/ui/ui_broker_impl.cc b/ash/quick_pair/ui/ui_broker_impl.cc new file mode 100644 index 0000000..0d9276a2 --- /dev/null +++ b/ash/quick_pair/ui/ui_broker_impl.cc
@@ -0,0 +1,108 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/quick_pair/ui/ui_broker_impl.h" + +#include <memory> + +#include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/common/protocol.h" +#include "ash/quick_pair/ui/actions.h" +#include "ash/quick_pair/ui/fast_pair/fast_pair_presenter.h" +#include "base/bind.h" + +namespace ash { +namespace quick_pair { + +UIBrokerImpl::UIBrokerImpl() + : fast_pair_presenter_(std::make_unique<FastPairPresenter>()) {} + +UIBrokerImpl::~UIBrokerImpl() = default; + +void UIBrokerImpl::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void UIBrokerImpl::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void UIBrokerImpl::ShowDiscovery(const Device& device) { + switch (device.protocol) { + case Protocol::kFastPair: + fast_pair_presenter_->ShowDiscovery( + device, + base::BindOnce(&UIBrokerImpl::NotifyDiscoveryAction, + weak_pointer_factory_.GetWeakPtr(), std::ref(device))); + break; + } +} + +void UIBrokerImpl::ShowPairing(const Device& device) { + switch (device.protocol) { + case Protocol::kFastPair: + fast_pair_presenter_->ShowPairing(device); + break; + } +} + +void UIBrokerImpl::ShowPairingFailed(const Device& device) { + switch (device.protocol) { + case Protocol::kFastPair: + fast_pair_presenter_->ShowPairingFailed( + device, + base::BindOnce(&UIBrokerImpl::NotifyPairingFailedAction, + weak_pointer_factory_.GetWeakPtr(), std::ref(device))); + break; + } +} + +void UIBrokerImpl::ShowAssociateAccount(const Device& device) { + switch (device.protocol) { + case Protocol::kFastPair: + fast_pair_presenter_->ShowAssociateAccount( + device, + base::BindOnce(&UIBrokerImpl::NotifyAssociateAccountAction, + weak_pointer_factory_.GetWeakPtr(), std::ref(device))); + break; + } +} + +void UIBrokerImpl::ShowCompanionApp(const Device& device) { + switch (device.protocol) { + case Protocol::kFastPair: + fast_pair_presenter_->ShowCompanionApp( + device, + base::BindOnce(&UIBrokerImpl::NotifyCompanionAppAction, + weak_pointer_factory_.GetWeakPtr(), std::ref(device))); + break; + } +} + +void UIBrokerImpl::NotifyDiscoveryAction(const Device& device, + DiscoveryAction action) { + for (auto& observer : observers_) + observer.OnDiscoveryAction(device, action); +} + +void UIBrokerImpl::NotifyPairingFailedAction(const Device& device, + PairingFailedAction action) { + for (auto& observer : observers_) + observer.OnPairingFailureAction(device, action); +} + +void UIBrokerImpl::NotifyAssociateAccountAction(const Device& device, + AssociateAccountAction action) { + for (auto& observer : observers_) + observer.OnAssociateAccountAction(device, action); +} + +void UIBrokerImpl::NotifyCompanionAppAction(const Device& device, + CompanionAppAction action) { + for (auto& observer : observers_) + observer.OnCompanionAppAction(device, action); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/ui/ui_broker_impl.h b/ash/quick_pair/ui/ui_broker_impl.h new file mode 100644 index 0000000..991552d0 --- /dev/null +++ b/ash/quick_pair/ui/ui_broker_impl.h
@@ -0,0 +1,53 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_QUICK_PAIR_UI_UI_BROKER_IMPL_H_ +#define ASH_QUICK_PAIR_UI_UI_BROKER_IMPL_H_ + +#include <memory> + +#include "ash/quick_pair/ui/actions.h" +#include "ash/quick_pair/ui/ui_broker.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" + +namespace ash { +namespace quick_pair { + +class FastPairPresenter; + +class UIBrokerImpl : public UIBroker { + public: + UIBrokerImpl(); + UIBrokerImpl(const UIBrokerImpl&) = delete; + UIBrokerImpl& operator=(const UIBrokerImpl&) = delete; + ~UIBrokerImpl(); + + // UIBroker: + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + void ShowDiscovery(const Device& device) override; + void ShowPairing(const Device& device) override; + void ShowPairingFailed(const Device& device) override; + void ShowAssociateAccount(const Device& device) override; + void ShowCompanionApp(const Device& device) override; + + private: + void NotifyDiscoveryAction(const Device& device, DiscoveryAction action); + void NotifyPairingFailedAction(const Device& device, + PairingFailedAction action); + void NotifyAssociateAccountAction(const Device& device, + AssociateAccountAction action); + void NotifyCompanionAppAction(const Device& device, + CompanionAppAction action); + + std::unique_ptr<FastPairPresenter> fast_pair_presenter_; + base::ObserverList<Observer> observers_; + base::WeakPtrFactory<UIBrokerImpl> weak_pointer_factory_{this}; +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_UI_UI_BROKER_IMPL_H_
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index a8ce5af..9d58724 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -333,6 +333,7 @@ friend class ShelfLayoutManagerWindowDraggingTest; friend class NotificationTrayTest; friend class UnifiedSystemTrayTest; + friend class TrayBackgroundViewTest; friend class Shelf; struct State {
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index 6acf153..d4af9e8 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -152,6 +152,14 @@ widget->GetClientAreaBoundsInScreen().top_center().y(); } +// Creates and displays a test app in the hotseat. +void AddApp() { + ShelfController* controller = Shell::Get()->shelf_controller(); + const int next_app_index = controller->model()->item_count(); + ShelfTestUtil::AddAppShortcut( + "app_id_" + base::NumberToString(next_app_index), TYPE_PINNED_APP); +} + class TestDisplayObserver : public display::DisplayObserver { public: TestDisplayObserver() = default; @@ -2842,6 +2850,67 @@ base::i18n::SetICUDefaultLocale(locale); } +// Tests the auto-hide shelf status when opening and closing a context menu. +TEST_F(ShelfLayoutManagerTest, AutoHideShelfWithContextMenu) { + // Create one window, or the shelf won't auto-hide. + CreateTestWidget(); + + // Set the shelf to auto-hide. + Shelf* shelf = GetPrimaryShelf(); + shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways); + ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); + layout_manager->LayoutShelf(); + EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); + + // Create an app that we can use to pull up a context menu. + EXPECT_EQ(0, + ShelfViewTestAPI(shelf->GetShelfViewForTesting()).GetButtonCount()); + AddApp(); + EXPECT_EQ(1, + ShelfViewTestAPI(shelf->GetShelfViewForTesting()).GetButtonCount()); + + // Swipe up to show the shelf. + SwipeUpOnShelf(); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Open hotseat context menu. + ui::test::EventGenerator* generator = GetEventGenerator(); + ShelfAppButton* clickable_app_button = + ShelfViewTestAPI(shelf->GetShelfViewForTesting()).GetButton(0); + EXPECT_TRUE(clickable_app_button); + EXPECT_FALSE(shelf->shelf_widget()->IsShowingMenu()); + generator->MoveMouseTo( + clickable_app_button->GetBoundsInScreen().CenterPoint()); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + generator->ClickRightButton(); + EXPECT_TRUE(shelf->shelf_widget()->IsShowingMenu()); + + // Close the context menu with the mouse over the shelf. The shelf should + // remain shown. + generator->ClickRightButton(); + ASSERT_FALSE(TriggerAutoHideTimeout()); + EXPECT_FALSE(shelf->shelf_widget()->IsShowingMenu()); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Reopen hotseat context menu. + generator->ClickRightButton(); + EXPECT_TRUE(shelf->shelf_widget()->IsShowingMenu()); + + // Mouse away from the shelf with the context menu still showing. The shelf + // should remain shown. + generator->MoveMouseTo(0, 0); + ASSERT_TRUE(TriggerAutoHideTimeout()); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Close the context menu with the mouse away from the shelf. The shelf + // should hide. + generator->ClickRightButton(); + ASSERT_FALSE(TriggerAutoHideTimeout()); + EXPECT_FALSE(shelf->shelf_widget()->IsShowingMenu()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); +} + class AppListBubbleShelfLayoutManagerTest : public ShelfLayoutManagerTest { public: AppListBubbleShelfLayoutManagerTest() { @@ -3942,18 +4011,11 @@ aura::Window::Windows root_windows = Shell::GetAllRootWindows(); EXPECT_EQ(display_count, root_windows.size()); - auto add_app = []() { - ShelfController* controller = Shell::Get()->shelf_controller(); - int n_apps = controller->model()->item_count(); - ShelfTestUtil::AddAppShortcut("app_id_" + base::NumberToString(n_apps), - TYPE_PINNED_APP); - }; - // Keep this low so that all apps fit at the center of the screen on all // displays. const int max_app_count = 4; for (int app_count = 1; app_count <= max_app_count; ++app_count) { - add_app(); + AddApp(); // Wait for everything to settle down. for (unsigned int display_index = 0; display_index < display_count;
diff --git a/ash/shell.cc b/ash/shell.cc index 45ce219..ce5ed27 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -87,6 +87,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/views_text_services_context_menu_impl.h" #include "ash/quick_answers/quick_answers_controller_impl.h" +#include "ash/quick_pair/keyed_service/quick_pair_mediator.h" #include "ash/root_window_controller.h" #include "ash/screenshot_delegate.h" #include "ash/session/session_controller_impl.h" @@ -559,7 +560,8 @@ shell_delegate_(std::move(shell_delegate)), shutdown_controller_(std::make_unique<ShutdownControllerImpl>()), system_tray_notifier_(std::make_unique<SystemTrayNotifier>()), - native_cursor_manager_(nullptr) { + native_cursor_manager_(nullptr), + quick_pair_mediator_(quick_pair::Mediator::Factory::Create()) { AccelerometerReader::GetInstance()->Initialize(); login_screen_controller_ =
diff --git a/ash/shell.h b/ash/shell.h index 0dffada..4f7aa96 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -207,6 +207,10 @@ enum class LoginStatus; +namespace quick_pair { +class Mediator; +} // namespace quick_pair + // Shell is a singleton object that presents the Shell API and implements the // RootWindow's delegate interface. // @@ -889,6 +893,8 @@ std::unique_ptr<OcclusionTrackerPauser> occlusion_tracker_pauser_; + std::unique_ptr<quick_pair::Mediator> quick_pair_mediator_; + base::ObserverList<ShellObserver>::Unchecked shell_observers_; base::WeakPtrFactory<Shell> weak_factory_{this};
diff --git a/ash/system/holding_space/holding_space_tray.cc b/ash/system/holding_space/holding_space_tray.cc index e6958c4c..ace2d3d 100644 --- a/ash/system/holding_space/holding_space_tray.cc +++ b/ash/system/holding_space/holding_space_tray.cc
@@ -45,7 +45,6 @@ #include "ui/gfx/paint_vector_icon.h" #include "ui/views/animation/ink_drop.h" #include "ui/views/controls/image_view.h" -#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/vector_icons.h" #include "ui/wm/core/coordinate_conversion.h" @@ -277,7 +276,7 @@ layer()->Add(progress_ring_->layer()); // Enable context menu, which supports an action to toggle item previews. - set_context_menu_controller(this); + SetContextMenuEnabled(true); } HoldingSpaceTray::~HoldingSpaceTray() = default; @@ -543,6 +542,34 @@ previews_tray_icon_->set_should_animate_updates(should_animate); } +std::unique_ptr<ui::SimpleMenuModel> +HoldingSpaceTray::CreateContextMenuModel() { + holding_space_metrics::RecordPodAction( + holding_space_metrics::PodAction::kShowContextMenu); + + bool previews_enabled = holding_space_prefs::IsPreviewsEnabled( + Shell::Get()->session_controller()->GetActivePrefService()); + auto context_menu_model = std::make_unique<ui::SimpleMenuModel>(this); + + if (previews_enabled) { + context_menu_model->AddItemWithIcon( + static_cast<int>(HoldingSpaceCommandId::kHidePreviews), + l10n_util::GetStringUTF16( + IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_HIDE_PREVIEWS), + ui::ImageModel::FromVectorIcon(kVisibilityOffIcon, /*color_id=*/-1, + kHoldingSpaceIconSize)); + } else { + context_menu_model->AddItemWithIcon( + static_cast<int>(HoldingSpaceCommandId::kShowPreviews), + l10n_util::GetStringUTF16( + IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_SHOW_PREVIEWS), + ui::ImageModel::FromVectorIcon(kVisibilityIcon, /*color_id=*/-1, + kHoldingSpaceIconSize)); + } + + return context_menu_model; +} + void HoldingSpaceTray::OnHoldingSpaceModelAttached(HoldingSpaceModel* model) { // When the `model` is attached the session is either being started/unlocked // or the active profile is being changed. It's also possible that the status @@ -625,60 +652,6 @@ } } -void HoldingSpaceTray::ShowContextMenuForViewImpl( - views::View* source, - const gfx::Point& point, - ui::MenuSourceType source_type) { - holding_space_metrics::RecordPodAction( - holding_space_metrics::PodAction::kShowContextMenu); - - context_menu_model_ = std::make_unique<ui::SimpleMenuModel>(this); - - const bool previews_enabled = holding_space_prefs::IsPreviewsEnabled( - Shell::Get()->session_controller()->GetActivePrefService()); - - if (previews_enabled) { - context_menu_model_->AddItemWithIcon( - static_cast<int>(HoldingSpaceCommandId::kHidePreviews), - l10n_util::GetStringUTF16( - IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_HIDE_PREVIEWS), - ui::ImageModel::FromVectorIcon(kVisibilityOffIcon, /*color_id=*/-1, - kHoldingSpaceIconSize)); - } else { - context_menu_model_->AddItemWithIcon( - static_cast<int>(HoldingSpaceCommandId::kShowPreviews), - l10n_util::GetStringUTF16( - IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_SHOW_PREVIEWS), - ui::ImageModel::FromVectorIcon(kVisibilityIcon, /*color_id=*/-1, - kHoldingSpaceIconSize)); - } - - const int run_types = views::MenuRunner::USE_TOUCHABLE_LAYOUT | - views::MenuRunner::CONTEXT_MENU | - views::MenuRunner::FIXED_ANCHOR; - - context_menu_runner_ = - std::make_unique<views::MenuRunner>(context_menu_model_.get(), run_types); - - views::MenuAnchorPosition anchor; - switch (shelf()->alignment()) { - case ShelfAlignment::kBottom: - case ShelfAlignment::kBottomLocked: - anchor = views::MenuAnchorPosition::kBubbleTopRight; - break; - case ShelfAlignment::kLeft: - anchor = views::MenuAnchorPosition::kBubbleRight; - break; - case ShelfAlignment::kRight: - anchor = views::MenuAnchorPosition::kBubbleLeft; - break; - } - - context_menu_runner_->RunMenuAt( - source->GetWidget(), /*button_controller=*/nullptr, - source->GetBoundsInScreen(), anchor, source_type); -} - void HoldingSpaceTray::OnWidgetDragWillStart(views::Widget* widget) { // The holding space bubble should be closed while dragging holding space // items so as not to obstruct drop targets. Post the task to close the bubble
diff --git a/ash/system/holding_space/holding_space_tray.h b/ash/system/holding_space/holding_space_tray.h index 555c4c4..65d0243 100644 --- a/ash/system/holding_space/holding_space_tray.h +++ b/ash/system/holding_space/holding_space_tray.h
@@ -23,7 +23,6 @@ #include "base/timer/timer.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/models/simple_menu_model.h" -#include "ui/views/context_menu_controller.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_observer.h" @@ -52,7 +51,6 @@ public HoldingSpaceModelObserver, public SessionObserver, public ui::SimpleMenuModel::Delegate, - public views::ContextMenuController, public views::WidgetObserver { public: METADATA_HEADER(HoldingSpaceTray); @@ -90,6 +88,7 @@ void VisibilityChanged(views::View* starting_from, bool is_visible) override; void OnThemeChanged() override; void OnShouldShowAnimationChanged(bool should_animate) override; + std::unique_ptr<ui::SimpleMenuModel> CreateContextMenuModel() override; // Invoke to cause the holding space tray to recalculate and update its // visibility. Note that this may or may not result in a visibility change @@ -132,11 +131,6 @@ // ui::SimpleMenuModel::Delegate: void ExecuteCommand(int command_id, int event_flags) override; - // views::ContextMenuController: - void ShowContextMenuForViewImpl(views::View* source, - const gfx::Point& point, - ui::MenuSourceType source_type) override; - // views::WidgetObserver: void OnWidgetDragWillStart(views::Widget* widget) override; void OnWidgetDestroying(views::Widget* widget) override; @@ -183,8 +177,6 @@ ui::mojom::DragOperation& output_drag_op); std::unique_ptr<HoldingSpaceTrayBubble> bubble_; - std::unique_ptr<ui::SimpleMenuModel> context_menu_model_; - std::unique_ptr<views::MenuRunner> context_menu_runner_; std::unique_ptr<aura::client::DragDropClientObserver> drag_drop_observer_; // Default tray icon shown when there are no previews available (or the
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc index 54af1a6..4a3dc7abf 100644 --- a/ash/system/ime_menu/ime_menu_tray.cc +++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -33,6 +33,7 @@ #include "base/metrics/user_metrics.h" #include "base/strings/utf_string_conversions.h" #include "components/session_manager/session_manager_types.h" +#include "ui/base/emoji/emoji_panel_helper.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/ime_bridge.h" #include "ui/base/ime/text_input_client.h" @@ -215,10 +216,8 @@ if (show_emoji) { emoji_button_ = new SystemMenuButton( - base::BindRepeating(&ImeButtonsView::KeysetButtonPressed, - base::Unretained(this), - chromeos::input_method::ImeKeyset::kEmoji), - kImeMenuEmoticonIcon, IDS_ASH_STATUS_TRAY_IME_EMOJI); + base::BindRepeating(&ui::ShowEmojiPanel), kImeMenuEmoticonIcon, + IDS_ASH_STATUS_TRAY_IME_EMOJI); emoji_button_->SetID(kEmojiButtonId); AddChildView(emoji_button_); }
diff --git a/ash/system/ime_menu/ime_menu_tray_unittest.cc b/ash/system/ime_menu/ime_menu_tray_unittest.cc index 8547dc0..a932bc0f 100644 --- a/ash/system/ime_menu/ime_menu_tray_unittest.cc +++ b/ash/system/ime_menu/ime_menu_tray_unittest.cc
@@ -18,6 +18,7 @@ #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/base/emoji/emoji_panel_helper.h" #include "ui/base/ime/chromeos/ime_bridge.h" #include "ui/base/ime/text_input_flags.h" #include "ui/display/test/display_manager_test_api.h" @@ -330,6 +331,10 @@ // Tests that tapping the emoji button does not crash. http://crbug.com/739630 TEST_F(ImeMenuTrayTest, TapEmojiButton) { + int callCount = 0; + ui::SetShowEmojiKeyboardCallback( + base::BindRepeating([](int* count) { (*count)++; }, (&callCount))); + Shell::Get()->ime_controller()->ShowImeMenuOnShelf(true); Shell::Get()->ime_controller()->SetExtraInputOptionsEnabledState( true /* ui enabled */, true /* emoji input enabled */, @@ -345,8 +350,11 @@ ASSERT_TRUE(emoji_button); emoji_button->OnGestureEvent(&tap); - // The menu should be hidden. - EXPECT_FALSE(IsBubbleShown()); + // The callback should have been called. + EXPECT_EQ(callCount, 1); + + // Cleanup. + ui::SetShowEmojiKeyboardCallback(base::DoNothing()); } TEST_F(ImeMenuTrayTest, ShouldShowBottomButtons) {
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc index aaee4e7..d207974 100644 --- a/ash/system/status_area_widget.cc +++ b/ash/system/status_area_widget.cc
@@ -548,6 +548,12 @@ if (unified_system_tray_->IsBubbleShown()) return true; + // If any tray is showing a context menu, the shelf should be visible. + for (TrayBackgroundView* tray_button : tray_buttons_) { + if (tray_button->IsShowingMenu()) + return true; + } + // If it has a slider bubble, return false. if (unified_system_tray_->IsSliderBubbleShown()) return false;
diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc index f1d58ab..f546130 100644 --- a/ash/system/tray/tray_background_view.cc +++ b/ash/system/tray/tray_background_view.cc
@@ -33,6 +33,8 @@ #include "ui/accessibility/ax_node_data.h" #include "ui/aura/window.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/models/menu_model.h" +#include "ui/base/ui_base_types.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_element.h" #include "ui/compositor/layer_animation_sequence.h" @@ -52,6 +54,7 @@ #include "ui/views/background.h" #include "ui/views/controls/focus_ring.h" #include "ui/views/controls/highlight_path_generator.h" +#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/painter.h" #include "ui/views/view_class_properties.h" @@ -319,6 +322,10 @@ UpdateStatusArea(true /*should_log_visible_pod_count*/); } +bool TrayBackgroundView::IsShowingMenu() const { + return context_menu_runner_ && context_menu_runner_->IsRunning(); +} + void TrayBackgroundView::StartVisibilityAnimation(bool visible) { if (visible == layer()->GetTargetVisibility()) return; @@ -390,6 +397,40 @@ } } +void TrayBackgroundView::ShowContextMenuForViewImpl( + views::View* source, + const gfx::Point& point, + ui::MenuSourceType source_type) { + context_menu_model_ = CreateContextMenuModel(); + if (!context_menu_model_) + return; + + const int run_types = views::MenuRunner::USE_TOUCHABLE_LAYOUT | + views::MenuRunner::CONTEXT_MENU | + views::MenuRunner::FIXED_ANCHOR; + context_menu_runner_ = std::make_unique<views::MenuRunner>( + context_menu_model_.get(), run_types, + base::BindRepeating(&Shelf::UpdateAutoHideState, + base::Unretained(shelf_))); + views::MenuAnchorPosition anchor; + switch (shelf_->alignment()) { + case ShelfAlignment::kBottom: + case ShelfAlignment::kBottomLocked: + anchor = views::MenuAnchorPosition::kBubbleTopRight; + break; + case ShelfAlignment::kLeft: + anchor = views::MenuAnchorPosition::kBubbleRight; + break; + case ShelfAlignment::kRight: + anchor = views::MenuAnchorPosition::kBubbleLeft; + break; + } + + context_menu_runner_->RunMenuAt( + source->GetWidget(), /*button_controller=*/nullptr, + source->GetBoundsInScreen(), anchor, source_type); +} + void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse) { Shelf* shelf = Shelf::ForWindow(GetWidget()->GetNativeWindow()); StatusAreaWidgetDelegate* delegate = @@ -704,6 +745,11 @@ ActionableView::HandlePerformActionResult(action_performed, event); } +std::unique_ptr<ui::SimpleMenuModel> +TrayBackgroundView::CreateContextMenuModel() { + return nullptr; +} + views::PaintInfo::ScaleType TrayBackgroundView::GetPaintScaleType() const { return views::PaintInfo::ScaleType::kUniformScaling; }
diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h index 3e4a6ca..2fd8e30a4 100644 --- a/ash/system/tray/tray_background_view.h +++ b/ash/system/tray/tray_background_view.h
@@ -17,6 +17,16 @@ #include "base/memory/weak_ptr.h" #include "ui/compositor/layer_animation_observer.h" #include "ui/gfx/geometry/insets.h" +#include "ui/views/context_menu_controller.h" + +namespace ui { +enum MenuSourceType; +} // namespace ui + +namespace views { +class MenuRunner; +class View; +} // namespace views namespace ash { class Shelf; @@ -28,6 +38,7 @@ // inherits from ActionableView so that the tray items can override // PerformAction when clicked on. class ASH_EXPORT TrayBackgroundView : public ActionableView, + public views::ContextMenuController, public ui::LayerAnimationObserver, public ShelfBackgroundAnimatorObserver, public TrayBubbleView::Delegate, @@ -149,6 +160,9 @@ // disabled until the returned scoped closure runner is run. base::ScopedClosureRunner DisableShowAnimation() WARN_UNUSED_RESULT; + // Returns true if the view is showing a context menu. + bool IsShowingMenu() const; + protected: // ActionableView: void OnBoundsChanged(const gfx::Rect& previous_bounds) override; @@ -159,6 +173,15 @@ virtual void OnShouldShowAnimationChanged(bool should_animate) {} + // Specifies the menu that appears when this tray is right-clicked if + // `SetContextMenuEnabled(true)` has been called. Default implementation + // returns a nullptr, in which case no context menu is shown. + virtual std::unique_ptr<ui::SimpleMenuModel> CreateContextMenuModel(); + + void SetContextMenuEnabled(bool should_enable_menu) { + set_context_menu_controller(should_enable_menu ? this : nullptr); + } + void set_show_with_virtual_keyboard(bool show_with_virtual_keyboard) { show_with_virtual_keyboard_ = show_with_virtual_keyboard; } @@ -182,6 +205,11 @@ void OnVisibilityAnimationFinished(bool should_log_visible_pod_count, bool aborted); + // views::ContextMenuController: + void ShowContextMenuForViewImpl(views::View* source, + const gfx::Point& point, + ui::MenuSourceType source_type) override; + // views::View: void AboutToRequestFocusFromTabTraversal(bool reverse) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; @@ -252,6 +280,8 @@ std::unique_ptr<TrayWidgetObserver> widget_observer_; std::unique_ptr<TrayEventFilter> tray_event_filter_; std::unique_ptr<TrayBackgroundViewSessionChangeHandler> handler_; + std::unique_ptr<ui::SimpleMenuModel> context_menu_model_; + std::unique_ptr<views::MenuRunner> context_menu_runner_; base::WeakPtrFactory<TrayBackgroundView> weak_factory_{this}; };
diff --git a/ash/system/tray/tray_background_view_unittest.cc b/ash/system/tray/tray_background_view_unittest.cc index 9e6a3ce..68aaa45 100644 --- a/ash/system/tray/tray_background_view_unittest.cc +++ b/ash/system/tray/tray_background_view_unittest.cc
@@ -7,6 +7,8 @@ #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller_impl.h" +#include "ash/shelf/shelf.h" +#include "ash/shelf/shelf_layout_manager.h" #include "ash/shell.h" #include "ash/system/accessibility/dictation_button_tray.h" #include "ash/system/status_area_widget_delegate.h" @@ -14,15 +16,17 @@ #include "ash/test/ash_test_base.h" #include "base/test/task_environment.h" #include "components/user_manager/user_manager.h" +#include "ui/base/models/simple_menu_model.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/scoped_layer_animation_settings.h" namespace ash { -class TrayBackgroundViewTestView : public TrayBackgroundView { +class TrayBackgroundViewTestView : public TrayBackgroundView, + public ui::SimpleMenuModel::Delegate { public: explicit TrayBackgroundViewTestView(Shelf* shelf) - : TrayBackgroundView(shelf) {} + : TrayBackgroundView(shelf), provide_menu_model_(false) {} TrayBackgroundViewTestView(const TrayBackgroundViewTestView&) = delete; TrayBackgroundViewTestView& operator=(const TrayBackgroundViewTestView&) = @@ -30,12 +34,31 @@ ~TrayBackgroundViewTestView() override = default; + // TrayBackgroundView: void ClickedOutsideBubble() override {} std::u16string GetAccessibleNameForTray() override { return u"TrayBackgroundViewTestView"; } void HandleLocaleChange() override {} void HideBubbleWithView(const TrayBubbleView* bubble_view) override {} + std::unique_ptr<ui::SimpleMenuModel> CreateContextMenuModel() override { + return provide_menu_model_ ? std::make_unique<ui::SimpleMenuModel>(this) + : nullptr; + } + + // ui::SimpleMenuModel::Delegate: + void ExecuteCommand(int command_id, int event_flags) override {} + + void set_provide_menu_model(bool provide_menu_model) { + provide_menu_model_ = provide_menu_model; + } + + void SetShouldShowMenu(bool should_show_menu) { + SetContextMenuEnabled(should_show_menu); + } + + private: + bool provide_menu_model_; }; class TrayBackgroundViewTest : public AshTestBase { @@ -86,6 +109,14 @@ ->dictation_button_tray(); } + bool TriggerAutoHideTimeout(ShelfLayoutManager* layout_manager) { + if (!layout_manager->auto_hide_timer_.IsRunning()) + return false; + + layout_manager->auto_hide_timer_.FireNow(); + return true; + } + private: TrayBackgroundViewTestView* test_view_ = nullptr; }; @@ -221,4 +252,94 @@ EXPECT_TRUE(GetPrimaryDictationTray()->GetVisible()); } +// Tests that a context menu only appears when a tray provides a menu model and +// the tray should show a context menu. +TEST_F(TrayBackgroundViewTest, ContextMenu) { + test_view()->SetVisiblePreferred(true); + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->MoveMouseTo(test_view()->GetBoundsInScreen().CenterPoint()); + EXPECT_FALSE(test_view()->IsShowingMenu()); + + // The tray should not display a context menu, and no model is provided, so + // no menu should appear. + generator->ClickRightButton(); + EXPECT_FALSE(test_view()->IsShowingMenu()); + + // The tray should display a context menu, but no model is provided, so no + // menu should appear. + test_view()->SetShouldShowMenu(true); + generator->ClickRightButton(); + EXPECT_FALSE(test_view()->IsShowingMenu()); + + // The tray should display a context menu, and a model is provided, so a menu + // should appear. + test_view()->set_provide_menu_model(true); + generator->ClickRightButton(); + EXPECT_TRUE(test_view()->IsShowingMenu()); + + // The tray should not display a context menu, so even though a model is + // provided, no menu should appear. + test_view()->SetShouldShowMenu(false); + generator->ClickRightButton(); + EXPECT_FALSE(test_view()->IsShowingMenu()); +} + +// Tests the auto-hide shelf status when opening and closing a context menu. +TEST_F(TrayBackgroundViewTest, AutoHideShelfWithContextMenu) { + // Create one window, or the shelf won't auto-hide. + std::unique_ptr<views::Widget> unused = CreateTestWidget(); + + // Set the shelf to auto-hide. + Shelf* shelf = test_view()->shelf(); + EXPECT_TRUE(shelf); + shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways); + ShelfLayoutManager* layout_manager = shelf->shelf_layout_manager(); + EXPECT_TRUE(layout_manager); + ASSERT_FALSE(TriggerAutoHideTimeout(layout_manager)); + EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); + + // Move mouse to display the shelf. + ui::test::EventGenerator* generator = GetEventGenerator(); + gfx::Rect display_bounds = + display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); + generator->MoveMouseTo(display_bounds.bottom_center()); + ASSERT_TRUE(TriggerAutoHideTimeout(layout_manager)); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Open tray context menu. + test_view()->SetVisiblePreferred(true); + test_view()->set_provide_menu_model(true); + test_view()->SetShouldShowMenu(true); + generator->MoveMouseTo(test_view()->GetBoundsInScreen().CenterPoint()); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + EXPECT_FALSE(test_view()->IsShowingMenu()); + generator->ClickRightButton(); + EXPECT_TRUE(test_view()->IsShowingMenu()); + + // Close the context menu with the mouse over the shelf. The shelf should + // remain shown. + generator->ClickRightButton(); + ASSERT_FALSE(TriggerAutoHideTimeout(layout_manager)); + EXPECT_FALSE(test_view()->IsShowingMenu()); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Reopen tray context menu. + generator->ClickRightButton(); + EXPECT_TRUE(test_view()->IsShowingMenu()); + + // Mouse away from the shelf with the context menu still showing. The shelf + // should remain shown. + generator->MoveMouseTo(0, 0); + ASSERT_TRUE(TriggerAutoHideTimeout(layout_manager)); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Close the context menu with the mouse away from the shelf. The shelf + // should hide. + generator->ClickRightButton(); + ASSERT_FALSE(TriggerAutoHideTimeout(layout_manager)); + EXPECT_FALSE(test_view()->IsShowingMenu()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); +} + } // namespace ash
diff --git a/ash/webui/diagnostics_ui/resources/battery_status_card.js b/ash/webui/diagnostics_ui/resources/battery_status_card.js index 631333e..205bd396e 100644 --- a/ash/webui/diagnostics_ui/resources/battery_status_card.js +++ b/ash/webui/diagnostics_ui/resources/battery_status_card.js
@@ -256,7 +256,7 @@ return ''; } - const disableRunButtonThreshold = 98; + const disableRunButtonThreshold = 95; const percentage = Math.round( 100 * this.batteryChargeStatus_.chargeNowMilliampHours / this.batteryHealth_.chargeFullNowMilliampHours);
diff --git a/ash/webui/scanning/resources/action_toolbar.html b/ash/webui/scanning/resources/action_toolbar.html index afb96fc..b8d79fb4 100644 --- a/ash/webui/scanning/resources/action_toolbar.html +++ b/ash/webui/scanning/resources/action_toolbar.html
@@ -26,6 +26,14 @@ --cr-icon-button-fill-color: var(--google-grey-200); } + #pageNumbers { + color: var(--scanning-action-toolbar-text-color); + font-family: var(--scanning-action-toolbar-font-family); + font-size: var(--scanning-action-toolbar-font-size); + font-weight: var(--scanning-medium-font-weight); + line-height: var(--scanning-action-toolbar-line-height); + } + #removePageIcon { --cr-icon-button-margin-end: 16px; --cr-icon-image: url(svg/remove_page.svg); @@ -36,6 +44,7 @@ } </style> <div id="actionToolbar"> + <div id="pageNumbers">[[pageNumberText_]]</div> <div class="separator"></div> <div> <cr-icon-button id="removePageIcon"></cr-icon-button>
diff --git a/ash/webui/scanning/resources/action_toolbar.js b/ash/webui/scanning/resources/action_toolbar.js index db021d2..eb0850d 100644 --- a/ash/webui/scanning/resources/action_toolbar.js +++ b/ash/webui/scanning/resources/action_toolbar.js
@@ -5,6 +5,8 @@ import './scanning_shared_css.js'; import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; /** @@ -15,4 +17,37 @@ is: 'action-toolbar', _template: html`{__html_template__}`, + + behaviors: [I18nBehavior], + + properties: { + /** @type {number} */ + currentPageInView: Number, + + /** @type {number} */ + numTotalPages: Number, + + /** @private {string} */ + pageNumberText_: { + type: String, + computed: 'computePageNumberText_(currentPageInView, numTotalPages)', + }, + }, + + /** + * @return {string} + * @private + */ + computePageNumberText_() { + if (!this.currentPageInView || !this.numTotalPages) { + return ''; + } + + assert(this.currentPageInView > 0 && this.numTotalPages > 0); + assert(this.currentPageInView <= this.numTotalPages); + + return this.i18n( + 'actionToolbarPageCountText', this.currentPageInView, + this.numTotalPages); + }, });
diff --git a/ash/webui/scanning/resources/scanning_app.js b/ash/webui/scanning/resources/scanning_app.js index 5f0a1a7..9e3479f3 100644 --- a/ash/webui/scanning/resources/scanning_app.js +++ b/ash/webui/scanning/resources/scanning_app.js
@@ -336,8 +336,8 @@ /** @private {boolean} */ showMultiPageCheckbox_: { type: Boolean, - computed: 'computeShowMultiPageCheckbox_(appState_, selectedSource, ' + - 'selectedFileType, scanAppMultiPageScanEnabled_)', + computed: 'computeShowMultiPageCheckbox_(showScanSettings_, ' + + 'selectedSource, selectedFileType, scanAppMultiPageScanEnabled_)', reflectToAttribute: true, }, @@ -1029,9 +1029,8 @@ * @private */ computeShowMultiPageCheckbox_() { - return this.scanAppMultiPageScanEnabled_ && - this.appState_ === AppState.READY && this.isPDFSelected_() && - this.isFlatbedSelected_(); + return this.scanAppMultiPageScanEnabled_ && this.showScanSettings_ && + this.isPDFSelected_() && this.isFlatbedSelected_(); }, /** @@ -1039,7 +1038,8 @@ * @private */ isPDFSelected_() { - return fileTypeFromString(this.selectedFileType) === + return !!this.selectedFileType && + fileTypeFromString(this.selectedFileType) === ash.scanning.mojom.FileType.kPdf; }, @@ -1048,7 +1048,8 @@ * @private */ isFlatbedSelected_() { - return this.sourceTypeMap_.get(this.selectedSource) === + return !!this.selectedSource && + this.sourceTypeMap_.get(this.selectedSource) === ash.scanning.mojom.SourceType.kFlatbed; },
diff --git a/ash/webui/scanning/resources/scanning_fonts_css.html b/ash/webui/scanning/resources/scanning_fonts_css.html index ba6f6cb..5569ee3d 100644 --- a/ash/webui/scanning/resources/scanning_fonts_css.html +++ b/ash/webui/scanning/resources/scanning_fonts_css.html
@@ -1,6 +1,7 @@ <template> <style> :host { + --scanning-action-toolbar-font-family: Roboto; --scanning-app-title-font-family: "Google Sans", Roboto, sans-serif; --scanning-done-section-option-font-family: Roboto; --scanning-helper-text-font-family: Roboto; @@ -11,6 +12,7 @@ --scanning-scan-setting-font-family: Roboto; --scanning-scanners-loading-font-family: "Google Sans", Roboto, sans-serif; + --scanning-action-toolbar-font-size: 13px; --scanning-app-title-font-size: 22px; --scanning-done-section-option-font-size: 13px; --scanning-helper-text-font-size: 13px; @@ -21,6 +23,7 @@ --scanning-scan-setting-font-size: 13px; --scanning-scanners-loading-font-size: 22px; + --scanning-action-toolbar-line-height: 20px; --scanning-app-title-line-height: 28px; --scanning-done-section-option-line-height: 20px; --scanning-helper-text-line-height: 20px; @@ -34,6 +37,7 @@ --scanning-regular-font-weight: 400; --scanning-medium-font-weight: 500; + --scanning-action-toolbar-text-color: var(--google-grey-200); --scanning-app-title-text-color: var(--google-grey-900); --scanning-done-section-option-text-color: var(--google-grey-900); --scanning-helper-text-color: var(--google-grey-700);
diff --git a/ash/webui/scanning/scanning_ui.cc b/ash/webui/scanning/scanning_ui.cc index 2a8d633..34935e39 100644 --- a/ash/webui/scanning/scanning_ui.cc +++ b/ash/webui/scanning/scanning_ui.cc
@@ -48,6 +48,8 @@ void AddScanningAppStrings(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { {"a4OptionText", IDS_SCANNING_APP_A4_OPTION_TEXT}, + {"actionToolbarPageCountText", + IDS_SCANNING_APP_ACTION_TOOLBAR_PAGE_COUNT_TEXT}, {"appTitle", IDS_SCANNING_APP_TITLE}, {"blackAndWhiteOptionText", IDS_SCANNING_APP_BLACK_AND_WHITE_OPTION_TEXT}, {"cancelButtonText", IDS_SCANNING_APP_CANCEL_BUTTON_TEXT},
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc index 02d6580..8cb64f5 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc +++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -4,8 +4,10 @@ #include "ash/webui/shimless_rma/backend/shimless_rma_service.h" +#include "ash/webui/shimless_rma/mojom/shimless_rma.mojom.h" #include "ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h" #include "base/bind.h" +#include "chromeos/dbus/rmad/rmad.pb.h" #include "chromeos/dbus/rmad/rmad_client.h" namespace ash { @@ -13,25 +15,6 @@ namespace { -using StateTraits = - mojo::EnumTraits<mojom::RmaState, rmad::RmadState::StateCase>; - -using ErrorTraits = mojo::EnumTraits<mojom::RmadErrorCode, rmad::RmadErrorCode>; - -using ComponentTraits = mojo::EnumTraits<mojom::ComponentType, - rmad::ComponentRepairState::Component>; - -using RepairTraits = mojo::EnumTraits<mojom::ComponentRepairState, - rmad::ComponentRepairState::RepairState>; - -using CalibrationTraits = - mojo::EnumTraits<mojom::CalibrationComponent, - rmad::CalibrateComponentsState::CalibrationComponent>; - -using ProvisionTraits = - mojo::EnumTraits<mojom::ProvisioningStep, - rmad::ProvisionDeviceState::ProvisioningStep>; - class RmadObserver : chromeos::RmadClient::Observer { public: void Error(rmad::RmadErrorCode error) override {} @@ -104,8 +87,8 @@ if (state_proto_.state_case() != rmad::RmadState::kUpdateChrome) { LOG(ERROR) << "UpdateChrome called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_update_chrome()->set_update( @@ -117,8 +100,8 @@ if (state_proto_.state_case() != rmad::RmadState::kUpdateChrome) { LOG(ERROR) << "UpdateChrome called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_update_chrome()->set_update( @@ -130,8 +113,8 @@ if (state_proto_.state_case() != rmad::RmadState::kDeviceDestination) { LOG(ERROR) << "SetSameOwner called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_device_destination()->set_destination( @@ -143,8 +126,8 @@ if (state_proto_.state_case() != rmad::RmadState::kDeviceDestination) { LOG(ERROR) << "SetDifferentOwner called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_device_destination()->set_destination( @@ -158,8 +141,8 @@ LOG(ERROR) << "ChooseManuallyDisableWriteProtect called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_wp_disable_method()->set_disable_method( @@ -172,8 +155,8 @@ if (state_proto_.state_case() != rmad::RmadState::kWpDisableMethod) { LOG(ERROR) << "ChooseRsuDisableWriteProtect called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_wp_disable_method()->set_disable_method( @@ -187,8 +170,8 @@ if (state_proto_.state_case() != rmad::RmadState::kWpDisableRsu) { LOG(ERROR) << "SetRsuDisableWriteProtectCode called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_wp_disable_rsu()->set_unlock_code(code); @@ -196,43 +179,37 @@ } void ShimlessRmaService::GetComponentList(GetComponentListCallback callback) { - std::vector<mojom::ComponentPtr> components; + std::vector<::rmad::ComponentRepairState> components; if (state_proto_.state_case() != rmad::RmadState::kComponentsRepair) { LOG(ERROR) << "GetComponentList called from incorrect state " << state_proto_.state_case(); } else { components.reserve(state_proto_.components_repair().components_size()); for (auto component : state_proto_.components_repair().components()) { - components.push_back(mojom::Component::New( - ComponentTraits::ToMojom(component.name()), - RepairTraits::ToMojom(component.repair_state()))); + components.push_back(component); } } std::move(callback).Run(std::move(components)); } void ShimlessRmaService::SetComponentList( - std::vector<mojom::ComponentPtr> component_list, + const std::vector<::rmad::ComponentRepairState>& component_list, SetComponentListCallback callback) { if (state_proto_.state_case() != rmad::RmadState::kComponentsRepair) { LOG(ERROR) << "SetComponentList called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_components_repair()->clear_components(); state_proto_.mutable_components_repair()->mutable_components()->Reserve( component_list.size()); for (auto& component : component_list) { - rmad::ComponentRepairState::Component rmad_component; - rmad::ComponentRepairState::RepairState rmad_repair_state; - ComponentTraits::FromMojom(component->component, &rmad_component); - RepairTraits::FromMojom(component->state, &rmad_repair_state); rmad::ComponentRepairState* proto_component = state_proto_.mutable_components_repair()->add_components(); - proto_component->set_name(rmad_component); - proto_component->set_repair_state(rmad_repair_state); + proto_component->set_name(component.name()); + proto_component->set_repair_state(component.repair_state()); } GetNextStateGeneric(std::move(callback)); } @@ -241,8 +218,8 @@ if (state_proto_.state_case() != rmad::RmadState::kComponentsRepair) { LOG(ERROR) << "ReworkMainboard called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } // Create a new proto so that the full component list is retained while @@ -278,15 +255,15 @@ if (state_proto_.state_case() != rmad::RmadState::kUpdateRoFirmware) { LOG(ERROR) << "ReimageSkipped called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } // TODO(gavindodd): Is it better to just rely on rmad to enforce this? if (!state_proto_.update_ro_firmware().optional()) { LOG(ERROR) << "ReimageSkipped called when reimage required."; - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_update_ro_firmware()->set_update( @@ -299,8 +276,8 @@ if (state_proto_.state_case() != rmad::RmadState::kUpdateRoFirmware) { LOG(ERROR) << "ReimageFromDownload called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_update_ro_firmware()->set_update( @@ -312,8 +289,8 @@ if (state_proto_.state_case() != rmad::RmadState::kUpdateRoFirmware) { LOG(ERROR) << "ReimageFromUsb called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_update_ro_firmware()->set_update( @@ -366,8 +343,8 @@ if (state_proto_.state_case() != rmad::RmadState::kUpdateDeviceInfo) { LOG(ERROR) << "SetDeviceInformation called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_update_device_info()->set_serial_number(serial_number); @@ -380,8 +357,8 @@ if (state_proto_.state_case() != rmad::RmadState::kFinalize) { LOG(ERROR) << "FinalizeAndReboot called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_finalize()->set_shutdown( @@ -394,8 +371,8 @@ if (state_proto_.state_case() != rmad::RmadState::kFinalize) { LOG(ERROR) << "FinalizeAndShutdown called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_finalize()->set_shutdown( @@ -407,8 +384,8 @@ if (state_proto_.state_case() != rmad::RmadState::kFinalize) { LOG(ERROR) << "CutoffBattery called from incorrect state " << state_proto_.state_case(); - std::move(callback).Run(StateTraits::ToMojom(state_proto_.state_case()), - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } state_proto_.mutable_finalize()->set_shutdown( @@ -419,28 +396,24 @@ //////////////////////////////// // Observers void ShimlessRmaService::Error(rmad::RmadErrorCode error) { - mojom::RmadErrorCode mojo_error = ErrorTraits::ToMojom(error); if (error_observer_.is_bound()) { - error_observer_->OnError(mojo_error); + error_observer_->OnError(error); } } void ShimlessRmaService::CalibrationProgress( rmad::CalibrateComponentsState::CalibrationComponent component, double progress) { - mojom::CalibrationComponent mojo_component = - CalibrationTraits::ToMojom(component); if (calibration_observer_.is_bound()) { - calibration_observer_->OnCalibrationUpdated(mojo_component, progress); + calibration_observer_->OnCalibrationUpdated(component, progress); } } void ShimlessRmaService::ProvisioningProgress( rmad::ProvisionDeviceState::ProvisioningStep step, double progress) { - mojom::ProvisioningStep mojo_step = ProvisionTraits::ToMojom(step); if (provisioning_observer_.is_bound()) { - provisioning_observer_->OnProvisioningUpdated(mojo_step, progress); + provisioning_observer_->OnProvisioningUpdated(step, progress); } } @@ -505,25 +478,21 @@ absl::optional<rmad::GetStateReply> response) { if (!response) { LOG(ERROR) << "Failed to call rmadClient"; - std::move(callback).Run(mojom::RmaState::kUnknown, - mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(rmad::RmadState::STATE_NOT_SET, + rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } - const mojom::RmaState state = - StateTraits::ToMojom(response->state().state_case()); - if (!mojom::IsKnownEnumValue(state)) { - LOG(ERROR) << "rmadClient returned unknown state " << state; - std::move(callback).Run(mojom::RmaState::kUnknown, - mojom::RmadErrorCode::kTransitionFailed); - return; - } + // TODO(gavindodd): When platform and chrome release cycles are decoupled + // there needs to be a way to detect an unexpected state and switch to update + // Chrome screen. state_proto_ = response->state(); if (response->error() != rmad::RMAD_ERROR_OK) { LOG(ERROR) << "rmadClient returned error " << response->error(); - std::move(callback).Run(state, ErrorTraits::ToMojom(response->error())); + std::move(callback).Run(state_proto_.state_case(), response->error()); return; } - std::move(callback).Run(state, mojom::RmadErrorCode::kOk); + std::move(callback).Run(state_proto_.state_case(), + rmad::RmadErrorCode::RMAD_ERROR_OK); } void ShimlessRmaService::OnAbortRmaResponse( @@ -531,10 +500,10 @@ absl::optional<rmad::AbortRmaReply> response) { if (!response) { LOG(ERROR) << "Failed to call rmad::AbortRma"; - std::move(callback).Run(mojom::RmadErrorCode::kRequestInvalid); + std::move(callback).Run(rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } - std::move(callback).Run(ErrorTraits::ToMojom(response->error())); + std::move(callback).Run(response->error()); } } // namespace shimless_rma
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.h b/ash/webui/shimless_rma/backend/shimless_rma_service.h index 2e87ac8..134602f 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service.h +++ b/ash/webui/shimless_rma/backend/shimless_rma_service.h
@@ -52,8 +52,9 @@ SetRsuDisableWriteProtectCodeCallback callback) override; void GetComponentList(GetComponentListCallback callback) override; - void SetComponentList(std::vector<mojom::ComponentPtr> component_list, - SetComponentListCallback callback) override; + void SetComponentList( + const std::vector<::rmad::ComponentRepairState>& component_list, + SetComponentListCallback callback) override; void ReworkMainboard(ReworkMainboardCallback callback) override; void ReimageRequired(ReimageRequiredCallback callback) override;
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc index e40fa0b..a014df4 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc +++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -168,9 +168,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -181,9 +181,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kUnknown); - EXPECT_EQ(error, mojom::RmadErrorCode::kRmaNotRequired); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::STATE_NOT_SET); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_RMA_NOT_REQUIRED); run_loop.Quit(); })); run_loop.Run(); @@ -198,15 +198,15 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->GetNextState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kConfigureNetwork); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kSelectNetwork); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -221,9 +221,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetNextState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -235,15 +235,15 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->GetNextState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kTransitionFailed); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_TRANSITION_FAILED); run_loop.Quit(); })); run_loop.Run(); @@ -258,21 +258,21 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->GetNextState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kConfigureNetwork); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kSelectNetwork); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->GetPrevState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -287,9 +287,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetPrevState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kTransitionFailed); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_TRANSITION_FAILED); run_loop.Quit(); })); run_loop.Run(); @@ -301,15 +301,15 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->GetPrevState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kTransitionFailed); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_TRANSITION_FAILED); run_loop.Quit(); })); run_loop.Run(); @@ -322,8 +322,8 @@ fake_rmad_client_()->SetAbortable(true); base::RunLoop run_loop; shimless_rma_provider_->AbortRma( - base::BindLambdaForTesting([&](mojom::RmadErrorCode error) { - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + base::BindLambdaForTesting([&](rmad::RmadErrorCode error) { + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -336,8 +336,8 @@ fake_rmad_client_()->SetAbortable(false); base::RunLoop run_loop; shimless_rma_provider_->AbortRma( - base::BindLambdaForTesting([&](mojom::RmadErrorCode error) { - EXPECT_EQ(error, mojom::RmadErrorCode::kCannotCancelRma); + base::BindLambdaForTesting([&](rmad::RmadErrorCode error) { + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_CANNOT_CANCEL_RMA); run_loop.Quit(); })); run_loop.Run(); @@ -357,16 +357,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseDestination); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kDeviceDestination); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetSameOwner(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -378,16 +378,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetSameOwner(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -407,16 +407,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseDestination); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kDeviceDestination); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetDifferentOwner(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -428,15 +428,15 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetDifferentOwner(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -456,17 +456,17 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseWriteProtectDisableMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWpDisableMethod); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ChooseManuallyDisableWriteProtect( base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -479,17 +479,17 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ChooseManuallyDisableWriteProtect( base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -508,17 +508,17 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseWriteProtectDisableMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWpDisableMethod); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ChooseRsuDisableWriteProtect( base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -530,17 +530,17 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ChooseRsuDisableWriteProtect( base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -558,18 +558,18 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kEnterRSUWPDisableCode); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWpDisableRsu); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetRsuDisableWriteProtectCode( "test RSU unlock code", base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -582,18 +582,18 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetRsuDisableWriteProtectCode( "test RSU unlock code", base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -621,19 +621,24 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kSelectComponents); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kComponentsRepair); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->GetComponentList(base::BindLambdaForTesting( - [&](std::vector<mojom::ComponentPtr> components) { + [&](const std::vector<rmad::ComponentRepairState>& components) { EXPECT_EQ(2UL, components.size()); - EXPECT_EQ(components[0]->component, mojom::ComponentType::kKeyboard); - EXPECT_EQ(components[0]->state, mojom::ComponentRepairState::kOriginal); - EXPECT_EQ(components[1]->component, mojom::ComponentType::kTrackpad); - EXPECT_EQ(components[1]->state, mojom::ComponentRepairState::kReplaced); + EXPECT_EQ(components[0].name(), + + rmad::ComponentRepairState::RMAD_COMPONENT_KEYBOARD); + EXPECT_EQ(components[0].repair_state(), + rmad::ComponentRepairState::RMAD_REPAIR_ORIGINAL); + EXPECT_EQ(components[1].name(), + rmad::ComponentRepairState::RMAD_COMPONENT_TRACKPAD); + EXPECT_EQ(components[1].repair_state(), + rmad::ComponentRepairState::RMAD_REPAIR_REPLACED); run_loop.Quit(); })); run_loop.Run(); @@ -645,14 +650,14 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->GetComponentList(base::BindLambdaForTesting( - [&](std::vector<mojom::ComponentPtr> components) { + [&](const std::vector<rmad::ComponentRepairState>& components) { EXPECT_EQ(0UL, components.size()); run_loop.Quit(); })); @@ -694,24 +699,27 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kSelectComponents); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kComponentsRepair); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); - std::vector<mojom::ComponentPtr> components; - components.push_back(mojom::Component::New( - mojom::ComponentType::kKeyboard, mojom::ComponentRepairState::kReplaced)); - components.push_back(mojom::Component::New( - mojom::ComponentType::kTrackpad, mojom::ComponentRepairState::kOriginal)); + std::vector<rmad::ComponentRepairState> components(2); + components[0].set_name(rmad::ComponentRepairState::RMAD_COMPONENT_KEYBOARD); + components[0].set_repair_state( + + rmad::ComponentRepairState::RMAD_REPAIR_REPLACED); + components[1].set_name(rmad::ComponentRepairState::RMAD_COMPONENT_TRACKPAD); + components[1].set_repair_state( + rmad::ComponentRepairState::RMAD_REPAIR_ORIGINAL); shimless_rma_provider_->SetComponentList( std::move(components), base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -723,22 +731,23 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); - std::vector<mojom::ComponentPtr> components; - components.push_back(mojom::Component::New( - mojom::ComponentType::kKeyboard, mojom::ComponentRepairState::kReplaced)); + std::vector<rmad::ComponentRepairState> components(1); + components[0].set_name(rmad::ComponentRepairState::RMAD_COMPONENT_KEYBOARD); + components[0].set_repair_state( + rmad::ComponentRepairState::RMAD_REPAIR_REPLACED); shimless_rma_provider_->SetComponentList( std::move(components), base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -775,16 +784,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kSelectComponents); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kComponentsRepair); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReworkMainboard(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -796,16 +805,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReworkMainboard(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -818,9 +827,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseFirmwareReimageMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateRoFirmware); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -844,9 +853,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseFirmwareReimageMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateRoFirmware); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -864,9 +873,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -897,16 +906,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseFirmwareReimageMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateRoFirmware); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReimageSkipped(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -919,16 +928,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseFirmwareReimageMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateRoFirmware); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReimageSkipped(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseFirmwareReimageMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateRoFirmware); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -940,9 +949,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -968,16 +977,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseFirmwareReimageMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateRoFirmware); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReimageFromDownload(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -989,16 +998,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReimageFromDownload(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -1019,16 +1028,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kChooseFirmwareReimageMethod); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateRoFirmware); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReimageFromUsb(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -1040,16 +1049,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->ReimageFromUsb(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -1070,9 +1079,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kUpdateDeviceInformation); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateDeviceInfo); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -1090,9 +1099,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -1119,9 +1128,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kUpdateDeviceInformation); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateDeviceInfo); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -1139,9 +1148,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -1168,9 +1177,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kUpdateDeviceInformation); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateDeviceInfo); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -1188,9 +1197,9 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); @@ -1216,18 +1225,18 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kUpdateDeviceInformation); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kUpdateDeviceInfo); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetDeviceInformation( "serial number", 1, 2, base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -1239,18 +1248,18 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->SetDeviceInformation( "serial number", 1, 2, base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -1269,16 +1278,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kRepairComplete); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kFinalize); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->FinalizeAndReboot(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -1290,16 +1299,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->FinalizeAndReboot(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -1318,16 +1327,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kRepairComplete); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kFinalize); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->FinalizeAndShutdown(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -1339,16 +1348,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->FinalizeAndShutdown(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -1367,16 +1376,16 @@ }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kRepairComplete); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kFinalize); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->CutoffBattery(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); run_loop.Quit(); })); run_loop.Run(); @@ -1388,16 +1397,16 @@ fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kOk); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); })); run_loop.RunUntilIdle(); shimless_rma_provider_->CutoffBattery(base::BindLambdaForTesting( - [&](mojom::RmaState state, mojom::RmadErrorCode error) { - EXPECT_EQ(state, mojom::RmaState::kWelcomeScreen); - EXPECT_EQ(error, mojom::RmadErrorCode::kRequestInvalid); + [&](rmad::RmadState::StateCase state, rmad::RmadErrorCode error) { + EXPECT_EQ(state, rmad::RmadState::kWelcome); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); run_loop.Quit(); })); run_loop.Run(); @@ -1405,11 +1414,11 @@ class FakeErrorObserver : public mojom::ErrorObserver { public: - void OnError(mojom::RmadErrorCode error) override { + void OnError(rmad::RmadErrorCode error) override { observations.push_back(error); } - std::vector<mojom::RmadErrorCode> observations; + std::vector<rmad::RmadErrorCode> observations; mojo::Receiver<mojom::ErrorObserver> receiver{this}; }; @@ -1437,13 +1446,17 @@ class FakeCalibrationObserver : public mojom::CalibrationObserver { public: - void OnCalibrationUpdated(mojom::CalibrationComponent component, - float progress) override { + void OnCalibrationUpdated( + rmad::CalibrateComponentsState_CalibrationComponent component, + float progress) override { observations.push_back( - std::pair<mojom::CalibrationComponent, float>(component, progress)); + std::pair<rmad::CalibrateComponentsState_CalibrationComponent, float>( + component, progress)); } - std::vector<std::pair<mojom::CalibrationComponent, float>> observations; + std::vector< + std::pair<rmad::CalibrateComponentsState_CalibrationComponent, float>> + observations; mojo::Receiver<mojom::CalibrationObserver> receiver{this}; }; @@ -1461,13 +1474,15 @@ class FakeProvisioningObserver : public mojom::ProvisioningObserver { public: - void OnProvisioningUpdated(mojom::ProvisioningStep step, + void OnProvisioningUpdated(rmad::ProvisionDeviceState_ProvisioningStep step, float progress) override { observations.push_back( - std::pair<mojom::ProvisioningStep, float>(step, progress)); + std::pair<rmad::ProvisionDeviceState_ProvisioningStep, float>( + step, progress)); } - std::vector<std::pair<mojom::ProvisioningStep, float>> observations; + std::vector<std::pair<rmad::ProvisionDeviceState_ProvisioningStep, float>> + observations; mojo::Receiver<mojom::ProvisioningObserver> receiver{this}; };
diff --git a/ash/webui/shimless_rma/mojom/BUILD.gn b/ash/webui/shimless_rma/mojom/BUILD.gn index 6ebc4e6..f3ba9b92 100644 --- a/ash/webui/shimless_rma/mojom/BUILD.gn +++ b/ash/webui/shimless_rma/mojom/BUILD.gn
@@ -13,6 +13,34 @@ { types = [ { + mojom = "ash.shimless_rma.mojom.CalibrationComponent" + cpp = "::rmad::CalibrateComponentsState_CalibrationComponent" + }, + { + mojom = "ash.shimless_rma.mojom.ComponentRepairState" + cpp = "::rmad::ComponentRepairState_RepairState" + }, + { + mojom = "ash.shimless_rma.mojom.ComponentType" + cpp = "::rmad::ComponentRepairState_Component" + }, + { + mojom = "ash.shimless_rma.mojom.Component" + cpp = "::rmad::ComponentRepairState" + }, + { + mojom = "ash.shimless_rma.mojom.ProvisioningStep" + cpp = "::rmad::ProvisionDeviceState_ProvisioningStep" + }, + { + mojom = "ash.shimless_rma.mojom.RmaState" + cpp = "::rmad::RmadState::StateCase" + }, + { + mojom = "ash.shimless_rma.mojom.RmadErrorCode" + cpp = "::rmad::RmadErrorCode" + }, + { mojom = "media.mojom.CdmKeyInformation" cpp = "::std::unique_ptr<::media::CdmKeyInformation>" move_only = true @@ -22,7 +50,10 @@ cpp = "::media::CdmKeyInformation::KeyStatus" }, ] - traits_headers = [ "shimless_rma_mojom_traits.h" ] + traits_headers = [ + "shimless_rma_mojom_traits.h", + "//chromeos/dbus/rmad/rmad.pb.h", + ] traits_sources = [ "shimless_rma_mojom_traits.cc" ] traits_public_deps = [ "//chromeos/dbus/rmad:rmad_proto" ] },
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc index 00e2809..e0a3d5c 100644 --- a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc +++ b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc
@@ -18,11 +18,11 @@ using ProtoRmadErrorCode = rmad::RmadErrorCode; using MojomComponentType = ash::shimless_rma::mojom::ComponentType; -using ProtoComponentType = rmad::ComponentRepairState::Component; +using ProtoComponentType = rmad::ComponentRepairState_Component; using MojomComponentRepairState = ash::shimless_rma::mojom::ComponentRepairState; -using ProtoComponentRepairState = rmad::ComponentRepairState::RepairState; +using ProtoComponentRepairState = rmad::ComponentRepairState_RepairState; using MojomCalibrationComponent = ash::shimless_rma::mojom::CalibrationComponent; @@ -79,6 +79,60 @@ // static bool EnumTraits<MojomRmaState, ProtoRmadState>::FromMojom(MojomRmaState state, ProtoRmadState* out) { + switch (state) { + case MojomRmaState::kWelcomeScreen: + *out = ProtoRmadState::kWelcome; + return true; + case MojomRmaState::kConfigureNetwork: + *out = ProtoRmadState::kSelectNetwork; + return true; + case MojomRmaState::kUpdateChrome: + *out = ProtoRmadState::kUpdateChrome; + return true; + case MojomRmaState::kSelectComponents: + *out = ProtoRmadState::kComponentsRepair; + return true; + case MojomRmaState::kChooseDestination: + *out = ProtoRmadState::kDeviceDestination; + return true; + case MojomRmaState::kChooseWriteProtectDisableMethod: + *out = ProtoRmadState::kWpDisableMethod; + return true; + case MojomRmaState::kEnterRSUWPDisableCode: + *out = ProtoRmadState::kWpDisableRsu; + return true; + case MojomRmaState::kWaitForManualWPDisable: + *out = ProtoRmadState::kWpDisablePhysical; + return true; + case MojomRmaState::kWPDisableComplete: + *out = ProtoRmadState::kWpDisableComplete; + return true; + case MojomRmaState::kChooseFirmwareReimageMethod: + *out = ProtoRmadState::kUpdateRoFirmware; + return true; + case MojomRmaState::kRestock: + *out = ProtoRmadState::kRestock; + return true; + case MojomRmaState::kUpdateDeviceInformation: + *out = ProtoRmadState::kUpdateDeviceInfo; + return true; + case MojomRmaState::kCalibrateComponents: + *out = ProtoRmadState::kCalibrateComponents; + return true; + case MojomRmaState::kProvisionDevice: + *out = ProtoRmadState::kProvisionDevice; + return true; + case MojomRmaState::kWaitForManualWPEnable: + *out = ProtoRmadState::kWpEnablePhysical; + return true; + case MojomRmaState::kRepairComplete: + *out = ProtoRmadState::kFinalize; + return true; + + case MojomRmaState::kUnknown: + *out = ProtoRmadState::STATE_NOT_SET; + return true; + } NOTREACHED(); return false; } @@ -170,6 +224,118 @@ bool EnumTraits<MojomRmadErrorCode, ProtoRmadErrorCode>::FromMojom( MojomRmadErrorCode error, ProtoRmadErrorCode* out) { + switch (error) { + case MojomRmadErrorCode::kOk: + *out = ProtoRmadErrorCode::RMAD_ERROR_OK; + return true; + case MojomRmadErrorCode::KWait: + *out = ProtoRmadErrorCode::RMAD_ERROR_WAIT; + return true; + case MojomRmadErrorCode::KNeedReboot: + *out = ProtoRmadErrorCode::RMAD_ERROR_NEED_REBOOT; + return true; + case MojomRmadErrorCode::kRmaNotRequired: + *out = ProtoRmadErrorCode::RMAD_ERROR_RMA_NOT_REQUIRED; + return true; + case MojomRmadErrorCode::kStateHandlerMissing: + *out = ProtoRmadErrorCode::RMAD_ERROR_STATE_HANDLER_MISSING; + return true; + case MojomRmadErrorCode::kStateHandlerInitializationFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_STATE_HANDLER_INITIALIZATION_FAILED; + return true; + case MojomRmadErrorCode::kRequestInvalid: + *out = ProtoRmadErrorCode::RMAD_ERROR_REQUEST_INVALID; + return true; + case MojomRmadErrorCode::kRequestArgsMissing: + *out = ProtoRmadErrorCode::RMAD_ERROR_REQUEST_ARGS_MISSING; + return true; + case MojomRmadErrorCode::kRequestArgsViolation: + *out = ProtoRmadErrorCode::RMAD_ERROR_REQUEST_ARGS_VIOLATION; + return true; + case MojomRmadErrorCode::kTransitionFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_TRANSITION_FAILED; + return true; + case MojomRmadErrorCode::kAbortFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_ABORT_FAILED; + return true; + case MojomRmadErrorCode::kMissingComponent: + *out = ProtoRmadErrorCode::RMAD_ERROR_MISSING_COMPONENT; + return true; + case MojomRmadErrorCode::kWriteProtectDisableRsuNoChallenge: + *out = + ProtoRmadErrorCode::RMAD_ERROR_WRITE_PROTECT_DISABLE_RSU_NO_CHALLENGE; + return true; + case MojomRmadErrorCode::kWriteProtectDisableRsuCodeInvalid: + *out = + ProtoRmadErrorCode::RMAD_ERROR_WRITE_PROTECT_DISABLE_RSU_CODE_INVALID; + return true; + case MojomRmadErrorCode::kWriteProtectDisableBatteryNotDisconnected: + *out = ProtoRmadErrorCode:: + RMAD_ERROR_WRITE_PROTECT_DISABLE_BATTERY_NOT_DISCONNECTED; + return true; + case MojomRmadErrorCode::kWriteProtectSignalNotDetected: + *out = ProtoRmadErrorCode:: + RMAD_ERROR_WRITE_PROTECT_DISABLE_SIGNAL_NOT_DETECTED; + return true; + case MojomRmadErrorCode::kReimagingDownloadNoNetwork: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_DOWNLOAD_NO_NETWORK; + return true; + case MojomRmadErrorCode::kReimagingDownloadNetworkError: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_DOWNLOAD_NETWORK_ERROR; + return true; + case MojomRmadErrorCode::kReimagingDownloadCancelled: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_DOWNLOAD_CANCELLED; + return true; + case MojomRmadErrorCode::kReimagingUsbNotFound: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_USB_NOT_FOUND; + return true; + case MojomRmadErrorCode::kReimagingUsbTooManyFound: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_USB_TOO_MANY_FOUND; + return true; + case MojomRmadErrorCode::kReimagingUsbInvalidImage: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_USB_INVALID_IMAGE; + return true; + case MojomRmadErrorCode::kReimagingImagingFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_IMAGING_FAILED; + return true; + case MojomRmadErrorCode::kReimagingUnknownFailure: + *out = ProtoRmadErrorCode::RMAD_ERROR_REIMAGING_UNKNOWN_FAILURE; + return true; + case MojomRmadErrorCode::kDeviceInfoInvalid: + *out = ProtoRmadErrorCode::RMAD_ERROR_DEVICE_INFO_INVALID; + return true; + case MojomRmadErrorCode::kCalibrationFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_CALIBRATION_FAILED; + return true; + case MojomRmadErrorCode::kProvisioningFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_PROVISIONING_FAILED; + return true; + case MojomRmadErrorCode::kPowerwashFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_POWERWASH_FAILED; + return true; + case MojomRmadErrorCode::kFinalizationFailed: + *out = ProtoRmadErrorCode::RMAD_ERROR_FINALIZATION_FAILED; + return true; + case MojomRmadErrorCode::kLogUploadFtpServerCannotConnect: + *out = + ProtoRmadErrorCode::RMAD_ERROR_LOG_UPLOAD_FTP_SERVER_CANNOT_CONNECT; + return true; + case MojomRmadErrorCode::kLogUploadFtpServerConnectionRejected: + *out = ProtoRmadErrorCode:: + RMAD_ERROR_LOG_UPLOAD_FTP_SERVER_CONNECTION_REJECTED; + return true; + case MojomRmadErrorCode::kLogUploadFtpServerTransferFailed: + *out = + ProtoRmadErrorCode::RMAD_ERROR_LOG_UPLOAD_FTP_SERVER_TRANSFER_FAILED; + return true; + case MojomRmadErrorCode::kCannotCancelRma: + *out = ProtoRmadErrorCode::RMAD_ERROR_CANNOT_CANCEL_RMA; + return true; + + case MojomRmadErrorCode::kNotSet: + NOTREACHED(); + return false; + } NOTREACHED(); return false; } @@ -299,6 +465,15 @@ bool EnumTraits<MojomCalibrationComponent, ProtoCalibrationComponent>:: FromMojom(MojomCalibrationComponent component, ProtoCalibrationComponent* out) { + switch (component) { + case MojomCalibrationComponent::kAccelerometer: + *out = rmad::CalibrateComponentsState:: + RMAD_CALIBRATION_COMPONENT_ACCELEROMETER; + return true; + case MojomCalibrationComponent::kCalibrateUnknown: + NOTREACHED(); + return false; + } NOTREACHED(); return false; } @@ -326,8 +501,33 @@ bool EnumTraits<MojomProvisioningStep, ProtoProvisioningStep>::FromMojom( MojomProvisioningStep step, ProtoProvisioningStep* out) { + switch (step) { + case MojomProvisioningStep::kInProgress: + *out = rmad::ProvisionDeviceState::RMAD_PROVISIONING_STEP_IN_PROGRESS; + return true; + case MojomProvisioningStep::kProvisioningComplete: + *out = rmad::ProvisionDeviceState::RMAD_PROVISIONING_STEP_COMPLETE; + return true; + case MojomProvisioningStep::kProvisioningUnknown: + NOTREACHED(); + return false; + } NOTREACHED(); return false; } +bool StructTraits<ash::shimless_rma::mojom::ComponentDataView, + rmad::ComponentRepairState>:: + Read(ash::shimless_rma::mojom::ComponentDataView data, + rmad::ComponentRepairState* out) { + rmad::ComponentRepairState_Component name; + rmad::ComponentRepairState_RepairState repair_state; + if (data.ReadComponent(&name) && data.ReadState(&repair_state)) { + out->set_name(name); + out->set_repair_state(repair_state); + return true; + } + return false; +} + } // namespace mojo
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h index 175b8e03..9e3b6895 100644 --- a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h +++ b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h
@@ -33,22 +33,22 @@ template <> struct EnumTraits<ash::shimless_rma::mojom::ComponentType, - rmad::ComponentRepairState::Component> { + rmad::ComponentRepairState_Component> { static ash::shimless_rma::mojom::ComponentType ToMojom( - rmad::ComponentRepairState::Component key_status); + rmad::ComponentRepairState_Component key_status); static bool FromMojom(ash::shimless_rma::mojom::ComponentType input, - rmad::ComponentRepairState::Component* out); + rmad::ComponentRepairState_Component* out); }; template <> struct EnumTraits<ash::shimless_rma::mojom::ComponentRepairState, - rmad::ComponentRepairState::RepairState> { + rmad::ComponentRepairState_RepairState> { static ash::shimless_rma::mojom::ComponentRepairState ToMojom( - rmad::ComponentRepairState::RepairState key_status); + rmad::ComponentRepairState_RepairState key_status); static bool FromMojom(ash::shimless_rma::mojom::ComponentRepairState input, - rmad::ComponentRepairState::RepairState* out); + rmad::ComponentRepairState_RepairState* out); }; template <> @@ -71,6 +71,25 @@ static bool FromMojom(ash::shimless_rma::mojom::ProvisioningStep input, rmad::ProvisionDeviceState::ProvisioningStep* out); }; + +template <> +class StructTraits<ash::shimless_rma::mojom::ComponentDataView, + rmad::ComponentRepairState> { + public: + static rmad::ComponentRepairState_Component component( + const rmad::ComponentRepairState& component) { + return component.name(); + } + + static rmad::ComponentRepairState_RepairState state( + const rmad::ComponentRepairState& component) { + return component.repair_state(); + } + + static bool Read(ash::shimless_rma::mojom::ComponentDataView data, + rmad::ComponentRepairState* out); +}; + } // namespace mojo #endif // ASH_WEBUI_SHIMLESS_RMA_MOJOM_SHIMLESS_RMA_MOJOM_TRAITS_H_
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits_unittest.cc b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits_unittest.cc index bcfe6eb..b7c42f3 100644 --- a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits_unittest.cc +++ b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits_unittest.cc
@@ -101,6 +101,7 @@ (mojo::EnumTraits<mojom::RmaState, rmad::RmadState::StateCase>::ToMojom( rmad::RmadState::STATE_NOT_SET))); TestProtoToMojo(enums); + TestMojoToProto(enums); } TEST_F(ShimlessRmaMojoToProtoTest, ErrorsMatch) { @@ -175,6 +176,7 @@ rmad::RmadErrorCode::RMAD_ERROR_CANNOT_CANCEL_RMA}}); TestProtoToMojo(enums); + TestMojoToProto(enums); } TEST_F(ShimlessRmaMojoToProtoTest, RepairComponentsMatch) { @@ -222,6 +224,7 @@ RMAD_CALIBRATION_COMPONENT_ACCELEROMETER}}); TestProtoToMojo(enums); + TestMojoToProto(enums); } TEST_F(ShimlessRmaMojoToProtoTest, ProvisioningStepsMatch) { @@ -234,6 +237,7 @@ rmad::ProvisionDeviceState::RMAD_PROVISIONING_STEP_COMPLETE}}); TestProtoToMojo(enums); + TestMojoToProto(enums); } } // namespace shimless_rma
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index ab29dc70..3228ec3 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -41,6 +41,7 @@ #include "base/check_op.h" #include "base/containers/contains.h" #include "base/containers/unique_ptr_adapters.h" +#include "base/i18n/number_formatting.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/notreached.h" @@ -914,7 +915,7 @@ } void DesksController::CreateAndActivateNewDeskForTemplate( - const std::u16string& desk_name, + const std::u16string& template_name, base::OnceCallback<void(bool)> callback) { if (!CanCreateDesks()) { std::move(callback).Run(/*success=*/false); @@ -926,6 +927,15 @@ if (animation_) animation_.reset(); + // Change the desk name if the current name already exists. + int count = 1; + std::u16string desk_name = template_name; + while (HasDeskWithName(desk_name)) { + desk_name = std::u16string(template_name) + .append(u" (" + base::FormatNumber(count) + u")"); + count++; + } + NewDesk(DesksCreationRemovalSource::kLaunchTemplate); Desk* desk = desks().back().get(); desk->SetName(desk_name, /*set_by_user=*/true); @@ -1027,6 +1037,14 @@ return iter != desks_.end(); } +bool DesksController::HasDeskWithName(const std::u16string& desk_name) const { + auto iter = std::find_if(desks_.begin(), desks_.end(), + [desk_name](const std::unique_ptr<Desk>& d) { + return d->name() == desk_name; + }); + return iter != desks_.end(); +} + void DesksController::ActivateDeskInternal(const Desk* desk, bool update_window_activation) { DCHECK(HasDesk(desk));
diff --git a/ash/wm/desks/desks_controller.h b/ash/wm/desks/desks_controller.h index cffae166..f0ae9de 100644 --- a/ash/wm/desks/desks_controller.h +++ b/ash/wm/desks/desks_controller.h
@@ -240,7 +240,7 @@ void SendToDeskAtIndex(aura::Window* window, int desk_index) override; std::unique_ptr<DeskTemplate> CaptureActiveDeskAsTemplate() const override; void CreateAndActivateNewDeskForTemplate( - const std::u16string& desk_name, + const std::u16string& template_name, base::OnceCallback<void(bool)> callback) override; // Updates the default names (e.g. "Desk 1", "Desk 2", ... etc.) given to the @@ -273,6 +273,8 @@ bool HasDesk(const Desk* desk) const; + bool HasDeskWithName(const std::u16string& desk_name) const; + // Activates the given |desk| and deactivates the currently active one. |desk| // has to be an existing desk. If |update_window_activation| is true, // the active desk on the deactivated desk will be deactivated, and the most-
diff --git a/ash/wm/full_restore/full_restore_controller.cc b/ash/wm/full_restore/full_restore_controller.cc index 40113c4..04d7997 100644 --- a/ash/wm/full_restore/full_restore_controller.cc +++ b/ash/wm/full_restore/full_restore_controller.cc
@@ -67,6 +67,12 @@ constexpr AppType kSupportedAppTypes[3] = { AppType::BROWSER, AppType::CHROME_APP, AppType::ARC_APP}; +// Delay for certain app types before activation is allowed. This is because +// some apps' client request activation after creation, which can break user +// flow. +constexpr base::TimeDelta kAllowActivationDelay = + base::TimeDelta::FromSeconds(2); + full_restore::WindowInfo* GetWindowInfo(aura::Window* window) { return window->GetProperty(full_restore::kWindowInfoKey); } @@ -234,6 +240,12 @@ tablet_mode_observation_.Reset(); } +void FullRestoreController::OnRestorePrefChanged(const AccountId& account_id, + bool could_restore) { + if (could_restore) + SaveAllWindows(); +} + void FullRestoreController::OnWidgetInitialized(views::Widget* widget) { DCHECK(widget); @@ -278,12 +290,6 @@ UpdateAndObserveWindow(window); } -void FullRestoreController::OnRestorePrefChanged(const AccountId& account_id, - bool could_restore) { - if (could_restore) - SaveAllWindows(); -} - void FullRestoreController::OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) { @@ -369,6 +375,10 @@ // window is first shown, which will be async for exo apps. if (WindowState::Get(window)->IsMinimized()) { window->SetProperty(full_restore::kLaunchedFromFullRestoreKey, false); + } else if (window->IsVisible()) { + // If the window is already visible, do not wait until it is next visible to + // restore the state type and clear the launched key. + RestoreStateTypeAndClearLaunchedKey(window); } else { to_be_shown_windows_.insert(window); @@ -484,8 +494,18 @@ restore_property_clear_callbacks_.emplace( window, base::BindOnce(&FullRestoreController::ClearLaunchedKey, weak_ptr_factory_.GetWeakPtr(), window)); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, restore_property_clear_callbacks_[window].callback()); + + // Also, for some ARC and chrome apps, the client can request activation after + // showing. We cannot detect this, so we use a timeout to keep the window not + // activatable for a while longer. + const AppType app_type = + static_cast<AppType>(window->GetProperty(aura::client::kAppType)); + const base::TimeDelta delay = + app_type == AppType::CHROME_APP || app_type == AppType::ARC_APP + ? kAllowActivationDelay + : base::TimeDelta(); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, restore_property_clear_callbacks_[window].callback(), delay); } void FullRestoreController::ClearLaunchedKey(aura::Window* window) {
diff --git a/ash/wm/full_restore/full_restore_controller.h b/ash/wm/full_restore/full_restore_controller.h index 5fb30b7..6ae4e20 100644 --- a/ash/wm/full_restore/full_restore_controller.h +++ b/ash/wm/full_restore/full_restore_controller.h
@@ -71,10 +71,10 @@ void OnTabletControllerDestroyed() override; // full_restore::FullRestoreInfo::Observer: - void OnWidgetInitialized(views::Widget* widget) override; - void OnARCTaskReadyForUnparentedWindow(aura::Window* window) override; void OnRestorePrefChanged(const AccountId& account_id, bool could_restore) override; + void OnWidgetInitialized(views::Widget* widget) override; + void OnARCTaskReadyForUnparentedWindow(aura::Window* window) override; // aura::WindowObserver: void OnWindowPropertyChanged(aura::Window* window,
diff --git a/base/allocator/partition_allocator/starscan/pcscan_internal.cc b/base/allocator/partition_allocator/starscan/pcscan_internal.cc index 08159a0..f9bd1eb 100644 --- a/base/allocator/partition_allocator/starscan/pcscan_internal.cc +++ b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
@@ -306,12 +306,18 @@ using SlotSpan = SlotSpanMetadata<ThreadSafe>; // Threshold for which bucket size it is worthwhile in checking whether the // object is a quarantined object and can be skipped. - static constexpr size_t kDefaultScanAreasReservation = 10; static constexpr size_t kLargeScanAreaThreshold = 8192; + static constexpr size_t kDefaultScanAreasReservation = 10; - // If the super page is empty, return nullopt. + SuperPageSnapshot snapshot; + snapshot.scan_areas_.reserve(kDefaultScanAreasReservation); + auto* extent_entry = PartitionSuperPageToExtent<ThreadSafe>( reinterpret_cast<char*>(super_page)); + + typename Root::ScopedGuard lock(extent_entry->root->lock_); + + // If the super page is empty, return nullopt. const size_t nonempty_slot_spans = extent_entry->number_of_nonempty_slot_spans; if (!nonempty_slot_spans) { @@ -323,11 +329,6 @@ return absl::nullopt; } - SuperPageSnapshot snapshot; - snapshot.scan_areas_.reserve(kDefaultScanAreasReservation); - - typename Root::ScopedGuard lock(extent_entry->root->lock_); - IterateNonEmptySlotSpans( super_page, nonempty_slot_spans, [&snapshot](SlotSpan* slot_span) { auto* payload_begin =
diff --git a/base/debug/stack_trace_android.cc b/base/debug/stack_trace_android.cc index c9a8b01..7a133b42 100644 --- a/base/debug/stack_trace_android.cc +++ b/base/debug/stack_trace_android.cc
@@ -12,7 +12,6 @@ #include <ostream> #include "base/debug/proc_maps_linux.h" -#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h"
diff --git a/base/enterprise_util_mac.mm b/base/enterprise_util_mac.mm index 8a63920..24e067b 100644 --- a/base/enterprise_util_mac.mm +++ b/base/enterprise_util_mac.mm
@@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/mac/foundation_util.h" #include "base/process/launch.h" -#include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h"
diff --git a/base/file_version_info_win.cc b/base/file_version_info_win.cc index 3be33272..adb7830 100644 --- a/base/file_version_info_win.cc +++ b/base/file_version_info_win.cc
@@ -12,7 +12,6 @@ #include "base/check.h" #include "base/files/file_path.h" #include "base/memory/ptr_util.h" -#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/threading/scoped_blocking_call.h" #include "base/win/resource_util.h"
diff --git a/base/memory/checked_ptr.md b/base/memory/checked_ptr.md index 4b054a3..73763818 100644 --- a/base/memory/checked_ptr.md +++ b/base/memory/checked_ptr.md
@@ -322,22 +322,9 @@ - Avoid accessing `S` from the destructor of `Bar` (and in general, avoid doing significant work from destructors). -#### Non-PA allocation address space reuse - -An address goes from the "outside GigaCage" state to "inside GigaCage" while a `CheckedPtr` is pointing at it. - -```cpp - CheckedPtr<void> checked_ptr = mmap([...]); - munmap(checked_ptr); // must be safe to keep checked_ptr alive since it's not going to be dereferenced - void* ptr = allocator.root()->Alloc(16, ""); // PA creates a new superpage, which is by coincidence around the address checked_ptr points to - checked_ptr = nullptr; -``` - -When this happens, it is like we skipped an `AddRef()` and `Release()` may decrement a non-existent ref count field. There is not enough address space to avoid the reuse on 32-bit platforms. In theory, we could store whether `CheckedPtr` pointed to a non-PA allocation during initialization and, therefore, should act like a no-op pointer, but we don't have a single spare bit in 32-bit pointers. - #### Past-the-end pointers with non-PA allocations -If we increment a `CheckedPtr` pointing at a non-PA allocation until it points past the end of the allocation, that pointer may happen to be pointing at the beginning of a PA superpage. Advancing the pointer through `operator+=()` assumes that the pointer stays within an allocation. So when this happens, it is as if we skipped an `AddRef()`, and `Release()` may decrement a non-existent ref count field. +Pointers past the end of an allocation are supported only if they point exactly to the end of the allocation. Anything beyond that runs into a risk of modifying ref-count of the next allocation, or in the rare case, confusing the ref-counting logic entirely when an allocation is on the border of GigaCage. This could lead to obscure, hard to debug crashes. #### Pointers to address in another process
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index f8e1889..b2abd434 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -989,7 +989,8 @@ DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); DCHECK(queue->IsQueueEnabled()); // Only schedule DoWork if there's something to do. - if (queue->HasTaskToRunImmediately() && !queue->BlockedByFence()) + if (queue->HasTaskToRunImmediatelyOrReadyDelayedTask() && + !queue->BlockedByFence()) ScheduleWork(); }
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index 182553e9..ddaf1c6 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -744,13 +744,14 @@ EXPECT_THAT(run_order, ElementsAre(2u, 1u, 3u)); } -TEST_P(SequenceManagerTest, HasPendingImmediateWork_ImmediateTask) { +TEST_P(SequenceManagerTest, + HasTaskToRunImmediatelyOrReadyDelayedTask_ImmediateTask) { auto queue = CreateTaskQueue(); std::vector<EnqueueOrder> run_order; - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); - EXPECT_TRUE(queue->HasTaskToRunImmediately()); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); // Move the task into the |immediate_work_queue|. EXPECT_TRUE(queue->GetTaskQueueImpl()->immediate_work_queue()->Empty()); @@ -759,31 +760,32 @@ voter->SetVoteToEnable(false); RunLoop().RunUntilIdle(); EXPECT_FALSE(queue->GetTaskQueueImpl()->immediate_work_queue()->Empty()); - EXPECT_TRUE(queue->HasTaskToRunImmediately()); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); // Run the task, making the queue empty. voter->SetVoteToEnable(true); RunLoop().RunUntilIdle(); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); } -TEST_P(SequenceManagerTest, HasPendingImmediateWork_DelayedTask) { +TEST_P(SequenceManagerTest, + HasTaskToRunImmediatelyOrReadyDelayedTask_DelayedTask) { auto queue = CreateTaskQueue(); std::vector<EnqueueOrder> run_order; TimeDelta delay(TimeDelta::FromMilliseconds(10)); queue->task_runner()->PostDelayedTask( FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); AdvanceMockTickClock(delay); - EXPECT_TRUE(queue->HasTaskToRunImmediately()); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); // Move the task into the |delayed_work_queue|. LazyNow lazy_now(mock_tick_clock()); sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now); sequence_manager()->ScheduleWork(); EXPECT_FALSE(queue->GetTaskQueueImpl()->delayed_work_queue()->Empty()); - EXPECT_TRUE(queue->HasTaskToRunImmediately()); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); // Run the task, making the queue empty. RunLoop().RunUntilIdle(); @@ -798,7 +800,7 @@ queue->task_runner()->PostDelayedTask( FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay); EXPECT_EQ(TimeDelta::FromMilliseconds(10), NextPendingTaskDelay()); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); EXPECT_TRUE(run_order.empty()); // The task doesn't run before the delay has completed. @@ -808,7 +810,7 @@ // After the delay has completed, the task runs normally. FastForwardBy(TimeDelta::FromMilliseconds(1)); EXPECT_THAT(run_order, ElementsAre(1u)); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); } TEST(SequenceManagerTestWithMockTaskRunner, @@ -1000,7 +1002,7 @@ RunLoop().RunUntilIdle(); // However polling still works. - EXPECT_TRUE(queue->HasTaskToRunImmediately()); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); // After removing the fence the task runs normally. queue->RemoveFence(); @@ -1794,40 +1796,43 @@ EXPECT_TRUE(sequence_manager()->GetAndClearSystemIsQuiescentBit()); } -TEST_P(SequenceManagerTest, HasPendingImmediateWork) { +TEST_P(SequenceManagerTest, HasTaskToRunImmediatelyOrReadyDelayedTask) { auto queue = CreateTaskQueue(); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); queue->task_runner()->PostTask(FROM_HERE, BindOnce(NullTask)); - EXPECT_TRUE(queue->HasTaskToRunImmediately()); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); RunLoop().RunUntilIdle(); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); } -TEST_P(SequenceManagerTest, HasPendingImmediateWork_DelayedTasks) { +TEST_P(SequenceManagerTest, + HasTaskToRunImmediatelyOrReadyDelayedTask_DelayedTasks) { auto queue = CreateTaskQueue(); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(NullTask), TimeDelta::FromMilliseconds(12)); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); // Move time forwards until just before the delayed task should run. AdvanceMockTickClock(TimeDelta::FromMilliseconds(10)); LazyNow lazy_now_1(mock_tick_clock()); sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now_1); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); // Force the delayed task onto the work queue. AdvanceMockTickClock(TimeDelta::FromMilliseconds(2)); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); + LazyNow lazy_now_2(mock_tick_clock()); sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now_2); - EXPECT_TRUE(queue->HasTaskToRunImmediately()); + EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); sequence_manager()->ScheduleWork(); RunLoop().RunUntilIdle(); - EXPECT_FALSE(queue->HasTaskToRunImmediately()); + EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask()); } TEST_P(SequenceManagerTest, ImmediateTasksAreNotStarvedByDelayedTasks) {
diff --git a/base/task/sequence_manager/task_queue.cc b/base/task/sequence_manager/task_queue.cc index 94a134b..a4b8170 100644 --- a/base/task/sequence_manager/task_queue.cc +++ b/base/task/sequence_manager/task_queue.cc
@@ -228,11 +228,11 @@ return impl_->GetNumberOfPendingTasks(); } -bool TaskQueue::HasTaskToRunImmediately() const { +bool TaskQueue::HasTaskToRunImmediatelyOrReadyDelayedTask() const { DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); if (!impl_) return false; - return impl_->HasTaskToRunImmediately(); + return impl_->HasTaskToRunImmediatelyOrReadyDelayedTask(); } absl::optional<TimeTicks> TaskQueue::GetNextScheduledWakeUp() {
diff --git a/base/task/sequence_manager/task_queue.h b/base/task/sequence_manager/task_queue.h index 933ef41..c9d57d2 100644 --- a/base/task/sequence_manager/task_queue.h +++ b/base/task/sequence_manager/task_queue.h
@@ -240,9 +240,10 @@ // Returns the number of pending tasks in the queue. size_t GetNumberOfPendingTasks() const; - // Returns true if the queue has work that's ready to execute now. + // Returns true iff this queue has immediate tasks or delayed tasks that are + // ripe for execution. Ignores the queue's enabled state and fences. // NOTE: this must be called on the thread this TaskQueue was created by. - bool HasTaskToRunImmediately() const; + bool HasTaskToRunImmediatelyOrReadyDelayedTask() const; // Returns requested run time of next scheduled wake-up for a delayed task // which is not ready to run. If there are no such tasks (immediate tasks
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc index 6bad341..741dc8f 100644 --- a/base/task/sequence_manager/task_queue_impl.cc +++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -513,7 +513,7 @@ return task_count; } -bool TaskQueueImpl::HasTaskToRunImmediately() const { +bool TaskQueueImpl::HasTaskToRunImmediatelyOrReadyDelayedTask() const { // Any work queue tasks count as immediate work. if (!main_thread_only().delayed_work_queue->Empty() || !main_thread_only().immediate_work_queue->Empty()) { @@ -964,7 +964,7 @@ { base::internal::CheckedAutoLock lock(any_thread_lock_); UpdateCrossThreadQueueStateLocked(); - has_pending_immediate_work = HasPendingImmediateWorkLocked(); + has_pending_immediate_work = HasTaskToRunImmediatelyLocked(); // Copy over the task-reporting related state. any_thread_.tracing_only.is_enabled = enabled; @@ -1128,7 +1128,7 @@ main_thread_only().scheduled_wake_up = wake_up; if (wake_up && main_thread_only().task_queue_observer && - !HasPendingImmediateWork()) { + !HasTaskToRunImmediately()) { main_thread_only().task_queue_observer->OnQueueNextWakeUpChanged( wake_up->time); } @@ -1143,7 +1143,7 @@ UpdateDelayedWakeUpImpl(&lazy_now, wake_up); } -bool TaskQueueImpl::HasPendingImmediateWork() { +bool TaskQueueImpl::HasTaskToRunImmediately() const { // Any work queue tasks count as immediate work. if (!main_thread_only().delayed_work_queue->Empty() || !main_thread_only().immediate_work_queue->Empty()) { @@ -1155,7 +1155,7 @@ return !any_thread_.immediate_incoming_queue.empty(); } -bool TaskQueueImpl::HasPendingImmediateWorkLocked() { +bool TaskQueueImpl::HasTaskToRunImmediatelyLocked() const { return !main_thread_only().delayed_work_queue->Empty() || !main_thread_only().immediate_work_queue->Empty() || !any_thread_.immediate_incoming_queue.empty();
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h index cdb0c3b..4da4798 100644 --- a/base/task/sequence_manager/task_queue_impl.h +++ b/base/task/sequence_manager/task_queue_impl.h
@@ -111,7 +111,7 @@ void SetShouldReportPostedTasksWhenDisabled(bool should_report); bool IsEmpty() const; size_t GetNumberOfPendingTasks() const; - bool HasTaskToRunImmediately() const; + bool HasTaskToRunImmediatelyOrReadyDelayedTask() const; absl::optional<TimeTicks> GetNextScheduledWakeUp(); void SetQueuePriority(TaskQueue::QueuePriority priority); TaskQueue::QueuePriority GetQueuePriority() const; @@ -153,10 +153,13 @@ bool was_blocked_or_low_priority); void NotifyDidProcessTask(const Task& task); - // Check for available tasks in immediate work queues. - // Used to check if we need to generate notifications about delayed work. - bool HasPendingImmediateWork(); - bool HasPendingImmediateWorkLocked() + // Returns true iff this queue has work that can execute now, i.e. immediate + // tasks or delayed tasks that have been transferred to the work queue by + // MoveReadyDelayedTasksToWorkQueue(). Delayed tasks that are still in the + // incoming queue are not taken into account. Ignores the queue's enabled + // state and fences. + bool HasTaskToRunImmediately() const; + bool HasTaskToRunImmediatelyLocked() const EXCLUSIVE_LOCKS_REQUIRED(any_thread_lock_); bool has_pending_high_resolution_tasks() const {
diff --git a/base/values.cc b/base/values.cc index 9edb5ad..cbe40c6 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -1423,25 +1423,6 @@ return true; } -bool DictionaryValue::RemovePath(StringPiece path, - std::unique_ptr<Value>* out_value) { - bool result = false; - size_t delimiter_position = path.find('.'); - - if (delimiter_position == std::string::npos) - return RemoveWithoutPathExpansion(path, out_value); - - StringPiece subdict_path = path.substr(0, delimiter_position); - DictionaryValue* subdict = nullptr; - if (!GetDictionary(subdict_path, &subdict)) - return false; - result = subdict->RemovePath(path.substr(delimiter_position + 1), out_value); - if (result && subdict->DictEmpty()) - RemoveKey(subdict_path); - - return result; -} - std::unique_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren() const { std::unique_ptr<DictionaryValue> copy =
diff --git a/base/values.h b/base/values.h index c67a522a..33424506 100644 --- a/base/values.h +++ b/base/values.h
@@ -774,14 +774,6 @@ bool RemoveWithoutPathExpansion(StringPiece key, std::unique_ptr<Value>* out_value); - // Removes a path, clearing out all dictionaries on `path` that remain empty - // after removing the value at `path`. - // DEPRECATED, use `Value::RemovePath(path)` or `Value::ExtractPath(path)` - // instead. - bool RemovePath(StringPiece path, std::unique_ptr<Value>* out_value); - - using Value::RemovePath; // DictionaryValue::RemovePath shadows otherwise. - // Makes a copy of `this` but doesn't include empty dictionaries and lists in // the copy. This never returns NULL, even if `this` itself is empty. std::unique_ptr<DictionaryValue> DeepCopyWithoutEmptyChildren() const; @@ -839,10 +831,6 @@ // DEPRECATED, use `GetList()::size()` instead. size_t GetSize() const { return list().size(); } - // Returns whether the list is empty. - // DEPRECATED, use `GetList()::empty()` instead. - bool empty() const { return list().empty(); } - // Sets the list item at the given index to be the Value specified by // the value given. If the index beyond the current end of the list, null // Values will be used to pad out the list.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index ac43417..96bcc3a 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -1639,31 +1639,6 @@ EXPECT_EQ(Value::Type::NONE, value4->type()); } -TEST(ValuesTest, DictionaryRemovePath) { - DictionaryValue dict; - dict.SetInteger("a.long.way.down", 1); - dict.SetBoolean("a.long.key.path", true); - - std::unique_ptr<Value> removed_item; - EXPECT_TRUE(dict.RemovePath("a.long.way.down", &removed_item)); - ASSERT_TRUE(removed_item); - EXPECT_TRUE(removed_item->is_int()); - EXPECT_FALSE(dict.HasKey("a.long.way.down")); - EXPECT_FALSE(dict.HasKey("a.long.way")); - EXPECT_TRUE(dict.Get("a.long.key.path", nullptr)); - - removed_item.reset(); - EXPECT_FALSE(dict.RemovePath("a.long.way.down", &removed_item)); - EXPECT_FALSE(removed_item); - EXPECT_TRUE(dict.Get("a.long.key.path", nullptr)); - - removed_item.reset(); - EXPECT_TRUE(dict.RemovePath("a.long.key.path", &removed_item)); - ASSERT_TRUE(removed_item); - EXPECT_TRUE(removed_item->is_bool()); - EXPECT_TRUE(dict.DictEmpty()); -} - TEST(ValuesTest, DeepCopy) { DictionaryValue original_dict; Value* null_weak = original_dict.SetKey("null", Value());
diff --git a/base/win/embedded_i18n/language_selector.cc b/base/win/embedded_i18n/language_selector.cc index 08d589ac..57e95ab 100644 --- a/base/win/embedded_i18n/language_selector.cc +++ b/base/win/embedded_i18n/language_selector.cc
@@ -13,7 +13,6 @@ #include <functional> #include "base/check_op.h" -#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/win/i18n.h"
diff --git a/base/win/embedded_i18n/language_selector_unittest.cc b/base/win/embedded_i18n/language_selector_unittest.cc index c22edbf..240fc04 100644 --- a/base/win/embedded_i18n/language_selector_unittest.cc +++ b/base/win/embedded_i18n/language_selector_unittest.cc
@@ -6,7 +6,6 @@ #include <tuple> #include <vector> -#include "base/stl_util.h" #include "base/test/gtest_util.h" #include "base/win/embedded_i18n/language_selector.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/win/scoped_safearray_unittest.cc b/base/win/scoped_safearray_unittest.cc index dc6c5e0..48d181a 100644 --- a/base/win/scoped_safearray_unittest.cc +++ b/base/win/scoped_safearray_unittest.cc
@@ -9,7 +9,6 @@ #include <array> #include <vector> -#include "base/stl_util.h" #include "base/test/gtest_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/base/win/variant_vector_unittest.cc b/base/win/variant_vector_unittest.cc index f72adbc9..eaff4849 100644 --- a/base/win/variant_vector_unittest.cc +++ b/base/win/variant_vector_unittest.cc
@@ -8,7 +8,6 @@ #include <windows.foundation.h> #include <wrl/client.h> -#include "base/stl_util.h" #include "base/test/gtest_util.h" #include "base/win/dispatch_stub.h" #include "base/win/scoped_safearray.h"
diff --git a/base/win/windows_types.h b/base/win/windows_types.h index 414c8be..971dfdd 100644 --- a/base/win/windows_types.h +++ b/base/win/windows_types.h
@@ -108,6 +108,7 @@ typedef struct _GUID GUID; typedef GUID CLSID; +typedef GUID IID; typedef struct tagLOGFONTW LOGFONTW, *PLOGFONTW, *NPLOGFONTW, *LPLOGFONTW; typedef LOGFONTW LOGFONT;
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index d8ad10ab..aa15b23 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -5.20210708.1.1 +5.20210708.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index c6e8b97..b5505723 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -5.20210708.0.1 +5.20210708.2.1
diff --git a/cc/paint/paint_filter.cc b/cc/paint/paint_filter.cc index 56de046..c332f7d 100644 --- a/cc/paint/paint_filter.cc +++ b/cc/paint/paint_filter.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/no_destructor.h" +#include "build/build_config.h" #include "cc/paint/filter_operations.h" #include "cc/paint/paint_image_builder.h" #include "cc/paint/paint_op_writer.h" @@ -25,6 +26,7 @@ namespace { const bool kHasNoDiscardableImages = false; +#if defined(OS_ANDROID) struct StretchShaderUniforms { // multiplier to apply to scale effect float uMaxStretchIntensity; @@ -235,6 +237,13 @@ static const float CONTENT_DISTANCE_STRETCHED = 1.f; static const float INTERPOLATION_STRENGTH_VALUE = 0.7f; +sk_sp<SkRuntimeEffect> getStretchEffect() { + static base::NoDestructor<SkRuntimeEffect::Result> effect( + SkRuntimeEffect::MakeForShader(SkString(kStretchShader))); + return effect->effect; +} +#endif + bool AreFiltersEqual(const PaintFilter* one, const PaintFilter* two) { if (!one || !two) return !one && !two; @@ -264,12 +273,6 @@ return filter->SnapshotWithImages(image_provider); } -sk_sp<SkRuntimeEffect> getStretchEffect() { - static base::NoDestructor<SkRuntimeEffect::Result> effect( - SkRuntimeEffect::MakeForShader(SkString(kStretchShader))); - return effect->effect; -} - } // namespace PaintFilter::PaintFilter(Type type, @@ -1560,6 +1563,7 @@ width_(width), height_(height), input_(std::move(input)) { +#if defined(OS_ANDROID) float normOverScrollDistX = stretch_x_; float normOverScrollDistY = stretch_y_; float distanceStretchedX = @@ -1590,6 +1594,11 @@ sk_sp<SkData> uniformVals = SkData::MakeWithCopy(&uniforms, sizeof(uniforms)); cached_sk_filter_ = SkMakeRuntimeImageFilter(getStretchEffect(), uniformVals, GetSkFilter(input_.get())); +#else // defined(OS_ANDROID) + // Stretch filter is only used on android and removed from other platforms + // to reduce size. See https://crbug.com/1226170. + NOTREACHED(); +#endif // defined(OS_ANDROID) } StretchPaintFilter::~StretchPaintFilter() = default;
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc index 5640d14..07f3476 100644 --- a/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -1088,6 +1088,22 @@ } } + std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::RasterContextProvider> worker_context_provider) + override { + // Since this test counts shared images and SkiaRenderer uses shared images + // for render passes, we need render pass allocation to be stable. + auto settings = renderer_settings; + settings.disable_render_pass_bypassing = true; + auto frame_sink = LayerTreeHostCopyRequestTest::CreateLayerTreeFrameSink( + settings, refresh_rate, std::move(compositor_context_provider), + std::move(worker_context_provider)); + return frame_sink; + } + void DisplayDidDrawAndSwapOnThread() override { auto* sii = display_context_provider_->SharedImageInterface(); switch (num_swaps_++) {
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index cbf2ef11..a512d73 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1327,7 +1327,6 @@ public_deps = [ "//build:branding_buildflags", "//build:chromeos_buildflags", - "//chrome/app:shutdown_signal_handlers", "//chrome/browser", "//chrome/browser/policy:path_parser", "//chrome/common",
diff --git a/chrome/VERSION b/chrome/VERSION index 0217f36..0816405 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=93 MINOR=0 -BUILD=4570 +BUILD=4571 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index d545a9dc..f35b30d 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1128,7 +1128,6 @@ "java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTabHelper.java", "java/src/org/chromium/chrome/browser/tab/RedirectHandlerTabHelper.java", "java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java", - "java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java", "java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java", "java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java", "java/src/org/chromium/chrome/browser/tab/TabBuilder.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 1ded99f..c02eef76 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -196,7 +196,6 @@ "junit/src/org/chromium/chrome/browser/survey/SurveyHttpClientBridgeUnitTest.java", "junit/src/org/chromium/chrome/browser/sync/AndroidSyncSettingsTest.java", "junit/src/org/chromium/chrome/browser/tab/HistoricalTabSaverUnitTest.java", - "junit/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java", "junit/src/org/chromium/chrome/browser/tab/TabAttributesTest.java", "junit/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelperTest.java", "junit/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelperTest.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java index f687adf..72d15e1 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java
@@ -42,6 +42,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto; @@ -115,6 +116,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1220426") public void backButtonWithSnackbarDestroysAutofillAssistantUi() throws Exception { ChromeTabUtils.loadUrlOnUiThread( mTestRule.getActivity().getActivityTab(), getURL(TEST_PAGE_B)); @@ -175,6 +177,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1220329") public void backButtonWithSettingsShowsErrorMessageAndDestroysAutofillAssistantUi() throws Exception { ChromeTabUtils.loadUrlOnUiThread(
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInterruptIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInterruptIntegrationTest.java index e4b4fc5..eb672c11 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInterruptIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInterruptIntegrationTest.java
@@ -35,6 +35,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantTestService.ScriptsReturnMode; import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; import org.chromium.chrome.browser.autofill_assistant.proto.AutofillFormatProto; @@ -118,6 +119,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1219553") public void testInterruptClicksElementDuringPrompt() throws Exception { ArrayList<AutofillAssistantTestScript> scripts = new ArrayList<>(); SelectorProto touch_area_one = toCssSelector("#touch_area_one"); @@ -220,6 +222,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1222969") public void testInterruptCicksElementDuringShowGenericUi() throws Exception { ArrayList<AutofillAssistantTestScript> scripts = new ArrayList<>(); SelectorProto touch_area_one = toCssSelector("#touch_area_one");
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java index c99dd97f..c2d0a13 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java
@@ -63,6 +63,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisableIf; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; @@ -908,6 +909,7 @@ */ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1219046") public void testCreateShippingAddressAndCreditCard() { ArrayList<ActionProto> list = new ArrayList<>(); list.add(ActionProto.newBuilder()
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index acd2185..cb3db409 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -1174,10 +1174,14 @@ } if (mMode == TabListMode.GRID && pseudoTab.hasRealTab() && !pseudoTab.isIncognito()) { - if (PriceTrackingUtilities.isTrackPricesOnTabsEnabled()) { + if (PriceTrackingUtilities.isTrackPricesOnTabsEnabled() + && isUngroupedTab(pseudoTab.getId())) { mModel.get(index).model.set(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER, new ShoppingPersistedTabDataFetcher( pseudoTab.getTab(), mPriceWelcomeMessageController)); + } else { + mModel.get(index).model.set( + TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER, null); } if (StoreTrackingUtilities.isStoreHoursOnTabsEnabled()) { mModel.get(index).model.set(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER, @@ -1200,6 +1204,11 @@ } } + @VisibleForTesting + public boolean isUngroupedTab(int tabId) { + return getRelatedTabsForId(tabId).size() == 1; + } + /** * @return The callback that hosts the logic for swipe and drag related actions. */
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index 13bf3ed..3fca32c 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -1061,6 +1061,97 @@ } @Test + public void testShoppingFetcherActiveForForUngroupedTabs() { + prepareForPriceDrop(); + resetWithRegularTabs(false); + + assertThat(mModel.size(), equalTo(2)); + assertThat(mModel.get(0).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER), + instanceOf(TabListMediator.ShoppingPersistedTabDataFetcher.class)); + assertThat(mModel.get(1).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER), + instanceOf(TabListMediator.ShoppingPersistedTabDataFetcher.class)); + } + + @Test + public void testShoppingFetcherInactiveForForGroupedTabs() { + prepareForPriceDrop(); + resetWithRegularTabs(true); + + assertThat(mModel.size(), equalTo(2)); + assertNull(mModel.get(0).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER)); + assertNull(mModel.get(1).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER)); + } + + @Test + public void testShoppingFetcherGroupedThenUngrouped() { + prepareForPriceDrop(); + resetWithRegularTabs(true); + + assertThat(mModel.size(), equalTo(2)); + assertNull(mModel.get(0).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER)); + assertNull(mModel.get(1).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER)); + resetWithRegularTabs(false); + assertThat(mModel.size(), equalTo(2)); + assertThat(mModel.get(0).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER), + instanceOf(TabListMediator.ShoppingPersistedTabDataFetcher.class)); + assertThat(mModel.get(1).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER), + instanceOf(TabListMediator.ShoppingPersistedTabDataFetcher.class)); + } + + @Test + public void testShoppingFetcherUngroupedThenGrouped() { + prepareForPriceDrop(); + resetWithRegularTabs(false); + + assertThat(mModel.size(), equalTo(2)); + assertThat(mModel.get(0).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER), + instanceOf(TabListMediator.ShoppingPersistedTabDataFetcher.class)); + assertThat(mModel.get(1).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER), + instanceOf(TabListMediator.ShoppingPersistedTabDataFetcher.class)); + resetWithRegularTabs(true); + assertThat(mModel.size(), equalTo(2)); + assertNull(mModel.get(0).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER)); + assertNull(mModel.get(1).model.get(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER)); + } + + /** + * Set flags and initialize for verifying price drop behavior + */ + private void prepareForPriceDrop() { + PriceTrackingUtilities.ENABLE_PRICE_TRACKING.setForTesting(true); + PriceTrackingUtilities.setIsSignedInAndSyncEnabledForTesting(true); + PersistedTabDataConfiguration.setUseTestConfig(true); + initAndAssertAllProperties(); + setUpForTabGroupOperation(TabListMediatorType.TAB_SWITCHER); + } + + /** + * Reset mediator with non-incognito tabs which are optionally grouped + * @param isGrouped true if the tabs should be grouped + */ + private void resetWithRegularTabs(boolean isGrouped) { + doReturn(mTab1).when(mTabModelFilter).getTabAt(0); + doReturn(mTab2).when(mTabModelFilter).getTabAt(1); + doReturn(2).when(mTabModelFilter).getCount(); + doReturn(mTabModelFilter).when(mTabModelFilterProvider).getCurrentTabModelFilter(); + if (isGrouped) { + doReturn(Arrays.asList(mTab1, mTab2)) + .when(mTabModelFilter) + .getRelatedTabList(eq(TAB1_ID)); + doReturn(Arrays.asList(mTab1, mTab2)) + .when(mTabModelFilter) + .getRelatedTabList(eq(TAB2_ID)); + } else { + doReturn(Arrays.asList(mTab1)).when(mTabModelFilter).getRelatedTabList(eq(TAB1_ID)); + doReturn(Arrays.asList(mTab2)).when(mTabModelFilter).getRelatedTabList(eq(TAB2_ID)); + } + List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); + doReturn(false).when(mTab1).isIncognito(); + doReturn(false).when(mTab2).isIncognito(); + mMediator.resetWithListOfTabs(PseudoTab.getListOfPseudoTab(tabs), false, false); + } + + @Test public void tabMoveOutOfGroup_Dialog() { setUpForTabGroupOperation(TabListMediatorType.TAB_GRID_DIALOG); @@ -1921,6 +2012,7 @@ for (boolean priceTrackingEnabled : new boolean[] {false, true}) { for (boolean incognito : new boolean[] {false, true}) { TabListMediator mMediatorSpy = spy(mMediator); + doReturn(true).when(mMediatorSpy).isUngroupedTab(anyInt()); PriceTrackingUtilities.setIsSignedInAndSyncEnabledForTesting( signedInAndSyncEnabled); PriceTrackingUtilities.SHARED_PREFERENCES_MANAGER.writeBoolean(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index 54ac527..b80068f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -23,7 +23,6 @@ import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil; import org.chromium.chrome.browser.tasks.tab_management.PriceTrackingUtilities; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; -import org.chromium.chrome.browser.toolbar.adaptive.AdaptiveToolbarFeatures; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import java.util.ArrayList; @@ -66,7 +65,6 @@ // clang-format off List<String> featuresToCache = Arrays.asList( - ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, ChromeFeatureList.ANDROID_PARTNER_CUSTOMIZATION_PHENOTYPE, ChromeFeatureList.APP_MENU_MOBILE_SITE_OPTION, ChromeFeatureList.APP_TO_WEB_ATTRIBUTION, @@ -109,7 +107,6 @@ // clang-format off List<CachedFieldTrialParameter> fieldTrialsToCache = Arrays.asList( - AdaptiveToolbarFeatures.MODE_PARAM, ChimeFeatures.ALWAYS_REGISTER, ConditionalTabStripUtils.CONDITIONAL_TAB_STRIP_INFOBAR_LIMIT, ConditionalTabStripUtils.CONDITIONAL_TAB_STRIP_INFOBAR_PERIOD,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index 399f951..8e5be450 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -101,7 +101,7 @@ private static final String LENS_SUPPORT_STATUS_HISTOGRAM_NAME = "ContextMenu.LensSupportStatus"; private static final String SHARED_HIGHLIGHTING_SUPPORT_URL = - "https://support.google.com/chrome?=shared_highlighting"; + "https://support.google.com/chrome?p=shared_highlighting"; // True when the tracker indicates IPH in the form of "new" label needs to be shown. private Boolean mShowEphemeralTabNewLabel;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java index 2192dcb..892be09 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
@@ -36,6 +36,8 @@ static final String RELATED_SEARCHES_LANGUAGE_ALLOWLIST_PARAM_NAME = "language_allowlist"; private static final String RELATED_SEARCHES_CONFIG_STAMP_PARAM_NAME = "stamp"; + static final String RELATED_SEARCHES_SHOW_DEFAULT_QUERY_CHIP_PARAM_NAME = "default_query_chip"; + // Deprecated. private static final int MANDATORY_PROMO_DEFAULT_LIMIT = 10; @@ -306,6 +308,18 @@ ChromeFeatureList.RELATED_SEARCHES, relatedSearchesParamName, false); } + static boolean showDefaultChipInBar() { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.RELATED_SEARCHES_IN_BAR, + RELATED_SEARCHES_SHOW_DEFAULT_QUERY_CHIP_PARAM_NAME, false); + } + + static boolean showDefaultChipInPanel() { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.RELATED_SEARCHES_ALTERNATE_UX, + RELATED_SEARCHES_SHOW_DEFAULT_QUERY_CHIP_PARAM_NAME, false); + } + // -------------------------------------------------------------------------------------------- // Helpers. // --------------------------------------------------------------------------------------------
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 3deca439..a1b3b299 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -83,6 +83,7 @@ import org.chromium.ui.touch_selection.SelectionEventType; import org.chromium.url.GURL; +import java.util.ArrayList; import java.util.List; /** @@ -827,14 +828,20 @@ || !TextUtils.isEmpty(resolvedSearchTerm.thumbnailUrl()); assert mSearchPanel != null; - List<String> inBarRelatedSearches = - ChromeFeatureList.isEnabled(ChromeFeatureList.RELATED_SEARCHES_IN_BAR) - ? mRelatedSearches.getQueries(true) - : null; - List<String> inPanelRelatedSearches = - ChromeFeatureList.isEnabled(ChromeFeatureList.RELATED_SEARCHES_ALTERNATE_UX) - ? mRelatedSearches.getQueries(false) - : null; + // If there was an error, fall back onto a literal search for the selection. + // Since we're showing the panel, there must be a selection. + String searchTerm = resolvedSearchTerm.searchTerm(); + String alternateTerm = resolvedSearchTerm.alternateTerm(); + boolean doPreventPreload = resolvedSearchTerm.doPreventPreload(); + if (doLiteralSearch) { + searchTerm = mSelectionController.getSelectedText(); + alternateTerm = null; + doPreventPreload = true; + } + + List<String> inBarRelatedSearches = buildRelatedSearches(true, searchTerm); + List<String> inPanelRelatedSearches = buildRelatedSearches(false, searchTerm); + mSearchPanel.onSearchTermResolved(message, resolvedSearchTerm.thumbnailUrl(), resolvedSearchTerm.quickActionUri(), resolvedSearchTerm.quickActionCategory(), resolvedSearchTerm.cardTagEnum(), inBarRelatedSearches, inPanelRelatedSearches); @@ -864,16 +871,6 @@ mSearchPanel.getPanelMetrics().setWasQuickActionShown( quickActionShown, resolvedSearchTerm.quickActionCategory()); - // If there was an error, fall back onto a literal search for the selection. - // Since we're showing the panel, there must be a selection. - String searchTerm = resolvedSearchTerm.searchTerm(); - String alternateTerm = resolvedSearchTerm.alternateTerm(); - boolean doPreventPreload = resolvedSearchTerm.doPreventPreload(); - if (doLiteralSearch) { - searchTerm = mSelectionController.getSelectedText(); - alternateTerm = null; - doPreventPreload = true; - } if (!TextUtils.isEmpty(searchTerm)) { // TODO(donnd): Instead of preloading, we should prefetch (ie the URL should not // appear in the user's history until the user views it). See crbug.com/406446. @@ -1393,18 +1390,36 @@ @Override public void onRelatedSearchesSuggestionClicked(int suggestionIndex, boolean isInBarSuggestion) { - assert suggestionIndex < mRelatedSearches.getQueries(isInBarSuggestion).size(); + boolean showDefaultSearch = isInBarSuggestion + ? ContextualSearchFieldTrial.showDefaultChipInBar() + : ContextualSearchFieldTrial.showDefaultChipInPanel(); + int defaultSearchAdjustment = showDefaultSearch ? 1 : 0; + assert (suggestionIndex - defaultSearchAdjustment) + < mRelatedSearches.getQueries(isInBarSuggestion).size(); + if (isInBarSuggestion) mSearchPanel.expandPanel(StateChangeReason.CLICK); - // TODO(donnd): Does the index reflect the default query? See https://crbug.com/1216593. - String searchQuery = mRelatedSearches.getQueries(isInBarSuggestion).get(suggestionIndex); - Uri searchUri = mRelatedSearches.getSearchUri(suggestionIndex, isInBarSuggestion); - if (searchUri != null) { - mSearchRequest = new ContextualSearchRequest(searchUri); + if (showDefaultSearch && suggestionIndex == 0) { + // Click on the default query + mSearchRequest = new ContextualSearchRequest(mResolvedSearchTerm.searchTerm(), + mResolvedSearchTerm.alternateTerm(), mResolvedSearchTerm.mid(), + false /* isLowPriorityEnabled */, mResolvedSearchTerm.searchUrlFull(), + mResolvedSearchTerm.searchUrlPreload()); + mSearchPanel.setSearchTerm(mResolvedSearchTerm.searchTerm()); + mIsRelatedSearchesSerp = false; } else { - mSearchRequest = new ContextualSearchRequest(searchQuery); + String searchQuery = mRelatedSearches.getQueries(isInBarSuggestion) + .get(suggestionIndex - defaultSearchAdjustment); + Uri searchUri = mRelatedSearches.getSearchUri( + suggestionIndex - defaultSearchAdjustment, isInBarSuggestion); + if (searchUri != null) { + mSearchRequest = new ContextualSearchRequest(searchUri); + } else { + mSearchRequest = new ContextualSearchRequest(searchQuery); + } + mSearchPanel.setSearchTerm(searchQuery); + mIsRelatedSearchesSerp = true; } - mSearchPanel.setSearchTerm(searchQuery); - mIsRelatedSearchesSerp = true; + // TODO(donnd): determine what to show in the Caption, if anything. loadSearchUrl(); @@ -2001,6 +2016,37 @@ } } + /** + * Build the searches suggestions for the Bar or Panel. + * @param isInBarSuggestion Whether the query was displayed in the Bar or content area of the + * Panel. + * @param defaultSearch The resolved search term.. + * @return A {@code List<String>} of search suggestions in the bar or the Panel, or {@code null} + * if the feature for showing chips is not enabled. + */ + private @Nullable List<String> buildRelatedSearches( + boolean isInBarSuggestion, String defaultSearch) { + if (!ChromeFeatureList.isEnabled(isInBarSuggestion + ? ChromeFeatureList.RELATED_SEARCHES_IN_BAR + : ChromeFeatureList.RELATED_SEARCHES_ALTERNATE_UX)) { + return null; + } + + List<String> queries = mRelatedSearches.getQueries(isInBarSuggestion); + boolean showDefaultSearch = isInBarSuggestion + ? ContextualSearchFieldTrial.showDefaultChipInBar() + : ContextualSearchFieldTrial.showDefaultChipInPanel(); + if (!showDefaultSearch || queries.size() == 0) { + return queries; + } + + List<String> relatedSearches = new ArrayList<String>(queries.size() + 1); + relatedSearches.add(defaultSearch); + relatedSearches.addAll(queries); + + return relatedSearches; + } + // ============================================================================================ // Test helpers // ============================================================================================
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java index bf60927..9fc70cc7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java
@@ -135,6 +135,14 @@ } /** + * Returns true if reader mode prompt should be displayed as a message. Otherwise it will be + * displayed as an infobar. + */ + public static boolean useMessagesForReaderModePrompt() { + return ChromeFeatureList.isEnabled(ChromeFeatureList.MESSAGES_FOR_ANDROID_READER_MODE); + } + + /** * Set an InterceptNavigationDelegate on a WebContents. * @param delegate The navigation delegate. * @param webContents The WebContents to bind the delegate to.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java index 3538e595..85121f4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
@@ -6,6 +6,7 @@ import android.app.Activity; import android.content.Intent; +import android.content.res.Resources; import android.net.Uri; import android.os.SystemClock; @@ -20,6 +21,7 @@ import org.chromium.base.SysUtils; import org.chromium.base.UserData; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.chrome.R; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager; import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider.CustomTabsUiType; @@ -39,6 +41,12 @@ import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabUtils; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; +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.MessageScopeType; import org.chromium.components.navigation_interception.InterceptNavigationDelegate; import org.chromium.content_public.browser.LoadCommittedDetails; import org.chromium.content_public.browser.LoadUrlParams; @@ -48,6 +56,7 @@ import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.util.ColorUtils; import org.chromium.url.GURL; @@ -123,15 +132,19 @@ private boolean mIsDestroyed; /** The tab this manager is attached to. */ - private Tab mTab; + private final Tab mTab; + + /** The MessageDispatcher to display the message. */ + private final MessageDispatcher mMessageDispatcher; // Hold on to the InterceptNavigationDelegate that the custom tab uses. InterceptNavigationDelegate mCustomTabNavigationDelegate; - ReaderModeManager(Tab tab) { + ReaderModeManager(Tab tab, MessageDispatcher messageDispatcher) { super(); mTab = tab; mTab.addObserver(this); + mMessageDispatcher = messageDispatcher; } /** @@ -139,7 +152,11 @@ * @param tab The tab that will have a manager instance attached to it. */ public static void createForTab(Tab tab) { - tab.getUserDataHost().setUserData(USER_DATA_KEY, new ReaderModeManager(tab)); + MessageDispatcher messageDispatcher = + MessageDispatcherProvider.from(tab.getWindowAndroid()); + + tab.getUserDataHost().setUserData( + USER_DATA_KEY, new ReaderModeManager(tab, messageDispatcher)); } /** @@ -211,7 +228,7 @@ if (mWebContentsObserver == null && mTab.getWebContents() != null) { mWebContentsObserver = createWebContentsObserver(); } - tryShowingInfoBar(); + tryShowingPrompt(); } @Override @@ -366,7 +383,7 @@ } mReaderModePageUrl = null; - if (mDistillationStatus == DistillationStatus.POSSIBLE) tryShowingInfoBar(); + if (mDistillationStatus == DistillationStatus.POSSIBLE) tryShowingPrompt(); } @Override @@ -399,9 +416,9 @@ RecordHistogram.recordLongTimesHistogram("DomDistiller.Time.ViewingReaderModePage", timeMs); } - /** Try showing the reader mode infobar. */ + /** Try showing the reader mode prompt. */ @VisibleForTesting - void tryShowingInfoBar() { + void tryShowingPrompt() { if (mTab == null || mTab.getWebContents() == null) return; // Test if the user is requesting the desktop site. Ignore this if distiller is set to @@ -415,7 +432,36 @@ return; } - ReaderModeInfoBar.showReaderModeInfoBar(mTab); + if (mMessageDispatcher != null && DomDistillerTabUtils.useMessagesForReaderModePrompt()) { + showReaderModeMessage(); + } else { + ReaderModeInfoBar.showReaderModeInfoBar(mTab); + } + } + + private void showReaderModeMessage() { + Resources resources = mTab.getContext().getResources(); + PropertyModel message = + new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS) + .with(MessageBannerProperties.MESSAGE_IDENTIFIER, + MessageIdentifier.READER_MODE) + .with(MessageBannerProperties.TITLE, + resources.getString(R.string.reader_mode_message_title)) + .with(MessageBannerProperties.ICON_RESOURCE_ID, + R.drawable.infobar_mobile_friendly) + .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, + resources.getString(R.string.reader_mode_message_button)) + .with(MessageBannerProperties.ON_PRIMARY_ACTION, this::activateReaderMode) + .with(MessageBannerProperties.ON_DISMISSED, this::onMessageDismissed) + .build(); + mMessageDispatcher.enqueueMessage( + message, mTab.getWebContents(), MessageScopeType.NAVIGATION, false); + } + + private void onMessageDismissed(@DismissReason int dismissReason) { + if (dismissReason == DismissReason.GESTURE) { + onClosed(); + } } public void activateReaderMode() { @@ -524,7 +570,7 @@ && !(isMobileOptimized && DomDistillerTabUtils.shouldExcludeMobileFriendly(tabToObserve))) { mDistillationStatus = DistillationStatus.POSSIBLE; - tryShowingInfoBar(); + tryShowingPrompt(); } else { mDistillationStatus = DistillationStatus.NOT_POSSIBLE; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java index ad2b53b..ca8b0557 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java
@@ -206,18 +206,10 @@ } private static boolean isFeatureEnabled() { - if (AdaptiveToolbarFeatures.isSingleVariantModeEnabled()) { - return AdaptiveToolbarFeatures.getSingleVariantMode() - == AdaptiveToolbarButtonVariant.SHARE; - } else { - // For customization, we do not check the variant here, AdaptiveToolbarButtonController - // will check it by AdaptiveToolbarStatePredictor#recomputeUiState. We do not check here - // because AdaptiveToolbarStatePredictor#recomputeUiState depends on native - // initialization, to avoid race condition, we only check at one place, which is - // AdaptiveToolbarButtonController. - return ChromeFeatureList.isEnabled(ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR) - || AdaptiveToolbarFeatures.isCustomizationEnabled(); - } + return (AdaptiveToolbarFeatures.isSingleVariantModeEnabled() + && AdaptiveToolbarFeatures.getSingleVariantMode() + == AdaptiveToolbarButtonVariant.SHARE) + || AdaptiveToolbarFeatures.isCustomizationEnabled(); } private void notifyObservers(boolean hint) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 40e0caa..d1cf2513 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -742,8 +742,7 @@ adaptiveToolbarButtonController.addButtonVariant( AdaptiveToolbarButtonVariant.VOICE, voiceToolbarButtonController); mButtonDataProviders = - Arrays.asList(mIdentityDiscController, adaptiveToolbarButtonController, - shareButtonController, voiceToolbarButtonController); + Arrays.asList(mIdentityDiscController, adaptiveToolbarButtonController); mToolbarManager = new ToolbarManager(mActivity, mBrowserControlsManager, mActivity.getFullscreenManager(), toolbarContainer, mActivity.getCompositorViewHolder(), urlFocusChangedCallback,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java index 758a612b..88c4345 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java
@@ -10,11 +10,8 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import android.view.View; - import androidx.preference.CheckBoxPreference; import androidx.preference.PreferenceScreen; -import androidx.test.filters.LargeTest; import androidx.test.filters.SmallTest; import org.junit.After; @@ -27,21 +24,16 @@ import org.chromium.base.CollectionUtil; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataFragment.DialogOption; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.settings.SettingsActivityTestRule; import org.chromium.chrome.browser.sync.SyncService; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.ChromeRenderTestRule; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.components.sync.ModelType; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import java.io.IOException; import java.util.HashSet; /** @@ -65,10 +57,6 @@ @Rule public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule(); - @Rule - public ChromeRenderTestRule mRenderTestRule = - ChromeRenderTestRule.Builder.withPublicCorpus().build(); - private static final String GOOGLE_ACCOUNT = "Google Account"; private static final String OTHER_ACTIVITY = "other forms of browsing history"; private static final String SYNCED_DEVICES = "synced devices"; @@ -185,45 +173,4 @@ assertThat(historySummary, containsString(SYNCED_DEVICES)); }); } - - @Test - @LargeTest - @Feature({"RenderTest"}) - @DisableFeatures(ChromeFeatureList.SEARCH_HISTORY_LINK) - public void testRenderNotSignedIn() throws IOException { - mSettingsActivityTestRule.startSettingsActivity(); - View view = mSettingsActivityTestRule.getActivity() - .findViewById(android.R.id.content) - .getRootView(); - mRenderTestRule.render(view, "clear_browsing_data_basic_signed_out"); - } - - @Test - @LargeTest - @Feature({"RenderTest"}) - @DisableFeatures(ChromeFeatureList.SEARCH_HISTORY_LINK) - public void testRenderSignedInNotSyncing() throws IOException { - mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync(); - // Simulate that Sync was stopped but the primary account remained. - setSyncable(false); - mSettingsActivityTestRule.startSettingsActivity(); - View view = mSettingsActivityTestRule.getActivity() - .findViewById(android.R.id.content) - .getRootView(); - mRenderTestRule.render(view, "clear_browsing_data_basic_signed_in_no_sync"); - } - - @Test - @LargeTest - @Feature({"RenderTest"}) - @DisableFeatures(ChromeFeatureList.SEARCH_HISTORY_LINK) - public void testRenderSignedInAndSyncing() throws IOException { - mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync(); - setSyncable(true); - mSettingsActivityTestRule.startSettingsActivity(); - View view = mSettingsActivityTestRule.getActivity() - .findViewById(android.R.id.content) - .getRootView(); - mRenderTestRule.render(view, "clear_browsing_data_basic_signed_in_sync"); - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index d39b830..8966fba 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -3975,6 +3975,38 @@ // TODO(donnd): Validate UMA metrics once we log in-bar selections. } + @Test + @SmallTest + @Feature({"ContextualSearch"}) + public void testRelatedSearchesInBarWithDefaultQuery() throws Exception { + FeatureList.TestValues testValues = new FeatureList.TestValues(); + testValues.setFeatureFlagsOverride(ENABLE_RELATED_SEARCHES_IN_BAR); + testValues.addFieldTrialParamOverride(ChromeFeatureList.RELATED_SEARCHES_IN_BAR, + ContextualSearchFieldTrial.RELATED_SEARCHES_SHOW_DEFAULT_QUERY_CHIP_PARAM_NAME, + "true"); + FeatureList.setTestValues(testValues); + mFakeServer.reset(); + + FakeResolveSearch fakeSearch = simulateResolveSearch("intelligence"); + ResolvedSearchTerm resolvedSearchTerm = fakeSearch.getResolvedSearchTerm(); + Assert.assertTrue("Related Searches results should have been returned but were not!", + !resolvedSearchTerm.relatedSearchesJson().isEmpty()); + // Select a chip in the Bar, which should expand the panel. + final int chipToSelect = 0; + TestThreadUtils.runOnUiThreadBlocking( + () -> mPanel.getRelatedSearchesInBarControl().selectChipForTest(chipToSelect)); + waitForPanelToExpand(); + + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat( + mPanel.getSearchBarControl().getSearchTerm(), Matchers.is("Intelligence")); + }); + + // Close the panel + closePanel(); + // TODO(donnd): Validate UMA metrics once we log in-bar selections. + } + // -------------------------------------------------------------------------------------------- // Forced Caption Feature tests. // --------------------------------------------------------------------------------------------
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerPhoneTest.java index 4a74a91..1ab0847b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerPhoneTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerPhoneTest.java
@@ -43,7 +43,6 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; import org.chromium.chrome.test.util.ActivityTestUtils; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiDisableIf; @@ -55,7 +54,6 @@ */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) -@EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "enable-features=" + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR + "<Study", "force-fieldtrials=Study/Group", "force-fieldtrial-params=Study.Group:mode/always-new-tab"}) @@ -177,6 +175,8 @@ @MediumTest public void testButton_hidesOnNTP() { sActivityTestRule.loadUrl(mTestPageUrl, /*secondsToWait=*/10); + TestThreadUtils.runOnUiThreadBlocking( + () -> sActivityTestRule.getActivity().getActivityTab().reload()); onViewWaiting(allOf(withId(R.id.optional_toolbar_button), isDisplayed(), isEnabled(), withContentDescription(mButtonDescription)));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeSmokeTest.java b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeSmokeTest.java index 2ac8c91..be02f81 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeSmokeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeSmokeTest.java
@@ -19,7 +19,6 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.test.pagecontroller.rules.ChromeUiApplicationTestRule; import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator; import org.chromium.chrome.test.pagecontroller.utils.Ui2Locators; @@ -44,7 +43,6 @@ } @Test - @FlakyTest(message = "crbug.com/1107896") public void testHello() { Context context = InstrumentationRegistry.getContext(); final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(DATA_URL));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java index 9605caa..c3040d7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java
@@ -5,13 +5,18 @@ package org.chromium.chrome.browser.dom_distiller; import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import androidx.test.core.app.ApplicationProvider; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; @@ -24,12 +29,16 @@ import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.dom_distiller.ReaderModeManager.DistillationStatus; import org.chromium.chrome.browser.dom_distiller.TabDistillabilityProvider.DistillabilityObserver; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.infobar.ReaderModeInfoBar; import org.chromium.chrome.browser.infobar.ReaderModeInfoBarJni; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtilsJni; +import org.chromium.components.messages.MessageDispatcher; +import org.chromium.components.messages.MessageScopeType; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; import org.chromium.content_public.browser.NavigationHandle; @@ -50,6 +59,9 @@ @Rule public JniMocker jniMocker = new JniMocker(); + @Rule + public final TestRule mFeatureProcessor = new Features.JUnitProcessor(); + @Mock private Tab mTab; @@ -74,6 +86,9 @@ @Mock private NavigationHandle mNavigationHandle; + @Mock + private MessageDispatcher mMessageDispatcher; + @Captor private ArgumentCaptor<TabObserver> mTabObserverCaptor; private TabObserver mTabObserver; @@ -105,6 +120,7 @@ when(mTab.getUserDataHost()).thenReturn(mUserDataHost); when(mTab.getWebContents()).thenReturn(mWebContents); when(mTab.getUrl()).thenReturn(MOCK_URL); + when(mTab.getContext()).thenReturn(ApplicationProvider.getApplicationContext()); when(mWebContents.getNavigationController()).thenReturn(mNavController); when(mNavController.getUseDesktopUserAgent()).thenReturn(false); @@ -114,7 +130,7 @@ when(DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(MOCK_DISTILLER_URL)) .thenReturn(MOCK_URL); - mManager = new ReaderModeManager(mTab); + mManager = new ReaderModeManager(mTab, mMessageDispatcher); // Ensure the tab observer is attached when the manager is created. verify(mTab).addObserver(mTabObserverCaptor.capture()); @@ -132,11 +148,26 @@ @Test @Feature("ReaderMode") - public void testUI_triggered() { + @Features.DisableFeatures({ChromeFeatureList.MESSAGES_FOR_ANDROID_READER_MODE}) + public void testUI_triggered_infobar() { mDistillabilityObserver.onIsPageDistillableResult(mTab, true, true, false); assertEquals("Distillation should be possible.", DistillationStatus.POSSIBLE, mManager.getDistillationStatus()); verify(mReaderModeInfobarJniMock).create(mTab); + verifyNoMoreInteractions(mMessageDispatcher); + } + + @Test + @Feature("ReaderMode") + @Features.EnableFeatures({ChromeFeatureList.MESSAGES_FOR_ANDROID_READER_MODE}) + public void testUI_triggered_messages() { + mDistillabilityObserver.onIsPageDistillableResult(mTab, true, true, false); + assertEquals("Distillation should be possible.", DistillationStatus.POSSIBLE, + mManager.getDistillationStatus()); + verify(mMessageDispatcher) + .enqueueMessage( + any(), eq(mWebContents), eq(MessageScopeType.NAVIGATION), eq(false)); + verifyNoMoreInteractions(mReaderModeInfobarJniMock); } @Test @@ -146,6 +177,7 @@ assertEquals("Distillation should not be possible.", DistillationStatus.NOT_POSSIBLE, mManager.getDistillationStatus()); verifyNoMoreInteractions(mReaderModeInfobarJniMock); + verifyNoMoreInteractions(mMessageDispatcher); } @Test @@ -162,12 +194,13 @@ @Test @Feature("ReaderMode") + @Features.DisableFeatures({ChromeFeatureList.MESSAGES_FOR_ANDROID_READER_MODE}) public void testUI_notTriggered_afterDismiss() { mDistillabilityObserver.onIsPageDistillableResult(mTab, true, true, false); verify(mReaderModeInfobarJniMock).create(mTab); mManager.onClosed(); - mManager.tryShowingInfoBar(); + mManager.tryShowingPrompt(); verifyNoMoreInteractions(mReaderModeInfobarJniMock); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerActivityTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerActivityTest.java index f1e8ddf..5cc05cf 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerActivityTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerActivityTest.java
@@ -18,6 +18,7 @@ import androidx.test.filters.MediumTest; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,7 +32,6 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.tab.MockTab; @@ -49,7 +49,9 @@ import org.chromium.url.JUnitTestGURLs; import org.chromium.url.ShadowGURL; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; /** @@ -57,6 +59,7 @@ * ChromeTabbedActivity}. */ @Config(shadows = {OptionalNewTabButtonControllerActivityTest.ShadowDelegate.class, + OptionalNewTabButtonControllerActivityTest.ShadowChromeFeatureList.class, ShadowGURL.class}) @RunWith(BaseRobolectricTestRunner.class) public class OptionalNewTabButtonControllerActivityTest { @@ -85,6 +88,27 @@ } } + // TODO(crbug.com/1199025): Remove this shadow. + @Implements(ChromeFeatureList.class) + static class ShadowChromeFeatureList { + private static final Map<String, String> sParamValues = new HashMap<>(); + + @Implementation + public static String getFieldTrialParamByFeature(String feature, String paramKey) { + Assert.assertTrue(ChromeFeatureList.isEnabled(feature)); + return sParamValues.getOrDefault(paramKey, ""); + } + + @Implementation + public static boolean isEnabled(String featureName) { + return featureName.equals(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR); + } + + public static void reset() { + sParamValues.clear(); + } + } + private ActivityScenario<ChromeTabbedActivity> mActivityScenario; private AdaptiveToolbarButtonController mAdaptiveButtonController; private MockTab mTab; @@ -95,8 +119,7 @@ resetStaticState(); CommandLine.getInstance().appendSwitch(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE); CommandLine.getInstance().appendSwitch(ChromeSwitches.DISABLE_NATIVE_INITIALIZATION); - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, true); - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_NEW_TAB); + ShadowChromeFeatureList.sParamValues.put("mode", AdaptiveToolbarFeatures.ALWAYS_NEW_TAB); MockTabModelSelector tabModelSelector = new MockTabModelSelector( /*tabCount=*/1, /*incognitoTabCount=*/0, (id, incognito) -> { @@ -114,6 +137,7 @@ mActivityScenario = ActivityScenario.launch(ChromeTabbedActivity.class); mActivityScenario.onActivity(activity -> { mAdaptiveButtonController = getAdaptiveButton(getOptionalButtonController(activity)); + mAdaptiveButtonController.onFinishNativeInitialization(); }); } @@ -125,6 +149,7 @@ private static void resetStaticState() { ShadowDelegate.reset(); + ShadowChromeFeatureList.reset(); // DisplayAndroidManager will reuse the Display between tests. This can cause // AsyncInitializationActivity#applyOverrides to set incorrect smallestWidth. DisplayAndroidManager.resetInstanceForTesting();
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 9ae049251..dd5fd693 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -25,17 +25,6 @@ ] } -# TODO: put back in chrome/browser if necessary. http://crbug.com/771801. -source_set("shutdown_signal_handlers") { - if (is_posix || is_fuchsia) { - sources = [ - "shutdown_signal_handlers_posix.cc", - "shutdown_signal_handlers_posix.h", - ] - } - deps = [ "//base" ] -} - # On Windows, links chrome_dll.rc. On other platforms, does nothing so you can # unconditionally depend on it. source_set("chrome_dll_resources") { @@ -126,7 +115,6 @@ deps = [ "//base", "//build:chromeos_buildflags", - "//chrome/app:shutdown_signal_handlers", "//chrome/browser", "//chrome/browser/policy:path_parser", "//chrome/child",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 8d41d06..a3f4c28 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -1643,6 +1643,10 @@ desc="Download page message: Server problem."> Unknown server error. Please try again, or contact the server administrator. </message> + <message name="IDS_DOWNLOAD_INTERRUPTED_DESCRIPTION_WEB_DRIVE_ERROR" + desc="Download page message: Upload failed."> + <ph name="WEB_DRIVE_MESSAGE">$1<ex>Storage limit reached.</ex></ph> (<ph name="SUPPORT_INFO">$2<ex>Request ID 12345</ex></ph>) + </message> <message name="IDS_DOWNLOAD_INTERRUPTED_STATUS_SHUTDOWN" desc="Shutdown."> Shutdown @@ -1773,6 +1777,15 @@ <message name="IDS_DOWNLOAD_STATUS_REMOVED" desc="Text that appears under the downloaded files that have been removed."> Removed </message> + <message name="IDS_DOWNLOAD_STATUS_UPLOADING" desc="Status text for a download item that is being uploaded."> + Sending to <ph name="WEB_DRIVE">$1<ex>Google Drive</ex></ph> + </message> + <message name="IDS_DOWNLOAD_STATUS_UPLOADED" desc="Status text for a download item that has been uploaded."> + Saved to <ph name="WEB_DRIVE">$1<ex>Google Drive</ex></ph> + </message> + <message name="IDS_DOWNLOAD_STATUS_UPLOAD_INTERRUPTED" desc="Status text for a download item that was interrupted during reroute upload."> + Failed to save to <ph name="WEB_DRIVE">$1<ex>Google Drive</ex></ph> - <ph name="INTERRUPT_REASON">$2<ex>Disk full</ex></ph> + </message> <message name="IDS_DOWNLOAD_STATUS_INTERRUPTED" desc="Status text for a download item that was interrupted."> Failed - <ph name="INTERRUPT_REASON">$1<ex>Disk full</ex></ph> </message> @@ -5806,6 +5819,9 @@ <message name="IDS_NTP_MODULES_CART_SENTENCE" desc="Name of the chrome cart module in sentence case shown in various UIs."> Your carts </message> + <message name="IDS_NTP_MODULES_CART_SENTENCE_V2" desc="Name of the chrome cart module V2 in sentence case shown in various UIs."> + In your shopping cart + </message> <message name="IDS_NTP_MODULES_CART_LOWER" desc="Name of the chrome cart module in lowercase shown in various UIs."> carts </message> @@ -11357,6 +11373,14 @@ Open now </message> + <!-- Enterprise file system connector service providers' display names --> + <message name="IDS_FILE_SYSTEM_CONNECTOR_BOX" meaning="box.com" desc="Display name for Box."> + Box + </message> + <message name="IDS_FILE_SYSTEM_CONNECTOR_GOOGLE_DRIVE" desc="Display name for Google Drive."> + Google Drive + </message> + <!-- App uninstall prompt title --> <message name="IDS_PROMPT_APP_UNINSTALL_TITLE" desc="Title text for uninstalling an app."> Uninstall "<ph name="APP_NAME">$1<ex>Gmail Checker</ex></ph>"?
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_INTERRUPTED_DESCRIPTION_WEB_DRIVE_ERROR.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_INTERRUPTED_DESCRIPTION_WEB_DRIVE_ERROR.png.sha1 new file mode 100644 index 0000000..63e952c --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_INTERRUPTED_DESCRIPTION_WEB_DRIVE_ERROR.png.sha1
@@ -0,0 +1 @@ +09f8df5eb7512cdf02fffb88303df2dedd8ff009 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOADED.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOADED.png.sha1 new file mode 100644 index 0000000..25c1bb6 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOADED.png.sha1
@@ -0,0 +1 @@ +2ebb50b84eb0e8e50ed15c782676293f6cc3f2f4 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOADING.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOADING.png.sha1 new file mode 100644 index 0000000..621c95f --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOADING.png.sha1
@@ -0,0 +1 @@ +b0bdd1c702b8052abd314b0c76b5f61fdd29cc34 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOAD_INTERRUPTED.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOAD_INTERRUPTED.png.sha1 new file mode 100644 index 0000000..cfe47eb --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_STATUS_UPLOAD_INTERRUPTED.png.sha1
@@ -0,0 +1 @@ +01f4a0929a5bf2e14c870fa4e768443473063be6 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FILE_SYSTEM_CONNECTOR_BOX.png.sha1 b/chrome/app/generated_resources_grd/IDS_FILE_SYSTEM_CONNECTOR_BOX.png.sha1 new file mode 100644 index 0000000..25c1bb6 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_FILE_SYSTEM_CONNECTOR_BOX.png.sha1
@@ -0,0 +1 @@ +2ebb50b84eb0e8e50ed15c782676293f6cc3f2f4 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FILE_SYSTEM_CONNECTOR_GOOGLE_DRIVE.png.sha1 b/chrome/app/generated_resources_grd/IDS_FILE_SYSTEM_CONNECTOR_GOOGLE_DRIVE.png.sha1 new file mode 100644 index 0000000..709faea --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_FILE_SYSTEM_CONNECTOR_GOOGLE_DRIVE.png.sha1
@@ -0,0 +1 @@ +3ee8c53025da1388a68ac34e6180bf329241de93 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_CART_SENTENCE_V2.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_CART_SENTENCE_V2.png.sha1 new file mode 100644 index 0000000..e36c8c7 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_CART_SENTENCE_V2.png.sha1
@@ -0,0 +1 @@ +23207107d44ab78e0ced5cb975925a491069ab49 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index d306a16..2d95950f 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -3429,12 +3429,6 @@ <message name="IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE" desc="In Device Settings > Displays, the label of the option to set the automatic schedule of the Night Light feature to turn on at sunset and off at sunrise."> Sunset to sunrise </message> - <message name="IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_START_TIME" desc="In Device Settings > Displays, the label of the start time bubble."> - Start time - </message> - <message name="IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_STOP_TIME" desc="In Device Settings > Displays, the label of the end time bubble."> - End time - </message> <message name="IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT" desc="In Device Settings > Displays, text describing the Night Light feature."> Make it easier to look at your screen or read in dim light </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 0374ac5..024321c 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -228,8 +228,11 @@ <message name="IDS_SETTINGS_EDIT" desc="Label used on a menu item or button, used in different contexts to edit an item."> Edit </message> + <message name="IDS_SETTINGS_END_TIME" desc="The label of the end time bubble of settings-scheduler-slider"> + End time + </message> <message name="IDS_SETTINGS_NOT_VALID" desc="Text indicating that an input is not valid."> - Not valid + Not valid </message> <message name="IDS_SETTINGS_NOT_VALID_WEB_ADDRESS" desc="Text indicating that the Web address entered by the user is invalid." > Not a valid web address @@ -238,11 +241,14 @@ Origin must be secure </message> <message name="IDS_SETTINGS_RETRY" desc="The label text of the retry button because there is an error."> - Retry + Retry </message> <message name="IDS_SETTINGS_SLIDER_MIN_MAX_ARIA_ROLE_DESCRIPTION" desc="A label to be read aloud by screen readers when a user focuses on a slider. A settings slider generally has a minimum value, a maximum value, and a fixed range of values in between. This label gives the user context for what the minimum and maximum values represent for that particular slider."> Slider: <ph name="MIN_LABEL">$1<ex>Slowest</ex></ph> to <ph name="MAX_LABEL">$2<ex>Fastest</ex></ph> </message> + <message name="IDS_SETTINGS_START_TIME" desc="The label of the start time bubble of settings-scheduler-slider"> + Start time + </message> <!-- Autofill Page --> <message name="IDS_SETTINGS_AUTOFILL" desc="Name of the settings page which allows managing passwords, payment methods and addresses settings.">
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_END_TIME.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_END_TIME.png.sha1 new file mode 100644 index 0000000..e150d47 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_END_TIME.png.sha1
@@ -0,0 +1 @@ +5b1d5700a12e4506a1ee7452b62d47e81d68dc95 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_START_TIME.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_START_TIME.png.sha1 new file mode 100644 index 0000000..e150d47 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_START_TIME.png.sha1
@@ -0,0 +1 @@ +5b1d5700a12e4506a1ee7452b62d47e81d68dc95 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 8440204d..d4faa4c5 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -78,9 +78,9 @@ "dwmapi.lib", "imm32.lib", # chrome_elf_init.cc "netapi32.lib", - "ndfapi.lib", # For browser / net / net_error_diagnostics_dialog_win.h - "pdh.lib", # For browser / private_working_set_snapshot.h - "wbemuuid.lib", # For browser / metrics / + "ndfapi.lib", # For browser/net/net_error_diagnostics_dialog_win.h + "pdh.lib", # For browser/private_working_set_snapshot.h + "wbemuuid.lib", # For browser/metrics / # antivirus_metrics_provider_win.cc ] ldflags = [ @@ -1866,6 +1866,7 @@ "//chrome/services/file_util/public/mojom", "//components/account_id", "//components/autofill/core/browser", + "//components/enterprise/common/proto:download_item_reroute_info_proto", "//components/nacl/common:buildflags", "//components/optimization_guide:machine_learning_tflite_buildflags", "//components/page_info", @@ -1885,6 +1886,7 @@ deps = [ ":active_use_util", ":availability_protos", + ":browser_process", ":buildflags", ":dev_ui_browser_resources_grit", ":expired_flags_list", @@ -1907,7 +1909,6 @@ "//chrome/app/resources:platform_locale_settings", "//chrome/app/theme:theme_resources", "//chrome/app/vector_icons", - "//chrome/browser:browser_process", "//chrome/browser/browsing_data:constants", "//chrome/browser/devtools", "//chrome/browser/image_decoder", @@ -3331,8 +3332,7 @@ "//components/safe_browsing/core/browser/password_protection:password_protection_metrics_util", "//components/security_state/content/android", "//components/send_tab_to_self", - "//components/signin/internal/identity_manager", # cf android / signin / - # DEPS + "//components/signin/internal/identity_manager", # cf android/signin/DEPS "//components/signin/public/android:jni_headers", "//components/subresource_filter/android", "//components/thin_webview/internal", @@ -4244,7 +4244,6 @@ "//components/accuracy_tips", "//components/constrained_window", "//components/enterprise/common/proto:device_trust_report_event_proto", - "//components/enterprise/common/proto:download_item_reroute_info_proto", "//components/feedback", "//components/feedback/content:factory", "//components/image_fetcher/core", @@ -5348,7 +5347,10 @@ } if (is_posix || is_fuchsia) { - deps += [ "//chrome/app:shutdown_signal_handlers" ] + sources += [ + "shutdown_signal_handlers_posix.cc", + "shutdown_signal_handlers_posix.h", + ] } if (is_win || is_mac) { @@ -5379,6 +5381,8 @@ if (is_win || is_chromeos_ash || is_mac) { sources += [ + "webshare/safe_browsing_request.cc", + "webshare/safe_browsing_request.h", "webshare/share_service_impl.cc", "webshare/share_service_impl.h", ] @@ -5498,7 +5502,7 @@ } if (is_posix && !is_mac) { - # TODO(crbug.com / 753619): Enable crash reporting on Fuchsia. + # TODO(crbug.com/753619): Enable crash reporting on Fuchsia. sources += [ "//chrome/app/chrome_crash_reporter_client.cc", "//chrome/app/chrome_crash_reporter_client.h", @@ -5549,8 +5553,8 @@ "media_galleries/fileapi/mtp_file_stream_reader.h", ] if (is_chromeos_ash && use_dbus) { - # TODO(donna.wu@intel.com): push this into chrome / browser / chromeos - # and chrome / browser / media_galleries / chromeos + # TODO(donna.wu@intel.com): push this into chrome/browser/chromeos + # and chrome/browser/media_galleries/chromeos deps += [ "//services/device/public/mojom" ] } } @@ -5671,7 +5675,10 @@ "printing/print_backend_service_manager.cc", "printing/print_backend_service_manager.h", ] - deps += [ "//chrome/services/printing/public/mojom" ] + deps += [ + "//chrome/services/printing/public/mojom", + "//components/crash/core/common", + ] } if (is_win || enable_print_preview) { deps += [ "//chrome/services/printing/public/mojom" ] @@ -6953,9 +6960,9 @@ "//chrome/browser/ui:test_support", ] deps = [ + ":browser_process", "//build:chromeos_buildflags", "//chrome/app/theme:theme_resources", - "//chrome/browser:browser_process", "//chrome/common", "//chrome/common/safe_browsing:proto", "//components/consent_auditor:test_support", @@ -7258,8 +7265,8 @@ deps = [ ":browser", + ":browser_process", "//chrome:browser_tests_pak", - "//chrome/browser:browser_process", "//chrome/browser/profiles:profile", "//chrome/common:mojo_bindings", "//chrome/test/data:web_ui_test_bindings",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d400e9a4..91bab064 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1641,6 +1641,30 @@ kOverridePrefsForHrefTranslateForceAuto, base::size(kOverridePrefsForHrefTranslateForceAuto), nullptr}}; +const FeatureEntry::FeatureParam + kOverrideUnsupportedPageLanguageForHrefTranslateForceAuto[] = { + {"force-auto-translate-for-unsupported-page-language", "true"}}; + +const FeatureEntry::FeatureVariation + kOverrideUnsupportedPageLanguageForHrefTranslateVariations[] = { + {"(Force automatic translation of pages with unknown language for " + "hrefTranslate)", + kOverrideUnsupportedPageLanguageForHrefTranslateForceAuto, + base::size(kOverrideUnsupportedPageLanguageForHrefTranslateForceAuto), + nullptr}}; + +const FeatureEntry::FeatureParam + kOverrideSimilarLanguagesForHrefTranslateForceAuto[] = { + {"force-auto-translate-for-similar-languages", "true"}}; + +const FeatureEntry::FeatureVariation + kOverrideSimilarLanguagesForHrefTranslateVariations[] = { + {"(Force automatic translation of pages with the same language as the " + "target language for hrefTranslate)", + kOverrideSimilarLanguagesForHrefTranslateForceAuto, + base::size(kOverrideSimilarLanguagesForHrefTranslateForceAuto), + nullptr}}; + #if defined(OS_ANDROID) const FeatureEntry::FeatureParam kExploreSitesExperimental = { chrome::android::explore_sites::kExploreSitesVariationParameterName, @@ -1681,6 +1705,28 @@ {"extreme", &kRelatedSearchesUiExtreme, 1, nullptr}, }; +const FeatureEntry::FeatureParam kRelatedSearchesInBarNoShowDefaultChip = { + "default_query_chip", "false"}; +const FeatureEntry::FeatureParam kRelatedSearchesInBarShowDefaultChip = { + "default_query_chip", "true"}; +const FeatureEntry::FeatureVariation kRelatedSearchesInBarVariations[] = { + {"without default query chip", &kRelatedSearchesInBarNoShowDefaultChip, 1, + nullptr}, + {"with default query chip", &kRelatedSearchesInBarShowDefaultChip, 1, + nullptr}, +}; + +const FeatureEntry::FeatureParam kRelatedSearchesAlternateUxNoShowDefaultChip = + {"default_query_chip", "false"}; +const FeatureEntry::FeatureParam kRelatedSearchesAlternateUxShowDefaultChip = { + "default_query_chip", "true"}; +const FeatureEntry::FeatureVariation kRelatedSearchesAlternateUxVariations[] = { + {"without default query chip", + &kRelatedSearchesAlternateUxNoShowDefaultChip, 1, nullptr}, + {"with default query chip", &kRelatedSearchesAlternateUxShowDefaultChip, 1, + nullptr}, +}; + #endif // defined(OS_ANDROID) const FeatureEntry::FeatureParam kResamplingInputEventsLSQEnabled[] = { @@ -2785,11 +2831,16 @@ "RelatedSearchesUi")}, {"related-searches-in-bar", flag_descriptions::kRelatedSearchesInBarName, flag_descriptions::kRelatedSearchesInBarDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kRelatedSearchesInBar)}, + FEATURE_WITH_PARAMS_VALUE_TYPE(chrome::android::kRelatedSearchesInBar, + kRelatedSearchesInBarVariations, + "RelatedSearchesInBar")}, {"related-searches-alternate-ux", flag_descriptions::kRelatedSearchesAlternateUxName, flag_descriptions::kRelatedSearchesAlternateUxDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kRelatedSearchesAlternateUx)}, + FEATURE_WITH_PARAMS_VALUE_TYPE( + chrome::android::kRelatedSearchesAlternateUx, + kRelatedSearchesAlternateUxVariations, + "RelatedSearchesAlternateUx")}, {"related-searches-simplified-ux", flag_descriptions::kRelatedSearchesSimplifiedUxName, flag_descriptions::kRelatedSearchesSimplifiedUxDescription, kOsAndroid, @@ -3314,6 +3365,23 @@ translate::kOverrideSitePrefsForHrefTranslate, kOverrideSitePrefsForHrefTranslateVariations, "OverrideSitePrefsForHrefTranslate")}, + {"override-unsupported-page-language-for-href-translate", + flag_descriptions::kOverrideUnsupportedPageLanguageForHrefTranslateName, + flag_descriptions:: + kOverrideUnsupportedPageLanguageForHrefTranslateDescription, + kOsAll, + FEATURE_WITH_PARAMS_VALUE_TYPE( + translate::kOverrideUnsupportedPageLanguageForHrefTranslate, + kOverrideUnsupportedPageLanguageForHrefTranslateVariations, + "OverrideUnsupportedPageLanguageForHrefTranslate")}, + {"override-similar-languages-for-href-translate", + flag_descriptions::kOverrideSimilarLanguagesForHrefTranslateName, + flag_descriptions::kOverrideSimilarLanguagesForHrefTranslateDescription, + kOsAll, + FEATURE_WITH_PARAMS_VALUE_TYPE( + translate::kOverrideSimilarLanguagesForHrefTranslate, + kOverrideSimilarLanguagesForHrefTranslateVariations, + "OverrideSimilarLanguagesForHrefTranslate")}, #if BUILDFLAG(ENABLE_SYSTEM_NOTIFICATIONS) && !BUILDFLAG(IS_CHROMEOS_ASH) {"enable-system-notifications", @@ -3603,6 +3671,10 @@ flag_descriptions::kDesktopPWAsWindowControlsOverlayDescription, kOsWin | kOsLinux | kOsMac, FEATURE_VALUE_TYPE(features::kWebAppWindowControlsOverlay)}, + {"enable-desktop-pwas-web-bundles", + flag_descriptions::kDesktopPWAsWebBundlesName, + flag_descriptions::kDesktopPWAsWebBundlesDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kDesktopPWAsWebBundles)}, {"record-web-app-debug-info", flag_descriptions::kRecordWebAppDebugInfoName, flag_descriptions::kRecordWebAppDebugInfoDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kRecordWebAppDebugInfo)}, @@ -3859,10 +3931,6 @@ kInterestFeedV2ClickAndViewActionsConditionalUploadDescription, kOsAndroid, FEATURE_VALUE_TYPE(feed::kInterestFeedV2ClicksAndViewsConditionalUpload)}, - {"interest-feed-notice-card-auto-dismiss", - flag_descriptions::kInterestFeedNoticeCardAutoDismissName, - flag_descriptions::kInterestFeedNoticeCardAutoDismissDescription, - kOsAndroid, FEATURE_VALUE_TYPE(feed::kInterestFeedNoticeCardAutoDismiss)}, #endif // OS_ANDROID {"PasswordImport", flag_descriptions::kPasswordImportName, flag_descriptions::kPasswordImportDescription, kOsAll, @@ -3915,6 +3983,10 @@ flag_descriptions::kImeAssistMultiWordName, flag_descriptions::kImeAssistMultiWordDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kAssistMultiWord)}, + {"enable-cros-ime-assist-multi-word-expanded", + flag_descriptions::kImeAssistMultiWordExpandedName, + flag_descriptions::kImeAssistMultiWordExpandedDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kAssistMultiWordExpanded)}, {"enable-cros-ime-assist-personal-info", flag_descriptions::kImeAssistPersonalInfoName, flag_descriptions::kImeAssistPersonalInfoDescription, kOsCrOS, @@ -6683,6 +6755,10 @@ flag_descriptions::kMessagesForAndroidPopupBlockedName, flag_descriptions::kMessagesForAndroidPopupBlockedDescription, kOsAndroid, FEATURE_VALUE_TYPE(messages::kMessagesForAndroidPopupBlocked)}, + {"messages-for-android-reader-mode", + flag_descriptions::kMessagesForAndroidReaderModeName, + flag_descriptions::kMessagesForAndroidReaderModeDescription, kOsAndroid, + FEATURE_VALUE_TYPE(messages::kMessagesForAndroidReaderMode)}, {"messages-for-android-safety-tip", flag_descriptions::kMessagesForAndroidSafetyTipName, flag_descriptions::kMessagesForAndroidSafetyTipDescription, kOsAndroid,
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc index 8a5edab5..2087c17 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.cc +++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -38,6 +38,8 @@ #include "chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h" +#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/ui/android/infobars/framebust_block_infobar.h" #include "chrome/browser/ui/android/tab_model/tab_model_list.h" @@ -153,6 +155,9 @@ content::WebContents* portal_contents) { WebContentsDelegateAndroid::PortalWebContentsCreated(portal_contents); + Profile* profile = + Profile::FromBrowserContext(portal_contents->GetBrowserContext()); + // This is a subset of the tab helpers that would be attached by // TabAndroid::AttachTabHelpers. // @@ -174,7 +179,10 @@ PrefsTabHelper::CreateForWebContents(portal_contents); DataReductionProxyTabHelper::CreateForWebContents(portal_contents); safe_browsing::SafeBrowsingNavigationObserver::MaybeCreateForWebContents( - portal_contents); + portal_contents, HostContentSettingsMapFactory::GetForProfile(profile), + safe_browsing::SafeBrowsingNavigationObserverManagerFactory:: + GetForBrowserContext(profile), + profile->GetPrefs(), g_browser_process->safe_browsing_service()); } void TabWebContentsDelegateAndroid::RunFileChooser(
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm index a78d458..4686e3ff 100644 --- a/chrome/browser/app_controller_mac_browsertest.mm +++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -82,6 +82,7 @@ #include "extensions/common/extension.h" #include "extensions/test/extension_test_message_listener.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "third_party/blink/public/common/features.h" #import "ui/events/test/cocoa_test_event_utils.h" #include "ui/views/test/dialog_test.h" #include "ui/views/widget/any_widget_observer.h" @@ -901,7 +902,10 @@ protected: StartupWebAppUrlHandlingBrowserTest() : test_web_app_provider_creator_(base::BindRepeating( - &StartupWebAppUrlHandlingBrowserTest::CreateTestWebAppProvider)) {} + &StartupWebAppUrlHandlingBrowserTest::CreateTestWebAppProvider)) { + scoped_feature_list_.InitAndEnableFeature( + blink::features::kWebAppEnableUrlHandlers); + } web_app::AppId InstallWebAppWithUrlHandlers( const std::vector<apps::UrlHandlerInfo>& url_handlers) { @@ -939,6 +943,7 @@ } web_app::TestWebAppProviderCreator test_web_app_provider_creator_; + base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(StartupWebAppUrlHandlingBrowserTest,
diff --git a/chrome/browser/apps/app_service/app_icon_factory_unittest.cc b/chrome/browser/apps/app_service/app_icon_factory_unittest.cc index 05b59b7..1f1459641 100644 --- a/chrome/browser/apps/app_service/app_icon_factory_unittest.cc +++ b/chrome/browser/apps/app_service/app_icon_factory_unittest.cc
@@ -535,7 +535,8 @@ std::unique_ptr<web_app::WebApp> CreateWebApp() { const GURL app_url("https://example.com/path"); - const std::string app_id = web_app::GenerateAppIdFromURL(app_url); + const std::string app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, app_url); auto web_app = std::make_unique<web_app::WebApp>(app_id); web_app->AddSource(web_app::Source::kSync);
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc index 701a711..8a827a6 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.cc +++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -485,6 +485,9 @@ return apps::mojom::OptionalBool::kFalse; case arc::mojom::ArcResizeLockState::UNDEFINED: case arc::mojom::ArcResizeLockState::READY: + // FULLY_LOCKED means the resize-lock-related features are not available + // including the resizability toggle in the app management page. + case arc::mojom::ArcResizeLockState::FULLY_LOCKED: return apps::mojom::OptionalBool::kUnknown; } }
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc index 3a7c7e3..92e98bd9 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -30,9 +30,9 @@ #include "chrome/browser/ash/arc/arc_web_contents_data.h" #include "chrome/browser/ash/child_accounts/time_limits/app_time_limit_interface.h" #include "chrome/browser/ash/crostini/crostini_util.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/extensions/gfx_utils.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/extensions/extension_util.h"
diff --git a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.cc b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.cc index 1d6bd3f..e05e9cf 100644 --- a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.cc +++ b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.cc
@@ -96,7 +96,8 @@ void WebKioskAppManager::AddAppForTesting(const AccountId& account_id, const GURL& install_url) { - const std::string app_id = web_app::GenerateAppIdFromURL(install_url); + const std::string app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, install_url); apps_.push_back(std::make_unique<WebKioskAppData>( this, app_id, account_id, install_url, /*title*/ std::string(), /*icon_url*/ GURL())); @@ -144,7 +145,8 @@ std::string title = account.web_kiosk_app_info.title(); GURL icon_url = GURL(account.web_kiosk_app_info.icon_url()); - std::string app_id = web_app::GenerateAppIdFromURL(url); + std::string app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, url); auto old_it = old_apps.find(app_id); if (old_it != old_apps.end()) {
diff --git a/chrome/browser/ash/apps/apk_web_app_service.cc b/chrome/browser/ash/apps/apk_web_app_service.cc index d3ef17c..8184d4f 100644 --- a/chrome/browser/ash/apps/apk_web_app_service.cc +++ b/chrome/browser/ash/apps/apk_web_app_service.cc
@@ -192,7 +192,8 @@ // Compute the current app id. It may have changed if the package has been // updated from an Android app to a web app, or vice versa. if (!package_info->web_app_info.is_null()) { - new_app_id = web_app::GenerateAppIdFromURL( + new_app_id = web_app::GenerateAppId( + /*manifest_id=*/absl::nullopt, GURL(package_info->web_app_info->start_url)); } else { // Get the first app in the package. If there are multiple apps in the
diff --git a/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc b/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc index 9876224..22357e1e 100644 --- a/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc +++ b/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc
@@ -14,8 +14,8 @@ #include "chrome/browser/apps/intent_helper/intent_picker_internal.h" #include "chrome/browser/ash/apps/intent_helper/ash_intent_picker_helpers.h" #include "chrome/browser/ash/apps/metrics/intent_handling_metrics.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" #include "chrome/browser/web_applications/components/web_app_helpers.h"
diff --git a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc index 117a049..1a65865 100644 --- a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc +++ b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -374,12 +374,6 @@ tree_tracker_.InvalidateTrees(); } -aura::Window* ArcAccessibilityHelperBridge::GetFocusedArcWindow() const { - if (!exo::WMHelper::HasInstance()) - return nullptr; - return FindArcWindow(exo::WMHelper::GetInstance()->GetFocusedWindow()); -} - extensions::EventRouter* ArcAccessibilityHelperBridge::GetEventRouter() const { return extensions::EventRouter::Get(profile_); }
diff --git a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.h b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.h index c5fba7a7..0ea81ea 100644 --- a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.h +++ b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.h
@@ -109,7 +109,6 @@ private: // virtual for testing. - virtual aura::Window* GetFocusedArcWindow() const; virtual extensions::EventRouter* GetEventRouter() const; virtual arc::mojom::AccessibilityFilterType GetFilterType();
diff --git a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc index 5b1a470..a05bd3d4 100644 --- a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc +++ b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc
@@ -32,8 +32,6 @@ #include "components/arc/arc_util.h" #include "components/arc/mojom/accessibility_helper.mojom.h" #include "components/arc/session/arc_bridge_service.h" -#include "components/exo/shell_surface.h" -#include "components/exo/shell_surface_util.h" #include "components/language/core/browser/pref_names.h" #include "components/live_caption/pref_names.h" #include "components/prefs/pref_registry_simple.h" @@ -41,8 +39,6 @@ #include "extensions/browser/event_router.h" #include "extensions/browser/test_event_router.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/window.h" #include "ui/display/display.h" #include "ui/display/manager/managed_display_info.h" #include "ui/message_center/public/cpp/notification.h" @@ -75,16 +71,12 @@ TestArcAccessibilityHelperBridge(content::BrowserContext* browser_context, ArcBridgeService* arc_bridge_service) : ArcAccessibilityHelperBridge(browser_context, arc_bridge_service), - window_(new aura::Window(nullptr)), event_router_( extensions::CreateAndUseTestEventRouter(browser_context)) { - window_->Init(ui::LAYER_NOT_DRAWN); - window_->SetProperty(aura::client::kAppType, - static_cast<int>(ash::AppType::ARC_APP)); event_router_->AddEventObserver(this); } - ~TestArcAccessibilityHelperBridge() override { window_.reset(); } + ~TestArcAccessibilityHelperBridge() override = default; int GetEventCount(const std::string& event_name) const { return event_router_->GetEventCount(event_name); @@ -97,15 +89,10 @@ void OnDispatchEventToExtension(const std::string& extension_id, const extensions::Event& event) override {} - std::unique_ptr<aura::Window> window_; std::unique_ptr<extensions::Event> last_event; private: // ArcAccessibilityHelperBridge overrides: - aura::Window* GetFocusedArcWindow() const override { - DCHECK(!window_ || ash::IsArcWindow(window_.get())); - return window_.get(); - } extensions::EventRouter* GetEventRouter() const override { return event_router_; }
diff --git a/chrome/browser/ash/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/ash/arc/intent_helper/arc_settings_service_browsertest.cc index 638684d..b8daae90 100644 --- a/chrome/browser/ash/arc/intent_helper/arc_settings_service_browsertest.cc +++ b/chrome/browser/ash/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -16,7 +16,7 @@ #include "base/run_loop.h" #include "base/task/current_thread.h" #include "base/values.h" -#include "chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h" +#include "chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/ash/arc/policy/arc_policy_util.cc b/chrome/browser/ash/arc/policy/arc_policy_util.cc index 2d4fffa61..c720bc6 100644 --- a/chrome/browser/ash/arc/policy/arc_policy_util.cc +++ b/chrome/browser/ash/arc/policy/arc_policy_util.cc
@@ -10,7 +10,7 @@ #include "base/command_line.h" #include "base/json/json_reader.h" #include "base/values.h" -#include "chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h" +#include "chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" #include "components/arc/arc_prefs.h"
diff --git a/chrome/browser/ash/arc/session/arc_session_manager.cc b/chrome/browser/ash/arc/session/arc_session_manager.cc index 9bd7f8e5..4d69550 100644 --- a/chrome/browser/ash/arc/session/arc_session_manager.cc +++ b/chrome/browser/ash/arc/session/arc_session_manager.cc
@@ -38,9 +38,9 @@ #include "chrome/browser/ash/arc/session/arc_provisioning_result.h" #include "chrome/browser/ash/login/demo_mode/demo_resources.h" #include "chrome/browser/ash/login/demo_mode/demo_session.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc index 531e99b2..39464e84 100644 --- a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc +++ b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
@@ -35,8 +35,8 @@ #include "chrome/browser/ash/arc/test/test_arc_session_manager.h" #include "chrome/browser/ash/login/ui/fake_login_display_host.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/prefs/pref_service_syncable_util.h"
diff --git a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc index d9f9c283..1ee3658 100644 --- a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc +++ b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc
@@ -47,7 +47,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" -using web_app::GenerateAppIdFromURL; +using web_app::GenerateAppId; using web_app::WebAppProviderBase; namespace ash { @@ -272,15 +272,17 @@ // Add extension app. It will be ignored, because PATL does not support // extensions (with exception of Chrome) now. - const AppId app2(apps::mojom::AppType::kExtension, - GenerateAppIdFromURL(GURL(kExtensionAppUrl))); + const AppId app2( + apps::mojom::AppType::kExtension, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kExtensionAppUrl))); EXPECT_CALL(test_listener(), OnAppInstalled(app2)).Times(1); SimulateAppInstalled(app2, kExtensionNameA, kExtensionAppUrl); // Add web app. - const AppId app3(apps::mojom::AppType::kWeb, - GenerateAppIdFromURL(GURL(kWebAppUrl1))); + const AppId app3( + apps::mojom::AppType::kWeb, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kWebAppUrl1))); EXPECT_CALL(test_listener(), OnAppInstalled(app3)).Times(1); SimulateAppInstalled(app3, kWebAppName1, kWebAppUrl1); @@ -302,14 +304,16 @@ EXPECT_CALL(test_listener(), OnAppInstalled(app1)).Times(1); SimulateAppInstalled(app1, kArcApp1); - const AppId app2(apps::mojom::AppType::kExtension, - GenerateAppIdFromURL(GURL(kExtensionAppUrl))); + const AppId app2( + apps::mojom::AppType::kExtension, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kExtensionAppUrl))); EXPECT_CALL(test_listener(), OnAppInstalled(app2)).Times(1); SimulateAppInstalled(app2, kExtensionNameA, kExtensionAppUrl); - const AppId app3(apps::mojom::AppType::kWeb, - GenerateAppIdFromURL(GURL(kWebAppUrl1))); + const AppId app3( + apps::mojom::AppType::kWeb, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kWebAppUrl1))); EXPECT_CALL(test_listener(), OnAppInstalled(app3)).Times(1); SimulateAppInstalled(app3, kWebAppName1, kWebAppUrl1); @@ -356,8 +360,9 @@ EXPECT_EQ(1u, tested_wrapper().GetInstalledApps().size()); // Install first web app. - const AppId app1(apps::mojom::AppType::kWeb, - GenerateAppIdFromURL(GURL(kWebAppUrl1))); + const AppId app1( + apps::mojom::AppType::kWeb, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kWebAppUrl1))); EXPECT_CALL(test_listener(), OnAppInstalled(app1)).Times(1); SimulateAppInstalled(app1, kWebAppName1, kWebAppUrl1); @@ -366,8 +371,9 @@ EXPECT_TRUE(base::Contains(installed_apps, app1)); // Install second web app. - const AppId app2(apps::mojom::AppType::kWeb, - GenerateAppIdFromURL(GURL(kWebAppUrl2))); + const AppId app2( + apps::mojom::AppType::kWeb, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kWebAppUrl2))); EXPECT_CALL(test_listener(), OnAppInstalled(app2)).Times(1); SimulateAppInstalled(app2, kWebAppName2, kWebAppUrl2); @@ -401,8 +407,9 @@ TEST_F(AppServiceWrapperTest, WebAppDisabled) { // Install web app. - const AppId app(apps::mojom::AppType::kWeb, - GenerateAppIdFromURL(GURL(kWebAppUrl1))); + const AppId app( + apps::mojom::AppType::kWeb, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kWebAppUrl1))); EXPECT_CALL(test_listener(), OnAppInstalled(app)).Times(1); SimulateAppInstalled(app, kWebAppName1, kWebAppUrl1); @@ -422,8 +429,9 @@ std::vector<AppId> installed_apps = tested_wrapper().GetInstalledApps(); EXPECT_TRUE(base::Contains(installed_apps, chrome)); - const AppId app1(apps::mojom::AppType::kExtension, - GenerateAppIdFromURL(GURL(kExtensionAppUrl))); + const AppId app1( + apps::mojom::AppType::kExtension, + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kExtensionAppUrl))); EXPECT_CALL(test_listener(), OnAppInstalled(app1)).Times(1); SimulateAppInstalled(app1, kExtensionNameA, kExtensionAppUrl);
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc index bbb5b2e..289f8bdd 100644 --- a/chrome/browser/ash/crosapi/browser_manager.cc +++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -458,6 +458,8 @@ // Ensure we're not trying to open a window before the shelf is initialized. DCHECK(ChromeShelfController::instance()); + // Always reset |relaunch_requested_| when launching Lacros. + relaunch_requested_ = false; SetState(State::CREATING_LOG_FILE); // TODO(ythjkt): After M92 cherry-pick, clean up the following code by moving @@ -664,6 +666,12 @@ browser_service_.reset(); } +void BrowserManager::OnBrowserRelaunchRequested(CrosapiId id) { + if (id != crosapi_id_) + return; + relaunch_requested_ = true; +} + void BrowserManager::OnMojoDisconnected() { DCHECK(state_ == State::STARTING || state_ == State::RUNNING); LOG(WARNING) @@ -688,6 +696,9 @@ // TODO(https://crbug.com/1109366): Restart lacros-chrome if it exits // abnormally (e.g. crashes). For now, assume the user meant to close it. SetLaunchOnLoginPref(false); + + if (relaunch_requested_) + Start(mojom::InitialBrowserAction::kRestoreLastSession); } void BrowserManager::OnSessionStateChanged() {
diff --git a/chrome/browser/ash/crosapi/browser_manager.h b/chrome/browser/ash/crosapi/browser_manager.h index e1b14cb..0a4360d8 100644 --- a/chrome/browser/ash/crosapi/browser_manager.h +++ b/chrome/browser/ash/crosapi/browser_manager.h
@@ -264,6 +264,7 @@ uint32_t browser_service_version) override; void OnBrowserServiceDisconnected(CrosapiId id, mojo::RemoteSetElementId mojo_id) override; + void OnBrowserRelaunchRequested(CrosapiId id) override; // Called when the Mojo connection to lacros-chrome is disconnected. // It may be "just a Mojo error" or "lacros-chrome crash". @@ -327,6 +328,10 @@ // Available during lacros-chrome is running. absl::optional<BrowserServiceInfo> browser_service_; + // Remembers the request from Lacros-chrome whether it needs to be + // relaunched. Reset on new process start in any cases. + bool relaunch_requested_ = false; + // Helps set up and manage the mojo connections between lacros-chrome and // ash-chrome in testing environment. Only applicable when // '--lacros-mojo-socket-for-testing' is present in the command line.
diff --git a/chrome/browser/ash/crosapi/browser_service_host_ash.cc b/chrome/browser/ash/crosapi/browser_service_host_ash.cc index a4ddbd6..dbd4a36 100644 --- a/chrome/browser/ash/crosapi/browser_service_host_ash.cc +++ b/chrome/browser/ash/crosapi/browser_service_host_ash.cc
@@ -76,6 +76,12 @@ observer.OnBrowserServiceConnected(id, mojo_id, service, version); } +void BrowserServiceHostAsh::RequestRelaunch() { + CrosapiId crosapi_id = receiver_set_.current_context(); + for (auto& observer : observer_list_) + observer.OnBrowserRelaunchRequested(crosapi_id); +} + void BrowserServiceHostAsh::OnDisconnected(mojo::RemoteSetElementId mojo_id) { auto it = crosapi_map_.find(mojo_id); if (it == crosapi_map_.end())
diff --git a/chrome/browser/ash/crosapi/browser_service_host_ash.h b/chrome/browser/ash/crosapi/browser_service_host_ash.h index 54c3686..a6d4e1b 100644 --- a/chrome/browser/ash/crosapi/browser_service_host_ash.h +++ b/chrome/browser/ash/crosapi/browser_service_host_ash.h
@@ -42,6 +42,7 @@ // crosapi::mojom::BrowserServiceHost void AddBrowserService( mojo::PendingRemote<mojom::BrowserService> remote) override; + void RequestRelaunch() override; private: void AddRemote(CrosapiId id, mojo::Remote<mojom::BrowserService> remote);
diff --git a/chrome/browser/ash/crosapi/browser_service_host_observer.h b/chrome/browser/ash/crosapi/browser_service_host_observer.h index 639f44f..9aa16b7 100644 --- a/chrome/browser/ash/crosapi/browser_service_host_observer.h +++ b/chrome/browser/ash/crosapi/browser_service_host_observer.h
@@ -29,6 +29,10 @@ // When this is called, mojom::BrowserService is already destroyed. virtual void OnBrowserServiceDisconnected(CrosapiId id, mojo::RemoteSetElementId mojo_id) {} + + // Called when BrowserServiceHost::RequestRelaunch is called from + // the Crosapi client. + virtual void OnBrowserRelaunchRequested(CrosapiId id) {} }; } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index 3a147a6..2e17267 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -83,6 +83,7 @@ #include "components/user_manager/user_type.h" #include "components/version_info/channel.h" #include "components/version_info/version_info.h" +#include "google_apis/gaia/gaia_auth_util.h" #include "media/capture/mojom/video_capture.mojom.h" #include "mojo/public/cpp/platform/platform_channel.h" #include "mojo/public/cpp/system/invitation.h" @@ -125,7 +126,25 @@ } } +// Returns true if the main profile is associated with a google internal +// account. +bool IsGoogleInternal() { + user_manager::UserManager* user_manager = user_manager::UserManager::Get(); + const user_manager::User* user = user_manager->GetPrimaryUser(); + if (!user) + return false; + return gaia::IsGoogleInternalAccountEmail( + user->GetAccountId().GetUserEmail()); +} + // Returns the lacros integration suggested by the policy lacros-availability. +// There are several reasons why we might choose to ignore the +// lacros-availability policy. +// 1. The user has set a command line or chrome://flag for +// kLacrosAvailabilityIgnore. +// 2. The user is a Googler and they are not opted into the +// kLacrosGooglePolicyRollout trial and they did not have the +// kLacrosDisallowed policy. LacrosLaunchSwitch GetLaunchSwitch() { // Users can set this switch in chrome://flags to disable the effect of the // lacros-availability policy. @@ -141,8 +160,15 @@ return LacrosLaunchSwitch::kUserChoice; } - return static_cast<LacrosLaunchSwitch>( + LacrosLaunchSwitch result = static_cast<LacrosLaunchSwitch>( g_browser_process->local_state()->GetInteger(prefs::kLacrosLaunchSwitch)); + if (IsGoogleInternal() && + !base::FeatureList::IsEnabled(kLacrosGooglePolicyRollout) && + result != LacrosLaunchSwitch::kLacrosDisallowed) { + return LacrosLaunchSwitch::kUserChoice; + } + + return result; } // Gets called from IsLacrosAllowedToBeEnabled with primary user or from @@ -340,6 +366,11 @@ const base::Feature kLacrosAllowOnStableChannel{ "LacrosAllowOnStableChannel", base::FEATURE_ENABLED_BY_DEFAULT}; +// When this feature is enabled, Lacros is allowed to roll out by policy to +// Googlers. +const base::Feature kLacrosGooglePolicyRollout{ + "LacrosGooglePolicyRollout", base::FEATURE_DISABLED_BY_DEFAULT}; + const char kLacrosStabilitySwitch[] = "lacros-stability"; const char kLacrosStabilityLeastStable[] = "least-stable"; const char kLacrosStabilityLessStable[] = "less-stable"; @@ -785,5 +816,9 @@ return user->IsAffiliated(); } +LacrosLaunchSwitch GetLaunchSwitchForTesting() { + return GetLaunchSwitch(); +} + } // namespace browser_util } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h index 848f01d..f6682c39c 100644 --- a/chrome/browser/ash/crosapi/browser_util.h +++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -63,6 +63,7 @@ }; extern const base::Feature kLacrosAllowOnStableChannel; +extern const base::Feature kLacrosGooglePolicyRollout; // A command-line switch that can also be set from chrome://flags that affects // the frequency of Lacros updates. @@ -218,6 +219,10 @@ base::Version GetRootfsLacrosVersionMayBlock( const base::FilePath& version_file_path); +// Exposed for testing. Returns the lacros integration suggested by the policy +// lacros-availability, modified by Finch flags and user flags as appropriate. +LacrosLaunchSwitch GetLaunchSwitchForTesting(); + } // namespace browser_util } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_util_unittest.cc b/chrome/browser/ash/crosapi/browser_util_unittest.cc index e0eaafb..b5b2dac0 100644 --- a/chrome/browser/ash/crosapi/browser_util_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_util_unittest.cc
@@ -79,6 +79,22 @@ EXPECT_TRUE(browser_util::IsLacrosEnabled()); } +TEST_F(BrowserUtilTest, LacrosGoogleRollout) { + AddRegularUser("user@google.com"); + g_browser_process->local_state()->SetInteger( + prefs::kLacrosLaunchSwitch, + static_cast<int>(browser_util::LacrosLaunchSwitch::kSideBySide)); + + EXPECT_EQ(browser_util::GetLaunchSwitchForTesting(), + browser_util::LacrosLaunchSwitch::kUserChoice); + + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures({browser_util::kLacrosGooglePolicyRollout}, {}); + + EXPECT_EQ(browser_util::GetLaunchSwitchForTesting(), + browser_util::LacrosLaunchSwitch::kSideBySide); +} + TEST_F(BrowserUtilTest, LacrosEnabledForChannels) { AddRegularUser("user@test.com");
diff --git a/chrome/browser/ash/crosapi/device_attributes_ash.cc b/chrome/browser/ash/crosapi/device_attributes_ash.cc index 2d5ada8..5175a0d 100644 --- a/chrome/browser/ash/crosapi/device_attributes_ash.cc +++ b/chrome/browser/ash/crosapi/device_attributes_ash.cc
@@ -8,10 +8,10 @@ #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chromeos/crosapi/mojom/device_attributes.mojom.h" @@ -112,14 +112,14 @@ std::move(callback).Run(StringResult::NewErrorMessage(kAccessDenied)); return; } - std::string result = g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetDeviceNamePolicyHandler() - ->GetDeviceHostname(); - if (result.empty()) { + absl::optional<std::string> result = g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetDeviceNamePolicyHandler() + ->GetHostnameChosenByAdministrator(); + if (!result) { std::move(callback).Run(StringResult::NewErrorMessage(kAccessDenied)); } else { - std::move(callback).Run(StringResult::NewContents(result)); + std::move(callback).Run(StringResult::NewContents(*result)); } }
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc index 056d583..1d623d2 100644 --- a/chrome/browser/ash/crostini/crostini_manager.cc +++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -42,10 +42,10 @@ #include "chrome/browser/ash/file_manager/volume_manager.h" #include "chrome/browser/ash/guest_os/guest_os_share_path.h" #include "chrome/browser/ash/guest_os/guest_os_stability_monitor.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/usb/cros_usb_detector.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/chromeos/scheduler_configuration_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc index 7dc66893..6e02c15b16 100644 --- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc +++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -24,8 +24,8 @@ #include "chrome/browser/ash/crostini/crostini_util.h" #include "chrome/browser/ash/crostini/fake_crostini_features.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/component_updater/fake_cros_component_manager.h" #include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/notifications/system_notification_helper.h"
diff --git a/chrome/browser/ash/crostini/crostini_util.cc b/chrome/browser/ash/crostini/crostini_util.cc index 7c02fca..9d27eae 100644 --- a/chrome/browser/ash/crostini/crostini_util.cc +++ b/chrome/browser/ash/crostini/crostini_util.cc
@@ -55,7 +55,7 @@ // We use an arbitrary well-formed extension id for the Terminal app, this // is equal to GenerateId("Terminal"). const char kCrostiniDeletedTerminalId[] = "oajcgpnkmhaalajejhlfpacbiokdnnfe"; -// web_app::GenerateAppIdFromURL( +// web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, // GURL("chrome-untrusted://terminal/html/terminal.html")) const char kCrostiniTerminalSystemAppId[] = "fhicihalidkgcimdmhpohldehjmcabcf";
diff --git a/chrome/browser/ash/crostini/crostini_util.h b/chrome/browser/ash/crostini/crostini_util.h index 421a71e..2236c3a8 100644 --- a/chrome/browser/ash/crostini/crostini_util.h +++ b/chrome/browser/ash/crostini/crostini_util.h
@@ -39,7 +39,7 @@ // We use an arbitrary well-formed extension id for the Terminal app, this // is equal to GenerateId("Terminal"). extern const char kCrostiniDeletedTerminalId[]; -// web_app::GenerateAppIdFromURL( +// web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, // GURL("chrome-untrusted://terminal/html/terminal.html")) extern const char kCrostiniTerminalSystemAppId[];
diff --git a/chrome/browser/ash/dbus/lock_to_single_user_service_provider.h b/chrome/browser/ash/dbus/lock_to_single_user_service_provider.h index 795e9731..c3501e7 100644 --- a/chrome/browser/ash/dbus/lock_to_single_user_service_provider.h +++ b/chrome/browser/ash/dbus/lock_to_single_user_service_provider.h
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.h" +#include "chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h" #include "chromeos/dbus/services/cros_dbus_service.h" #include "dbus/exported_object.h"
diff --git a/chrome/browser/ash/enhanced_network_tts/OWNERS b/chrome/browser/ash/enhanced_network_tts/OWNERS new file mode 100644 index 0000000..976b955 --- /dev/null +++ b/chrome/browser/ash/enhanced_network_tts/OWNERS
@@ -0,0 +1 @@ +file://ui/accessibility/OWNERS
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.cc b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.cc new file mode 100644 index 0000000..0fb9f36 --- /dev/null +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.cc
@@ -0,0 +1,18 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.h" + +namespace ash { +namespace enhanced_network_tts { + +const char kGoogApiKeyHeader[] = "X-Goog-Api-Key"; + +const char kReadAloudServerUrl[] = + "https://readaloud.googleapis.com//v1:generateAudioDocStream"; + +const char kNetworkRequestUploadType[] = "application/json"; + +} // namespace enhanced_network_tts +} // namespace ash
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.h b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.h new file mode 100644 index 0000000..9896f343 --- /dev/null +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.h
@@ -0,0 +1,28 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_CONSTANTS_H_ +#define CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_CONSTANTS_H_ + +#include <stddef.h> + +namespace ash { +namespace enhanced_network_tts { + +// The max size for a response. Set to 1MB. +constexpr size_t kEnhancedNetworkTtsMaxResponseSize = 1024 * 1024; + +// The HTTP request header in which the API key should be transmitted. +extern const char kGoogApiKeyHeader[]; + +// The server URL for the ReadAloud API. +extern const char kReadAloudServerUrl[]; + +// Upload type for the network request. +extern const char kNetworkRequestUploadType[]; + +} // namespace enhanced_network_tts +} // namespace ash + +#endif // CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_CONSTANTS_H_
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.cc b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.cc index 7e54b27..5e62137 100644 --- a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.cc +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.cc
@@ -4,49 +4,123 @@ #include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.h" -#include <string> +#include <iterator> #include <utility> -#include <vector> -#include "base/callback.h" +#include "base/base64.h" +#include "base/bind.h" +#include "base/logging.h" #include "base/no_destructor.h" +#include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.h" +#include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.h" +#include "components/google/core/common/google_util.h" +#include "google_apis/google_api_keys.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request.h" +#include "url/gurl.h" namespace ash { - -namespace { - -// TODO(crbug.com/1217301): Replace this placeholder implementation with the -// real data fetching logic. -std::vector<uint8_t> FetchData(const std::string& text) { - int n = text.length(); - std::vector<uint8_t> data; - for (int i = 0; i < n; i++) { - data.push_back(static_cast<uint8_t>(text[i])); - } - return data; -} - -} // namespace +namespace enhanced_network_tts { EnhancedNetworkTtsImpl& EnhancedNetworkTtsImpl::GetInstance() { static base::NoDestructor<EnhancedNetworkTtsImpl> tts_impl; return *tts_impl; } -EnhancedNetworkTtsImpl::EnhancedNetworkTtsImpl() = default; +EnhancedNetworkTtsImpl::EnhancedNetworkTtsImpl() + : api_key_(google_apis::GetReadAloudAPIKey()) {} EnhancedNetworkTtsImpl::~EnhancedNetworkTtsImpl() = default; -void EnhancedNetworkTtsImpl::BindReceiver( - mojo::PendingReceiver<enhanced_network_tts::mojom::EnhancedNetworkTts> - receiver) { +void EnhancedNetworkTtsImpl::BindReceiverAndURLFactory( + mojo::PendingReceiver<mojom::EnhancedNetworkTts> receiver, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { // Reset the receiver in case of rebinding (e.g., after the extension crash). receiver_.reset(); receiver_.Bind(std::move(receiver)); + + url_loader_factory_ = url_loader_factory; } void EnhancedNetworkTtsImpl::GetAudioData(const std::string& text, GetAudioDataCallback callback) { - std::move(callback).Run(FetchData(text)); + std::unique_ptr<network::SimpleURLLoader> url_loader = MakeRequestLoader(); + url_loader->AttachStringForUpload(FormatJsonRequest(text), + kNetworkRequestUploadType); + ongoing_server_requests_.push_back(std::move(url_loader)); + const UrlLoaderList::iterator last_request = + std::prev(ongoing_server_requests_.end()); + network::SimpleURLLoader::BodyAsStringCallback body_as_string_callback = + base::BindOnce(&EnhancedNetworkTtsImpl::OnServerResponseReceived, + weak_factory_.GetWeakPtr(), std::move(callback), + last_request); + ongoing_server_requests_.back()->DownloadToString( + url_loader_factory_.get(), std::move(body_as_string_callback), + kEnhancedNetworkTtsMaxResponseSize); } +data_decoder::mojom::JsonParser* EnhancedNetworkTtsImpl::GetJsonParser() { + if (!json_parser_) { + data_decoder_.GetService()->BindJsonParser( + json_parser_.BindNewPipeAndPassReceiver()); + json_parser_.reset_on_disconnect(); + } + + return json_parser_.get(); +} + +std::unique_ptr<network::SimpleURLLoader> +EnhancedNetworkTtsImpl::MakeRequestLoader() { + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->method = "POST"; + const GURL server_url = GURL(kReadAloudServerUrl); + resource_request->url = server_url; + resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + + // Put API key in request's header if a key exists, and the endpoint is + // trusted by Google. + if (!api_key_.empty() && server_url.SchemeIs(url::kHttpsScheme) && + google_util::IsGoogleAssociatedDomainUrl(server_url)) { + resource_request->headers.SetHeader(kGoogApiKeyHeader, api_key_); + } + + return network::SimpleURLLoader::Create(std::move(resource_request), + MISSING_TRAFFIC_ANNOTATION); +} + +void EnhancedNetworkTtsImpl::OnServerResponseReceived( + GetAudioDataCallback audio_callback, + const UrlLoaderList::iterator server_request_it, + const std::unique_ptr<std::string> json_response) { + ongoing_server_requests_.erase(server_request_it); + + if (!json_response) { + DVLOG(1) << "HTTP request for Enhance Network TTS failed."; + std::move(audio_callback).Run(GetResultOnError()); + return; + } + + // Send the JSON string to a dedicated service for safe parsing. + GetJsonParser()->Parse( + *json_response, + base::BindOnce(&EnhancedNetworkTtsImpl::OnResponseJsonParsed, + weak_factory_.GetWeakPtr(), std::move(audio_callback))); +} + +void EnhancedNetworkTtsImpl::OnResponseJsonParsed( + GetAudioDataCallback audio_callback, + const absl::optional<base::Value> json_data, + const absl::optional<std::string>& error) { + const bool success = json_data.has_value() && !error.has_value(); + + // Extract results for the request. + if (success) { + std::move(audio_callback).Run(UnpackJsonResponse(*json_data)); + } else { + DVLOG(1) << "Parsing server response JSON failed with error: " + << error.value_or("No reason reported."); + std::move(audio_callback).Run(GetResultOnError()); + } +} + +} // namespace enhanced_network_tts } // namespace ash
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.h b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.h index 51b5a78..8747ab8 100644 --- a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.h +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.h
@@ -5,17 +5,29 @@ #ifndef CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_IMPL_H_ #define CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_IMPL_H_ +#include <list> +#include <memory> +#include <string> + #include "ash/components/enhanced_network_tts/mojom/enhanced_network_tts.mojom.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/values.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "services/data_decoder/public/cpp/data_decoder.h" +#include "services/data_decoder/public/mojom/json_parser.mojom.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace ash { +namespace enhanced_network_tts { // The implementation of the enhanced network text-to-speech mojom receiver. // The remote of this mojom pipe will be invoked from the enhanced network tts // JS extension. This receiver fetches audio data on behalf of the remote. The // audio data is generated by Google's Speakr API. -class EnhancedNetworkTtsImpl - : public enhanced_network_tts::mojom::EnhancedNetworkTts { +class EnhancedNetworkTtsImpl : public mojom::EnhancedNetworkTts { public: // Getter for the singleton. static EnhancedNetworkTtsImpl& GetInstance(); @@ -25,20 +37,63 @@ void operator=(const EnhancedNetworkTtsImpl&) = delete; ~EnhancedNetworkTtsImpl() override; - // Binds a pending receiver sent from the remote. - void BindReceiver( + // Binds a pending receiver and a url factory. + void BindReceiverAndURLFactory( mojo::PendingReceiver<enhanced_network_tts::mojom::EnhancedNetworkTts> - receiver); + receiver, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); - // ash::enhanced_network_tts::mojom::EnhancedNetworkTts. + // ash::enhanced_network_tts::mojom::EnhancedNetworkTts: void GetAudioData(const std::string& text, GetAudioDataCallback callback) override; private: - mojo::Receiver<enhanced_network_tts::mojom::EnhancedNetworkTts> receiver_{ - this}; + // List of URL loader objects. + using UrlLoaderList = std::list<std::unique_ptr<network::SimpleURLLoader>>; + + // Create or reuse a connection to the data decoder service for safe JSON + // parsing. + data_decoder::mojom::JsonParser* GetJsonParser(); + + // Create a URL loader for a network request with an attached API key. + std::unique_ptr<network::SimpleURLLoader> MakeRequestLoader(); + + // Called when the ReadAloud server responds with audio data, which is + // encoded as a JSON string. + void OnServerResponseReceived( + GetAudioDataCallback audio_callback, + const UrlLoaderList::iterator server_request_it, + const std::unique_ptr<std::string> json_response); + + // Called when the data decoder service provides parsed JSON data for a + // server response. + void OnResponseJsonParsed(GetAudioDataCallback audio_callback, + absl::optional<base::Value> json_data, + const absl::optional<std::string>& error); + + // A list of currently-ongoing HTTP requests to the ReadAloud server. This + // helps us to better track the network requests. + // TODO(crbug.com/1217301): Consider only allowing one request at a time. + UrlLoaderList ongoing_server_requests_; + + // Decoder for data decoding service. + data_decoder::DataDecoder data_decoder_; + + // Url loader factory to be loaded. + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + + // Should not be used directly; GetJsonParser() should be called instead. + mojo::Remote<data_decoder::mojom::JsonParser> json_parser_; + + mojo::Receiver<mojom::EnhancedNetworkTts> receiver_{this}; + + const std::string api_key_; + + // Used for all callbacks. + base::WeakPtrFactory<EnhancedNetworkTtsImpl> weak_factory_{this}; }; +} // namespace enhanced_network_tts } // namespace ash #endif // CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_IMPL_H_
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl_unittest.cc b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl_unittest.cc index 195352c..234f508 100644 --- a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl_unittest.cc +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl_unittest.cc
@@ -4,25 +4,247 @@ #include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_impl.h" +#include <map> +#include <vector> + +#include "base/base64.h" #include "base/bind.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/strings/stringprintf.h" +#include "base/test/task_environment.h" +#include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_constants.h" +#include "google_apis/google_api_keys.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "net/base/net_errors.h" +#include "net/http/http_status_code.h" +#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/public/mojom/url_loader.mojom-shared.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" namespace ash { +namespace enhanced_network_tts { +namespace { -using EnhancedNetworkTtsImplTest = testing::Test; +// Template for a request. +constexpr char kTemplateRequest[] = R"({ + "text": { + "text_parts": ["%s"] + } + })"; -TEST_F(EnhancedNetworkTtsImplTest, GetAudioData) { +// Template for a server response. +constexpr char kTemplateResponse[] = R"([{ + "metadata": {} + } + , + { + "text": {} + } + , + { + "audio": { + "bytes": "%s" + } + } + ])"; + +// A fake server that supports test URL loading. +class TestServerURLLoaderFactory { + public: + TestServerURLLoaderFactory() + : shared_loader_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &loader_factory_)) {} + TestServerURLLoaderFactory(const TestServerURLLoaderFactory&) = delete; + TestServerURLLoaderFactory& operator=(const TestServerURLLoaderFactory&) = + delete; + ~TestServerURLLoaderFactory() = default; + + const std::vector<network::TestURLLoaderFactory::PendingRequest>& requests() { + return *loader_factory_.pending_requests(); + } + + // Expects that the earliest received request has the given URL, headers and + // body, and replies with the given response. + // + // |expected_headers| is a map from header key string to either: + // a) a null optional, if the given header should not be present, or + // b) a non-null optional, if the given header should be present and match + // the optional value. + // + // Consumes the earliest received request (i.e. a subsequent call will apply + // to the second-earliest received request and so on). + void ExpectRequestAndSimulateResponse( + const std::string& expected_url, + const std::map<std::string, absl::optional<std::string>>& + expected_headers, + const std::string& expected_body, + const std::string& response, + const net::HttpStatusCode response_code) { + const std::vector<network::TestURLLoaderFactory::PendingRequest>& + pending_requests = *loader_factory_.pending_requests(); + + ASSERT_FALSE(pending_requests.empty()); + const network::ResourceRequest& request = pending_requests.front().request; + + // Assert that the earliest request is for the given URL. + EXPECT_EQ(request.url, GURL(expected_url)); + + // Expect that specified headers are accurate. + for (const auto& kv : expected_headers) { + if (kv.second.has_value()) { + std::string actual_value; + EXPECT_TRUE(request.headers.GetHeader(kv.first, &actual_value)); + EXPECT_EQ(actual_value, *kv.second); + } else { + EXPECT_FALSE(request.headers.HasHeader(kv.first)); + } + } + + // Extract request body. + std::string actual_body; + if (request.request_body) { + const std::vector<network::DataElement>* const elements = + request.request_body->elements(); + + // We only support the simplest body structure. + if (elements && elements->size() == 1 && + (*elements)[0].type() == + network::mojom::DataElementDataView::Tag::kBytes) { + actual_body = std::string( + (*elements)[0].As<network::DataElementBytes>().AsStringPiece()); + } + } + + EXPECT_EQ(actual_body, expected_body); + + // Guaranteed to match the first request based on URL. + loader_factory_.SimulateResponseForPendingRequest(expected_url, response, + response_code); + } + + scoped_refptr<network::SharedURLLoaderFactory> AsSharedURLLoaderFactory() { + return shared_loader_factory_; + } + + private: + network::TestURLLoaderFactory loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_loader_factory_; +}; + +// Returns a JSON string of a formatted request for the |input_text|. The +// request is based on a template and is guaranteed to be correct. +std::string CreateCorrectRequest(const std::string& input_text) { + // Fills the template and then parse and rewrite it to a canonically + // formatted version. + const std::unique_ptr<base::Value> json = base::JSONReader::ReadDeprecated( + base::StringPrintf(kTemplateRequest, input_text.c_str())); + EXPECT_FALSE(json->DictEmpty()); + + std::string out; + base::JSONWriter::Write(*json, &out); + + return out; +} + +} // namespace + +class EnhancedNetworkTtsImplTest : public testing::Test { + protected: + void SetUp() override { + EnhancedNetworkTtsImpl::GetInstance().BindReceiverAndURLFactory( + remote_.BindNewPipeAndPassReceiver(), + test_url_factory_.AsSharedURLLoaderFactory()); + } + + base::test::TaskEnvironment test_task_env_; + TestServerURLLoaderFactory test_url_factory_; + data_decoder::test::InProcessDataDecoder in_process_data_decoder_; + mojo::Remote<mojom::EnhancedNetworkTts> remote_; +}; + +TEST_F(EnhancedNetworkTtsImplTest, GetAudioDataSucceeds) { + const std::string input_text = "Hi."; std::vector<uint8_t> result; - const std::string test = "test"; EnhancedNetworkTtsImpl::GetInstance().GetAudioData( - test, + input_text, base::BindOnce([](std::vector<uint8_t>* result, const std::vector<uint8_t>& bytes) { *result = bytes; }, &result)); - EXPECT_EQ(result[0], 116); - EXPECT_EQ(result[1], 101); - EXPECT_EQ(result[2], 115); - EXPECT_EQ(result[3], 116); + test_task_env_.RunUntilIdle(); + + const std::map<std::string, absl::optional<std::string>> expected_headers = { + {kGoogApiKeyHeader, google_apis::GetReadAloudAPIKey()}}; + const std::string expected_body = CreateCorrectRequest(input_text); + // |expected_output| here is arbitrary, which is encoded into a fake response + // sent by the fake server, |TestServerURLLoaderFactory|. In general, we + // expect the real server sends the audio data back as a base64 encoded JSON + // string. + const std::vector<uint8_t> expected_output = {1, 2, 5}; + std::string encoded_output(expected_output.begin(), expected_output.end()); + base::Base64Encode(encoded_output, &encoded_output); + test_url_factory_.ExpectRequestAndSimulateResponse( + kReadAloudServerUrl, expected_headers, expected_body, + base::StringPrintf(kTemplateResponse, encoded_output.c_str()), + net::HTTP_OK); + test_task_env_.RunUntilIdle(); + + // We only get the data after the server's response. We simulate the response + // in the code above. + EXPECT_EQ(result, expected_output); } +TEST_F(EnhancedNetworkTtsImplTest, ServerError) { + const std::string input_text = "Hi."; + std::vector<uint8_t> result; + EnhancedNetworkTtsImpl::GetInstance().GetAudioData( + input_text, + base::BindOnce([](std::vector<uint8_t>* result, + const std::vector<uint8_t>& bytes) { *result = bytes; }, + &result)); + test_task_env_.RunUntilIdle(); + + const std::map<std::string, absl::optional<std::string>> expected_headers = { + {kGoogApiKeyHeader, google_apis::GetReadAloudAPIKey()}}; + const std::string expected_body = CreateCorrectRequest(input_text); + test_url_factory_.ExpectRequestAndSimulateResponse( + kReadAloudServerUrl, expected_headers, expected_body, "" /* response= */, + net::HTTP_INTERNAL_SERVER_ERROR); + test_task_env_.RunUntilIdle(); + + // We only get the data after the server's response. We simulate the response + // in the code above. + EXPECT_EQ(result, std::vector<uint8_t>()); +} + +TEST_F(EnhancedNetworkTtsImplTest, JsonDecodingError) { + const std::string input_text = "Hi."; + std::vector<uint8_t> result; + EnhancedNetworkTtsImpl::GetInstance().GetAudioData( + input_text, + base::BindOnce([](std::vector<uint8_t>* result, + const std::vector<uint8_t>& bytes) { *result = bytes; }, + &result)); + test_task_env_.RunUntilIdle(); + + const std::map<std::string, absl::optional<std::string>> expected_headers = { + {kGoogApiKeyHeader, google_apis::GetReadAloudAPIKey()}}; + const std::string expected_body = CreateCorrectRequest(input_text); + const char response[] = R"([{some wired response)"; + test_url_factory_.ExpectRequestAndSimulateResponse( + kReadAloudServerUrl, expected_headers, expected_body, response, + net::HTTP_OK); + test_task_env_.RunUntilIdle(); + + // We only get the data after the server's response. We simulate the response + // in the code above. + EXPECT_EQ(result, std::vector<uint8_t>()); +} + +} // namespace enhanced_network_tts } // namespace ash
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.cc b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.cc new file mode 100644 index 0000000..f68bb73 --- /dev/null +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.cc
@@ -0,0 +1,64 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.h" + +#include <utility> + +#include "base/base64.h" +#include "base/json/json_writer.h" +#include "base/logging.h" + +namespace ash { +namespace enhanced_network_tts { + +std::string FormatJsonRequest(const std::string& input_text) { + base::Value text_parts(base::Value::Type::LIST); + text_parts.Append(std::move(input_text)); + + base::Value text(base::Value::Type::DICTIONARY); + text.SetKey("text_parts", std::move(text_parts)); + + base::Value request(base::Value::Type::DICTIONARY); + request.SetKey("text", std::move(text)); + + std::string json_request; + base::JSONWriter::Write(request, &json_request); + + return json_request; +} + +std::vector<uint8_t> GetResultOnError() { + return std::vector<uint8_t>(); +} + +std::vector<uint8_t> UnpackJsonResponse(const base::Value& json_data) { + base::Value::ConstListView list_data = json_data.GetList(); + + // Depending on the size of input text (n), the list size should be 1 + 2n. + // The first item in the list is "metadata", then each input text has one + // dictionary for "text" and another dictionary for "audio". Since we only + // have one input text (assuming one paragraph only), we should only have a + // list with a size of three. For now, we only send back the "audio" data. + // TODO(crbug.com/1217301): Send the "text" back to the caller. + if (list_data.size() != 3 || list_data[2].FindKey("audio") == nullptr || + list_data[2].FindKey("audio")->FindStringKey("bytes") == nullptr) { + DVLOG(1) << "HTTP response for Enhance Network TTS has unexpected data."; + return GetResultOnError(); + } + const std::string* audio_bytes_ptr = + list_data[2].FindKey("audio")->FindStringKey("bytes"); + std::string audio_bytes = *audio_bytes_ptr; + + if (!base::Base64Decode(audio_bytes, &audio_bytes)) { + DVLOG(1) << "Failed to decode the audio data for Enhance Network TTS."; + return GetResultOnError(); + } + + // Send the decoded data to the caller. + return std::vector<uint8_t>(audio_bytes.begin(), audio_bytes.end()); +} + +} // namespace enhanced_network_tts +} // namespace ash
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.h b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.h new file mode 100644 index 0000000..5c4866c3 --- /dev/null +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.h
@@ -0,0 +1,31 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_UTILS_H_ +#define CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_UTILS_H_ + +#include <string> +#include <vector> + +#include "base/values.h" + +namespace ash { +namespace enhanced_network_tts { + +// Format the |input_text| to a JSON string that will be accepted by the +// ReadAloud server. +std::string FormatJsonRequest(const std::string& input_text); + +// Generate a result when encountering errors (e.g., server error, parsing +// error). We return an empty vector for now. +// TODO(crbug.com/1217301): Provide more specific error information. +std::vector<uint8_t> GetResultOnError(); + +// Unpack the JSON audio data from the server response to a vector. +std::vector<uint8_t> UnpackJsonResponse(const base::Value& json_data); + +} // namespace enhanced_network_tts +} // namespace ash + +#endif // CHROME_BROWSER_ASH_ENHANCED_NETWORK_TTS_ENHANCED_NETWORK_TTS_UTILS_H_
diff --git a/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils_unittest.cc b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils_unittest.cc new file mode 100644 index 0000000..6bc76f78 --- /dev/null +++ b/chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils_unittest.cc
@@ -0,0 +1,111 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/enhanced_network_tts/enhanced_network_tts_utils.h" + +#include <memory> + +#include "base/base64.h" +#include "base/json/json_reader.h" +#include "base/strings/stringprintf.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash { +namespace enhanced_network_tts { + +namespace { + +// Template for a request. +constexpr char kTemplateRequest[] = R"({ + "text": { + "text_parts": ["%s"] + } + })"; + +// Template for a server response. +constexpr char kTemplateResponse[] = R"([{ + "metadata": {} + } + , + { + "text": {} + } + , + { + "audio": { + "bytes": "%s" + } + } + ])"; + +// Function to remove all spaces and line breaks from a given string +std::string RemoveSpaceAndLineBreak(std::string str) { + str.erase(std::remove(str.begin(), str.end(), ' '), str.end()); + str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); + return str; +} + +} // namespace + +using EnhancedNetworkTtsUtilsTest = testing::Test; + +TEST_F(EnhancedNetworkTtsUtilsTest, FormatJsonRequest) { + const std::string input_text = "Hello, World!"; + const std::string expected_text = + base::StringPrintf(kTemplateRequest, input_text.c_str()); + const std::string formated_text = FormatJsonRequest(input_text); + + EXPECT_EQ(RemoveSpaceAndLineBreak(formated_text), + RemoveSpaceAndLineBreak(expected_text)); +} + +TEST_F(EnhancedNetworkTtsUtilsTest, GetResultOnError) { + std::vector<uint8_t> result = GetResultOnError(); + + EXPECT_EQ(result, std::vector<uint8_t>()); +} + +TEST_F(EnhancedNetworkTtsUtilsTest, UnpackJsonResponseSucceed) { + const std::vector<uint8_t> response_data = {1, 2, 5}; + std::string encoded_data(response_data.begin(), response_data.end()); + base::Base64Encode(encoded_data, &encoded_data); + const std::string encoded_response = + base::StringPrintf(kTemplateResponse, encoded_data.c_str()); + const std::unique_ptr<base::Value> json = + base::JSONReader::ReadDeprecated(encoded_response); + + std::vector<uint8_t> result = UnpackJsonResponse(*json); + + EXPECT_EQ(result, std::vector<uint8_t>({1, 2, 5})); +} + +TEST_F(EnhancedNetworkTtsUtilsTest, + UnpackJsonResponseFailsWithWrongResponseFormat) { + const std::string encoded_response = "[{}, {}, {}]"; + const std::unique_ptr<base::Value> json = + base::JSONReader::ReadDeprecated(encoded_response); + + std::vector<uint8_t> result = UnpackJsonResponse(*json); + + EXPECT_EQ(result, std::vector<uint8_t>()); +} + +TEST_F(EnhancedNetworkTtsUtilsTest, + UnpackJsonResponseFailsWithWrongDataFormat) { + // The data is not Base64 encoded. + const std::vector<uint8_t> response_data = {1, 2, 5}; + const std::string encoded_data(response_data.begin(), response_data.end()); + const std::string encoded_response = + base::StringPrintf(kTemplateResponse, encoded_data.c_str()); + const std::unique_ptr<base::Value> json = + base::JSONReader::ReadDeprecated(encoded_response); + + std::vector<uint8_t> result = UnpackJsonResponse(*json); + + EXPECT_EQ(result, std::vector<uint8_t>()); +} + +} // namespace enhanced_network_tts +} // namespace ash
diff --git a/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc b/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc index 584ed6e..3f0a1dc0 100644 --- a/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc +++ b/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc
@@ -31,8 +31,7 @@ class WebFileTasksTest : public ::testing::Test { protected: - WebFileTasksTest() { - } + WebFileTasksTest() {} void SetUp() override { profile_ = std::make_unique<TestingProfile>(); @@ -89,6 +88,8 @@ return file_handler_manager_; } + base::test::ScopedFeatureList feature_list_; + private: content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfile> profile_; @@ -97,7 +98,22 @@ web_app::TestFileHandlerManager* file_handler_manager_; }; -TEST_F(WebFileTasksTest, WebAppFileHandlingCanBeDisabledByFlag) { +class WebFileTasksFileHandlingEnabledTests : public WebFileTasksTest { + public: + WebFileTasksFileHandlingEnabledTests() { + feature_list_.InitWithFeatures({blink::features::kFileHandlingAPI}, {}); + } +}; + +class WebFileTasksFileHandlingDisabledTests : public WebFileTasksTest { + public: + WebFileTasksFileHandlingDisabledTests() { + feature_list_.InitWithFeatures({}, {blink::features::kFileHandlingAPI}); + } +}; + +TEST_F(WebFileTasksFileHandlingDisabledTests, + WebAppFileHandlingCanBeDisabledByFlag) { const char kGraphrId[] = "graphr-app-id"; const char kGraphrAction[] = "https://graphr.tld/csv"; InstallFileHandler(kGraphrId, GURL(kGraphrAction), {{"text/csv", {".csv"}}}); @@ -109,39 +125,43 @@ std::vector<FullTaskDescriptor> tasks; - { - // Web Apps should not be able to handle files unless kFileHandlingAPI is - // enabled. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({}, - {blink::features::kFileHandlingAPI}); - FindWebTasks(profile(), entries, &tasks); - EXPECT_EQ(0u, tasks.size()); - tasks.clear(); - } - - { - // When the flag is enabled, it should be possible to handle files from - // bookmark apps. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({blink::features::kFileHandlingAPI}, - {}); - - // Note: FileHandlers aren't enabled while the flag is off. - file_handler_manager()->EnableAndRegisterOsFileHandlers(kGraphrId); - - // Test that when enabled, bookmark apps can handle files - FindWebTasks(profile(), entries, &tasks); - // Graphr should be a valid handler. - ASSERT_EQ(1u, tasks.size()); - EXPECT_EQ(kGraphrId, tasks[0].task_descriptor.app_id); - EXPECT_EQ(kGraphrAction, tasks[0].task_descriptor.action_id); - EXPECT_EQ(file_tasks::TaskType::TASK_TYPE_WEB_APP, - tasks[0].task_descriptor.task_type); - } + // Web Apps should not be able to handle files unless kFileHandlingAPI is + // enabled. + FindWebTasks(profile(), entries, &tasks); + EXPECT_EQ(0u, tasks.size()); + tasks.clear(); } -TEST_F(WebFileTasksTest, DisabledFileHandlersAreNotVisible) { +TEST_F(WebFileTasksFileHandlingEnabledTests, + WebAppFileHandlingCanBeEnabledByFlag) { + const char kGraphrId[] = "graphr-app-id"; + const char kGraphrAction[] = "https://graphr.tld/csv"; + InstallFileHandler(kGraphrId, GURL(kGraphrAction), {{"text/csv", {".csv"}}}); + + std::vector<extensions::EntryInfo> entries; + entries.emplace_back( + util::GetMyFilesFolderForProfile(profile()).AppendASCII("foo.csv"), + "text/csv", false); + + std::vector<FullTaskDescriptor> tasks; + + // When the flag is enabled, it should be possible to handle files from + // bookmark apps. + // Note: FileHandlers aren't enabled while the flag is off. + file_handler_manager()->EnableAndRegisterOsFileHandlers(kGraphrId); + + // Test that when enabled, bookmark apps can handle files + FindWebTasks(profile(), entries, &tasks); + // Graphr should be a valid handler. + ASSERT_EQ(1u, tasks.size()); + EXPECT_EQ(kGraphrId, tasks[0].task_descriptor.app_id); + EXPECT_EQ(kGraphrAction, tasks[0].task_descriptor.action_id); + EXPECT_EQ(file_tasks::TaskType::TASK_TYPE_WEB_APP, + tasks[0].task_descriptor.task_type); +} + +TEST_F(WebFileTasksFileHandlingEnabledTests, + DisabledFileHandlersAreNotVisible) { const char kGraphrId[] = "graphr-app-id"; const char kGraphrAction[] = "https://graphr.tld/csv"; @@ -150,9 +170,6 @@ // Web Apps should not be able to handle files unless kFileHandlingAPI is // enabled. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({blink::features::kFileHandlingAPI}, {}); - InstallFileHandler(kGraphrId, GURL(kGraphrAction), {{"text/csv", {".csv"}}}); InstallFileHandler(kFooId, GURL(kFooAction), {{"text/csv", {".csv"}}}); @@ -177,9 +194,7 @@ EXPECT_EQ(kFooId, tasks[0].task_descriptor.app_id); } -TEST_F(WebFileTasksTest, FindWebFileHandlerTasks) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({blink::features::kFileHandlingAPI}, {}); +TEST_F(WebFileTasksFileHandlingEnabledTests, FindWebFileHandlerTasks) { const char kFooId[] = "foo-app-id"; const char kFooAction[] = "https://foo.tld/files"; @@ -225,10 +240,7 @@ FindWebTasks(profile(), entries, &tasks); } -TEST_F(WebFileTasksTest, FindWebFileHandlerTask_Generic) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({blink::features::kFileHandlingAPI}, {}); - +TEST_F(WebFileTasksFileHandlingEnabledTests, FindWebFileHandlerTask_Generic) { const char kBarId[] = "bar-app-id"; const char kBarAction[] = "https://bar.tld/files";
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.cc b/chrome/browser/ash/login/enrollment/enrollment_screen.cc index 8d92337..15cb3f3c 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.cc
@@ -21,9 +21,9 @@ #include "chrome/browser/ash/login/wizard_context.h" #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/policy/enrollment_status.h"
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc index f54c52d..de43840 100644 --- a/chrome/browser/ash/login/existing_user_controller.cc +++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -55,6 +55,8 @@ #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" #include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/policy/core/device_local_account_policy_service.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/system/device_disabling_manager.h" @@ -62,8 +64,6 @@ #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/boot_times_recorder.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/net/system_network_context_manager.h"
diff --git a/chrome/browser/ash/login/screens/update_required_screen_browsertest.cc b/chrome/browser/ash/login/screens/update_required_screen_browsertest.cc index c251f90..652f590 100644 --- a/chrome/browser/ash/login/screens/update_required_screen_browsertest.cc +++ b/chrome/browser/ash/login/screens/update_required_screen_browsertest.cc
@@ -25,7 +25,7 @@ #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ash/policy/core/device_policy_builder.h" #include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h" #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
diff --git a/chrome/browser/ash/login/session/chrome_session_manager.cc b/chrome/browser/ash/login/session/chrome_session_manager.cc index 5ba8645..f65cae28 100644 --- a/chrome/browser/ash/login/session/chrome_session_manager.cc +++ b/chrome/browser/ash/login/session/chrome_session_manager.cc
@@ -32,12 +32,12 @@ #include "chrome/browser/ash/login/startup_utils.h" #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/boot_times_recorder.h" -#include "chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/chromeos/policy/reporting/app_install_event_log_manager_wrapper.h" #include "chrome/browser/chromeos/tether/tether_service.h" #include "chrome/browser/chromeos/tpm_firmware_update_notification.h"
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc index d89865a..3dec0daf 100644 --- a/chrome/browser/ash/login/session/user_session_manager.cc +++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -74,6 +74,9 @@ #include "chrome/browser/ash/login/users/supervised_user_manager.h" #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/about_flags.h" #include "chrome/browser/ash/settings/cros_settings.h" @@ -87,9 +90,6 @@ #include "chrome/browser/chromeos/first_run/first_run.h" #include "chrome/browser/chromeos/full_restore/full_restore_service.h" #include "chrome/browser/chromeos/logging.h" -#include "chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/chromeos/tether/tether_service.h" #include "chrome/browser/chromeos/tpm_firmware_update_notification.h" #include "chrome/browser/chromeos/u2f_notification.h"
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.h b/chrome/browser/ash/login/users/chrome_user_manager_impl.h index 5bf79bc..53959c6c0 100644 --- a/chrome/browser/ash/login/users/chrome_user_manager_impl.h +++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.h
@@ -22,9 +22,9 @@ #include "chrome/browser/ash/login/users/multi_profile_user_controller_delegate.h" #include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/policy/core/device_local_account_policy_service.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/settings/device_settings_service.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" // TODO(https://crbug.com/1164001): move to forward declaration when fixed. #include "chrome/browser/chromeos/session_length_limiter.h" #include "chrome/browser/profiles/profile_manager_observer.h"
diff --git a/chrome/browser/ash/notifications/update_required_notification.h b/chrome/browser/ash/notifications/update_required_notification.h index be9d8cb7..bf50eb24 100644 --- a/chrome/browser/ash/notifications/update_required_notification.h +++ b/chrome/browser/ash/notifications/update_required_notification.h
@@ -10,7 +10,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/public/cpp/notification_delegate.h"
diff --git a/chrome/browser/ash/notifications/update_required_notification_unittest.cc b/chrome/browser/ash/notifications/update_required_notification_unittest.cc index 675256a..f86b6245 100644 --- a/chrome/browser/ash/notifications/update_required_notification_unittest.cc +++ b/chrome/browser/ash/notifications/update_required_notification_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include <memory> @@ -13,9 +13,9 @@ #include "base/test/task_environment.h" #include "base/time/default_clock.h" #include "base/values.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h" #include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/notifications/system_notification_helper.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc b/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc index b3995a0..dd846b0d 100644 --- a/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc +++ b/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc
@@ -40,18 +40,18 @@ #include "chrome/browser/ash/policy/external_data/handlers/device_printers_external_data_handler.h" #include "chrome/browser/ash/policy/external_data/handlers/device_wallpaper_image_external_data_handler.h" #include "chrome/browser/ash/policy/external_data/handlers/device_wilco_dtc_configuration_external_data_handler.h" +#include "chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/bluetooth_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.h" +#include "chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h" +#include "chrome/browser/ash/policy/handlers/system_proxy_handler.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/settings/device_settings_service.h" #include "chrome/browser/ash/system/timezone_util.h" -#include "chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.h" -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.h" -#include "chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.h" -#include "chrome/browser/chromeos/policy/handlers/system_proxy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/chromeos/policy/invalidation/affiliated_cloud_policy_invalidator.h" #include "chrome/browser/chromeos/policy/invalidation/affiliated_invalidation_service_provider.h" #include "chrome/browser/chromeos/policy/invalidation/affiliated_invalidation_service_provider_impl.h"
diff --git a/chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.cc b/chrome/browser/ash/policy/fuzzer/policy_fuzzer.cc similarity index 98% rename from chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.cc rename to chrome/browser/ash/policy/fuzzer/policy_fuzzer.cc index 82c9e374..c384a99 100644 --- a/chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.cc +++ b/chrome/browser/ash/policy/fuzzer/policy_fuzzer.cc
@@ -16,9 +16,9 @@ #include "base/test/task_environment.h" #include "build/build_config.h" #include "chrome/browser/ash/dbus/ash_dbus_helper.h" +#include "chrome/browser/ash/policy/fuzzer/policy_fuzzer.pb.h" #include "chrome/browser/ash/settings/device_settings_provider.h" #include "chrome/browser/ash/settings/device_settings_service.h" -#include "chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.pb.h" #include "chrome/browser/policy/configuration_policy_handler_list_factory.h" #include "chrome/common/chrome_paths.h" #include "chromeos/tpm/install_attributes.h"
diff --git a/chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.proto b/chrome/browser/ash/policy/fuzzer/policy_fuzzer.proto similarity index 100% rename from chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.proto rename to chrome/browser/ash/policy/fuzzer/policy_fuzzer.proto
diff --git a/chrome/browser/chromeos/policy/handlers/README.md b/chrome/browser/ash/policy/handlers/README.md similarity index 69% rename from chrome/browser/chromeos/policy/handlers/README.md rename to chrome/browser/ash/policy/handlers/README.md index bb535023..6714db78 100644 --- a/chrome/browser/chromeos/policy/handlers/README.md +++ b/chrome/browser/ash/policy/handlers/README.md
@@ -1,8 +1,8 @@ -chrome/browser/chromeos/policy/handlers +chrome/browser/ash/policy/handlers ======================================= This directory should contain code that handles individual policies -that do not fit in another subdirectory under chrome/browser/chromeos/policy. +that do not fit in another subdirectory under chrome/browser/ash/policy. The file configuration_policy_handler_chromeos.h contains multiple possible base classes that can be used to verify policy values of different formats.
diff --git a/chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc rename to chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc index f85dd7d..99ad336 100644 --- a/chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc +++ b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" #include <utility>
diff --git a/chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h similarity index 93% rename from chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h rename to chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h index 0d86f01..1f620a6 100644 --- a/chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h +++ b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_ADB_SIDELOADING_ALLOWANCE_MODE_POLICY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_ADB_SIDELOADING_ALLOWANCE_MODE_POLICY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_ADB_SIDELOADING_ALLOWANCE_MODE_POLICY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_ADB_SIDELOADING_ALLOWANCE_MODE_POLICY_HANDLER_H_ #include <memory> @@ -122,4 +122,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_ADB_SIDELOADING_ALLOWANCE_MODE_POLICY_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_ADB_SIDELOADING_ALLOWANCE_MODE_POLICY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc rename to chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc index d5b16cf2..e0c06da 100644 --- a/chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" #include "base/bind.h" #include "base/run_loop.h"
diff --git a/chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.cc b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.cc similarity index 97% rename from chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.cc rename to chrome/browser/ash/policy/handlers/bluetooth_policy_handler.cc index 4cfb5899..0a5c778c 100644 --- a/chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.cc +++ b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/bluetooth_policy_handler.h" #include "base/bind.h" #include "base/callback_helpers.h"
diff --git a/chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.h b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.h similarity index 87% rename from chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.h rename to chrome/browser/ash/policy/handlers/bluetooth_policy_handler.h index 34a8b081..c81dfb72e 100644 --- a/chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.h +++ b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_BLUETOOTH_POLICY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_BLUETOOTH_POLICY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_BLUETOOTH_POLICY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_BLUETOOTH_POLICY_HANDLER_H_ #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -43,4 +43,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_BLUETOOTH_POLICY_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_BLUETOOTH_POLICY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler_unittest.cc similarity index 97% rename from chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler_unittest.cc rename to chrome/browser/ash/policy/handlers/bluetooth_policy_handler_unittest.cc index 7be63e3..e3a51047 100644 --- a/chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/bluetooth_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/bluetooth_policy_handler.h" #include "base/test/task_environment.h" #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
diff --git a/chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.cc b/chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.cc similarity index 99% rename from chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.cc rename to chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.cc index cd0d5cc..947ab9dc 100644 --- a/chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.cc +++ b/chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h" +#include "chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h" #include <stdint.h>
diff --git a/chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h b/chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h similarity index 96% rename from chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h rename to chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h index 42505ea4..3f1377a 100644 --- a/chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h +++ b/chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_ #include <string> @@ -212,4 +212,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_
diff --git a/chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos_unittest.cc b/chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos_unittest.cc similarity index 99% rename from chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos_unittest.cc rename to chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos_unittest.cc index f28b6ab0..eb18823 100644 --- a/chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos_unittest.cc +++ b/chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h" +#include "chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h" #include <memory> #include <utility>
diff --git a/chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.cc b/chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.cc similarity index 96% rename from chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.cc rename to chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.cc index 6afc4ba..942e7da 100644 --- a/chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.cc +++ b/chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.h" +#include "chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.h" #include "base/bind.h" #include "base/logging.h"
diff --git a/chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.h b/chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.h similarity index 80% rename from chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.h rename to chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.h index 5cce614..74440fe 100644 --- a/chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.h +++ b/chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_DOCK_MAC_ADDRESS_SOURCE_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_DOCK_MAC_ADDRESS_SOURCE_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_DOCK_MAC_ADDRESS_SOURCE_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_DOCK_MAC_ADDRESS_SOURCE_HANDLER_H_ #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -37,4 +37,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_DOCK_MAC_ADDRESS_SOURCE_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_DOCK_MAC_ADDRESS_SOURCE_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler_unittest.cc b/chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler_unittest.cc similarity index 96% rename from chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler_unittest.cc rename to chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler_unittest.cc index f7e9ecb..57ebf7f 100644 --- a/chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_dock_mac_address_source_handler.h" +#include "chrome/browser/ash/policy/handlers/device_dock_mac_address_source_handler.h" #include <memory> #include <string>
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler.cc b/chrome/browser/ash/policy/handlers/device_name_policy_handler.cc similarity index 89% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler.cc rename to chrome/browser/ash/policy/handlers/device_name_policy_handler.cc index a5c479f..042329a6 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler.cc +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler.h" namespace policy { @@ -23,4 +23,4 @@ observer.OnHostnamePolicyChanged(); } -} // namespace policy \ No newline at end of file +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h b/chrome/browser/ash/policy/handlers/device_name_policy_handler.h similarity index 80% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h rename to chrome/browser/ash/policy/handlers/device_name_policy_handler.h index e39df47..8839eee5 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_H_ #include "base/observer_list.h" #include "base/observer_list_types.h" @@ -38,10 +38,6 @@ virtual ~DeviceNamePolicyHandler(); - // Returns the device hostname that DeviceNamePolicyHandlerImpl has last set - // in shill. This is the hostname after formatting (by FormatHostname()). - virtual const std::string& GetDeviceHostname() const = 0; - // Provides the type of policy to be used for device name functionality. virtual DeviceNamePolicy GetDeviceNamePolicy() const = 0; @@ -64,4 +60,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_H_ \ No newline at end of file +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.cc b/chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.cc similarity index 95% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.cc rename to chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.cc index af661bd1..5a0caf7 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.cc +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.h" #include "base/bind.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.h" #include "chromeos/network/device_state.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" @@ -47,10 +47,6 @@ } } -const std::string& DeviceNamePolicyHandlerImpl::GetDeviceHostname() const { - return hostname_; -} - DeviceNamePolicyHandler::DeviceNamePolicy DeviceNamePolicyHandlerImpl::GetDeviceNamePolicy() const { return device_name_policy_;
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.h b/chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.h similarity index 84% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.h rename to chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.h index bf94bf2f..43faf32 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.h +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_IMPL_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_IMPL_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_IMPL_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_IMPL_H_ #include <memory> #include <string> @@ -11,8 +11,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler.h" #include "chrome/browser/ash/settings/cros_settings.h" -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h" #include "chromeos/network/network_state_handler_observer.h" #include "chromeos/system/statistics_provider.h" @@ -29,10 +29,7 @@ ~DeviceNamePolicyHandlerImpl() override; // DeviceNamePolicyHandler: - const std::string& GetDeviceHostname() const override; - DeviceNamePolicy GetDeviceNamePolicy() const override; - absl::optional<std::string> GetHostnameChosenByAdministrator() const override; private: @@ -70,4 +67,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_IMPL_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_IMPL_H_
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl_unittest.cc b/chrome/browser/ash/policy/handlers/device_name_policy_handler_impl_unittest.cc similarity index 95% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl_unittest.cc rename to chrome/browser/ash/policy/handlers/device_name_policy_handler_impl_unittest.cc index 87c8517b..7afdefb9 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl_unittest.cc +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler_impl_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler_impl.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler_impl.h" #include "base/test/task_environment.h" #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" @@ -115,13 +115,11 @@ DeviceNamePolicyHandler::DeviceNamePolicy::kPolicyHostnameChosenByAdmin, after); - // Check that GetDeviceHostname() and GetHostnameChosenByAdministrator() - // both return the expected hostname value. + // Check that GetHostnameChosenByAdministrator() returns the expected hostname + // value. const absl::optional<std::string> hostname_chosen_by_administrator = handler_->GetHostnameChosenByAdministrator(); - const std::string device_hostname = handler_->GetDeviceHostname(); EXPECT_EQ(hostname_chosen_by_administrator, "chromebook"); - EXPECT_EQ(device_hostname, "chromebook"); } // Check that OnHostnamePolicyChanged() correctly notifies observer when
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.cc b/chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.cc similarity index 95% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.cc rename to chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.cc index bcba56c..048266af 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.cc +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.h" #include "base/strings/string_util.h"
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.h b/chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.h similarity index 72% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.h rename to chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.h index 35a89ee..e21d12c 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.h +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_NAME_GENERATOR_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_NAME_GENERATOR_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_NAME_GENERATOR_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_NAME_GENERATOR_H_ #include <string> @@ -21,4 +21,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_NAME_GENERATOR_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_NAME_POLICY_HANDLER_NAME_GENERATOR_H_
diff --git a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator_unittest.cc b/chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator_unittest.cc similarity index 97% rename from chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator_unittest.cc rename to chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator_unittest.cc index c6710e59..c107d568 100644 --- a/chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator_unittest.cc +++ b/chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler_name_generator.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler_name_generator.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/chromeos/policy/handlers/device_quirks_policy_browsertest.cc b/chrome/browser/ash/policy/handlers/device_quirks_policy_browsertest.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/device_quirks_policy_browsertest.cc rename to chrome/browser/ash/policy/handlers/device_quirks_policy_browsertest.cc
diff --git a/chrome/browser/chromeos/policy/handlers/device_system_use_24hour_clock_browsertest.cc b/chrome/browser/ash/policy/handlers/device_system_use_24hour_clock_browsertest.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/device_system_use_24hour_clock_browsertest.cc rename to chrome/browser/ash/policy/handlers/device_system_use_24hour_clock_browsertest.cc
diff --git a/chrome/browser/chromeos/policy/handlers/device_system_wide_tracing_enabled_browsertest.cc b/chrome/browser/ash/policy/handlers/device_system_wide_tracing_enabled_browsertest.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/device_system_wide_tracing_enabled_browsertest.cc rename to chrome/browser/ash/policy/handlers/device_system_wide_tracing_enabled_browsertest.cc
diff --git a/chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.cc b/chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.cc similarity index 95% rename from chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.cc rename to chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.cc index b9e5d59..db9453f 100644 --- a/chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.cc +++ b/chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.h" +#include "chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.h" #include <vector>
diff --git a/chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.h b/chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.h similarity index 78% rename from chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.h rename to chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.h index 6e9332d..867899c 100644 --- a/chrome/browser/chromeos/policy/handlers/device_wifi_allowed_handler.h +++ b/chrome/browser/ash/policy/handlers/device_wifi_allowed_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_WIFI_ALLOWED_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_WIFI_ALLOWED_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_WIFI_ALLOWED_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_WIFI_ALLOWED_HANDLER_H_ #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -31,4 +31,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_DEVICE_WIFI_ALLOWED_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_DEVICE_WIFI_ALLOWED_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/extension_cache_unittest.cc b/chrome/browser/ash/policy/handlers/extension_cache_unittest.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/extension_cache_unittest.cc rename to chrome/browser/ash/policy/handlers/extension_cache_unittest.cc
diff --git a/chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.cc b/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.cc similarity index 96% rename from chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.cc rename to chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.cc index 6c2f626f..dcd1c238 100644 --- a/chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.cc +++ b/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h" #if !BUILDFLAG(IS_CHROMEOS_ASH) #error This file shall only be used in ash.
diff --git a/chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.h b/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h similarity index 83% rename from chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.h rename to chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h index f286b3f6..e743a8f 100644 --- a/chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.h +++ b/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_ #include <string> @@ -48,4 +48,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.cc b/chrome/browser/ash/policy/handlers/lock_to_single_user_manager.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.cc rename to chrome/browser/ash/policy/handlers/lock_to_single_user_manager.cc index 8913556e..e0839956 100644 --- a/chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.cc +++ b/chrome/browser/ash/policy/handlers/lock_to_single_user_manager.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.h" +#include "chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h" #include "base/bind.h" #include "base/logging.h"
diff --git a/chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.h b/chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h similarity index 92% rename from chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.h rename to chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h index 22b9bfa..ff288f6 100644 --- a/chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.h +++ b/chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_LOCK_TO_SINGLE_USER_MANAGER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_LOCK_TO_SINGLE_USER_MANAGER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_LOCK_TO_SINGLE_USER_MANAGER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_LOCK_TO_SINGLE_USER_MANAGER_H_ #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -82,4 +82,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_LOCK_TO_SINGLE_USER_MANAGER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_LOCK_TO_SINGLE_USER_MANAGER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager_unittest.cc b/chrome/browser/ash/policy/handlers/lock_to_single_user_manager_unittest.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager_unittest.cc rename to chrome/browser/ash/policy/handlers/lock_to_single_user_manager_unittest.cc index 86ae009..cd73b8c 100644 --- a/chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager_unittest.cc +++ b/chrome/browser/ash/policy/handlers/lock_to_single_user_manager_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.h" +#include "chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h" #include <memory>
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.cc rename to chrome/browser/ash/policy/handlers/minimum_version_policy_handler.cc index 221c9a9..21457964 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.cc +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include <algorithm> #include <string> @@ -20,9 +20,9 @@ #include "base/values.h" #include "chrome/browser/ash/notifications/update_required_notification.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.h" #include "chrome/browser/ui/ash/system_tray_client_impl.h" #include "chrome/browser/upgrade_detector/build_state.h" #include "chrome/browser/upgrade_detector/upgrade_detector.h"
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h similarity index 97% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h rename to chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h index 4c7b776..c319569 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_ #include <memory> @@ -317,4 +317,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_browsertest.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc similarity index 99% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_browsertest.cc rename to chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc index 856c2a2..43a4f96a 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_browsertest.cc +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc
@@ -31,12 +31,12 @@ #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" #include "chrome/browser/ash/policy/core/device_policy_builder.h" #include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/policy/profile_policy_connector.h"
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc similarity index 97% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.cc rename to chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc index 9551ebe..bfa06fde 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.cc +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h" #include "base/system/sys_info.h" #include "chrome/browser/ash/login/existing_user_controller.h"
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.h b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h similarity index 69% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.h rename to chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h index 47b101d..1b32536b9 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_delegate_impl.h +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_DELEGATE_IMPL_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_DELEGATE_IMPL_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_DELEGATE_IMPL_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_DELEGATE_IMPL_H_ #include "base/version.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" namespace policy { @@ -29,4 +29,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_DELEGATE_IMPL_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_DELEGATE_IMPL_H_
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_unittest.cc rename to chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc index 7e99419..10250845 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include <memory> @@ -13,9 +13,9 @@ #include "base/test/task_environment.h" #include "base/time/default_clock.h" #include "base/values.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.cc similarity index 90% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.cc rename to chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.cc index c17218dd..760d988a 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.cc +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" namespace policy {
diff --git a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h b/chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h similarity index 82% rename from chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h rename to chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h index a1c4989..37a1ada1 100644 --- a/chrome/browser/chromeos/policy/handlers/minimum_version_policy_test_helpers.h +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_test_helpers.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_TEST_HELPERS_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_TEST_HELPERS_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_TEST_HELPERS_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_TEST_HELPERS_H_ #include <string> @@ -33,4 +33,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_TEST_HELPERS_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_TEST_HELPERS_H_
diff --git a/chrome/browser/chromeos/policy/handlers/power_policy_browsertest.cc b/chrome/browser/ash/policy/handlers/power_policy_browsertest.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/power_policy_browsertest.cc rename to chrome/browser/ash/policy/handlers/power_policy_browsertest.cc
diff --git a/chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.cc b/chrome/browser/ash/policy/handlers/powerwash_requirements_checker.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.cc rename to chrome/browser/ash/policy/handlers/powerwash_requirements_checker.cc index 8e26fdc..1dda2da 100644 --- a/chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.cc +++ b/chrome/browser/ash/policy/handlers/powerwash_requirements_checker.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "ash/public/cpp/notification_utils.h" #include "base/logging.h"
diff --git a/chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h b/chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h similarity index 91% rename from chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h rename to chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h index 55402c8..8af9a71e 100644 --- a/chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h +++ b/chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_POWERWASH_REQUIREMENTS_CHECKER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_POWERWASH_REQUIREMENTS_CHECKER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_POWERWASH_REQUIREMENTS_CHECKER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_POWERWASH_REQUIREMENTS_CHECKER_H_ #include "base/macros.h" @@ -78,4 +78,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_POWERWASH_REQUIREMENTS_CHECKER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_POWERWASH_REQUIREMENTS_CHECKER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker_unittest.cc b/chrome/browser/ash/policy/handlers/powerwash_requirements_checker_unittest.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker_unittest.cc rename to chrome/browser/ash/policy/handlers/powerwash_requirements_checker_unittest.cc index fc2a3f4..14b8918 100644 --- a/chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker_unittest.cc +++ b/chrome/browser/ash/policy/handlers/powerwash_requirements_checker_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
diff --git a/chrome/browser/chromeos/policy/handlers/restore_on_startup_browsertest_chromeos.cc b/chrome/browser/ash/policy/handlers/restore_on_startup_browsertest_chromeos.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/restore_on_startup_browsertest_chromeos.cc rename to chrome/browser/ash/policy/handlers/restore_on_startup_browsertest_chromeos.cc
diff --git a/chrome/browser/chromeos/policy/handlers/site_isolation_flag_handling_browsertest.cc b/chrome/browser/ash/policy/handlers/site_isolation_flag_handling_browsertest.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/site_isolation_flag_handling_browsertest.cc rename to chrome/browser/ash/policy/handlers/site_isolation_flag_handling_browsertest.cc
diff --git a/chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.cc b/chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.cc rename to chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.cc
diff --git a/chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h b/chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h similarity index 89% rename from chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h rename to chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h index 5b6ad6d7d..344ca95b 100644 --- a/chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h +++ b/chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_SYSTEM_FEATURES_DISABLE_LIST_POLICY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_SYSTEM_FEATURES_DISABLE_LIST_POLICY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_SYSTEM_FEATURES_DISABLE_LIST_POLICY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_SYSTEM_FEATURES_DISABLE_LIST_POLICY_HANDLER_H_ #include <memory> @@ -73,4 +73,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_SYSTEM_FEATURES_DISABLE_LIST_POLICY_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_SYSTEM_FEATURES_DISABLE_LIST_POLICY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler_unittest.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler_unittest.cc rename to chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler_unittest.cc index 41c6684..e86ad27 100644 --- a/chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "ash/public/cpp/ash_pref_names.h" #include "base/test/metrics/histogram_tester.h"
diff --git a/chrome/browser/chromeos/policy/handlers/system_proxy_handler.cc b/chrome/browser/ash/policy/handlers/system_proxy_handler.cc similarity index 97% rename from chrome/browser/chromeos/policy/handlers/system_proxy_handler.cc rename to chrome/browser/ash/policy/handlers/system_proxy_handler.cc index e436611..af47d13b 100644 --- a/chrome/browser/chromeos/policy/handlers/system_proxy_handler.cc +++ b/chrome/browser/ash/policy/handlers/system_proxy_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/system_proxy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_proxy_handler.h" #include <string>
diff --git a/chrome/browser/chromeos/policy/handlers/system_proxy_handler.h b/chrome/browser/ash/policy/handlers/system_proxy_handler.h similarity index 85% rename from chrome/browser/chromeos/policy/handlers/system_proxy_handler.h rename to chrome/browser/ash/policy/handlers/system_proxy_handler.h index 20f28512..54f70a0b 100644 --- a/chrome/browser/chromeos/policy/handlers/system_proxy_handler.h +++ b/chrome/browser/ash/policy/handlers/system_proxy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_SYSTEM_PROXY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_SYSTEM_PROXY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_SYSTEM_PROXY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_SYSTEM_PROXY_HANDLER_H_ #include "base/memory/weak_ptr.h" #include "chrome/browser/ash/settings/cros_settings.h" @@ -42,4 +42,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_SYSTEM_PROXY_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_SYSTEM_PROXY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/system_proxy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/system_proxy_handler_unittest.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/system_proxy_handler_unittest.cc rename to chrome/browser/ash/policy/handlers/system_proxy_handler_unittest.cc index 3b25b7ad..5f80c8d9 100644 --- a/chrome/browser/chromeos/policy/handlers/system_proxy_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/system_proxy_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/system_proxy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_proxy_handler.h" #include <memory> #include <string>
diff --git a/chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.cc b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.cc rename to chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.cc index 8a25737b..88d2b46 100644 --- a/chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.cc +++ b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include <utility>
diff --git a/chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h similarity index 93% rename from chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h rename to chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h index 138eaab..53b47b80 100644 --- a/chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h +++ b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_TPM_AUTO_UPDATE_MODE_POLICY_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_TPM_AUTO_UPDATE_MODE_POLICY_HANDLER_H_ +#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_TPM_AUTO_UPDATE_MODE_POLICY_HANDLER_H_ +#define CHROME_BROWSER_ASH_POLICY_HANDLERS_TPM_AUTO_UPDATE_MODE_POLICY_HANDLER_H_ #include <memory> @@ -114,4 +114,4 @@ } // namespace policy -#endif // CHROME_BROWSER_CHROMEOS_POLICY_HANDLERS_TPM_AUTO_UPDATE_MODE_POLICY_HANDLER_H_ +#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_TPM_AUTO_UPDATE_MODE_POLICY_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc similarity index 98% rename from chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc rename to chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc index df1c893..690aa41 100644 --- a/chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include <utility>
diff --git a/chrome/browser/chromeos/policy/handlers/variations_service_policy_browsertest.cc b/chrome/browser/ash/policy/handlers/variations_service_policy_browsertest.cc similarity index 100% rename from chrome/browser/chromeos/policy/handlers/variations_service_policy_browsertest.cc rename to chrome/browser/ash/policy/handlers/variations_service_policy_browsertest.cc
diff --git a/chrome/browser/ash/settings/device_settings_provider.cc b/chrome/browser/ash/settings/device_settings_provider.cc index f76362b7..9739411 100644 --- a/chrome/browser/ash/settings/device_settings_provider.cc +++ b/chrome/browser/ash/settings/device_settings_provider.cc
@@ -24,10 +24,10 @@ #include "base/values.h" #include "chrome/browser/ash/ownership/owner_settings_service_ash.h" #include "chrome/browser/ash/policy/core/device_policy_decoder_chromeos.h" +#include "chrome/browser/ash/policy/handlers/system_proxy_handler.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/settings/device_settings_cache.h" #include "chrome/browser/ash/settings/stats_reporting_controller.h" -#include "chrome/browser/chromeos/policy/handlers/system_proxy_handler.h" #include "chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.h" #include "chrome/browser/chromeos/tpm_firmware_update.h" #include "chromeos/dbus/dbus_thread_manager.h"
diff --git a/chrome/browser/ash/smb_client/smb_service.cc b/chrome/browser/ash/smb_client/smb_service.cc index b1c705e..d3361294 100644 --- a/chrome/browser/ash/smb_client/smb_service.cc +++ b/chrome/browser/ash/smb_client/smb_service.cc
@@ -83,12 +83,6 @@ return std::make_unique<NetBiosClient>(network_context); } -// TODO(crbug.com/1203884): Remove this method and any code conditional on it -// being false. -bool IsSmbFsEnabled() { - return true; -} - // Metric recording functions. // This enum is used to define the buckets for an enumerated UMA histogram. @@ -320,7 +314,7 @@ return; } - if (IsSmbFsEnabled() && smbfs_shares_.size() >= kMaxSmbFsShares) { + if (smbfs_shares_.size() >= kMaxSmbFsShares) { // Prevent users from mounting an excessive number of shares. std::move(callback).Run(SmbMountResult::kTooManyOpened); return; @@ -419,9 +413,7 @@ platform_util::ShowItemInFolder(profile_, mount_path); } - if (IsSmbFsEnabled()) { - registry_.Save(info); - } + registry_.Save(info); RecordMountCount(); std::move(callback).Run(SmbMountResult::kSuccess); @@ -437,71 +429,48 @@ user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile_); DCHECK(user); - if (IsSmbFsEnabled()) { - SmbFsShare::MountOptions smbfs_options; - smbfs_options.resolved_host = - share_finder_->GetResolvedHost(info.share_url().GetHost()); - smbfs_options.username = info.username(); - smbfs_options.workgroup = info.workgroup(); - smbfs_options.password = password; - smbfs_options.allow_ntlm = IsNTLMAuthenticationEnabled(); - smbfs_options.skip_connect = skip_connect; - if (save_credentials && !info.password_salt().empty()) { - smbfs_options.save_restore_password = true; - smbfs_options.account_hash = user->username_hash(); - smbfs_options.password_salt = info.password_salt(); - } - if (info.use_kerberos()) { - if (user->IsActiveDirectoryUser()) { - smbfs_options.kerberos_options = - absl::make_optional<SmbFsShare::KerberosOptions>( - SmbFsShare::KerberosOptions::Source::kActiveDirectory, - user->GetAccountId().GetObjGuid()); - } else if (smb_credentials_updater_) { - smbfs_options.kerberos_options = - absl::make_optional<SmbFsShare::KerberosOptions>( - SmbFsShare::KerberosOptions::Source::kKerberos, - smb_credentials_updater_->active_account_name()); - } else { - LOG(WARNING) << "No Kerberos credential source available"; - std::move(callback).Run(SmbMountResult::kAuthenticationFailed, {}); - return; - } - } - - std::unique_ptr<SmbFsShare> mount = std::make_unique<SmbFsShare>( - profile_, info.share_url(), info.display_name(), smbfs_options); - if (smbfs_mounter_creation_callback_) { - mount->SetMounterCreationCallbackForTest( - smbfs_mounter_creation_callback_); - } - - SmbFsShare* raw_mount = mount.get(); - const std::string mount_id = mount->mount_id(); - smbfs_shares_[mount_id] = std::move(mount); - raw_mount->Mount(base::BindOnce(&SmbService::OnSmbfsMountDone, AsWeakPtr(), - mount_id, std::move(callback))); - } else { - // If using kerberos, the hostname should not be resolved since kerberos - // service tickets are keyed on hostname. - const SmbUrl url = info.use_kerberos() - ? info.share_url() - : share_finder_->GetResolvedUrl(info.share_url()); - - SmbProviderClient::MountOptions smb_mount_options; - smb_mount_options.original_path = info.share_url().ToString(); - smb_mount_options.username = info.username(); - smb_mount_options.workgroup = info.workgroup(); - smb_mount_options.ntlm_enabled = IsNTLMAuthenticationEnabled(); - smb_mount_options.save_password = save_credentials && !info.use_kerberos(); - smb_mount_options.account_hash = user->username_hash(); - smb_mount_options.skip_connect = skip_connect; - GetSmbProviderClient()->Mount( - base::FilePath(url.ToString()), smb_mount_options, - MakeFdWithContents(password), - base::BindOnce(&SmbService::OnProviderMountDone, AsWeakPtr(), - std::move(callback), options, save_credentials)); + SmbFsShare::MountOptions smbfs_options; + smbfs_options.resolved_host = + share_finder_->GetResolvedHost(info.share_url().GetHost()); + smbfs_options.username = info.username(); + smbfs_options.workgroup = info.workgroup(); + smbfs_options.password = password; + smbfs_options.allow_ntlm = IsNTLMAuthenticationEnabled(); + smbfs_options.skip_connect = skip_connect; + if (save_credentials && !info.password_salt().empty()) { + smbfs_options.save_restore_password = true; + smbfs_options.account_hash = user->username_hash(); + smbfs_options.password_salt = info.password_salt(); } + if (info.use_kerberos()) { + if (user->IsActiveDirectoryUser()) { + smbfs_options.kerberos_options = + absl::make_optional<SmbFsShare::KerberosOptions>( + SmbFsShare::KerberosOptions::Source::kActiveDirectory, + user->GetAccountId().GetObjGuid()); + } else if (smb_credentials_updater_) { + smbfs_options.kerberos_options = + absl::make_optional<SmbFsShare::KerberosOptions>( + SmbFsShare::KerberosOptions::Source::kKerberos, + smb_credentials_updater_->active_account_name()); + } else { + LOG(WARNING) << "No Kerberos credential source available"; + std::move(callback).Run(SmbMountResult::kAuthenticationFailed, {}); + return; + } + } + + std::unique_ptr<SmbFsShare> mount = std::make_unique<SmbFsShare>( + profile_, info.share_url(), info.display_name(), smbfs_options); + if (smbfs_mounter_creation_callback_) { + mount->SetMounterCreationCallbackForTest(smbfs_mounter_creation_callback_); + } + + SmbFsShare* raw_mount = mount.get(); + const std::string mount_id = mount->mount_id(); + smbfs_shares_[mount_id] = std::move(mount); + raw_mount->Mount(base::BindOnce(&SmbService::OnSmbfsMountDone, AsWeakPtr(), + mount_id, std::move(callback))); } void SmbService::OnSmbfsMountDone(const std::string& smbfs_mount_id, @@ -525,40 +494,6 @@ std::move(callback).Run(SmbMountResult::kSuccess, mount->mount_path()); } -void SmbService::OnProviderMountDone( - MountInternalCallback callback, - const file_system_provider::MountOptions& options, - bool save_credentials, - smbprovider::ErrorType error, - int32_t mount_id) { - SmbMountResult mount_result = TranslateErrorToMountResult(error); - RecordMountResult(mount_result); - - if (mount_result != SmbMountResult::kSuccess) { - std::move(callback).Run(mount_result, {}); - return; - } - - DCHECK_GE(mount_id, 0); - mount_id_map_[options.file_system_id] = mount_id; - - base::File::Error result = - GetProviderService()->MountFileSystem(provider_id_, options); - if (result != base::File::FILE_OK) { - mount_id_map_.erase(options.file_system_id); - // If the password was asked to be saved, remove it. - GetSmbProviderClient()->Unmount( - mount_id, save_credentials /* remove_password */, base::DoNothing()); - - std::move(callback).Run(TranslateErrorToMountResult(result), {}); - return; - } - - base::FilePath mount_path = file_system_provider::util::GetMountPath( - profile_, provider_id_, options.file_system_id); - std::move(callback).Run(SmbMountResult::kSuccess, mount_path); -} - int32_t SmbService::GetMountId( const file_system_provider::ProvidedFileSystemInfo& info) const { const auto iter = mount_id_map_.find(info.file_system_id()); @@ -604,11 +539,8 @@ GetPreconfiguredSharePathsForPremount(); std::vector<SmbShareInfo> saved_smbfs_shares; - if (IsSmbFsEnabled()) { - // Restore smbfs shares. - // TODO(crbug.com/1055571): Migrate saved smbprovider shares to smbfs. - saved_smbfs_shares = registry_.GetAll(); - } + // Restore smbfs shares. + saved_smbfs_shares = registry_.GetAll(); if (!provided_file_systems.empty() || !saved_smbfs_shares.empty() || !preconfigured_shares.empty()) {
diff --git a/chrome/browser/ash/smb_client/smb_service.h b/chrome/browser/ash/smb_client/smb_service.h index 86da20f..02ae011 100644 --- a/chrome/browser/ash/smb_client/smb_service.h +++ b/chrome/browser/ash/smb_client/smb_service.h
@@ -145,16 +145,6 @@ bool skip_connect, MountInternalCallback callback); - // Handles the response from mounting an SMB share using smbprovider. - // Completes the mounting of an SMB file system, passing |options| on to - // file_system_provider::Service::MountFileSystem(). Passes error status to - // callback. - void OnProviderMountDone(MountInternalCallback callback, - const file_system_provider::MountOptions& options, - bool save_credentials, - smbprovider::ErrorType error, - int32_t mount_id); - // Handles the response from mounting an smbfs share. Passes |result| onto // |callback|. void OnSmbfsMountDone(const std::string& smbfs_mount_id,
diff --git a/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc index 4f4a298..1664d8b 100644 --- a/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc
@@ -4,8 +4,8 @@ #include "ash/webui/scanning/url_constants.h" #include "base/values.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc index 66bf1f9a..cb5cc26 100644 --- a/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h"
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc index 6dfb9a9a..006ed0ab 100644 --- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -144,7 +144,8 @@ base::BindLambdaForTesting([&](const web_app::AppId& installed_app_id, web_app::InstallResultCode code) { EXPECT_EQ(web_app::InstallResultCode::kSuccessNewInstall, code); - EXPECT_EQ(installed_app_id, web_app::GenerateAppIdFromURL(url)); + EXPECT_EQ(installed_app_id, + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, url)); callback_called = true; }));
diff --git a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc index c46c9ef..9a4c9ce 100644 --- a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc +++ b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/metrics/field_trial.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h" @@ -29,7 +30,9 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/prerender_test_util.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/url_loader_interceptor.h" #include "device/bluetooth/bluetooth_adapter.h" @@ -42,6 +45,7 @@ #include "device/bluetooth/test/mock_bluetooth_device.h" #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h" #include "device/bluetooth/test/mock_bluetooth_gatt_service.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h" @@ -916,4 +920,153 @@ content::EvalJs(web_contents_, "second_device_promise")); } +class WebBluetoothTestWithNewPermissionsBackendEnabledInPrerendering + : public WebBluetoothTestWithNewPermissionsBackendEnabled { + public: + WebBluetoothTestWithNewPermissionsBackendEnabledInPrerendering() + : prerender_helper_(base::BindRepeating( + &WebBluetoothTestWithNewPermissionsBackendEnabledInPrerendering:: + GetWebContents, + base::Unretained(this))) {} + ~WebBluetoothTestWithNewPermissionsBackendEnabledInPrerendering() override = + default; + + void SetUpOnMainThread() override { + prerender_helper_.SetUpOnMainThread(embedded_test_server()); + WebBluetoothTestWithNewPermissionsBackendEnabled::SetUpOnMainThread(); + ASSERT_TRUE(test_server_handle_ = + embedded_test_server()->StartAndReturnHandle()); + + auto url = embedded_test_server()->GetURL("/empty.html"); + ui_test_utils::NavigateToURL(browser(), url); + web_contents_ = browser()->tab_strip_model()->GetActiveWebContents(); + } + + content::WebContents* GetWebContents() { return web_contents_; } + + content::test::PrerenderTestHelper* prerender_helper() { + return &prerender_helper_; + } + + private: + content::test::PrerenderTestHelper prerender_helper_; + net::test_server::EmbeddedTestServerHandle test_server_handle_; +}; + +class TestWebContentsObserver : public content::WebContentsObserver { + public: + explicit TestWebContentsObserver(content::WebContents* contents) + : WebContentsObserver(contents) {} + TestWebContentsObserver(const TestWebContentsObserver&) = delete; + TestWebContentsObserver& operator=(const TestWebContentsObserver&) = delete; + ~TestWebContentsObserver() override = default; + + void OnIsConnectedToBluetoothDeviceChanged( + bool is_connected_to_bluetooth_device) override { + ++num_is_connected_to_bluetooth_device_changed_; + last_is_connected_to_bluetooth_device_ = is_connected_to_bluetooth_device; + if (quit_closure_ && expected_updating_count_ == + num_is_connected_to_bluetooth_device_changed_) { + std::move(quit_closure_).Run(); + } + } + + int num_is_connected_to_bluetooth_device_changed() { + return num_is_connected_to_bluetooth_device_changed_; + } + + const absl::optional<bool>& last_is_connected_to_bluetooth_device() { + return last_is_connected_to_bluetooth_device_; + } + + void clear_last_is_connected_to_bluetooth_device() { + last_is_connected_to_bluetooth_device_.reset(); + } + + void WaitUntilConnectionIsUpdated(int expected_count) { + if (num_is_connected_to_bluetooth_device_changed_ == expected_count) + return; + expected_updating_count_ = expected_count; + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + private: + int num_is_connected_to_bluetooth_device_changed_ = 0; + absl::optional<bool> last_is_connected_to_bluetooth_device_; + int expected_updating_count_; + base::OnceClosure quit_closure_; +}; + +// Tests that the connection of Web Bluetooth is deferred in the prerendering. +IN_PROC_BROWSER_TEST_F( + WebBluetoothTestWithNewPermissionsBackendEnabledInPrerendering, + WebBluetoothDeviceConnectInPrerendering) { + TestWebContentsObserver observer(GetWebContents()); + + AddFakeDevice(kDeviceAddress); + SetDeviceToSelect(kDeviceAddress); + + ASSERT_TRUE(content::ExecJs(GetWebContents(), R"((async() => { + try { + let device = await navigator.bluetooth.requestDevice({ + filters: [{name: 'Test Device'}]}); + let gatt = await device.gatt.connect(); + let service = await gatt.getPrimaryService('heart_rate'); + return service.uuid; + } catch(e) { + return `${e.name}: ${e.message}`; + } + })())")); + + observer.WaitUntilConnectionIsUpdated(1); + // In the active main frame, the connection of Web Bluetooth works. + EXPECT_EQ(observer.num_is_connected_to_bluetooth_device_changed(), 1); + EXPECT_TRUE(observer.last_is_connected_to_bluetooth_device().has_value()); + EXPECT_TRUE(observer.last_is_connected_to_bluetooth_device().value()); + observer.clear_last_is_connected_to_bluetooth_device(); + + // Loads a page in the prerender. + auto prerender_url = embedded_test_server()->GetURL("/simple.html"); + // The prerendering doesn't affect the current scanning. + int host_id = prerender_helper()->AddPrerender(prerender_url); + content::test::PrerenderHostObserver host_observer(*GetWebContents(), + host_id); + content::RenderFrameHost* prerendered_frame_host = + prerender_helper()->GetPrerenderedMainFrameHost(host_id); + + // Runs JS asynchronously since Mojo calls is deferred on the prerendering. + content::ExecuteScriptAsync(prerendered_frame_host, R"((async() => { + try { + let device = await navigator.bluetooth.requestDevice({ + filters: [{name: 'Test Device'}]}); + let gatt = await device.gatt.connect(); + let service = await gatt.getPrimaryService('heart_rate'); + return service.uuid; + } catch(e) { + return `${e.name}: ${e.message}`; + } + })())"); + + // In the prerendering, the connection of Web Bluetooth is deferred and + // `observer` doesn't have any update. + EXPECT_EQ(observer.num_is_connected_to_bluetooth_device_changed(), 1); + EXPECT_FALSE(observer.last_is_connected_to_bluetooth_device().has_value()); + + // Navigates the primary page to the URL. + prerender_helper()->NavigatePrimaryPage(prerender_url); + // The page should be activated from the prerendering. + EXPECT_TRUE(host_observer.was_activated()); + + // Waits for the deferred Mojo call. + observer.WaitUntilConnectionIsUpdated(3); + + // After the prerendering activation, the connection of Web Bluetooth is + // updated. + EXPECT_EQ(observer.num_is_connected_to_bluetooth_device_changed(), 3); + EXPECT_TRUE(observer.last_is_connected_to_bluetooth_device().has_value()); + EXPECT_TRUE(observer.last_is_connected_to_bluetooth_device().value()); +} + } // namespace
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index b68dad6d..e5ed8ffd 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -17,8 +17,6 @@ <structure name="IDR_INCOGNITO_TAB_HTML" file="resources\ntp4\incognito_tab.html" flattenhtml="true" type="chrome_html" /> <structure name="IDR_INCOGNITO_TAB_THEME_CSS" file="resources\ntp4\incognito_tab_theme.css" flattenhtml="true" type="chrome_html" /> <structure name="IDR_GUEST_TAB_HTML" file="resources\ntp4\guest_tab.html" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_EPHEMERAL_GUEST_TAB_HTML" file="resources\ntp4\ephemeral_guest_tab.html" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_EPHEMERAL_GUEST_TAB_CSS" file="resources\ntp4\ephemeral_guest_tab.css" flattenhtml="true" type="chrome_html" /> <structure name="IDR_NEW_TAB_4_THEME_CSS" file="resources\ntp4\new_tab_theme.css" flattenhtml="true" type="chrome_html" /> </if> @@ -53,7 +51,7 @@ <if expr="not is_android"> <include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys\about_sys.html" type="BINDATA" /> <include name="IDR_ABOUT_SYS_CSS" file="resources\about_sys\about_sys.css" flattenhtml="true" type="BINDATA" /> - <include name="IDR_ABOUT_SYS_JS" file="resources\about_sys\about_sys.js" type="BINDATA" /> + <include name="IDR_ABOUT_SYS_JS" file="resources\about_sys\about_sys.js" preprocess="true" type="BINDATA" /> </if> <include name="IDR_AD_NETWORK_HASHES" file="resources\ad_networks.dat" type="BINDATA" /> <if expr="is_posix and not is_macosx">
diff --git a/chrome/browser/chrome_browser_main_posix.cc b/chrome/browser/chrome_browser_main_posix.cc index 9b8454ba..d5dbef8a 100644 --- a/chrome/browser/chrome_browser_main_posix.cc +++ b/chrome/browser/chrome_browser_main_posix.cc
@@ -19,9 +19,9 @@ #include "base/notreached.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" -#include "chrome/app/shutdown_signal_handlers_posix.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/sessions/session_restore.h" +#include "chrome/browser/shutdown_signal_handlers_posix.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/result_codes.h"
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 9b157d4..9dc1d01 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -4,10 +4,12 @@ #include "chrome/browser/chrome_browser_main_win.h" +// windows.h must be included before shellapi.h +#include <windows.h> + #include <shellapi.h> #include <stddef.h> #include <stdint.h> -#include <windows.h> #include <algorithm> #include <utility>
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 8a3f42f5..9aac3826 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -433,6 +433,7 @@ #include "chrome/browser/ash/login/signin/merge_session_throttling_utils.h" #include "chrome/browser/ash/login/signin_partition_manager.h" #include "chrome/browser/ash/login/startup_utils.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/smb_client/fileapi/smbfs_file_system_backend_delegate.h" #include "chrome/browser/ash/system/input_device_settings.h" @@ -444,7 +445,6 @@ #include "chrome/browser/chromeos/fileapi/file_system_backend.h" #include "chrome/browser/chromeos/fileapi/mtp_file_system_backend_delegate.h" #include "chrome/browser/chromeos/net/system_proxy_manager.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/chromeos/policy/networking/policy_cert_service_factory.h" #include "chrome/browser/speech/tts_chromeos.h" #include "chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h"
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index 03aab2f..c90b304 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -65,7 +65,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/webui/scanning/url_constants.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/chromeos/policy/networking/policy_cert_service.h" #include "chrome/browser/chromeos/policy/networking/policy_cert_service_factory.h" #include "chrome/test/base/scoped_testing_local_state.h"
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 209de37..351fad0a 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -45,6 +45,7 @@ "//chromeos/dbus:vm_permission_service_proto", "//chromeos/dbus:vm_sk_forwarding_proto", "//chromeos/dbus/power:power_manager_proto", + "//chromeos/metrics", "//chromeos/services/assistant/public/mojom", "//chromeos/strings", "//components/live_caption:constants", @@ -1233,8 +1234,12 @@ "../ash/drive/fileapi/drivefs_async_file_util.h", "../ash/drive/fileapi/drivefs_file_system_backend_delegate.cc", "../ash/drive/fileapi/drivefs_file_system_backend_delegate.h", + "../ash/enhanced_network_tts/enhanced_network_tts_constants.cc", + "../ash/enhanced_network_tts/enhanced_network_tts_constants.h", "../ash/enhanced_network_tts/enhanced_network_tts_impl.cc", "../ash/enhanced_network_tts/enhanced_network_tts_impl.h", + "../ash/enhanced_network_tts/enhanced_network_tts_utils.cc", + "../ash/enhanced_network_tts/enhanced_network_tts_utils.h", "../ash/exo/chrome_data_exchange_delegate.cc", "../ash/exo/chrome_data_exchange_delegate.h", "../ash/file_manager/app_id.h", @@ -2058,6 +2063,38 @@ "../ash/policy/external_data/handlers/wallpaper_image_external_data_handler.h", "../ash/policy/external_data/user_cloud_external_data_manager.cc", "../ash/policy/external_data/user_cloud_external_data_manager.h", + "../ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc", + "../ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h", + "../ash/policy/handlers/bluetooth_policy_handler.cc", + "../ash/policy/handlers/bluetooth_policy_handler.h", + "../ash/policy/handlers/configuration_policy_handler_chromeos.cc", + "../ash/policy/handlers/configuration_policy_handler_chromeos.h", + "../ash/policy/handlers/device_dock_mac_address_source_handler.cc", + "../ash/policy/handlers/device_dock_mac_address_source_handler.h", + "../ash/policy/handlers/device_name_policy_handler.cc", + "../ash/policy/handlers/device_name_policy_handler.h", + "../ash/policy/handlers/device_name_policy_handler_impl.cc", + "../ash/policy/handlers/device_name_policy_handler_impl.h", + "../ash/policy/handlers/device_name_policy_handler_name_generator.cc", + "../ash/policy/handlers/device_name_policy_handler_name_generator.h", + "../ash/policy/handlers/device_wifi_allowed_handler.cc", + "../ash/policy/handlers/device_wifi_allowed_handler.h", + "../ash/policy/handlers/lacros_availability_policy_handler.cc", + "../ash/policy/handlers/lacros_availability_policy_handler.h", + "../ash/policy/handlers/lock_to_single_user_manager.cc", + "../ash/policy/handlers/lock_to_single_user_manager.h", + "../ash/policy/handlers/minimum_version_policy_handler.cc", + "../ash/policy/handlers/minimum_version_policy_handler.h", + "../ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc", + "../ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h", + "../ash/policy/handlers/powerwash_requirements_checker.cc", + "../ash/policy/handlers/powerwash_requirements_checker.h", + "../ash/policy/handlers/system_features_disable_list_policy_handler.cc", + "../ash/policy/handlers/system_features_disable_list_policy_handler.h", + "../ash/policy/handlers/system_proxy_handler.cc", + "../ash/policy/handlers/system_proxy_handler.h", + "../ash/policy/handlers/tpm_auto_update_mode_policy_handler.cc", + "../ash/policy/handlers/tpm_auto_update_mode_policy_handler.h", "../ash/power/auto_screen_brightness/adapter.cc", "../ash/power/auto_screen_brightness/adapter.h", "../ash/power/auto_screen_brightness/als_file_reader.cc", @@ -2777,38 +2814,6 @@ "platform_keys/platform_keys_service_factory.cc", "platform_keys/platform_keys_service_factory.h", "platform_keys/platform_keys_service_nss.cc", - "policy/handlers/adb_sideloading_allowance_mode_policy_handler.cc", - "policy/handlers/adb_sideloading_allowance_mode_policy_handler.h", - "policy/handlers/bluetooth_policy_handler.cc", - "policy/handlers/bluetooth_policy_handler.h", - "policy/handlers/configuration_policy_handler_chromeos.cc", - "policy/handlers/configuration_policy_handler_chromeos.h", - "policy/handlers/device_dock_mac_address_source_handler.cc", - "policy/handlers/device_dock_mac_address_source_handler.h", - "policy/handlers/device_name_policy_handler.cc", - "policy/handlers/device_name_policy_handler.h", - "policy/handlers/device_name_policy_handler_impl.cc", - "policy/handlers/device_name_policy_handler_impl.h", - "policy/handlers/device_name_policy_handler_name_generator.cc", - "policy/handlers/device_name_policy_handler_name_generator.h", - "policy/handlers/device_wifi_allowed_handler.cc", - "policy/handlers/device_wifi_allowed_handler.h", - "policy/handlers/lacros_availability_policy_handler.cc", - "policy/handlers/lacros_availability_policy_handler.h", - "policy/handlers/lock_to_single_user_manager.cc", - "policy/handlers/lock_to_single_user_manager.h", - "policy/handlers/minimum_version_policy_handler.cc", - "policy/handlers/minimum_version_policy_handler.h", - "policy/handlers/minimum_version_policy_handler_delegate_impl.cc", - "policy/handlers/minimum_version_policy_handler_delegate_impl.h", - "policy/handlers/powerwash_requirements_checker.cc", - "policy/handlers/powerwash_requirements_checker.h", - "policy/handlers/system_features_disable_list_policy_handler.cc", - "policy/handlers/system_features_disable_list_policy_handler.h", - "policy/handlers/system_proxy_handler.cc", - "policy/handlers/system_proxy_handler.h", - "policy/handlers/tpm_auto_update_mode_policy_handler.cc", - "policy/handlers/tpm_auto_update_mode_policy_handler.h", "policy/invalidation/affiliated_cloud_policy_invalidator.cc", "policy/invalidation/affiliated_cloud_policy_invalidator.h", "policy/invalidation/affiliated_invalidation_service_provider.cc", @@ -3486,6 +3491,8 @@ "../ash/policy/core/user_policy_test_helper.h", "../ash/policy/dlp/dlp_content_manager_test_helper.cc", "../ash/policy/dlp/dlp_content_manager_test_helper.h", + "../ash/policy/handlers/minimum_version_policy_test_helpers.cc", + "../ash/policy/handlers/minimum_version_policy_test_helpers.h", "../ash/settings/scoped_testing_cros_settings.cc", "../ash/settings/scoped_testing_cros_settings.h", "android_sms/fake_android_sms_app_manager.cc", @@ -3505,8 +3512,6 @@ "platform_keys/key_permissions/mock_key_permissions_service.h", "platform_keys/mock_platform_keys_service.cc", "platform_keys/mock_platform_keys_service.h", - "policy/handlers/minimum_version_policy_test_helpers.cc", - "policy/handlers/minimum_version_policy_test_helpers.h", "policy/remote_commands/future_value.h", "printing/printing_stubs.cc", "printing/printing_stubs.h", @@ -3770,6 +3775,7 @@ "../ash/drive/drivefs_native_message_host_unittest.cc", "../ash/drive/file_system_util_unittest.cc", "../ash/enhanced_network_tts/enhanced_network_tts_impl_unittest.cc", + "../ash/enhanced_network_tts/enhanced_network_tts_utils_unittest.cc", "../ash/exo/chrome_data_exchange_delegate_unittest.cc", "../ash/file_manager/app_service_file_tasks_unittest.cc", "../ash/file_manager/documents_provider_root_manager_unittest.cc", @@ -3950,6 +3956,19 @@ "../ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc", "../ash/policy/external_data/handlers/device_print_servers_external_data_handler_unittest.cc", "../ash/policy/external_data/handlers/device_printers_external_data_handler_unittest.cc", + "../ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc", + "../ash/policy/handlers/bluetooth_policy_handler_unittest.cc", + "../ash/policy/handlers/configuration_policy_handler_chromeos_unittest.cc", + "../ash/policy/handlers/device_dock_mac_address_source_handler_unittest.cc", + "../ash/policy/handlers/device_name_policy_handler_impl_unittest.cc", + "../ash/policy/handlers/device_name_policy_handler_name_generator_unittest.cc", + "../ash/policy/handlers/extension_cache_unittest.cc", + "../ash/policy/handlers/lock_to_single_user_manager_unittest.cc", + "../ash/policy/handlers/minimum_version_policy_handler_unittest.cc", + "../ash/policy/handlers/powerwash_requirements_checker_unittest.cc", + "../ash/policy/handlers/system_features_disable_list_policy_handler_unittest.cc", + "../ash/policy/handlers/system_proxy_handler_unittest.cc", + "../ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc", "../ash/power/auto_screen_brightness/adapter_unittest.cc", "../ash/power/auto_screen_brightness/als_file_reader_unittest.cc", "../ash/power/auto_screen_brightness/als_reader_unittest.cc", @@ -4169,19 +4188,6 @@ "phonehub/browser_tabs_model_provider_impl_unittest.cc", "platform_keys/key_permissions/arc_key_permissions_manager_delegate_unittest.cc", "platform_keys/key_permissions/key_permissions_service_impl_unittest.cc", - "policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc", - "policy/handlers/bluetooth_policy_handler_unittest.cc", - "policy/handlers/configuration_policy_handler_chromeos_unittest.cc", - "policy/handlers/device_dock_mac_address_source_handler_unittest.cc", - "policy/handlers/device_name_policy_handler_impl_unittest.cc", - "policy/handlers/device_name_policy_handler_name_generator_unittest.cc", - "policy/handlers/extension_cache_unittest.cc", - "policy/handlers/lock_to_single_user_manager_unittest.cc", - "policy/handlers/minimum_version_policy_handler_unittest.cc", - "policy/handlers/powerwash_requirements_checker_unittest.cc", - "policy/handlers/system_features_disable_list_policy_handler_unittest.cc", - "policy/handlers/system_proxy_handler_unittest.cc", - "policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc", "policy/invalidation/affiliated_cloud_policy_invalidator_unittest.cc", "policy/invalidation/affiliated_invalidation_service_provider_impl_unittest.cc", "policy/invalidation/fake_affiliated_invalidation_service_provider.cc", @@ -4606,7 +4612,7 @@ if (use_libfuzzer) { fuzzer_test("policy_fuzzer") { - sources = [ "policy/fuzzer/policy_fuzzer.cc" ] + sources = [ "../ash/policy/fuzzer/policy_fuzzer.cc" ] deps = [ ":policy_fuzzer_proto", @@ -4623,7 +4629,7 @@ } fuzzable_proto_library("policy_fuzzer_proto") { - sources = [ "policy/fuzzer/policy_fuzzer.proto" ] + sources = [ "../ash/policy/fuzzer/policy_fuzzer.proto" ] import_dirs = [ # Add the fuzzable (full-protobuf) .pb.h files into include directories.
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc index 0d2d8ea..f1cba3a2 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc
@@ -144,7 +144,8 @@ if (base::Contains(url_to_pwa_map_, url)) return; - url_to_pwa_map_[url] = web_app::GenerateAppIdFromURL(url); + url_to_pwa_map_[url] = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, url); } // AndroidSmsAppSetupControllerImpl::PwaDelegate:
diff --git a/chrome/browser/chromeos/boot_times_recorder.cc b/chrome/browser/chromeos/boot_times_recorder.cc index c030e99..11d3707 100644 --- a/chrome/browser/chromeos/boot_times_recorder.cc +++ b/chrome/browser/chromeos/boot_times_recorder.cc
@@ -14,28 +14,15 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" #include "base/lazy_instance.h" #include "base/location.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/system/sys_info.h" -#include "base/task/thread_pool.h" -#include "base/threading/thread.h" -#include "base/threading/thread_restrictions.h" -#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "base/trace_event/trace_event.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "chromeos/metrics/login_event_recorder.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_task_traits.h" @@ -53,12 +40,6 @@ namespace { -const char kUptime[] = "uptime"; -const char kDisk[] = "disk"; - -// The pointer to this object is used as a perfetto async event id. -static const char kBootTimes[] = "BootTimes"; - RenderWidgetHost* GetRenderWidgetHost(NavigationController* tab) { WebContents* web_contents = tab->DeprecatedGetWebContents(); if (web_contents) { @@ -93,171 +74,40 @@ return std::string(); } -// Appends the given buffer into the file. Returns the number of bytes -// written, or -1 on error. -// TODO(satorux): Move this to file_util. -int AppendFile(const base::FilePath& file_path, const char* data, int size) { - // Appending boot times to (probably) a symlink in /tmp is a security risk for - // developers with chromeos=1 builds. - if (!base::SysInfo::IsRunningOnChromeOS()) - return -1; - - FILE* file = base::OpenFile(file_path, "a"); - if (!file) - return -1; - - const int num_bytes_written = fwrite(data, 1, size, file); - base::CloseFile(file); - return num_bytes_written; -} - } // namespace namespace chromeos { #define FPL(value) FILE_PATH_LITERAL(value) -// Dir uptime & disk logs are located in. -static const base::FilePath::CharType kLogPath[] = FPL("/tmp"); -// Dir log{in,out} logs are located in. -static const base::FilePath::CharType kLoginLogPath[] = - FPL("/home/chronos/user"); -// Prefix for the time measurement files. -static const base::FilePath::CharType kUptimePrefix[] = FPL("uptime-"); -// Prefix for the disk usage files. -static const base::FilePath::CharType kDiskPrefix[] = FPL("disk-"); // Name of the time that Chrome's main() is called. -static const base::FilePath::CharType kChromeMain[] = FPL("chrome-main"); -// Delay in milliseconds before writing the login times to disk. -static const int64_t kLoginTimeWriteDelayMs = 3000; +constexpr base::FilePath::CharType kChromeMain[] = FPL("chrome-main"); // Names of login stats files. -static const base::FilePath::CharType kLoginSuccess[] = FPL("login-success"); -static const base::FilePath::CharType kChromeFirstRender[] = +constexpr base::FilePath::CharType kChromeFirstRender[] = FPL("chrome-first-render"); // Names of login UMA values. static const char kUmaLogin[] = "BootTime.Login"; static const char kUmaLoginNewUser[] = "BootTime.LoginNewUser"; -static const char kUmaLoginPrefix[] = "BootTime."; -static const char kUmaLogout[] = "ShutdownTime.Logout"; -static const char kUmaLogoutPrefix[] = "ShutdownTime."; -static const char kUmaRestart[] = "ShutdownTime.Restart"; +constexpr char kUmaLoginPrefix[] = "BootTime."; +constexpr char kUmaLogout[] = "ShutdownTime.Logout"; +constexpr char kUmaLogoutPrefix[] = "ShutdownTime."; +constexpr char kUmaRestart[] = "ShutdownTime.Restart"; // Name of file collecting login times. -static const base::FilePath::CharType kLoginTimes[] = FPL("login-times"); +constexpr base::FilePath::CharType kLoginTimes[] = FPL("login-times"); // Name of file collecting logout times. -static const char kLogoutTimes[] = "logout-times"; +constexpr char kLogoutTimes[] = "logout-times"; static base::LazyInstance<BootTimesRecorder>::DestructorAtExit g_boot_times_recorder = LAZY_INSTANCE_INITIALIZER; -// static -BootTimesRecorder::Stats BootTimesRecorder::Stats::GetCurrentStats() { - const base::FilePath kProcUptime(FPL("/proc/uptime")); - const base::FilePath kDiskStat(FPL("/sys/block/sda/stat")); - Stats stats; - // Callers of this method expect synchronous behavior. - // It's safe to allow IO here, because only virtual FS are accessed. - base::ThreadRestrictions::ScopedAllowIO allow_io; - base::ReadFileToString(kProcUptime, &stats.uptime_); - base::ReadFileToString(kDiskStat, &stats.disk_); - return stats; -} - -std::string BootTimesRecorder::Stats::SerializeToString() const { - if (uptime_.empty() && disk_.empty()) - return std::string(); - base::DictionaryValue dictionary; - dictionary.SetString(kUptime, uptime_); - dictionary.SetString(kDisk, disk_); - - std::string result; - if (!base::JSONWriter::Write(dictionary, &result)) { - LOG(WARNING) << "BootTimesRecorder::Stats::SerializeToString(): failed."; - return std::string(); - } - - return result; -} - -// static -BootTimesRecorder::Stats BootTimesRecorder::Stats::DeserializeFromString( - const std::string& source) { - if (source.empty()) - return Stats(); - - std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(source); - base::DictionaryValue* dictionary; - if (!value || !value->GetAsDictionary(&dictionary)) { - LOG(ERROR) << "BootTimesRecorder::Stats::DeserializeFromString(): not a " - "dictionary: '" << source << "'"; - return Stats(); - } - - Stats result; - if (!dictionary->GetString(kUptime, &result.uptime_) || - !dictionary->GetString(kDisk, &result.disk_)) { - LOG(ERROR) - << "BootTimesRecorder::Stats::DeserializeFromString(): format error: '" - << source << "'"; - return Stats(); - } - - return result; -} - -bool BootTimesRecorder::Stats::UptimeDouble(double* result) const { - std::string uptime = uptime_; - const size_t space_at = uptime.find_first_of(' '); - if (space_at == std::string::npos) - return false; - - uptime.resize(space_at); - - if (base::StringToDouble(uptime, result)) - return true; - - return false; -} - -void BootTimesRecorder::Stats::RecordStats(const std::string& name) const { - base::ThreadPool::PostTask( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&BootTimesRecorder::Stats::RecordStatsAsync, - base::Owned(new Stats(*this)), name)); -} - -void BootTimesRecorder::Stats::RecordStatsWithCallback( - const std::string& name, - base::OnceClosure callback) const { - base::ThreadPool::PostTaskAndReply( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&BootTimesRecorder::Stats::RecordStatsAsync, - base::Owned(new Stats(*this)), name), - std::move(callback)); -} - -void BootTimesRecorder::Stats::RecordStatsAsync( - const base::FilePath::StringType& name) const { - const base::FilePath log_path(kLogPath); - const base::FilePath uptime_output = - log_path.Append(base::FilePath(kUptimePrefix + name)); - const base::FilePath disk_output = - log_path.Append(base::FilePath(kDiskPrefix + name)); - - // Append numbers to the files. - AppendFile(uptime_output, uptime_.data(), uptime_.size()); - AppendFile(disk_output, disk_.data(), disk_.size()); -} - BootTimesRecorder::BootTimesRecorder() : have_registered_(false), login_done_(false), restart_requested_(false) { - login_time_markers_.reserve(30); - logout_time_markers_.reserve(30); } BootTimesRecorder::~BootTimesRecorder() { @@ -268,115 +118,6 @@ return g_boot_times_recorder.Pointer(); } -BootTimesRecorder::TimeMarker::TimeMarker(const char* name, - absl::optional<std::string> url, - bool send_to_uma) - : name_(name), - time_(base::Time::NowFromSystemTime()), - url_(url), - send_to_uma_(send_to_uma) {} - -BootTimesRecorder::TimeMarker::TimeMarker(const TimeMarker& other) = default; - -BootTimesRecorder::TimeMarker::~TimeMarker() = default; - -void BootTimesRecorder::AddLoginTimeMarkerWithURL(const char* marker_name, - const std::string& url) { - AddMarker(&login_time_markers_, TimeMarker(marker_name, url, false)); -} - -// static -void BootTimesRecorder::WriteTimes(const std::string base_name, - const std::string uma_name, - const std::string uma_prefix, - std::vector<TimeMarker> login_times) { - const int kMinTimeMillis = 1; - const int kMaxTimeMillis = 30000; - const int kNumBuckets = 100; - const base::FilePath log_path(kLoginLogPath); - - // Need to sort by time since the entries may have been pushed onto the - // vector (on the UI thread) in a different order from which they were - // created (potentially on other threads). - std::sort(login_times.begin(), login_times.end()); - - base::Time first = login_times.front().time(); - base::Time last = login_times.back().time(); - base::TimeDelta total = last - first; - base::HistogramBase* total_hist = base::Histogram::FactoryTimeGet( - uma_name, - base::TimeDelta::FromMilliseconds(kMinTimeMillis), - base::TimeDelta::FromMilliseconds(kMaxTimeMillis), - kNumBuckets, - base::HistogramBase::kUmaTargetedHistogramFlag); - total_hist->AddTime(total); - std::string output = - base::StringPrintf("%s: %.2f", uma_name.c_str(), total.InSecondsF()); - base::Time prev = first; - // Convert base::Time to base::TimeTicks for tracing. - auto time2timeticks = [](const base::Time& ts) { - return base::TimeTicks::Now() - (base::Time::Now() - ts); - }; - // Send first event to name the track: - // "In Chrome, we usually don't bother setting explicit track names. If none - // is provided, the track is named after the first event on the track." - TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( - "startup", kBootTimes, TRACE_ID_LOCAL(kBootTimes), time2timeticks(prev)); - - for (unsigned int i = 0; i < login_times.size(); ++i) { - TimeMarker tm = login_times[i]; - - if (tm.url().has_value()) { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1( - "startup", tm.name(), TRACE_ID_LOCAL(kBootTimes), - time2timeticks(prev), "url", *tm.url()); - TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1( - "startup", tm.name(), TRACE_ID_LOCAL(kBootTimes), - time2timeticks(tm.time()), "url", *tm.url()); - } else { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( - "startup", tm.name(), TRACE_ID_LOCAL(kBootTimes), - time2timeticks(prev)); - TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0("startup", tm.name(), - TRACE_ID_LOCAL(kBootTimes), - time2timeticks(tm.time())); - } - - base::TimeDelta since_first = tm.time() - first; - base::TimeDelta since_prev = tm.time() - prev; - std::string name; - - if (tm.send_to_uma()) { - name = uma_prefix + tm.name(); - base::HistogramBase* prev_hist = base::Histogram::FactoryTimeGet( - name, - base::TimeDelta::FromMilliseconds(kMinTimeMillis), - base::TimeDelta::FromMilliseconds(kMaxTimeMillis), - kNumBuckets, - base::HistogramBase::kUmaTargetedHistogramFlag); - prev_hist->AddTime(since_prev); - } else { - name = tm.name(); - } - output += - base::StringPrintf( - "\n%.2f +%.4f %s", - since_first.InSecondsF(), - since_prev.InSecondsF(), - name.data()); - if (tm.url().has_value()) { - output += ": "; - output += *tm.url(); - } - prev = tm.time(); - } - output += '\n'; - TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( - "startup", kBootTimes, TRACE_ID_LOCAL(kBootTimes), time2timeticks(prev)); - - base::WriteFile(log_path.Append(base_name), output.data(), output.size()); -} - void BootTimesRecorder::LoginDone(bool is_user_new) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (login_done_) @@ -394,13 +135,9 @@ content::NotificationService::AllSources()); render_widget_host_observations_.RemoveAllObservations(); } - // Don't swamp the background thread right away. - base::ThreadPool::PostDelayedTask( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&WriteTimes, kLoginTimes, - (is_user_new ? kUmaLoginNewUser : kUmaLogin), - kUmaLoginPrefix, login_time_markers_), - base::TimeDelta::FromMilliseconds(kLoginTimeWriteDelayMs)); + LoginEventRecorder::Get()->WriteLoginTimes( + kLoginTimes, (is_user_new ? kUmaLoginNewUser : kUmaLogin), + kUmaLoginPrefix); } void BootTimesRecorder::WriteLogoutTimes() { @@ -409,11 +146,14 @@ // has already been terminated. DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) || BrowserThread::CurrentlyOn(BrowserThread::UI)); + LoginEventRecorder::Get()->WriteLogoutTimes( + kLogoutTimes, (restart_requested_ ? kUmaRestart : kUmaLogout), + kUmaLogoutPrefix); +} - WriteTimes(kLogoutTimes, - (restart_requested_ ? kUmaRestart : kUmaLogout), - kUmaLogoutPrefix, - logout_time_markers_); +void BootTimesRecorder::AddLoginTimeMarkerWithURL(const char* marker_name, + const std::string& url) { + LoginEventRecorder::Get()->AddLoginTimeMarkerWithURL(marker_name, url, false); } // static @@ -432,15 +172,15 @@ // Note that kLogoutStartedLast is not cleared on format error to stay in // logs in case of other fatal system errors. - const Stats logout_started_last_stats = - Stats::DeserializeFromString(logout_started_last_str); + const LoginEventRecorder::Stats logout_started_last_stats = + LoginEventRecorder::Stats::DeserializeFromString(logout_started_last_str); if (logout_started_last_stats.uptime().empty()) return; double logout_started_last; double uptime; if (!logout_started_last_stats.UptimeDouble(&logout_started_last) || - !Stats::GetCurrentStats().UptimeDouble(&uptime)) { + !LoginEventRecorder::Stats::GetCurrentStats().UptimeDouble(&uptime)) { return; } @@ -451,24 +191,25 @@ } // Write /tmp/uptime-logout-started as well. - const char kLogoutStarted[] = "logout-started"; + constexpr char kLogoutStarted[] = "logout-started"; logout_started_last_stats.RecordStatsWithCallback( kLogoutStarted, base::BindOnce(&BootTimesRecorder::ClearLogoutStartedLastPreference)); } void BootTimesRecorder::OnLogoutStarted(PrefService* state) { - const std::string uptime = Stats::GetCurrentStats().SerializeToString(); + const std::string uptime = + LoginEventRecorder::Stats::GetCurrentStats().SerializeToString(); if (!uptime.empty()) state->SetString(prefs::kLogoutStartedLast, uptime); } void BootTimesRecorder::RecordCurrentStats(const std::string& name) { - Stats::GetCurrentStats().RecordStats(name); + LoginEventRecorder::Get()->RecordCurrentStats(name); } void BootTimesRecorder::SaveChromeMainStats() { - chrome_main_stats_ = Stats::GetCurrentStats(); + chrome_main_stats_ = LoginEventRecorder::Stats::GetCurrentStats(); } void BootTimesRecorder::RecordChromeMainStats() { @@ -480,7 +221,7 @@ if (login_done_) return; - login_time_markers_.clear(); + LoginEventRecorder::Get()->ClearLoginTimeMarkers(); AddLoginTimeMarker("LoginStarted", false); if (!have_registered_) { have_registered_ = true; @@ -493,44 +234,12 @@ void BootTimesRecorder::AddLoginTimeMarker(const char* marker_name, bool send_to_uma) { - AddMarker( - &login_time_markers_, - TimeMarker(marker_name, absl::optional<std::string>(), send_to_uma)); + LoginEventRecorder::Get()->AddLoginTimeMarker(marker_name, send_to_uma); } void BootTimesRecorder::AddLogoutTimeMarker(const char* marker_name, bool send_to_uma) { - AddMarker( - &logout_time_markers_, - TimeMarker(marker_name, absl::optional<std::string>(), send_to_uma)); -} - -// static -void BootTimesRecorder::AddMarker(std::vector<TimeMarker>* vector, - TimeMarker marker) { - // The marker vectors can only be safely manipulated on the main thread. - // If we're late in the process of shutting down (eg. as can be the case at - // logout), then we have to assume we're on the main thread already. - if (!BrowserThread::IsThreadInitialized(BrowserThread::UI) || - BrowserThread::CurrentlyOn(BrowserThread::UI)) { - vector->push_back(marker); - } else { - // Add the marker on the UI thread. - // Note that it's safe to use an unretained pointer to the vector because - // BootTimesRecorder's lifetime exceeds that of the UI thread message loop. - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&BootTimesRecorder::AddMarker, - base::Unretained(vector), marker)); - } -} - -void BootTimesRecorder::RecordAuthenticationSuccess() { - AddLoginTimeMarker("Authenticate", true); - RecordCurrentStats(kLoginSuccess); -} - -void BootTimesRecorder::RecordAuthenticationFailure() { - // Do nothing for now. + LoginEventRecorder::Get()->AddLogoutTimeMarker(marker_name, send_to_uma); } void BootTimesRecorder::Observe(int type,
diff --git a/chrome/browser/chromeos/boot_times_recorder.h b/chrome/browser/chromeos/boot_times_recorder.h index d7491dc..a8dbe565 100644 --- a/chrome/browser/chromeos/boot_times_recorder.h +++ b/chrome/browser/chromeos/boot_times_recorder.h
@@ -10,16 +10,12 @@ #include "base/atomic_sequence_num.h" #include "base/callback_forward.h" #include "base/compiler_specific.h" -#include "base/macros.h" #include "base/scoped_multi_source_observation.h" -#include "base/task/cancelable_task_tracker.h" -#include "base/time/time.h" -#include "chromeos/login/auth/login_event_recorder.h" +#include "chromeos/metrics/login_event_recorder.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_observer.h" -#include "third_party/abseil-cpp/absl/types/optional.h" class PrefService; @@ -27,29 +23,20 @@ // BootTimesRecorder is used to record times of boot, login, and logout. class BootTimesRecorder : public content::NotificationObserver, - public content::RenderWidgetHostObserver, - public LoginEventRecorder::Delegate { + public content::RenderWidgetHostObserver { public: BootTimesRecorder(); + BootTimesRecorder(const BootTimesRecorder&) = delete; + BootTimesRecorder& operator=(const BootTimesRecorder&) = delete; ~BootTimesRecorder() override; static BootTimesRecorder* Get(); - // LoginEventRecorder::Delegate override. - void AddLoginTimeMarker(const char* marker_name, bool send_to_uma) override; - void RecordAuthenticationSuccess() override; - void RecordAuthenticationFailure() override; - - // Add a time marker for logout. A timeline will be dumped to - // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true - // the time between this marker and the last will be sent to UMA with - // the identifier ShutdownTime.|marker_name|. + // TODO(oshima): Deprecate following 3 methods and just use + // LoginEventRecorder. + void AddLoginTimeMarker(const char* marker_name, bool send_to_uma); void AddLogoutTimeMarker(const char* marker_name, bool send_to_uma); - // Records current uptime and disk usage for metrics use. - // Posts task to file thread. - // name will be used as part of file names in /tmp. - // Existing stats files will not be overwritten. void RecordCurrentStats(const std::string& name); // Saves away the stats at main, so the can be recorded later. At main() time @@ -93,87 +80,22 @@ content::RenderWidgetHost* widget_host) override; private: - class TimeMarker { - public: - TimeMarker(const char* name, - absl::optional<std::string> url, - bool send_to_uma); - TimeMarker(const TimeMarker& other); - ~TimeMarker(); - - const char* name() const { return name_; } - base::Time time() const { return time_; } - const absl::optional<std::string>& url() const { return url_; } - bool send_to_uma() const { return send_to_uma_; } - - // comparitor for sorting - bool operator<(const TimeMarker& other) const { - return time_ < other.time_; - } - - private: - friend class std::vector<TimeMarker>; - const char* name_; - base::Time time_; - absl::optional<std::string> url_; - bool send_to_uma_; - }; - - class Stats { - public: - // Initializes stats with current /proc values. - static Stats GetCurrentStats(); - - // Returns JSON representation. - std::string SerializeToString() const; - - // Creates new object from JSON representation. - static Stats DeserializeFromString(const std::string& value); - - const std::string& uptime() const { return uptime_; } - const std::string& disk() const { return disk_; } - - // Writes "uptime in seconds" to result. (This is first field in uptime_.) - // Returns true on successful conversion. - bool UptimeDouble(double* result) const; - - void RecordStats(const std::string& name) const; - void RecordStatsWithCallback(const std::string& name, - base::OnceClosure callback) const; - - private: - // Runs asynchronously when RecordStats(WithCallback) is called. - void RecordStatsAsync(const std::string& name) const; - - std::string uptime_; - std::string disk_; - }; - // Adds optional URL to the marker. void AddLoginTimeMarkerWithURL(const char* marker_name, const std::string& url); - static void WriteTimes(const std::string base_name, - const std::string uma_name, - const std::string uma_prefix, - std::vector<TimeMarker> login_times); - static void AddMarker(std::vector<TimeMarker>* vector, TimeMarker marker); - // Clear saved logout-started metric in Local State. // This method is called when logout-state was writen to file. static void ClearLogoutStartedLastPreference(); - // Used to hold the stats at main(). - Stats chrome_main_stats_; + // Used to hold the stats at mai(). + LoginEventRecorder::Stats chrome_main_stats_; // Used to track notifications for login. content::NotificationRegistrar registrar_; base::AtomicSequenceNumber num_tabs_; bool have_registered_; - std::vector<TimeMarker> login_time_markers_; - std::vector<TimeMarker> logout_time_markers_; - base::ScopedMultiSourceObservation<content::RenderWidgetHost, content::RenderWidgetHostObserver> render_widget_host_observations_{this}; @@ -181,8 +103,6 @@ bool login_done_; bool restart_requested_; - - DISALLOW_COPY_AND_ASSIGN(BootTimesRecorder); }; } // namespace chromeos
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index c200518..9d184c5 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -97,6 +97,7 @@ #include "chrome/browser/ash/ownership/owner_settings_service_ash_factory.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" #include "chrome/browser/ash/policy/core/device_local_account.h" +#include "chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h" #include "chrome/browser/ash/power/auto_screen_brightness/controller.h" #include "chrome/browser/ash/power/freezer_cgroup_process_manager.h" #include "chrome/browser/ash/power/idle_action_warning_observer.h" @@ -135,7 +136,6 @@ #include "chrome/browser/chromeos/network_change_manager_client.h" #include "chrome/browser/chromeos/note_taking_helper.h" #include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_manager_impl.h" -#include "chrome/browser/chromeos/policy/handlers/lock_to_single_user_manager.h" #include "chrome/browser/chromeos/printing/bulk_printers_calculator_factory.h" #include "chrome/browser/chromeos/scheduler_configuration_manager.h" #include "chrome/browser/chromeos/startup_settings_cache.h" @@ -177,7 +177,6 @@ #include "chromeos/dbus/session_manager/session_manager_client.h" #include "chromeos/dbus/util/version_loader.h" #include "chromeos/disks/disk_mount_manager.h" -#include "chromeos/login/auth/login_event_recorder.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/login/session/session_termination_manager.h" #include "chromeos/memory/memory_ablation_study.h" @@ -724,7 +723,6 @@ // Now that the file thread exists we can record our stats. BootTimesRecorder::Get()->RecordChromeMainStats(); - LoginEventRecorder::Get()->SetDelegate(BootTimesRecorder::Get()); // Trigger prefetching of ownership status. DeviceSettingsService::Get()->Load();
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index 3f0ec52..02bbc8a 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -1987,6 +1987,7 @@ web_app::SystemAppLaunchParams swa_params; swa_params.url = GURL(params->url); web_app::LaunchSystemWebAppAsync(profile, *app_type, swa_params); + web_app::FlushSystemWebAppLaunchesForTesting(profile); return RespondNow(NoArguments()); }
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc index bbd0f04e..3f00045 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc
@@ -366,8 +366,7 @@ }; // TODO(crbug.com/1201545): Fix flakiness. -IN_PROC_BROWSER_TEST_F(AutotestPrivateSystemWebAppsTest, - DISABLED_SystemWebApps) { +IN_PROC_BROWSER_TEST_F(AutotestPrivateSystemWebAppsTest, SystemWebApps) { ASSERT_TRUE(RunExtensionTest("autotest_private", {.custom_arg = "systemWebApps"}, {.load_as_component = true}))
diff --git a/chrome/browser/chromeos/full_restore/app_launch_handler.h b/chrome/browser/chromeos/full_restore/app_launch_handler.h index cdfca0d..b9de06d 100644 --- a/chrome/browser/chromeos/full_restore/app_launch_handler.h +++ b/chrome/browser/chromeos/full_restore/app_launch_handler.h
@@ -46,7 +46,7 @@ private: void LaunchApp(apps::mojom::AppType app_type, const std::string& app_id); - void LaunchSystemWebAppOrChromeApp( + virtual void LaunchSystemWebAppOrChromeApp( apps::mojom::AppType app_type, const std::string& app_id, const ::full_restore::RestoreData::LaunchList& launch_list);
diff --git a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc index 0c49d8b..0ff2cd0 100644 --- a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc +++ b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc
@@ -7,6 +7,7 @@ #include <utility> #include <vector> +#include "ash/shell.h" #include "base/callback.h" #include "base/containers/contains.h" #include "chrome/browser/apps/app_service/app_platform_metrics.h" @@ -17,26 +18,61 @@ #include "chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.h" #include "chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chromeos/services/cros_healthd/public/cpp/service_connection.h" #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h" +#include "components/arc/arc_util.h" #include "components/full_restore/app_launch_info.h" #include "components/full_restore/full_restore_read_handler.h" #include "components/full_restore/restore_data.h" #include "components/services/app_service/public/cpp/types_util.h" - -namespace chromeos { -namespace full_restore { +#include "components/services/app_service/public/mojom/types.mojom.h" +#include "ui/wm/public/activation_client.h" namespace { +// If the app launching condition doesn't match, e.g. the app is not ready, +// and after checking `kMaxCheckingNum` times, there is no improvement, move to +// the next window to launch. +constexpr int kMaxCheckingNum = 3; + +// Time interval between each checking for the app launching condition, e.g. the +// memory pressure level, or whether the app is ready. +constexpr base::TimeDelta kAppLaunchCheckingDelay = + base::TimeDelta::FromSeconds(1); + +// Delay between each app launching. +constexpr base::TimeDelta kAppLaunchDelay = base::TimeDelta::FromSeconds(3); + constexpr int kCpuUsageRefreshIntervalInSeconds = 1; constexpr int kCpuUsageCountWindowLength = 6 * kCpuUsageRefreshIntervalInSeconds; } // namespace -ArcAppLaunchHandler::ArcAppLaunchHandler() = default; -ArcAppLaunchHandler::~ArcAppLaunchHandler() = default; +namespace chromeos { +namespace full_restore { + +ArcAppLaunchHandler::ArcAppLaunchHandler() { + if (aura::Env::HasInstance()) + env_observer_.Observe(aura::Env::GetInstance()); + + if (ash::Shell::HasInstance() && ash::Shell::Get()->GetPrimaryRootWindow()) { + auto* activation_client = + wm::GetActivationClient(ash::Shell::Get()->GetPrimaryRootWindow()); + if (activation_client) + activation_client->AddObserver(this); + } +} + +ArcAppLaunchHandler::~ArcAppLaunchHandler() { + if (ash::Shell::HasInstance() && ash::Shell::Get()->GetPrimaryRootWindow()) { + auto* activation_client = + wm::GetActivationClient(ash::Shell::Get()->GetPrimaryRootWindow()); + if (activation_client) + activation_client->RemoveObserver(this); + } +} void ArcAppLaunchHandler::RestoreArcApps( FullRestoreAppLaunchHandler* app_launch_handler) { @@ -81,7 +117,7 @@ return; if (!apps_util::IsInstalled(update.Readiness())) { - RemoveApp(update.AppId()); + RemoveWindowsForApp(update.AppId()); return; } @@ -120,6 +156,74 @@ StartCpuUsageCount(); } +void ArcAppLaunchHandler::LaunchApp(const std::string& app_id) { + if (!IsAppReady(app_id)) + return; + + DCHECK(handler_); + const auto it = handler_->restore_data_->app_id_to_launch_list().find(app_id); + if (it == handler_->restore_data_->app_id_to_launch_list().end()) + return; + + if (it->second.empty()) { + handler_->restore_data_->RemoveApp(app_id); + return; + } + + for (const auto& data_it : it->second) + LaunchApp(app_id, data_it.first); + + RemoveWindowsForApp(app_id); +} + +void ArcAppLaunchHandler::OnWindowActivated( + ::wm::ActivationChangeObserver::ActivationReason reason, + aura::Window* new_active, + aura::Window* old_active) { + const auto session_id = arc::GetWindowSessionId(new_active); + if (!session_id.has_value()) + return; + + const std::string* arc_app_id = + new_active->GetProperty(::full_restore::kAppIdKey); + if (!arc_app_id || arc_app_id->empty() || !IsAppReady(*arc_app_id)) + return; + + auto it = session_id_to_window_id_.find(session_id.value()); + if (it == session_id_to_window_id_.end()) + return; + + RemoveWindow(*arc_app_id, it->second); + LaunchApp(*arc_app_id, it->second); +} + +void ArcAppLaunchHandler::OnWindowInitialized(aura::Window* window) { + // An app window has type WINDOW_TYPE_NORMAL, a WindowDelegate and + // is a top level views widget. Tooltips, menus, and other kinds of transient + // windows that can't activate are filtered out. + if (window->GetType() != aura::client::WINDOW_TYPE_NORMAL || + !window->delegate()) + return; + views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); + if (!widget || !widget->is_top_level() || + !arc::GetWindowSessionId(window).has_value()) { + return; + } + + observed_windows_.AddObservation(window); +} + +void ArcAppLaunchHandler::OnWindowDestroying(aura::Window* window) { + DCHECK(observed_windows_.IsObservingSource(window)); + observed_windows_.RemoveObservation(window); + + const auto session_id = arc::GetWindowSessionId(window); + if (!session_id.has_value()) + return; + + session_id_to_window_id_.erase(session_id.value()); +} + void ArcAppLaunchHandler::LoadRestoreData() { DCHECK(handler_); apps::AppRegistryCache& cache = @@ -176,6 +280,8 @@ window_info->window_id = arc_session_id; ::full_restore::FullRestoreReadHandler::GetInstance() ->SetArcSessionIdForWindowId(arc_session_id, data_it.first); + window_id_to_session_id_[data_it.first] = arc_session_id; + session_id_to_window_id_[arc_session_id] = data_it.first; bool launch_ghost_window = false; #if BUILDFLAG(ENABLE_WAYLAND_SERVER) @@ -213,7 +319,8 @@ } bool ArcAppLaunchHandler::HasRestoreData() { - return !(windows_.empty() && no_stack_windows_.empty()); + return !(windows_.empty() && no_stack_windows_.empty() && + pending_windows_.empty()); } bool ArcAppLaunchHandler::CanLaunchApp() { @@ -226,7 +333,117 @@ } } -void ArcAppLaunchHandler::RemoveApp(const std::string& app_id) { +bool ArcAppLaunchHandler::IsAppReady(const std::string& app_id) { + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(handler_->profile_); + if (!prefs) + return false; + + std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(app_id); + if (!app_info || app_info->suspended || !app_info->ready) + return false; + + return true; +} + +void ArcAppLaunchHandler::MaybeLaunchApp() { + if (!CanLaunchApp()) + return; + + for (auto it = pending_windows_.begin(); it != pending_windows_.end(); ++it) { + if (IsAppReady(it->app_id)) { + LaunchApp(it->app_id, it->window_id); + pending_windows_.erase(it); + MaybeReStartTimer(kAppLaunchDelay); + return; + } + } + + if (!windows_.empty()) { + auto it = windows_.begin(); + if (IsAppReady(it->second.app_id)) { + launch_count_ = 0; + LaunchApp(it->second.app_id, it->second.window_id); + windows_.erase(it); + MaybeReStartTimer(kAppLaunchDelay); + } else { + ++launch_count_; + if (launch_count_ >= kMaxCheckingNum) { + pending_windows_.push_back({it->second.app_id, it->second.window_id}); + windows_.erase(it); + launch_count_ = 0; + } else if (launch_count_ == 1) { + MaybeReStartTimer(kAppLaunchCheckingDelay); + } + } + return; + } + + for (auto it = no_stack_windows_.begin(); it != no_stack_windows_.end(); + ++it) { + if (IsAppReady(it->app_id)) { + LaunchApp(it->app_id, it->window_id); + no_stack_windows_.erase(it); + MaybeReStartTimer(kAppLaunchDelay); + return; + } + } +} + +void ArcAppLaunchHandler::LaunchApp(const std::string& app_id, + int32_t window_id) { + DCHECK(handler_); + const auto it = handler_->restore_data_->app_id_to_launch_list().find(app_id); + if (it == handler_->restore_data_->app_id_to_launch_list().end()) + return; + + if (it->second.empty()) { + handler_->restore_data_->RemoveApp(app_id); + return; + } + + const auto data_it = it->second.find(window_id); + if (data_it == it->second.end()) + return; + + auto* proxy = apps::AppServiceProxyFactory::GetForProfile(handler_->profile_); + DCHECK(proxy); + + DCHECK(data_it->second->event_flag.has_value()); + + apps::mojom::WindowInfoPtr window_info = + HandleArcWindowInfo(data_it->second->GetAppWindowInfo()); + const auto window_it = window_id_to_session_id_.find(window_id); + if (window_it != window_id_to_session_id_.end()) { + window_info->window_id = window_it->second; + window_id_to_session_id_.erase(window_it); + } else { + // Set an ARC session id to find the restore window id based on the new + // created ARC task id in FullRestoreReadHandler. + int32_t arc_session_id = + ::full_restore::FullRestoreReadHandler::GetInstance() + ->GetArcSessionId(); + window_info->window_id = arc_session_id; + ::full_restore::FullRestoreReadHandler::GetInstance() + ->SetArcSessionIdForWindowId(arc_session_id, window_id); + window_id_to_session_id_[window_id] = arc_session_id; + } + + if (data_it->second->intent.has_value()) { + proxy->LaunchAppWithIntent(app_id, data_it->second->event_flag.value(), + std::move(data_it->second->intent.value()), + apps::mojom::LaunchSource::kFromFullRestore, + std::move(window_info)); + } else { + proxy->Launch(app_id, data_it->second->event_flag.value(), + apps::mojom::LaunchSource::kFromFullRestore, + std::move(window_info)); + } + + if (!HasRestoreData()) + StopRestore(); +} + +void ArcAppLaunchHandler::RemoveWindowsForApp(const std::string& app_id) { app_ids_.erase(app_id); std::vector<int32_t> window_stacks; for (auto& it : windows_) { @@ -246,6 +463,73 @@ for (auto it : windows) no_stack_windows_.erase(it); + windows.clear(); + + for (auto it = pending_windows_.begin(); it != pending_windows_.end(); ++it) { + if (it->app_id == app_id) + windows.push_back(it); + } + + for (auto it : windows) + pending_windows_.erase(it); +} + +void ArcAppLaunchHandler::RemoveWindow(const std::string& app_id, + int32_t window_id) { + for (auto& it : windows_) { + if (it.second.app_id == app_id && it.second.window_id == window_id) { + windows_.erase(it.first); + return; + } + } + + for (auto it = no_stack_windows_.begin(); it != no_stack_windows_.end(); + ++it) { + if (it->app_id == app_id && it->window_id == window_id) { + no_stack_windows_.erase(it); + return; + } + } + + for (auto it = pending_windows_.begin(); it != pending_windows_.end(); ++it) { + if (it->app_id == app_id && it->window_id == window_id) { + pending_windows_.erase(it); + return; + } + } +} + +void ArcAppLaunchHandler::MaybeReStartTimer(const base::TimeDelta& delay) { + DCHECK(app_launch_timer_); + + // If there is no window to be launched, stop the timer. + if (!HasRestoreData()) { + StopRestore(); + return; + } + + if (current_delay_ == delay) + return; + + // If the delay is changed, restart the timer. + if (app_launch_timer_->IsRunning()) + app_launch_timer_->Stop(); + + current_delay_ = delay; + app_launch_timer_->Start( + FROM_HERE, current_delay_, + base::BindRepeating(&ArcAppLaunchHandler::MaybeLaunchApp, + weak_ptr_factory_.GetWeakPtr())); +} + +void ArcAppLaunchHandler::StopRestore() { + if (app_launch_timer_ && app_launch_timer_->IsRunning()) + app_launch_timer_->Stop(); + app_launch_timer_.reset(); + + if (stop_restore_timer_ && stop_restore_timer_->IsRunning()) + stop_restore_timer_->Stop(); + stop_restore_timer_.reset(); } int ArcAppLaunchHandler::GetCpuUsageRate() {
diff --git a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h index a469cdf4..993e260 100644 --- a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h +++ b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h
@@ -9,6 +9,7 @@ #include <map> #include "base/memory/weak_ptr.h" +#include "base/scoped_multi_source_observation.h" #include "base/scoped_observation.h" #include "base/timer/timer.h" #include "chromeos/dbus/resourced/resourced_client.h" @@ -16,6 +17,11 @@ #include "components/services/app_service/public/cpp/app_registry_cache.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/aura/env.h" +#include "ui/aura/env_observer.h" +#include "ui/aura/window.h" +#include "ui/aura/window_observer.h" +#include "ui/wm/public/activation_change_observer.h" namespace apps { class AppUpdate; @@ -44,7 +50,10 @@ // 2. Add app launch policy. // 3. Check whether the ARC app is ready before launch the ARC apps. class ArcAppLaunchHandler : public apps::AppRegistryCache::Observer, - public chromeos::ResourcedClient::Observer { + public chromeos::ResourcedClient::Observer, + public wm::ActivationChangeObserver, + public aura::EnvObserver, + public aura::WindowObserver { public: struct WindowInfo { std::string app_id; @@ -67,6 +76,20 @@ void OnAppConnectionReady(); + void LaunchApp(const std::string& app_id); + + // wm::ActivationChangeObserver: + void OnWindowActivated( + ::wm::ActivationChangeObserver::ActivationReason reason, + aura::Window* new_active, + aura::Window* old_active) override; + + // aura::EnvObserver: + void OnWindowInitialized(aura::Window* window) override; + + // aura::WindowObserver: + void OnWindowDestroying(aura::Window* window) override; + private: friend ArcAppLaunchHandlerArcAppBrowserTest; @@ -89,8 +112,26 @@ // Returns true if the app can be launched. Otherwise, returns false. bool CanLaunchApp(); - // Invoked when the app of the given `app_id` is removed. - void RemoveApp(const std::string& app_id); + // Returns true if the app is ready to be launched. Otherwise, returns false. + bool IsAppReady(const std::string& app_id); + + // Checks the app launching condition. If we can launch an app, launch the app + // following the window stack priority. + void MaybeLaunchApp(); + + void LaunchApp(const std::string& app_id, int32_t window_id); + + // Removes all windows records related with `app_id` from `windows_`, + // `no_stack_windows_`, and `pending_windows_`. + void RemoveWindowsForApp(const std::string& app_id); + + // Removes the window record related with `app_id` and `window_id` from + // `windows_`, `no_stack_windows_`, or `pending_windows_`. + void RemoveWindow(const std::string& app_id, int32_t window_id); + + void MaybeReStartTimer(const base::TimeDelta& delay); + + void StopRestore(); // Returns [0, 100] as percentage of device CPU usage rate. int GetCpuUsageRate(); @@ -117,8 +158,34 @@ // the windows to be restored. std::list<WindowInfo> no_stack_windows_; + // If the app launching condition doesn't match, e.g. the app is not ready, + // and after checking `kMaxCheckingNum` times, there is no improvement, the + // window is moved to `pending_windows_` to be launched later. + std::list<WindowInfo> pending_windows_; + + std::map<int32_t, int32_t> window_id_to_session_id_; + std::map<int32_t, int32_t> session_id_to_window_id_; + ArcWindowHandler* window_handler_ = nullptr; + // The number to record how many times the current top window has been + // launched. + int launch_count_ = 0; + + // A repeating timer to check whether we can restore the ARC apps. + std::unique_ptr<base::RepeatingTimer> app_launch_timer_; + + // A one shot timer to stop the restoration process. + std::unique_ptr<base::OneShotTimer> stop_restore_timer_; + + // The timer delay. + base::TimeDelta current_delay_; + + base::ScopedObservation<aura::Env, aura::EnvObserver> env_observer_{this}; + + base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver> + observed_windows_{this}; + chromeos::ResourcedClient::PressureLevel pressure_level_ = chromeos::ResourcedClient::PressureLevel::MODERATE;
diff --git a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc index d227bd9..30da607 100644 --- a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc +++ b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc
@@ -756,10 +756,16 @@ EXPECT_EQ(kDeskId, window->GetProperty(aura::client::kWindowWorkspaceKey)); // Windows created from full restore are not activated. They will become - // activatable after a post task is run. + // activatable after a couple seconds. EXPECT_FALSE(views::Widget::GetWidgetForNativeView(window)->IsActive()); EXPECT_FALSE(wm::CanActivateWindow(window)); - base::RunLoop().RunUntilIdle(); + + // Wait a couple seconds and verify the window is now activatable. + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(3)); + run_loop.Run(); + EXPECT_TRUE(wm::CanActivateWindow(window)); EXPECT_EQ(0, ::full_restore::FetchRestoreWindowId(extension->id()));
diff --git a/chrome/browser/chromeos/input_method/assistive_suggester.cc b/chrome/browser/chromeos/input_method/assistive_suggester.cc index ad04bd6..eda45099 100644 --- a/chrome/browser/chromeos/input_method/assistive_suggester.cc +++ b/chrome/browser/chromeos/input_method/assistive_suggester.cc
@@ -348,6 +348,12 @@ prefs::kAssistPredictiveWritingEnabled); } +bool AssistiveSuggester::IsExpandedMultiWordSuggestEnabled() { + return IsMultiWordSuggestEnabled() && + base::FeatureList::IsEnabled( + chromeos::features::kAssistMultiWordExpanded); +} + DisabledReason AssistiveSuggester::GetDisabledReasonForPersonalInfo() { if (!base::FeatureList::IsEnabled(chromeos::features::kAssistPersonalInfo)) { return DisabledReason::kFeatureFlagOff; @@ -461,7 +467,8 @@ void AssistiveSuggester::OnExternalSuggestionsUpdated( const std::vector<TextSuggestion>& suggestions) { if (!IsMultiWordSuggestEnabled() || - !IsAllowedUrlOrAppForMultiWordSuggestion()) { + (!IsAllowedUrlOrAppForMultiWordSuggestion() && + !IsExpandedMultiWordSuggestEnabled())) { RecordAssistiveDisabledReasonForMultiWord(GetDisabledReasonForMultiWord()); return; }
diff --git a/chrome/browser/chromeos/input_method/assistive_suggester.h b/chrome/browser/chromeos/input_method/assistive_suggester.h index 16ca951..7ee572a5 100644 --- a/chrome/browser/chromeos/input_method/assistive_suggester.h +++ b/chrome/browser/chromeos/input_method/assistive_suggester.h
@@ -81,6 +81,8 @@ bool IsMultiWordSuggestEnabled(); + bool IsExpandedMultiWordSuggestEnabled(); + void RecordAssistiveMatchMetricsForAction(AssistiveType action); // Only the first applicable reason in DisabledReason enum is returned.
diff --git a/chrome/browser/chromeos/input_method/grammar_manager.cc b/chrome/browser/chromeos/input_method/grammar_manager.cc index 47d0c10..4c11785 100644 --- a/chrome/browser/chromeos/input_method/grammar_manager.cc +++ b/chrome/browser/chromeos/input_method/grammar_manager.cc
@@ -82,27 +82,41 @@ DismissSuggestion(); return true; } - if (event.code() == ui::DomCode::TAB) { - if (highlighted_button_ == ui::ime::ButtonId::kSuggestion) { - highlighted_button_ = ui::ime::ButtonId::kIgnoreSuggestion; - SetButtonHighlighted(ignore_button_); - } else { - highlighted_button_ = ui::ime::ButtonId::kSuggestion; - SetButtonHighlighted(suggestion_button_); - } - return true; - } - if (event.code() == ui::DomCode::ENTER) { - switch (highlighted_button_) { - case ui::ime::ButtonId::kSuggestion: - AcceptSuggestion(); + + switch (highlighted_button_) { + case ui::ime::ButtonId::kNone: + if (event.code() == ui::DomCode::TAB || + event.code() == ui::DomCode::ARROW_UP) { + highlighted_button_ = ui::ime::ButtonId::kSuggestion; + SetButtonHighlighted(suggestion_button_, true); return true; - case ui::ime::ButtonId::kIgnoreSuggestion: + } + break; + case ui::ime::ButtonId::kSuggestion: + switch (event.code()) { + case ui::DomCode::TAB: + highlighted_button_ = ui::ime::ButtonId::kIgnoreSuggestion; + SetButtonHighlighted(ignore_button_, true); + return true; + case ui::DomCode::ARROW_DOWN: + highlighted_button_ = ui::ime::ButtonId::kNone; + SetButtonHighlighted(suggestion_button_, false); + return true; + case ui::DomCode::ENTER: + AcceptSuggestion(); + return true; + default: + break; + } + break; + case ui::ime::ButtonId::kIgnoreSuggestion: + if (event.code() == ui::DomCode::ENTER) { IgnoreSuggestion(); return true; - default: - break; - } + } + break; + default: + break; } return false; } @@ -277,9 +291,11 @@ } void GrammarManager::SetButtonHighlighted( - const ui::ime::AssistiveWindowButton& button) { + const ui::ime::AssistiveWindowButton& button, + bool highlighted) { std::string error; - suggestion_handler_->SetButtonHighlighted(context_id_, button, true, &error); + suggestion_handler_->SetButtonHighlighted(context_id_, button, highlighted, + &error); if (!error.empty()) { LOG(ERROR) << "Failed to set button highlighted. " << error; }
diff --git a/chrome/browser/chromeos/input_method/grammar_manager.h b/chrome/browser/chromeos/input_method/grammar_manager.h index 19ca4c1d..51b6172e 100644 --- a/chrome/browser/chromeos/input_method/grammar_manager.h +++ b/chrome/browser/chromeos/input_method/grammar_manager.h
@@ -74,7 +74,8 @@ void DismissSuggestion(); - void SetButtonHighlighted(const ui::ime::AssistiveWindowButton& button); + void SetButtonHighlighted(const ui::ime::AssistiveWindowButton& button, + bool highlighted); Profile* profile_; std::unique_ptr<GrammarServiceClient> grammar_client_;
diff --git a/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc b/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc index 9ece8dc9..3db77f5 100644 --- a/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc +++ b/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc
@@ -287,7 +287,7 @@ manager.OnSurroundingTextChanged(u"There is error.", 9, 10); } -TEST_F(GrammarManagerTest, HighlightsAndCommitsGrammarSuggestion) { +TEST_F(GrammarManagerTest, HighlightsAndCommitsGrammarSuggestionWithTab) { ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler; GrammarManager manager(profile_.get(), std::make_unique<TestGrammarServiceClient>(), @@ -326,6 +326,45 @@ 2 /*GrammarAction::kAccepted*/, 1); } +TEST_F(GrammarManagerTest, HighlightsAndCommitsGrammarSuggestionWithUpArrow) { + ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler; + GrammarManager manager(profile_.get(), + std::make_unique<TestGrammarServiceClient>(), + &mock_suggestion_handler); + base::HistogramTester histogram_tester; + + mock_ime_input_context_handler_.Reset(); + + manager.OnFocus(1); + manager.OnSurroundingTextChanged(u"There is error.", 0, 0); + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000)); + + EXPECT_CALL(mock_suggestion_handler, SetAssistiveWindowProperties(1, _, _)); + manager.OnSurroundingTextChanged(u"There is error.", 10, 10); + + ui::ime::AssistiveWindowButton suggestion_button{ + .id = ui::ime::ButtonId::kSuggestion, + .window_type = ui::ime::AssistiveWindowType::kGrammarSuggestion, + }; + EXPECT_CALL(mock_suggestion_handler, + SetButtonHighlighted(1, suggestion_button, true, _)); + manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::ARROW_UP)); + EXPECT_CALL(mock_suggestion_handler, DismissSuggestion(1, _)); + manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::ENTER)); + + EXPECT_EQ( + mock_ime_input_context_handler_.delete_surrounding_text_call_count(), 1); + auto deleteSurroundingTextArg = + mock_ime_input_context_handler_.last_delete_surrounding_text_arg(); + EXPECT_EQ(deleteSurroundingTextArg.offset, 9); + EXPECT_EQ(deleteSurroundingTextArg.length, 5); + + EXPECT_EQ(mock_ime_input_context_handler_.commit_text_call_count(), 1); + EXPECT_EQ(mock_ime_input_context_handler_.last_commit_text(), u"correct"); + histogram_tester.ExpectBucketCount("InputMethod.Assistive.Grammar.Actions", + 2 /*GrammarAction::kAccepted*/, 1); +} + TEST_F(GrammarManagerTest, IgnoresGrammarSuggestion) { ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler; GrammarManager manager(profile_.get(),
diff --git a/chrome/browser/component_updater/pki_metadata_component_installer.cc b/chrome/browser/component_updater/pki_metadata_component_installer.cc index ce7287c2..1367137 100644 --- a/chrome/browser/component_updater/pki_metadata_component_installer.cc +++ b/chrome/browser/component_updater/pki_metadata_component_installer.cc
@@ -14,7 +14,6 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/stl_util.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/scoped_blocking_call.h"
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc index ac3f46d..f28e049 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.cc +++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -54,6 +54,9 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +// For ::GetTickCount() +#include <windows.h> + namespace component_updater { namespace {
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java index 1863c4d..6833f55 100644 --- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java +++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
@@ -94,6 +94,7 @@ @Override public void dismiss() { NoteCreationMetrics.recordNoteCreationStatus(/*created=*/false); + NoteCreationMetrics.recordNbTemplateChanges(mDialog.getNbTemplateSwitches()); mDialog.dismiss(); } @@ -112,8 +113,12 @@ public void executeAction() { NoteCreationMetrics.recordNoteTemplateSelected(); NoteCreationMetrics.recordNoteCreationStatus(/*created=*/true); + NoteCreationMetrics.recordNbTemplateChanges(mDialog.getNbTemplateSwitches()); - View noteView = mDialog.getNoteViewAt(mDialog.getSelectedItemIndex()); + int selectedNoteIndex = mDialog.getSelectedItemIndex(); + NoteCreationMetrics.recordSelectedTemplateId( + mListModel.get(selectedNoteIndex).model.get(NoteProperties.TEMPLATE).id); + View noteView = mDialog.getNoteViewAt(selectedNoteIndex); assert noteView != null;
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java index e3ff2b8..93ad0c0c 100644 --- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java +++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java
@@ -45,6 +45,7 @@ private int mSelectedItemIndex; private Toast mToast; private boolean mIsPublishAvailable; + private int mNbTemplateSwitches; interface NoteDialogObserver { void onViewCreated(View view); @@ -159,6 +160,13 @@ return noteContainerView == null ? null : noteContainerView.findViewById(R.id.item); } + /** + * Returns the number of template switches the user did. + */ + public int getNbTemplateSwitches() { + return mNbTemplateSwitches; + } + private void bindCarouselItem(PropertyModel model, ViewGroup parent, PropertyKey propertyKey) { NoteTemplate template = model.get(NoteProperties.TEMPLATE); @@ -239,6 +247,7 @@ } private void focus(int index) { + ++mNbTemplateSwitches; View noteView = getNoteViewAt(index); noteView.setElevation( getActivity().getResources().getDimension(R.dimen.focused_note_elevation));
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java index 54fb5bb..a0615e4 100644 --- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java +++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java
@@ -26,6 +26,24 @@ int NUM_ENTRIES = 3; } + // Constants used to log the selected template ID. + // This is a mirror of the NoteTemplateIds enum found in + // components/content_creation/notes/core/templates/template_types.h + private @interface NoteTemplateIds { + int UNKNOWN = 0; + int CLASSIC = 1; + int FRIENDLY = 2; + int FRESH = 3; + int POWERFUL = 4; + int IMPACTFUL = 5; + int LOVELY = 6; + int GROOVY = 7; + int MONOCHROME = 8; + int BOLD = 9; + int DREAMY = 10; + int NUM_ENTRIES = 11; + } + public static void recordNoteCreationSelected() { RecordHistogram.recordEnumeratedHistogram("NoteCreation.Funnel", NoteCreationFunnel.NOTE_CREATION_SELECTED, NoteCreationFunnel.NUM_ENTRIES); @@ -50,6 +68,21 @@ RecordHistogram.recordBooleanHistogram("NoteCreation.CreationStatus", created); } + public static void recordNbTemplateChanges(int nbChanges) { + RecordHistogram.recordCount100Histogram("NoteCreation.NumberOfTemplateChanges", nbChanges); + } + + public static void recordSelectedTemplateId(int selectedTemplateId) { + assert selectedTemplateId < NoteTemplateIds.NUM_ENTRIES; + + if (selectedTemplateId >= NoteTemplateIds.NUM_ENTRIES) { + selectedTemplateId = NoteTemplateIds.UNKNOWN; + } + + RecordHistogram.recordEnumeratedHistogram( + "NoteCreation.SelectedTemplate", selectedTemplateId, NoteTemplateIds.NUM_ENTRIES); + } + // Empty private constructor for the "static" class. private NoteCreationMetrics() {} }
diff --git a/chrome/browser/device_api/device_attribute_api.cc b/chrome/browser/device_api/device_attribute_api.cc index 7a33849..31311476 100644 --- a/chrome/browser/device_api/device_attribute_api.cc +++ b/chrome/browser/device_api/device_attribute_api.cc
@@ -8,9 +8,9 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h" #include "chromeos/system/statistics_provider.h" #elif BUILDFLAG(IS_CHROMEOS_LACROS) #include "chromeos/lacros/lacros_chrome_service_impl.h" @@ -69,15 +69,12 @@ void GetHostname(DeviceAPIService::GetHostnameCallback callback) { #if BUILDFLAG(IS_CHROMEOS_ASH) - const std::string attribute = g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetDeviceNamePolicyHandler() - ->GetDeviceHostname(); - if (attribute.empty()) - std::move(callback).Run( - Result::NewAttribute(absl::optional<std::string>())); - else - std::move(callback).Run(Result::NewAttribute(attribute)); + const absl::optional<std::string> attribute = + g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetDeviceNamePolicyHandler() + ->GetHostnameChosenByAdministrator(); + std::move(callback).Run(Result::NewAttribute(attribute)); #elif BUILDFLAG(IS_CHROMEOS_LACROS) chromeos::LacrosChromeServiceImpl::Get() ->GetRemote<crosapi::mojom::DeviceAttributes>()
diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc index 629d4a7..a7e9b501 100644 --- a/chrome/browser/download/download_item_model.cc +++ b/chrome/browser/download/download_item_model.cc
@@ -12,6 +12,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/field_trial.h" #include "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" #include "base/supports_user_data.h" #include "base/time/time.h" #include "build/build_config.h" @@ -406,6 +407,50 @@ return download_; } +std::u16string DownloadItemModel::GetWebDriveName() const { + const auto& reroute_info = download_->GetRerouteInfo(); + if (!reroute_info.IsInitialized() || !reroute_info.has_service_provider()) { + return std::u16string(); + } + using Provider = enterprise_connectors::FileSystemServiceProvider; + switch (reroute_info.service_provider()) { + case (Provider::BOX): + return l10n_util::GetStringUTF16(IDS_FILE_SYSTEM_CONNECTOR_BOX); + case (Provider::GOOGLE_DRIVE): + return l10n_util::GetStringUTF16(IDS_FILE_SYSTEM_CONNECTOR_GOOGLE_DRIVE); + } +} + +std::u16string DownloadItemModel::GetWebDriveMessage(bool verbose) const { + const auto& reroute_info = download_->GetRerouteInfo(); + if (!reroute_info.IsInitialized() || !reroute_info.has_service_provider()) { + return std::u16string(); + } + using Provider = enterprise_connectors::FileSystemServiceProvider; + switch (reroute_info.service_provider()) { + case (Provider::BOX): { + DCHECK(reroute_info.has_box()); + const auto& info = reroute_info.box(); + std::u16string msg, supp_msg; + if (info.has_error_message()) { + msg = base::UTF8ToUTF16(info.error_message()); + } + if (msg.size() && verbose && info.has_additional_message()) { + supp_msg = base::UTF8ToUTF16(info.additional_message()); + } + if (supp_msg.empty()) { + return msg; + } + // <WEB_DRIVE_MESSAGE> (<SUPPORT_INFO>)" + return l10n_util::GetStringFUTF16( + IDS_DOWNLOAD_INTERRUPTED_DESCRIPTION_WEB_DRIVE_ERROR, msg, supp_msg); + } + case (Provider::GOOGLE_DRIVE): + break; + } + return std::u16string(); +} + base::FilePath DownloadItemModel::GetFileNameToReportUser() const { return download_->GetFileNameToReportUser(); }
diff --git a/chrome/browser/download/download_item_model.h b/chrome/browser/download/download_item_model.h index 91e7403..c194f9c3 100644 --- a/chrome/browser/download/download_item_model.h +++ b/chrome/browser/download/download_item_model.h
@@ -61,6 +61,8 @@ bool IsBeingRevived() const override; void SetIsBeingRevived(bool is_being_revived) override; download::DownloadItem* download() override; + std::u16string GetWebDriveName() const override; + std::u16string GetWebDriveMessage(bool verbose) const override; base::FilePath GetFileNameToReportUser() const override; base::FilePath GetTargetFilePath() const override; void OpenDownload() override;
diff --git a/chrome/browser/download/download_item_model_unittest.cc b/chrome/browser/download/download_item_model_unittest.cc index 90435d2..d5f045f 100644 --- a/chrome/browser/download/download_item_model_unittest.cc +++ b/chrome/browser/download/download_item_model_unittest.cc
@@ -14,9 +14,11 @@ #include "base/cxx17_backports.h" #include "base/i18n/rtl.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "components/download/public/common/mock_download_item.h" +#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/text/bytes_formatting.h" @@ -55,6 +57,29 @@ // Default URL for a mock download item in DownloadItemModelTest. const char kDefaultURL[] = "http://example.com/foo.bar"; +// Constants and helper functions to test rerouted items. +using Provider = enterprise_connectors::FileSystemServiceProvider; +using RerouteInfo = enterprise_connectors::DownloadItemRerouteInfo; +const char kTestProviderDisplayName[] = "Box"; +const char kTestProviderErrorMessage[] = "400 - \"item_name_invalid\""; +const char kTestProviderAdditionalMessage[] = "abcdefg"; +const Provider kTestProvider = Provider::BOX; +RerouteInfo MakeTestRerouteInfo(Provider provider) { + RerouteInfo info; + info.set_service_provider(provider); + switch (provider) { + case (Provider::BOX): + info.mutable_box()->set_error_message(kTestProviderErrorMessage); + info.mutable_box()->set_additional_message( + kTestProviderAdditionalMessage); + break; + default: + NOTREACHED(); + } + return info; +} +const RerouteInfo kTestRerouteInfo = MakeTestRerouteInfo(kTestProvider); + class DownloadItemModelTest : public testing::Test { public: DownloadItemModelTest() @@ -81,6 +106,8 @@ .WillByDefault(Return(base::FilePath(kDefaultDisplayFileName))); ON_CALL(item_, GetTargetFilePath()) .WillByDefault(ReturnRefOfCopy(base::FilePath(kDefaultTargetFilePath))); + ON_CALL(item_, GetRerouteInfo()) + .WillByDefault(ReturnRefOfCopy(RerouteInfo())); ON_CALL(item_, GetTargetDisposition()) .WillByDefault( Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE)); @@ -96,6 +123,12 @@ : DownloadItem::INTERRUPTED)); } + void SetupCompletedDownloadItem() { + ON_CALL(item_, GetFileExternallyRemoved()).WillByDefault(Return(false)); + EXPECT_CALL(item_, GetState()) + .WillRepeatedly(Return(DownloadItem::COMPLETE)); + } + download::MockDownloadItem& item() { return item_; } DownloadItemModel& model() { @@ -117,71 +150,93 @@ download::DownloadInterruptReason reason; // Expected status string. This will include the progress as well. - const char* expected_status; + const char* expected_status_msg; } kTestCases[] = { {download::DOWNLOAD_INTERRUPT_REASON_NONE, "1/2 B"}, - {download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, - "Failed - Download error"}, + {download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, "%s - Download error"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, - "Failed - Insufficient permissions"}, - {download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, "Failed - Disk full"}, + "%s - Insufficient permissions"}, + {download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, "%s - Disk full"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG, - "Failed - Path too long"}, + "%s - Path too long"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE, - "Failed - File too large"}, + "%s - File too large"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED, - "Failed - Virus detected"}, - {download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, "Failed - Blocked"}, + "%s - Virus detected"}, + {download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, "%s - Blocked"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED, - "Failed - Virus scan failed"}, + "%s - Virus scan failed"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT, - "Failed - File truncated"}, + "%s - File truncated"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE, - "Failed - Already downloaded"}, + "%s - Already downloaded"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, - "Failed - System busy"}, + "%s - System busy"}, {download::DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, - "Failed - Download error"}, + "%s - Download error"}, {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, - "Failed - Network error"}, + "%s - Network error"}, {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, - "Failed - Network timeout"}, + "%s - Network timeout"}, {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, - "Failed - Network disconnected"}, + "%s - Network disconnected"}, {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN, - "Failed - Server unavailable"}, + "%s - Server unavailable"}, {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST, - "Failed - Network error"}, + "%s - Network error"}, {download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, - "Failed - Server problem"}, + "%s - Server problem"}, {download::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE, - "Failed - Download error"}, - {download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, - "Failed - No file"}, + "%s - Download error"}, + {download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, "%s - No file"}, {download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED, - "Failed - Needs authorization"}, + "%s - Needs authorization"}, {download::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM, - "Failed - Bad certificate"}, - {download::DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN, - "Failed - Forbidden"}, + "%s - Bad certificate"}, + {download::DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN, "%s - Forbidden"}, {download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE, - "Failed - Server unreachable"}, + "%s - Server unreachable"}, {download::DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH, - "Failed - File incomplete"}, + "%s - File incomplete"}, {download::DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT, - "Failed - Download error"}, + "%s - Download error"}, {download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, "Canceled"}, - {download::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN, "Failed - Shutdown"}, - {download::DOWNLOAD_INTERRUPT_REASON_CRASH, "Failed - Crash"}, + {download::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN, "%s - Shutdown"}, + {download::DOWNLOAD_INTERRUPT_REASON_CRASH, "%s - Crash"}, }; static_assert(kInterruptReasonCount == base::size(kTestCases), "interrupt reason mismatch"); SetupDownloadItemDefaults(); + + const char default_failed_msg[] = "Failed"; for (const auto& test_case : kTestCases) { SetupInterruptedDownloadItem(test_case.reason); - EXPECT_EQ(test_case.expected_status, - base::UTF16ToUTF8(model().GetStatusText())); + std::string expected_status_msg = + base::StringPrintf(test_case.expected_status_msg, default_failed_msg); + EXPECT_EQ(expected_status_msg, base::UTF16ToUTF8(model().GetStatusText())); + } + + const std::string provider_failed_msg = + base::StringPrintf("Failed to save to %s", kTestProviderDisplayName); + for (const auto& test_case : kTestCases) { + SetupInterruptedDownloadItem(test_case.reason); + EXPECT_CALL(item(), GetRerouteInfo()) + .WillRepeatedly(ReturnRef(kTestRerouteInfo)); + std::string expected_status_msg, expected_history_page_text; + if (test_case.reason == download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED) { + expected_status_msg = + provider_failed_msg + " - " + kTestProviderErrorMessage; + expected_history_page_text = + expected_status_msg + " (" + kTestProviderAdditionalMessage + ")"; + } else { + expected_status_msg = base::StringPrintf(test_case.expected_status_msg, + provider_failed_msg.c_str()); + expected_history_page_text = expected_status_msg; + } + EXPECT_EQ(expected_status_msg, base::UTF16ToUTF8(model().GetStatusText())); + EXPECT_EQ(expected_history_page_text, + base::UTF16ToUTF8(model().GetHistoryPageStatusText())); } } @@ -264,52 +319,59 @@ } TEST_F(DownloadItemModelTest, InProgressStatus) { + const std::string provider_sending_str = + base::StringPrintf("Sending to %s", kTestProviderDisplayName); + const char* reroute_status = provider_sending_str.c_str(); const struct TestCase { int64_t received_bytes; // Return value of GetReceivedBytes(). int64_t total_bytes; // Return value of GetTotalBytes(). bool time_remaining_known; // If TimeRemaining() is known. bool open_when_complete; // GetOpenWhenComplete(). bool is_paused; // IsPaused(). - const char* expected_status; // Expected status text. + const RerouteInfo reroute_info; // GetRerouteInfo(). + const char* expected_status_msg; // Expected status text. } kTestCases[] = { - // These are all the valid combinations of the above fields for a download - // that is in IN_PROGRESS state. Go through all of them and check the return - // value of DownloadItemModel::GetStatusText(). The point isn't to lock down - // the status strings, but to make sure we end up with something sane for - // all the circumstances we care about. - // - // For GetReceivedBytes()/GetTotalBytes(), we only check whether each is - // non-zero. In addition, if |total_bytes| is zero, then - // |time_remaining_known| is also false. - // - // .-- .TimeRemaining() is known. - // | .-- .GetOpenWhenComplete() - // | | .---- .IsPaused() - { 0, 0, false, false, false, "Starting\xE2\x80\xA6" }, - { 1, 0, false, false, false, "1 B" }, - { 0, 2, false, false, false, "Starting\xE2\x80\xA6"}, - { 1, 2, false, false, false, "1/2 B" }, - { 0, 2, true, false, false, "0/2 B, 10 secs left" }, - { 1, 2, true, false, false, "1/2 B, 10 secs left" }, - { 0, 0, false, true, false, "Opening when complete" }, - { 1, 0, false, true, false, "Opening when complete" }, - { 0, 2, false, true, false, "Opening when complete" }, - { 1, 2, false, true, false, "Opening when complete" }, - { 0, 2, true, true, false, "Opening in 10 secs\xE2\x80\xA6"}, - { 1, 2, true, true, false, "Opening in 10 secs\xE2\x80\xA6"}, - { 0, 0, false, false, true, "0 B, Paused" }, - { 1, 0, false, false, true, "1 B, Paused" }, - { 0, 2, false, false, true, "0/2 B, Paused" }, - { 1, 2, false, false, true, "1/2 B, Paused" }, - { 0, 2, true, false, true, "0/2 B, Paused" }, - { 1, 2, true, false, true, "1/2 B, Paused" }, - { 0, 0, false, true, true, "0 B, Paused" }, - { 1, 0, false, true, true, "1 B, Paused" }, - { 0, 2, false, true, true, "0/2 B, Paused" }, - { 1, 2, false, true, true, "1/2 B, Paused" }, - { 0, 2, true, true, true, "0/2 B, Paused" }, - { 1, 2, true, true, true, "1/2 B, Paused" }, - }; + // These are all the valid combinations of the above fields for a download + // that is in IN_PROGRESS state. Go through all of them and check the + // return + // value of DownloadItemModel::GetStatusText(). The point isn't to lock + // down + // the status strings, but to make sure we end up with something sane for + // all the circumstances we care about. + // + // For GetReceivedBytes()/GetTotalBytes(), we only check whether each is + // non-zero. In addition, if |total_bytes| is zero, then + // |time_remaining_known| is also false. + // + // .-- .TimeRemaining() is known. + // | .-- .GetOpenWhenComplete() + // | | .---- .IsPaused() + // | | | .---- .GetRerouteInfo() + {0, 0, false, false, false, {}, "Starting\xE2\x80\xA6"}, + {1, 0, false, false, false, {}, "1 B"}, + {0, 2, false, false, false, {}, "Starting\xE2\x80\xA6"}, + {1, 2, false, false, false, {}, "1/2 B"}, + {0, 2, true, false, false, {}, "0/2 B, 10 secs left"}, + {1, 2, true, false, false, {}, "1/2 B, 10 secs left"}, + {0, 0, false, true, false, {}, "Opening when complete"}, + {1, 0, false, true, false, {}, "Opening when complete"}, + {0, 2, false, true, false, {}, "Opening when complete"}, + {1, 2, false, true, false, {}, "Opening when complete"}, + {0, 2, true, true, false, {}, "Opening in 10 secs\xE2\x80\xA6"}, + {1, 2, true, true, false, {}, "Opening in 10 secs\xE2\x80\xA6"}, + {0, 0, false, false, true, {}, "0 B, Paused"}, + {1, 0, false, false, true, {}, "1 B, Paused"}, + {0, 2, false, false, true, {}, "0/2 B, Paused"}, + {1, 2, false, false, true, {}, "1/2 B, Paused"}, + {0, 2, true, false, true, {}, "0/2 B, Paused"}, + {1, 2, true, false, true, {}, "1/2 B, Paused"}, + {0, 0, false, true, true, {}, "0 B, Paused"}, + {1, 0, false, true, true, {}, "1 B, Paused"}, + {0, 2, false, true, true, {}, "0/2 B, Paused"}, + {1, 2, false, true, true, {}, "1/2 B, Paused"}, + {0, 2, true, true, true, {}, "0/2 B, Paused"}, + {1, 2, true, true, true, {}, "1/2 B, Paused"}, + {5, 5, true, true, false, kTestRerouteInfo, reroute_status}}; SetupDownloadItemDefaults(); @@ -328,12 +390,27 @@ .WillRepeatedly(Return(test_case.open_when_complete)); EXPECT_CALL(item(), IsPaused()) .WillRepeatedly(Return(test_case.is_paused)); + EXPECT_CALL(item(), GetRerouteInfo()) + .WillRepeatedly(ReturnRef(test_case.reroute_info)); - EXPECT_EQ(test_case.expected_status, + EXPECT_EQ(test_case.expected_status_msg, base::UTF16ToUTF8(model().GetStatusText())); } } +TEST_F(DownloadItemModelTest, CompletedStatus) { + SetupDownloadItemDefaults(); + SetupCompletedDownloadItem(); + + EXPECT_TRUE(model().GetStatusText().empty()); + + EXPECT_CALL(item(), GetRerouteInfo()) + .WillRepeatedly(ReturnRef(kTestRerouteInfo)); + std::string expected_status_msg = + base::StringPrintf("Saved to %s", kTestProviderDisplayName); + EXPECT_EQ(expected_status_msg, base::UTF16ToUTF8(model().GetStatusText())); +} + TEST_F(DownloadItemModelTest, ShouldShowInShelf) { SetupDownloadItemDefaults();
diff --git a/chrome/browser/download/download_ui_model.cc b/chrome/browser/download/download_ui_model.cc index bdf072d..0f6fbf3 100644 --- a/chrome/browser/download/download_ui_model.cc +++ b/chrome/browser/download/download_ui_model.cc
@@ -42,7 +42,7 @@ // TODO(qinmin): Migrate this description generator to OfflineItemUtils once // that component gets used to build desktop UI. -std::u16string FailStateMessage(FailState fail_state) { +std::u16string FailStateDescription(FailState fail_state) { int string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS; std::u16string status_text; @@ -198,28 +198,16 @@ return size_ratio; } -std::u16string DownloadUIModel::GetInterruptReasonText() const { - if (GetState() != DownloadItem::INTERRUPTED || - GetLastFailState() == FailState::USER_CANCELED) { - return std::u16string(); - } - return FailStateMessage(GetLastFailState()); -} - std::u16string DownloadUIModel::GetStatusText() const { switch (GetState()) { case DownloadItem::IN_PROGRESS: - return GetInProgressStatusString(); + return GetInProgressStatusText(); case DownloadItem::COMPLETE: - return GetFileExternallyRemoved() - ? l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED) - : std::u16string(); + return GetCompletedStatusText(); case DownloadItem::INTERRUPTED: { const FailState fail_state = GetLastFailState(); if (fail_state != FailState::USER_CANCELED) { - return l10n_util::GetStringFUTF16( - IDS_DOWNLOAD_STATUS_INTERRUPTED, - OfflineItemUtils::GetFailStateMessage(fail_state)); + return GetInterruptedStatusText(fail_state); } } FALLTHROUGH; @@ -235,8 +223,7 @@ std::u16string tooltip = GetFileNameToReportUser().LossyDisplayName(); if (GetState() == DownloadItem::INTERRUPTED && GetLastFailState() != FailState::USER_CANCELED) { - tooltip += - u"\n" + OfflineItemUtils::GetFailStateMessage(GetLastFailState()); + tooltip += u"\n" + GetFailStateMessage(GetLastFailState()); } return tooltip; } @@ -435,6 +422,14 @@ return nullptr; } +std::u16string DownloadUIModel::GetWebDriveName() const { + return std::u16string(); +} + +std::u16string DownloadUIModel::GetWebDriveMessage(bool) const { + return std::u16string(); +} + base::FilePath DownloadUIModel::GetFileNameToReportUser() const { return base::FilePath(); } @@ -443,7 +438,9 @@ return base::FilePath(); } -void DownloadUIModel::OpenDownload() {} +void DownloadUIModel::OpenDownload() { + NOTREACHED(); +} download::DownloadItem::DownloadState DownloadUIModel::GetState() const { return download::DownloadItem::IN_PROGRESS; @@ -655,12 +652,15 @@ return false; } -std::u16string DownloadUIModel::GetInProgressStatusString() const { +std::u16string DownloadUIModel::GetInProgressStatusText() const { DCHECK_EQ(DownloadItem::IN_PROGRESS, GetState()); + const auto web_drive = GetWebDriveName(); TimeDelta time_remaining; - // time_remaining is only known if the download isn't paused. - bool time_remaining_known = (!IsPaused() && TimeRemaining(&time_remaining)); + // time_remaining is only known if the download isn't paused, and it isn't + // going to be rerouted to a web drive. + bool time_remaining_known = + (!IsPaused() && TimeRemaining(&time_remaining) && web_drive.empty()); // Indication of progress. (E.g.:"100/200 MB" or "100MB") std::u16string size_ratio = GetProgressSizesString(); @@ -679,7 +679,7 @@ } // A download scheduled to be opened when complete: "Opening in 10 secs" - if (GetOpenWhenComplete()) { + if (web_drive.empty() && GetOpenWhenComplete()) { if (!time_remaining_known) return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_OPEN_WHEN_COMPLETE); @@ -697,13 +697,94 @@ ui::TimeFormat::LENGTH_SHORT, time_remaining)); } - // In progress download with no known time left and non-zero completed bytes: - // "100/120 MB" or "100 MB" - if (GetCompletedBytes() > 0) + const auto completed_bytes = GetCompletedBytes(); + const auto total_bytes = GetTotalBytes(); + if (completed_bytes == 0) { + // Instead of displaying "0 B" we say "Starting..." + return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING); + } else if (completed_bytes < total_bytes || total_bytes == 0) { + // In progress download with no known time left and non-zero completed + // bytes: "100/120 MB" or "100 MB" return size_ratio; + } else if (web_drive.size()) { + // If all bytes of the file has been downloaded and it is being rerouted: + // "Sending to <WEB_DRIVE>..." + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_UPLOADING, web_drive); + } else { + return std::u16string(); + } +} - // Instead of displaying "0 B" we say "Starting..." - return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING); +std::u16string DownloadUIModel::GetCompletedStatusText() const { + if (GetFileExternallyRemoved()) { + return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED); + } + + const auto web_drive = GetWebDriveName(); + if (web_drive.size()) { + // "Saved to <WEB_DRIVE>" + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_UPLOADED, web_drive); + } + return std::u16string(); +} + +// To clarify variable / method names in methods below that help form failure +// status messages: +// long & descriptive / short & concise +// "Failed - <STATE_DESCRIPTION / STATE_MESSAGE>" +// "Fail to save to <WEB_DRIVE> - <STATE_DESCRIPTION / STATE_MESSAGE>" +// < DESCRIPTION/STATUS_TEXT > + +std::u16string DownloadUIModel::GetFailStateMessage( + offline_items_collection::FailState fail_state) const { + std::u16string state_msg; + if (fail_state != FailState::SERVER_FAILED || + (state_msg = GetWebDriveMessage(/* verbose = */ false)).empty()) { + return OfflineItemUtils::GetFailStateMessage(fail_state); + } + return state_msg; +} + +std::u16string DownloadUIModel::GetInterruptDescription() const { + std::u16string state_description; + const auto fail_state = GetLastFailState(); + if (fail_state != FailState::SERVER_FAILED || + (state_description = GetWebDriveMessage(/* verbose = */ true)).empty()) { + state_description = FailStateDescription(fail_state); + } + + const auto web_drive = GetWebDriveName(); + if (web_drive.empty()) { + // "Failed - <STATE_DESCRIPTION>" + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED, + state_description); + } + // else: file was rerouted. Formulate the message string accordingly. + // "Fail to save to <WEB_DRIVE> - <STATE_DESCRIPTION>" + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_UPLOAD_INTERRUPTED, + web_drive, state_description); +} + +std::u16string DownloadUIModel::GetHistoryPageStatusText() const { + if (GetLastFailState() == FailState::SERVER_FAILED) { + // Display the full error description in case of server failure. + return GetInterruptDescription(); + } + return GetStatusText(); +} + +std::u16string DownloadUIModel::GetInterruptedStatusText( + FailState fail_state) const { + auto state_msg = GetFailStateMessage(fail_state); + const auto web_drive = GetWebDriveName(); + if (web_drive.empty()) { + // "Failed - <STATE_MESSAGE>" + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED, + state_msg); + } + // "Fail to save to <WEB_DRIVE> - <STATE_MESSAGE>" + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_UPLOAD_INTERRUPTED, + web_drive, state_msg); } #if BUILDFLAG(FULL_SAFE_BROWSING)
diff --git a/chrome/browser/download/download_ui_model.h b/chrome/browser/download/download_ui_model.h index 7c845b6e..a63c7aa 100644 --- a/chrome/browser/download/download_ui_model.h +++ b/chrome/browser/download/download_ui_model.h
@@ -65,7 +65,10 @@ // Returns a long descriptive string for a download that's in the INTERRUPTED // state. For other downloads, the returned string will be empty. - std::u16string GetInterruptReasonText() const; + std::u16string GetInterruptDescription() const; + + // Returns a status string for the download history page. + std::u16string GetHistoryPageStatusText() const; // Returns a short one-line status string for the download. std::u16string GetStatusText() const; @@ -201,6 +204,9 @@ // otherwise. virtual download::DownloadItem* download(); + // Returns the display name for the web drive where the file is rerouted to. + virtual std::u16string GetWebDriveName() const; + // Returns the file-name that should be reported to the user. virtual base::FilePath GetFileNameToReportUser() const; @@ -327,11 +333,25 @@ // Returns whether the download is triggered by an extension. virtual bool IsExtensionDownload() const; + // Returns the message, if any, to be displayed for file rerouted. + virtual std::u16string GetWebDriveMessage(bool verbose) const; + base::ObserverList<Observer>::Unchecked observers_; private: // Returns a string indicating the status of an in-progress download. - std::u16string GetInProgressStatusString() const; + std::u16string GetInProgressStatusText() const; + + // Returns a string indicating the status of a completed download. + std::u16string GetCompletedStatusText() const; + + // Returns a string indicating the status of an interrupted download. + std::u16string GetInterruptedStatusText( + offline_items_collection::FailState fail_state) const; + + // Returns a short string indicating why the download failed. + std::u16string GetFailStateMessage( + offline_items_collection::FailState fail_state) const; base::WeakPtrFactory<DownloadUIModel> weak_ptr_factory_{this};
diff --git a/chrome/browser/download/notification/download_item_notification.cc b/chrome/browser/download/notification/download_item_notification.cc index d88e6110..449d280 100644 --- a/chrome/browser/download/notification/download_item_notification.cc +++ b/chrome/browser/download/notification/download_item_notification.cc
@@ -40,6 +40,7 @@ #include "components/download/public/common/download_danger_type.h" #include "components/download/public/common/download_interrupt_reasons.h" #include "components/download/public/common/download_item.h" +#include "components/download/public/common/download_utils.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" @@ -965,6 +966,7 @@ IDS_PROMPT_DOWNLOAD_DEEP_SCANNED_OPENED_DANGEROUS); } + auto web_drive = item_->GetWebDriveName(); switch (item_->GetState()) { case download::DownloadItem::IN_PROGRESS: // The download is a CRX (app, extension, theme, ...) and it is being @@ -972,35 +974,41 @@ if (item_->AllDataSaved() && IsExtensionDownload(item_.get())) { return l10n_util::GetStringUTF16( IDS_DOWNLOAD_STATUS_CRX_INSTALL_RUNNING); + } else if (web_drive.size()) { + // If the file is being uploaded: "Sending to <WEB_DRIVE>" + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_UPLOADING, + web_drive); } else { return GetInProgressSubStatusString(); } - case download::DownloadItem::COMPLETE: - // If the file has been removed: Removed + case download::DownloadItem::COMPLETE: { if (item_->GetFileExternallyRemoved()) { + // If the file has been removed: "Removed" return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED); + } else if (web_drive.size()) { + // If the file was uploaded: "Saved to <WEB_DRIVE>" + return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_UPLOADED, + web_drive); } else { std::u16string file_name = item_->GetFileNameToReportUser().LossyDisplayName(); base::i18n::AdjustStringForLocaleDirection(&file_name); return file_name; } - case download::DownloadItem::CANCELLED: - // "Cancelled" - return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_CANCELLED); + } case download::DownloadItem::INTERRUPTED: { FailState fail_state = item_->GetLastFailState(); if (fail_state != FailState::USER_CANCELED) { - // "Failed - <REASON>" - std::u16string interrupt_reason = item_->GetInterruptReasonText(); - DCHECK(!interrupt_reason.empty()); - return l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED, - interrupt_reason); - } else { - // Same as DownloadItem::CANCELLED. - return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_CANCELLED); + const auto interrupt_text = item_->GetInterruptDescription(); + DCHECK(!interrupt_text.empty()); + return interrupt_text; } + FALLTHROUGH; // Same as download::DownloadItem::CANCELLED. } + case download::DownloadItem::CANCELLED: + // "Cancelled" + return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_CANCELLED); + default: NOTREACHED(); }
diff --git a/chrome/browser/download/notification/download_item_notification_unittest.cc b/chrome/browser/download/notification/download_item_notification_unittest.cc index bb1fd63..fdcbcb0 100644 --- a/chrome/browser/download/notification/download_item_notification_unittest.cc +++ b/chrome/browser/download/notification/download_item_notification_unittest.cc
@@ -29,16 +29,20 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/download/public/common/mock_download_item.h" +#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" #include "content/public/browser/download_item_utils.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/mock_download_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::_; using testing::NiceMock; using testing::Return; using testing::ReturnRefOfCopy; -using testing::_; +using testing::ValuesIn; +using Provider = enterprise_connectors::FileSystemServiceProvider; +using RerouteInfo = enterprise_connectors::DownloadItemRerouteInfo; namespace { @@ -79,6 +83,8 @@ .WillByDefault(Return(base::FilePath("TITLE.bin"))); ON_CALL(*download_item_, GetTargetFilePath()) .WillByDefault(ReturnRefOfCopy(download_item_target_path)); + ON_CALL(*download_item_, GetRerouteInfo()) + .WillByDefault(ReturnRefOfCopy(RerouteInfo())); ON_CALL(*download_item_, GetDangerType()) .WillByDefault(Return(download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); ON_CALL(*download_item_, IsDone()).WillByDefault(Return(false)); @@ -332,4 +338,72 @@ download_item_notification_->Click(absl::nullopt, absl::nullopt); } +struct FileReroutedTestCase { + download::DownloadItem::DownloadState state; + download::DownloadInterruptReason reason; + RerouteInfo reroute_info; +}; + +RerouteInfo MakeTestRerouteInfo(std::string file_id = std::string()) { + RerouteInfo info; + info.set_service_provider(Provider::BOX); + if (file_id.size()) + info.mutable_box()->set_file_id(file_id); + return info; +} + +RerouteInfo MakeTestRerouteInfoWithError(std::string error_message) { + RerouteInfo info; + info.set_service_provider(Provider::BOX); + info.mutable_box()->set_error_message(error_message); + return info; +} + +class DownloadItemNotificationParametrizedTest + : public DownloadItemNotificationTest, + public ::testing::WithParamInterface<FileReroutedTestCase> {}; + +TEST_P(DownloadItemNotificationParametrizedTest, + CreateDownloadItemNotification) { + RerouteInfo reroute_info; + reroute_info.set_service_provider(Provider::BOX); + + // Setup file rerouted to Box info. + EXPECT_CALL(*download_item_, GetRerouteInfo()) + .WillRepeatedly(ReturnRefOfCopy(GetParam().reroute_info)); + EXPECT_CALL(*download_item_, GetState()) + .WillRepeatedly(Return(GetParam().state)); + + switch (GetParam().state) { + case (download::DownloadItem::INTERRUPTED): + EXPECT_CALL(*download_item_, GetLastReason()) + .WillRepeatedly(Return(GetParam().reason)); + break; + case (download::DownloadItem::COMPLETE): + EXPECT_CALL(*download_item_, IsDone()).WillRepeatedly(Return(true)); + FALLTHROUGH; + default: + EXPECT_CALL(*download_item_, GetLastReason()).Times(0); + } + + // Show the download item notification. + CreateDownloadItemNotification(); + download_item_->NotifyObserversDownloadOpened(); +} + +const FileReroutedTestCase kFileReroutedTestCases[] = { + {download::DownloadItem::DownloadState::IN_PROGRESS, + download::DOWNLOAD_INTERRUPT_REASON_NONE, MakeTestRerouteInfo()}, + {download::DownloadItem::DownloadState::INTERRUPTED, + download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, + MakeTestRerouteInfo()}, + {download::DownloadItem::DownloadState::INTERRUPTED, + download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, + MakeTestRerouteInfoWithError("400 - \"item_name_invalid\"")}, + {download::DownloadItem::DownloadState::COMPLETE, + download::DOWNLOAD_INTERRUPT_REASON_NONE, MakeTestRerouteInfo("13579")}}; + +INSTANTIATE_TEST_SUITE_P(ReroutedByFileSystemConnectorTest, + DownloadItemNotificationParametrizedTest, + ValuesIn(kFileReroutedTestCases)); } // namespace test
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chrome/browser/extensions/api/chrome_extensions_api_client.cc index 7e22c3c..ff81674 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.cc +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
@@ -324,9 +324,12 @@ return std::make_unique<ChromeDevicePermissionsPrompt>(web_contents); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) bool ChromeExtensionsAPIClient::ShouldAllowDetachingUsb(int vid, int pid) const { + // TOOD(huangs): Figure out how to do the following in Lacros, which does not + // have access to ash::CrosSettings (https://crbug.com/1219329). +#if BUILDFLAG(IS_CHROMEOS_ASH) const base::ListValue* policy_list; if (ash::CrosSettings::Get()->GetList(chromeos::kUsbDetachableAllowlist, &policy_list)) { @@ -337,10 +340,10 @@ } } } - +#endif // BUILDFLAG(IS_CHROMEOS_ASH) return false; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) std::unique_ptr<VirtualKeyboardDelegate> ChromeExtensionsAPIClient::CreateVirtualKeyboardDelegate(
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.h b/chrome/browser/extensions/api/chrome_extensions_api_client.h index 3aecf420..f9cab00 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.h +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.h
@@ -65,9 +65,9 @@ RulesCacheDelegate* cache_delegate) const override; std::unique_ptr<DevicePermissionsPrompt> CreateDevicePermissionsPrompt( content::WebContents* web_contents) const override; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) bool ShouldAllowDetachingUsb(int vid, int pid) const override; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) std::unique_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate( content::BrowserContext* browser_context) const override; ManagementAPIDelegate* CreateManagementAPIDelegate() const override;
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash.cc index cd2d3f3d..6c20692 100644 --- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash.cc +++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash.cc
@@ -8,10 +8,10 @@ #include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/device_name_policy_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/device_name_policy_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/enterprise_device_attributes.h" #include "chromeos/system/statistics_provider.h" @@ -114,14 +114,18 @@ ExtensionFunction::ResponseAction EnterpriseDeviceAttributesGetDeviceHostnameFunction::Run() { + // If string is nullopt, it means there is no policy set by admin. std::string hostname; Profile* profile = Profile::FromBrowserContext(browser_context()); if (crosapi::browser_util::IsSigninProfileOrBelongsToAffiliatedUser( profile)) { - hostname = g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetDeviceNamePolicyHandler() - ->GetDeviceHostname(); + absl::optional<std::string> hostname_chosen_by_admin = + g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetDeviceNamePolicyHandler() + ->GetHostnameChosenByAdministrator(); + if (hostname_chosen_by_admin) + hostname = *hostname_chosen_by_admin; } return RespondNow(ArgumentList( api::enterprise_device_attributes::GetDeviceHostname::Results::Create(
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc index 41261d64c..75447a44 100644 --- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc +++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -12,7 +12,6 @@ #include "base/location.h" #include "base/metrics/histogram_functions.h" #include "base/notreached.h" -#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h"
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index 6df85f1..926c10a 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -536,7 +536,9 @@ // Launch the app if web_app_url happens to match start_url. If not, the app // could still be installed with different start_url. if (provider->registrar().IsLocallyInstalled(web_app_url)) { - LaunchWebApp(web_app::GenerateAppIdFromURL(web_app_url), profile); + LaunchWebApp( + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, web_app_url), + profile); std::move(callback).Run(InstallOrLaunchWebAppResult::kSuccess); return; }
diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc index 3ba885d..5b4eb521 100644 --- a/chrome/browser/extensions/api/management/management_apitest.cc +++ b/chrome/browser/extensions/api/management/management_apitest.cc
@@ -207,7 +207,8 @@ chrome::SetAutoAcceptPWAInstallConfirmationForTesting(true); const GURL start_url = https_test_server_.GetURL(web_app_start_url); - web_app::AppId web_app_id = web_app::GenerateAppIdFromURL(start_url); + web_app::AppId web_app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto* provider = web_app::WebAppProviderBase::GetProviderBase(browser()->profile()); EXPECT_FALSE(provider->registrar().IsLocallyInstalled(start_url));
diff --git a/chrome/browser/extensions/api/scripting/scripting_api.cc b/chrome/browser/extensions/api/scripting/scripting_api.cc index e4d9646..d197f53 100644 --- a/chrome/browser/extensions/api/scripting/scripting_api.cc +++ b/chrome/browser/extensions/api/scripting/scripting_api.cc
@@ -198,15 +198,9 @@ } // Returns true if the loaded resource is valid for injection. -bool CheckLoadedResource(bool success, - std::string* data, +bool CheckLoadedResource(std::string* data, const std::string& file_name, std::string* error) { - if (!success) { - *error = ErrorUtils::FormatErrorMessage(kCouldNotLoadFileError, file_name); - return false; - } - DCHECK(data); // TODO(devlin): What necessitates this encoding requirement? Is it needed for // blink injection? @@ -226,14 +220,14 @@ bool CheckAndLoadFiles(const std::vector<std::string>& files, const Extension& extension, bool requires_localization, - LoadAndLocalizeResourceCallback callback, + LoadAndLocalizeResourcesCallback callback, std::string* error) { ExtensionResource resource; if (!GetFileResource(files, extension, &resource, error)) return false; - LoadAndLocalizeResource(extension, resource, requires_localization, - std::move(callback)); + LoadAndLocalizeResources(extension, {std::move(resource)}, + requires_localization, std::move(callback)); return true; } @@ -363,20 +357,27 @@ } void ScriptingExecuteScriptFunction::DidLoadResource( - bool success, - std::unique_ptr<std::string> data) { + std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> load_error) { DCHECK(injection_.files); DCHECK_EQ(1u, injection_.files->size()); + if (load_error) { + Respond(Error(std::move(*load_error))); + return; + } + + // TODO(devlin): Remove this DCHECK when multiple files are supported. + DCHECK_EQ(1u, data.size()); + auto file_data = std::move(data.front()); std::string error; - if (!CheckLoadedResource(success, data.get(), injection_.files->at(0), - &error)) { + if (!CheckLoadedResource(file_data.get(), injection_.files->at(0), &error)) { Respond(Error(std::move(error))); return; } GURL script_url = extension()->GetResourceURL(injection_.files->at(0)); - if (!Execute(std::move(*data), std::move(script_url), &error)) + if (!Execute(std::move(*file_data), std::move(script_url), &error)) Respond(Error(std::move(error))); } @@ -481,20 +482,27 @@ } void ScriptingInsertCSSFunction::DidLoadResource( - bool success, - std::unique_ptr<std::string> data) { + std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> load_error) { DCHECK(injection_.files); DCHECK_EQ(1u, injection_.files->size()); + if (load_error) { + Respond(Error(std::move(*load_error))); + return; + } + + // TODO(devlin): Remove this DCHECK when multiple files are supported. + DCHECK_EQ(1u, data.size()); std::string error; - if (!CheckLoadedResource(success, data.get(), injection_.files->at(0), - &error)) { + auto& file_data = data.front(); + if (!CheckLoadedResource(file_data.get(), injection_.files->at(0), &error)) { Respond(Error(std::move(error))); return; } GURL script_url = extension()->GetResourceURL(injection_.files->at(0)); - if (!Execute(std::move(*data), std::move(script_url), &error)) + if (!Execute(std::move(*file_data), std::move(script_url), &error)) Respond(Error(std::move(error))); }
diff --git a/chrome/browser/extensions/api/scripting/scripting_api.h b/chrome/browser/extensions/api/scripting/scripting_api.h index 3a1b720a..8e7fc14 100644 --- a/chrome/browser/extensions/api/scripting/scripting_api.h +++ b/chrome/browser/extensions/api/scripting/scripting_api.h
@@ -5,8 +5,10 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_SCRIPTING_SCRIPTING_API_H_ #define CHROME_BROWSER_EXTENSIONS_API_SCRIPTING_SCRIPTING_API_H_ +#include <memory> #include <string> #include <utility> +#include <vector> #include "chrome/common/extensions/api/scripting.h" #include "extensions/browser/extension_function.h" @@ -33,7 +35,8 @@ ~ScriptingExecuteScriptFunction() override; // Called when the resource file to be injected has been loaded. - void DidLoadResource(bool success, std::unique_ptr<std::string> data); + void DidLoadResource(std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> load_error); // Triggers the execution of `code_to_execute` in the appropriate context. // Returns true on success; on failure, populates `error`. @@ -63,7 +66,8 @@ ~ScriptingInsertCSSFunction() override; // Called when the resource file to be injected has been loaded. - void DidLoadResource(bool success, std::unique_ptr<std::string> data); + void DidLoadResource(std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> load_error); // Triggers the execution of `code_to_execute` in the appropriate context. // Returns true on success; on failure, populates `error`.
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 64d2fbf..cd8b63d 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -248,10 +248,6 @@ settings_api::PrefType::PREF_TYPE_STRING; #endif - // Printing settings. - (*s_allowlist)[::prefs::kLocalDiscoveryNotificationsEnabled] = - settings_api::PrefType::PREF_TYPE_BOOLEAN; - // Miscellaneous. TODO(stevenjb): categorize. (*s_allowlist)[::prefs::kEnableDoNotTrack] = settings_api::PrefType::PREF_TYPE_BOOLEAN;
diff --git a/chrome/browser/extensions/api/storage/syncable_settings_storage.cc b/chrome/browser/extensions/api/storage/syncable_settings_storage.cc index 2becc1b..afd0570 100644 --- a/chrome/browser/extensions/api/storage/syncable_settings_storage.cc +++ b/chrome/browser/extensions/api/storage/syncable_settings_storage.cc
@@ -192,8 +192,7 @@ // It's not possible to iterate over a DictionaryValue and modify it at the // same time, so hack around that restriction. std::string key = base::DictionaryValue::Iterator(*local_state).key(); - std::unique_ptr<base::Value> value; - local_state->RemoveWithoutPathExpansion(key, &value); + absl::optional<base::Value> value = local_state->ExtractKey(key); changes.push_back(ValueStoreChange(key, absl::nullopt, std::move(*value))); } @@ -215,15 +214,15 @@ for (base::DictionaryValue::Iterator it(*local_state); !it.IsAtEnd(); it.Advance()) { - std::unique_ptr<base::Value> sync_value; - if (sync_state->RemoveWithoutPathExpansion(it.key(), &sync_value)) { + absl::optional<base::Value> sync_value = sync_state->ExtractKey(it.key()); + if (sync_value.has_value()) { if (*sync_value == it.value()) { // Sync and local values are the same, no changes to send. } else { // Sync value is different, update local setting with new value. changes->push_back(std::make_unique<SettingSyncData>( syncer::SyncChange::ACTION_UPDATE, extension_id_, it.key(), - std::move(sync_value))); + base::Value::ToUniquePtrValue(std::move(*sync_value)))); } } else { // Not synced, delete local setting. @@ -238,10 +237,11 @@ // It's not possible to iterate over a DictionaryValue and modify it at the // same time, so hack around that restriction. std::string key = base::DictionaryValue::Iterator(*sync_state).key(); - std::unique_ptr<base::Value> value; - CHECK(sync_state->RemoveWithoutPathExpansion(key, &value)); + absl::optional<base::Value> value = sync_state->ExtractKey(key); + CHECK(value.has_value()); changes->push_back(std::make_unique<SettingSyncData>( - syncer::SyncChange::ACTION_ADD, extension_id_, key, std::move(value))); + syncer::SyncChange::ACTION_ADD, extension_id_, key, + base::Value::ToUniquePtrValue(std::move(*value)))); } if (changes->empty()) @@ -272,7 +272,7 @@ const std::string& key = sync_change->key(); std::unique_ptr<base::Value> change_value = sync_change->PassValue(); - std::unique_ptr<base::Value> current_value; + absl::optional<base::Value> current_value; { ReadResult maybe_settings = Get(key); if (!maybe_settings.status().ok()) { @@ -284,7 +284,7 @@ sync_processor_->type())); continue; } - maybe_settings.settings().RemoveWithoutPathExpansion(key, ¤t_value); + current_value = maybe_settings.settings().ExtractKey(key); } syncer::SyncError error; @@ -293,22 +293,24 @@ switch (*sync_change->change_type()) { case syncer::SyncChange::ACTION_ADD: - if (!current_value.get()) { + if (!current_value) { error = OnSyncAdd(key, std::move(change_value), &changes); } else { // Already a value; hopefully a local change has beaten sync in a // race and change's not a bug, so pretend change's an update. LOG(WARNING) << "Got add from sync for existing setting " << extension_id_ << "/" << key; - error = OnSyncUpdate(key, std::move(current_value), - std::move(change_value), &changes); + error = OnSyncUpdate( + key, base::Value::ToUniquePtrValue(std::move(*current_value)), + std::move(change_value), &changes); } break; case syncer::SyncChange::ACTION_UPDATE: - if (current_value.get()) { - error = OnSyncUpdate(key, std::move(current_value), - std::move(change_value), &changes); + if (current_value.has_value()) { + error = OnSyncUpdate( + key, base::Value::ToUniquePtrValue(std::move(*current_value)), + std::move(change_value), &changes); } else { // Similarly, pretend change's an add. LOG(WARNING) << "Got update from sync for nonexistent setting" << @@ -318,8 +320,10 @@ break; case syncer::SyncChange::ACTION_DELETE: - if (current_value.get()) { - error = OnSyncDelete(key, std::move(current_value), &changes); + if (current_value.has_value()) { + error = OnSyncDelete( + key, base::Value::ToUniquePtrValue(std::move(*current_value)), + &changes); } else { // Similarly, ignore change. LOG(WARNING) << "Got delete from sync for nonexistent setting " <<
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index c9f469cc..6d8752c 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -1754,9 +1754,12 @@ if (!get_zoom_result) return testing::AssertionFailure() << "no result"; - if (!get_zoom_result->GetAsDouble(zoom_factor)) + + absl::optional<double> maybe_value = get_zoom_result->GetIfDouble(); + if (!maybe_value.has_value()) return testing::AssertionFailure() << "result was not a double"; + *zoom_factor = maybe_value.value(); return testing::AssertionSuccess(); }
diff --git a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc index 721c587..c4d0738 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
@@ -99,7 +99,11 @@ content::RenderFrameHost* render_frame_host, mojo::PendingReceiver<ash::enhanced_network_tts::mojom::EnhancedNetworkTts> receiver) { - ash::EnhancedNetworkTtsImpl::GetInstance().BindReceiver(std::move(receiver)); + ash::enhanced_network_tts::EnhancedNetworkTtsImpl::GetInstance() + .BindReceiverAndURLFactory( + std::move(receiver), + Profile::FromBrowserContext(render_frame_host->GetBrowserContext()) + ->GetURLLoaderFactory()); } #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/extensions/content_verifier_browsertest.cc b/chrome/browser/extensions/content_verifier_browsertest.cc index 856dacc..b808c136 100644 --- a/chrome/browser/extensions/content_verifier_browsertest.cc +++ b/chrome/browser/extensions/content_verifier_browsertest.cc
@@ -524,8 +524,9 @@ } // Now actually test what happens on the next startup after the PRE test above. +// TODO(https://crbug.com/1226260): Test is flaky. IN_PROC_BROWSER_TEST_F(UserInstalledContentVerifierTest, - UserInstalledCorruptedResourceOnStartup) { + DISABLED_UserInstalledCorruptedResourceOnStartup) { ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); int disable_reasons = prefs->GetDisableReasons(kStoragePermissionExtensionId);
diff --git a/chrome/browser/extensions/cross_origin_isolation_browsertest.cc b/chrome/browser/extensions/cross_origin_isolation_browsertest.cc index 50c63fb3..97cb330 100644 --- a/chrome/browser/extensions/cross_origin_isolation_browsertest.cc +++ b/chrome/browser/extensions/cross_origin_isolation_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/version_info/channel.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -17,12 +18,22 @@ #include "extensions/browser/process_map.h" #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_channel.h" +#include "extensions/test/extension_test_message_listener.h" +#include "extensions/test/result_catcher.h" #include "extensions/test/test_extension_dir.h" #include "testing/gmock/include/gmock/gmock.h" namespace extensions { namespace { +void RestrictProcessCount() { + // Set the maximum number of processes to 1. This is a soft limit that + // we're allowed to exceed if processes *must* not share, which is the case + // for cross-origin-isolated contexts vs non-cross-origin-isolated + // contexts. + content::RenderProcessHost::SetMaxRendererProcessCount(1); +} + class CrossOriginIsolationTest : public ExtensionBrowserTest { public: CrossOriginIsolationTest() = default; @@ -32,12 +43,13 @@ const Extension* LoadExtension(TestExtensionDir& dir, const char* coep_value, - const char* coop_value) { + const char* coop_value, + bool use_service_worker = false, + const char* background_script = "", + const char* test_js = "") { constexpr char kManifestTemplate[] = R"( { - "background": { - "scripts": ["background.js"] - }, + "background": { %s }, "manifest_version": 2, "name": "CrossOriginIsolation", "version": "1.1", @@ -47,13 +59,28 @@ "cross_origin_opener_policy": { "value": "%s" }, - "web_accessible_resources": ["test.html"] + "web_accessible_resources": ["test.html"], + "browser_action": { + "default_title": "foo" + } } )"; - dir.WriteManifest( - base::StringPrintf(kManifestTemplate, coep_value, coop_value)); - dir.WriteFile(FILE_PATH_LITERAL("background.js"), ""); - dir.WriteFile(FILE_PATH_LITERAL("test.html"), ""); + + constexpr char kPersistentBackgroundValue[] = R"( + "scripts": ["background.js"] + )"; + constexpr char kServiceWorkerValue[] = R"( + "service_worker": "background.js" + )"; + + dir.WriteManifest(base::StringPrintf( + kManifestTemplate, + use_service_worker ? kServiceWorkerValue : kPersistentBackgroundValue, + coep_value, coop_value)); + dir.WriteFile(FILE_PATH_LITERAL("background.js"), background_script); + dir.WriteFile(FILE_PATH_LITERAL("test.html"), + "<script src='test.js'></script>"); + dir.WriteFile(FILE_PATH_LITERAL("test.js"), test_js); return ExtensionBrowserTest::LoadExtension(dir.UnpackedPath()); } @@ -85,11 +112,7 @@ // Tests that extensions can opt into cross origin isolation. IN_PROC_BROWSER_TEST_F(CrossOriginIsolationTest, CrossOriginIsolation) { - // Set the maximum number of processes to 1. This is a soft limit that - // we're allowed to exceed if processes *must* not share, which is the case - // for cross-origin-isolated origins vs non-cross-origin-isolated - // origins. - content::RenderProcessHost::SetMaxRendererProcessCount(1); + RestrictProcessCount(); TestExtensionDir coi_test_dir; const Extension* coi_extension = @@ -120,11 +143,7 @@ IN_PROC_BROWSER_TEST_F(CrossOriginIsolationTest, WebAccessibleFrame) { ASSERT_TRUE(embedded_test_server()->Start()); - // Set the maximum number of processes to 1. This is a soft limit that - // we're allowed to exceed if processes *must* not share, which is the case - // for cross-origin-isolated origins vs non-cross-origin-isolated - // origins. - content::RenderProcessHost::SetMaxRendererProcessCount(1); + RestrictProcessCount(); TestExtensionDir coi_test_dir; const Extension* coi_extension = @@ -197,6 +216,94 @@ process_map->GetMostLikelyContextType( coi_extension, extension_iframe->GetProcess()->GetID(), url)); } + + // Finally make some extension API calls to ensure both cross-origin-isolated + // and non-cross-origin-isolated extension contexts are considered "blessed". + { + auto verify_is_blessed_context = [](content::RenderFrameHost* host) { + std::string result; + const char* kScript = R"( + chrome.browserAction.getTitle({}, title => { + window.domAutomationController.send(title); + }); + )"; + ASSERT_TRUE( + content::ExecuteScriptAndExtractString(host, kScript, &result)); + EXPECT_EQ("foo", result); + }; + + { + SCOPED_TRACE("Verifying coi extension background is a blessed context."); + verify_is_blessed_context(coi_background_rfh); + } + { + SCOPED_TRACE("Verifying non-coi extension iframe is a blessed context."); + verify_is_blessed_context(extension_iframe); + } + } +} + +// Test that an extension service worker for a cross origin isolated extension +// is not cross origin isolated. See crbug.com/1131404. +IN_PROC_BROWSER_TEST_F(CrossOriginIsolationTest, ServiceWorker) { + ASSERT_TRUE(embedded_test_server()->Start()); + + RestrictProcessCount(); + + constexpr char kServiceWorkerScript[] = R"( + const readyMessage = crossOriginIsolated ? + 'crossOriginIsolated' : 'notCrossOriginIsolated'; + chrome.test.sendMessage(readyMessage, () => {}); + )"; + + ExtensionTestMessageListener ready_listener("notCrossOriginIsolated", + true /* will_reply */); + TestExtensionDir coi_test_dir; + const Extension* coi_extension = + LoadExtension(coi_test_dir, "require-corp", "same-origin", + true /* use_service_worker */, kServiceWorkerScript); + ASSERT_TRUE(coi_extension); + EXPECT_TRUE(ready_listener.WaitUntilSatisfied()); + + GURL extension_test_url = coi_extension->GetResourceURL("test.html"); + content::RenderFrameHost* extension_tab = + ui_test_utils::NavigateToURL(browser(), extension_test_url); + ASSERT_TRUE(extension_tab); + + // The service worker should be active since it's waiting for a response to + // chrome.test.sendMessage call. + std::vector<WorkerId> service_workers = + ProcessManager::Get(profile())->GetServiceWorkersForExtension( + coi_extension->id()); + ASSERT_EQ(1u, service_workers.size()); + + // Sanity checking that the service worker (non-cross-origin-isolated) and the + // extension tab (cross-origin-isolated) don't share a process. + content::RenderProcessHost* service_worker_process = + content::RenderProcessHost::FromID(service_workers[0].render_process_id); + ASSERT_TRUE(service_worker_process); + EXPECT_NE(service_worker_process, extension_tab->GetProcess()); + + // Check ProcessMap APIs to ensure they work correctly for the case where an + // extension has multiple processes for the same profile. + ProcessMap* process_map = ProcessMap::Get(profile()); + ASSERT_TRUE(process_map); + EXPECT_TRUE(process_map->Contains(coi_extension->id(), + extension_tab->GetProcess()->GetID())); + EXPECT_TRUE(process_map->Contains(coi_extension->id(), + service_worker_process->GetID())); + + GURL* url = nullptr; + EXPECT_EQ(Feature::BLESSED_EXTENSION_CONTEXT, + process_map->GetMostLikelyContextType( + coi_extension, extension_tab->GetProcess()->GetID(), url)); + EXPECT_EQ(Feature::BLESSED_EXTENSION_CONTEXT, + process_map->GetMostLikelyContextType( + coi_extension, service_worker_process->GetID(), url)); + + // Reply to the service worker. This is not useful for the test but is + // required by ExtensionTestMessageListener. + ready_listener.Reply(""); } // Tests certain extension APIs which retrieve in-process extension windows. @@ -286,5 +393,170 @@ } } +// Tests extension messaging between cross origin isolated and +// non-cross-origin-isolated frames of an extension. +IN_PROC_BROWSER_TEST_F(CrossOriginIsolationTest, ExtensionMessaging_Frames) { + ASSERT_TRUE(embedded_test_server()->Start()); + + RestrictProcessCount(); + + constexpr char kTestJs[] = R"( + function inIframe () { + try { + // Accessing `window.top` may raise an error due to the same origin + // policy. + return window.self !== window.top; + } catch (e) { + return true; + } + } + + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message !== 'hello') { + sendResponse('Unexpected message in test script ' + message); + return; + } + + if (inIframe()) + sendResponse('ack-from-iframe'); + else + sendResponse('ack-from-tab'); + }); + )"; + + TestExtensionDir coi_test_dir; + const Extension* coi_extension = LoadExtension( + coi_test_dir, "require-corp", "same-origin", + false /* use_service_worker */, "" /* background_js */, kTestJs); + ASSERT_TRUE(coi_extension); + + ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/iframe_blank.html")); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + GURL extension_test_url = coi_extension->GetResourceURL("test.html"); + ASSERT_TRUE( + content::NavigateIframeToURL(web_contents, "test", extension_test_url)); + content::RenderFrameHost* extension_iframe = + content::ChildFrameAt(web_contents->GetMainFrame(), 0); + ASSERT_TRUE(extension_iframe); + + content::RenderFrameHost* extension_tab = + ui_test_utils::NavigateToURLWithDisposition( + browser(), extension_test_url, + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + ASSERT_TRUE(extension_tab); + + // `extension_iframe` and `extension_tab` should not share a process as they + // are non-cross-origin-isolated and cross-origin-isolated respectively. + EXPECT_NE(extension_iframe->GetProcess(), extension_tab->GetProcess()); + + // However they should be able to use extension messaging to communicate. + auto test_messaging = [](content::RenderFrameHost* source, + content::RenderFrameHost* destination, + const char* expected_response) { + constexpr char kScript[] = R"( + chrome.runtime.sendMessage('hello', response => { + chrome.test.assertNoLastError(); + chrome.test.assertEq($1, response); + chrome.test.succeed(); + }); + )"; + + ResultCatcher catcher; + ASSERT_TRUE(content::ExecuteScript( + source, content::JsReplace(kScript, expected_response))); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + }; + + { + SCOPED_TRACE("Message from iframe to tab."); + test_messaging(extension_iframe, extension_tab, "ack-from-tab"); + } + + { + SCOPED_TRACE("Message from tab to iframe."); + test_messaging(extension_tab, extension_iframe, "ack-from-iframe"); + } +} + +// Tests extension messaging between a cross origin isolated extension frame and +// the extension service worker which is not cross origin isolated (and hence in +// a different process). +IN_PROC_BROWSER_TEST_F(CrossOriginIsolationTest, + ExtensionMessaging_ServiceWorker) { + ASSERT_TRUE(embedded_test_server()->Start()); + + RestrictProcessCount(); + + constexpr char kTestJs[] = R"( + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + console.log('message received'); + if (message !== 'hello-from-service-worker') { + sendResponse('Invalid message received by tab ' + message); + return; + } + + sendResponse('ack-from-tab'); + }); + )"; + + constexpr char kServiceWorkerScript[] = R"( + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message !== 'hello-from-tab') { + sendResponse('Invalid message received by service worker ' + message); + return; + } + + sendResponse('ack-from-service-worker'); + }); + + chrome.test.sendMessage('ready', () => { + chrome.runtime.sendMessage( + 'hello-from-service-worker', response => { + chrome.test.assertNoLastError(); + chrome.test.assertEq('ack-from-tab', response); + chrome.test.succeed(); + }); + }); + )"; + + ExtensionTestMessageListener ready_listener("ready", true /* will_reply */); + TestExtensionDir coi_test_dir; + const Extension* coi_extension = LoadExtension( + coi_test_dir, "require-corp", "same-origin", + true /* use_service_worker */, kServiceWorkerScript, kTestJs); + ASSERT_TRUE(coi_extension); + EXPECT_TRUE(ready_listener.WaitUntilSatisfied()); + + GURL extension_test_url = coi_extension->GetResourceURL("test.html"); + content::RenderFrameHost* extension_tab = + ui_test_utils::NavigateToURL(browser(), extension_test_url); + ASSERT_TRUE(extension_tab); + + { + SCOPED_TRACE("Message from service worker to tab."); + ResultCatcher catcher; + ready_listener.Reply(""); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + } + + { + SCOPED_TRACE("Message from tab to service worker."); + constexpr char kScript[] = R"( + chrome.runtime.sendMessage('hello-from-tab', response => { + chrome.test.assertNoLastError(); + chrome.test.assertEq('ack-from-service-worker', response); + chrome.test.succeed(); + }); + )"; + ResultCatcher catcher; + ASSERT_TRUE(content::ExecuteScript(extension_tab, kScript)); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + } +} + } // namespace } // namespace extensions
diff --git a/chrome/browser/extensions/preinstalled_apps_browsertest.cc b/chrome/browser/extensions/preinstalled_apps_browsertest.cc index ac69753..934497f 100644 --- a/chrome/browser/extensions/preinstalled_apps_browsertest.cc +++ b/chrome/browser/extensions/preinstalled_apps_browsertest.cc
@@ -237,13 +237,15 @@ // Returns true if the web app is currently installed in this profile (even if // it was installed from a previous run). bool IsWebAppCurrentlyInstalled() { - const web_app::AppId app_id = web_app::GenerateAppIdFromURL(GetAppUrl()); + const web_app::AppId app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GetAppUrl()); return web_app::WebAppProvider::Get(profile())->registrar().IsInstalled( app_id); } bool CanWebAppAlwaysUpdateIdentity() { - const web_app::AppId app_id = web_app::GenerateAppIdFromURL(GetAppUrl()); + const web_app::AppId app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GetAppUrl()); const web_app::WebApp* web_app = web_app::WebAppProvider::Get(profile()) ->registrar() .AsWebAppRegistrar()
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroController.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroController.java index fb1fc9ef..4bf942c2 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroController.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroController.java
@@ -13,6 +13,7 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.feed.FeedServiceBridge; import org.chromium.chrome.browser.feed.v2.FeedUserActionType; @@ -32,6 +33,7 @@ import org.chromium.components.feature_engagement.Tracker; import org.chromium.components.prefs.PrefService; import org.chromium.components.user_prefs.UserPrefs; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.widget.LoadingView; import org.chromium.url.GURL; @@ -42,7 +44,7 @@ * Controls when and how the Web Feed follow intro is shown. */ public class WebFeedFollowIntroController { - static final long INTRO_WAIT_TIME_MS = TimeUnit.SECONDS.toMillis(5); + static final long INTRO_WAIT_TIME_MS = TimeUnit.SECONDS.toMillis(8); // Visit history requirements. static final int DEFAULT_DAILY_VISIT_MIN = 3; static final int DEFAULT_NUM_VISIT_MIN = 5; @@ -76,12 +78,14 @@ private boolean mAcceleratorPressed; private boolean mIntroShown; - private boolean mIsRecommended; private boolean mMeetsVisitRequirement; - private long mPageLoadTime; - private byte[] mWebFeedId; - private GURL mUrl; - private String mTitle; + + private class RecommendedWebFeedInfo { + public byte[] webFeedId; + public GURL url; + public String title; + } + private RecommendedWebFeedInfo mRecommendedInfo; /** * Constructs an instance of {@link WebFeedFollowIntroController}. @@ -123,42 +127,42 @@ } @Override - public void onContentViewScrollingEnded(int verticalScrollDelta) { - if (verticalScrollDelta > 0) { - maybeShowFollowIntro(); - } - } - - @Override public void didFirstVisuallyNonEmptyPaint(Tab tab) { // Note that we're using didFirstVisuallyNonEmptyPaint as a proxy for a page load // event because some pages never fully load even though they are perfectly // interactive. GURL url = tab.getUrl(); + // TODO(crbug/1152592): Also check for certificate errors or SafeBrowser warnings. if (tab.isIncognito() || !(url.getScheme().equals("http") || url.getScheme().equals("https"))) { return; } - mPageLoadTime = mClock.currentTimeMillis(); - WebFeedBridge.getVisitCountsToHost(url, result -> mMeetsVisitRequirement = result.visits >= numVisitMin && result.dailyVisits >= dailyVisitMin); WebFeedBridge.getWebFeedMetadataForPage(tab, url, result -> { - // Shouldn't be recommended if there's no metadata or if the ID doesn't exist. - if (result == null || result.id == null || result.id.length == 0) { - mIsRecommended = false; - return; - } - mWebFeedId = result.id; - mIsRecommended = result.isRecommended + // Shouldn't be recommended if there's no metadata, ID doesn't exist, or if it + // is already followed. + if (result != null && result.id != null && result.id.length > 0 + && result.isRecommended && result.subscriptionStatus - == WebFeedSubscriptionStatus.NOT_SUBSCRIBED; - mTitle = result.title; - mUrl = url; + == WebFeedSubscriptionStatus.NOT_SUBSCRIBED) { + mRecommendedInfo = new RecommendedWebFeedInfo(); + mRecommendedInfo.webFeedId = result.id; + mRecommendedInfo.title = result.title; + mRecommendedInfo.url = url; + } else { + mRecommendedInfo = null; + } }); + + // The requests for information above should all be done by the time this delayed + // task is executed. + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, + WebFeedFollowIntroController.this::maybeShowFollowIntro, + INTRO_WAIT_TIME_MS); } }; mCurrentTabObserver = new CurrentTabObserver(tabSupplier, mTabObserver, this::swapTabs); @@ -174,15 +178,13 @@ private void clearPageInfo() { mIntroShown = false; - mIsRecommended = false; + mRecommendedInfo = null; mAcceleratorPressed = false; mMeetsVisitRequirement = false; } private void maybeShowFollowIntro() { - if (!shouldShowFollowIntro()) { - return; - } + if (!shouldShowFollowIntro()) return; // TODO(crbug/1152592): Add IPH variation. showFollowAccelerator(); } @@ -200,7 +202,8 @@ mSharedPreferencesManager.writeLong( ChromePreferenceKeys.WEB_FEED_INTRO_LAST_SHOWN_TIME_MS, currentTimeMillis); mSharedPreferencesManager.writeLong( - getWebFeedIntroWebFeedIdShownTimeMsKey(mWebFeedId), currentTimeMillis); + getWebFeedIntroWebFeedIdShownTimeMsKey(mRecommendedInfo.webFeedId), + currentTimeMillis); } GestureDetector gestureDetector = new GestureDetector( @@ -237,7 +240,7 @@ FeedServiceBridge.reportOtherUserAction( FeedUserActionType.TAPPED_FOLLOW_ON_FOLLOW_ACCELERATOR); - WebFeedBridge.followFromId(mWebFeedId, + WebFeedBridge.followFromId(mRecommendedInfo.webFeedId, results -> mWebFeedFollowIntroView.hideLoadingUI(new LoadingView.Observer() { @Override public void onShowLoadingUIComplete() {} @@ -249,29 +252,47 @@ mWebFeedFollowIntroView.showFollowingBubble(); } byte[] followId = results.metadata != null ? results.metadata.id : null; - mWebFeedSnackbarController.showPostFollowHelp( - currentTab, results, followId, mUrl, mTitle); + mWebFeedSnackbarController.showPostFollowHelp(currentTab, results, followId, + mRecommendedInfo.url, mRecommendedInfo.title); } })); } + /** + * Allows the intro to be presented if (all must be true): + * * It was not already presented for this page + * * The URL is recommended. + * * This site was visited enough in day-boolean count and in total. + * * Enough time has passed since the last intro was presented and since the last intro was + * presented for this site. + * * Feature trackers allows it, which includes checking for a weekly limit. + * + * If the intro debug mode pref is enabled, then only checks for the intro not having been + * presented yet. + * + * @return true if the follow intro should be shown. false otherwise. + */ private boolean shouldShowFollowIntro() { - if (!mIsRecommended) return false; + if (mIntroShown) return false; - long currentTimeMillis = mClock.currentTimeMillis(); - boolean hasBeenOnPageLongEnough = (currentTimeMillis - mPageLoadTime) > INTRO_WAIT_TIME_MS; if (mPrefService.getBoolean(Pref.ENABLE_WEB_FEED_FOLLOW_INTRO_DEBUG)) { - return !mIntroShown && hasBeenOnPageLongEnough; + return true; } - long lastShownTime = mSharedPreferencesManager.readLong( - ChromePreferenceKeys.WEB_FEED_INTRO_LAST_SHOWN_TIME_MS); - long lastShownForWebFeedIdMs = mSharedPreferencesManager.readLong( - getWebFeedIntroWebFeedIdShownTimeMsKey(mWebFeedId)); - return !mIntroShown && mMeetsVisitRequirement && hasBeenOnPageLongEnough - && ((currentTimeMillis - lastShownTime) > mAppearanceThresholdMs) - && ((currentTimeMillis - lastShownForWebFeedIdMs) - > WEB_FEED_ID_APPEARANCE_THRESHOLD_MILLIS) + if (mRecommendedInfo == null) return false; + + long currentTimeMillis = mClock.currentTimeMillis(); + long timeSinceLastShown = currentTimeMillis + - mSharedPreferencesManager.readLong( + ChromePreferenceKeys.WEB_FEED_INTRO_LAST_SHOWN_TIME_MS); + long timeSinceLastShownForWebFeed = currentTimeMillis + - mSharedPreferencesManager.readLong( + getWebFeedIntroWebFeedIdShownTimeMsKey(mRecommendedInfo.webFeedId)); + // Note: the maximum number of weekly appearances is controlled by FeatureEngagementTracker + // based on the configuration used for this IPH. See the kIPHWebFeedFollowFeature entry in + // components/feature_engagement/public/feature_configurations.cc. + return mMeetsVisitRequirement && (timeSinceLastShown > mAppearanceThresholdMs) + && (timeSinceLastShownForWebFeed > WEB_FEED_ID_APPEARANCE_THRESHOLD_MILLIS) && mFeatureEngagementTracker.shouldTriggerHelpUI( FeatureConstants.IPH_WEB_FEED_FOLLOW_FEATURE); }
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java index fb64ad1..0205eef 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java
@@ -34,10 +34,12 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; import org.chromium.base.Callback; import org.chromium.base.FeatureList; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.task.test.ShadowPostTask; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; @@ -60,12 +62,16 @@ import org.chromium.url.JUnitTestGURLs; import java.util.HashMap; +import java.util.concurrent.TimeUnit; /** * Tests {@link WebFeedFollowIntroController}. */ @RunWith(BaseRobolectricTestRunner.class) +@Config(shadows = {ShadowPostTask.class}) public final class WebFeedFollowIntroControllerTest { + private static final long SAFE_INTRO_WAIT_TIME = + WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 10; private static final GURL sTestUrl = JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL); private static final byte[] sWebFeedId = "webFeedId".getBytes(); private static final SharedPreferencesManager sSharedPreferencesManager = @@ -108,8 +114,6 @@ @Before public void setUp() { - FeatureList.setTestFeatures(new HashMap<String, Boolean>()); - MockitoAnnotations.initMocks(this); mJniMocker.mock(WebFeedBridge.getTestHooksForTesting(), mWebFeedBridgeJniMock); mJniMocker.mock(UserPrefsJni.TEST_HOOKS, mUserPrefsJniMock); @@ -117,7 +121,6 @@ Profile.setLastUsedProfileForTesting(mProfile); Mockito.when(mUserPrefsJniMock.get(mProfile)).thenReturn(mPrefService); - Profile.setLastUsedProfileForTesting(mProfile); mActivity = Robolectric.setupActivity(Activity.class); // Required for resolving an attribute used in AppMenuItemText. mActivity.setTheme(R.style.Theme_BrowserUI); @@ -127,13 +130,16 @@ when(mTab.getUrl()).thenReturn(sTestUrl); when(mTab.isIncognito()).thenReturn(false); TrackerFactory.setTrackerForTests(mTracker); + + // This empty setTestFeatures call below is needed to enable the field trial param calls. + FeatureList.setTestFeatures(new HashMap<String, Boolean>()); mNumVisitMin = ChromeFeatureList.getFieldTrialParamByFeatureAsInt( ChromeFeatureList.WEB_FEED, PARAM_NUM_VISIT_MIN, DEFAULT_NUM_VISIT_MIN); mDailyVisitMin = ChromeFeatureList.getFieldTrialParamByFeatureAsInt( ChromeFeatureList.WEB_FEED, PARAM_DAILY_VISIT_MIN, DEFAULT_DAILY_VISIT_MIN); + mWebFeedFollowIntroController = new WebFeedFollowIntroController(mActivity, mAppMenuHandler, mTabSupplier, new View(mActivity), mFeedLauncher, mDialogManager, mSnackbarManager); - mEmptyTabObserver = mWebFeedFollowIntroController.getEmptyTabObserverForTesting(); mWebFeedFollowIntroController.setClockForTesting(mClock); } @@ -146,8 +152,11 @@ @Test @SmallTest public void meetsShowingRequirements_showsIntro() { - prepareForMeetingIntroRequirements(); - performScrollUpAfterDelay(WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 1); + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/true); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); assertTrue( "Intro should be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); @@ -165,10 +174,11 @@ @Test @SmallTest public void notRecommended_doesNotShowIntro() { - performScrollUpAfterDelay(WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 1); - invokePageLoad(new WebFeedBridge.WebFeedMetadata(sWebFeedId, "title", sTestUrl, - WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isActive=*/ - true, /*isRecommended=*/false)); + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/false); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); assertFalse("Intro should not be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); @@ -177,10 +187,11 @@ @Test @SmallTest public void subscribed_doesNotShowIntro() { - performScrollUpAfterDelay(WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 1); - invokePageLoad(new WebFeedBridge.WebFeedMetadata(sWebFeedId, "title", sTestUrl, - WebFeedSubscriptionStatus.SUBSCRIBED, /*isActive=*/ - true, /*isRecommended=*/true)); + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.SUBSCRIBED, /*isRecommended=*/true); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); assertFalse("Intro should not be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); @@ -188,8 +199,12 @@ @Test @SmallTest - public void scrollUpWithoutDelay_doesNotShowIntro() { - performScrollUpAfterDelay(0); + public void tooShortDelay_doesNotShowIntro() { + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/true); + advanceClockByMs(SAFE_INTRO_WAIT_TIME / 2); assertFalse("Intro should not be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); @@ -197,10 +212,25 @@ @Test @SmallTest - public void doesNotMeetVisitRequirements_doesNotShowIntro() { - setRecommendableVisitCount( - new WebFeedBridge.VisitCounts(mNumVisitMin - 1, mDailyVisitMin - 1)); - performScrollUpAfterDelay(WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 1); + public void doesNotMeetTotalVisitRequirement_doesNotShowIntro() { + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin - 1, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/true); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); + + assertFalse("Intro should not be shown.", + mWebFeedFollowIntroController.getIntroShownForTesting()); + } + + @Test + @SmallTest + public void doesNotMeetDailyVisitRequirement_doesNotShowIntro() { + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin - 1); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/true); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); assertFalse("Intro should not be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); @@ -209,9 +239,11 @@ @Test @SmallTest public void lastShownTimeTooClose_doesNotShowIntro() { - setSharedPreferences(/*webFeedIntroLastShownTimeMs=*/mClock.currentTimeMillis(), - /*webFeedIntroWebFeedIdShownTimeMs=*/0); - performScrollUpAfterDelay(WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 1); + setWebFeedIntroLastShownTimeMsPref(mClock.currentTimeMillis() - 1000); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/true); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); assertFalse("Intro should not be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); @@ -220,9 +252,11 @@ @Test @SmallTest public void lastShownForWebFeedIdTimeTooClose_doesNotShowIntro() { - setSharedPreferences(/*webFeedIntroLastShownTimeMs=*/0, - /*webFeedIntroWebFeedIdShownTimeMs=*/mClock.currentTimeMillis()); - performScrollUpAfterDelay(WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 1); + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(mClock.currentTimeMillis() - 1000); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/true); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); assertFalse("Intro should not be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); @@ -231,34 +265,33 @@ @Test @SmallTest public void featureEngagementTrackerSaysDoNotShow_doesNotShowIntro() { + setWebFeedIntroLastShownTimeMsPref(0); + setWebFeedIntroWebFeedIdShownTimeMsPref(0); + setRecommendableVisitCount(mNumVisitMin, mDailyVisitMin); + invokePageLoad(WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isRecommended=*/true); when(mTracker.shouldTriggerHelpUI(FeatureConstants.IPH_WEB_FEED_FOLLOW_FEATURE)) .thenReturn(false); - performScrollUpAfterDelay(WebFeedFollowIntroController.INTRO_WAIT_TIME_MS + 1); + advanceClockByMs(SAFE_INTRO_WAIT_TIME); assertFalse("Intro should not be shown.", mWebFeedFollowIntroController.getIntroShownForTesting()); } - private void prepareForMeetingIntroRequirements() { - setSharedPreferences( - /*webFeedIntroLastShownTimeMs=*/0, /*webFeedIntroWebFeedIdShownTimeMs=*/0); - setRecommendableVisitCount(new WebFeedBridge.VisitCounts(mNumVisitMin, mDailyVisitMin)); - invokePageLoad(new WebFeedBridge.WebFeedMetadata(sWebFeedId, "title", sTestUrl, - WebFeedSubscriptionStatus.NOT_SUBSCRIBED, /*isActive=*/ - true, /*isRecommended=*/true)); - } - - private void setSharedPreferences( - long webFeedIntroLastShownTimeMs, long webFeedIntroWebFeedIdShownTimeMs) { + private void setWebFeedIntroLastShownTimeMsPref(long webFeedIntroLastShownTimeMs) { sSharedPreferencesManager.writeLong(ChromePreferenceKeys.WEB_FEED_INTRO_LAST_SHOWN_TIME_MS, webFeedIntroLastShownTimeMs); + } + + private void setWebFeedIntroWebFeedIdShownTimeMsPref(long webFeedIntroWebFeedIdShownTimeMs) { sSharedPreferencesManager.writeLong( ChromePreferenceKeys.WEB_FEED_INTRO_WEB_FEED_ID_SHOWN_TIME_MS_PREFIX.createKey( Base64.encodeToString(sWebFeedId, Base64.DEFAULT)), webFeedIntroWebFeedIdShownTimeMs); } - private void setRecommendableVisitCount(WebFeedBridge.VisitCounts visitCounts) { + private void setRecommendableVisitCount(int numVisits, int dailyVisits) { + WebFeedBridge.VisitCounts visitCounts = + new WebFeedBridge.VisitCounts(numVisits, dailyVisits); doAnswer(invocation -> { invocation.<Callback<int[]>>getArgument(1).onResult( new int[] {visitCounts.visits, visitCounts.dailyVisits}); @@ -268,7 +301,11 @@ .getRecentVisitCountsToHost(eq(sTestUrl), any(Callback.class)); } - private void invokePageLoad(WebFeedBridge.WebFeedMetadata webFeedMetadata) { + private void invokePageLoad( + @WebFeedSubscriptionStatus int subscriptionStatus, boolean isRecommended) { + WebFeedBridge.WebFeedMetadata webFeedMetadata = + new WebFeedBridge.WebFeedMetadata(sWebFeedId, "title", sTestUrl, subscriptionStatus, + /*isActive=*/true, isRecommended); doAnswer(invocation -> { invocation.<Callback<WebFeedBridge.WebFeedMetadata>>getArgument(1).onResult( webFeedMetadata); @@ -283,9 +320,9 @@ assertEquals(sTestUrl, mPageInformationCaptor.getValue().mUrl); } - private void performScrollUpAfterDelay(long delay) { - mClock.advanceCurrentTimeMillis(delay); - mEmptyTabObserver.onContentViewScrollingEnded(/*verticalScrollDelta=*/10); + private void advanceClockByMs(long timeMs) { + mClock.advanceCurrentTimeMillis(timeMs); + Robolectric.getForegroundThreadScheduler().advanceBy(timeMs, TimeUnit.MILLISECONDS); } /**
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc index 3127164..4e8e732 100644 --- a/chrome/browser/first_run/first_run.cc +++ b/chrome/browser/first_run/first_run.cc
@@ -416,8 +416,7 @@ // The distribution dictionary (and any prefs below it) are never registered // for use in Chrome's PrefService. Strip them from the initial dictionary // before mapping it to prefs. - initial_dictionary->RemoveWithoutPathExpansion( - installer::initial_preferences::kDistroDict, nullptr); + initial_dictionary->RemoveKey(installer::initial_preferences::kDistroDict); if (!chrome_prefs::InitializePrefsFromMasterPrefs( profiles::GetDefaultProfileDir(user_data_dir),
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 05a4e33..dc39ba4 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1574,6 +1574,11 @@ "expiry_milestone": 95 }, { + "name": "enable-cros-ime-assist-multi-word-expanded", + "owners": [ "curtismcmullan", "essential-inputs-team@google.com" ], + "expiry_milestone": 96 + }, + { "name": "enable-cros-ime-assist-personal-info", "owners": [ "jiwan", "essential-inputs-team@google.com" ], "expiry_milestone": 95 @@ -1768,6 +1773,11 @@ "expiry_milestone": 95 }, { + "name": "enable-desktop-pwas-web-bundles", + "owners": [ "loyso@chromium.org", "desktop-pwas-team@google.com" ], + "expiry_milestone": 110 + }, + { "name": "enable-desktop-pwas-window-controls-overlay", "owners": [ "ambake@microsoft.com", "desktop-pwas-team@google.com" ], "expiry_milestone": 96 @@ -3707,7 +3717,7 @@ { "name": "messages-for-android-passwords", "owners": [ "pavely", "lazzzis" ], - "expiry_milestone": 95 + "expiry_milestone": 99 }, { "name": "messages-for-android-popup-blocked", @@ -3715,6 +3725,11 @@ "expiry_milestone": 97 }, { + "name": "messages-for-android-reader-mode", + "owners": [ "pavely", "lazzzis" ], + "expiry_milestone": 99 + }, + { "name": "messages-for-android-safety-tip", "owners": [ "pavely", "lazzzis" ], "expiry_milestone": 98 @@ -4238,12 +4253,22 @@ { "name": "override-language-prefs-for-href-translate", "owners": [ "sclittle", "chrome-language@google.com" ], - "expiry_milestone": 91 + "expiry_milestone": 97 + }, + { + "name": "override-similar-languages-for-href-translate", + "owners": [ "sclittle", "chrome-language@google.com" ], + "expiry_milestone": 97 }, { "name": "override-site-prefs-for-href-translate", "owners": [ "sclittle", "chrome-language@google.com" ], - "expiry_milestone": 91 + "expiry_milestone": 97 + }, + { + "name": "override-unsupported-page-language-for-href-translate", + "owners": [ "sclittle", "chrome-language@google.com" ], + "expiry_milestone": 97 }, { // This flag is used by ChromeOS for some accessibility users.
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index bfd6b4d..137aba4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -835,6 +835,11 @@ "override. Prototype implementation of: " "https://github.com/WICG/window-controls-overlay/blob/main/explainer.md"; +const char kDesktopPWAsWebBundlesName[] = "Desktop PWAs Web Bundles"; +const char kDesktopPWAsWebBundlesDescription[] = + "Adds support for web bundles, making web apps able to be launched " + "offline."; + const char kEnableMigrateDefaultChromeAppToWebAppsGSuiteName[] = "Migrate default G Suite Chrome apps to web apps"; const char kEnableMigrateDefaultChromeAppToWebAppsGSuiteDescription[] = @@ -1974,6 +1979,16 @@ const char kOverrideSitePrefsForHrefTranslateDescription[] = "When using hrefTranslate, ignore the user's blocklist of websites that " "shouldn't be translated."; +const char kOverrideUnsupportedPageLanguageForHrefTranslateName[] = + "Force translation on pages with unsupported languages for hrefTranslate"; +const char kOverrideUnsupportedPageLanguageForHrefTranslateDescription[] = + "When using hrefTranslate, force translation on pages where the page's " + "language cannot be determined or is unsupported."; +const char kOverrideSimilarLanguagesForHrefTranslateName[] = + "Force translation on pages with a similar page language for hrefTranslate"; +const char kOverrideSimilarLanguagesForHrefTranslateDescription[] = + "When using hrefTranslate, force translation on pages where the page's " + "language is similar to the target language specified via hrefTranslate."; const char kOverscrollHistoryNavigationName[] = "Overscroll history navigation"; const char kOverscrollHistoryNavigationDescription[] = @@ -3194,12 +3209,6 @@ const char kInterestFeedContentSuggestionsName[] = "Interest Feed Content Suggestions"; -const char kInterestFeedNoticeCardAutoDismissName[] = - "Interest Feed notice card auto-dismiss"; -const char kInterestFeedNoticeCardAutoDismissDescription[] = - "Auto-dismiss the notice card when there are enough clicks or views on the " - "notice card."; - const char kInterestFeedV2Name[] = "Interest Feed v2"; const char kInterestFeedV2Description[] = "Show content suggestions on the New Tab Page and Start Surface using the " @@ -3235,6 +3244,10 @@ const char kMessagesForAndroidPopupBlockedDescription[] = "When enabled, popup blocked prompt will use the new Messages UI."; +const char kMessagesForAndroidReaderModeName[] = "Reader Mode Messages UI"; +const char kMessagesForAndroidReaderModeDescription[] = + "When enabled, reader mode prompt will use the new Messages UI."; + const char kMessagesForAndroidSafetyTipName[] = "Safety Tip Messages UI"; const char kMessagesForAndroidSafetyTipDescription[] = "When enabled, safety tip prompt will use the new Messages UI."; @@ -4726,6 +4739,11 @@ const char kImeAssistMultiWordDescription[] = "Enable assistive multi word suggestions for native IME"; +const char kImeAssistMultiWordExpandedName[] = + "Enable expanded assistive multi word suggestions"; +const char kImeAssistMultiWordExpandedDescription[] = + "Enable expanded assistive multi word suggestions for native IME"; + const char kImeAssistPersonalInfoName[] = "Enable assistive personal info"; const char kImeAssistPersonalInfoDescription[] = "Enable auto-complete suggestions on personal infomation for native IME.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index b1f093b..b571564 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -495,6 +495,9 @@ extern const char kDesktopPWAsUrlHandlingName[]; extern const char kDesktopPWAsUrlHandlingDescription[]; +extern const char kDesktopPWAsWebBundlesName[]; +extern const char kDesktopPWAsWebBundlesDescription[]; + extern const char kDesktopPWAsWindowControlsOverlayName[]; extern const char kDesktopPWAsWindowControlsOverlayDescription[]; @@ -1125,6 +1128,10 @@ extern const char kOverrideLanguagePrefsForHrefTranslateDescription[]; extern const char kOverrideSitePrefsForHrefTranslateName[]; extern const char kOverrideSitePrefsForHrefTranslateDescription[]; +extern const char kOverrideUnsupportedPageLanguageForHrefTranslateName[]; +extern const char kOverrideUnsupportedPageLanguageForHrefTranslateDescription[]; +extern const char kOverrideSimilarLanguagesForHrefTranslateName[]; +extern const char kOverrideSimilarLanguagesForHrefTranslateDescription[]; extern const char kUpdateHoverAtBeginFrameName[]; extern const char kUpdateHoverAtBeginFrameDescription[]; @@ -1829,9 +1836,6 @@ extern const char kInterestFeedContentSuggestionsName[]; extern const char kInterestFeedContentSuggestionsDescription[]; -extern const char kInterestFeedNoticeCardAutoDismissName[]; -extern const char kInterestFeedNoticeCardAutoDismissDescription[]; - extern const char kInterestFeedV2Name[]; extern const char kInterestFeedV2Description[]; @@ -1858,6 +1862,9 @@ extern const char kMessagesForAndroidPopupBlockedName[]; extern const char kMessagesForAndroidPopupBlockedDescription[]; +extern const char kMessagesForAndroidReaderModeName[]; +extern const char kMessagesForAndroidReaderModeDescription[]; + extern const char kMessagesForAndroidSafetyTipName[]; extern const char kMessagesForAndroidSafetyTipDescription[]; @@ -2719,6 +2726,9 @@ extern const char kImeAssistMultiWordName[]; extern const char kImeAssistMultiWordDescription[]; +extern const char kImeAssistMultiWordExpandedName[]; +extern const char kImeAssistMultiWordExpandedDescription[]; + extern const char kImeAssistPersonalInfoName[]; extern const char kImeAssistPersonalInfoDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 6a485001..ca6e5ff0 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -125,7 +125,6 @@ &feature_engagement::kIPHTabSwitcherButtonFeature, &feed::kFeedInteractiveRefresh, &feed::kInterestFeedContentSuggestions, - &feed::kInterestFeedNoticeCardAutoDismiss, &feed::kInterestFeedSpinnerAlwaysAnimate, &feed::kInterestFeedV1ClicksAndViewsConditionalUpload, &feed::kInterestFeedV2, @@ -281,6 +280,7 @@ &language::kTranslateAssistContent, &language::kTranslateIntent, &messages::kMessagesForAndroidInfrastructure, + &messages::kMessagesForAndroidReaderMode, &offline_pages::kOfflineIndicatorFeature, &offline_pages::kOfflinePagesCTFeature, // See crbug.com/620421. &offline_pages::kOfflinePagesCTV2Feature, // See crbug.com/734753.
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java index a71ec11..eaa9d9a4 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -46,7 +46,6 @@ */ private static Map<String, Boolean> sDefaults = new HashMap<String, Boolean>() { { - put(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, false); put(ChromeFeatureList.ANDROID_PARTNER_CUSTOMIZATION_PHENOTYPE, true); put(ChromeFeatureList.BOOKMARK_BOTTOM_SHEET, false); put(ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID, false);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 31a78918..6b20a770 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -383,6 +383,7 @@ public static final String MARK_HTTP_AS = "MarkHttpAs"; public static final String MESSAGES_FOR_ANDROID_INFRASTRUCTURE = "MessagesForAndroidInfrastructure"; + public static final String MESSAGES_FOR_ANDROID_READER_MODE = "MessagesForAndroidReaderMode"; public static final String MOBILE_IDENTITY_CONSISTENCY_VAR = "MobileIdentityConsistencyVar"; public static final String MOBILE_IDENTITY_CONSISTENCY_M2 = "MobileIdentityConsistencyFRE"; public static final String MOBILE_IDENTITY_CONSISTENCY_PROMOS =
diff --git a/chrome/browser/lifetime/DEPS b/chrome/browser/lifetime/DEPS index 64b44dc..a6241bb 100644 --- a/chrome/browser/lifetime/DEPS +++ b/chrome/browser/lifetime/DEPS
@@ -1,5 +1,9 @@ specific_include_rules = { "application_lifetime_aura\.cc": [ "+ash/shell.h", - ] + ], + "application_lifetime\.cc": [ + "+chromeos/crosapi/mojom/crosapi.mojom.h", + "+chromeos/lacros/lacros_service.h", + ], }
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc index b724126..f7dd53aa 100644 --- a/chrome/browser/lifetime/application_lifetime.cc +++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -57,6 +57,11 @@ #include "ui/aura/env.h" #endif +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chromeos/crosapi/mojom/crosapi.mojom.h" +#include "chromeos/lacros/lacros_service.h" +#endif + #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/ui/profile_picker.h" #endif @@ -167,14 +172,30 @@ // Run exit process in clean stack. content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&ExitIgnoreUnloadHandlers)); -#else +#else // !BUILDFLAG(IS_CHROMEOS_ASH). +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // Request ash-chrome to relaunch Lacros on its process termination. + // Do not set kRestartLastSessionOnShutdown for Lacros, because it tries to + // respawn another Chrome process from the current Chrome process, which + // does not work on Lacros. + auto* lacros_service = chromeos::LacrosService::Get(); + if (lacros_service->IsAvailable<crosapi::mojom::BrowserServiceHost>() && + lacros_service->GetInterfaceVersion( + crosapi::mojom::BrowserServiceHost::Uuid_) >= + static_cast<int>( + crosapi::mojom::BrowserServiceHost::kRequestRelaunchMinVersion)) { + lacros_service->GetRemote<crosapi::mojom::BrowserServiceHost>() + ->RequestRelaunch(); + } +#else // !BUILDFLAG(IS_CHROMEOS_LACROS) // Set the flag to restore state after the restart. pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) if (ignore_unload_handlers) ExitIgnoreUnloadHandlers(); else AttemptExit(); -#endif +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } #endif // !defined(OS_ANDROID)
diff --git a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc index 9f92f387..2e880f5 100644 --- a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc +++ b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc
@@ -161,6 +161,10 @@ const extensions::Extension* extension) { content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(render_frame_host); + + DCHECK_EQ(render_frame_host->GetLifecycleState(), + content::RenderFrameHost::LifecycleState::kActive); + Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); ContentSettingsType content_settings_type =
diff --git a/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc index e3335cff..94b3c7f 100644 --- a/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc
@@ -5,6 +5,7 @@ #include "base/command_line.h" #include "base/json/json_reader.h" #include "base/strings/string_util.h" +#include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" @@ -18,6 +19,8 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/content_settings/core/browser/cookie_settings.h" +#include "components/permissions/permission_request_manager.h" +#include "components/permissions/test/permission_request_observer.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browsing_data_remover.h" #include "content/public/common/content_features.h" @@ -25,6 +28,7 @@ #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/browsing_data_remover_test_util.h" +#include "content/public/test/prerender_test_util.h" #include "media/audio/audio_device_description.h" #include "media/audio/audio_manager.h" #include "media/base/media_switches.h" @@ -333,3 +337,61 @@ EXPECT_EQ(devices.size(), devices2.size()); CheckEnumerationsAreDifferent(devices, devices2); } + +class WebRtcGetMediaDevicesPrerenderingBrowserTest + : public WebRtcGetMediaDevicesBrowserTest { + public: + WebRtcGetMediaDevicesPrerenderingBrowserTest() + : prerender_helper_(base::BindRepeating( + &WebRtcGetMediaDevicesPrerenderingBrowserTest::web_contents, + base::Unretained(this))) {} + ~WebRtcGetMediaDevicesPrerenderingBrowserTest() override = default; + + content::test::PrerenderTestHelper* prerender_helper() { + return &prerender_helper_; + } + + content::WebContents* web_contents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + private: + content::test::PrerenderTestHelper prerender_helper_; +}; + +IN_PROC_BROWSER_TEST_F(WebRtcGetMediaDevicesPrerenderingBrowserTest, + EnumerateDevicesInPrerendering) { + ASSERT_TRUE(embedded_test_server()->Start()); + + // Loads a simple page as a primary page. + GURL url = embedded_test_server()->GetURL("/empty.html"); + ui_test_utils::NavigateToURL(browser(), url); + + // Loads a page in the prerender. + auto prerender_url = embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage); + int host_id = prerender_helper()->AddPrerender(prerender_url); + content::test::PrerenderHostObserver host_observer(*web_contents(), host_id); + content::RenderFrameHost* prerender_rfh = + prerender_helper()->GetPrerenderedMainFrameHost(host_id); + + CookieSettingsFactory::GetForProfile(browser()->profile()) + ->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); + + base::RunLoop run_loop; + permissions::PermissionRequestObserver observer(web_contents()); + prerender_rfh->ExecuteJavaScriptForTests( + u"doGetUserMedia({audio: true, video: true});", base::NullCallback()); + + // The prerendering page should not show a permission request's bubble UI. + EXPECT_FALSE(observer.request_shown()); + + // Activates the page from the prerendering. + prerender_helper()->NavigatePrimaryPage(prerender_url); + observer.Wait(); + + // Makes sure that the page is activated from the prerendering. + EXPECT_TRUE(host_observer.was_activated()); + + // The prerendered page should show the permission request's bubble UI. + EXPECT_TRUE(observer.request_shown()); +}
diff --git a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc index 447acc8..11ba45b 100644 --- a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc +++ b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
@@ -14,7 +14,6 @@ #include "base/location.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/stl_util.h" #include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h"
diff --git a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc index 34bff2e4..20be0f1b 100644 --- a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc +++ b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
@@ -366,8 +366,9 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +// TODO(https://crbug.com/1225946): Test is flaky. IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceNoHistoryTest, - ModelExecutesButDoesntWriteToHistory) { + DISABLED_ModelExecutesButDoesntWriteToHistory) { base::HistogramTester histogram_tester; GURL url(embedded_test_server()->GetURL("a.com", "/hello-no-history.html"));
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html b/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html index facce65d..71db767 100644 --- a/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html +++ b/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html
@@ -1,13 +1,14 @@ +<iframe width="96" height="96" src="iframe_with_image.html"></iframe> <script> const lcpPromise = new Promise(resolve => { window.addEventListener("message", event => { iframeLCP = event.data.startTime; timeOriginDelta = event.data.timeOrigin - performance.timeOrigin; - resolve(iframeLCP + timeOriginDelta); + lcpTime = iframeLCP + timeOriginDelta; + resolve(); }); }); - function waitForLCP() { - return lcpPromise; + async function waitForLCP() { + await lcpPromise; } </script> -<iframe width="96" height="96" src="iframe_with_image.html"></iframe>
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html b/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html index 05f5ff30..fa995b323 100644 --- a/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html +++ b/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html
@@ -6,12 +6,8 @@ <img src="images/blue96x96.png" /> <script> new PerformanceObserver(e => { - // We only care about entry with url, i.e. for images, not any spurrious - // text entry. - const entries = e.getEntries().filter(e => e.url != ''); - if (entries.length === 0) - return; - const entry = entries[0]; + const entries = e.getEntries(); + const entry = entries[entries.length - 1]; window.parent.postMessage({ startTime: entry.startTime, timeOrigin: performance.timeOrigin }, '*');
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc index 834eaab8b..ccb71e345 100644 --- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc +++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -166,11 +166,12 @@ base::test::ScopedFeatureList feature_list_; }; -IN_PROC_BROWSER_TEST_F(PageViewportInLCPTest, FullSizeImageInIframe) { +IN_PROC_BROWSER_TEST_F(PageViewportInLCPTest, DISABLED_FullSizeImageInIframe) { Start(); StartTracing({"loading"}); Load("/full_size_image.html"); - double lcpTime = EvalJs(web_contents(), "waitForLCP()").ExtractDouble(); + content::EvalJsResult result = EvalJs(web_contents(), "waitForLCP()"); + double lcpTime = EvalJs(web_contents(), "lcpTime").ExtractDouble(); // Navigate away to force metrics recording. ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
diff --git a/chrome/browser/plugins/plugin_observer.cc b/chrome/browser/plugins/plugin_observer.cc index de58227..50b3b0d4 100644 --- a/chrome/browser/plugins/plugin_observer.cc +++ b/chrome/browser/plugins/plugin_observer.cc
@@ -46,6 +46,10 @@ #include "services/service_manager/public/cpp/interface_provider.h" #include "ui/base/l10n/l10n_util.h" +#if defined(OS_WIN) +#include "base/win/windows_types.h" +#endif + using content::PluginService; // PluginObserver -------------------------------------------------------------
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc index d4586c69..89c0608 100644 --- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -328,9 +328,9 @@ // This test verifies that when the user signs out then any existing component // policy caches are dropped, and that it's still possible to sign back in and // get policy for components working again. -// crbug.com/1224925 flaky on Win. -#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_WIN) -IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, SignOutAndBackIn) { +// TODO(https://crbug.com/1224925): Test is flaky on all platforms. +#if !BUILDFLAG(IS_CHROMEOS_ASH) +IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, DISABLED_SignOutAndBackIn) { // Read the initial policy. ExtensionTestMessageListener initial_policy_listener(kTestPolicyJSON, true); event_listener_->Reply("get-policy-Name");
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index fe000441..44cee0b4 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -130,10 +130,10 @@ #include "chrome/browser/ash/borealis/borealis_prefs.h" #include "chrome/browser/ash/crostini/crostini_pref_names.h" #include "chrome/browser/ash/plugin_vm/plugin_vm_pref_names.h" +#include "chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h" +#include "chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h" -#include "chrome/browser/chromeos/policy/handlers/lacros_availability_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/chromeos/policy/login/secondary_google_account_signin_policy_handler.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/policy/default_geolocation_policy_handler.h"
diff --git a/chrome/browser/policy/test/arc_policy_browsertest.cc b/chrome/browser/policy/test/arc_policy_browsertest.cc index cc1467fa..763be2d 100644 --- a/chrome/browser/policy/test/arc_policy_browsertest.cc +++ b/chrome/browser/policy/test/arc_policy_browsertest.cc
@@ -4,7 +4,7 @@ #include "base/memory/ptr_util.h" #include "chrome/browser/ash/arc/session/arc_session_manager.h" -#include "chrome/browser/chromeos/policy/handlers/configuration_policy_handler_chromeos.h" +#include "chrome/browser/ash/policy/handlers/configuration_policy_handler_chromeos.h" #include "chrome/browser/policy/policy_test_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/policy/test/system_features_policy_browsertest.cc b/chrome/browser/policy/test/system_features_policy_browsertest.cc index f7345d0..1e9f231f6 100644 --- a/chrome/browser/policy/test/system_features_policy_browsertest.cc +++ b/chrome/browser/policy/test/system_features_policy_browsertest.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/policy/policy_test_utils.h"
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 78ab555..0a92105 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -14,11 +14,11 @@ #include "chrome/browser/accessibility/accessibility_labels_service.h" #include "chrome/browser/accessibility/accessibility_ui.h" #include "chrome/browser/accessibility/invert_bubble_prefs.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/ash/web_applications/help_app/help_app_notification_controller.h" #include "chrome/browser/availability/availability_prober.h" #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/chrome_content_browser_client.h" -#include "chrome/browser/chromeos/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/chromeos/scheduler_configuration_manager.h" #include "chrome/browser/component_updater/component_updater_prefs.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" @@ -182,12 +182,12 @@ #include "chrome/browser/ash/guest_os/guest_os_share_path.h" #include "chrome/browser/ash/kerberos/kerberos_credentials_manager.h" #include "chrome/browser/ash/login/easy_unlock/easy_unlock_service.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/ash/settings/stats_reporting_controller.h" #include "chrome/browser/chromeos/device_name_store.h" #include "chrome/browser/chromeos/extensions/extensions_permissions_tracker.h" #include "chrome/browser/chromeos/net/system_proxy_manager.h" #include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_manager_impl.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/component_updater/metadata_table_chromeos.h" #include "chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) @@ -316,6 +316,8 @@ #include "chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.h" #include "chrome/browser/ash/policy/enrollment/enrollment_requisition_manager.h" #include "chrome/browser/ash/policy/external_data/handlers/device_wallpaper_image_external_data_handler.h" +#include "chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/ash/power/auto_screen_brightness/metrics_reporter.h" #include "chrome/browser/ash/power/power_metrics_reporter.h" #include "chrome/browser/ash/release_notes/release_notes_storage.h" @@ -330,8 +332,6 @@ #include "chrome/browser/chromeos/first_run/first_run.h" #include "chrome/browser/chromeos/full_restore/full_restore_prefs.h" #include "chrome/browser/chromeos/net/network_throttling_observer.h" -#include "chrome/browser/chromeos/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/chromeos/policy/networking/policy_cert_service_factory.h" #include "chrome/browser/chromeos/policy/reporting/app_install_event_log_manager_wrapper.h" #include "chrome/browser/chromeos/policy/reporting/arc_app_install_event_logger.h" @@ -461,6 +461,13 @@ const char kFirstRunTrialGroup[] = "help_app_first_run.trial_group"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) +// Deprecated 11/2020 +const char kLocalDiscoveryEnabled[] = "local_discovery.enabled"; +const char kLocalDiscoveryNotificationsEnabled[] = + "local_discovery.notifications_enabled"; +#endif + // Deprecated 6/2020 const char kStricterMixedContentTreatmentEnabled[] = "security_state.stricter_mixed_content_treatment_enabled"; @@ -680,9 +687,8 @@ #endif #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - registry->RegisterBooleanPref(prefs::kLocalDiscoveryEnabled, true); - registry->RegisterBooleanPref(prefs::kLocalDiscoveryNotificationsEnabled, - false); + registry->RegisterBooleanPref(kLocalDiscoveryEnabled, true); + registry->RegisterBooleanPref(kLocalDiscoveryNotificationsEnabled, false); #endif registry->RegisterIntegerPref(kSettingsLaunchedPasswordChecks, 0); @@ -1416,8 +1422,8 @@ // Added 11/2020. #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - profile_prefs->ClearPref(prefs::kLocalDiscoveryEnabled); - profile_prefs->ClearPref(prefs::kLocalDiscoveryNotificationsEnabled); + profile_prefs->ClearPref(kLocalDiscoveryEnabled); + profile_prefs->ClearPref(kLocalDiscoveryNotificationsEnabled); #endif // Added 11/2020
diff --git a/chrome/browser/printing/print_backend_service_manager.cc b/chrome/browser/printing/print_backend_service_manager.cc index 0b9f4d8a..0263067 100644 --- a/chrome/browser/printing/print_backend_service_manager.cc +++ b/chrome/browser/printing/print_backend_service_manager.cc
@@ -4,13 +4,16 @@ #include "chrome/browser/printing/print_backend_service_manager.h" +#include <memory> #include <string> #include "base/bind.h" #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/logging.h" +#include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_functions.h" +#include "base/threading/scoped_blocking_call.h" #include "base/time/time.h" #include "base/unguessable_token.h" #include "build/build_config.h" @@ -18,9 +21,11 @@ #include "chrome/browser/service_sandbox_type.h" #include "chrome/grit/generated_resources.h" #include "chrome/services/printing/public/mojom/print_backend_service.mojom.h" +#include "components/crash/core/common/crash_keys.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/service_process_host.h" #include "mojo/public/cpp/bindings/remote.h" +#include "printing/backend/print_backend.h" namespace printing { @@ -34,8 +39,10 @@ "Printing.PrintBackend.DriversRequiringElevatedPrivilegeEncountered"; // Amount of idle time to wait before resetting the connection to the service. -constexpr base::TimeDelta kResetOnIdleTimeout = - base::TimeDelta::FromSeconds(20); +constexpr base::TimeDelta kNoClientsRegisteredResetOnIdleTimeout = + base::TimeDelta::FromSeconds(10); +constexpr base::TimeDelta kClientsRegisteredResetOnIdleTimeout = + base::TimeDelta::FromSeconds(120); PrintBackendServiceManager* g_print_backend_service_manager_singleton = nullptr; @@ -49,6 +56,84 @@ return is_sandboxed_service_; } +uint32_t PrintBackendServiceManager::RegisterClient() { + uint32_t client_id = ++last_client_id_; + + VLOG(1) << "Registering a client with ID " << client_id + << " for print backend service."; + clients_.emplace(client_id); + + // A new client registration is a signal of impending activity to a print + // backend service. Performance can be improved if we ensure that an initial + // service is ready for when the first Mojo call should happen shortly after + // this registration. + // It is possible that there might have been prior clients registered that + // persisted for a long time (e.g., a tab with a Print Preview left open + // indefinitely). We use a long timeout against idleness for that scenario, + // so we want to perform this optimization check every time regardless of + // number of clients registered. + // We don't know if a particular printer might be needed, so for now just + // start for the blank `printer_name` which would cover queries like getting + // the default printer and enumerating the list of printers. + constexpr char kEmptyPrinterName[] = ""; + std::string remote_id = GetRemoteIdForPrinterName(kEmptyPrinterName); + auto iter = sandboxed_remotes_.find(remote_id); + if (iter == sandboxed_remotes_.end()) { + // Service not already available, so launch it now so that it will be + // ready by the time the client gets to point of invoking a Mojo call. + GetService(kEmptyPrinterName); + } else { + // Service already existed, possibly was recently marked for being reset + // with a short timeout. Ensure it has the long timeout to be available + // across user interactions but to also get reclaimed should the user leave + // it unused indefinitely. + // Safe to use base::Unretained(this) since `this` is a global singleton + // which never goes away. + DVLOG(1) << "Updating to long idle timeout for print backend service id `" + << remote_id << "`"; + mojo::Remote<printing::mojom::PrintBackendService>& service = iter->second; + service.set_idle_handler( + kClientsRegisteredResetOnIdleTimeout, + base::BindRepeating(&PrintBackendServiceManager::OnIdleTimeout, + base::Unretained(this), /*sandboxed=*/true, + remote_id)); + + // TODO(crbug.com/1225111) Maybe need to issue a quick call here to get + // adjusted timeout to take effect? Ideally not, since there is supposed + // to be an expected call "soon" after having registered. + } + + return client_id; +} + +void PrintBackendServiceManager::UnregisterClient(uint32_t id) { + if (!clients_.erase(id)) { + DVLOG(1) << "Unknown client ID " << id + << ", is client being unregistered multiple times?"; + return; + } + VLOG(1) << "Unregistering client with ID " << id + << " from print backend service."; + + if (!clients_.empty()) + return; + + // No more clients means that there is an opportunity to more aggressively + // reclaim resources by letting service processes terminate. Register a + // short idle timeout with services. This is preferred to just resetting + // them immediately here, in case a user immediately reopens a Print Preview. + for (auto& iter : sandboxed_remotes_) { + const std::string& remote_id = iter.first; + mojo::Remote<printing::mojom::PrintBackendService>& service = iter.second; + UpdateServiceToShortIdleTimeout(service, /*sandboxed=*/true, remote_id); + } + for (auto& iter : unsandboxed_remotes_) { + const std::string& remote_id = iter.first; + mojo::Remote<printing::mojom::PrintBackendService>& service = iter.second; + UpdateServiceToShortIdleTimeout(service, /*sandboxed=*/false, remote_id); + } +} + const mojo::Remote<printing::mojom::PrintBackendService>& PrintBackendServiceManager::GetService(const std::string& printer_name) { // Value of `is_sandboxed_service_` will be referenced during the service @@ -66,6 +151,10 @@ return *sandboxed_service_remote_for_test_; } + // Performance is improved if a service is launched ahead of the time it will + // be needed by client callers. + DCHECK(!clients_.empty()); + RemotesMap& remote = is_sandboxed_service_ ? sandboxed_remotes_ : unsandboxed_remotes_; @@ -106,18 +195,15 @@ &PrintBackendServiceManager::OnRemoteDisconnected, base::Unretained(this), is_sandboxed_service_, remote_id)); - // TODO(crbug.com/809738) Interactions with the service should be expected - // as long as any Print Preview dialogs are open (and there could be more - // than one preview open at a time). Keeping the service present as long - // as those are open would help provide a more responsive experience for - // the user. For now, to ensure that this process doesn't stick around - // forever we make it go away after a short delay of idleness, but that - // should be adjusted to happen only after all UI references have been - // removed. + // Beware of case where a user leaves a tab with a Print Preview open + // indefinitely. Use a long timeout against idleness to reclaim the unused + // resources of an idle print backend service for this case. // Safe to use base::Unretained(this) since `this` is a global singleton // which never goes away. + DVLOG(1) << "Updating to long idle timeout for print backend service id `" + << remote_id << "`"; service.set_idle_handler( - kResetOnIdleTimeout, + kClientsRegisteredResetOnIdleTimeout, base::BindRepeating(&PrintBackendServiceManager::OnIdleTimeout, base::Unretained(this), is_sandboxed_service_, remote_id)); @@ -169,6 +255,18 @@ SaveCallback(GetRemoteSavedFetchCapabilitiesCallbacks(is_sandboxed_service_), remote_id, saved_callback_id, std::move(callback)); + if (!sandboxed_service_remote_for_test_) { + // TODO(1227561) Remove local call for driver info, don't want any + // residual accesses left into the printer drivers from the browser + // process. + base::ScopedBlockingCall scoped_blocking_call( + FROM_HERE, base::BlockingType::MAY_BLOCK); + scoped_refptr<PrintBackend> print_backend = + PrintBackend::CreateInstance(g_browser_process->GetApplicationLocale()); + crash_keys_ = std::make_unique<crash_keys::ScopedPrinterInfo>( + print_backend->GetPrinterDriverInfo(printer_name)); + } + DVLOG(1) << "Sending FetchCapabilities on remote `" << remote_id << "`, saved callback ID of " << saved_callback_id; service->FetchCapabilities( @@ -272,6 +370,24 @@ #endif } +void PrintBackendServiceManager::UpdateServiceToShortIdleTimeout( + mojo::Remote<printing::mojom::PrintBackendService>& service, + bool sandboxed, + const std::string& remote_id) { + DVLOG(1) << "Updating to short idle timeout for " + << (sandboxed ? "sandboxed" : "unsandboxed") + << " print backend service id `" << remote_id << "`"; + service.set_idle_handler( + kNoClientsRegisteredResetOnIdleTimeout, + base::BindRepeating(&PrintBackendServiceManager::OnIdleTimeout, + base::Unretained(this), sandboxed, remote_id)); + + // TODO(crbug.com/1225111) Make a superfluous call to the service, just to + // cause an IPC that will in turn make the adjusted timeout value actually + // take effect. + service->Poke(); +} + void PrintBackendServiceManager::OnIdleTimeout(bool sandboxed, const std::string& remote_id) { DVLOG(1) << "Print Backend service idle timeout for "
diff --git a/chrome/browser/printing/print_backend_service_manager.h b/chrome/browser/printing/print_backend_service_manager.h index 97b8f39..0858d70 100644 --- a/chrome/browser/printing/print_backend_service_manager.h +++ b/chrome/browser/printing/print_backend_service_manager.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_PRINTING_PRINT_BACKEND_SERVICE_MANAGER_H_ #define CHROME_BROWSER_PRINTING_PRINT_BACKEND_SERVICE_MANAGER_H_ +#include <memory> #include <string> #include "base/containers/flat_map.h" @@ -14,6 +15,10 @@ #include "chrome/services/printing/public/mojom/print_backend_service.mojom.h" #include "mojo/public/cpp/bindings/remote.h" +namespace crash_keys { +class ScopedPrinterInfo; +} + namespace printing { class PrintBackendServiceManager { @@ -26,6 +31,14 @@ // otherwise. bool ShouldSandboxPrintBackendService() const; + // Register as a client of PrintBackendServiceManager. This acts as a signal + // of impending activity enabling possible optimizations within the manager. + uint32_t RegisterClient(); + + // Notify the manager that this client is no longer needing print backend + // services. This signal might alter the manager's internal optimizations. + void UnregisterClient(uint32_t id); + // Acquires a remote handle to the Print Backend Service instance, launching a // process to host the service if necessary. const mojo::Remote<printing::mojom::PrintBackendService>& GetService( @@ -103,6 +116,12 @@ // Determine the remote ID that is used for the specified `printer_name`. std::string GetRemoteIdForPrinterName(const std::string& printer_name) const; + // Help function to reset idle timeout duration to a short value. + void UpdateServiceToShortIdleTimeout( + mojo::Remote<printing::mojom::PrintBackendService>& service, + bool sandboxed, + const std::string& remote_id); + // Callback when predetermined idle timeout occurs indicating no in-flight // messages for a short period of time. `sandboxed` is used to distinguish // which mapping of remotes the timeout applies to. @@ -166,6 +185,12 @@ RemotesMap sandboxed_remotes_; RemotesMap unsandboxed_remotes_; + // Set of IDs for clients actively engaged in printing. This could include + // tabs in print preview as well as an active system print. Retention of a + // service process can have benefit so long as there are active clients. + base::flat_set<uint32_t> clients_; + uint32_t last_client_id_ = 0; + // Track the saved callbacks for each remote. RemoteSavedEnumeratePrintersCallbacks sandboxed_saved_enumerate_printers_callbacks_; @@ -190,6 +215,11 @@ // performing the operation with modified restrictions. base::flat_set<std::string> drivers_requiring_elevated_privilege_; + // Crash key is kept at class level so that we can obtain printer driver + // information for a prior call should the process be terminated due to Mojo + // message response validation. + std::unique_ptr<crash_keys::ScopedPrinterInfo> crash_keys_; + // Override of service to use for testing. mojo::Remote<printing::mojom::PrintBackendService>* sandboxed_service_remote_for_test_ = nullptr;
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 75e7f6f..f5b34ce 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc
@@ -96,6 +96,9 @@ if (IsCrashed()) return false; + // TODO(crbug.com/809738) Register with `PrintBackendServiceManager` when + // system print is enabled out-of-process. + SetPrintingRFH(print_preview_rfh_); GetPrintRenderFrame(print_preview_rfh_)->PrintForSystemDialog(); return true;
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index e0880a4..e18abf27 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -359,6 +359,10 @@ if (IsCrashed()) return false; + // TODO(crbug.com/809738) Register with `PrintBackendServiceManager` when + // system print is enabled out-of-process. A corresponding unregister should + // go in `ReleasePrintJob()`. + SetPrintingRFH(rfh); GetPrintRenderFrame(rfh)->PrintRequestedPages(); return true;
diff --git a/chrome/browser/privacy_budget/BUILD.gn b/chrome/browser/privacy_budget/BUILD.gn index 333eb41..31c612a7 100644 --- a/chrome/browser/privacy_budget/BUILD.gn +++ b/chrome/browser/privacy_budget/BUILD.gn
@@ -12,6 +12,8 @@ "privacy_budget_ukm_entry_filter.h", "representative_surface_set.h", "surface_set_equivalence.h", + "surface_set_valuation.h", + "surface_set_with_valuation.h", ] deps = [ @@ -33,6 +35,8 @@ "privacy_budget_ukm_entry_filter.cc", "representative_surface_set.cc", "surface_set_equivalence.cc", + "surface_set_valuation.cc", + "surface_set_with_valuation.cc", ] public_deps = [ ":headers" ] @@ -61,6 +65,8 @@ "privacy_budget_ukm_entry_filter_unittest.cc", "representative_surface_set_unittest.cc", "surface_set_equivalence_unittest.cc", + "surface_set_valuation_unittest.cc", + "surface_set_with_valuation_unittest.cc", ] deps = [
diff --git a/chrome/browser/privacy_budget/surface_set_valuation.cc b/chrome/browser/privacy_budget/surface_set_valuation.cc new file mode 100644 index 0000000..fb7c094e --- /dev/null +++ b/chrome/browser/privacy_budget/surface_set_valuation.cc
@@ -0,0 +1,80 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/privacy_budget/surface_set_valuation.h" + +#include <algorithm> +#include <functional> +#include <limits> +#include <tuple> +#include <type_traits> + +#include "base/check_op.h" +#include "base/containers/contains.h" +#include "base/numerics/ranges.h" +#include "base/rand_util.h" +#include "base/ranges/algorithm.h" +#include "base/stl_util.h" +#include "base/strings/string_piece_forward.h" +#include "chrome/browser/privacy_budget/representative_surface_set.h" +#include "chrome/browser/privacy_budget/surface_set_equivalence.h" +#include "chrome/common/privacy_budget/field_trial_param_conversions.h" +#include "chrome/common/privacy_budget/privacy_budget_features.h" +#include "chrome/common/privacy_budget/types.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +SurfaceSetValuation::SurfaceSetValuation( + const SurfaceSetEquivalence& surface_set_equivalence) + : equivalence_sets_(surface_set_equivalence), + per_surface_costs_( + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceCostMap>( + features::kIdentifiabilityStudyPerHashCost.Get())), + per_type_costs_( + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeCostMap>( + features::kIdentifiabilityStudyPerTypeCost.Get())) {} + +SurfaceSetValuation::~SurfaceSetValuation() = default; + +// static +const double SurfaceSetValuation::kDefaultCost; + +double SurfaceSetValuation::Cost(const IdentifiableSurfaceSet& set) const { + return Cost(equivalence_sets_.GetRepresentatives(set)); +} + +double SurfaceSetValuation::Cost(const RepresentativeSurfaceSet& set) const { + double cost = 0.0; + // This is a naive calculation that assumes that surfaces within an + // equivalence class is perfectly correlated with each other while surfaces + // that are not in the same class are perfectly independent. In reality + // nothing is quite cut and dry. Until we have a better model we are going to + // use this one. + for (auto surface : set) + cost += Cost(surface); + return cost; +} + +double SurfaceSetValuation::Cost(blink::IdentifiableSurface surface) const { + return Cost(equivalence_sets_.GetRepresentative(surface)); +} + +double SurfaceSetValuation::Cost(RepresentativeSurface surface) const { + auto surface_cost_iter = per_surface_costs_.find(surface.value()); + if (surface_cost_iter != per_surface_costs_.end()) + return surface_cost_iter->second; + + auto type_cost_iter = per_type_costs_.find(surface->GetType()); + if (type_cost_iter != per_type_costs_.end()) + return type_cost_iter->second; + + return kDefaultCost; +} + +double SurfaceSetValuation::IncrementalCost( + const RepresentativeSurfaceSet& prior, + RepresentativeSurface new_addition) const { + if (base::Contains(prior, new_addition)) + return 0.0; + return Cost(new_addition); +}
diff --git a/chrome/browser/privacy_budget/surface_set_valuation.h b/chrome/browser/privacy_budget/surface_set_valuation.h new file mode 100644 index 0000000..674e9a3 --- /dev/null +++ b/chrome/browser/privacy_budget/surface_set_valuation.h
@@ -0,0 +1,70 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_VALUATION_H_ +#define CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_VALUATION_H_ + +#include "base/containers/flat_map.h" +#include "chrome/browser/privacy_budget/representative_surface_set.h" +#include "chrome/browser/privacy_budget/surface_set_equivalence.h" +#include "chrome/common/privacy_budget/privacy_budget_settings_provider.h" +#include "chrome/common/privacy_budget/types.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +// Estimates the privacy budget cost for a set of identifiable surfaces. +// +// The costing model is currently naive. The cost is reported based on an +// arbitrary unit whose value is 1.0 for a "median" identifiable surface. Costs +// for other surfaces are measured relative to the median surface. Scale should +// be assumed to be roughly logarithmic. See documentation for +// `PrivacyBudgetCost` for more details. +// +// All costs returned by the costing functions should be considered to be +// _upper bounds_ on the actual cost. I.e. these functions will always +// over-estimate. +class SurfaceSetValuation { + public: + // The default cost is always one median identifiable surface. + static constexpr double kDefaultCost = 1.0; + + // Constructs a valuation object. The SurfaceSetEquivalence object passed in + // by reference as `equivalence` MUST outlive this object. + explicit SurfaceSetValuation(const SurfaceSetEquivalence& equivalence); + ~SurfaceSetValuation(); + + // Returns an upper-bound for the cost of the surfaces in `set`. + PrivacyBudgetCost Cost(const IdentifiableSurfaceSet& set) const; + + // Returns an upper-bound for the cost of `surface`. + PrivacyBudgetCost Cost(blink::IdentifiableSurface surface) const; + + // Returns an upper-bound for the cost of `surface`. + PrivacyBudgetCost Cost(RepresentativeSurface surface) const; + + // Returns an upper-bound for the cost of the surfaces in `set`. + PrivacyBudgetCost Cost(const RepresentativeSurfaceSet& set) const; + + // Returns the _incremental_ change in cost that would result from adding + // `new_addition` to the set of surfaces represented by `prior`. + // + // Costs are always zero or positive, so the returned value will never be + // negative. + PrivacyBudgetCost IncrementalCost(const RepresentativeSurfaceSet& prior, + RepresentativeSurface new_addition) const; + + // Returns a reference to the underlying identifiable surface equivalence + // model. + const SurfaceSetEquivalence& equivalence() const { return equivalence_sets_; } + + private: + const SurfaceSetEquivalence& equivalence_sets_; + + // Per surface relative cost. + const IdentifiableSurfaceCostMap per_surface_costs_; + + // Per surface type relative cost. + const IdentifiableSurfaceTypeCostMap per_type_costs_; +}; + +#endif // CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_VALUATION_H_
diff --git a/chrome/browser/privacy_budget/surface_set_valuation_unittest.cc b/chrome/browser/privacy_budget/surface_set_valuation_unittest.cc new file mode 100644 index 0000000..9ad5afd --- /dev/null +++ b/chrome/browser/privacy_budget/surface_set_valuation_unittest.cc
@@ -0,0 +1,80 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/privacy_budget/surface_set_valuation.h" + +#include "chrome/browser/privacy_budget/surface_set_equivalence.h" +#include "chrome/common/privacy_budget/scoped_privacy_budget_config.h" +#include "chrome/common/privacy_budget/types.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +namespace { + +constexpr auto kSurface1 = blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kCanvasRenderingContext, + 3); +constexpr auto kSurface2 = blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kHTMLMediaElement_CanPlayType, + 5); +constexpr auto kSurface3 = blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kWebFeature, + 3); +constexpr auto kSurface4 = blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kWebFeature, + 4); + +} // namespace + +TEST(SurfaceSetValuationTest, NoConfig) { + // Verify behavior when there's no server config that defines costing + // parameters. All surfaces should be valued at 1.0. + + test::ScopedPrivacyBudgetConfig::Parameters config_params; + config_params.enabled = true; + ASSERT_TRUE(config_params.per_surface_cost.empty()); + ASSERT_TRUE(config_params.per_type_cost.empty()); + test::ScopedPrivacyBudgetConfig study_configuration(config_params); + + SurfaceSetEquivalence equivalence; + SurfaceSetValuation valuation(equivalence); + + IdentifiableSurfaceSet surfaces = {kSurface1, kSurface2, kSurface3, + kSurface4}; + + EXPECT_FLOAT_EQ(1.0, valuation.Cost(kSurface1)); + EXPECT_FLOAT_EQ(4.0, valuation.Cost(surfaces)); +} + +TEST(SurfaceSetValuationTest, PerSurface) { + test::ScopedPrivacyBudgetConfig::Parameters config_params; + config_params.enabled = true; + config_params.per_surface_cost = + IdentifiableSurfaceCostMap{{kSurface1, 0.5}, {kSurface2, 0.25}}; + test::ScopedPrivacyBudgetConfig study_configuration(config_params); + + SurfaceSetEquivalence equivalence; + SurfaceSetValuation valuation(equivalence); + + EXPECT_FLOAT_EQ(0.5, valuation.Cost(kSurface1)); + EXPECT_FLOAT_EQ(1.0, valuation.Cost(kSurface4)); + EXPECT_FLOAT_EQ(1.75, valuation.Cost(IdentifiableSurfaceSet{ + kSurface1, kSurface2, kSurface3})); +} + +TEST(SurfaceSetValuationTest, PerType) { + test::ScopedPrivacyBudgetConfig::Parameters config_params; + config_params.enabled = true; + config_params.per_type_cost[blink::IdentifiableSurface::Type::kWebFeature] = + 0.25; + test::ScopedPrivacyBudgetConfig study_configuration(config_params); + + SurfaceSetEquivalence equivalence; + SurfaceSetValuation valuation(equivalence); + + EXPECT_FLOAT_EQ(1.0, valuation.Cost(kSurface1)); + EXPECT_FLOAT_EQ(0.25, valuation.Cost(kSurface4)); + EXPECT_FLOAT_EQ(2.25, valuation.Cost(IdentifiableSurfaceSet{ + kSurface1, kSurface2, kSurface3})); +}
diff --git a/chrome/browser/privacy_budget/surface_set_with_valuation.cc b/chrome/browser/privacy_budget/surface_set_with_valuation.cc new file mode 100644 index 0000000..81f625b --- /dev/null +++ b/chrome/browser/privacy_budget/surface_set_with_valuation.cc
@@ -0,0 +1,81 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/privacy_budget/surface_set_with_valuation.h" + +#include <type_traits> +#include <utility> +#include <vector> + +#include "base/check.h" +#include "base/rand_util.h" +#include "base/ranges/algorithm.h" +#include "base/stl_util.h" + +static_assert(std::is_same<RepresentativeSurface, + SurfaceSetWithValuation::key_type>::value, + ""); + +SurfaceSetWithValuation::SurfaceSetWithValuation( + const SurfaceSetValuation& valuation) + : valuation_(valuation) {} + +SurfaceSetWithValuation::~SurfaceSetWithValuation() = default; + +bool SurfaceSetWithValuation::TryAdd(RepresentativeSurface surface, + PrivacyBudgetCost budget) { + if (cost_ > budget) + return false; + + auto it = surfaces_.find(surface); + if (it != surfaces_.end()) + return true; + + double new_cost = cost_ + valuation_.IncrementalCost(surfaces_, surface); + if (new_cost > budget) + return false; + + cost_ = new_cost; + auto insertion_result = surfaces_.insert(surface); + DCHECK(insertion_result.second); + return true; +} + +bool SurfaceSetWithValuation::TryAdd(blink::IdentifiableSurface surface, + PrivacyBudgetCost budget) { + return TryAdd(valuation_.equivalence().GetRepresentative(surface), budget); +} + +void SurfaceSetWithValuation::AssignWithBudget( + RepresentativeSurfaceSet&& incoming_container, + double budget) { + surfaces_ = std::move(incoming_container); + cost_ = valuation_.Cost(surfaces_); + + if (cost_ <= budget) + return; + + // In case the budget doesn't accommodate all of `surfaces_`, we'll randomly + // drop elements until we meet the budget's restrictions. + auto container = std::move(surfaces_).extract(); + base::RandomBitGenerator g; + base::ranges::shuffle(container, g); + + auto new_beginning = container.begin(); + for (; new_beginning != container.end() && cost_ > budget; + cost_ -= valuation_.Cost(*new_beginning), ++new_beginning) { + } + + surfaces_ = container_type(new_beginning, container.end()); +} + +void SurfaceSetWithValuation::Clear() { + cost_ = 0; + base::STLClearObject(&surfaces_); +} + +RepresentativeSurfaceSet SurfaceSetWithValuation::Take() && { + cost_ = 0; + return std::move(surfaces_); +}
diff --git a/chrome/browser/privacy_budget/surface_set_with_valuation.h b/chrome/browser/privacy_budget/surface_set_with_valuation.h new file mode 100644 index 0000000..82d678e --- /dev/null +++ b/chrome/browser/privacy_budget/surface_set_with_valuation.h
@@ -0,0 +1,114 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_WITH_VALUATION_H_ +#define CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_WITH_VALUATION_H_ + +#include "base/containers/flat_tree.h" +#include "chrome/browser/privacy_budget/representative_surface_set.h" +#include "chrome/browser/privacy_budget/surface_set_equivalence.h" +#include "chrome/browser/privacy_budget/surface_set_valuation.h" +#include "chrome/common/privacy_budget/types.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +// A set-like container for blink::IdentifiableSurface and RepresentativeSurface +// that maintains an aggregate surface cost (via SurfaceSetValuation). +// +// * The container only consumes representative surfaces (see +// RepresentativeSurface). +// +// * Adding a RepresentativeSurface is the equivalent of adding all the +// surfaces that are in the same equivalence class. I.e. contains(s) will +// return true for all `s` that are in the same equivalence class as the +// representative that was added. +// +// * Adding a IdentifiableSurface is the equivalent of adding its corresponding +// RepresentativeSurface, and thus the equivalent of adding all the surfaces +// in its equivalence class. +class SurfaceSetWithValuation { + public: + explicit SurfaceSetWithValuation(const SurfaceSetValuation& valuation); + ~SurfaceSetWithValuation(); + + using container_type = RepresentativeSurfaceSet; + using key_type = container_type::key_type; + using value_type = container_type::value_type; + using key_compare = container_type::key_compare; + using value_compare = container_type::value_compare; + using reference = container_type::reference; + using const_reference = container_type::const_reference; + using iterator = container_type::iterator; + using const_iterator = container_type::const_iterator; + using size_type = container_type::size_type; + + const_iterator begin() const noexcept { return surfaces_.begin(); } + const_iterator end() const noexcept { return surfaces_.end(); } + + bool Empty() const { return surfaces_.empty(); } + size_type Size() const { return surfaces_.size(); } + + // Returns the current cost of the surfaces included in the container. This + // function is very cheap to use. + PrivacyBudgetCost Cost() const { return cost_; } + + // All mutations to the underlying data must be done through one of these + // functions. All others are intentionally written to not return a non-const + // reference nor cause mutations of the underlying container. + + // Try to add surface `surface` while keeping the cost under `budget`. + // Returns true if successful. No changes are made if the surface cannot be + // added without exceeding the budget. + // + // Adding a surface that's already in the container -- either explicitly or + // due to its equivalence class being a member of the container -- results in + // a return value of `true`. + bool TryAdd(RepresentativeSurface surface, PrivacyBudgetCost budget); + + // Try to add surface `surface` while keeping the cost under `budget`. + // Returns true if successful. No changes are made if the surface cannot be + // added without exceeding the budget. + // + // Adding a surface that's already in the container -- either explicitly or + // due to its equivalence class being a member of the container -- results in + // a return value of `true`. + bool TryAdd(blink::IdentifiableSurface surface, PrivacyBudgetCost budget); + + // Assign a set of surfaces. Any existing surfaces in this container will be + // removed. + // + // If the surfaces in `container` exceed the cost set out in `budget`, then + // this function removes random elements in `container` until the cost falls + // below or meets `budget`. The order in which elements are removed is + // random. + void AssignWithBudget(RepresentativeSurfaceSet&& container, + PrivacyBudgetCost budget); + + // Removes all surfaces from this container. + void Clear(); + + // Returns a reference to the underlying container. + const RepresentativeSurfaceSet& Container() const { return surfaces_; } + + // Acquire the underlying container. + RepresentativeSurfaceSet Take() &&; + + key_compare key_comp() const { return surfaces_.key_comp(); } + value_compare value_comp() const { return surfaces_.value_comp(); } + + const_iterator find(const key_type& k) const { return surfaces_.find(k); } + size_type count(const key_type& k) const { return surfaces_.count(k); } + bool contains(RepresentativeSurface k) const { + return surfaces_.find(k) != surfaces_.end(); + } + bool contains(const blink::IdentifiableSurface surface) const { + return contains(valuation_.equivalence().GetRepresentative(surface)); + } + + private: + const SurfaceSetValuation& valuation_; + RepresentativeSurfaceSet surfaces_; + PrivacyBudgetCost cost_ = 0.0; +}; + +#endif // CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_WITH_VALUATION_H_
diff --git a/chrome/browser/privacy_budget/surface_set_with_valuation_unittest.cc b/chrome/browser/privacy_budget/surface_set_with_valuation_unittest.cc new file mode 100644 index 0000000..a15d3aa --- /dev/null +++ b/chrome/browser/privacy_budget/surface_set_with_valuation_unittest.cc
@@ -0,0 +1,189 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/privacy_budget/surface_set_with_valuation.h" + +#include <cstddef> + +#include "base/containers/contains.h" +#include "chrome/browser/privacy_budget/surface_set_equivalence.h" +#include "chrome/browser/privacy_budget/surface_set_valuation.h" +#include "chrome/common/privacy_budget/scoped_privacy_budget_config.h" +#include "chrome/common/privacy_budget/types.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +namespace { + +constexpr auto kSurface1 = blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kCanvasRenderingContext, + 3); +constexpr auto kSurface2 = blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kHTMLMediaElement_CanPlayType, + 5); + +// Usual budgets range from 20..40. +constexpr PrivacyBudgetCost kDefaultMediumBudget = 30.0; + +struct ScopedValuation { + ScopedValuation() + : study_configuration(test::ScopedPrivacyBudgetConfig::kEnable), + valuation(equivalence) {} + + explicit ScopedValuation( + test::ScopedPrivacyBudgetConfig::Parameters parameters) + : study_configuration(parameters), valuation(equivalence) {} + + test::ScopedPrivacyBudgetConfig study_configuration; + SurfaceSetEquivalence equivalence; + SurfaceSetValuation valuation; +}; + +IdentifiableSurfaceSet CreateSurfaceSetWithSize(size_t count) { + IdentifiableSurfaceSet set; + set.reserve(count); + for (auto token = 0u; token < count; ++token) { + set.insert(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kWebFeature, token)); + } + return set; +} + +} // namespace + +TEST(SurfaceSetWithValuation, BasicGetters) { + ScopedValuation fixture; + SurfaceSetWithValuation set(fixture.valuation); + + EXPECT_TRUE(set.Empty()); + EXPECT_TRUE(set.TryAdd(kSurface1, kDefaultMediumBudget)); + EXPECT_FALSE(set.Empty()); + EXPECT_EQ(1u, set.Size()); + EXPECT_TRUE(set.contains(kSurface1)); + EXPECT_FALSE(set.contains(kSurface2)); + + set.Clear(); + EXPECT_TRUE(set.Empty()); +} + +TEST(SurfaceSetWithValuation, Idempotence) { + ScopedValuation fixture; + SurfaceSetWithValuation set(fixture.valuation); + + ASSERT_TRUE(set.TryAdd(kSurface1, kDefaultMediumBudget)); + ASSERT_EQ(SurfaceSetValuation::kDefaultCost, set.Cost()); + ASSERT_EQ(1u, set.Size()); + + // Nothing should change. + ASSERT_TRUE(set.TryAdd(kSurface1, kDefaultMediumBudget)); + ASSERT_EQ(SurfaceSetValuation::kDefaultCost, set.Cost()); +} + +TEST(SurfaceSetWithValuation, Overflow) { + ScopedValuation fixture; + SurfaceSetWithValuation set(fixture.valuation); + + int token = 10; // Different surfaces just need to have different token + // values. The values themselves don't matter. + + // Adds surfaces until we hit the budget ceiling. The only expected outcome of + // this exercise is that when the loop is done `set` can't accept any more + // surfaces. + // + // By default, ScopedValuation sets things up so that each surface + // independently costs kDefaultCost. + for (PrivacyBudgetCost cost = 0.0; cost < kDefaultMediumBudget; + cost += SurfaceSetValuation::kDefaultCost) { + ASSERT_TRUE( + set.TryAdd(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kWebFeature, token), + kDefaultMediumBudget)); + ++token; + } + + // Overflows + EXPECT_FALSE( + set.TryAdd(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kWebFeature, token), + kDefaultMediumBudget)); +} + +TEST(SurfaceSetWithValuation, Fill) { + ScopedValuation fixture; + SurfaceSetWithValuation set(fixture.valuation); + + int token = 10; // As before, this value doesn't matter. All we care about is + // that each surface is different. + while (set.TryAdd(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kWebFeature, ++token), + kDefaultMediumBudget)) { + } + EXPECT_LE(kDefaultMediumBudget, set.Cost()); +} + +TEST(SurfaceSetWithValuation, AssignWithBudget_Fits) { + ScopedValuation fixture; + SurfaceSetWithValuation set(fixture.valuation); + + const auto kRawSurfaceSet = CreateSurfaceSetWithSize( + kDefaultMediumBudget / SurfaceSetValuation::kDefaultCost); + auto representative_surface_set = + fixture.equivalence.GetRepresentatives(kRawSurfaceSet); + + ASSERT_EQ(kRawSurfaceSet.size(), representative_surface_set.size()); + + // All the surfaces in representative_surface_set should exist as-is in `set`. + set.AssignWithBudget(std::move(representative_surface_set), + kDefaultMediumBudget); + ASSERT_EQ(kRawSurfaceSet.size(), set.Size()); +} + +TEST(SurfaceSetWithValuation, AssignWithBudget_Overflows) { + ScopedValuation fixture; + SurfaceSetWithValuation set(fixture.valuation); + + // Contains twice as many surfaces as is expected to fit. + const auto kRawSurfaceSet = CreateSurfaceSetWithSize( + 2 * kDefaultMediumBudget / SurfaceSetValuation::kDefaultCost); + + auto representative_surface_set = + fixture.equivalence.GetRepresentatives(kRawSurfaceSet); + + ASSERT_EQ(kRawSurfaceSet.size(), representative_surface_set.size()); + + set.AssignWithBudget(std::move(representative_surface_set), + kDefaultMediumBudget); + EXPECT_GT(kRawSurfaceSet.size(), set.Size()); + EXPECT_GE(kDefaultMediumBudget, set.Cost()); + + for (const auto& s : set) + EXPECT_TRUE(base::Contains(kRawSurfaceSet, s.value())); +} + +TEST(SurfaceSetWithValuation, RepresentativeSurface) { + const auto kEquivalenceSet = CreateSurfaceSetWithSize(10); + const auto kEquivalenceList = + IdentifiableSurfaceList(kEquivalenceSet.begin(), kEquivalenceSet.end()); + + test::ScopedPrivacyBudgetConfig::Parameters pb_parameters; + pb_parameters.enabled = true; + pb_parameters.equivalence_classes.emplace_back(kEquivalenceList); + + ScopedValuation fixture(pb_parameters); + SurfaceSetWithValuation set(fixture.valuation); + + for (const auto& s : kEquivalenceSet) { + ASSERT_TRUE(set.TryAdd(s, kDefaultMediumBudget)); + } + + // Since all the surfaces are in the same equivalence class, `set` only + // retains a single representative surface. + EXPECT_EQ(1u, set.Size()); + for (const auto& s : kEquivalenceSet) { + EXPECT_TRUE(set.contains(s)); + } + const auto representative_surface = + fixture.equivalence.GetRepresentative(*kEquivalenceSet.begin()); + EXPECT_TRUE(set.contains(representative_surface)); +}
diff --git a/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc b/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc index d10f864..bacbd48 100644 --- a/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc +++ b/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc
@@ -21,6 +21,8 @@ #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +#include <windows.h> + using base::win::RegKey; class TriggeredProfileResetterTest : public testing::Test {
diff --git a/chrome/browser/profiling_host/memlog_browsertest.cc b/chrome/browser/profiling_host/memlog_browsertest.cc index 68d1b6795..00ff0c0 100644 --- a/chrome/browser/profiling_host/memlog_browsertest.cc +++ b/chrome/browser/profiling_host/memlog_browsertest.cc
@@ -56,8 +56,8 @@ } }; -// Flaky on Android: crbug.com/1223739. -#if defined(OS_ANDROID) +// Flaky on Android and Mac: crbug.com/1223739. +#if defined(OS_ANDROID) || defined(OS_MAC) #define MAYBE_EndToEnd DISABLED_EndToEnd #else #define MAYBE_EndToEnd EndToEnd
diff --git a/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc b/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc index 179993e..44666eb 100644 --- a/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc +++ b/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc
@@ -8,6 +8,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" +#include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h" @@ -187,7 +188,14 @@ } // crbug.com/1139864 -IN_PROC_BROWSER_TEST_P(LinkToTextMenuObserverTest, InvalidSelectorForIframe) { +// TODO(crbug.com/1227242): Test is flaky on Mac and Windows. +#if defined(OS_MAC) || defined(OS_WIN) +#define MAYBE_InvalidSelectorForIframe DISABLED_InvalidSelectorForIframe +#else +#define MAYBE_InvalidSelectorForIframe InvalidSelectorForIframe +#endif +IN_PROC_BROWSER_TEST_P(LinkToTextMenuObserverTest, + MAYBE_InvalidSelectorForIframe) { GURL main_url( embedded_test_server()->GetURL("a.com", "/page_with_iframe.html"));
diff --git a/chrome/browser/resources/about_sys/about_sys.js b/chrome/browser/resources/about_sys/about_sys.js index e5ecf9b3..c76da239 100644 --- a/chrome/browser/resources/about_sys/about_sys.js +++ b/chrome/browser/resources/about_sys/about_sys.js
@@ -15,6 +15,12 @@ // Limit file size to 10 MiB to prevent hanging on accidental upload. const MAX_FILE_SIZE = 10485760; +// <if expr="chromeos"> +// Link to markdown doc with documentation for Chrome OS. +const CROS_MD_DOC_URL = + 'https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/debugd/docs/log_entries.md'; +// </if> + function getValueDivForButton(button) { return $(button.id.substr(0, button.id.length - 4)); } @@ -118,9 +124,24 @@ nameCell.className = 'name'; const nameDiv = document.createElement('div'); nameDiv.className = 'stat-name'; + + // Add an anchor link that links to the log entry. + const anchor = document.createElement('a'); + anchor.href = `#${log.statName}`; + anchor.text = '🔗'; + nameDiv.appendChild(anchor); + const a = document.createElement('a'); a.className = 'stat-name-link'; - a.href = `#${log.statName}`; + + // Let URL be anchor to the section of this page by default. + let urlPrefix = ''; + // <if expr="chromeos"> + // Link to the markdown doc with documentation for the entry for Chrome OS + // instead. + urlPrefix = CROS_MD_DOC_URL; + // </if> + a.href = `${urlPrefix}#${log.statName}`; a.name = a.text = log.statName; nameDiv.appendChild(a); nameCell.appendChild(nameDiv);
diff --git a/chrome/browser/resources/chromeos/accessibility/common/cursors/cursors_test.js b/chrome/browser/resources/chromeos/accessibility/common/cursors/cursors_test.js index 4c7d839..3a55c1b 100644 --- a/chrome/browser/resources/chromeos/accessibility/common/cursors/cursors_test.js +++ b/chrome/browser/resources/chromeos/accessibility/common/cursors/cursors_test.js
@@ -388,49 +388,52 @@ }); }); -TEST_F('AccessibilityExtensionCursorsTest', 'SingleDocSelection', function() { - this.runWithLoadedTree( - ` +// Disabled due to being flaky on ChromeOS. See https://crbug.com/1227435. +TEST_F( + 'AccessibilityExtensionCursorsTest', 'DISABLED_SingleDocSelection', + function() { + this.runWithLoadedTree( + ` <span>start</span> <p><a href="google.com">google home page</a></p> <p>some more text</p> <p>end of text</p> `, - function(root) { - // For some reason, Blink fails if we don't first select something on - // the page. - ChromeVoxState.instance.currentRange.select(); - const link = root.find({role: RoleType.LINK}); - const p1 = root.find({role: RoleType.PARAGRAPH}); - const p2 = p1.nextSibling; + function(root) { + // For some reason, Blink fails if we don't first select something + // on the page. + ChromeVoxState.instance.currentRange.select(); + const link = root.find({role: RoleType.LINK}); + const p1 = root.find({role: RoleType.PARAGRAPH}); + const p2 = p1.nextSibling; - const singleSel = new cursors.Range( - new cursors.Cursor(link, 0), new cursors.Cursor(link, 1)); + const singleSel = new cursors.Range( + new cursors.Cursor(link, 0), new cursors.Cursor(link, 1)); - const multiSel = new cursors.Range( - new cursors.Cursor(p1.firstChild, 2), - new cursors.Cursor(p2.firstChild, 4)); + const multiSel = new cursors.Range( + new cursors.Cursor(p1.firstChild, 2), + new cursors.Cursor(p2.firstChild, 4)); - function verifySel() { - if (root.selectionStartObject === link.firstChild) { - assertEquals(link.firstChild, root.selectionStartObject); - assertEquals(0, root.selectionStartOffset); - assertEquals(link.firstChild, root.selectionEndObject); - assertEquals(1, root.selectionEndOffset); - this.listenOnce(root, 'textSelectionChanged', verifySel); - multiSel.select(); - } else if (root.selectionStartObject === p1.firstChild) { - assertEquals(p1.firstChild, root.selectionStartObject); - assertEquals(2, root.selectionStartOffset); - assertEquals(p2.firstChild, root.selectionEndObject); - assertEquals(4, root.selectionEndOffset); - } - } + function verifySel() { + if (root.selectionStartObject === link.firstChild) { + assertEquals(link.firstChild, root.selectionStartObject); + assertEquals(0, root.selectionStartOffset); + assertEquals(link.firstChild, root.selectionEndObject); + assertEquals(1, root.selectionEndOffset); + this.listenOnce(root, 'textSelectionChanged', verifySel); + multiSel.select(); + } else if (root.selectionStartObject === p1.firstChild) { + assertEquals(p1.firstChild, root.selectionStartObject); + assertEquals(2, root.selectionStartOffset); + assertEquals(p2.firstChild, root.selectionEndObject); + assertEquals(4, root.selectionEndOffset); + } + } - this.listenOnce(root, 'textSelectionChanged', verifySel, true); - singleSel.select(); - }); -}); + this.listenOnce(root, 'textSelectionChanged', verifySel, true); + singleSel.select(); + }); + }); TEST_F( 'AccessibilityExtensionCursorsTest', 'MultiLineOffsetSelection',
diff --git a/chrome/browser/resources/memories/BUILD.gn b/chrome/browser/resources/memories/BUILD.gn index 9b375341..bc5da79 100644 --- a/chrome/browser/resources/memories/BUILD.gn +++ b/chrome/browser/resources/memories/BUILD.gn
@@ -32,8 +32,6 @@ "visit_row.js", ] path_mappings = [ - "chrome://resources/mojo/url/mojom/*|" + - rebase_path("$preprocess_folder/*", target_gen_dir), "/chrome/browser/ui/webui/history_clusters/*|" + rebase_path( "$preprocess_folder/chrome/browser/ui/webui/history_clusters/*", @@ -45,9 +43,9 @@ deps = [ "//third_party/polymer/v3_0:library", "//ui/webui/resources:library", + "//ui/webui/resources/mojo:library", ] extra_deps = [ - ":copy_chrome_resources_mojom", ":copy_history_clusters_api_mojom", ":copy_history_clusters_definitions_mojom", ":preprocess", @@ -55,12 +53,6 @@ ] } -copy("copy_chrome_resources_mojom") { - sources = [ "$root_gen_dir/mojom-webui/url/mojom/url.mojom-webui.js" ] - outputs = [ "$preprocess_folder/{{source_file_part}}" ] - deps = [ "//url/mojom:url_mojom_gurl_js__generator" ] -} - copy("copy_history_clusters_api_mojom") { sources = [ "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/history_clusters/history_clusters.mojom-webui.js" ] outputs = [ "$preprocess_folder/chrome/browser/ui/webui/history_clusters/{{source_file_part}}" ]
diff --git a/chrome/browser/resources/new_tab_page/modules/cart_v2/module.html b/chrome/browser/resources/new_tab_page/modules/cart_v2/module.html index 923404d..7851aab8 100644 --- a/chrome/browser/resources/new_tab_page/modules/cart_v2/module.html +++ b/chrome/browser/resources/new_tab_page/modules/cart_v2/module.html
@@ -54,7 +54,7 @@ #consentCard, .cart-item { - margin: 0 4px; + margin: 0 15px 24px 15px; } .cart-item { @@ -120,6 +120,7 @@ color: var(--cr-primary-text-color); display: flex; flex-direction: column; + flex-shrink: 0; font-size: 13px; width: 99px; } @@ -286,7 +287,7 @@ 'modulesCartLower')]]" show-dismiss-button on-dismiss-button-click="onDismissButtonClick_" on-disable-button-click="onDisableButtonClick_"> - [[i18n('modulesCartSentence')]] + [[i18n('modulesCartSentenceV2')]] </ntp-module-header> <div id="moduleContent"> <div id="cartCarousel"> @@ -375,18 +376,14 @@ </cr-action-menu> </div> <div id="moduleFooter"> - <template is="dom-if" if="[[showLeftScrollButton_]]"> - <div id="leftScrollShadow" class="side-scroll-shadow"></div> - <cr-icon-button id="leftScrollButton" - class="side-scroll-button" on-click="onLeftScrollClick_"> - </cr-icon-button> - </template> - <template is="dom-if" if="[[showRightScrollButton_]]"> - <div id="rightScrollShadow" class="side-scroll-shadow"> </div> - <cr-icon-button id="rightScrollButton" - class="side-scroll-button" on-click="onRightScrollClick_"> - </cr-icon-button> - </template> + <div id="leftScrollShadow" class="side-scroll-shadow"></div> + <cr-icon-button id="leftScrollButton" class="side-scroll-button" + disabled="[[!showLeftScrollButton_]]" on-click="onLeftScrollClick_"> + </cr-icon-button> + <div id="rightScrollShadow" class="side-scroll-shadow"> </div> + <cr-icon-button id="rightScrollButton" class="side-scroll-button" + disabled="[[!showRightScrollButton_]]" on-click="onRightScrollClick_"> + </cr-icon-button> </div> </div> <cr-toast id="dismissCartToast" duration="10000">
diff --git a/chrome/browser/resources/ntp4/ephemeral_guest_tab.css b/chrome/browser/resources/ntp4/ephemeral_guest_tab.css deleted file mode 100644 index 1aca6cb..0000000 --- a/chrome/browser/resources/ntp4/ephemeral_guest_tab.css +++ /dev/null
@@ -1,22 +0,0 @@ -/* Copyright 2020 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Ephemeral Guest Profile CSS. - * TODO(crbug.com/1125474): move styling to guest tab.css and remove this file - * once all instances of non-ephemeral Guest profiles are deprecated. - */ - -a { - color: rgb(51, 103, 214); -} - -@media (prefers-color-scheme: dark) { - html { - background: rgb(53, 54, 58); - color: rgb(232, 234, 237); /* --google-grey-200 */ - } - :-webkit-any(a, .learn-more-button) { - color: rgb(138, 180, 248); /* --google-blue-refresh-300 */ - } -} \ No newline at end of file
diff --git a/chrome/browser/resources/ntp4/ephemeral_guest_tab.html b/chrome/browser/resources/ntp4/ephemeral_guest_tab.html deleted file mode 100644 index f45cd798..0000000 --- a/chrome/browser/resources/ntp4/ephemeral_guest_tab.html +++ /dev/null
@@ -1,36 +0,0 @@ -<!-- Copyright 2020 The Chromium Authors. All rights reserved. - -- Use of this source code is governed by a BSD-style license that can be - -- found in the LICENSE file. ---> - -<!-- TODO(crbug.com/1125474): Rename file to guest_tab.html once all audit is - -- done and all instances of non-ephemeral Guest profiles are deprecated. ---> - -<!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}"> -<head> -<meta charset="utf-16"> -<title>$i18n{title}</title> -<script src="chrome://resources/js/util.js"></script> -<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> -<link rel="stylesheet" href="incognito_and_guest_tab.css"> -<link rel="stylesheet" href="ephemeral_guest_tab.css"> -</head> -<body> -<div class="content"> - <h1>$i18nRaw{guestTabHeading}</h1> - <p id="subtitle"> - <span>$i18nRaw{guestTabDescription}</span> - <a class="learn-more-button" - href="$i18n{learnMoreLink}">$i18n{learnMore}</a> - </p> - <div id="bulletpoints-wrapper"> - <div class="bulletpoints first">$i18nRaw{guestTabFeatures}</div> - <div class="bulletpoints">$i18nRaw{guestTabWarning}</div> - </div> - <a class="learn-more-button" href="$i18n{learnMoreLink}">$i18n{learnMore}</a> -</div> -<script type="module" src="ephemeral_guest_tab.js"></script> -</body> -</html>
diff --git a/chrome/browser/resources/ntp4/ephemeral_guest_tab.js b/chrome/browser/resources/ntp4/ephemeral_guest_tab.js deleted file mode 100644 index 22d3b81..0000000 --- a/chrome/browser/resources/ntp4/ephemeral_guest_tab.js +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(crbug.com/1125474): Rename file to guest_tab.js once all audit is done -// and all instances of non-ephemeral Guest profiles are deprecated. - -// clang-format off -import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; -// clang-format on - -/** @interface */ -class GuestSignIn { - /** - * Handles sign in and sign out based on user's sign in status. - */ - onChangeSignInStatusClicked() {} -} - -/** @implements {GuestSignIn} */ -class GuestSignInImpl { - onChangeSignInStatusClicked() { - chrome.send('onChangeSignInStatusClicked'); - } -} - -addSingletonGetter(GuestSignInImpl); - -window.addEventListener('load', function() { - $('change-sign-in-status').onclick = () => - GuestSignInImpl.getInstance().onChangeSignInStatusClicked(); -});
diff --git a/chrome/browser/resources/ntp4/guest_tab.css b/chrome/browser/resources/ntp4/guest_tab.css deleted file mode 100644 index dae49a6..0000000 --- a/chrome/browser/resources/ntp4/guest_tab.css +++ /dev/null
@@ -1,92 +0,0 @@ -/* Copyright 2020 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -body { - -webkit-font-smoothing: antialiased; - font-size: 85%; -} - -@media (prefers-color-scheme: dark) { - html { - background: rgb(53, 54, 58); - color: rgb(232, 234, 237); /* --google-grey-200 */ - } -} - -h1 { - font-size: 200%; - font-weight: 400; - margin-bottom: .77em; -} - -p { - line-height: 1.5; - margin: .588em 0; - text-align: start; -} - -a { - color: rgb(51, 103, 214); -} - -a:hover { - text-decoration: underline; -} - -.learn-more-button { - color: rgb(66, 133, 244); - display: inline-block; - font-size: 92.8%; - font-weight: 500; - margin-top: 1.98em; - padding: 10.5px 12px; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - :-webkit-any(a, .learn-more-button) { - color: rgb(138, 180, 248); /* --google-blue-refresh-300 */ - } -} - -.content { - box-sizing: border-box; - margin: 3.5em auto 0; - max-width: 480px; - min-width: 240px; - padding: 30px 35px; - text-align: center; -} - -html[hascustombackground='true'] .content { - border-radius: 2px; - box-shadow: 0 4px 6px 1px rgba(0, 0, 0, 0.4); -} - -.content > span { - display: block; -} - -@media (max-width:700px) { - body { - margin: 1em 2em 2em; - } -} - -@media (max-width:400px) { - body { - margin: 3em 1.5em 2em; - } - - /* Adjustment for narrow screen to prevent horizontal scrollbar. */ - .content { - padding: 16px 8px; - } -} - -@media (max-height:480px) and (max-width:400px) { - .content { - margin: auto; - } -}
diff --git a/chrome/browser/resources/ntp4/guest_tab.html b/chrome/browser/resources/ntp4/guest_tab.html index 18dcc288..a89226c 100644 --- a/chrome/browser/resources/ntp4/guest_tab.html +++ b/chrome/browser/resources/ntp4/guest_tab.html
@@ -4,7 +4,7 @@ <meta charset="utf-8"> <title>$i18n{title}</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> -<link rel="stylesheet" href="guest_tab.css"> +<link rel="stylesheet" href="incognito_and_guest_tab.css"> </head> <body> <div class="content">
diff --git a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css index 888efe04..5d9d7a7 100644 --- a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css +++ b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
@@ -4,229 +4,91 @@ * * Incognito and guest mode NTP shared CSS. */ -body { + body { -webkit-font-smoothing: antialiased; - font-size: 100%; - margin: 0; + font-size: 85%; } -[hidden] { - display: none !important; -} - -/** Typography -------------------------------------------------------------- */ - -.content { - font-size: calc(100% - 2px); - line-height: calc(100% + 6px); - min-width: 240px; +@media (prefers-color-scheme: dark) { + html { + background: rgb(53, 54, 58); + color: rgb(232, 234, 237); /* --google-grey-200 */ + } } h1 { - font-size: calc(100% + 8px); + font-size: 200%; font-weight: 400; - line-height: calc(100% + 8px); + margin-bottom: .77em; } -em { - color: white; - font-style: normal; +p { + line-height: 1.5; + margin: .588em 0; + text-align: start; } a { - cursor: pointer; + color: rgb(51, 103, 214); +} + +a:hover { + text-decoration: underline; } .learn-more-button { + color: rgb(66, 133, 244); + display: inline-block; + font-size: 92.8%; + font-weight: 500; + margin-top: 1.98em; + padding: 10.5px 12px; text-decoration: none; } -/* Small font on small screens. */ -@media (max-width: 240px), - (max-height: 320px) { - .content { - font-size: calc(100% - 4px); - line-height: calc(100% + 6px); - } - - h1 { - font-size: calc(100% + 4px); - line-height: calc(100% + 4px); +@media (prefers-color-scheme: dark) { + :-webkit-any(a, .learn-more-button) { + color: rgb(138, 180, 248); /* --google-blue-refresh-300 */ } } -/** The "Learn more" link --------------------------------------------------- */ - -/* By default, we only show the inline "Learn more" link. */ -.content > .learn-more-button { - display: none; -} - -/* On narrow screens, we show the standalone "Learn more" link. */ -@media (max-width: 720px) { - #subtitle > .learn-more-button { - display: none; - } - - .content > .learn-more-button { - display: block; - } -} - -/** Layout ------------------------------------------------------------------ */ - -/* Align the content and title to the center. */ .content { - margin-inline-end: auto; - margin-inline-start: auto; - max-width: 600px; -} - -h1 { + box-sizing: border-box; + margin: 3.5em auto 0; + max-width: 480px; + min-width: 240px; + padding: 30px 35px; text-align: center; } -/* Align the two columns of bulletpoints next to each other. */ -#bulletpoints-wrapper { - display: flex; - flex-wrap: wrap; - justify-content: space-between; +html[hascustombackground='true'] .content { + border-radius: 2px; + box-shadow: 0 4px 6px 1px rgba(0, 0, 0, 0.4); } -.bulletpoints { - flex-basis: 285px; /* (600px - 30px) / 2. */ - flex-grow: 1; - flex-shrink: 0; +.content > span { + display: block; } -.bulletpoints.first { - margin-inline-end: 30px; +@media (max-width:700px) { + body { + margin: 1em 2em 2em; + } } -/* On narrow screens, align everything to the left. */ -@media (max-width: 720px) { +@media (max-width:400px) { + body { + margin: 3em 1.5em 2em; + } + + /* Adjustment for narrow screen to prevent horizontal scrollbar. */ .content { - max-width: 600px !important; /* must override the rule set by JS which - * is only valid for width > 720px cases. */ - text-align: start; - } - - h1 { - text-align: start; + padding: 16px 8px; } } -/** Paddings and margins ---------------------------------------------------- */ - -.bulletpoints ul { - margin: 4px 0 0; - padding-inline-start: 16px; -} - -/* Wide screens. */ -@media (min-width: 720px) { - h1, - #subtitle, - .learn-more-button { - margin-top: 1.5rem; - } - - h1, - #subtitle, - .bulletpoints { - margin-bottom: 1.5rem; - } - +@media (max-height:480px) and (max-width:400px) { .content { - margin-top: 40px; - min-width: 240px; - padding: 8px 48px 24px; - } - - /* Snap the content box to the whole height on short screens. */ - @media (max-height: 480px) { - html, - body, - .content { - height: 100%; - } - - .content { - margin-bottom: 0; - margin-top: 0; - padding-bottom: 0; - padding-top: 0; - } - } - - /* Smaller vertical margins on very short screens. */ - @media (max-height: 320px) { - h1, - #subtitle { - margin-bottom: 16px; - margin-top: 16px; - } - - .learn-more-button, - .bulletpoints { - margin-bottom: 16px; - } - } -} - -/* Narrow screens */ -@media (max-width: 720px) { - .content { - min-width: 176px; - padding: 72px 32px; - } - - h1, - #subtitle { - margin-bottom: 1.5rem; - margin-top: 1.5rem; - } - - .bulletpoints, - .learn-more-button { - margin-bottom: 1.5rem; - } - - /* Smaller offsets on smaller screens. */ - @media (max-height: 600px) { - .content { - padding-top: 48px; - } - - h1, - #subtitle { - margin-bottom: 1rem; - margin-top: 1rem; - } - - .bulletpoints, - .learn-more-button { - margin-bottom: 1rem; - } - } - - /* Small top offset on very small screens. */ - @media (max-height: 480px) { - .content { - padding-top: 32px; - } - } - - .learn-more-button { - margin-bottom: 0; - } -} - -/* Very narrow screens. */ -@media (max-width: 240px) { - .content { - min-width: 192px; - padding-inline-end: 24px; - padding-inline-start: 24px; + margin: auto; } }
diff --git a/chrome/browser/resources/ntp4/incognito_tab.css b/chrome/browser/resources/ntp4/incognito_tab.css index 9117653..6ed9363 100644 --- a/chrome/browser/resources/ntp4/incognito_tab.css +++ b/chrome/browser/resources/ntp4/incognito_tab.css
@@ -2,6 +2,16 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +body { + -webkit-font-smoothing: antialiased; + font-size: 100%; + margin: 0; +} + +[hidden] { + display: none !important; +} + /** Typography -------------------------------------------------------------- */ .content { @@ -9,10 +19,39 @@ for the case when a theme with a background image is installed. */ background-color: rgb(53, 54, 58); color: rgb(232, 234, 237); /* --google-grey-200 */ + font-size: calc(100% - 2px); + line-height: calc(100% + 6px); + min-width: 240px; +} + +h1 { + font-size: calc(100% + 8px); + font-weight: 400; + line-height: calc(100% + 8px); +} + +em { + color: white; + font-style: normal; } .learn-more-button { color: rgb(138, 180, 248); + text-decoration: none; +} + +/* Small font on small screens. */ +@media (max-width: 240px), + (max-height: 320px) { + .content { + font-size: calc(100% - 4px); + line-height: calc(100% + 6px); + } + + h1 { + font-size: calc(100% + 4px); + line-height: calc(100% + 4px); + } } /** Icon -------------------------------------------------------------------- */ @@ -100,34 +139,101 @@ /** Layout ------------------------------------------------------------------ */ -/* Align the icon to the center. */ +/* Align the content, icon, and title to to the center. */ +.content { + margin-inline-end: auto; + margin-inline-start: auto; + max-width: 600px; +} + .icon { margin-inline-end: auto; margin-inline-start: auto; } +h1 { + text-align: center; +} + +/* Align the two columns of bulletpoints next to each other. */ +#bulletpoints-wrapper { + display: flex; + flex-wrap: wrap; + justify-content: space-between; +} + +.bulletpoints { + flex-basis: 285px; /* (600px - 30px) / 2. */ + flex-grow: 1; + flex-shrink: 0; +} + +.bulletpoints.first { + margin-inline-end: 30px; +} + /* On narrow screens, align everything to the left. */ @media (max-width: 720px) { + .content { + max-width: 600px !important; /* must override the rule set by JS which + * is only valid for width > 720px cases. */ + text-align: start; + } + .icon { - margin-inline-start: 0; + margin-inline-start: 0; + } + + h1 { + text-align: start; } } /** Paddings and margins ---------------------------------------------------- */ +.bulletpoints ul { + margin: 4px 0 0; + padding-inline-start: 16px; +} + /* Wide screens. */ @media (min-width: 720px) { - .icon { + .icon, + h1, + #subtitle, + .learn-more-button { margin-top: 1.5rem; } .icon, + h1, + #subtitle, + .bulletpoints, #cookie-controls { margin-bottom: 1.5rem; } + .content { + margin-top: 40px; + min-width: 240px; + padding: 8px 48px 24px; + } + /* Snap the content box to the whole height on short screens. */ @media (max-height: 480px) { + html, + body, + .content { + height: 100%; + } + + .content { + margin-bottom: 0; + margin-top: 0; + padding-bottom: 0; + padding-top: 0; + } + .icon { margin-top: 0; padding-top: 32px; /* Define the top offset through the icon's padding, @@ -137,6 +243,14 @@ /* Smaller vertical margins on very short screens. */ @media (max-height: 320px) { + h1, + #subtitle { + margin-bottom: 16px; + margin-top: 16px; + } + + .learn-more-button, + .bulletpoints, .icon, #cookie-controls { margin-bottom: 16px; @@ -146,29 +260,66 @@ /* Narrow screens */ @media (max-width: 720px) { - .icon { + .content { + min-width: 176px; + padding: 72px 32px; + } + + .icon, + h1, + #subtitle { margin-bottom: 1.5rem; margin-top: 1.5rem; } + .bulletpoints, + .learn-more-button, #cookie-controls { margin-bottom: 1.5rem; } /* Smaller offsets on smaller screens. */ @media (max-height: 600px) { - .icon { + .content { + padding-top: 48px; + } + + .icon, + h1, + #subtitle { margin-bottom: 1rem; margin-top: 1rem; } + .bulletpoints, + .learn-more-button, #cookie-controls { margin-bottom: 1rem; } } + /* Small top offset on very small screens. */ + @media (max-height: 480px) { + .content { + padding-top: 32px; + } + } + /* Undo the first and last elements margins. */ .icon { margin-top: 0; } + + .learn-more-button { + margin-bottom: 0; + } +} + +/* Very narrow screens. */ +@media (max-width: 240px) { + .content { + min-width: 192px; + padding-inline-end: 24px; + padding-inline-start: 24px; + } }
diff --git a/chrome/browser/resources/ntp4/incognito_tab.html b/chrome/browser/resources/ntp4/incognito_tab.html index e9bd9fd9..bef88b1 100644 --- a/chrome/browser/resources/ntp4/incognito_tab.html +++ b/chrome/browser/resources/ntp4/incognito_tab.html
@@ -16,7 +16,6 @@ 'chrome://theme/css/incognito_tab_theme.css?' + Date.now(); </script> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> -<link rel="stylesheet" href="incognito_and_guest_tab.css"> <link rel="stylesheet" href="incognito_tab.css"> </head> <body>
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index ae2d16b..8b5c95d 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -297,7 +297,6 @@ "chromeos/device_page/drag_behavior.m.js", "chromeos/device_page/keyboard.m.js", "chromeos/device_page/layout_behavior.m.js", - "chromeos/device_page/night_light_slider.m.js", "chromeos/device_page/pointers.m.js", "chromeos/device_page/power.m.js", "chromeos/device_page/storage.m.js", @@ -489,6 +488,7 @@ "chromeos/pref_to_setting_metric_converter.m.js", "chromeos/route_origin_behavior.m.js", "chromeos/search_handler.m.js", + "chromeos/settings_scheduler_slider/settings_scheduler_slider.js", "controls/controlled_button.js", "controls/controlled_radio_button.js", "controls/extension_controlled_indicator.js", @@ -553,6 +553,7 @@ "os_toolbar:closure_compile_module", "parental_controls_page:closure_compile_module", "personalization_page:closure_compile_module", + "settings_scheduler_slider:closure_compile_module", ] } @@ -706,6 +707,7 @@ "os_toolbar:polymer3_elements", "parental_controls_page:polymer3_elements", "personalization_page:polymer3_elements", + "settings_scheduler_slider:web_components", # Local targets ":modulize",
diff --git a/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn index d817e07e..12b62ea7 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn
@@ -20,7 +20,6 @@ ":drag_behavior.m", ":keyboard.m", ":layout_behavior.m", - ":night_light_slider.m", ":pointers.m", ":power.m", ":storage.m", @@ -57,6 +56,7 @@ "..:os_route.m", "../..:router", "../../controls:settings_slider", + "../settings_scheduler_slider:settings_scheduler_slider", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_slider:cr_slider", "//ui/webui/resources/js:cr.m", @@ -123,16 +123,6 @@ ] } -js_library("night_light_slider.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/device_page/night_light_slider.m.js" ] - deps = [ - "../../prefs:prefs_behavior", - "//third_party/polymer/v3_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior", - "//third_party/polymer/v3_0/components-chromium/paper-behaviors:paper-ripple-behavior", - ] - extra_deps = [ ":night_light_slider_module" ] -} - js_library("pointers.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/device_page/pointers.m.js" ] deps = [ @@ -221,7 +211,6 @@ ":display_overscan_dialog_module", ":keyboard_module", ":modulize", - ":night_light_slider_module", ":pointers_module", ":power_module", ":storage_external_entry_module", @@ -276,15 +265,6 @@ namespace_rewrites = os_settings_namespace_rewrites } -polymer_modulizer("night_light_slider") { - js_file = "night_light_slider.js" - html_file = "night_light_slider.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - auto_imports = os_settings_auto_imports - namespace_rewrites = os_settings_namespace_rewrites -} - polymer_modulizer("pointers") { js_file = "pointers.js" html_file = "pointers.html"
diff --git a/chrome/browser/resources/settings/chromeos/device_page/display.html b/chrome/browser/resources/settings/chromeos/device_page/display.html index 45a14fc..804fdd4 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/display.html +++ b/chrome/browser/resources/settings/chromeos/device_page/display.html
@@ -15,9 +15,9 @@ <link rel="import" href="device_page_browser_proxy.html"> <link rel="import" href="display_layout.html"> <link rel="import" href="display_overscan_dialog.html"> -<link rel="import" href="night_light_slider.html"> <link rel="import" href="../os_route.html"> <link rel="import" href="../deep_linking_behavior.html"> +<link rel="import" href="../settings_scheduler_slider/settings_scheduler_slider.html"> <link rel="import" href="../../controls/settings_dropdown_menu.html"> <link rel="import" href="../../controls/settings_slider.html"> <link rel="import" href="../../prefs/prefs_behavior.html"> @@ -369,8 +369,10 @@ <div class="settings-box indented continuation"> <div class="start text-area layout vertical"> <div class="settings-box continuation self-stretch"> - <night-light-slider id="nightLightSlider" prefs="{{prefs}}"> - </night-light-slider> + <settings-scheduler-slider id="nightLightSlider" prefs="{{prefs}}" + pref-start-time="{{prefs.ash.night_light.custom_start_time}}" + pref-end-time="{{prefs.ash.night_light.custom_end_time}}"> + </settings-scheduler-slider> </div> </div> </div>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/night_light_slider.html b/chrome/browser/resources/settings/chromeos/device_page/night_light_slider.html deleted file mode 100644 index cf10af28..0000000 --- a/chrome/browser/resources/settings/chromeos/device_page/night_light_slider.html +++ /dev/null
@@ -1,197 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-resizable-behavior/iron-resizable-behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-behaviors/paper-ripple-behavior.html"> -<link rel="import" href="../../prefs/prefs_behavior.html"> - -<dom-module id="night-light-slider"> - <template> - <style> - :host { - cursor: default; - font-weight: 500; - text-align: center; - user-select: none; - } - - #sliderContainer { - display: inline-block; - position: relative; - user-select: none; - width: 100%; - } - - #sliderBar { - background-color: rgba(var(--google-blue-600-rgb), .24); - background-size: 100%; - display: inline-block; - height: 2px; - position: relative; - width: inherit; - } - - .knob { - height: 32px; - margin-left: -16px; - margin-top: -15px; - position: absolute; - width: 32px; - z-index: 3; - } - - .knob:focus { - outline: none; - } - - .knob-inner { - background: var(--google-blue-600); - border-radius: 6px; - height: 10px; - left: 0; - margin: 11px; - position: absolute; - width: 10px; - z-index: 3; - } - - .knob-inner:focus { - outline: none; - } - - #progressContainer { - height: 100%; - overflow: hidden; - position: absolute; - width: 100%; - } - - .progress { - background: var(--google-blue-600); - height: 100%; - position: absolute; - z-index: 1; - } - - #labelContainer { - height: 1.75em; - } - - .label { - background: var(--google-blue-600); - border-radius: 14px; - color: white; - font-size: 12px; - left: 0; - line-height: 1.5em; - margin-left: -2.5em; - position: absolute; - text-align: center; - transition: margin-top 200ms cubic-bezier(0, 0, 0.2, 1); - vertical-align: middle; - width: 5em; - } - - .end-label-overlap { - margin-top: -2em; - } - - #markersContainer { - display: flex; - height: 100%; - left: 0; - position: absolute; - width: 100%; - } - - .active-marker, - .inactive-marker { - background-color: rgba(255, 255, 255, 0.54); - border-radius: 50%; - display: block; - height: 100%; - margin-left: -1px; - padding: 0; - position: absolute; - width: 2PX; - z-index: 2; - } - - .inactive-marker { - background-color: rgba(26, 115, 232, 0.54); - } - - #legendContainer { - height: 10px; - position: relative; - width: inherit; - } - - #legendContainer > div { - color: rgb(100, 100, 100); - font-size: 12px; - margin-left: -2.5em; - position: absolute; - text-align: center; - top: 5px; - width: 5em; - } - - paper-ripple { - color: var(--google-blue-600); - } - </style> - - <div id="sliderContainer"> - <div id="labelContainer"> - <div id="startLabel" class="label" - aria-label="$i18n{displayNightLightStartTime}"> - [[getTimeString_(prefs.ash.night_light.custom_start_time.value, - shouldUse24Hours_)]] - </div> - <div id="endLabel" class="label" - aria-label="$i18n{displayNightLightStopTime}"> - [[getTimeString_(prefs.ash.night_light.custom_end_time.value, - shouldUse24Hours_)]] - </div> - </div> - <div id="sliderBar"> - <div id="progressContainer"> - <div id="endProgress" class="progress"></div> - <div id="startProgress" class="progress"></div> - </div> - <div id="markersContainer"> - </div> - <div id="startKnob" class="knob" tabindex="1" on-down="startDrag_" - on-up="endDrag_" on-track="continueDrag_"> - <div class="knob-inner" tabindex="-1"></div> - </div> - <div id="endKnob" class="knob" tabindex="2" on-down="startDrag_" - on-up="endDrag_" on-track="continueDrag_"> - <div class="knob-inner" tabindex="-1"></div> - </div> - </div> - <div id="legendContainer"> - <div style="[[getLegendStyle_(0, isRTL_)]]"> - [[getLocaleTimeString_(18, 0, shouldUse24Hours_)]] - </div> - <div style="[[getLegendStyle_(25, isRTL_)]]"> - [[getLocaleTimeString_(0, 0, shouldUse24Hours_)]] - </div> - <div style="[[getLegendStyle_(50, isRTL_)]]"> - [[getLocaleTimeString_(6, 0, shouldUse24Hours_)]] - </div> - <div style="[[getLegendStyle_(75, isRTL_)]]"> - [[getLocaleTimeString_(12, 0, shouldUse24Hours_)]] - </div> - <div style="[[getLegendStyle_(100, isRTL_)]]"> - [[getLocaleTimeString_(18, 0, shouldUse24Hours_)]] - </div> - </div> - <div id="dummyRippleContainer" hidden></div> - </div> - - </template> - <script src="night_light_slider.js"></script> -</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index fb8f92e..89343d3 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -347,6 +347,7 @@ "chrome/browser/resources/settings/chromeos/personalization_page/change_picture_browser_proxy.html", "chrome/browser/resources/settings/chromeos/personalization_page/wallpaper_browser_proxy.html", "chrome/browser/resources/settings/chromeos/keyboard_shortcut_banner/keyboard_shortcut_banner.html", + "chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.html", "chrome/browser/resources/settings/controls/controlled_button.html", "chrome/browser/resources/settings/controls/controlled_radio_button.html", "chrome/browser/resources/settings/controls/extension_controlled_indicator.html",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index bbaf37f2..9dfcce2 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -12,7 +12,6 @@ import './device_page/display_layout.m.js'; import './device_page/display_overscan_dialog.m.js'; import './device_page/keyboard.m.js'; -import './device_page/night_light_slider.m.js'; import './device_page/pointers.m.js'; import './device_page/power.m.js'; import './device_page/storage.m.js'; @@ -82,6 +81,7 @@ import './os_settings_search_box/os_settings_search_box.m.js'; import './os_toolbar/os_toolbar.m.js'; import './parental_controls_page/parental_controls_page.m.js'; +import './settings_scheduler_slider/settings_scheduler_slider.js'; export {AboutPageBrowserProxyImpl, BrowserChannel, UpdateStatus} from '../about_page/about_page_browser_proxy.js'; export {LifetimeBrowserProxy, LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/BUILD.gn b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/BUILD.gn new file mode 100644 index 0000000..f64a4cc --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/BUILD.gn
@@ -0,0 +1,25 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") +import("../os_settings.gni") + +js_type_check("closure_compile_module") { + closure_flags = os_settings_closure_flags + is_polymer3 = true + deps = [ ":settings_scheduler_slider" ] +} + +js_library("settings_scheduler_slider") { + deps = [ + "../../prefs:prefs_behavior", + "//third_party/polymer/v3_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior", + "//third_party/polymer/v3_0/components-chromium/paper-behaviors:paper-ripple-behavior", + ] +} + +html_to_js("web_components") { + js_files = [ "settings_scheduler_slider.js" ] +}
diff --git a/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.html b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.html new file mode 100644 index 0000000..264b32e --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.html
@@ -0,0 +1,181 @@ +<style> + :host { + cursor: default; + font-weight: 500; + text-align: center; + user-select: none; + } + + #sliderContainer { + display: inline-block; + position: relative; + user-select: none; + width: 100%; + } + + #sliderBar { + background-color: rgba(var(--google-blue-600-rgb), .24); + background-size: 100%; + display: inline-block; + height: 2px; + position: relative; + width: inherit; + } + + .knob { + height: 32px; + margin-inline-start: -16px; + margin-top: -15px; + position: absolute; + width: 32px; + z-index: 3; + } + + .knob:focus { + outline: none; + } + + .knob-inner { + background: var(--google-blue-600); + border-radius: 6px; + height: 10px; + left: 0; + margin: 11px; + position: absolute; + width: 10px; + z-index: 3; + } + + .knob-inner:focus { + outline: none; + } + + #progressContainer { + height: 100%; + overflow: hidden; + position: absolute; + width: 100%; + } + + .progress { + background: var(--google-blue-600); + height: 100%; + position: absolute; + z-index: 1; + } + + #labelContainer { + height: 1.75em; + } + + .label { + background: var(--google-blue-600); + border-radius: 14px; + color: white; + font-size: 12px; + left: 0; + line-height: 1.5em; + margin-inline-start: -2.5em; + position: absolute; + text-align: center; + transition: margin-top 200ms cubic-bezier(0, 0, 0.2, 1); + vertical-align: middle; + width: 5em; + } + + .end-label-overlap { + margin-top: -2em; + } + + #markersContainer { + display: flex; + height: 100%; + left: 0; + position: absolute; + width: 100%; + } + + .active-marker, + .inactive-marker { + background-color: rgba(255, 255, 255, 0.54); + border-radius: 50%; + display: block; + height: 100%; + margin-inline-start: -1px; + padding: 0; + position: absolute; + width: 2PX; + z-index: 2; + } + + .inactive-marker { + background-color: rgba(26, 115, 232, 0.54); + } + + #legendContainer { + height: 10px; + margin-bottom: 40px; + position: relative; + width: inherit; + } + + #legendContainer > div { + color: rgb(100, 100, 100); + font-size: 12px; + margin-inline-start: -2.5em; + position: absolute; + text-align: center; + top: 5px; + width: 5em; + } + + paper-ripple { + color: var(--google-blue-600); + } +</style> +<div id="sliderContainer"> + <div id="labelContainer"> + <div id="startLabel" class="label" + aria-label="$i18n{startTime}"> + [[getTimeString_(startTime_, shouldUse24Hours_)]] + </div> + <div id="endLabel" class="label" + aria-label="$i18n{endTime}"> + [[getTimeString_(endTime_, shouldUse24Hours_)]] + </div> + </div> + <div id="sliderBar"> + <div id="progressContainer"> + <div id="endProgress" class="progress"></div> + <div id="startProgress" class="progress"></div> + </div> + <div id="markersContainer"> + </div> + <div id="startKnob" class="knob" tabindex="1" on-down="startDrag_" + on-up="endDrag_" on-track="continueDrag_"> + <div class="knob-inner" tabindex="-1"></div> + </div> + <div id="endKnob" class="knob" tabindex="2" on-down="startDrag_" + on-up="endDrag_" on-track="continueDrag_"> + <div class="knob-inner" tabindex="-1"></div> + </div> + </div> + <div id="legendContainer"> + <div style="[[getLegendStyle_(0, isRTL_)]]"> + [[getLocaleTimeString_(18, 0, shouldUse24Hours_)]] + </div> + <div style="[[getLegendStyle_(25, isRTL_)]]"> + [[getLocaleTimeString_(0, 0, shouldUse24Hours_)]] + </div> + <div style="[[getLegendStyle_(50, isRTL_)]]"> + [[getLocaleTimeString_(6, 0, shouldUse24Hours_)]] + </div> + <div style="[[getLegendStyle_(75, isRTL_)]]"> + [[getLocaleTimeString_(12, 0, shouldUse24Hours_)]] + </div> + <div style="[[getLegendStyle_(100, isRTL_)]]"> + [[getLocaleTimeString_(18, 0, shouldUse24Hours_)]] + </div> + </div> + <div id="dummyRippleContainer" hidden></div> +</div> \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/device_page/night_light_slider.js b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.js similarity index 81% rename from chrome/browser/resources/settings/chromeos/device_page/night_light_slider.js rename to chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.js index 4fe7538..7b15067 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/night_light_slider.js +++ b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.js
@@ -2,15 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -(function() { - /** - * @fileoverview - * night-light-slider is used to set the custom automatic schedule of the - * Night Light feature, so that users can set their desired start and end - * times. + * @fileoverview settings-scheduler-slider is used to set the custom automatic + * schedule of the Night Light feature, so that users can set their desired + * start and end times. */ +import '../../settings_shared_css.js'; + +import {IronResizableBehavior} from '//resources/polymer/v3_0/iron-resizable-behavior/iron-resizable-behavior.js'; +import {PaperRippleBehavior} from '//resources/polymer/v3_0/paper-behaviors/paper-ripple-behavior.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {PrefsBehavior} from '../../prefs/prefs_behavior.js'; + const HOURS_PER_DAY = 24; const MIN_KNOBS_DISTANCE_MINUTES = 60; const OFFSET_MINUTES_6PM = 18 * 60; @@ -38,15 +43,37 @@ } Polymer({ - is: 'night-light-slider', + + _template: html`{__html_template__}`, + + is: 'settings-scheduler-slider', behaviors: [ PrefsBehavior, - Polymer.IronResizableBehavior, - Polymer.PaperRippleBehavior, + IronResizableBehavior, + PaperRippleBehavior, ], properties: { + + /** + * The start time pref object being tracked. + * @type {!chrome.settingsPrivate.PrefObject} + */ + prefStartTime: { + type: Object, + notify: true, + }, + + /** + * The end time pref object being tracked. + * @type {!chrome.settingsPrivate.PrefObject} + */ + prefEndTime: { + type: Object, + notify: true, + }, + /** * Whether the element is ready and fully rendered. * @private @@ -65,6 +92,18 @@ * @private */ shouldUse24Hours_: Boolean, + + /** + * Start time in minute of the slider. + * @private + */ + startTime_: Number, + + /** + * End time in minute of the slider. + * @private + */ + endTime_: Number, }, listeners: { @@ -75,11 +114,9 @@ }, observers: [ - 'updateKnobs_(prefs.ash.night_light.custom_start_time.*, ' + - 'prefs.ash.night_light.custom_end_time.*, isRTL_, isReady_)', + 'updateKnobs_(prefs.*, isRTL_, isReady_)', 'hourFormatChanged_(prefs.settings.clock.use_24hour_clock.*)', - 'updateMarkers_(prefs.ash.night_light.custom_start_time.*, ' + - 'prefs.ash.night_light.custom_end_time.*, isRTL_, isReady_)', + 'updateMarkers_(prefs.*, isRTL_, isReady_)', ], /** @@ -90,9 +127,14 @@ dragObject_: null, /** @override */ + ready() { + this.startTime_ = /** @type {number} */ (this.prefStartTime.value); + this.endTime_ = /** @type {number} */ (this.prefEndTime.value); + }, + + /** @override */ attached() { this.isRTL_ = window.getComputedStyle(this).direction === 'rtl'; - this.$.sliderContainer.addEventListener('contextmenu', function(e) { // Prevent the context menu from interfering with dragging the knobs using // touch. @@ -114,9 +156,8 @@ * @private */ prefsAvailable() { - return ['custom_start_time', 'custom_end_time'] - .map(key => `prefs.ash.night_light.${key}.value`) - .every(path => this.get(path) !== undefined); + return [this.prefStartTime, this.prefEndTime].every( + pref => pref !== undefined); }, /** @private */ @@ -125,13 +166,8 @@ return; } - const startHour = - /** @type {number} */ ( - this.getPref('ash.night_light.custom_start_time').value) / - 60.0; - const endHour = /** @type {number} */ ( - this.getPref('ash.night_light.custom_end_time').value) / - 60.0; + const startHour = (/** @type {number} */ (this.prefStartTime.value)) / 60.0; + const endHour = (/** @type {number} */ (this.prefEndTime.value)) / 60.0; const markersContainer = this.$.markersContainer; markersContainer.innerHTML = ''; @@ -156,6 +192,24 @@ }, /** + * Return true if the start knob is focused. + * @return {boolean} + * @private + */ + isStartKnobFocused_() { + return (this.shadowRoot.activeElement === this.$.startKnob); + }, + + /** + * Return true if the end knob is focused. + * @return {boolean} + * @private + */ + isEndKnobFocused_() { + return (this.shadowRoot.activeElement === this.$.endKnob); + }, + + /** * Invoked when the element is resized and the knobs positions need to be * updated. * @private @@ -191,10 +245,8 @@ * @private */ blurAnyFocusedKnob_() { - const activeElement = this.shadowRoot.activeElement; - if (activeElement === this.$.startKnob || - activeElement === this.$.endKnob) { - activeElement.blur(); + if (this.isEitherKnobFocused_()) { + this.shadowRoot.activeElement.blur(); } }, @@ -211,17 +263,17 @@ if (event.target === this.$.startKnob || event.target === this.$.startKnob.firstElementChild) { this.dragObject_ = this.$.startKnob; + this.valueAtDragStart_ = this.prefStartTime.value; } else if ( event.target === this.$.endKnob || event.target === this.$.endKnob.firstElementChild) { this.dragObject_ = this.$.endKnob; + this.valueAtDragStart_ = this.prefEndTime.value; } else { return; } this.handleKnobEvent_(event, this.dragObject_); - - this.valueAtDragStart_ = this.getPrefValue_(this.dragObject_); }, /** @@ -337,7 +389,6 @@ getTimeString_(offsetMinutes, shouldUse24Hours) { const hour = Math.floor(offsetMinutes / 60); const minute = Math.floor(offsetMinutes % 60); - return this.getLocaleTimeString_(hour, minute, shouldUse24Hours); }, @@ -351,12 +402,19 @@ this.$.sliderBar.offsetWidth === 0) { return; } - const startOffsetMinutes = /** @type {number} */ ( - this.getPref('ash.night_light.custom_start_time').value); + + /** @type {number} */ + const startOffsetMinutes = + /** @type {number} */ (this.prefStartTime.value); this.updateKnobLeft_(this.$.startKnob, startOffsetMinutes); - const endOffsetMinutes = /** @type {number} */ ( - this.getPref('ash.night_light.custom_end_time').value); + this.startTime_ = startOffsetMinutes; + + /** @type {number} */ + const endOffsetMinutes = + /** @type {number} */ (this.prefEndTime.value); this.updateKnobLeft_(this.$.endKnob, endOffsetMinutes); + this.endTime_ = endOffsetMinutes; + this.refresh_(); }, @@ -449,20 +507,16 @@ }, /** - * Given the |prefPath| that corresponds to one knob time, it gets the value - * of the pref that corresponds to the other knob. - * @param {string} prefPath + * Return the value of the pref that corresponds to the other knob than + * `this.shadowRoot.activeElement` * @return {number} * @private */ - getOtherKnobPrefValue_(prefPath) { - if (prefPath === 'ash.night_light.custom_start_time') { - return /** @type {number} */ ( - this.getPref('ash.night_light.custom_end_time').value); + getOtherKnobPrefValue_() { + if (this.isStartKnobFocused_()) { + return /** @type {number} */ (this.prefEndTime.value); } - - return /** @type {number} */ ( - this.getPref('ash.night_light.custom_start_time').value); + return /** @type {number} */ (this.prefStartTime.value); }, /** @@ -494,8 +548,7 @@ * @private */ updatePref_(updatedValue, fromUserGesture) { - const prefPath = assert(this.getFocusedKnobPrefPathIfAny_()); - const otherValue = this.getOtherKnobPrefValue_(prefPath); + const otherValue = this.getOtherKnobPrefValue_(); const totalMinutes = TOTAL_MINUTES_PER_DAY; const minDistance = MIN_KNOBS_DISTANCE_MINUTES; @@ -506,24 +559,13 @@ } // The knobs are allowed to wrap around. - this.setPrefValue(prefPath, modulo(updatedValue, TOTAL_MINUTES_PER_DAY)); - }, - - /** - * @param {Element} knob - * @returns {?string} - * @private - */ - getPrefPath_(knob) { - if (knob === this.$.startKnob) { - return 'ash.night_light.custom_start_time'; + if (this.isStartKnobFocused_()) { + this.set( + 'prefStartTime.value', modulo(updatedValue, TOTAL_MINUTES_PER_DAY)); + } else if (this.isEndKnobFocused_()) { + this.set( + 'prefEndTime.value', modulo(updatedValue, TOTAL_MINUTES_PER_DAY)); } - - if (knob === this.$.endKnob) { - return 'ash.night_light.custom_end_time'; - } - - return null; }, /** @@ -531,19 +573,14 @@ * @returns {?number} * @private */ - getPrefValue_(knob) { - const path = this.getPrefPath_(knob); - return path ? /** @type {number} */ (this.getPref(path).value) : null; - }, - - /** - * Gets the pref path of the currently focused knob. Returns null if no knob - * is currently focused. - * @return {?string} - * @private - */ - getFocusedKnobPrefPathIfAny_() { - return this.getPrefPath_(this.shadowRoot.activeElement); + getPrefValue(knob) { + if (this.isStartKnobFocused_()) { + return /** @type {number} */ (this.prefStartTime.value); + } else if (this.isEndKnobFocused_()) { + return /** @type {number} */ (this.prefEndTime.value); + } else { + return null; + } }, /** @@ -551,9 +588,7 @@ * @private */ isEitherKnobFocused_() { - const activeElement = this.shadowRoot.activeElement; - return activeElement === this.$.startKnob || - activeElement === this.$.endKnob; + return this.isStartKnobFocused_() || this.isEndKnobFocused_(); }, /** @@ -572,7 +607,7 @@ // to be created under a hidden element. this._rippleContainer = this.$.dummyRippleContainer; } - const ripple = Polymer.PaperRippleBehavior._createRipple(); + const ripple = PaperRippleBehavior._createRipple(); ripple.id = 'ink'; ripple.setAttribute('recenters', ''); ripple.classList.add('circle', 'toggle-ink'); @@ -642,13 +677,13 @@ onKeyDown_(event) { const activeElement = this.shadowRoot.activeElement; if (event.key === 'Tab') { - if (event.shiftKey && this.$.endKnob === activeElement) { + if (event.shiftKey && this.isEndKnobFocused_()) { event.preventDefault(); this.handleKnobEvent_(event, this.$.startKnob); return; } - if (!event.shiftKey && this.$.startKnob === activeElement) { + if (!event.shiftKey && this.isStartKnobFocused_()) { event.preventDefault(); this.handleKnobEvent_(event, this.$.endKnob); } @@ -672,8 +707,8 @@ this.handleKnobEvent_(event); event.preventDefault(); - const value = this.getPrefValue_(activeElement); - if (value == null) { + const value = this.getPrefValue(activeElement); + if (value === null) { return; } @@ -682,4 +717,3 @@ } }, }); -})();
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc index ebf17544..e3a4e48 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc
@@ -51,6 +51,9 @@ #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" +// Needed for QueryUnbiasedInterruptTime and other Windows functions. +#include <windows.h> + using content::BrowserThread; namespace safe_browsing {
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win_unittest.cc index d5b5ec3..582ae94 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win_unittest.cc
@@ -23,6 +23,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" +#include <windows.h> + using ::testing::AssertionFailure; using ::testing::AssertionResult; using ::testing::AssertionSuccess;
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc index c9ae705..e5f89c72d 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/safe_browsing/client_side_detection_host_delegate.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" @@ -23,13 +25,15 @@ void SetUp() override { BrowserWithTestWindowTest::SetUp(); AddTab(browser(), GURL("http://foo/0")); - content::BrowserContext* browser_context = - browser()->tab_strip_model()->GetWebContentsAt(0)->GetBrowserContext(); + Profile* profile = Profile::FromBrowserContext( + browser()->tab_strip_model()->GetWebContentsAt(0)->GetBrowserContext()); navigation_observer_manager_ = SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( - browser_context); + profile); navigation_observer_ = new SafeBrowsingNavigationObserver( - browser()->tab_strip_model()->GetWebContentsAt(0)); + browser()->tab_strip_model()->GetWebContentsAt(0), + HostContentSettingsMapFactory::GetForProfile(profile), + navigation_observer_manager_); scoped_feature_list_.InitAndEnableFeature( kClientSideDetectionReferrerChain); }
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index 4c9451c6..e20ad66b 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -36,6 +36,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/enterprise/connectors/connectors_service.h" #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h" #include "chrome/browser/history/history_service_factory.h" @@ -54,6 +55,7 @@ #include "chrome/browser/safe_browsing/download_protection/ppapi_download_request.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h" +#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/test_extension_event_observer.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" @@ -3004,7 +3006,11 @@ TEST_F(DownloadProtectionServiceTest, VerifyReferrerChainLengthForExtendedReporting) { - SafeBrowsingNavigationObserver::MaybeCreateForWebContents(web_contents()); + SafeBrowsingNavigationObserver::MaybeCreateForWebContents( + web_contents(), HostContentSettingsMapFactory::GetForProfile(profile()), + SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( + profile()), + profile()->GetPrefs(), g_browser_process->safe_browsing_service()); // Simulate 6 user interactions SimulateLinkClick(GURL("http://example.com/0"));
diff --git a/chrome/browser/safe_browsing/incident_reporting/platform_state_store_win_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/platform_state_store_win_unittest.cc index 90ddf1fd1..3fd9d90 100644 --- a/chrome/browser/safe_browsing/incident_reporting/platform_state_store_win_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/platform_state_store_win_unittest.cc
@@ -21,6 +21,8 @@ #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +#include <windows.h> + namespace safe_browsing { namespace platform_state_store {
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc index 04d19853..fe88782 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
@@ -7,12 +7,7 @@ #include <memory> #include "base/time/time.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" -#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" -#include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "components/page_info/page_info_ui.h" #include "components/sessions/content/session_tab_helper.h" #include "content/public/browser/browser_context.h" @@ -83,17 +78,20 @@ // static void SafeBrowsingNavigationObserver::MaybeCreateForWebContents( - content::WebContents* web_contents) { + content::WebContents* web_contents, + HostContentSettingsMap* host_content_settings_map, + SafeBrowsingNavigationObserverManager* observer_manager, + PrefService* prefs, + SafeBrowsingServiceInterface* safe_browsing_service) { if (FromWebContents(web_contents)) return; if (safe_browsing::SafeBrowsingNavigationObserverManager::IsEnabledAndReady( - Profile::FromBrowserContext(web_contents->GetBrowserContext()) - ->GetPrefs(), - g_browser_process->safe_browsing_service())) { + prefs, safe_browsing_service)) { web_contents->SetUserData( kWebContentsUserDataKey, - std::make_unique<SafeBrowsingNavigationObserver>(web_contents)); + std::make_unique<SafeBrowsingNavigationObserver>( + web_contents, host_content_settings_map, observer_manager)); } } @@ -105,11 +103,12 @@ } SafeBrowsingNavigationObserver::SafeBrowsingNavigationObserver( - content::WebContents* contents) - : content::WebContentsObserver(contents) { - content_settings_observation_.Observe( - HostContentSettingsMapFactory::GetForProfile( - Profile::FromBrowserContext(web_contents()->GetBrowserContext()))); + content::WebContents* contents, + HostContentSettingsMap* host_content_settings_map, + SafeBrowsingNavigationObserverManager* observer_manager) + : content::WebContentsObserver(contents), + observer_manager_(observer_manager) { + content_settings_observation_.Observe(host_content_settings_map); } SafeBrowsingNavigationObserver::~SafeBrowsingNavigationObserver() {} @@ -319,18 +318,12 @@ SafeBrowsingNavigationObserverManager* SafeBrowsingNavigationObserver::GetObserverManager() { - if (observer_manager_for_testing_) { - return observer_manager_for_testing_; - } - content::BrowserContext* browser_context = - web_contents()->GetBrowserContext(); - return safe_browsing::SafeBrowsingNavigationObserverManagerFactory:: - GetForBrowserContext(browser_context); + return observer_manager_; } void SafeBrowsingNavigationObserver::SetObserverManagerForTesting( SafeBrowsingNavigationObserverManager* observer_manager) { - observer_manager_for_testing_ = observer_manager; + observer_manager_ = observer_manager; } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h index 1353188..a6c481d 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h
@@ -23,6 +23,7 @@ namespace safe_browsing { class SafeBrowsingNavigationObserverManager; +class SafeBrowsingServiceInterface; // Struct to record the details of a navigation event for any frame. // This information will be used to fill referrer chain info in various Safe @@ -103,12 +104,19 @@ public content_settings::Observer { public: static void MaybeCreateForWebContents( - content::WebContents* web_contents); + content::WebContents* web_contents, + HostContentSettingsMap* host_content_settings_map, + SafeBrowsingNavigationObserverManager* observer_manager, + PrefService* prefs, + SafeBrowsingServiceInterface* safe_browsing_service); static SafeBrowsingNavigationObserver* FromWebContents( content::WebContents* web_contents); - explicit SafeBrowsingNavigationObserver(content::WebContents* contents); + SafeBrowsingNavigationObserver( + content::WebContents* contents, + HostContentSettingsMap* host_content_settings_map, + SafeBrowsingNavigationObserverManager* observer_manager); ~SafeBrowsingNavigationObserver() override; @@ -159,8 +167,7 @@ base::ScopedObservation<HostContentSettingsMap, content_settings::Observer> content_settings_observation_{this}; - SafeBrowsingNavigationObserverManager* observer_manager_for_testing_ = - nullptr; + SafeBrowsingNavigationObserverManager* observer_manager_ = nullptr; DISALLOW_COPY_AND_ASSIGN(SafeBrowsingNavigationObserver); };
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc index e7b57e7..f629164 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -9,11 +9,13 @@ #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" +#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -181,7 +183,12 @@ void ObserveContents(content::WebContents* contents) { ASSERT_TRUE(contents); - auto observer = std::make_unique<SafeBrowsingNavigationObserver>(contents); + Profile* profile = + Profile::FromBrowserContext(contents->GetBrowserContext()); + auto observer = std::make_unique<SafeBrowsingNavigationObserver>( + contents, HostContentSettingsMapFactory::GetForProfile(profile), + safe_browsing::SafeBrowsingNavigationObserverManagerFactory:: + GetForBrowserContext(profile)); observer->SetObserverManagerForTesting(this); observer_list_.push_back(std::move(observer)); inner_contents_creation_observers_.push_back( @@ -2951,6 +2958,42 @@ } IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, + AllowlistDomainsRemoved_ServerRedirect) { + ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL(kSingleFrameTestURL)); + GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); + GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); + GURL request_url = + embedded_test_server()->GetURL("/server-redirect?" + download_url.spec()); + ui_test_utils::NavigateToURL(browser(), request_url); + std::string test_server_ip(embedded_test_server()->host_port_pair().host()); + + // Add URLs to the Safe Browsing allowlist. + base::ListValue allowlist; + allowlist.AppendString(initial_url.host()); + allowlist.AppendString(download_url.host()); + allowlist.AppendString(request_url.host()); + browser()->profile()->GetPrefs()->Set(prefs::kSafeBrowsingAllowlistDomains, + allowlist); + + ReferrerChain referrer_chain; + IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); + ASSERT_EQ(1, referrer_chain.size()); + EXPECT_TRUE(referrer_chain.Get(0).is_url_removed_by_policy()); + // All URL fields should be empty because they all match the allowlist. + VerifyReferrerChainEntry(GURL(), // url + GURL(), // main_frame_url + ReferrerChainEntry::EVENT_URL, // type + test_server_ip, // ip_address + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + {GURL(), GURL()}, // server redirects + ReferrerChainEntry::BROWSER_INITIATED, + referrer_chain.Get(0)); +} + +IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, AllowlistDomainsRemoved_RecentNavigation) { ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL(kSingleFrameTestURL));
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc index 80a75cb..4a08421 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
@@ -808,6 +808,15 @@ entry.clear_referrer_main_frame_url(); is_url_removed_by_policy = true; } + for (ReferrerChainEntry::ServerRedirect& server_redirect_entry : + *entry.mutable_server_redirect_chain()) { + if (IsURLAllowlistedByPolicy(GURL(server_redirect_entry.url()), + *pref_service_)) { + server_redirect_entry.clear_url(); + is_url_removed_by_policy = true; + } + } + entry.set_is_url_removed_by_policy(is_url_removed_by_policy); } }
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc index c501564..c0a57c8e 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
@@ -7,6 +7,8 @@ #include <memory> #include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -29,13 +31,15 @@ void SetUp() override { BrowserWithTestWindowTest::SetUp(); AddTab(browser(), GURL("http://foo/0")); - content::BrowserContext* browser_context = - browser()->tab_strip_model()->GetWebContentsAt(0)->GetBrowserContext(); + Profile* profile = Profile::FromBrowserContext( + browser()->tab_strip_model()->GetWebContentsAt(0)->GetBrowserContext()); navigation_observer_manager_ = SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( - browser_context); + profile); navigation_observer_ = new SafeBrowsingNavigationObserver( - browser()->tab_strip_model()->GetWebContentsAt(0)); + browser()->tab_strip_model()->GetWebContentsAt(0), + HostContentSettingsMapFactory::GetForProfile(profile), + navigation_observer_manager_); } void TearDown() override { delete navigation_observer_;
diff --git a/chrome/browser/safe_browsing/ui_manager_unittest.cc b/chrome/browser/safe_browsing/ui_manager_unittest.cc index d455b05..74e6a6c 100644 --- a/chrome/browser/safe_browsing/ui_manager_unittest.cc +++ b/chrome/browser/safe_browsing/ui_manager_unittest.cc
@@ -608,4 +608,13 @@ } #endif +TEST_F(SafeBrowsingUIManagerTest, InvalidRenderFrameHostId) { + security_interstitials::UnsafeResource resource = + MakeUnsafeResourceAndStartNavigation(kBadURL); + resource.web_contents_getter = security_interstitials::GetWebContentsGetter( + web_contents()->GetMainFrame()->GetProcess()->GetID(), -1); + + EXPECT_FALSE(IsAllowlisted(resource)); +} + } // namespace safe_browsing
diff --git a/chrome/app/shutdown_signal_handlers_posix.cc b/chrome/browser/shutdown_signal_handlers_posix.cc similarity index 98% rename from chrome/app/shutdown_signal_handlers_posix.cc rename to chrome/browser/shutdown_signal_handlers_posix.cc index 621d441..ccc39d4 100644 --- a/chrome/app/shutdown_signal_handlers_posix.cc +++ b/chrome/browser/shutdown_signal_handlers_posix.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/app/shutdown_signal_handlers_posix.h" +#include "chrome/browser/shutdown_signal_handlers_posix.h" #include <limits.h> #include <signal.h>
diff --git a/chrome/app/shutdown_signal_handlers_posix.h b/chrome/browser/shutdown_signal_handlers_posix.h similarity index 79% rename from chrome/app/shutdown_signal_handlers_posix.h rename to chrome/browser/shutdown_signal_handlers_posix.h index 0724a74..7fb563a 100644 --- a/chrome/app/shutdown_signal_handlers_posix.h +++ b/chrome/browser/shutdown_signal_handlers_posix.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_APP_SHUTDOWN_SIGNAL_HANDLERS_POSIX_H_ -#define CHROME_APP_SHUTDOWN_SIGNAL_HANDLERS_POSIX_H_ +#ifndef CHROME_BROWSER_SHUTDOWN_SIGNAL_HANDLERS_POSIX_H_ +#define CHROME_BROWSER_SHUTDOWN_SIGNAL_HANDLERS_POSIX_H_ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" @@ -19,4 +19,4 @@ base::OnceCallback<void(int)> shutdown_callback, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); -#endif // CHROME_APP_SHUTDOWN_SIGNAL_HANDLERS_POSIX_H_ +#endif // CHROME_BROWSER_SHUTDOWN_SIGNAL_HANDLERS_POSIX_H_
diff --git a/chrome/browser/signin/signin_util.cc b/chrome/browser/signin/signin_util.cc index 52281e54..19014b7 100644 --- a/chrome/browser/signin/signin_util.cc +++ b/chrome/browser/signin/signin_util.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "base/supports_user_data.h" #include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" @@ -47,7 +48,6 @@ namespace { constexpr char kSignoutSettingKey[] = "signout_setting"; -constexpr char kGuestSignedInUserDataKey[] = "guest_signin"; #if defined(CAN_DELETE_PROFILE) // Manager that presents the profile will be deleted dialog on the first active @@ -270,27 +270,4 @@ #endif // !BUILDFLAG(IS_CHROMEOS_ASH) } -// TODO(crbug.com/1134111): Remove GuestSignedInUserData when Ephemeral Guest -// sign in functioncality is implemented. -void GuestSignedInUserData::SetIsSignedIn(Profile* profile, bool is_signed_in) { - GuestSignedInUserData* data = GetForProfile(profile); - data->is_signed_in_ = is_signed_in; -} - -bool GuestSignedInUserData::IsSignedIn(Profile* profile) { - return GetForProfile(profile)->is_signed_in_; -} - -GuestSignedInUserData* GuestSignedInUserData::GetForProfile(Profile* profile) { - GuestSignedInUserData* data = static_cast<GuestSignedInUserData*>( - profile->GetUserData(kGuestSignedInUserDataKey)); - if (!data) { - profile->SetUserData(kGuestSignedInUserDataKey, - std::make_unique<GuestSignedInUserData>()); - data = static_cast<GuestSignedInUserData*>( - profile->GetUserData(kGuestSignedInUserDataKey)); - } - return data; -} - } // namespace signin_util
diff --git a/chrome/browser/signin/signin_util.h b/chrome/browser/signin/signin_util.h index 4477e8c..d2fccfd4 100644 --- a/chrome/browser/signin/signin_util.h +++ b/chrome/browser/signin/signin_util.h
@@ -5,25 +5,10 @@ #ifndef CHROME_BROWSER_SIGNIN_SIGNIN_UTIL_H_ #define CHROME_BROWSER_SIGNIN_SIGNIN_UTIL_H_ -#include "base/supports_user_data.h" - class Profile; namespace signin_util { -// TODO(crbug.com/1134111): Remove GuestSignedInUserData when Ephemeral Guest -// sign in functioncality is implemented. -class GuestSignedInUserData : public base::SupportsUserData::Data { - public: - static void SetIsSignedIn(Profile* profile, bool is_signed_in); - static bool IsSignedIn(Profile* profile); - - private: - static GuestSignedInUserData* GetForProfile(Profile* profile); - - bool is_signed_in_ = false; -}; - // This class calls ResetForceSigninForTesting when destroyed, so that // ForcedSigning doesn't leak across tests. class ScopedForceSigninSetterForTesting {
diff --git a/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc b/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc index cfc0b3f..83c9ce5 100644 --- a/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc
@@ -163,7 +163,8 @@ IN_PROC_BROWSER_TEST_F(SingleClientWebAppsSyncTest, AppWithValidIdSyncInstalled) { GURL url("https://example.com/"); - const std::string app_id = web_app::GenerateAppIdFromURL(url); + const std::string app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, url); InjectWebAppEntityToFakeServer(app_id, url); ASSERT_TRUE(SetupSync()); AwaitWebAppQuiescence(); @@ -177,7 +178,8 @@ IN_PROC_BROWSER_TEST_F(SingleClientWebAppsSyncTest, PRE_BookmarkAppNotSyncInstalled) { std::string url = "https://example.com/"; - const std::string app_id = web_app::GenerateAppIdFromURL(GURL(url)); + const std::string app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(url)); InjectBookmarkAppEntityToFakeServer(app_id, url); ASSERT_TRUE(SetupSync()); AwaitWebAppQuiescence(); @@ -193,7 +195,8 @@ IN_PROC_BROWSER_TEST_F(SingleClientWebAppsSyncTest, BookmarkAppNotSyncInstalled) { std::string url = "https://example.com/"; - const std::string app_id = web_app::GenerateAppIdFromURL(GURL(url)); + const std::string app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(url)); ASSERT_TRUE(SetupSync()); AwaitWebAppQuiescence(); auto* web_app_registrar = web_app::WebAppProvider::Get(GetProfile(0)) @@ -263,8 +266,8 @@ const web_app::AppId installed_app_id = apps_helper::InstallWebApp(GetProfile(0), info); - const std::string expected_app_id = - web_app::GenerateAppIdFromURL(GURL("https://example.com/explicit_id")); + const std::string expected_app_id = web_app::GenerateAppId( + /*manifest_id=*/absl::nullopt, GURL("https://example.com/explicit_id")); EXPECT_EQ(expected_app_id, installed_app_id); } @@ -293,8 +296,8 @@ const web_app::AppId installed_app_id = apps_helper::InstallWebApp(GetProfile(0), info); - const std::string expected_app_id = - web_app::GenerateAppIdFromURL(GURL("https://example.com/")); + const std::string expected_app_id = web_app::GenerateAppId( + /*manifest_id=*/absl::nullopt, GURL("https://example.com/")); EXPECT_EQ(expected_app_id, installed_app_id); } } // namespace
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn index 9df817b..a6c16cd 100644 --- a/chrome/browser/tab/BUILD.gn +++ b/chrome/browser/tab/BUILD.gn
@@ -13,6 +13,7 @@ "java/src/org/chromium/chrome/browser/tab/SadTab.java", "java/src/org/chromium/chrome/browser/tab/SadTabView.java", "java/src/org/chromium/chrome/browser/tab/Tab.java", + "java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java", "java/src/org/chromium/chrome/browser/tab/TabAttributeKeys.java", "java/src/org/chromium/chrome/browser/tab/TabAttributes.java", "java/src/org/chromium/chrome/browser/tab/TabCreationState.java", @@ -135,16 +136,21 @@ android_library("junit") { bypass_platform_checks = true testonly = true - sources = - [ "java/src/org/chromium/chrome/browser/tab/CurrentTabObserverTest.java" ] + sources = [ + "java/src/org/chromium/chrome/browser/tab/CurrentTabObserverTest.java", + "java/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java", + ] deps = [ ":java", "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//content/public/android:content_full_java", "//third_party/android_deps:robolectric_all_java", + "//third_party/android_support_test_runner:runner_java", "//third_party/junit", "//third_party/mockito:mockito_java", + "//ui/android:ui_no_recycler_view_java", ] }
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/DEPS b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/DEPS index 898a922..c45a072ea 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/DEPS +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/DEPS
@@ -3,6 +3,7 @@ include_rules = [ "-chrome", "+base/android/java/src/org/chromium/base", + "+base/test/android/junit", "+chrome/browser/android/crypto/java", "+chrome/browser/contextmenu/java", "+chrome/browser/endpoint_fetcher",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java similarity index 100% rename from chrome/android/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java rename to chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java similarity index 100% rename from chrome/android/junit/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java rename to chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java
diff --git a/chrome/browser/translate/chrome_translate_client.cc b/chrome/browser/translate/chrome_translate_client.cc index fd23550..9450e8b 100644 --- a/chrome/browser/translate/chrome_translate_client.cc +++ b/chrome/browser/translate/chrome_translate_client.cc
@@ -258,7 +258,7 @@ DCHECK(TranslateService::IsTranslateBubbleEnabled()); // Bubble UI. if (step == translate::TRANSLATE_STEP_BEFORE_TRANSLATE && - translate_manager_->ShouldSuppressBubbleUI()) { + translate_manager_->ShouldSuppressBubbleUI(target_language)) { return false; }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 4ff17c7..73e6c9d9 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1446,8 +1446,6 @@ "webui/ntp/cookie_controls_handler.h", "webui/ntp/core_app_launcher_handler.cc", "webui/ntp/core_app_launcher_handler.h", - "webui/ntp/ephemeral_guest_signin_handler.cc", - "webui/ntp/ephemeral_guest_signin_handler.h", "webui/ntp/new_tab_ui.cc", "webui/ntp/new_tab_ui.h", "webui/ntp/ntp_resource_cache.cc", @@ -2716,6 +2714,7 @@ "//ash/public/cpp/app_list/vector_icons", "//ash/public/cpp/resources:ash_public_unscaled_resources", "//ash/quick_pair/common", + "//ash/quick_pair/ui", "//ash/services/recording/public/mojom", "//ash/shortcut_viewer", "//ash/webui/diagnostics_ui",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java index b63623b..0e92713 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java
@@ -73,7 +73,6 @@ import org.chromium.chrome.browser.profiles.ProfileJni; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.toolbar.VoiceToolbarButtonController; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; @@ -229,6 +228,7 @@ private LocationBarMediator mMediator; private LocationBarMediator mTabletMediator; private UrlBarData mUrlBarData; + private boolean mIsToolbarMicEnabled; @Before public void setUp() { @@ -248,8 +248,8 @@ mLocationBarLayout, mLocationBarDataProvider, mProfileSupplier, mPrivacyPreferencesManager, mOverrideUrlLoadingDelegate, mLocaleManager, mTemplateUrlServiceSupplier, mOverrideBackKeyBehaviorDelegate, mWindowAndroid, - /*isTablet=*/false, mSearchEngineLogoUtils, mLensController, noAction, tab -> true, - (tab, transition) -> {}, VoiceToolbarButtonController::isToolbarMicEnabled); + /*isTablet=*/false, mSearchEngineLogoUtils, mLensController, noAction, + tab -> true, (tab, transition) -> {}, () -> mIsToolbarMicEnabled); mMediator.setCoordinators(mUrlCoordinator, mAutocompleteCoordinator, mStatusCoordinator); ObjectAnimatorShadow.setUrlAnimator(mUrlAnimator); GSAStateShadow.setGSAState(mGSAState); @@ -258,8 +258,8 @@ mLocationBarTablet, mLocationBarDataProvider, mProfileSupplier, mPrivacyPreferencesManager, mOverrideUrlLoadingDelegate, mLocaleManager, mTemplateUrlServiceSupplier, mOverrideBackKeyBehaviorDelegate, mWindowAndroid, - /*isTablet=*/true, mSearchEngineLogoUtils, mLensController, noAction, tab -> true, - (tab, transition) -> {}, VoiceToolbarButtonController::isToolbarMicEnabled); + /*isTablet=*/true, mSearchEngineLogoUtils, mLensController, noAction, + tab -> true, (tab, transition) -> {}, () -> mIsToolbarMicEnabled); mTabletMediator.setCoordinators( mUrlCoordinator, mAutocompleteCoordinator, mStatusCoordinator); } @@ -906,10 +906,10 @@ } @Test - @Features.EnableFeatures(ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR) - public void testButtonVisibility_toolbarMicEnabled_phone() { + public void testButtonVisibility_phone_toolbarMicEnabled() { // Regression test for phones: toolbar mic visibility shouldn't impact the location // bar mic. + mIsToolbarMicEnabled = true; verifyPhoneMicButtonVisibility(); } @@ -940,8 +940,8 @@ } @Test - @Features.EnableFeatures(ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR) public void testMicButtonVisibility_toolbarMicEnabled_tablet() { + mIsToolbarMicEnabled = true; verifyMicButtonVisibilityWhenFocusChanges(false); } @@ -981,8 +981,8 @@ } @Test - @Features.EnableFeatures(ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR) public void testButtonVisibility_showMicUnfocused_toolbarMicEnabled_tablet() { + mIsToolbarMicEnabled = true; verifyMicButtonVisibilityWhenShowMicUnfocused(false); }
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 8be2f10..a8c8d21 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3316,6 +3316,12 @@ <message name="IDS_READER_VIEW_TEXT_ALT" desc='Message shown on the reader mode button bar, to invite the user to tap to open a reader mode. Reader mode extracts content and removes clutter from a web page and puts the result in a panel making it easier to read. This is used when "Reader Mode for Accessibility" is available.'> Show simplified view </message> + <message name="IDS_READER_MODE_MESSAGE_TITLE" desc="Message shown on the reader mode prompt, to invite the user to tap to open a reader mode."> + View simplified page? + </message> + <message name="IDS_READER_MODE_MESSAGE_BUTTON" desc="The label for the button to open the current page in reader mode."> + View + </message> <message name="IDS_CONTENT_PROVIDER_SEARCH_DESCRIPTION" desc="Description for Chrome's entry in QSB's list of search suggestion providers [CHAR_LIMIT=32]"> Bookmarks and web history </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READER_MODE_MESSAGE_BUTTON.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READER_MODE_MESSAGE_BUTTON.png.sha1 new file mode 100644 index 0000000..f4dbdde --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READER_MODE_MESSAGE_BUTTON.png.sha1
@@ -0,0 +1 @@ +5c83572ae1fdb6b24336b0f043e029341c15df0e \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READER_MODE_MESSAGE_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READER_MODE_MESSAGE_TITLE.png.sha1 new file mode 100644 index 0000000..f4dbdde --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READER_MODE_MESSAGE_TITLE.png.sha1
@@ -0,0 +1 @@ +5c83572ae1fdb6b24336b0f043e029341c15df0e \ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java index f293385..134860f 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java
@@ -228,18 +228,9 @@ /** Returns whether the feature flags allow showing the mic icon in the toolbar. */ public static boolean isToolbarMicEnabled() { if (!FeatureList.isInitialized()) return false; - if (AdaptiveToolbarFeatures.isSingleVariantModeEnabled()) { - return AdaptiveToolbarFeatures.getSingleVariantMode() - == AdaptiveToolbarButtonVariant.VOICE; - } else { - // For customization, we do not check the variant here, AdaptiveToolbarButtonController - // will check it by AdaptiveToolbarStatePredictor#recomputeUiState. We do not check here - // because AdaptiveToolbarStatePredictor#recomputeUiState depends on native - // initialization, to avoid race condition, we only check at one place, which is - // AdaptiveToolbarButtonController. - return ChromeFeatureList.isEnabled(ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR) - || AdaptiveToolbarFeatures.isCustomizationEnabled(); - } + return AdaptiveToolbarFeatures.isSingleVariantModeEnabled() + && AdaptiveToolbarFeatures.getSingleVariantMode() + == AdaptiveToolbarButtonVariant.VOICE; } private void notifyObservers(boolean hint) {
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonControllerUnitTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonControllerUnitTest.java index 161a1269..1a4cdd3 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonControllerUnitTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonControllerUnitTest.java
@@ -19,6 +19,7 @@ import android.graphics.drawable.Drawable; import android.view.View; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -28,9 +29,10 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.tab.Tab; @@ -46,10 +48,30 @@ import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.url.GURL; +import java.util.HashMap; +import java.util.Map; + /** Unit tests for {@link VoiceToolbarButtonController}. */ @RunWith(LocalRobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@Config(manifest = Config.NONE, + shadows = {VoiceToolbarButtonControllerUnitTest.ShadowChromeFeatureList.class}) public final class VoiceToolbarButtonControllerUnitTest { + // TODO(crbug.com/1199025): Remove this shadow. + @Implements(ChromeFeatureList.class) + static class ShadowChromeFeatureList { + private static final Map<String, String> sParamValues = new HashMap<>(); + + @Implementation + public static String getFieldTrialParamByFeature(String feature, String paramKey) { + Assert.assertTrue(ChromeFeatureList.isEnabled(feature)); + return sParamValues.getOrDefault(paramKey, ""); + } + + public static void reset() { + sParamValues.clear(); + } + } + private static final int WIDTH_DELTA = 50; @Rule @@ -80,6 +102,7 @@ @Before public void setUp() { MockitoAnnotations.initMocks(this); + ShadowChromeFeatureList.reset(); mConfiguration.screenWidthDp = VoiceToolbarButtonController.DEFAULT_MIN_WIDTH_DP + WIDTH_DELTA; @@ -104,15 +127,14 @@ TrackerFactory.setTrackerForTests(mTracker); } - @EnableFeatures({ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR}) - @DisableFeatures({ChromeFeatureList.TOOLBAR_MIC_IPH_ANDROID, - ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) @Test + @DisableFeatures({ChromeFeatureList.TOOLBAR_MIC_IPH_ANDROID, + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION, + ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR}) + @EnableFeatures({ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR}) public void onConfigurationChanged_screenWidthChanged() { - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, false); - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_NONE); - assertTrue(mVoiceToolbarButtonController.get(mTab).canShow()); // Screen width shrinks below the threshold (e.g. screen rotated). @@ -130,13 +152,14 @@ assertTrue(mVoiceToolbarButtonController.get(mTab).canShow()); } + @Test + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION, + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, + ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR}) @EnableFeatures({ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR, ChromeFeatureList.TOOLBAR_MIC_IPH_ANDROID}) - @Test public void testIPHCommandHelper() { - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, false); - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_NONE); assertNull(mVoiceToolbarButtonController.get(/*tab*/ null) .getButtonSpec() .getIPHCommandBuilder()); @@ -152,13 +175,11 @@ } @Test - @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) @DisableFeatures({ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR, ChromeFeatureList.TOOLBAR_MIC_IPH_ANDROID}) + @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testIPHEvent() { - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, false); - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_NONE); doReturn(true).when(mTracker).shouldTriggerHelpUI( FeatureConstants.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_VOICE_SEARCH_FEATURE); @@ -170,26 +191,29 @@ } @Test + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) + @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) public void isToolbarMicEnabled_adaptiveButtons_nonVoice() { - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, true); - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_SHARE); - + ShadowChromeFeatureList.sParamValues.put("mode", AdaptiveToolbarFeatures.ALWAYS_NEW_TAB); assertFalse(VoiceToolbarButtonController.isToolbarMicEnabled()); } @Test + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) + @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) public void isToolbarMicEnabled_adaptiveButtons_voice() { - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, true); - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_VOICE); - + ShadowChromeFeatureList.sParamValues.put("mode", AdaptiveToolbarFeatures.ALWAYS_VOICE); assertTrue(VoiceToolbarButtonController.isToolbarMicEnabled()); } - @EnableFeatures({ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR}) @Test + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION, + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, + ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR}) + @EnableFeatures({ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR}) + // clang-format off public void isToolbarMicEnabled_toolbarMic() { - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, false); - + // clang-format on assertTrue(VoiceToolbarButtonController.isToolbarMicEnabled()); } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveButtonActionMenuCoordinatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveButtonActionMenuCoordinatorTest.java index d3d95f0..3a6e68c 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveButtonActionMenuCoordinatorTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveButtonActionMenuCoordinatorTest.java
@@ -13,7 +13,6 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.filters.SmallTest; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; @@ -55,9 +54,6 @@ @Mock private Callback<Integer> mCallback; - @Before - public void setUp() {} - @Test @SmallTest @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR})
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java index cd630a1..66dbb8a 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java
@@ -116,11 +116,6 @@ != AdaptiveToolbarButtonVariant.NONE : "must not provide NONE button provider"; mButtonDataProviderMap.put(variant, buttonProvider); - - if (AdaptiveToolbarFeatures.isSingleVariantModeEnabled() - && variant == AdaptiveToolbarFeatures.getSingleVariantMode()) { - setSingleProvider(buttonProvider); - } } @Override @@ -217,18 +212,25 @@ @Override public void onFinishNativeInitialization() { - if (!AdaptiveToolbarFeatures.isCustomizationEnabled()) return; - new AdaptiveToolbarStatePredictor().recomputeUiState(uiState -> { - setSingleProvider(uiState.canShowUi - ? mButtonDataProviderMap.get(uiState.toolbarButtonState) - : null); - notifyObservers(uiState.canShowUi); - }); + if (AdaptiveToolbarFeatures.isSingleVariantModeEnabled()) { + @AdaptiveToolbarButtonVariant + int variant = AdaptiveToolbarFeatures.getSingleVariantMode(); + setSingleProvider(mButtonDataProviderMap.get(variant)); + } else if (AdaptiveToolbarFeatures.isCustomizationEnabled()) { + new AdaptiveToolbarStatePredictor().recomputeUiState(uiState -> { + setSingleProvider(uiState.canShowUi + ? mButtonDataProviderMap.get(uiState.toolbarButtonState) + : null); + notifyObservers(uiState.canShowUi); + }); + // We need the menu handler only if the customization feature is on. + if (mMenuHandler != null) return; + mMenuHandler = createMenuHandler(); + if (mMenuHandler == null) return; + } else { + return; + } - // We need the menu handler only if the customization feature is on. - if (mMenuHandler != null) return; - mMenuHandler = createMenuHandler(); - if (mMenuHandler == null) return; // Clearing mOriginalButtonSpec forces a refresh of mButtonData on the next get() mOriginalButtonSpec = null; notifyObservers(mButtonData.canShow());
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java index 3f3a395c..b7eff14c 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java
@@ -32,11 +32,12 @@ import org.mockito.stubbing.Answer; import org.robolectric.Robolectric; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; import org.chromium.base.Callback; import org.chromium.base.metrics.test.ShadowRecordHistogram; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; @@ -55,12 +56,29 @@ import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.browser_ui.settings.SettingsLauncher; +import java.util.HashMap; +import java.util.Map; + /** Unit tests for the {@link AdaptiveToolbarButtonController} */ -@Config(manifest = Config.NONE, shadows = {ShadowRecordHistogram.class}) +@Config(manifest = Config.NONE, + shadows = {ShadowRecordHistogram.class, + AdaptiveToolbarButtonControllerTest.ShadowChromeFeatureList.class}) @RunWith(BaseRobolectricTestRunner.class) @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION) public class AdaptiveToolbarButtonControllerTest { + // TODO(crbug.com/1199025): Remove this shadow. + @Implements(ChromeFeatureList.class) + static class ShadowChromeFeatureList { + static final Map<String, String> sParamValues = new HashMap<>(); + + @Implementation + public static String getFieldTrialParamByFeature(String feature, String paramKey) { + Assert.assertTrue(ChromeFeatureList.isEnabled(feature)); + return sParamValues.getOrDefault(paramKey, ""); + } + } + @Rule public TestRule mProcessor = new Features.JUnitProcessor(); @@ -80,6 +98,7 @@ @Before public void setUp() { MockitoAnnotations.initMocks(this); + ShadowChromeFeatureList.sParamValues.clear(); ShadowRecordHistogram.reset(); AdaptiveToolbarFeatures.clearParsedParamsForTesting(); mButtonData = new ButtonDataImpl( @@ -100,8 +119,7 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testDestroy_alwaysNone() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_NONE); - + setModeParam(AdaptiveToolbarFeatures.ALWAYS_NONE); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); adaptiveToolbarButtonController.destroy(); @@ -114,9 +132,9 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testDestroy_alwaysNewTab() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_NEW_TAB); - + setModeParam(AdaptiveToolbarFeatures.ALWAYS_NEW_TAB); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); adaptiveToolbarButtonController.destroy(); verify(mNewTabButtonController).destroy(); @@ -130,9 +148,9 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testDestroy_alwaysShare() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_SHARE); - + setModeParam(AdaptiveToolbarFeatures.ALWAYS_SHARE); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); adaptiveToolbarButtonController.destroy(); verify(mNewTabButtonController).destroy(); @@ -146,9 +164,9 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testDestroy_alwaysVoice() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_VOICE); - + setModeParam(AdaptiveToolbarFeatures.ALWAYS_VOICE); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); adaptiveToolbarButtonController.destroy(); verify(mNewTabButtonController).destroy(); @@ -162,12 +180,13 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testGet_alwaysShare() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_SHARE); + setModeParam(AdaptiveToolbarFeatures.ALWAYS_SHARE); mButtonData.setButtonSpec(makeButtonSpec(AdaptiveToolbarButtonVariant.SHARE)); when(mShareButtonController.get(any())).thenReturn(mButtonData); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); ButtonData buttonData = adaptiveToolbarButtonController.get(mTab); adaptiveToolbarButtonController.destroy(); @@ -179,12 +198,13 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testGet_alwaysVoice() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_VOICE); + setModeParam(AdaptiveToolbarFeatures.ALWAYS_VOICE); mButtonData.setButtonSpec(makeButtonSpec(AdaptiveToolbarButtonVariant.VOICE)); when(mVoiceToolbarButtonController.get(any())).thenReturn(mButtonData); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); ButtonData buttonData = adaptiveToolbarButtonController.get(mTab); adaptiveToolbarButtonController.destroy(); @@ -196,13 +216,14 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testMetrics() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_SHARE); + setModeParam(AdaptiveToolbarFeatures.ALWAYS_SHARE); mButtonData.setCanShow(true); mButtonData.setEnabled(true); mButtonData.setButtonSpec(makeButtonSpec(AdaptiveToolbarButtonVariant.SHARE)); when(mShareButtonController.get(any())).thenReturn(mButtonData); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); ButtonData buttonData = adaptiveToolbarButtonController.get(mTab); Assert.assertEquals(1, @@ -231,9 +252,9 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testAddObserver_alwaysShare() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_SHARE); - + setModeParam(AdaptiveToolbarFeatures.ALWAYS_SHARE); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); adaptiveToolbarButtonController.destroy(); verify(mShareButtonController).addObserver(adaptiveToolbarButtonController); @@ -244,9 +265,9 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testAddObserver_alwaysVoice() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_VOICE); - + setModeParam(AdaptiveToolbarFeatures.ALWAYS_VOICE); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); adaptiveToolbarButtonController.destroy(); verify(mVoiceToolbarButtonController).addObserver(adaptiveToolbarButtonController); @@ -257,10 +278,11 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testButtonDataChanged() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_VOICE); + setModeParam(AdaptiveToolbarFeatures.ALWAYS_VOICE); ButtonDataObserver observer = mock(ButtonDataObserver.class); AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); adaptiveToolbarButtonController.addObserver(observer); adaptiveToolbarButtonController.buttonDataChanged(true); adaptiveToolbarButtonController.destroy(); @@ -271,7 +293,7 @@ @Test @SmallTest @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) - @DisableFeatures(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR) + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) public void testCustomization_newTab() { AdaptiveToolbarPrefs.saveToolbarSettingsToggleState(true); AdaptiveToolbarStatePredictor.setSegmentationResultsForTesting( @@ -293,7 +315,7 @@ @Test @SmallTest @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) - @DisableFeatures(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR) + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) public void testCustomization_share() { AdaptiveToolbarPrefs.saveToolbarSettingsToggleState(true); AdaptiveToolbarStatePredictor.setSegmentationResultsForTesting( @@ -315,7 +337,7 @@ @Test @SmallTest @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) - @DisableFeatures(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR) + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) public void testCustomization_voice() { AdaptiveToolbarPrefs.saveToolbarSettingsToggleState(true); AdaptiveToolbarStatePredictor.setSegmentationResultsForTesting( @@ -337,7 +359,7 @@ @Test @SmallTest @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) - @DisableFeatures(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR) + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) public void testCustomization_prefChangeTriggersButtonChange() { AdaptiveToolbarPrefs.saveToolbarSettingsToggleState(true); AdaptiveToolbarStatePredictor.setSegmentationResultsForTesting( @@ -366,10 +388,11 @@ @Test @SmallTest @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) - @DisableFeatures(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR) + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) public void testLongPress() { - CachedFeatureFlags.setForTesting(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, true); - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_NEW_TAB); + AdaptiveToolbarPrefs.saveToolbarSettingsToggleState(true); + AdaptiveToolbarStatePredictor.setSegmentationResultsForTesting( + new Pair<>(true, AdaptiveToolbarButtonVariant.NEW_TAB)); Activity activity = Robolectric.setupActivity(Activity.class); SettingsLauncher settingsLauncher = mock(SettingsLauncher.class); @@ -388,6 +411,8 @@ SharedPreferencesManager.getInstance()); adaptiveToolbarButtonController.addButtonVariant( AdaptiveToolbarButtonVariant.NEW_TAB, mNewTabButtonController); + adaptiveToolbarButtonController.onFinishNativeInitialization(); + mButtonData.setCanShow(true); mButtonData.setEnabled(true); mButtonData.setButtonSpec(makeButtonSpec(AdaptiveToolbarButtonVariant.NEW_TAB)); @@ -404,6 +429,40 @@ .launchSettingsActivity(activity, AdaptiveToolbarPreferenceFragment.class); } + @Test + @SmallTest + @EnableFeatures({ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR}) + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION, + ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR}) + public void + testLegacyVoiceToolbarFeature() { + AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); + + Assert.assertEquals(mVoiceToolbarButtonController, + adaptiveToolbarButtonController.getSingleProviderForTesting()); + } + + @Test + @SmallTest + @EnableFeatures({ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR}) + @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION, + ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR}) + public void + testLegacyShareToolbarFeature() { + AdaptiveToolbarButtonController adaptiveToolbarButtonController = buildController(); + adaptiveToolbarButtonController.onFinishNativeInitialization(); + + Assert.assertEquals(mShareButtonController, + adaptiveToolbarButtonController.getSingleProviderForTesting()); + } + + private static void setModeParam(String modeValue) { + ShadowChromeFeatureList.sParamValues.put("mode", modeValue); + } + private AdaptiveToolbarButtonController buildController() { AdaptiveToolbarButtonController adaptiveToolbarButtonController = new AdaptiveToolbarButtonController(mock(Activity.class),
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarFeatures.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarFeatures.java index 6c03a84..2786d09 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarFeatures.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarFeatures.java
@@ -9,17 +9,16 @@ import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.flags.StringCachedFieldTrialParameter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * A utility class for handling feature flags used by {@link AdaptiveToolbarButtonController}. - * TODO(shaktisahu): This class supports both the data collection and the customization experiment. - * Cleanup once the former is no longer needed. + * + * <p>TODO(shaktisahu): This class supports both the data collection and the customization + * experiment. Cleanup once the former is no longer needed. */ public class AdaptiveToolbarFeatures { /** Adaptive toolbar button is always empty. */ @@ -38,25 +37,21 @@ /** Finch default group for voice search variation. */ static final String VOICE = "voice"; - /** - * Finch param for which toolbar button to be shown. Should be deprecated after the data - * collection experiment. - */ - public static final StringCachedFieldTrialParameter MODE_PARAM = - new StringCachedFieldTrialParameter( - ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, "mode", ""); - /** Field trial params. */ private static final String VARIATION_PARAM_DEFAULT_SEGMENT = "default_segment"; + private static final String VARIATION_PARAM_DISABLE_UI = "disable_ui"; private static final String VARIATION_PARAM_IGNORE_SEGMENTATION_RESULTS = "ignore_segmentation_results"; - private static final String VARIATION_PARAM_DISABLE_UI = "disable_ui"; + private static final String VARIATION_PARAM_SINGLE_VARIANT_MODE = "mode"; private static final String VARIATION_PARAM_SHOW_UI_ONLY_AFTER_READY = "show_ui_only_after_ready"; /** Default value to use in case finch param isn't available for default segment. */ private static final String DEFAULT_PARAM_VALUE_DEFAULT_SEGMENT = NEW_TAB; + @AdaptiveToolbarButtonVariant + private static Integer sButtonVariant; + /** For testing only. */ private static String sDefaultSegmentForTesting; private static Boolean sIgnoreSegmentationResultsForTesting; @@ -65,6 +60,7 @@ /** * Unique identifiers for each of the possible button variants. + * * <p>These values are persisted to logs. Entries should not be renumbered and numeric values * should never be reused. */ @@ -83,34 +79,56 @@ int NUM_ENTRIES = 6; } - /** Returns {@code true} if the adaptive toolbar is enabled in single variant mode. */ + /** + * Returns whether the adaptive toolbar is enabled in single variant mode. Returns true also to + * provide legacy support for feature flags {@code ShareButtonInTopToolbar} and {@code + * VoiceButtonInTopToolbar}. + * + * <p>Must be called with the {@link FeatureList} initialized. + */ public static boolean isSingleVariantModeEnabled() { - return CachedFeatureFlags.isEnabled(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR); + if (isCustomizationEnabled()) return false; + if (ChromeFeatureList.isEnabled(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR)) { + return true; + } + return isLegacyShareButtonEnabled() || isLegacyVoiceButtonEnabled(); } /** - * @return The main feature flag for segmentation based adaptive toolbar customization. + * Returns whether the adaptive toolbar is enabled with segmentation and customization. + * + * <p>Must be called with the {@link FeatureList} initialized. */ public static boolean isCustomizationEnabled() { - if (isSingleVariantModeEnabled()) return false; return ChromeFeatureList.isEnabled( ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION); } /** * When the adaptive toolbar is configured in a single button variant mode, returns the {@link - * AdaptiveToolbarButtonVariant} being used. Returns {@link - * AdaptiveToolbarButtonVariant#UNKNOWN} otherwise. - * <p> - * This methods avoids parsing param strings more than once. Tests need to call {@link + * AdaptiveToolbarButtonVariant} being used. + * + * <p>This methods avoids parsing param strings more than once. Tests need to call {@link * #clearParsedParamsForTesting()} to clear the cached values. - * TODO(shaktisahu): Have a similar method for segmentation. + * + * <p>Must be called with the {@link FeatureList} initialized. + * + * <p>TODO(shaktisahu): Have a similar method for segmentation. */ @AdaptiveToolbarButtonVariant public static int getSingleVariantMode() { assert isSingleVariantModeEnabled(); if (sButtonVariant != null) return sButtonVariant; - String mode = MODE_PARAM.getValue(); + if (isLegacyShareButtonEnabled()) { + sButtonVariant = AdaptiveToolbarButtonVariant.SHARE; + } else if (isLegacyVoiceButtonEnabled()) { + sButtonVariant = AdaptiveToolbarButtonVariant.VOICE; + } + if (sButtonVariant != null) return sButtonVariant; + + String mode = ChromeFeatureList.getFieldTrialParamByFeature( + ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, + VARIATION_PARAM_SINGLE_VARIANT_MODE); switch (mode) { case ALWAYS_NONE: sButtonVariant = AdaptiveToolbarButtonVariant.NONE; @@ -132,8 +150,8 @@ } /** - * @return The default variant to be shown in segmentation experiment when the backend results - * are unavailable or not configured. + * Returns the default variant to be shown in segmentation experiment when the backend results + * are unavailable or not configured. */ @AdaptiveToolbarButtonVariant static int getSegmentationDefault() { @@ -158,9 +176,7 @@ return sButtonVariant; } - /** - * @return The default segment set by the finch experiment. - */ + /** Returns the default segment set by the finch experiment. */ static String getDefaultSegment() { if (sDefaultSegmentForTesting != null) return sDefaultSegmentForTesting; @@ -171,9 +187,7 @@ return defaultSegment; } - /** - * @return Whether or not we should ignore the segmentation backend results. - */ + /** Returns whether we should ignore the segmentation backend results. */ static boolean ignoreSegmentationResults() { if (sIgnoreSegmentationResultsForTesting != null) { return sIgnoreSegmentationResultsForTesting; @@ -185,8 +199,8 @@ } /** - * @return Whether the UI should be disabled. If disabled, the UI will ignore the backend - * results. + * Returns whether the UI should be disabled. If disabled, the UI will ignore the backend + * results. */ static boolean disableUi() { if (sDisableUiForTesting != null) return sDisableUiForTesting; @@ -197,8 +211,8 @@ } /** - * @return Whether the UI can be shown only after the backend is ready and has sufficient - * information for result computation. + * Returns whether the UI can be shown only after the backend is ready and has sufficient + * information for result computation. */ static boolean showUiOnlyAfterReady() { if (sShowUiOnlyAfterReadyForTesting != null) return sShowUiOnlyAfterReadyForTesting; @@ -228,9 +242,6 @@ sShowUiOnlyAfterReadyForTesting = showUiOnlyAfterReady; } - @AdaptiveToolbarButtonVariant - private static Integer sButtonVariant; - @VisibleForTesting public static void clearParsedParamsForTesting() { sButtonVariant = null; @@ -240,5 +251,33 @@ sShowUiOnlyAfterReadyForTesting = null; } + /** + * Returns whether the adaptive toolbar is providing legacy support for the feature flag {@code + * VoiceButtonInTopToolbar}. + * + * <p>Must be called with the {@link FeatureList} initialized. + */ + private static boolean isLegacyShareButtonEnabled() { + if (isCustomizationEnabled()) return false; + if (ChromeFeatureList.isEnabled(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR)) { + return false; + } + return ChromeFeatureList.isEnabled(ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR); + } + + /** + * Returns whether the adaptive toolbar is providing legacy support for the feature flag {@code + * ShareButtonInTopToolbar}. + * + * <p>Must be called with the {@link FeatureList} initialized. + */ + private static boolean isLegacyVoiceButtonEnabled() { + if (isCustomizationEnabled()) return false; + if (ChromeFeatureList.isEnabled(ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR)) { + return false; + } + return ChromeFeatureList.isEnabled(ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR); + } + private AdaptiveToolbarFeatures() {} }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStatePredictorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStatePredictorTest.java index b4ba75b..eb9641d9 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStatePredictorTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStatePredictorTest.java
@@ -16,6 +16,8 @@ import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; @@ -27,16 +29,40 @@ import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.optimization_guide.proto.ModelsProto.OptimizationTarget; +import java.util.HashMap; +import java.util.Map; + /** Unit tests for the {@code AdaptiveToolbarStatePredictor} */ -@Config(manifest = Config.NONE) +@Config(manifest = Config.NONE, + shadows = {AdaptiveToolbarStatePredictorTest.ShadowChromeFeatureList.class}) @RunWith(BaseRobolectricTestRunner.class) +@DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR, + ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR, + ChromeFeatureList.VOICE_BUTTON_IN_TOP_TOOLBAR}) @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public class AdaptiveToolbarStatePredictorTest { + // TODO(crbug.com/1199025): Remove this shadow. + @Implements(ChromeFeatureList.class) + static class ShadowChromeFeatureList { + static final Map<String, String> sParamValues = new HashMap<>(); + + @Implementation + public static String getFieldTrialParamByFeature(String feature, String paramKey) { + Assert.assertTrue(ChromeFeatureList.isEnabled(feature)); + return sParamValues.getOrDefault(paramKey, ""); + } + + public static void reset() { + sParamValues.clear(); + } + } + @Rule public TestRule mProcessor = new Features.JUnitProcessor(); @Before public void setUp() { + ShadowChromeFeatureList.reset(); AdaptiveToolbarFeatures.clearParsedParamsForTesting(); } @@ -51,7 +77,6 @@ public void testDisableFeature() { AdaptiveToolbarFeatures.setDefaultSegmentForTesting(AdaptiveToolbarFeatures.SHARE); AdaptiveToolbarFeatures.setIgnoreSegmentationResultsForTesting(false); - AdaptiveToolbarStatePredictor statePredictor = buildStatePredictor( true, AdaptiveToolbarButtonVariant.VOICE, true, AdaptiveToolbarButtonVariant.SHARE); UiState expected = new UiState(false, AdaptiveToolbarButtonVariant.UNKNOWN, @@ -64,8 +89,7 @@ @EnableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR}) @DisableFeatures({ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION}) public void testWorksWithDataCollectionFeatureFlag() { - AdaptiveToolbarFeatures.MODE_PARAM.setForTesting(AdaptiveToolbarFeatures.ALWAYS_VOICE); - + ShadowChromeFeatureList.sParamValues.put("mode", "always-voice"); AdaptiveToolbarStatePredictor statePredictor = buildStatePredictor( true, AdaptiveToolbarButtonVariant.VOICE, true, AdaptiveToolbarButtonVariant.SHARE); UiState expected = new UiState(true, AdaptiveToolbarButtonVariant.VOICE,
diff --git a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc index 8dccbb59..3370705 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" #include "chrome/browser/ui/app_list/search/search_controller.h" #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" @@ -75,6 +76,29 @@ // Browser Test for AppListClientImpl. using AppListClientImplBrowserTest = extensions::PlatformAppBrowserTest; +namespace { +class TestObserver : public app_list::AppListSyncableService::Observer { + public: + explicit TestObserver(app_list::AppListSyncableService* syncable_service) + : syncable_service_(syncable_service) { + syncable_service_->AddObserverAndStart(this); + } + TestObserver(const TestObserver&) = delete; + TestObserver& operator=(const TestObserver&) = delete; + ~TestObserver() override { syncable_service_->RemoveObserver(this); } + + size_t add_or_update_count() const { return add_or_update_count_; } + + // app_list::AppListSyncableService::Observer: + void OnSyncModelUpdated() override {} + void OnAddOrUpdateFromSyncItemForTest() override { ++add_or_update_count_; } + + private: + app_list::AppListSyncableService* const syncable_service_; + size_t add_or_update_count_ = 0; +}; +} // namespace + // Test AppListClient::IsAppOpen for extension apps. IN_PROC_BROWSER_TEST_F(AppListClientImplBrowserTest, IsExtensionAppOpen) { AppListControllerDelegate* delegate = AppListClientImpl::GetInstance(); @@ -249,19 +273,27 @@ // Emulate that the current user is new. client->InitializeAsIfNewUserLoginForTest(); - AppListModelUpdater* model_updater = test::GetModelUpdater(client); + TestObserver syncable_service_observer( + app_list::AppListSyncableServiceFactory::GetInstance()->GetForProfile( + profile())); // Add an app item. + AppListModelUpdater* model_updater = test::GetModelUpdater(client); const std::string app_id("fake_id"); model_updater->AddItem(std::make_unique<ChromeAppListItem>( browser()->profile(), app_id, model_updater)); - ChromeAppListItem* item = model_updater->FindItem(app_id); - ASSERT_TRUE(item); + + // Verify that the app addition from the app list client side should not + // trigger the update recursively, i.e. the client side observers the update + // in the app list model then reacts to it. + EXPECT_EQ(0u, syncable_service_observer.add_or_update_count()); base::HistogramTester histogram_tester; // Verify that app activation is recorded. client->ShowAppList(); + ChromeAppListItem* item = model_updater->FindItem(app_id); + ASSERT_TRUE(item); client->ActivateItem(/*profile_id=*/0, item->id(), /*event_flags=*/0); histogram_tester.ExpectBucketCount( "Apps.FirstLauncherActionByNewUsers",
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc index ba57cc2ea..77802cb6 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -719,6 +719,9 @@ void AppListSyncableService::AddOrUpdateFromSyncItem( const ChromeAppListItem* app_item) { + for (auto& observer : observer_list_) + observer.OnAddOrUpdateFromSyncItemForTest(); + // Do not create a sync item for the OEM folder here, do that in // ResolveFolderPositions once the position has been resolved. if (app_item->id() == ash::kOemFolderId)
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.h b/chrome/browser/ui/app_list/app_list_syncable_service.h index cefc3fb..a096d06 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.h +++ b/chrome/browser/ui/app_list/app_list_syncable_service.h
@@ -70,6 +70,9 @@ // Notifies that sync model was updated. virtual void OnSyncModelUpdated() = 0; + // Notifies the addition or update from the sync items for testing. + virtual void OnAddOrUpdateFromSyncItemForTest() {} + protected: ~Observer() override; };
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc index bfeb92d0..9c28cfc 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -30,8 +30,8 @@ #include "chrome/browser/ash/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" #include "chrome/browser/ash/arc/notification/arc_management_transition_notification.h" #include "chrome/browser/ash/arc/session/arc_session_manager.h" +#include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_observer.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h"
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h index 82930c6f..1e121df2 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -66,7 +66,6 @@ const std::string& id, std::unique_ptr<ash::SearchResultMetadata> metadata) override; - // Methods only for visiting Chrome items that never talk to ash. void ActivateChromeItem(const std::string& id, int event_flags) override; ChromeAppListItem* AddChromeItem(std::unique_ptr<ChromeAppListItem> app_item); void RemoveChromeItem(const std::string& id);
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc index 1bbe353..943b9ffa 100644 --- a/chrome/browser/ui/ash/chrome_new_window_client.cc +++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -752,7 +752,8 @@ if (!profile) return; - web_app::AppId app_id = web_app::GenerateAppIdFromURL(start_url); + web_app::AppId app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); bool app_installed = false; auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile);
diff --git a/chrome/browser/ui/ash/desks_client.h b/chrome/browser/ui/ash/desks_client.h index 09edd7e..d5854f4 100644 --- a/chrome/browser/ui/ash/desks_client.h +++ b/chrome/browser/ui/ash/desks_client.h
@@ -41,6 +41,7 @@ private: friend class DesksClientTest; + friend class ScopedDeskClientAppLaunchHandlerSetter; // Callback function that is ran after a desk is created, or has failed to be // created.
diff --git a/chrome/browser/ui/ash/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks_client_browsertest.cc index cfc6cde..a65b4d7 100644 --- a/chrome/browser/ui/ash/desks_client_browsertest.cc +++ b/chrome/browser/ui/ash/desks_client_browsertest.cc
@@ -17,6 +17,8 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/apps/platform_apps/app_browsertest_util.h" +#include "chrome/browser/ui/ash/desk_template_app_launch_handler.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_tabstrip.h" @@ -33,11 +35,14 @@ #include "components/full_restore/restore_data.h" #include "content/public/test/browser_test.h" #include "extensions/common/constants.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" #include "ui/display/screen.h" #include "url/gurl.h" +using ::testing::_; + namespace { constexpr int32_t kSettingsWindowId = 100; @@ -62,9 +67,65 @@ return urls; } +class MockDeskTemplateAppLaunchHandler : public DeskTemplateAppLaunchHandler { + public: + explicit MockDeskTemplateAppLaunchHandler(Profile* profile) + : DeskTemplateAppLaunchHandler(profile) {} + MockDeskTemplateAppLaunchHandler(const MockDeskTemplateAppLaunchHandler&) = + delete; + MockDeskTemplateAppLaunchHandler& operator=( + const MockDeskTemplateAppLaunchHandler&) = delete; + ~MockDeskTemplateAppLaunchHandler() override = default; + + MOCK_METHOD(void, + LaunchSystemWebAppOrChromeApp, + (apps::mojom::AppType, + const std::string&, + const ::full_restore::RestoreData::LaunchList&), + (override)); +}; + } // namespace -class DesksClientTest : public InProcessBrowserTest { +// Scoped class that temporarily sets a new app launch handler for testing +// purposes. +class ScopedDeskClientAppLaunchHandlerSetter { + public: + explicit ScopedDeskClientAppLaunchHandlerSetter( + std::unique_ptr<DeskTemplateAppLaunchHandler> launch_handler) { + DCHECK_EQ(0, instance_count_); + ++instance_count_; + + DesksClient* desks_client = DesksClient::Get(); + DCHECK(desks_client); + old_app_launch_handler_ = std::move(desks_client->app_launch_handler_); + desks_client->app_launch_handler_ = std::move(launch_handler); + } + ScopedDeskClientAppLaunchHandlerSetter( + const ScopedDeskClientAppLaunchHandlerSetter&) = delete; + ScopedDeskClientAppLaunchHandlerSetter& operator=( + const ScopedDeskClientAppLaunchHandlerSetter&) = delete; + ~ScopedDeskClientAppLaunchHandlerSetter() { + DCHECK_EQ(1, instance_count_); + --instance_count_; + + DesksClient* desks_client = DesksClient::Get(); + DCHECK(desks_client); + desks_client->app_launch_handler_ = std::move(old_app_launch_handler_); + } + + private: + // Variable to ensure we never have more than one instance of this object. + static int instance_count_; + + // The old app launch handler prior to the object being created. May be + // nullptr. + std::unique_ptr<DeskTemplateAppLaunchHandler> old_app_launch_handler_; +}; + +int ScopedDeskClientAppLaunchHandlerSetter::instance_count_ = 0; + +class DesksClientTest : public extensions::PlatformAppBrowserTest { public: DesksClientTest() { // This feature depends on full restore feature, so need to enable it. @@ -75,7 +136,7 @@ void SetUpOnMainThread() override { ::full_restore::SetActiveProfilePath(browser()->profile()->GetPath()); - InProcessBrowserTest::SetUpOnMainThread(); + extensions::PlatformAppBrowserTest::SetUpOnMainThread(); } void SetLaunchTemplate(std::unique_ptr<ash::DeskTemplate> launch_template) { @@ -269,6 +330,54 @@ EXPECT_EQ(kDeskName, desks_helper->GetDeskName(1)); } +// Tests that launching the same desk template multiple times creates desks with +// different/incremented names. +IN_PROC_BROWSER_TEST_F(DesksClientTest, LaunchMultipleEmptyDeskTemplates) { + const double kDeskUuid = 40.0; + const std::u16string kDeskName(u"Test Desk Name"); + + auto* desks_controller = ash::DesksController::Get(); + + ASSERT_EQ(0, desks_controller->GetActiveDeskIndex()); + + auto desk_template = std::make_unique<ash::DeskTemplate>(kDeskUuid); + desk_template->set_template_name(kDeskName); + SetLaunchTemplate(std::move(desk_template)); + + auto check_launch_template_desk_name = + [kDeskUuid, desks_controller](const std::u16string& desk_name) { + ash::DeskSwitchAnimationWaiter waiter; + DesksClient::Get()->LaunchDeskTemplate(kDeskUuid); + waiter.Wait(); + + EXPECT_EQ(desk_name, desks_controller->GetDeskName( + desks_controller->GetActiveDeskIndex())); + }; + + // Launching a desk from the template creates a desk with the same name as the + // template. + check_launch_template_desk_name(kDeskName); + + // Launch more desks from the template and verify that the newly created desks + // have unique names. + check_launch_template_desk_name(std::u16string(kDeskName).append(u" (1)")); + check_launch_template_desk_name(std::u16string(kDeskName).append(u" (2)")); + + // Remove "Test Desk Name (1)", which means the next created desk from + // template will have that name. Then it will skip (2) since it already + // exists, and create the next desk with (3). + RemoveDesk(desks_controller->desks()[2].get()); + check_launch_template_desk_name(std::u16string(kDeskName).append(u" (1)")); + check_launch_template_desk_name(std::u16string(kDeskName).append(u" (3)")); + + // Same as above, but make sure that deleting the desk with the exact template + // name still functions the same by only filling in whatever name is + // available. + RemoveDesk(desks_controller->desks()[1].get()); + check_launch_template_desk_name(kDeskName); + check_launch_template_desk_name(std::u16string(kDeskName).append(u" (4)")); +} + // Tests that launching a template that contains a system web app works as // expected. IN_PROC_BROWSER_TEST_F(DesksClientTest, LaunchTemplateWithSystemApp) { @@ -333,3 +442,62 @@ ash::kShellWindowId_DeskContainerB), settings_window->parent()); } + +// Tests that launching a template that contains a chrome app works as expected. +IN_PROC_BROWSER_TEST_F(DesksClientTest, LaunchTemplateWithChromeApp) { + DesksClient* desks_client = DesksClient::Get(); + ASSERT_TRUE(desks_client); + + // Create a chrome app. + const extensions::Extension* extension = + LoadAndLaunchPlatformApp("launch", "Launched"); + ASSERT_TRUE(extension); + + const std::string extension_id = extension->id(); + ::full_restore::SaveAppLaunchInfo( + browser()->profile()->GetPath(), + std::make_unique<::full_restore::AppLaunchInfo>( + extension_id, apps::mojom::LaunchContainer::kLaunchContainerWindow, + WindowOpenDisposition::NEW_WINDOW, display::kDefaultDisplayId, + std::vector<base::FilePath>{}, nullptr)); + + extensions::AppWindow* app_window = + CreateAppWindow(browser()->profile(), extension); + ASSERT_TRUE(app_window); + ASSERT_TRUE(GetFirstAppWindowForApp(extension_id)); + + // Capture the active desk, which contains the chrome app. + std::unique_ptr<ash::DeskTemplate> desk_template = + DesksClient::Get()->CaptureActiveDeskAsTemplate(); + ASSERT_TRUE(desk_template); + + // Close the chrome app window. We'll need to verify if it reopens later. + views::Widget* app_widget = + views::Widget::GetWidgetForNativeWindow(app_window->GetNativeWindow()); + app_widget->CloseNow(); + ASSERT_FALSE(GetFirstAppWindowForApp(extension_id)); + + ash::DesksHelper* desks_helper = ash::DesksHelper::Get(); + ASSERT_EQ(0, desks_helper->GetActiveDeskIndex()); + + // `BrowserAppLauncher::LaunchAppWithParams()` does not launch the chrome app + // in tests, so here we set up a mock app launch handler and just verify a + // `LaunchSystemWebAppOrChromeApp()` call with the associated extension is + // seen. + auto mock_app_launch_handler = + std::make_unique<MockDeskTemplateAppLaunchHandler>(browser()->profile()); + MockDeskTemplateAppLaunchHandler* mock_app_launch_handler_ptr = + mock_app_launch_handler.get(); + ScopedDeskClientAppLaunchHandlerSetter scoped_launch_handler( + std::move(mock_app_launch_handler)); + + EXPECT_CALL(*mock_app_launch_handler_ptr, + LaunchSystemWebAppOrChromeApp(_, extension_id, _)); + + // Set the template we created as the template we want to launch. + ash::DeskTemplate* desk_template_ptr = desk_template.get(); + SetLaunchTemplate(std::move(desk_template)); + ash::DeskSwitchAnimationWaiter waiter; + DesksClient::Get()->LaunchDeskTemplate(desk_template_ptr->uuid()); + waiter.Wait(); +}
diff --git a/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.cc b/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.cc index 84108e6..dd6dbd4 100644 --- a/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.cc +++ b/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.cc
@@ -5,11 +5,13 @@ #include "chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.h" #include "chrome/browser/ash/arc/session/arc_session_manager.h" +#include "chrome/browser/chromeos/full_restore/arc_app_launch_handler.h" #include "chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/ash/shelf/shelf_spinner_controller.h" #include "components/arc/metrics/arc_metrics_constants.h" +#include "components/full_restore/full_restore_utils.h" ArcShelfSpinnerItemController::ArcShelfSpinnerItemController( const std::string& arc_app_id, @@ -41,17 +43,29 @@ observed_profile_ = controller->OwnerProfile(); ArcAppListPrefs::Get(observed_profile_)->AddObserver(this); -#if BUILDFLAG(ENABLE_WAYLAND_SERVER) - auto* arc_task_handler = - chromeos::full_restore::FullRestoreArcTaskHandler::GetForProfile( - observed_profile_); - if (arc_task_handler && arc_task_handler->window_handler()) - arc_handler_observation_.Observe(arc_task_handler->window_handler()); -#endif - ShelfSpinnerItemController::SetHost(controller); } +void ArcShelfSpinnerItemController::ItemSelected( + std::unique_ptr<ui::Event> event, + int64_t display_id, + ash::ShelfLaunchSource source, + ItemSelectedCallback callback, + const ItemFilterPredicate& filter_predicate) { + if (window_info_ && + window_info_->window_id > + full_restore::kArcSessionIdOffsetForRestoredLaunching) { + chromeos::full_restore::FullRestoreArcTaskHandler::GetForProfile( + observed_profile_) + ->arc_app_launch_handler() + ->LaunchApp(app_id()); + std::move(callback).Run(ash::SHELF_ACTION_NEW_WINDOW_CREATED, {}); + return; + } + + std::move(callback).Run(ash::SHELF_ACTION_NONE, {}); +} + void ArcShelfSpinnerItemController::OnAppStatesChanged( const std::string& arc_app_id, const ArcAppListPrefs::AppInfo& app_info) { @@ -84,8 +98,3 @@ // If ARC was disabled, remove the deferred launch request. Close(); } - -void ArcShelfSpinnerItemController::OnWindowCloseRequested(int window_id) { - if (window_info_ && window_info_->window_id == window_id) - Close(); -}
diff --git a/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.h b/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.h index bb5fea1..e1a3efc 100644 --- a/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.h +++ b/chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.h
@@ -13,7 +13,6 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "chrome/browser/ash/arc/session/arc_session_manager_observer.h" -#include "chrome/browser/chromeos/full_restore/arc_window_handler.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/ash/shelf/shelf_spinner_item_controller.h" @@ -22,11 +21,9 @@ // ArcShelfSpinnerItemController displays the icon of the ARC app that // cannot be launched immediately (due to ARC not being ready) on Chrome OS' // shelf, with an overlaid spinner to provide visual feedback. -class ArcShelfSpinnerItemController - : public ShelfSpinnerItemController, - public ArcAppListPrefs::Observer, - public arc::ArcSessionManagerObserver, - public chromeos::full_restore::ArcWindowHandler::Observer { +class ArcShelfSpinnerItemController : public ShelfSpinnerItemController, + public ArcAppListPrefs::Observer, + public arc::ArcSessionManagerObserver { public: ArcShelfSpinnerItemController(const std::string& arc_app_id, int event_flags, @@ -38,6 +35,13 @@ // ShelfSpinnerItemController: void SetHost(const base::WeakPtr<ShelfSpinnerController>& host) override; + // ash::ShelfItemDelegate overrides: + void ItemSelected(std::unique_ptr<ui::Event> event, + int64_t display_id, + ash::ShelfLaunchSource source, + ItemSelectedCallback callback, + const ItemFilterPredicate& filter_predicate) override; + // ArcAppListPrefs::Observer: void OnAppStatesChanged(const std::string& app_id, const ArcAppListPrefs::AppInfo& app_info) override; @@ -46,9 +50,6 @@ // arc::ArcSessionManagerObserver: void OnArcPlayStoreEnabledChanged(bool enabled) override; - // chromeos::full_restore::ArcWindowHandler::Observer: - void OnWindowCloseRequested(int window_id) override; - private: // The flags of the event that caused the ARC app to be activated. These will // be propagated to the launch event once the app is actually launched. @@ -62,10 +63,6 @@ // Unowned Profile* observed_profile_ = nullptr; - base::ScopedObservation<chromeos::full_restore::ArcWindowHandler, - chromeos::full_restore::ArcWindowHandler::Observer> - arc_handler_observation_{this}; - DISALLOW_COPY_AND_ASSIGN(ArcShelfSpinnerItemController); };
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc index cd9eb58e..2ef177b7 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
@@ -2503,7 +2503,8 @@ IN_PROC_BROWSER_TEST_F(ShelfWebAppBrowserTest, WebAppPolicyNonExistentApp) { // Don't install the web app. GURL app_url = GURL("https://example.org/"); - web_app::AppId app_id = web_app::GenerateAppIdFromURL(app_url); + web_app::AppId app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, app_url); // Set policy to pin the non existent web app. base::DictionaryValue entry;
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index 6fc03bd..63deba50 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -998,10 +998,12 @@ // Add a screenschange handler to requestFullscreen after awaiting getScreens. const std::string request_fullscreen_script = R"( - window.onscreenschange = async () => { - const screens = await self.getScreensDeprecated(); - await document.body.requestFullscreen(); - }; + (async () => { + const screenInterface = await window.getScreens(); + screenInterface.onscreenschange = async () => { + await document.body.requestFullscreen(); + }; + })(); )"; EXPECT_TRUE(EvalJs(tab, request_fullscreen_script).error.empty()); EXPECT_FALSE(browser()->window()->IsFullscreen());
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 449715d..d854e30 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -57,6 +57,8 @@ #include "chrome/browser/reputation/reputation_web_contents_observer.h" #include "chrome/browser/resource_coordinator/tab_helper.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h" +#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h" #include "chrome/browser/safe_browsing/trigger_creator.h" #include "chrome/browser/sessions/session_tab_helper_factory.h" @@ -313,7 +315,10 @@ resource_coordinator::ResourceCoordinatorTabHelper::CreateForWebContents( web_contents); safe_browsing::SafeBrowsingNavigationObserver::MaybeCreateForWebContents( - web_contents); + web_contents, HostContentSettingsMapFactory::GetForProfile(profile), + safe_browsing::SafeBrowsingNavigationObserverManagerFactory:: + GetForBrowserContext(profile), + profile->GetPrefs(), g_browser_process->safe_browsing_service()); safe_browsing::SafeBrowsingTabObserver::CreateForWebContents(web_contents); safe_browsing::TriggerCreator::MaybeCreateTriggersForWebContents( profile, web_contents);
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index 33bbc46..0507eac 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -97,7 +97,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/constants/ash_switches.h" #include "ash/public/cpp/tablet_mode.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "components/policy/core/common/policy_pref_names.h" #endif
diff --git a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc index 7065a9f..0042862 100644 --- a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
@@ -27,7 +27,7 @@ #include "ui/gfx/color_palette.h" #if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "components/policy/core/common/policy_pref_names.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/views/frame/windows_10_tab_search_caption_button.cc b/chrome/browser/ui/views/frame/windows_10_tab_search_caption_button.cc index dc9747a7..1bb9e4e 100644 --- a/chrome/browser/ui/views/frame/windows_10_tab_search_caption_button.cc +++ b/chrome/browser/ui/views/frame/windows_10_tab_search_caption_button.cc
@@ -27,7 +27,9 @@ accessible_name), tab_search_bubble_host_(std::make_unique<TabSearchBubbleHost>( this, - frame_view->browser_view()->GetProfile())) {} + frame_view->browser_view()->GetProfile())) { + SetFocusBehavior(FocusBehavior::ALWAYS); +} Windows10TabSearchCaptionButton::~Windows10TabSearchCaptionButton() = default;
diff --git a/chrome/browser/ui/views/hover_button.h b/chrome/browser/ui/views/hover_button.h index 68f22604..62411a6 100644 --- a/chrome/browser/ui/views/hover_button.h +++ b/chrome/browser/ui/views/hover_button.h
@@ -54,6 +54,8 @@ // When |resize_row_for_secondary_icon| is false, the button tries to // accommodate the view's preferred size by reducing the top and bottom // insets appropriately up to a value of 0. + // Warning: |icon_view| must have a fixed size and be correctly set during its + // constructor for the HoverButton to layout correctly. HoverButton(PressedCallback callback, std::unique_ptr<views::View> icon_view, const std::u16string& title,
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc index ea33b67..0d56541 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
@@ -680,7 +680,8 @@ // shown once in an user session. web_app::RecordInstallIphIgnored( profile()->GetPrefs(), - web_app::GenerateAppIdFromURL(app_banner_manager_->GetManifestStartUrl()), + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, + app_banner_manager_->GetManifestStartUrl()), base::Time::Now()); bool installable = OpenTab(app_url).installable; ASSERT_TRUE(installable);
diff --git a/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc b/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc index 185d842..e6d2c405 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc
@@ -205,8 +205,8 @@ // Checks that both the signin web view and the main picker view are able to // process a back keyboard event. -// TODO(https://crbug.com/1173544): Flaky on linux. -#if defined(OS_LINUX) +// TODO(https://crbug.com/1173544): Flaky on linux and Win7. +#if defined(OS_LINUX) || defined(OS_WIN) #define MAYBE_NavigateBackWithKeyboard DISABLED_NavigateBackWithKeyboard #else #define MAYBE_NavigateBackWithKeyboard NavigateBackWithKeyboard
diff --git a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc index f35c4ca..8c373f7 100644 --- a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc +++ b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc
@@ -188,8 +188,8 @@ // If |web_app_info_| is populated, then the bubble was not accepted. if (iph_state_ == chrome::PwaInProductHelpState::kShown && web_app_info_) { - web_app::AppId app_id = - web_app::GenerateAppIdFromURL(web_app_info_->start_url); + web_app::AppId app_id = web_app::GenerateAppId(web_app_info_->manifest_id, + web_app_info_->start_url); UMA_HISTOGRAM_ENUMERATION("WebApp.InstallIphPromo.Result", web_app::InstallIphResult::kCanceled); web_app::RecordInstallIphIgnored(prefs_, app_id, base::Time::Now()); @@ -208,8 +208,8 @@ } if (iph_state_ == chrome::PwaInProductHelpState::kShown) { - web_app::AppId app_id = - web_app::GenerateAppIdFromURL(web_app_info_->start_url); + web_app::AppId app_id = web_app::GenerateAppId(web_app_info_->manifest_id, + web_app_info_->start_url); UMA_HISTOGRAM_ENUMERATION("WebApp.InstallIphPromo.Result", web_app::InstallIphResult::kInstalled); web_app::RecordInstallIphInstalled(prefs_, app_id);
diff --git a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc index 62a7b43..d7d6b695 100644 --- a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc
@@ -123,7 +123,8 @@ ->GetActiveWebContents() ->GetBrowserContext()) ->GetPrefs(); - web_app::AppId app_id = web_app::GenerateAppIdFromURL(start_url); + web_app::AppId app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); EXPECT_EQ( web_app::GetIntWebAppPref(pref_service, app_id, web_app::kIphIgnoreCount) .value(), @@ -143,7 +144,8 @@ AcceptDialogResetIphCounters) { auto app_info = GetAppInfo(); GURL start_url = app_info->start_url; - web_app::AppId app_id = web_app::GenerateAppIdFromURL(start_url); + web_app::AppId app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); PrefService* pref_service = Profile::FromBrowserContext(browser() ->tab_strip_model()
diff --git a/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc b/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc index d2982b1..c703992 100644 --- a/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc +++ b/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc
@@ -15,6 +15,7 @@ #include "base/check.h" #include "base/compiler_specific.h" #include "base/containers/flat_set.h" +#include "base/feature_list.h" #include "base/location.h" #include "base/metrics/histogram_functions.h" #include "base/stl_util.h" @@ -38,6 +39,7 @@ #include "components/keep_alive_registry/scoped_keep_alive.h" #include "extensions/browser/extension_dialog_auto_confirm.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/features.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -326,6 +328,9 @@ layout->StartRowWithPadding(views::GridLayout::kFixedSize, kColumnSetIdPadded, views::GridLayout::kFixedSize, 0); + enable_remember_checkbox_ = + base::FeatureList::IsEnabled(blink::features::kWebAppEnableUrlHandlers); + if (enable_remember_checkbox_) { remember_selection_checkbox_ = layout->AddView( std::make_unique<views::Checkbox>(l10n_util::GetStringUTF16(
diff --git a/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.h b/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.h index 138cafb..b55323f9 100644 --- a/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.h +++ b/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.h
@@ -98,9 +98,10 @@ std::unique_ptr<ScopedKeepAlive> keep_alive_; std::vector<WebAppUrlHandlerHoverButton*> hover_buttons_; - // Allow the checkbox to be enabled or disabled. + // Allow the checkbox to be enabled or disabled. Enabled if the URL Handling + // feature flag is enabled, disabled otherwise. // TODO(crbug.com/1072058): Remove when settings are implemented. - const bool enable_remember_checkbox_ = true; + bool enable_remember_checkbox_ = false; views::Checkbox* remember_selection_checkbox_ = nullptr; views::ScrollView* scroll_view_ = nullptr;
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index 9402f481..5f47d4e 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -1470,9 +1470,10 @@ auto* provider = WebAppProviderBase::GetProviderBase(profile()); auto* app = provider->registrar().AsWebAppRegistrar()->GetAppById(app_id); - EXPECT_EQ(web_app::GenerateAppIdFromURL( - provider->registrar().GetAppStartUrl(app_id)), - app_id); + EXPECT_EQ( + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, + provider->registrar().GetAppStartUrl(app_id)), + app_id); EXPECT_EQ(app->start_url().spec().substr( app->start_url().GetOrigin().spec().size()), app->manifest_id()); @@ -1490,6 +1491,8 @@ EXPECT_EQ(web_app::GenerateAppId(app->manifest_id(), app->start_url()), app_id); - EXPECT_NE(web_app::GenerateAppIdFromURL(app->start_url()), app_id); + EXPECT_NE( + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, app->start_url()), + app_id); } } // namespace web_app
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index fb756a4f..915d0ac 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -43,13 +43,13 @@ #include "chrome/browser/ash/login/users/chrome_user_manager_util.h" #include "chrome/browser/ash/login/users/multi_profile_user_controller.h" #include "chrome/browser/ash/login/wizard_controller.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/system/system_clock.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/language_preferences.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_metrics.h"
diff --git a/chrome/browser/ui/webui/downloads/downloads_list_tracker.cc b/chrome/browser/ui/webui/downloads/downloads_list_tracker.cc index d07ad06..24a86f9 100644 --- a/chrome/browser/ui/webui/downloads/downloads_list_tracker.cc +++ b/chrome/browser/ui/webui/downloads/downloads_list_tracker.cc
@@ -309,11 +309,11 @@ if (download_item->CanResume()) percent = download_item->PercentComplete(); - // TODO(asanka): last_reason_text should be set via - // download_model.GetInterruptReasonText(). But we are using + // TODO(https://crbug.com/609255): GetHistoryPageStatusText() is using // GetStatusText() as a temporary measure until the layout is fixed to - // accommodate the longer string. http://crbug.com/609255 - last_reason_text = download_model.GetStatusText(); + // accommodate the longer string. Should update it to simply use + // GetInterruptDescription(). + last_reason_text = download_model.GetHistoryPageStatusText(); if (download::DOWNLOAD_INTERRUPT_REASON_CRASH == download_item->GetLastReason() && !download_item->CanResume()) {
diff --git a/chrome/browser/ui/webui/management/management_ui_handler.cc b/chrome/browser/ui/webui/management/management_ui_handler.cc index fc895685..38cd675 100644 --- a/chrome/browser/ui/webui/management/management_ui_handler.cc +++ b/chrome/browser/ui/webui/management/management_ui_handler.cc
@@ -48,9 +48,9 @@ #include "chrome/browser/ash/policy/core/device_cloud_policy_manager_chromeos.h" #include "chrome/browser/ash/policy/dlp/dlp_rules_manager.h" #include "chrome/browser/ash/policy/dlp/dlp_rules_manager_factory.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/cros_settings.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/chromeos/policy/networking/policy_cert_service.h" #include "chrome/browser/chromeos/policy/networking/policy_cert_service_factory.h" #include "chrome/browser/chromeos/policy/status_collector/device_status_collector.h"
diff --git a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc index 877100a..780ee496 100644 --- a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc +++ b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc
@@ -4,9 +4,14 @@ #include "chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.h" +#include <memory> + +#include "ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h" #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/i18n/time_formatting.h" #include "base/values.h" +#include "ui/gfx/image/image.h" namespace { // Keys in the JSON representation of a log message @@ -16,6 +21,9 @@ const char kLogMessageLineKey[] = "line"; const char kLogMessageSeverityKey[] = "severity"; +// Test device metadata for debug purposes +const char16_t kTestDeviceName[] = u"Pixel Buds"; + // Converts |log_message| to a raw dictionary value used as a JSON argument to // JavaScript functions. base::Value LogMessageToDictionary( @@ -32,7 +40,10 @@ } } // namespace -QuickPairHandler::QuickPairHandler() {} +QuickPairHandler::QuickPairHandler() + : fast_pair_notification_controller_( + std::make_unique<ash::quick_pair::FastPairNotificationController>()) { +} QuickPairHandler::~QuickPairHandler() = default; @@ -83,8 +94,17 @@ LogMessageToDictionary(log_message)); } -void QuickPairHandler::NotifyFastPairError(const base::ListValue* args) {} +void QuickPairHandler::NotifyFastPairError(const base::ListValue* args) { + fast_pair_notification_controller_->ShowErrorNotification( + kTestDeviceName, gfx::Image(), base::DoNothing(), base::DoNothing()); +} -void QuickPairHandler::NotifyFastPairDiscovery(const base::ListValue* args) {} +void QuickPairHandler::NotifyFastPairDiscovery(const base::ListValue* args) { + fast_pair_notification_controller_->ShowDiscoveryNotification( + kTestDeviceName, gfx::Image(), base::DoNothing(), base::DoNothing()); +} -void QuickPairHandler::NotifyFastPairPairing(const base::ListValue* args) {} +void QuickPairHandler::NotifyFastPairPairing(const base::ListValue* args) { + fast_pair_notification_controller_->ShowPairingNotification( + kTestDeviceName, gfx::Image(), base::DoNothing(), base::DoNothing()); +}
diff --git a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.h b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.h index e3e5037..74440c4 100644 --- a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.h +++ b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_WEBUI_NEARBY_INTERNALS_QUICK_PAIR_QUICK_PAIR_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_NEARBY_INTERNALS_QUICK_PAIR_QUICK_PAIR_HANDLER_H_ +#include <memory> #include "ash/quick_pair/common/log_buffer.h" #include "ash/quick_pair/common/logging.h" #include "base/memory/weak_ptr.h" @@ -12,6 +13,12 @@ #include "base/values.h" #include "content/public/browser/web_ui_message_handler.h" +namespace ash { +namespace quick_pair { +class FastPairNotificationController; +} // namespace quick_pair +} // namespace ash + // WebUIMessageHandler for the Quick Pair debug page at // chrome://nearby-internals class QuickPairHandler : public content::WebUIMessageHandler, @@ -44,6 +51,9 @@ void NotifyFastPairDiscovery(const base::ListValue* args); void NotifyFastPairPairing(const base::ListValue* args); + std::unique_ptr<ash::quick_pair::FastPairNotificationController> + fast_pair_notification_controller_; + base::ScopedObservation<ash::quick_pair::LogBuffer, ash::quick_pair::LogBuffer::Observer> observation_{this};
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 f26bd39..e809edf 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
@@ -209,6 +209,7 @@ IDS_NTP_MODULES_RECIPE_TASKS_LOWER_THESE}, {"modulesTasksInfo", IDS_NTP_MODULES_TASKS_INFO}, {"modulesCartSentence", IDS_NTP_MODULES_CART_SENTENCE}, + {"modulesCartSentenceV2", IDS_NTP_MODULES_CART_SENTENCE_V2}, {"modulesCartLower", IDS_NTP_MODULES_CART_LOWER}, {"modulesCartLowerThese", IDS_NTP_MODULES_CART_LOWER_THESE}, {"modulesCartLowerYour", IDS_NTP_MODULES_CART_LOWER_YOUR},
diff --git a/chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.cc b/chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.cc deleted file mode 100644 index f460bcd..0000000 --- a/chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.h" - -#include "base/bind.h" -#include "base/values.h" -#include "chrome/browser/signin/signin_util.h" - -EphemeralGuestSigninHandler::EphemeralGuestSigninHandler(Profile* profile) - : profile_(profile) {} -EphemeralGuestSigninHandler::~EphemeralGuestSigninHandler() = default; -// WebUIMessageHandler -void EphemeralGuestSigninHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "onChangeSignInStatusClicked", - base::BindRepeating( - &EphemeralGuestSigninHandler::HandleOnChangeSignInStatusClicked, - base::Unretained(this))); -} - -void EphemeralGuestSigninHandler::HandleOnChangeSignInStatusClicked( - const base::ListValue* args) { - IsSignedIn() ? SignOutAsGuest() : SignInAsGuest(); -} - -void EphemeralGuestSigninHandler::SignInAsGuest() { - // TODO(crbug.com/1134111): Use IdentityManager to sign in when Ephemeral - // Guest sign in functioncality is implemented. - signin_util::GuestSignedInUserData::SetIsSignedIn(profile_, - /*is_signed_in*/ true); -} - -void EphemeralGuestSigninHandler::SignOutAsGuest() { - // TODO(crbug.com/1134111): Use IdentityManager to sign out when Ephemeral - // Guest sign in functioncality is implemented. - signin_util::GuestSignedInUserData::SetIsSignedIn(profile_, - /*is_signed_in*/ false); -} - -bool EphemeralGuestSigninHandler::IsSignedIn() { - // TODO(crbug.com/1134111): Use IdentityManager to check sign in status when - // Ephemeral Guest sign in functioncality is implemented. - return signin_util::GuestSignedInUserData::IsSignedIn(profile_); -}
diff --git a/chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.h b/chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.h deleted file mode 100644 index 2057c34..0000000 --- a/chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_NTP_EPHEMERAL_GUEST_SIGNIN_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_NTP_EPHEMERAL_GUEST_SIGNIN_HANDLER_H_ - -#include "chrome/browser/profiles/profile.h" -#include "content/public/browser/web_ui_message_handler.h" - -namespace base { -class ListValue; -} // namespace base - -// TODO(crbug.com/1125474): Rename to GuestSigninHandler once all audit is done -// and all instances of non-ephemeral Guest profiles are deprecated. -// Communicates with the ephemeral guest ntp to handle sign-in and sign-out. -class EphemeralGuestSigninHandler : public content::WebUIMessageHandler { - public: - explicit EphemeralGuestSigninHandler(Profile* profile); - ~EphemeralGuestSigninHandler() override; - - // WebUIMessageHandler - void RegisterMessages() override; - - // Resolves JS call to sign in or sign out based on the |profile_| sign in - // status. - void HandleOnChangeSignInStatusClicked(const base::ListValue*); - - private: - // Helper methods to handle sign in and sign out. - void SignInAsGuest(); - void SignOutAsGuest(); - bool IsSignedIn(); - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(EphemeralGuestSigninHandler); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_NTP_EPHEMERAL_GUEST_SIGNIN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui.cc b/chrome/browser/ui/webui/ntp/new_tab_ui.cc index a050423..3644800 100644 --- a/chrome/browser/ui/webui/ntp/new_tab_ui.cc +++ b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" #include "chrome/browser/ui/webui/ntp/cookie_controls_handler.h" #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" -#include "chrome/browser/ui/webui/ntp/ephemeral_guest_signin_handler.h" #include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h" #include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h" #include "chrome/browser/ui/webui/theme_handler.h" @@ -67,15 +66,12 @@ : IDS_NEW_TAB_TITLE; web_ui->OverrideTitle(l10n_util::GetStringUTF16(title_resource_id)); - if (!profile->IsGuestSession() && !profile->IsEphemeralGuestProfile()) { + if (!profile->IsGuestSession()) { web_ui->AddMessageHandler(std::make_unique<ThemeHandler>()); if (profile->IsOffTheRecord()) { web_ui->AddMessageHandler( std::make_unique<CookieControlsHandler>(profile)); } - } else if (profile->IsEphemeralGuestProfile()) { - web_ui->AddMessageHandler( - std::make_unique<EphemeralGuestSigninHandler>(profile)); } // content::URLDataSource assumes the ownership of the html source. @@ -147,8 +143,7 @@ // NewTabHTMLSource NewTabUI::NewTabHTMLSource::NewTabHTMLSource(Profile* profile) - : profile_(profile) { -} + : profile_(profile) {} std::string NewTabUI::NewTabHTMLSource::GetSource() { return chrome::kChromeUINewTabHost; @@ -172,11 +167,11 @@ content::WebContents* web_contents = wc_getter.Run(); content::RenderProcessHost* render_host = web_contents ? web_contents->GetMainFrame()->GetProcess() : nullptr; - NTPResourceCache::WindowType win_type = NTPResourceCache::GetWindowType( - profile_, render_host); + NTPResourceCache::WindowType win_type = + NTPResourceCache::GetWindowType(profile_, render_host); scoped_refptr<base::RefCountedMemory> html_bytes( - NTPResourceCacheFactory::GetForProfile(profile_)-> - GetNewTabHTML(win_type)); + NTPResourceCacheFactory::GetForProfile(profile_)->GetNewTabHTML( + win_type)); std::move(callback).Run(html_bytes.get()); }
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index 331ec6bc..555e636 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "base/memory/ref_counted_memory.h" #include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -18,7 +19,6 @@ #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" @@ -80,10 +80,6 @@ "https://support.google.com/chrome/?p=ui_guest"; #endif -// The URL for the Learn More page shown on ephermal guest session new tab. -const char kLearnMoreEphemeralGuestSessionUrl[] = - "https://support.google.com/chrome/?p=ui_guest"; - std::string ReplaceTemplateExpressions( const scoped_refptr<base::RefCountedMemory>& bytes, const ui::TemplateReplacements& replacements) { @@ -158,8 +154,9 @@ NTPResourceCache::~NTPResourceCache() = default; NTPResourceCache::WindowType NTPResourceCache::GetWindowType( - Profile* profile, content::RenderProcessHost* render_host) { - if (profile->IsGuestSession() || profile->IsEphemeralGuestProfile()) + Profile* profile, + content::RenderProcessHost* render_host) { + if (profile->IsGuestSession()) return GUEST; // Sometimes the |profile| is the parent (non-incognito) version of the user @@ -176,17 +173,8 @@ } base::RefCountedMemory* NTPResourceCache::GetNewTabGuestHTML() { - // TODO(crbug.com/1134111): For full launch of ephemeral Guest profiles, - // instead of the below code block, use IdentityManager for ephemeral Guest - // profiles to check sign in status and return either - // |CreateNewTabEphemeralGuestSignedInHTML()| or - // |CreateNewTabEphemeralGuestSignedOutHTML()|. - if (!new_tab_guest_html_) { - GuestNTPInfo guest_ntp_info{kLearnMoreGuestSessionUrl, IDR_GUEST_TAB_HTML, - IDS_NEW_TAB_GUEST_SESSION_HEADING, - IDS_NEW_TAB_GUEST_SESSION_DESCRIPTION}; - new_tab_guest_html_ = CreateNewTabGuestHTML(guest_ntp_info); - } + if (!new_tab_guest_html_) + CreateNewTabGuestHTML(); return new_tab_guest_html_.get(); } @@ -265,7 +253,6 @@ new_tab_incognito_css_ = nullptr; new_tab_css_ = nullptr; new_tab_guest_html_ = nullptr; - new_tab_guest_signed_in_html_ = nullptr; } void NTPResourceCache::CreateNewTabIncognitoHTML() { @@ -337,47 +324,15 @@ new_tab_incognito_html_ = base::RefCountedString::TakeString(&full_html); } -base::RefCountedMemory* -NTPResourceCache::CreateNewTabEphemeralGuestSignedInHTML() { - if (!new_tab_guest_signed_in_html_) { - GuestNTPInfo guest_ntp_info{ - kLearnMoreEphemeralGuestSessionUrl, - IDR_EPHEMERAL_GUEST_TAB_HTML, - IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_IN, - IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_IN, - IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_IN, - IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED}; - new_tab_guest_signed_in_html_ = CreateNewTabGuestHTML(guest_ntp_info); - } - - return new_tab_guest_signed_in_html_.get(); -} - -base::RefCountedMemory* -NTPResourceCache::CreateNewTabEphemeralGuestSignedOutHTML() { - // Clear cached signed in HTML on sign out to avoid loading previously cached - // user name from other signed in guest sessions. - new_tab_guest_signed_in_html_ = nullptr; - - if (!new_tab_guest_signed_out_html_) { - GuestNTPInfo guest_ntp_info{ - kLearnMoreEphemeralGuestSessionUrl, - IDR_EPHEMERAL_GUEST_TAB_HTML, - IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_OUT, - IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_OUT, - IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_OUT, - IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED}; - new_tab_guest_signed_out_html_ = CreateNewTabGuestHTML(guest_ntp_info); - } - return new_tab_guest_signed_out_html_.get(); -} - -scoped_refptr<base::RefCountedString> NTPResourceCache::CreateNewTabGuestHTML( - const GuestNTPInfo& guest_ntp_info) { +void NTPResourceCache::CreateNewTabGuestHTML() { base::DictionaryValue localized_strings; localized_strings.SetString("title", - l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE)); - int guest_tab_idr = guest_ntp_info.html_idr; + l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE)); + const char* guest_tab_link = kLearnMoreGuestSessionUrl; + int guest_tab_idr = IDR_GUEST_TAB_HTML; + int guest_tab_description_ids = IDS_NEW_TAB_GUEST_SESSION_DESCRIPTION; + int guest_tab_heading_ids = IDS_NEW_TAB_GUEST_SESSION_HEADING; + int guest_tab_link_ids = IDS_LEARN_MORE; #if BUILDFLAG(IS_CHROMEOS_ASH) guest_tab_idr = IDR_GUEST_SESSION_TAB_HTML; @@ -413,28 +368,14 @@ } #endif - if (guest_ntp_info.features_ids != -1) { - localized_strings.SetString( - "guestTabFeatures", - l10n_util::GetStringUTF16(guest_ntp_info.features_ids)); - } - - if (guest_ntp_info.warnings_ids != -1) { - localized_strings.SetString( - "guestTabWarning", - l10n_util::GetStringUTF16(guest_ntp_info.warnings_ids)); - } - localized_strings.SetString( "guestTabDescription", - l10n_util::GetStringUTF16(guest_ntp_info.description_ids)); - // TODO(crbug.com/1134111): Replace placeholder with user's name in the - // greeting message when the guest sign in functionality is implemented. - localized_strings.SetString( - "guestTabHeading", l10n_util::GetStringUTF16(guest_ntp_info.heading_ids)); + l10n_util::GetStringUTF16(guest_tab_description_ids)); + localized_strings.SetString("guestTabHeading", + l10n_util::GetStringUTF16(guest_tab_heading_ids)); localized_strings.SetString("learnMore", - l10n_util::GetStringUTF16(IDS_LEARN_MORE)); - localized_strings.SetString("learnMoreLink", guest_ntp_info.learn_more_link); + l10n_util::GetStringUTF16(guest_tab_link_ids)); + localized_strings.SetString("learnMoreLink", guest_tab_link); const std::string& app_locale = g_browser_process->GetApplicationLocale(); webui::SetLoadTimeDataDefaults(app_locale, &localized_strings); @@ -449,7 +390,7 @@ std::string full_html = ReplaceTemplateExpressions(*guest_tab_html, replacements); - return base::RefCountedString::TakeString(&full_html); + new_tab_guest_html_ = base::RefCountedString::TakeString(&full_html); } void NTPResourceCache::CreateNewTabIncognitoCSS( @@ -510,9 +451,7 @@ // BookmarkBarView::Paint for how we do this for the bookmark bar // borders. SkColor color_section_border = - SkColorSetARGB(80, - SkColorGetR(color_header), - SkColorGetG(color_header), + SkColorSetARGB(80, SkColorGetR(color_header), SkColorGetG(color_header), SkColorGetB(color_header)); // Generate the replacements.
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.h b/chrome/browser/ui/webui/ntp/ntp_resource_cache.h index 329247f7..e98ab91 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.h +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.h
@@ -25,7 +25,7 @@ namespace base { class RefCountedMemory; class Value; -} +} // namespace base namespace content { class RenderProcessHost; @@ -75,32 +75,10 @@ // ThemeServiceObserver: void OnThemeChanged() override; - static WindowType GetWindowType( - Profile* profile, content::RenderProcessHost* render_host); + static WindowType GetWindowType(Profile* profile, + content::RenderProcessHost* render_host); private: - struct GuestNTPInfo { - explicit GuestNTPInfo(const char* learn_more_link, - int html_idr, - int heading_ids, - int description_ids, - int features_ids = -1, - int warnings_ids = -1) - : learn_more_link(learn_more_link), - html_idr(html_idr), - heading_ids(heading_ids), - description_ids(description_ids), - features_ids(features_ids), - warnings_ids(warnings_ids) {} - - const char* learn_more_link; - int html_idr; - int heading_ids; - int description_ids; - int features_ids; - int warnings_ids; - }; - // KeyedService: void Shutdown() override; @@ -126,13 +104,7 @@ void CreateNewTabIncognitoHTML(); void CreateNewTabIncognitoCSS(const content::WebContents::Getter wc_getter); - scoped_refptr<base::RefCountedString> CreateNewTabGuestHTML( - const GuestNTPInfo& guest_ntp_info); - // TODO(crbug.com/1125474): Rename to CreateNewTabGuestSigned{In|Out}HTML once - // all audit is done and all instances of non-ephemeral Guest profiles are - // deprecated. - base::RefCountedMemory* CreateNewTabEphemeralGuestSignedInHTML(); - base::RefCountedMemory* CreateNewTabEphemeralGuestSignedOutHTML(); + void CreateNewTabGuestHTML(); void SetDarkKey(base::Value* dict); @@ -140,8 +112,6 @@ scoped_refptr<base::RefCountedMemory> new_tab_css_; scoped_refptr<base::RefCountedMemory> new_tab_guest_html_; - scoped_refptr<base::RefCountedMemory> new_tab_guest_signed_in_html_; - scoped_refptr<base::RefCountedMemory> new_tab_guest_signed_out_html_; scoped_refptr<base::RefCountedMemory> new_tab_incognito_html_; scoped_refptr<base::RefCountedMemory> new_tab_incognito_css_; scoped_refptr<base::RefCountedMemory> new_tab_non_primary_otr_html_;
diff --git a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc index 1ad3803..4b949a4 100644 --- a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc +++ b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -70,8 +70,7 @@ bool ChromeNTPTilesInternalsMessageHandlerClient::SupportsNTPTiles() { Profile* profile = Profile::FromWebUI(web_ui()); - return !(profile->IsGuestSession() || profile->IsEphemeralGuestProfile() || - profile->IsOffTheRecord()); + return !(profile->IsGuestSession() || profile->IsOffTheRecord()); } bool ChromeNTPTilesInternalsMessageHandlerClient::DoesSourceExist(
diff --git a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc index 78bbfa6..6006b3e 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc +++ b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
@@ -460,10 +460,8 @@ // Change policy values. values.Erase(policy::key::kDefaultImagesSetting); - expected_values.RemovePath( - std::string("chromePolicies.") + - std::string(policy::key::kDefaultImagesSetting), - nullptr); + expected_values.RemovePath(std::string("chromePolicies.") + + std::string(policy::key::kDefaultImagesSetting)); popups_blocked_for_urls.AppendString("ddd"); values.Set(policy::key::kPopupsBlockedForUrls, policy::POLICY_LEVEL_MANDATORY,
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc index a1740cb..091a989b 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc +++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -119,6 +119,8 @@ #endif #if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include <windows.h> + #include <DSRole.h> #include "chrome/browser/google/google_update_policy_fetcher_win.h"
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index 4adb6f3..4155b71 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/pdf/pdf_extension_util.h" #include "chrome/browser/printing/background_printing_manager.h" #include "chrome/browser/printing/pdf_nup_converter_client.h" +#include "chrome/browser/printing/print_backend_service_manager.h" #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/print_preview_data_service.h" #include "chrome/browser/printing/print_preview_dialog_controller.h" @@ -69,6 +70,7 @@ #include "printing/mojom/print.mojom.h" #include "printing/nup_parameters.h" #include "printing/print_job_constants.h" +#include "printing/printing_features.h" #include "services/network/public/mojom/content_security_policy.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" @@ -469,6 +471,14 @@ initial_preview_start_time_(base::TimeTicks::Now()), handler_(handler.get()) { web_ui->AddMessageHandler(std::move(handler)); + + // Register with print backend service manager; it is beneficial to have a + // the print backend service be present and ready for at least as long as + // this UI is around. + if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + service_manager_client_id_ = + PrintBackendServiceManager::GetInstance().RegisterClient(); + } } PrintPreviewUI::PrintPreviewUI(content::WebUI* web_ui) @@ -486,9 +496,21 @@ // Set up the chrome://theme/ source. content::URLDataSource::Add(profile, std::make_unique<ThemeSource>(profile)); + + // Register with print backend service manager; it is beneficial to have a + // the print backend service be present and ready for at least as long as + // this UI is around. + if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + service_manager_client_id_ = + PrintBackendServiceManager::GetInstance().RegisterClient(); + } } PrintPreviewUI::~PrintPreviewUI() { + if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + PrintBackendServiceManager::GetInstance().UnregisterClient( + service_manager_client_id_); + } ClearPreviewUIId(); }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chrome/browser/ui/webui/print_preview/print_preview_ui.h index 16f9a62..2937bfef 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
@@ -273,6 +273,9 @@ // GetIDForPrintPreviewUI() everywhere. absl::optional<int32_t> id_; + // This UI's client ID with the print backend service manager. + uint32_t service_manager_client_id_; + // Weak pointer to the WebUI handler. PrintPreviewHandler* const handler_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_section.cc b/chrome/browser/ui/webui/settings/chromeos/device_section.cc index 11e1cc8f..e833c28b 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_section.cc
@@ -591,9 +591,6 @@ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER}, {"displayNightLightScheduleSunsetToSunRise", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE}, - {"displayNightLightStartTime", - IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_START_TIME}, - {"displayNightLightStopTime", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_STOP_TIME}, {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT}, {"displayNightLightTemperatureLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL},
diff --git a/chrome/browser/ui/webui/settings/chromeos/main_section.cc b/chrome/browser/ui/webui/settings/chromeos/main_section.cc index be7f05b..2a8043c 100644 --- a/chrome/browser/ui/webui/settings/chromeos/main_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/main_section.cc
@@ -12,10 +12,10 @@ #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/metrics_handler.h" #include "chrome/browser/ui/webui/plural_string_handler.h" @@ -130,6 +130,7 @@ {"dismiss", IDS_SETTINGS_DISMISS}, {"done", IDS_DONE}, {"edit", IDS_SETTINGS_EDIT}, + {"endTime", IDS_SETTINGS_END_TIME}, {"extensionsLinkTooltip", IDS_SETTINGS_MENU_EXTENSIONS_LINK_TOOLTIP}, {"learnMore", IDS_LEARN_MORE}, {"shortcutBannerDismissed", IDS_SETTINGS_SHORTCUT_BANNER_DISMISSED}, @@ -143,6 +144,7 @@ {"searchResultsBubbleText", IDS_SEARCH_RESULTS_BUBBLE_TEXT}, {"settings", IDS_SETTINGS_SETTINGS}, {"settingsAltPageTitle", IDS_SETTINGS_ALT_PAGE_TITLE}, + {"startTime", IDS_SETTINGS_START_TIME}, {"subpageArrowRoleDescription", IDS_SETTINGS_SUBPAGE_BUTTON}, {"subpageBackButtonAriaLabel", IDS_SETTINGS_SUBPAGE_BACK_BUTTON_ARIA_LABEL},
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 0f48497..4279e343 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -70,7 +70,7 @@ #include "ui/base/text/bytes_formatting.h" #include "ui/webui/webui_allowlist.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "chrome/browser/ash/login/users/mock_user_manager.h" #include "components/user_manager/scoped_user_manager.h" #endif @@ -197,7 +197,8 @@ std::unique_ptr<web_app::WebApp> CreateWebApp() { const GURL app_url = GURL("http://abc.example.com/path"); - const web_app::AppId app_id = web_app::GenerateAppIdFromURL(app_url); + const web_app::AppId app_id = + web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, app_url); auto web_app = std::make_unique<web_app::WebApp>(app_id); web_app->AddSource(web_app::Source::kSync);
diff --git a/chrome/browser/web_applications/components/app_registrar.cc b/chrome/browser/web_applications/components/app_registrar.cc index fd62d41..3ef6ae39 100644 --- a/chrome/browser/web_applications/components/app_registrar.cc +++ b/chrome/browser/web_applications/components/app_registrar.cc
@@ -29,7 +29,8 @@ } bool AppRegistrar::IsLocallyInstalled(const GURL& start_url) const { - return IsLocallyInstalled(GenerateAppIdFromURL(start_url)); + return IsLocallyInstalled( + GenerateAppId(/*manifest_id=*/absl::nullopt, start_url)); } bool AppRegistrar::IsPlaceholderApp(const AppId& app_id) const {
diff --git a/chrome/browser/web_applications/components/externally_managed_app_manager_unittest.cc b/chrome/browser/web_applications/components/externally_managed_app_manager_unittest.cc index b88d925f4..a67c687 100644 --- a/chrome/browser/web_applications/components/externally_managed_app_manager_unittest.cc +++ b/chrome/browser/web_applications/components/externally_managed_app_manager_unittest.cc
@@ -43,13 +43,14 @@ [this](const ExternalInstallOptions& install_options) -> ExternallyManagedAppManager::InstallResult { const GURL& install_url = install_options.install_url; - if (!app_registrar().GetAppById( - GenerateAppIdFromURL(install_url))) { + if (!app_registrar().GetAppById(GenerateAppId( + /*manifest_id=*/absl::nullopt, install_url))) { std::unique_ptr<WebApp> web_app = CreateWebApp(install_url); controller().RegisterApp(std::move(web_app)); externally_installed_app_prefs().Insert( - install_url, GenerateAppIdFromURL(install_url), + install_url, + GenerateAppId(/*manifest_id=*/absl::nullopt, install_url), install_options.install_source); ++deduped_install_count_; } @@ -119,7 +120,8 @@ } std::unique_ptr<WebApp> CreateWebApp(const GURL& start_url) { - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->SetStartUrl(start_url);
diff --git a/chrome/browser/web_applications/components/install_finalizer_unittest.cc b/chrome/browser/web_applications/components/install_finalizer_unittest.cc index 4b5d2a91..ea2d394 100644 --- a/chrome/browser/web_applications/components/install_finalizer_unittest.cc +++ b/chrome/browser/web_applications/components/install_finalizer_unittest.cc
@@ -117,7 +117,8 @@ FinalizeInstallResult result = AwaitFinalizeInstall(*info, options); EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); - EXPECT_EQ(result.installed_app_id, GenerateAppIdFromURL(info->start_url)); + EXPECT_EQ(result.installed_app_id, + GenerateAppId(/*manifest_id=*/absl::nullopt, info->start_url)); } TEST_F(InstallFinalizerUnitTest, ConcurrentInstallSucceeds) { @@ -143,7 +144,9 @@ base::BindLambdaForTesting([&](const AppId& installed_app_id, InstallResultCode code) { EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code); - EXPECT_EQ(installed_app_id, GenerateAppIdFromURL(info1->start_url)); + EXPECT_EQ( + installed_app_id, + GenerateAppId(/*manifest_id=*/absl::nullopt, info1->start_url)); callback1_called = true; if (callback2_called) run_loop.Quit(); @@ -157,7 +160,9 @@ base::BindLambdaForTesting([&](const AppId& installed_app_id, InstallResultCode code) { EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code); - EXPECT_EQ(installed_app_id, GenerateAppIdFromURL(info2->start_url)); + EXPECT_EQ( + installed_app_id, + GenerateAppId(/*manifest_id=*/absl::nullopt, info2->start_url)); callback2_called = true; if (callback1_called) run_loop.Quit();
diff --git a/chrome/browser/web_applications/components/protocol_handler_manager_unittest.cc b/chrome/browser/web_applications/components/protocol_handler_manager_unittest.cc index 7b161f5..a43a66d8 100644 --- a/chrome/browser/web_applications/components/protocol_handler_manager_unittest.cc +++ b/chrome/browser/web_applications/components/protocol_handler_manager_unittest.cc
@@ -30,7 +30,7 @@ std::unique_ptr<WebApp> CreateWebApp() { const GURL app_url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(app_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, app_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->AddSource(Source::kSync);
diff --git a/chrome/browser/web_applications/components/url_handler_manager_impl_unittest.cc b/chrome/browser/web_applications/components/url_handler_manager_impl_unittest.cc index 1ec2e01..cb2f3a1 100644 --- a/chrome/browser/web_applications/components/url_handler_manager_impl_unittest.cc +++ b/chrome/browser/web_applications/components/url_handler_manager_impl_unittest.cc
@@ -87,7 +87,8 @@ std::unique_ptr<WebApp> CreateWebAppWithUrlHandlers( const GURL& app_url, const apps::UrlHandlers& url_handlers) { - const std::string app_id = GenerateAppIdFromURL(app_url); + const std::string app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->AddSource(Source::kDefault); web_app->SetDisplayMode(DisplayMode::kStandalone);
diff --git a/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc b/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc index df31b17..80bac61b 100644 --- a/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc +++ b/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc
@@ -77,7 +77,8 @@ std::unique_ptr<WebApp> WebAppWithUrlHandlers( const GURL& app_url, const apps::UrlHandlers& url_handlers) { - auto web_app = std::make_unique<WebApp>(GenerateAppIdFromURL(app_url)); + auto web_app = std::make_unique<WebApp>( + GenerateAppId(/*manifest_id=*/absl::nullopt, app_url)); web_app->SetName("AppName"); web_app->SetDisplayMode(DisplayMode::kStandalone); web_app->SetStartUrl(app_url);
diff --git a/chrome/browser/web_applications/components/web_app_file_handler_registration_win.cc b/chrome/browser/web_applications/components/web_app_file_handler_registration_win.cc index 8a1d186..c1002c4 100644 --- a/chrome/browser/web_applications/components/web_app_file_handler_registration_win.cc +++ b/chrome/browser/web_applications/components/web_app_file_handler_registration_win.cc
@@ -50,7 +50,7 @@ bool result = ShellUtil::AddFileAssociations( GetProgIdForApp(profile_path, app_id), app_specific_launcher_command, - user_visible_app_name, app_name, icon_path, file_extensions); + user_visible_app_name, app_name, icon_path, icon_path, file_extensions); if (!result) RecordRegistration(RegistrationResult::kFailToAddFileAssociation); else
diff --git a/chrome/browser/web_applications/components/web_app_helpers.h b/chrome/browser/web_applications/components/web_app_helpers.h index eb46efb4..ff80345 100644 --- a/chrome/browser/web_applications/components/web_app_helpers.h +++ b/chrome/browser/web_applications/components/web_app_helpers.h
@@ -42,9 +42,6 @@ // // App ID and App Key match Extension ID and Extension Key for migration. -// Deprecated. Please use GenerateAppId instead. -AppId GenerateAppIdFromURL(const GURL& url); - // Generate App id using manfiest_id, if null, use start_url instead. AppId GenerateAppId(const absl::optional<std::string>& manifest_id, const GURL& start_url);
diff --git a/chrome/browser/web_applications/components/web_app_helpers_unittest.cc b/chrome/browser/web_applications/components/web_app_helpers_unittest.cc index f6a871dd7..4df7f37c 100644 --- a/chrome/browser/web_applications/components/web_app_helpers_unittest.cc +++ b/chrome/browser/web_applications/components/web_app_helpers_unittest.cc
@@ -19,17 +19,17 @@ GenerateApplicationNameFromURL(GURL("https://example.com/path"))); } -TEST(WebAppHelpers, GenerateAppIdFromURL) { - EXPECT_EQ( - "fedbieoalmbobgfjapopkghdmhgncnaa", - GenerateAppIdFromURL(GURL("https://www.chromestatus.com/features"))); +TEST(WebAppHelpers, GenerateAppId) { + EXPECT_EQ("fedbieoalmbobgfjapopkghdmhgncnaa", + GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://www.chromestatus.com/features"))); // The io2016 example is also walked through at // https://play.golang.org/p/VrIq_QKFjiV - EXPECT_EQ( - "mjgafbdfajpigcjmkgmeokfbodbcfijl", - GenerateAppIdFromURL(GURL( - "https://events.google.com/io2016/?utm_source=web_app_manifest"))); + EXPECT_EQ("mjgafbdfajpigcjmkgmeokfbodbcfijl", + GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://events.google.com/io2016/" + "?utm_source=web_app_manifest"))); } TEST(WebAppHelpers, IsValidWebAppUrl) {
diff --git a/chrome/browser/web_applications/components/web_app_id_constants.cc b/chrome/browser/web_applications/components/web_app_id_constants.cc index 724439c..ab4fdbd 100644 --- a/chrome/browser/web_applications/components/web_app_id_constants.cc +++ b/chrome/browser/web_applications/components/web_app_id_constants.cc
@@ -13,125 +13,127 @@ // TODO(crbug.com/1198418): Update when app URL is finalized. const char kA4AppId[] = "apignacaigpffemhdbhmnajajaccbckh"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://camera-app/views/main.html")) const char kCameraAppId[] = "njfbnohfdkmbmnjapinfcopialeghnmh"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://canvas.apps.chrome/")) const char kCanvasAppId[] = "ieailfmhaghpphfffooibmlghaeopach"; -// Generated as: web_app::GenerateAppIdFromURL(GURL("chrome://diagnostics/")) +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, +// GURL("chrome://diagnostics/")) const char kDiagnosticsAppId[] = "keejpcfcpecjhmepmpcfgjemkmlicpam"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://mail.google.com/mail/?usp=installed_webapp")) const char kGmailAppId[] = "fmgjjmmmlfnkbppncabfkddbjimcfncm"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://calendar.google.com/calendar/r")) const char kGoogleCalendarAppId[] = "kjbdgfilnfhdoflbpgamdcdgpehopbep"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://mail.google.com/chat/")) const char kGoogleChatAppId[] = "mdpkiolbdkhdjpekfbkbmhigcaggjagi"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://docs.google.com/document/?usp=installed_webapp")) const char kGoogleDocsAppId[] = "mpnpojknpmmopombnjdcgaaiekajbnjb"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://drive.google.com/?lfhs=2")) const char kGoogleDriveAppId[] = "aghbiahbpaijignceidepookljebhfak"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://keep.google.com/?usp=installed_webapp")) const char kGoogleKeepAppId[] = "eilembjdkfgodjkcjnpgpaenohkicgjd"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://www.google.com/maps?force=tt&source=ttpwa")) const char kGoogleMapsAppId[] = "mnhkaebcjjhencmpkapnbdaogjamfbcj"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://meet.google.com/landing?lfhs=2")) const char kGoogleMeetAppId[] = "kjgfgldnnfoeklkmfkjfagphfepbbdan"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://news.google.com/?lfhs=2")) const char kGoogleNewsAppId[] = "kfgapjallbhpciobgmlhlhokknljkgho"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://docs.google.com/spreadsheets/?usp=installed_webapp")) const char kGoogleSheetsAppId[] = "fhihpiojkbmbpdjeoajapmgkhlnakfjf"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://docs.google.com/presentation/?usp=installed_webapp")) const char kGoogleSlidesAppId[] = "kefjledonklijopmnomlcbpllchaibag"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://help-app/")) const char kHelpAppId[] = "nbljnnecbjbmifnoehiemkgefbnpoeak"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://media-app/")) const char kMediaAppId[] = "jhdjimmaggjajfjphpljagpgkidjilnj"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://messages.google.com/web/")) const char kMessagesAppId[] = "hpfldicfbfomlpcikngkocigghgafkph"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://test-system-app/pwa.html")) const char kMockSystemAppId[] = "maphiehpiinjgiaepbljmopkodkadcbh"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://os-feedback/")) const char kOsFeedbackAppId[] = "iffgohomcomlpmkfikfffagkkoojjffm"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://os-settings/")) const char kOsSettingsAppId[] = "odknhmnlageboeamepcngndbggdpaobj"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://books.google.com/ebooks/app")) const char kPlayBooksAppId[] = "jglfhlbohpgcbefmhdmpancnijacbbji"; -// Generated as:web_app::GenerateAppIdFromURL(GURL( +// Generated as:web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://print-management/")) const char kPrintManagementAppId[] = "fglkccnmnaankjodgccmiodmlkpaiodc"; -// Generated as: web_app::GenerateAppIdFromURL(GURL("chrome://scanning/")) +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, +// GURL("chrome://scanning/")) const char kScanningAppId[] = "cdkahakpgkdaoffdmfgnhgomkelkocfo"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://settings/")) const char kSettingsAppId[] = "inogagmajamaleonmanpkpkkigmklfad"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://shortcut-customization")) const char kShortcutCustomizationAppId[] = "ihgeegogifolehadhdgelgcnbnmemikp"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "chrome://shimless-rma/")) const char kShimlessRMAAppId[] = "ijolhdommgkkhpenofmpkkhlepahelcm"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://www.showtime.com/")) const char kShowtimeAppId[] = "eoccpgmpiempcflglfokeengliildkag"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://stadia.google.com/?lfhs=2")) const char kStadiaAppId[] = "pnkcfpnngfokcnnijgkllghjlhkailce"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://www.youtube.com/?feature=ytca")) const char kYoutubeAppId[] = "agimnkijcaahngcdmfeangaknmldooml"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://music.youtube.com/?source=pwa")) const char kYoutubeMusicAppId[] = "cinhimbnkkaeohfgghhklpknlkffjgod"; -// Generated as: web_app::GenerateAppIdFromURL(GURL( +// Generated as: web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, GURL( // "https://tv.youtube.com/")) const char kYoutubeTVAppId[] = "kiemjbkkegajmpbobdfngbmjccjhnofh";
diff --git a/chrome/browser/web_applications/components/web_app_utils_unittest.cc b/chrome/browser/web_applications/components/web_app_utils_unittest.cc index a55ca0c..1fcc502 100644 --- a/chrome/browser/web_applications/components/web_app_utils_unittest.cc +++ b/chrome/browser/web_applications/components/web_app_utils_unittest.cc
@@ -26,25 +26,9 @@ namespace web_app { +using WebAppUtilsTest = WebAppTest; using ::testing::ElementsAre; -class WebAppUtilsTest : public WebAppTest, - public ::testing::WithParamInterface<bool> { - public: - WebAppUtilsTest() : is_ephemeral_guest_(GetParam()) { - // Update for platforms which do not support ephemeral Guest profiles. - is_ephemeral_guest_ &= - TestingProfile::SetScopedFeatureListForEphemeralGuestProfiles( - scoped_feature_list_, is_ephemeral_guest_); - } - - bool is_ephemeral_guest() const { return is_ephemeral_guest_; } - - private: - base::test::ScopedFeatureList scoped_feature_list_; - bool is_ephemeral_guest_; -}; - // Sanity check that iteration order of SortedSizesPx is ascending. The // correctness of most usage of SortedSizesPx depends on this. TEST(WebAppTest, SortedSizesPxIsAscending) { @@ -64,7 +48,7 @@ ASSERT_THAT(base_reversed, ElementsAre(512, 256, 64, 32, 16)); } -TEST_P(WebAppUtilsTest, AreWebAppsEnabled) { +TEST_F(WebAppUtilsTest, AreWebAppsEnabled) { Profile* regular_profile = profile(); EXPECT_FALSE(AreWebAppsEnabled(nullptr)); @@ -80,9 +64,8 @@ Profile* guest_profile = profile_manager.CreateGuestProfile(); EXPECT_TRUE(AreWebAppsEnabled(guest_profile)); - if (!is_ephemeral_guest()) - EXPECT_TRUE(AreWebAppsEnabled( - guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true))); + EXPECT_TRUE(AreWebAppsEnabled( + guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true))); Profile* system_profile = profile_manager.CreateSystemProfile(); EXPECT_FALSE(AreWebAppsEnabled(system_profile)); @@ -125,7 +108,7 @@ #endif } -TEST_P(WebAppUtilsTest, AreWebAppsUserInstallable) { +TEST_F(WebAppUtilsTest, AreWebAppsUserInstallable) { Profile* regular_profile = profile(); EXPECT_FALSE(AreWebAppsEnabled(nullptr)); @@ -142,10 +125,8 @@ Profile* guest_profile = profile_manager.CreateGuestProfile(); EXPECT_FALSE(AreWebAppsUserInstallable(guest_profile)); - if (!is_ephemeral_guest()) { - EXPECT_FALSE(AreWebAppsUserInstallable( - guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true))); - } + EXPECT_FALSE(AreWebAppsUserInstallable( + guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true))); Profile* system_profile = profile_manager.CreateSystemProfile(); EXPECT_FALSE(AreWebAppsUserInstallable(system_profile)); @@ -167,7 +148,7 @@ #endif } -TEST_P(WebAppUtilsTest, GetBrowserContextForWebApps) { +TEST_F(WebAppUtilsTest, GetBrowserContextForWebApps) { Profile* regular_profile = profile(); EXPECT_EQ(regular_profile, GetBrowserContextForWebApps(regular_profile)); @@ -184,11 +165,9 @@ Profile* guest_profile = profile_manager.CreateGuestProfile(); EXPECT_EQ(guest_profile, GetBrowserContextForWebApps(guest_profile)); - if (!is_ephemeral_guest()) { - EXPECT_EQ(guest_profile, - GetBrowserContextForWebApps(guest_profile->GetPrimaryOTRProfile( - /*create_if_needed=*/true))); - } + EXPECT_EQ(guest_profile, + GetBrowserContextForWebApps(guest_profile->GetPrimaryOTRProfile( + /*create_if_needed=*/true))); Profile* system_profile = profile_manager.CreateSystemProfile(); EXPECT_EQ(nullptr, GetBrowserContextForWebApps(system_profile)); @@ -197,7 +176,7 @@ /*create_if_needed=*/true))); } -TEST_P(WebAppUtilsTest, GetBrowserContextForWebAppMetrics) { +TEST_F(WebAppUtilsTest, GetBrowserContextForWebAppMetrics) { Profile* regular_profile = profile(); EXPECT_EQ(regular_profile, @@ -217,12 +196,10 @@ Profile* guest_profile = profile_manager.CreateGuestProfile(); EXPECT_EQ(nullptr, GetBrowserContextForWebAppMetrics(guest_profile)); - if (!is_ephemeral_guest()) { - EXPECT_EQ( - nullptr, - GetBrowserContextForWebAppMetrics( - guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true))); - } + EXPECT_EQ( + nullptr, + GetBrowserContextForWebAppMetrics( + guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true))); Profile* system_profile = profile_manager.CreateSystemProfile(); EXPECT_EQ(nullptr, GetBrowserContextForWebAppMetrics(system_profile)); @@ -232,8 +209,4 @@ system_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true))); } -INSTANTIATE_TEST_SUITE_P(AllGuestTypes, - WebAppUtilsTest, - /*is_ephemeral_guest=*/testing::Bool()); - } // namespace web_app
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc index 296b09e..57a0899 100644 --- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -41,7 +41,7 @@ #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "components/policy/core/common/policy_pref_names.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) @@ -225,7 +225,7 @@ std::unique_ptr<WebApp> CreateWebApp(const GURL& start_url, Source::Type source_type) { - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->SetStartUrl(start_url); @@ -291,8 +291,8 @@ [this](const ExternalInstallOptions& install_options) -> ExternallyManagedAppManager::InstallResult { const GURL& install_url = install_options.install_url; - if (!app_registrar()->GetAppById( - GenerateAppIdFromURL(install_url))) { + if (!app_registrar()->GetAppById(GenerateAppId( + /*manifest_id=*/absl::nullopt, install_url))) { const auto install_source = install_options.install_source; std::unique_ptr<WebApp> web_app = CreateWebApp( install_url, @@ -300,7 +300,8 @@ RegisterApp(std::move(web_app)); externally_installed_app_prefs().Insert( - install_url, GenerateAppIdFromURL(install_url), + install_url, + GenerateAppId(/*manifest_id=*/absl::nullopt, install_url), install_source); } return {.code = install_result_code_}; @@ -326,8 +327,8 @@ url, ConvertExternalInstallSourceToSourceType(install_source)); RegisterApp(std::move(web_app)); - externally_installed_app_prefs().Insert(url, GenerateAppIdFromURL(url), - install_source); + externally_installed_app_prefs().Insert( + url, GenerateAppId(/*manifest_id=*/absl::nullopt, url), install_source); } void AwaitPolicyManagerAppsSynchronized() {
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/policy/web_app_policy_manager.cc index 7b0027d..944bb94 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_manager.cc +++ b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
@@ -31,8 +31,8 @@ #include "content/public/browser/browser_thread.h" #if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" #include "components/policy/core/common/policy_pref_names.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.h b/chrome/browser/web_applications/policy/web_app_policy_manager.h index 68a49e2..74203dc 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_manager.h +++ b/chrome/browser/web_applications/policy/web_app_policy_manager.h
@@ -16,7 +16,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) class PrefService;
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc index 77c6b10..562585f1 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
@@ -218,7 +218,7 @@ ASSERT_TRUE(embedded_test_server()->Start()); GURL start_url = embedded_test_server()->GetURL("/web_apps/basic.html"); - AppId app_id = GenerateAppIdFromURL(start_url); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); EXPECT_FALSE(registrar().IsInstalled(app_id)); constexpr char kAppConfigTemplate[] = @@ -255,7 +255,7 @@ "/web_apps/query_params_in_start_url.html"); GURL start_url = embedded_test_server()->GetURL( "/web_apps/query_params_in_start_url.html?query_params=in&start=url"); - AppId app_id = GenerateAppIdFromURL(start_url); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); EXPECT_FALSE(registrar().IsInstalled(app_id)); constexpr char kAppConfigTemplate[] = @@ -290,7 +290,7 @@ GURL start_url = embedded_test_server()->GetURL("/web_apps/basic.html"); GURL launch_url = embedded_test_server()->GetURL( "/web_apps/basic.html?more=than&one=query¶m"); - AppId app_id = GenerateAppIdFromURL(start_url); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); EXPECT_FALSE(registrar().IsInstalled(app_id)); constexpr char kAppConfigTemplate[] = @@ -324,7 +324,7 @@ "/web_apps/query_params_in_start_url.html"); GURL start_url = embedded_test_server()->GetURL( "/web_apps/query_params_in_start_url.html?query_params=in&start=url"); - AppId app_id = GenerateAppIdFromURL(start_url); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); EXPECT_FALSE(registrar().IsInstalled(app_id)); constexpr char kAppConfigTemplate[] = @@ -463,7 +463,8 @@ SyncPreinstalledAppConfig(GURL{kSimpleManifestStartUrl}, prev_app_config), InstallResultCode::kSuccessNewInstall); - AppId app_id = GenerateAppIdFromURL(GURL{kSimpleManifestStartUrl}); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL{kSimpleManifestStartUrl}); EXPECT_TRUE(registrar().IsInstalled(app_id)); } @@ -481,7 +482,8 @@ SyncPreinstalledAppConfig(GURL{kSimpleManifestStartUrl}, next_app_config), InstallResultCode::kSuccessAlreadyInstalled); - AppId app_id = GenerateAppIdFromURL(GURL{kSimpleManifestStartUrl}); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL{kSimpleManifestStartUrl}); EXPECT_TRUE(registrar().IsInstalled(app_id)); } @@ -498,7 +500,8 @@ prev_app_config), InstallResultCode::kNotValidManifestForWebApp); - AppId app_id = GenerateAppIdFromURL(GURL{kNoManifestTestPageStartUrl}); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL{kNoManifestTestPageStartUrl}); EXPECT_FALSE(registrar().IsInstalled(app_id)); } @@ -516,7 +519,8 @@ next_app_config), absl::nullopt); - AppId app_id = GenerateAppIdFromURL(GURL{kNoManifestTestPageStartUrl}); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL{kNoManifestTestPageStartUrl}); EXPECT_FALSE(registrar().IsInstalled(app_id)); } @@ -532,7 +536,8 @@ constexpr char kAppStartUrl[] = "https://offline-site.com/start.html"; constexpr char kAppScope[] = "https://offline-site.com/"; - AppId app_id = GenerateAppIdFromURL(GURL(kAppStartUrl)); + AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kAppStartUrl)); EXPECT_FALSE(registrar().IsInstalled(app_id)); constexpr char kAppConfigTemplate[] = @@ -583,7 +588,8 @@ "/web_apps/offline-only-start-url-that-does-not-exist.html"); GURL scope = embedded_test_server()->GetURL("/web_apps/"); - AppId offline_app_id = GenerateAppIdFromURL(offline_start_url); + AppId offline_app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, offline_start_url); EXPECT_FALSE(registrar().IsInstalled(offline_app_id)); constexpr char kAppConfigTemplate[] = @@ -609,7 +615,7 @@ EXPECT_FALSE(registrar().IsInstalled(offline_app_id)); // basic.html's manifest start_url is basic.html. - AppId app_id = GenerateAppIdFromURL(install_url); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, install_url); EXPECT_TRUE(registrar().IsInstalled(app_id)); EXPECT_EQ(registrar().GetAppShortName(app_id), "Basic web app"); EXPECT_EQ(registrar().GetAppStartUrl(app_id).spec(), install_url); @@ -627,7 +633,8 @@ constexpr char kAppStartUrl[] = "https://offline-site.com/start.html"; constexpr char kAppScope[] = "https://offline-site.com/"; - AppId app_id = GenerateAppIdFromURL(GURL(kAppStartUrl)); + AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(kAppStartUrl)); EXPECT_FALSE(registrar().IsInstalled(app_id)); constexpr char kAppConfigTemplate[] = @@ -679,7 +686,7 @@ "/web_apps/offline-only-start-url-that-does-not-exist.html"); GURL scope = embedded_test_server()->GetURL("/web_apps/"); - AppId app_id = GenerateAppIdFromURL(start_url); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); EXPECT_FALSE(registrar().IsInstalled(app_id)); constexpr char kAppConfigTemplate[] = @@ -795,7 +802,7 @@ {GetAppUrl().spec()}, nullptr)), InstallResultCode::kSuccessNewInstall); - AppId app_id = GenerateAppIdFromURL(GetAppUrl()); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, GetAppUrl()); EXPECT_TRUE(registrar().WasInstalledByOem(app_id)); } @@ -824,7 +831,7 @@ "user_type": ["unmanaged"] })", {GetAppUrl().spec()}, nullptr); - AppId app_id = GenerateAppIdFromURL(GetAppUrl()); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, GetAppUrl()); const auto& disabled_configs = manager().debug_info()->disabled_configs; constexpr char kErrorMessage[] = " disabled because the device does not have a built-in touchscreen with " @@ -897,7 +904,8 @@ kAppConfigTemplate, {preinstalled_app_start_url.spec()}, nullptr); EXPECT_EQ(SyncPreinstalledAppConfig(preinstalled_app_start_url, app_config), InstallResultCode::kSuccessOfflineOnlyInstall); - AppId preinstalled_app_id = GenerateAppIdFromURL(preinstalled_app_start_url); + AppId preinstalled_app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, preinstalled_app_start_url); // Install user app. auto web_application_info = std::make_unique<WebApplicationInfo>();
diff --git a/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc index 1b58206..638122fb 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc +++ b/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc
@@ -80,7 +80,9 @@ return embedded_test_server()->GetURL(kWebAppPath); } - AppId GetWebAppId() const { return GenerateAppIdFromURL(GetWebAppUrl()); } + AppId GetWebAppId() const { + return GenerateAppId(/*manifest_id=*/absl::nullopt, GetWebAppUrl()); + } // InProcessBrowserTest: void SetUp() override {
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc index 3af851b3..9804be1c 100644 --- a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc +++ b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc
@@ -35,16 +35,13 @@ std::vector<ExternalInstallOptions>* g_preinstalled_app_data_for_testing = nullptr; -bool g_force_use_preinstalled_web_apps_for_testing = false; - } // namespace std::vector<ExternalInstallOptions> GetPreinstalledWebApps() { if (g_preinstalled_app_data_for_testing) return *g_preinstalled_app_data_for_testing; - if (!g_force_use_preinstalled_web_apps_for_testing && - base::CommandLine::ForCurrentProcess()->HasSwitch( + if (base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kDisablePreinstalledApps)) { return {}; } @@ -79,10 +76,6 @@ return {}; } -void ForceUsePreinstalledWebAppsForTesting() { - g_force_use_preinstalled_web_apps_for_testing = true; -} - ScopedTestingPreinstalledAppData::ScopedTestingPreinstalledAppData() { DCHECK_EQ(nullptr, g_preinstalled_app_data_for_testing); g_preinstalled_app_data_for_testing = &apps;
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.h b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.h index d40e1fd..8703109c 100644 --- a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.h +++ b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.h
@@ -14,11 +14,6 @@ // Returns the list of web apps that should be pre-installed on new profiles. std::vector<ExternalInstallOptions> GetPreinstalledWebApps(); -// Preinstalled app configs are disabled in tests by default (having web apps -// install during start up adds a lot of noise). This allows tests to opt into -// having them install. -void ForceUsePreinstalledWebAppsForTesting(); - // A scoped helper to provide a testing set of preinstalled app data. This will // replace the default set. struct ScopedTestingPreinstalledAppData {
diff --git a/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc index 8ab718a..e5e702c5 100644 --- a/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc +++ b/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/web_applications/preinstalled_web_app_manager.h" #include "chrome/browser/web_applications/test/test_os_integration_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" @@ -24,7 +25,6 @@ PreinstalledWebAppManager::SkipStartupForTesting(); // Ignore any default app configs on disk. PreinstalledWebAppManager::SetConfigDirForTesting(&empty_path_); - ForceUsePreinstalledWebAppsForTesting(); WebAppProvider::SetOsIntegrationManagerFactoryForTesting( [](Profile* profile) -> std::unique_ptr<OsIntegrationManager> { return std::make_unique<TestOsIntegrationManager>( @@ -32,6 +32,14 @@ }); } + void SetUpDefaultCommandLine(base::CommandLine* command_line) override { + InProcessBrowserTest::SetUpDefaultCommandLine(command_line); + + // This was added by PrepareBrowserCommandLineForTests(), re-enable default + // apps as we wish to test that they get installed. + command_line->RemoveSwitch(switches::kDisablePreinstalledApps); + } + base::FilePath empty_path_; };
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc index 3aae8d1..48766eb3 100644 --- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
@@ -65,7 +65,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/ash/file_manager/file_manager_test_util.h" -#include "chrome/browser/chromeos/policy/handlers/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h"
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc index 715f42d3..61a399a 100644 --- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc +++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc
@@ -225,13 +225,14 @@ bool IsInstalled(const GURL& install_url) { return controller().registrar().IsInstalled( - GenerateAppIdFromURL(install_url)); + GenerateAppId(/*manifest_id=*/absl::nullopt, install_url)); } std::unique_ptr<WebApp> CreateWebApp( const GURL& start_url, Source::Type source_type = Source::kDefault) { - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->SetStartUrl(start_url); @@ -263,7 +264,8 @@ registry.emplace(app_id, std::move(web_app)); externally_installed_app_prefs().Insert( - data.url, GenerateAppIdFromURL(data.url), data.source); + data.url, GenerateAppId(/*manifest_id=*/absl::nullopt, data.url), + data.source); } InitRegistrarWithRegistry(registry); } @@ -1020,8 +1022,8 @@ } system_web_app_manager().set_current_version(base::Version("1.0.0.0")); StartAndWaitForAppsToSynchronize(); - EXPECT_TRUE( - system_web_app_manager().IsSystemWebApp(GenerateAppIdFromURL(AppUrl1()))); + EXPECT_TRUE(system_web_app_manager().IsSystemWebApp( + GenerateAppId(/*manifest_id=*/absl::nullopt, AppUrl1()))); auto unsynced_system_web_app_manager = std::make_unique<TestSystemWebAppManager>(profile()); @@ -1041,7 +1043,7 @@ } EXPECT_TRUE(unsynced_system_web_app_manager->IsSystemWebApp( - GenerateAppIdFromURL(AppUrl1()))); + GenerateAppId(/*manifest_id=*/absl::nullopt, AppUrl1()))); } class TimerSystemAppDelegate : public UnittestingSystemAppDelegate {
diff --git a/chrome/browser/web_applications/test/test_install_finalizer.cc b/chrome/browser/web_applications/test/test_install_finalizer.cc index 6f6e14f..8a65b64f 100644 --- a/chrome/browser/web_applications/test/test_install_finalizer.cc +++ b/chrome/browser/web_applications/test/test_install_finalizer.cc
@@ -22,7 +22,7 @@ // static AppId TestInstallFinalizer::GetAppIdForUrl(const GURL& url) { - return GenerateAppIdFromURL(url); + return GenerateAppId(/*manifest_id=*/absl::nullopt, url); } TestInstallFinalizer::TestInstallFinalizer() = default;
diff --git a/chrome/browser/web_applications/test/test_web_app_database_factory.cc b/chrome/browser/web_applications/test/test_web_app_database_factory.cc index 844ffe5..56270a0 100644 --- a/chrome/browser/web_applications/test/test_web_app_database_factory.cc +++ b/chrome/browser/web_applications/test/test_web_app_database_factory.cc
@@ -72,7 +72,7 @@ GURL start_url(proto->sync_data().start_url()); DCHECK(!start_url.is_empty()); DCHECK(start_url.is_valid()); - AppId app_id = GenerateAppIdFromURL(start_url); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); write_batch->WriteData(app_id, proto->SerializeAsString()); }
diff --git a/chrome/browser/web_applications/test/test_web_app_registry_controller.cc b/chrome/browser/web_applications/test/test_web_app_registry_controller.cc index 2a12f94..ca44046 100644 --- a/chrome/browser/web_applications/test/test_web_app_registry_controller.cc +++ b/chrome/browser/web_applications/test/test_web_app_registry_controller.cc
@@ -72,7 +72,7 @@ syncer::EntityChangeList entity_changes; for (const GURL& app_url : apps_to_add) { - const AppId app_id = GenerateAppIdFromURL(app_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, app_url); auto web_app_server_data = std::make_unique<WebApp>(app_id); web_app_server_data->SetName("WebApp name");
diff --git a/chrome/browser/web_applications/test/web_app_install_test_utils.cc b/chrome/browser/web_applications/test/web_app_install_test_utils.cc index 2764954..48f992e 100644 --- a/chrome/browser/web_applications/test/web_app_install_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
@@ -64,7 +64,7 @@ AppId InstallDummyWebApp(Profile* profile, const std::string& app_name, const GURL& start_url) { - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); WebApplicationInfo web_app_info; web_app_info.start_url = start_url;
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc index fdd9ad8..1ae2690 100644 --- a/chrome/browser/web_applications/test/web_app_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -213,7 +213,7 @@ std::unique_ptr<WebApp> CreateMinimalWebApp() { const GURL app_url("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(app_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, app_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->AddSource(Source::kSync);
diff --git a/chrome/browser/web_applications/web_app_database_unittest.cc b/chrome/browser/web_applications/web_app_database_unittest.cc index 7ecc58b..9fef1d0 100644 --- a/chrome/browser/web_applications/web_app_database_unittest.cc +++ b/chrome/browser/web_applications/web_app_database_unittest.cc
@@ -208,7 +208,7 @@ TEST_F(WebAppDatabaseTest, BackwardCompatibility_WebAppWithOnlyRequiredFields) { const GURL start_url{"https://example.com/"}; - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); const std::string name = "App Name"; const auto user_display_mode = DisplayMode::kBrowser; const bool is_locally_installed = true; @@ -272,7 +272,8 @@ controller().Init(); const auto start_url = GURL("https://example.com/"); - const AppId app_id = GenerateAppIdFromURL(GURL(start_url)); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(start_url)); const std::string name = "Name"; const auto user_display_mode = DisplayMode::kBrowser;
diff --git a/chrome/browser/web_applications/web_app_helpers.cc b/chrome/browser/web_applications/web_app_helpers.cc index 7ae17dd..057abc6c 100644 --- a/chrome/browser/web_applications/web_app_helpers.cc +++ b/chrome/browser/web_applications/web_app_helpers.cc
@@ -51,10 +51,6 @@ return crypto::SHA256HashString(url.spec()); } -AppId GenerateAppIdFromURL(const GURL& url) { - return crx_file::id_util::GenerateId(GenerateAppHashFromURL(url)); -} - std::string GenerateAppIdUnhashed( const absl::optional<std::string>& manifest_id, const GURL& start_url) {
diff --git a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc index 468a4b0..8e24ab50 100644 --- a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc
@@ -953,8 +953,10 @@ } TEST_F(WebAppIconManagerTest, DeleteData_Success) { - const AppId app1_id = GenerateAppIdFromURL(GURL("https://example.com/")); - const AppId app2_id = GenerateAppIdFromURL(GURL("https://example.org/")); + const AppId app1_id = GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://example.com/")); + const AppId app2_id = GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://example.org/")); const std::vector<int> sizes_px{icon_size::k128}; const std::vector<SkColor> colors{SK_ColorMAGENTA}; @@ -997,7 +999,8 @@ } TEST_F(WebAppIconManagerTest, DeleteData_Failure) { - const AppId app_id = GenerateAppIdFromURL(GURL("https://example.com/")); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://example.com/")); file_utils().SetNextDeleteFileRecursivelyResult(false);
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc index 11150e1..a208606 100644 --- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -234,7 +234,8 @@ std::unique_ptr<WebApp> CreateWebApp(const GURL& start_url, Source::Type source, DisplayMode user_display_mode) { - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->SetStartUrl(start_url); @@ -470,10 +471,10 @@ WebAppUrlLoader::Result::kUrlLoaded}); const GURL url1{"https://example.com/path"}; - const AppId app1_id = GenerateAppIdFromURL(url1); + const AppId app1_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url1); const GURL url2{"https://example.org/path"}; - const AppId app2_id = GenerateAppIdFromURL(url2); + const AppId app2_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url2); { std::unique_ptr<WebApp> app1 = CreateWebAppInSyncInstall( url1, "Name1 from sync", DisplayMode::kStandalone, SK_ColorRED, @@ -620,7 +621,7 @@ } const GURL start_url{"https://example.com/path"}; - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); { std::unique_ptr<WebApp> app_in_sync_install = CreateWebAppInSyncInstall( @@ -961,7 +962,8 @@ InitEmptyRegistrar(); const GURL url("https://example.com/path"); - const AppId expected_app_id = GenerateAppIdFromURL(url); + const AppId expected_app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, url); auto server_web_app_info = std::make_unique<WebApplicationInfo>(); server_web_app_info->start_url = url; @@ -1032,7 +1034,7 @@ } const GURL start_url{"https://example.com/path"}; - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); { std::unique_ptr<WebApp> app_in_sync_install = CreateWebAppInSyncInstall(
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc index 0a581eb..1d39457 100644 --- a/chrome/browser/web_applications/web_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -47,7 +47,6 @@ #include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" @@ -404,7 +403,7 @@ const GURL scope = GURL("https://example.com/scope"); const absl::optional<SkColor> theme_color = 0xFFAABBCC; - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); CreateRendererAppInfo(url, "Renderer Name", description, /*scope*/ GURL{}, theme_color, @@ -451,7 +450,7 @@ TEST_F(WebAppInstallTaskTest, ForceReinstall) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); CreateDefaultDataToRetrieve(url); CreateRendererAppInfo(url, "Renderer Name", "Renderer Description"); @@ -554,7 +553,8 @@ GURL("https://renderer.com/scope"), 0x00, /*open_as_window*/ true); const GURL manifest_start_url = GURL("https://example.com/start"); - const AppId app_id = GenerateAppIdFromURL(manifest_start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, manifest_start_url); const std::string manifest_name = "Name from Manifest"; const GURL manifest_scope = GURL("https://example.com/scope"); const absl::optional<SkColor> manifest_theme_color = 0xAABBCCDD; @@ -817,7 +817,7 @@ EXPECT_TRUE(file_utils_->DirectoryExists(temp_dir)); EXPECT_TRUE(file_utils_->IsDirectoryEmpty(temp_dir)); - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); const base::FilePath app_dir = manifest_resources_directory.AppendASCII(app_id); EXPECT_FALSE(file_utils_->DirectoryExists(app_dir)); @@ -825,7 +825,7 @@ TEST_F(WebAppInstallTaskTest, UserInstallDeclined) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); CreateDefaultDataToRetrieve(url); CreateRendererAppInfo(url, "Name", "Description"); @@ -891,7 +891,7 @@ TEST_F(WebAppInstallTaskTest, InstallWebAppFromManifest_Success) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); auto manifest = std::make_unique<blink::Manifest>(); manifest->start_url = url; @@ -919,7 +919,7 @@ SetInstallFinalizerForTesting(); const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); auto web_app_info = std::make_unique<WebApplicationInfo>(); web_app_info->start_url = url; @@ -1062,20 +1062,8 @@ } #endif -class GuestWebAppInstallTaskTest : public WebAppInstallTaskTest, - public ::testing::WithParamInterface<bool> { - public: - GuestWebAppInstallTaskTest() { - TestingProfile::SetScopedFeatureListForEphemeralGuestProfiles( - scoped_feature_list_, GetParam()); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - // Default apps should be installable for guest profiles. -TEST_P(GuestWebAppInstallTaskTest, InstallWebAppWithParams_GuestProfile) { +TEST_F(WebAppInstallTaskTest, InstallWebAppWithParams_GuestProfile) { SetInstallFinalizerForTesting(); TestingProfileManager profile_manager(TestingBrowserProcess::GetGlobal()); @@ -1103,10 +1091,6 @@ run_loop.Run(); } -INSTANTIATE_TEST_SUITE_P(AllGuestTypes, - GuestWebAppInstallTaskTest, - /*is_ephemeral_guest=*/testing::Bool()); - TEST_F(WebAppInstallTaskTest, InstallWebAppWithParams_DisplayMode) { { CreateDataToRetrieve(GURL("https://example.com/"), @@ -1150,8 +1134,8 @@ TEST_F(WebAppInstallTaskTest, InstallWebAppFromManifest_ExpectAppId) { const auto url1 = GURL("https://example.com/"); const auto url2 = GURL("https://example.org/"); - const AppId app_id1 = GenerateAppIdFromURL(url1); - const AppId app_id2 = GenerateAppIdFromURL(url2); + const AppId app_id1 = GenerateAppId(/*manifest_id=*/absl::nullopt, url1); + const AppId app_id2 = GenerateAppId(/*manifest_id=*/absl::nullopt, url2); ASSERT_NE(app_id1, app_id2); { CreateDefaultDataToRetrieve(url1); @@ -1174,7 +1158,7 @@ TEST_F(WebAppInstallTaskTest, LoadAndInstallWebAppFromManifestWithFallback) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); { CreateDefaultDataToRetrieve(url); url_loader().SetNextLoadUrlResult( @@ -1223,7 +1207,7 @@ const GURL start_url = GURL("https://example.com/start"); const std::string name = "Name"; const std::string description = "Description"; - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); { CreateDefaultDataToRetrieve(url); url_loader().SetNextLoadUrlResult( @@ -1283,7 +1267,8 @@ TEST_F(WebAppInstallTaskTest, StorageIsolationFlagSaved) { const GURL manifest_start_url = GURL("https://example.com/start"); - const AppId app_id = GenerateAppIdFromURL(manifest_start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, manifest_start_url); auto manifest = std::make_unique<blink::Manifest>(); manifest->short_name = u"Short Name from Manifest"; @@ -1331,7 +1316,7 @@ const GURL scope = GURL("https://example.com/scope"); const absl::optional<SkColor> theme_color = 0xFFAABBCC; - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); CreateDefaultDataToRetrieve(url, scope); CreateRendererAppInfo(url, name, description, /*scope=*/GURL{}, theme_color, @@ -1378,7 +1363,7 @@ const GURL scope = GURL("https://example.com/scope"); const absl::optional<SkColor> theme_color = 0xFFAABBCC; - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); CreateDefaultDataToRetrieve(url, scope); CreateRendererAppInfo(url, name, description, /*scope=*/GURL{}, theme_color, @@ -1516,7 +1501,7 @@ SquareSizePx icon_size, GURL icon_src) { InstallResult result; - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); auto web_app_info = std::make_unique<WebApplicationInfo>(); web_app_info->start_url = url; @@ -1601,7 +1586,7 @@ TEST_F(WebAppInstallTaskTestWithShortcutsMenu, InstallWebAppFromManifest_Success) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); InstallResult result = InstallWebAppWithShortcutsMenuValidateAndGetResults( url, kInitialThemeColor, "shortcut", @@ -1614,7 +1599,7 @@ TEST_F(WebAppInstallTaskTestWithShortcutsMenu, UpdateWebAppFromInfo_AddShortcutsMenu) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); // Install the app without a shortcuts menu. { @@ -1639,7 +1624,7 @@ TEST_F(WebAppInstallTaskTestWithShortcutsMenu, UpdateWebAppFromInfo_UpdateShortcutsMenu) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); // Install the app. { @@ -1665,7 +1650,7 @@ TEST_F(WebAppInstallTaskTestWithShortcutsMenu, UpdateWebAppFromInfo_ShortcutsMenuNotChanged) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); // Install the app. { @@ -1787,7 +1772,7 @@ TEST_F(WebAppInstallTaskTestWithFileHandlers, InstallWebAppFromManifest_OsIntegrationEnabledForUserInstalledApps) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); auto manifest = CreateManifest(url); AddFileHandler(&manifest->file_handlers); @@ -1802,7 +1787,7 @@ TEST_F(WebAppInstallTaskTestWithFileHandlers, InstallWebAppFromManifest_OsIntegrationDisabledForDefaultApps) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); auto manifest = CreateManifest(url); AddFileHandler(&manifest->file_handlers); @@ -1822,7 +1807,7 @@ TEST_F(WebAppInstallTaskTestWithFileHandlers, UpdateWebAppFromInfo_OsIntegrationEnabledForUserInstalledApps) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); // Install the app. InstallResult install_result = InstallWebAppFromManifest( @@ -1847,7 +1832,7 @@ TEST_F(WebAppInstallTaskTestWithFileHandlers, UpdateWebAppFromInfo_OsIntegrationDisabledForDefaultApps) { const GURL url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, url); // Install the app. InstallResult install_result = InstallWebAppFromManifest(
diff --git a/chrome/browser/web_applications/web_app_installation_utils_unittest.cc b/chrome/browser/web_applications/web_app_installation_utils_unittest.cc index d9a3a0c..feedeba 100644 --- a/chrome/browser/web_applications/web_app_installation_utils_unittest.cc +++ b/chrome/browser/web_applications/web_app_installation_utils_unittest.cc
@@ -42,7 +42,8 @@ web_app_info.theme_color = SK_ColorCYAN; web_app_info.background_color = SK_ColorMAGENTA; - const AppId app_id = GenerateAppIdFromURL(web_app_info.start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, web_app_info.start_url); auto web_app = std::make_unique<WebApp>(app_id); SetWebAppManifestFields(web_app_info, *web_app); @@ -67,7 +68,8 @@ web_app_info.scope = web_app_info.start_url.GetWithoutFilename(); web_app_info.title = u"App Name"; - const AppId app_id = GenerateAppIdFromURL(web_app_info.start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, web_app_info.start_url); auto web_app = std::make_unique<WebApp>(app_id); { @@ -153,7 +155,8 @@ web_app_info.scope = web_app_info.start_url.GetWithoutFilename(); web_app_info.title = u"App Name"; - const AppId app_id = GenerateAppIdFromURL(web_app_info.start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, web_app_info.start_url); auto web_app = std::make_unique<WebApp>(app_id); {
diff --git a/chrome/browser/web_applications/web_app_mover_browsertest.cc b/chrome/browser/web_applications/web_app_mover_browsertest.cc index 5c856cf..b7dcd70a 100644 --- a/chrome/browser/web_applications/web_app_mover_browsertest.cc +++ b/chrome/browser/web_applications/web_app_mover_browsertest.cc
@@ -136,7 +136,7 @@ } ASSERT_EQ(GetProvider().registrar().GetAppIds().size(), 1ul); EXPECT_EQ(GetProvider().registrar().GetAppIds().front(), - GenerateAppIdFromURL(GetMigratingToApp())); + GenerateAppId(/*manifest_id=*/absl::nullopt, GetMigratingToApp())); } class WebAppMoverPatternBrowsertest : public WebAppMoverBrowsertestBase { @@ -171,10 +171,12 @@ completed_callback_ = run_loop.QuitClosure(); run_loop.Run(); } - EXPECT_THAT(GetProvider().registrar().GetAppIds(), - testing::UnorderedElementsAre( - GenerateAppIdFromURL(GetMigratingToApp()), - GenerateAppIdFromURL(GetMigratingFromAppB()))); + EXPECT_THAT( + GetProvider().registrar().GetAppIds(), + testing::UnorderedElementsAre( + GenerateAppId(/*manifest_id=*/absl::nullopt, GetMigratingToApp()), + GenerateAppId(/*manifest_id=*/absl::nullopt, + GetMigratingFromAppB()))); } // The WebAppMover requires a full match. This tests that a partial match @@ -215,11 +217,13 @@ } EXPECT_EQ(GetProvider().registrar().GetAppIds().size(), 3ul); - EXPECT_THAT(GetProvider().registrar().GetAppIds(), - testing::UnorderedElementsAre( - GenerateAppIdFromURL(GetMigratingFromAppA()), - GenerateAppIdFromURL(GetMigratingFromAppB()), - GenerateAppIdFromURL(GetMigratingFromAppC()))); + EXPECT_THAT( + GetProvider().registrar().GetAppIds(), + testing::UnorderedElementsAre( + GenerateAppId(/*manifest_id=*/absl::nullopt, GetMigratingFromAppA()), + GenerateAppId(/*manifest_id=*/absl::nullopt, GetMigratingFromAppB()), + GenerateAppId(/*manifest_id=*/absl::nullopt, + GetMigratingFromAppC()))); } } // namespace
diff --git a/chrome/browser/web_applications/web_app_registrar_unittest.cc b/chrome/browser/web_applications/web_app_registrar_unittest.cc index 8abe81b..e009e5f 100644 --- a/chrome/browser/web_applications/web_app_registrar_unittest.cc +++ b/chrome/browser/web_applications/web_app_registrar_unittest.cc
@@ -37,7 +37,8 @@ for (int i = 0; i < num_apps; ++i) { const auto url = base_url + base::NumberToString(i); - const AppId app_id = GenerateAppIdFromURL(GURL(url)); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, GURL(url)); auto web_app = std::make_unique<WebApp>(app_id); web_app->AddSource(Source::kSync); @@ -134,7 +135,8 @@ std::unique_ptr<WebApp> CreateWebAppWithSource(const std::string& url, Source::Type source) { const GURL start_url(url); - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto web_app = std::make_unique<WebApp>(app_id); @@ -172,14 +174,15 @@ EXPECT_FALSE(registrar().GetAppById(AppId())); const GURL start_url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); const std::string name = "Name"; const std::string description = "Description"; const GURL scope = GURL("https://example.com/scope"); const absl::optional<SkColor> theme_color = 0xAABBCCDD; const GURL start_url2 = GURL("https://example.com/path2"); - const AppId app_id2 = GenerateAppIdFromURL(start_url2); + const AppId app_id2 = + GenerateAppId(/*manifest_id=*/absl::nullopt, start_url2); auto web_app = std::make_unique<WebApp>(app_id); auto web_app2 = std::make_unique<WebApp>(app_id2); @@ -386,7 +389,7 @@ controller().Init(); const GURL start_url = GURL("https://example.com/path"); - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); const std::string name = "Name"; const std::string description = "Description"; const absl::optional<SkColor> theme_color = 0xAABBCCDD; @@ -466,9 +469,12 @@ const GURL app2_scope("https://example.com/app-two"); const GURL app3_scope("https://not-example.com/app"); - const AppId app1_id = GenerateAppIdFromURL(app1_scope); - const AppId app2_id = GenerateAppIdFromURL(app2_scope); - const AppId app3_id = GenerateAppIdFromURL(app3_scope); + const AppId app1_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app1_scope); + const AppId app2_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app2_scope); + const AppId app3_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app3_scope); std::vector<AppId> in_scope = registrar().FindAppsInScope(origin_scope); EXPECT_EQ(0u, in_scope.size()); @@ -527,9 +533,12 @@ const GURL app2_scope("https://example.com/app-two"); const GURL app3_scope("https://not-example.com/app"); - const AppId app1_id = GenerateAppIdFromURL(app1_scope); - const AppId app2_id = GenerateAppIdFromURL(app2_scope); - const AppId app3_id = GenerateAppIdFromURL(app3_scope); + const AppId app1_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app1_scope); + const AppId app2_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app2_scope); + const AppId app3_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app3_scope); auto app1 = CreateWebApp(app1_scope.spec()); app1->SetScope(app1_scope); @@ -581,9 +590,12 @@ const GURL app2_launch("https://example.com/app-two/launch"); const GURL app3_launch("https://not-example.com/app/launch"); - const AppId app1_id = GenerateAppIdFromURL(app1_launch); - const AppId app2_id = GenerateAppIdFromURL(app2_launch); - const AppId app3_id = GenerateAppIdFromURL(app3_launch); + const AppId app1_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app1_launch); + const AppId app2_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app2_launch); + const AppId app3_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app3_launch); // Implicit scope "https://example.com/app/" auto app1 = CreateWebApp(app1_launch.spec()); @@ -624,7 +636,8 @@ const GURL app2_scope("https://example.com/app"); const GURL app2_page("https://example.com/app/specific/page2"); - const AppId app2_id = GenerateAppIdFromURL(app2_scope); + const AppId app2_id = + GenerateAppId(/*manifest_id=*/absl::nullopt, app2_scope); const GURL app3_launch("https://example.com/app/specific/launch3"); @@ -745,7 +758,7 @@ controller().Init(); const GURL start_url("https://example.com"); - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); const WebApp* app = nullptr; { auto new_app = CreateWebApp(start_url.spec());
diff --git a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc index e990c652..7f5eb2c 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc +++ b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
@@ -52,7 +52,8 @@ return false; const GURL sync_start_url(entity_data.specifics.web_app().start_url()); - if (expected_app.app_id() != GenerateAppIdFromURL(sync_start_url)) + if (expected_app.app_id() != + GenerateAppId(/*manifest_id=*/absl::nullopt, sync_start_url)) return false; // ApplySyncDataToApp enforces kSync source on |app_to_apply_sync_data|. @@ -91,7 +92,7 @@ std::unique_ptr<WebApp> CreateWebApp(const std::string& url) { const GURL start_url(url); - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->SetStartUrl(start_url); @@ -102,7 +103,7 @@ std::unique_ptr<WebApp> CreateWebAppWithSyncOnlyFields(const std::string& url) { const GURL start_url(url); - const AppId app_id = GenerateAppIdFromURL(start_url); + const AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); auto web_app = std::make_unique<WebApp>(app_id); web_app->AddSource(Source::kSync);
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc index 6013df65e..27ca8aa 100644 --- a/chrome/browser/web_applications/web_app_unittest.cc +++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -26,7 +26,8 @@ } // namespace TEST(WebAppTest, HasAnySources) { - WebApp app{GenerateAppIdFromURL(GURL("https://example.com"))}; + WebApp app{GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://example.com"))}; EXPECT_FALSE(app.HasAnySources()); for (int i = Source::kMinValue; i <= Source::kMaxValue; ++i) { @@ -42,7 +43,8 @@ } TEST(WebAppTest, HasOnlySource) { - WebApp app{GenerateAppIdFromURL(GURL("https://example.com"))}; + WebApp app{GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://example.com"))}; for (int i = Source::kMinValue; i <= Source::kMaxValue; ++i) { auto source = static_cast<Source::Type>(i); @@ -78,7 +80,8 @@ } TEST(WebAppTest, WasInstalledByUser) { - WebApp app{GenerateAppIdFromURL(GURL("https://example.com"))}; + WebApp app{GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://example.com"))}; app.AddSource(Source::kSync); EXPECT_TRUE(app.WasInstalledByUser()); @@ -112,7 +115,8 @@ } TEST(WebAppTest, CanUserUninstallWebApp) { - WebApp app{GenerateAppIdFromURL(GURL("https://example.com"))}; + WebApp app{GenerateAppId(/*manifest_id=*/absl::nullopt, + GURL("https://example.com"))}; app.AddSource(Source::kDefault); EXPECT_TRUE(app.IsPreinstalledApp());
diff --git a/chrome/browser/webshare/safe_browsing_request.cc b/chrome/browser/webshare/safe_browsing_request.cc new file mode 100644 index 0000000..24bcbb0 --- /dev/null +++ b/chrome/browser/webshare/safe_browsing_request.cc
@@ -0,0 +1,113 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/webshare/safe_browsing_request.h" + +#include <utility> + +#include "base/bind.h" +#include "base/location.h" +#include "base/task/task_traits.h" +#include "base/task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "base/timer/timer.h" +#include "components/safe_browsing/core/browser/db/database_manager.h" +#include "content/public/browser/browser_task_traits.h" +#include "url/gurl.h" + +namespace { + +// The maximum amount of time to wait for the Safe Browsing response. +constexpr base::TimeDelta kSafeBrowsingCheckTimeout = + base::TimeDelta::FromSeconds(2); + +} // namespace + +// SafeBrowsingRequest::SafeBrowsingClient -------------------------- + +class SafeBrowsingRequest::SafeBrowsingClient + : public safe_browsing::SafeBrowsingDatabaseManager::Client { + public: + SafeBrowsingClient(scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> + database_manager, + base::WeakPtr<SafeBrowsingRequest> handler, + scoped_refptr<base::TaskRunner> handler_task_runner) + : database_manager_(database_manager), + handler_(handler), + handler_task_runner_(handler_task_runner) {} + + ~SafeBrowsingClient() override { + if (timeout_.IsRunning()) + database_manager_->CancelApiCheck(this); + } + + void CheckUrl(const GURL& url) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + // Start the timer before the call to CheckDownloadUrl(), as it may + // call back into CheckDownloadUrl() synchronously. + timeout_.Start(FROM_HERE, kSafeBrowsingCheckTimeout, this, + &SafeBrowsingClient::OnTimeout); + + if (!database_manager_->IsSupported() || + database_manager_->CheckDownloadUrl({url}, this)) { + timeout_.AbandonAndStop(); + SendResultToHandler(/*is_url_safe=*/true); + } + } + + private: + SafeBrowsingClient(const SafeBrowsingClient&) = delete; + SafeBrowsingClient& operator=(const SafeBrowsingClient&) = delete; + + void OnTimeout() { + database_manager_->CancelApiCheck(this); + SendResultToHandler(/*is_url_safe=*/true); + } + + void SendResultToHandler(bool is_url_safe) { + handler_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&SafeBrowsingRequest::OnResultReceived, + handler_, is_url_safe)); + } + + // SafeBrowsingDatabaseManager::Client: + void OnCheckDownloadUrlResult( + const std::vector<GURL>& url_chain, + safe_browsing::SBThreatType threat_type) override { + timeout_.AbandonAndStop(); + bool is_url_safe = threat_type == safe_browsing::SB_THREAT_TYPE_SAFE; + SendResultToHandler(is_url_safe); + } + + base::OneShotTimer timeout_; + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_; + base::WeakPtr<SafeBrowsingRequest> handler_; + scoped_refptr<base::TaskRunner> handler_task_runner_; +}; + +// SafeBrowsingRequest ---------------------------------------------- + +SafeBrowsingRequest::SafeBrowsingRequest( + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager, + const GURL& url, + base::OnceCallback<void(bool)> callback) + : callback_(std::move(callback)) { + client_ = std::make_unique<SafeBrowsingClient>( + database_manager, weak_factory_.GetWeakPtr(), + base::SequencedTaskRunnerHandle::Get()); + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&SafeBrowsingClient::CheckUrl, + base::Unretained(client_.get()), url)); +} + +SafeBrowsingRequest::~SafeBrowsingRequest() { + content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, + client_.release()); +} + +void SafeBrowsingRequest::OnResultReceived(bool is_url_safe) { + DCHECK(callback_); + std::move(callback_).Run(is_url_safe); +}
diff --git a/chrome/browser/webshare/safe_browsing_request.h b/chrome/browser/webshare/safe_browsing_request.h new file mode 100644 index 0000000..869580e --- /dev/null +++ b/chrome/browser/webshare/safe_browsing_request.h
@@ -0,0 +1,58 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEBSHARE_SAFE_BROWSING_REQUEST_H_ +#define CHROME_BROWSER_WEBSHARE_SAFE_BROWSING_REQUEST_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "content/public/browser/browser_thread.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" + +namespace safe_browsing { +class SafeBrowsingDatabaseManager; +} + +// Represents a single request to the Safe Browsing service to check whether +// a website is safe when sharing files with the Web Share API. It is used for +// PDFs for instance on Desktop platforms. Can be created and used on any one +// thread. +class SafeBrowsingRequest { + public: + // Constructs a request that check whether a website |url| is safe by + // consulting the |database_manager|, and invokes |callback| when done. + // + // It is guaranteed that |callback| will never be invoked synchronously, and + // it will not be invoked after |this| goes out of scope. + SafeBrowsingRequest(scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> + database_manager, + const GURL& url, + base::OnceCallback<void(bool)> callback); + ~SafeBrowsingRequest(); + + private: + class SafeBrowsingClient; + + SafeBrowsingRequest(const SafeBrowsingRequest&) = delete; + SafeBrowsingRequest& operator=(const SafeBrowsingRequest&) = delete; + + // Posted by the |client_| from the IO thread when it gets a response. + void OnResultReceived(bool is_url_safe); + + // The client interfacing with Safe Browsing. Created on |this| thread, but + // used on the IO thread for the rest of its life and destroyed there. + std::unique_ptr<SafeBrowsingClient> client_; + + base::OnceCallback<void(bool)> callback_; + + base::WeakPtrFactory<SafeBrowsingRequest> weak_factory_{this}; +}; + +#endif // CHROME_BROWSER_WEBSHARE_SAFE_BROWSING_REQUEST_H_
diff --git a/chrome/browser/webshare/share_service_browsertest.cc b/chrome/browser/webshare/share_service_browsertest.cc index 0f80a95..6bce2ae 100644 --- a/chrome/browser/webshare/share_service_browsertest.cc +++ b/chrome/browser/webshare/share_service_browsertest.cc
@@ -5,11 +5,14 @@ #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/safe_browsing/core/browser/db/fake_database_manager.h" +#include "content/public/browser/browser_task_traits.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" @@ -106,3 +109,61 @@ EXPECT_EQ("share succeeded", result); } + +class SafeBrowsingShareServiceBrowserTest : public ShareServiceBrowserTest { + public: + SafeBrowsingShareServiceBrowserTest() + : safe_browsing_factory_( + std::make_unique<safe_browsing::TestSafeBrowsingServiceFactory>()) { + } + + protected: + void CreatedBrowserMainParts( + content::BrowserMainParts* browser_main_parts) override { + fake_safe_browsing_database_manager_ = + base::MakeRefCounted<safe_browsing::FakeSafeBrowsingDatabaseManager>( + content::GetUIThreadTaskRunner({}), + content::GetIOThreadTaskRunner({})); + safe_browsing_factory_->SetTestDatabaseManager( + fake_safe_browsing_database_manager_.get()); + safe_browsing::SafeBrowsingService::RegisterFactory( + safe_browsing_factory_.get()); + ShareServiceBrowserTest::CreatedBrowserMainParts(browser_main_parts); + } + + void AddDangerousUrl(const GURL& dangerous_url) { + fake_safe_browsing_database_manager_->AddDangerousUrl( + dangerous_url, safe_browsing::SB_THREAT_TYPE_URL_BINARY_MALWARE); + } + + void TearDown() override { + ShareServiceBrowserTest::TearDown(); + safe_browsing::SafeBrowsingService::RegisterFactory(nullptr); + } + + private: + scoped_refptr<safe_browsing::FakeSafeBrowsingDatabaseManager> + fake_safe_browsing_database_manager_; + std::unique_ptr<safe_browsing::TestSafeBrowsingServiceFactory> + safe_browsing_factory_; +}; + +IN_PROC_BROWSER_TEST_F(SafeBrowsingShareServiceBrowserTest, + PortableDocumentFile) { +#if defined(OS_WIN) + if (!IsSupportedEnvironment()) + return; +#endif + + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url(embedded_test_server()->GetURL("/webshare/index.html")); + ui_test_utils::NavigateToURL(browser(), url); + content::WebContents* const contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_EQ("share succeeded", content::EvalJs(contents, "share_pdf_file()")); + + AddDangerousUrl(url); + EXPECT_EQ("share failed: NotAllowedError: Permission denied", + content::EvalJs(contents, "share_pdf_file()")); +}
diff --git a/chrome/browser/webshare/share_service_impl.cc b/chrome/browser/webshare/share_service_impl.cc index 34662478..1880f6e5 100644 --- a/chrome/browser/webshare/share_service_impl.cc +++ b/chrome/browser/webshare/share_service_impl.cc
@@ -11,7 +11,11 @@ #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/chrome_features.h" +#include "components/safe_browsing/content/common/file_type_policies.h" +#include "components/safe_browsing/core/browser/db/database_manager.h" #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" @@ -50,7 +54,7 @@ // static bool ShareServiceImpl::IsDangerousFilename(base::StringPiece name) { - constexpr std::array<const char*, 39> kPermitted = { + constexpr std::array<const char*, 40> kPermitted = { ".bmp", // image/bmp / image/x-ms-bmp ".css", // text/css ".csv", // text/csv / text/comma-separated-values @@ -74,6 +78,7 @@ ".ogm", // video/ogg ".ogv", // video/ogg ".opus", // audio/ogg + ".pdf", // application/pdf ".pjp", // image/jpeg ".pjpeg", // image/jpeg ".png", // image/png @@ -101,7 +106,8 @@ // static bool ShareServiceImpl::IsDangerousMimeType(base::StringPiece content_type) { - constexpr std::array<const char*, 26> kPermitted = { + constexpr std::array<const char*, 27> kPermitted = { + "application/pdf", "audio/flac", "audio/mp3", "audio/mpeg", @@ -156,6 +162,7 @@ return; } + bool should_check_url = false; for (auto& file : files) { if (!file || !file->blob || !file->blob->blob) { mojo::ReportBadMessage("Invalid file to share()"); @@ -170,6 +177,15 @@ return; } + // Check if at least one file is marked by the download protection service + // to send a ping to check this file type. + const base::FilePath path = base::FilePath::FromUTF8Unsafe(file->name); + if (!should_check_url && + safe_browsing::FileTypePolicies::GetInstance()->IsCheckedBinaryFile( + path)) { + should_check_url = true; + } + // In the case where the original blob handle was to a native file (of // unknown size), the serialized data does not contain an accurate file // size. To handle this, the comparison against kMaxSharedFileBytes should @@ -177,6 +193,45 @@ // the blobs. } + DCHECK(!safe_browsing_request_); + if (should_check_url && g_browser_process->safe_browsing_service()) { + safe_browsing_request_.emplace( + g_browser_process->safe_browsing_service()->database_manager(), + web_contents->GetLastCommittedURL(), + base::BindOnce(&ShareServiceImpl::OnSafeBrowsingResultReceived, + weak_factory_.GetWeakPtr(), title, text, share_url, + std::move(files), std::move(callback))); + return; + } + + OnSafeBrowsingResultReceived(title, text, share_url, std::move(files), + std::move(callback), + /*is_url_safe=*/true); +} + +void ShareServiceImpl::OnSafeBrowsingResultReceived( + const std::string& title, + const std::string& text, + const GURL& share_url, + std::vector<blink::mojom::SharedFilePtr> files, + ShareCallback callback, + bool is_url_safe) { + safe_browsing_request_.reset(); + + content::WebContents* const web_contents = + content::WebContents::FromRenderFrameHost(render_frame_host_); + if (!web_contents) { + VLOG(1) << "Cannot share after navigating away"; + std::move(callback).Run(blink::mojom::ShareError::PERMISSION_DENIED); + return; + } + + if (!is_url_safe) { + VLOG(1) << "File not safe to share from this website"; + std::move(callback).Run(blink::mojom::ShareError::PERMISSION_DENIED); + return; + } + #if BUILDFLAG(IS_CHROMEOS_ASH) sharesheet_client_.Share(title, text, share_url, std::move(files), std::move(callback));
diff --git a/chrome/browser/webshare/share_service_impl.h b/chrome/browser/webshare/share_service_impl.h index 97104c9..838b38d2 100644 --- a/chrome/browser/webshare/share_service_impl.h +++ b/chrome/browser/webshare/share_service_impl.h
@@ -8,10 +8,13 @@ #include <string> #include <vector> +#include "base/memory/weak_ptr.h" #include "base/strings/string_piece.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/webshare/safe_browsing_request.h" #include "content/public/browser/web_contents_observer.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/webshare/webshare.mojom.h" #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -49,14 +52,26 @@ std::vector<blink::mojom::SharedFilePtr> files, ShareCallback callback) override; + void OnSafeBrowsingResultReceived( + const std::string& title, + const std::string& text, + const GURL& share_url, + std::vector<blink::mojom::SharedFilePtr> files, + ShareCallback callback, + bool is_safe); + // content::WebContentsObserver: void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; private: + absl::optional<SafeBrowsingRequest> safe_browsing_request_; + #if BUILDFLAG(IS_CHROMEOS_ASH) webshare::SharesheetClient sharesheet_client_; #endif content::RenderFrameHost* render_frame_host_; + + base::WeakPtrFactory<ShareServiceImpl> weak_factory_{this}; }; #endif // CHROME_BROWSER_WEBSHARE_SHARE_SERVICE_IMPL_H_
diff --git a/chrome/browser/webshare/share_service_unittest.cc b/chrome/browser/webshare/share_service_unittest.cc index 7491e1e..4c8a50fb 100644 --- a/chrome/browser/webshare/share_service_unittest.cc +++ b/chrome/browser/webshare/share_service_unittest.cc
@@ -232,10 +232,7 @@ return; #endif - // TODO(crbug.com/1006055): Support sharing of pdf files. - // The URL will be checked using Safe Browsing. - EXPECT_EQ(ShareError::PERMISSION_DENIED, - ShareGeneratedFileData(".pdf", "application/pdf")); + EXPECT_EQ(ShareError::OK, ShareGeneratedFileData(".pdf", "application/pdf")); } #if defined(OS_WIN)
diff --git a/chrome/browser/win/conflicts/third_party_conflicts_manager.cc b/chrome/browser/win/conflicts/third_party_conflicts_manager.cc index 47210739..342b427 100644 --- a/chrome/browser/win/conflicts/third_party_conflicts_manager.cc +++ b/chrome/browser/win/conflicts/third_party_conflicts_manager.cc
@@ -40,6 +40,8 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include <windows.h> + namespace { scoped_refptr<ModuleListFilter> CreateModuleListFilter(
diff --git a/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc b/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc index cf590f10..cbe6d59 100644 --- a/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc +++ b/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc
@@ -34,19 +34,6 @@ })(); )"; -#if !defined(OS_WIN) -// TODO(enne): Remove this in http://crbug.com/1205676 -constexpr char kDeprecatedIsMultiscreen[] = R"( - (async () => { - try { - return await window.isMultiScreen() - } catch (e) { - return 'error'; - } - })(); -)"; -#endif // !defined(OS_WIN) - // Tests of WindowPlacementPermissionContext behavior. class WindowPlacementPermissionContextTest : public InProcessBrowserTest { public: @@ -260,12 +247,6 @@ content::EXECUTE_SCRIPT_NO_USER_GESTURE)); EXPECT_EQ(true, EvalJs(child, R"(window.screen.isExtended)", content::EXECUTE_SCRIPT_NO_USER_GESTURE)); - - // TODO(enne): Remove this in http://crbug.com/1205676 - EXPECT_EQ(true, EvalJs(tab, kDeprecatedIsMultiscreen, - content::EXECUTE_SCRIPT_NO_USER_GESTURE)); - EXPECT_EQ(true, EvalJs(child, kDeprecatedIsMultiscreen, - content::EXECUTE_SCRIPT_NO_USER_GESTURE)); } // Verify that window.screen.isExtended returns false in a cross-origin @@ -286,12 +267,6 @@ content::EXECUTE_SCRIPT_NO_USER_GESTURE)); EXPECT_EQ(false, EvalJs(child, R"(window.screen.isExtended)", content::EXECUTE_SCRIPT_NO_USER_GESTURE)); - - // TODO(enne): Remove this in http://crbug.com/1205676 - EXPECT_EQ(true, EvalJs(tab, kDeprecatedIsMultiscreen, - content::EXECUTE_SCRIPT_NO_USER_GESTURE)); - EXPECT_EQ("error", EvalJs(child, kDeprecatedIsMultiscreen, - content::EXECUTE_SCRIPT_NO_USER_GESTURE)); } // Verify that window.screen.isExtended returns true in a cross-origin @@ -319,12 +294,6 @@ content::EXECUTE_SCRIPT_NO_USER_GESTURE)); EXPECT_EQ(true, EvalJs(child, R"(window.screen.isExtended)", content::EXECUTE_SCRIPT_NO_USER_GESTURE)); - - // TODO(enne): Remove this in http://crbug.com/1205676 - EXPECT_EQ(true, EvalJs(tab, kDeprecatedIsMultiscreen, - content::EXECUTE_SCRIPT_NO_USER_GESTURE)); - EXPECT_EQ(true, EvalJs(child, kDeprecatedIsMultiscreen, - content::EXECUTE_SCRIPT_NO_USER_GESTURE)); } #endif // !defined(OS_WIN)
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 99cbe8a..5a78ff1 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -294,6 +294,10 @@ const base::Feature kDesktopPWAsTabStripSettings{ "DesktopPWAsTabStripSettings", base::FEATURE_DISABLED_BY_DEFAULT}; +// Adds support for web bundles, making web apps able to be launched offline. +const base::Feature kDesktopPWAsWebBundles{"DesktopPWAsWebBundles", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enable DNS over HTTPS (DoH). const base::Feature kDnsOverHttps { "DnsOverHttps",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 87ba7507..4474ced 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -202,6 +202,9 @@ extern const base::Feature kDesktopPWAsTabStripSettings; COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::Feature kDesktopPWAsWebBundles; + +COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kDnsOverHttps; COMPONENT_EXPORT(CHROME_FEATURES) extern const base::FeatureParam<bool> kDnsOverHttpsFallbackParam;
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 190cefe3..23e224e 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1493,17 +1493,6 @@ // platforms. const char kFullscreenAllowed[] = "fullscreen.allowed"; -// Enable controllable features in the local discovery UI (chrome://devices). -// The UI shows discoverable devices near the user and registered cloud devices, -// and allow users to add printers to cloud print when not on Chrome OS -// devices . -const char kLocalDiscoveryEnabled[] = "local_discovery.enabled"; - -// Enable notifications for new devices on the local network that can be -// registered to the user's account, e.g. Google Cloud Print printers. -const char kLocalDiscoveryNotificationsEnabled[] = - "local_discovery.notifications_enabled"; - #if defined(OS_ANDROID) // Boolean pref indicating whether notification permissions were migrated to // notification channels (on Android O+ we use channels to store notification
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 142a6a69..d42ad753 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -484,9 +484,6 @@ extern const char kFullscreenAllowed[]; -extern const char kLocalDiscoveryEnabled[]; -extern const char kLocalDiscoveryNotificationsEnabled[]; - #if defined(OS_ANDROID) extern const char kMigratedToSiteNotificationChannels[]; extern const char kClearedBlockedSiteNotificationChannels[];
diff --git a/chrome/common/privacy_budget/container_ops.h b/chrome/common/privacy_budget/container_ops.h index 6449586..0cc57476 100644 --- a/chrome/common/privacy_budget/container_ops.h +++ b/chrome/common/privacy_budget/container_ops.h
@@ -11,7 +11,6 @@ #include "base/containers/contains.h" #include "base/rand_util.h" -#include "base/stl_util.h" #include "base/strings/string_piece.h" namespace internal {
diff --git a/chrome/common/privacy_budget/privacy_budget_features.cc b/chrome/common/privacy_budget/privacy_budget_features.cc index cb81633..c5edb770 100644 --- a/chrome/common/privacy_budget/privacy_budget_features.cc +++ b/chrome/common/privacy_budget/privacy_budget_features.cc
@@ -30,6 +30,12 @@ const base::FeatureParam<std::string> kIdentifiabilityStudyPerTypeSettings = { &kIdentifiabilityStudy, "TypeRate", ""}; +const base::FeatureParam<std::string> kIdentifiabilityStudyPerHashCost = { + &kIdentifiabilityStudy, "HashCost", ""}; + +const base::FeatureParam<std::string> kIdentifiabilityStudyPerTypeCost = { + &kIdentifiabilityStudy, "TypeCost", ""}; + const base::FeatureParam<std::string> kIdentifiabilityStudySurfaceEquivalenceClasses = {&kIdentifiabilityStudy, "Classes", ""};
diff --git a/chrome/common/privacy_budget/privacy_budget_features.h b/chrome/common/privacy_budget/privacy_budget_features.h index dc7aecee..597147de 100644 --- a/chrome/common/privacy_budget/privacy_budget_features.h +++ b/chrome/common/privacy_budget/privacy_budget_features.h
@@ -14,10 +14,12 @@ // # Encoding of IdentifiableSurfaces: // -// An IdentifiableSurface is encoded as the decimal representation of it's -// ToUkmMetricHash() result. +// When used in fieldtrial parameters, nn IdentifiableSurface is encoded as the +// decimal representation of its ToUkmMetricHash() result. An +// IdentifiableSurface::Type is encoded as the decimal representation of the +// enum value. -// Parent feature for all identifiability study logic. +// Root feature for all identifiability study logic. // // If the feature is disabled, then this browser instance will not be // participating in the identifiability study. I.e. no identifiability metrics @@ -141,6 +143,44 @@ extern const base::FeatureParam<std::string> kIdentifiabilityStudyPerTypeSettings; +// Per surface relative cost. +// +// Parameter name: "HashCost" +// Parameter type: Comma separated list of <surface;cost> pairs. +// +// By default all surfaces cost 1 *average* surface. Exceptions are noted +// individually and by type. This parameter contains individual costs. +// +// Costs are always specified in units of _average_ surface. The value can be +// a float expressed in decimal. +// +// When specifying these values on the command-line, the commas and semicolons +// should be escaped using URL encoding. I.e. '1;2,3;4' -> '1%3B2%2C3%3B4'. +// +// E.g.: +// * "261;0.5" : Sets the relative cost of 0.5 for surface with ID 261, which +// is a surface of type kWebFeature and token 1. +extern const base::FeatureParam<std::string> kIdentifiabilityStudyPerHashCost; + +// Per type relative cost. +// +// Parameter name: "TypeCost" +// Parameter type: Comma separated list of <surface-type;cost> pairs. +// +// By default all surfaces cost 1 _average_ surface. Exceptions are noted +// individually and by type. This parameter contains the per-type costs. +// +// Costs are always specified in units of _average_ surface. The value can be +// a float expressed in decimal. +// +// When specifying these values on the command-line, the commas and semicolons +// should be escaped using URL encoding. I.e. '1;2,3;4' -> '1%3B2%2C3%3B4'. +// +// E.g.: +// * "1;0.5" : Sets the relative cost of 0.5 for all surfaces of type +// kWebFeature. +extern const base::FeatureParam<std::string> kIdentifiabilityStudyPerTypeCost; + } // namespace features #endif // CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
diff --git a/chrome/common/privacy_budget/scoped_privacy_budget_config.cc b/chrome/common/privacy_budget/scoped_privacy_budget_config.cc index 6da3ee20..2f0c9aa 100644 --- a/chrome/common/privacy_budget/scoped_privacy_budget_config.cc +++ b/chrome/common/privacy_budget/scoped_privacy_budget_config.cc
@@ -92,6 +92,16 @@ EncodeIdentifiabilityFieldTrialParam( parameters.per_type_sampling_rate)}); } + if (!parameters.per_surface_cost.empty()) { + ftp.insert( + {features::kIdentifiabilityStudyPerHashCost.name, + EncodeIdentifiabilityFieldTrialParam(parameters.per_surface_cost)}); + } + if (!parameters.per_type_cost.empty()) { + ftp.insert( + {features::kIdentifiabilityStudyPerTypeCost.name, + EncodeIdentifiabilityFieldTrialParam(parameters.per_type_cost)}); + } if (!parameters.equivalence_classes.empty()) { ftp.insert( {features::kIdentifiabilityStudySurfaceEquivalenceClasses.name,
diff --git a/chrome/common/privacy_budget/scoped_privacy_budget_config.h b/chrome/common/privacy_budget/scoped_privacy_budget_config.h index 74a2fe5..b6e6fb7 100644 --- a/chrome/common/privacy_budget/scoped_privacy_budget_config.h +++ b/chrome/common/privacy_budget/scoped_privacy_budget_config.h
@@ -58,6 +58,8 @@ int max_surfaces = std::numeric_limits<int>::max(); std::map<blink::IdentifiableSurface, int> per_surface_sampling_rate; std::map<blink::IdentifiableSurface::Type, int> per_type_sampling_rate; + IdentifiableSurfaceCostMap per_surface_cost; + IdentifiableSurfaceTypeCostMap per_type_cost; SurfaceSetEquivalentClassesList equivalence_classes; };
diff --git a/chrome/install_static/BUILD.gn b/chrome/install_static/BUILD.gn index 2c6b87a..e835facc 100644 --- a/chrome/install_static/BUILD.gn +++ b/chrome/install_static/BUILD.gn
@@ -34,6 +34,7 @@ sources = [ "../app/chrome_dll_resource.h", "../common/chrome_icon_resources_win.h", + "//base/win/windows_types.h", "install_constants.h", "install_details.cc", "install_details.h",
diff --git a/chrome/install_static/DEPS b/chrome/install_static/DEPS index fb8f633..c252412 100644 --- a/chrome/install_static/DEPS +++ b/chrome/install_static/DEPS
@@ -1,6 +1,8 @@ include_rules = [ # Nothing from base. "-base", + # To avoid including windows.h in headers. + "+base/win/windows_types.h", # Nothing from chrome. "-chrome", # For the app icon resource identifiers.
diff --git a/chrome/install_static/install_details.h b/chrome/install_static/install_details.h index 66e4aed..e69187f 100644 --- a/chrome/install_static/install_details.h +++ b/chrome/install_static/install_details.h
@@ -5,11 +5,10 @@ #ifndef CHROME_INSTALL_STATIC_INSTALL_DETAILS_H_ #define CHROME_INSTALL_STATIC_INSTALL_DETAILS_H_ -#include <windows.h> - #include <memory> #include <string> +#include "base/win/windows_types.h" #include "chrome/install_static/install_constants.h" #include "chrome/install_static/install_modes.h" #include "chrome/install_static/install_util.h"
diff --git a/chrome/install_static/install_util.cc b/chrome/install_static/install_util.cc index 5ed43e2c..c09b9009 100644 --- a/chrome/install_static/install_util.cc +++ b/chrome/install_static/install_util.cc
@@ -7,6 +7,7 @@ #include <assert.h> #include <stdlib.h> #include <string.h> +#include <windows.h> #include <algorithm> #include <iterator> @@ -430,7 +431,7 @@ return InstallDetails::Get().elevator_clsid(); } -const CLSID& GetElevatorIid() { +const IID& GetElevatorIid() { return InstallDetails::Get().elevator_iid(); }
diff --git a/chrome/install_static/install_util.h b/chrome/install_static/install_util.h index 3150ec3d..d1239ea 100644 --- a/chrome/install_static/install_util.h +++ b/chrome/install_static/install_util.h
@@ -10,11 +10,11 @@ #ifndef CHROME_INSTALL_STATIC_INSTALL_UTIL_H_ #define CHROME_INSTALL_STATIC_INSTALL_UTIL_H_ -#include <windows.h> - #include <string> #include <vector> +#include "base/win/windows_types.h" + namespace version_info { enum class Channel; }
diff --git a/chrome/installer/linux/common/installer.include b/chrome/installer/linux/common/installer.include index 64f7e3b..64f961a 100644 --- a/chrome/installer/linux/common/installer.include +++ b/chrome/installer/linux/common/installer.include
@@ -227,6 +227,16 @@ done fi + # ANGLE's libvulkan library + if [ -f "${OUTPUTDIR}/libvulkan.so.1" ]; then + file="libvulkan.so.1" + buildfile="${OUTPUTDIR}/${file}" + strippedfile="${buildfile}.stripped" + debugfile="${buildfile}.debug" + "${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}" + install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}" + fi + # SwiftShader ES if [ -f "${OUTPUTDIR}/swiftshader/libEGL.so" ]; then install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/swiftshader/"
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc index 4848567..337b625 100644 --- a/chrome/installer/util/shell_util.cc +++ b/chrome/installer/util/shell_util.cc
@@ -2554,7 +2554,8 @@ const base::CommandLine& command_line, const std::wstring& application_name, const std::wstring& file_type_name, - const base::FilePath& icon_path, + const base::FilePath& application_icon_path, + const base::FilePath& file_type_icon_path, const std::set<std::wstring>& file_extensions) { std::vector<std::unique_ptr<RegistryEntry>> entries; @@ -2562,10 +2563,10 @@ ApplicationInfo app_info; app_info.prog_id = prog_id; app_info.application_name = application_name; - app_info.application_icon_path = icon_path; + app_info.application_icon_path = application_icon_path; app_info.application_icon_index = 0; app_info.file_type_name = file_type_name; - app_info.file_type_icon_path = icon_path; + app_info.file_type_icon_path = file_type_icon_path; app_info.file_type_icon_index = 0; app_info.command_line = command_line.GetCommandLineStringForShell();
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h index 20013fb..e78976b9 100644 --- a/chrome/installer/util/shell_util.h +++ b/chrome/installer/util/shell_util.h
@@ -730,9 +730,10 @@ // the Open With menu. // |file_type_name| is the friendly name for files of these types when // associated with this application by default. - // |icon_path| is the path of the icon displayed for this application in the - // Open With menu, and used for files of these types when associated with this - // application by default. + // |application_icon_path| is the path of the icon displayed for this + // application in the Open With menu. + // |file_type_icon_path| is the path of the icon used for files of these + // types when associated with this application by default. // |file_extensions| is the set of extensions to associate. They must not be // empty or start with a '.'. // Returns true on success, false on failure. @@ -741,7 +742,8 @@ const base::CommandLine& command_line, const std::wstring& application_name, const std::wstring& file_type_name, - const base::FilePath& icon_path, + const base::FilePath& application_icon_path, + const base::FilePath& file_type_icon_path, const std::set<std::wstring>& file_extensions); // Deletes all associations with a particular application in the Windows
diff --git a/chrome/installer/util/shell_util_unittest.cc b/chrome/installer/util/shell_util_unittest.cc index cca5e3d..3627841 100644 --- a/chrome/installer/util/shell_util_unittest.cc +++ b/chrome/installer/util/shell_util_unittest.cc
@@ -45,6 +45,7 @@ const wchar_t kTestApplicationDescription[] = L"Application Description"; const wchar_t kTestFileTypeName[] = L"Test File Type"; const wchar_t kTestIconPath[] = L"D:\\test.ico"; +const wchar_t kTestFileTypeIconPath[] = L"D:\\test_file_type.ico"; const wchar_t* kTestFileExtensions[] = { L"test1", L"test2", @@ -1110,7 +1111,8 @@ // Create file associations. EXPECT_TRUE(ShellUtil::AddFileAssociations( kTestProgid, OpenCommand(), kTestApplicationName, kTestFileTypeName, - base::FilePath(kTestIconPath), FileExtensions())); + base::FilePath(kTestIconPath), base::FilePath(kTestFileTypeIconPath), + FileExtensions())); // Ensure that the registry keys have been correctly set. base::win::RegKey key; @@ -1125,7 +1127,7 @@ key.Open(HKEY_CURRENT_USER, L"Software\\Classes\\TestApp\\DefaultIcon", KEY_READ)); EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(L"", &value)); - EXPECT_EQ(L"D:\\test.ico,0", value); + EXPECT_EQ(L"D:\\test_file_type.ico,0", value); ASSERT_EQ( ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, @@ -1174,7 +1176,8 @@ // Create file associations. ASSERT_TRUE(ShellUtil::AddFileAssociations( kTestProgid, OpenCommand(), kTestApplicationName, kTestFileTypeName, - base::FilePath(kTestIconPath), FileExtensions())); + base::FilePath(kTestIconPath), base::FilePath(kTestFileTypeIconPath), + FileExtensions())); // Delete them. EXPECT_TRUE(ShellUtil::DeleteFileAssociations(kTestProgid)); @@ -1269,7 +1272,8 @@ // command executable name as the app_name. ASSERT_TRUE(ShellUtil::AddFileAssociations( kTestProgid, OpenCommand(), kTestApplicationName, kTestFileTypeName, - base::FilePath(kTestIconPath), FileExtensions())); + base::FilePath(kTestIconPath), base::FilePath(kTestFileTypeIconPath), + FileExtensions())); ShellUtil::FileAssociationsAndAppName file_associations_and_app_name( ShellUtil::GetFileAssociationsAndAppName(kTestProgid)); EXPECT_EQ(file_associations_and_app_name.app_name, kTestApplicationName); @@ -1431,7 +1435,8 @@ // Create file associations. ASSERT_TRUE(ShellUtil::AddFileAssociations( kTestProgid, OpenCommand(), kTestApplicationName, kTestFileTypeName, - base::FilePath(kTestIconPath), FileExtensions())); + base::FilePath(kTestIconPath), base::FilePath(kTestFileTypeIconPath), + FileExtensions())); base::FilePath exe_path = ShellUtil::GetApplicationPathForProgId(kTestProgid); EXPECT_EQ(exe_path, base::FilePath(kTestOpenCommand)); }
diff --git a/chrome/renderer/autofill/password_generation_agent_browsertest.cc b/chrome/renderer/autofill/password_generation_agent_browsertest.cc index d3951fc1..6080197 100644 --- a/chrome/renderer/autofill/password_generation_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/ranges/algorithm.h" #include "base/run_loop.h" -#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h"
diff --git a/chrome/renderer/cart/commerce_hint_agent_unittest.cc b/chrome/renderer/cart/commerce_hint_agent_unittest.cc index 41a4e07..4713a6d 100644 --- a/chrome/renderer/cart/commerce_hint_agent_unittest.cc +++ b/chrome/renderer/cart/commerce_hint_agent_unittest.cc
@@ -927,7 +927,8 @@ BUILDFLAG(CFI_ENFORCEMENT_TRAP) #define MAYBE_RegexBenchmark DISABLED_RegexBenchmark #else -#define MAYBE_RegexBenchmark RegexBenchmark +// TODO(https://crbug.com/1223680): Test is flaky everywhere +#define MAYBE_RegexBenchmark DISABLED_RegexBenchmark #endif TEST(CommerceHintAgentTest, MAYBE_RegexBenchmark) {
diff --git a/chrome/services/printing/print_backend_service_impl.cc b/chrome/services/printing/print_backend_service_impl.cc index b827c6e..9e67479 100644 --- a/chrome/services/printing/print_backend_service_impl.cc +++ b/chrome/services/printing/print_backend_service_impl.cc
@@ -34,6 +34,10 @@ print_backend_ = PrintBackend::CreateInstance(locale); } +// TODO(crbug.com/1225111) Do nothing, this is just to assist an idle timeout +// change by providing a low-cost call to ensure it is applied. +void PrintBackendServiceImpl::Poke() {} + void PrintBackendServiceImpl::EnumeratePrinters( mojom::PrintBackendService::EnumeratePrintersCallback callback) { if (!print_backend_) {
diff --git a/chrome/services/printing/print_backend_service_impl.h b/chrome/services/printing/print_backend_service_impl.h index 4332469..2e6a856 100644 --- a/chrome/services/printing/print_backend_service_impl.h +++ b/chrome/services/printing/print_backend_service_impl.h
@@ -35,6 +35,7 @@ // mojom::PrintBackendService implementation: void Init(const std::string& locale) override; + void Poke() override; void EnumeratePrinters( mojom::PrintBackendService::EnumeratePrintersCallback callback) override; void GetDefaultPrinterName(
diff --git a/chrome/services/printing/public/mojom/print_backend_service.mojom b/chrome/services/printing/public/mojom/print_backend_service.mojom index 5cea403..7832aa65 100644 --- a/chrome/services/printing/public/mojom/print_backend_service.mojom +++ b/chrome/services/printing/public/mojom/print_backend_service.mojom
@@ -52,6 +52,10 @@ // interface to the underlying data source. Init(string locale); + // TODO(crbug.com/1225111) Message with no arguments and no reply that is + // useful to ensure that an idle timeout change takes effect. + Poke(); + // Enumerates the list of installed local and network printers. EnumeratePrinters() => (PrinterListResult printer_list);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 0c285fd..c5b2a5b7 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2408,7 +2408,6 @@ if (!is_chromeos_ash) { sources += [ "../browser/external_protocol/external_protocol_handler_browsertest.cc", - "../browser/lifetime/application_lifetime_browsertest.cc", "../browser/ui/signin_reauth_view_controller_browsertest.cc", ] } @@ -2416,6 +2415,7 @@ if (!is_chromeos) { sources += [ "../browser/external_protocol/external_protocol_policy_browsertest.cc", + "../browser/lifetime/application_lifetime_browsertest.cc", "../browser/policy/test/promotional_tabs_enabled_policy_browsertest.cc", ] } @@ -3278,6 +3278,14 @@ "../browser/ash/policy/external_data/device_policy_cloud_external_data_manager_browsertest.cc", "../browser/ash/policy/external_data/handlers/device_wilco_dtc_configuration_external_data_handler_browsertest.cc", "../browser/ash/policy/external_data/user_cloud_external_data_manager_browsertest.cc", + "../browser/ash/policy/handlers/device_quirks_policy_browsertest.cc", + "../browser/ash/policy/handlers/device_system_use_24hour_clock_browsertest.cc", + "../browser/ash/policy/handlers/device_system_wide_tracing_enabled_browsertest.cc", + "../browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc", + "../browser/ash/policy/handlers/power_policy_browsertest.cc", + "../browser/ash/policy/handlers/restore_on_startup_browsertest_chromeos.cc", + "../browser/ash/policy/handlers/site_isolation_flag_handling_browsertest.cc", + "../browser/ash/policy/handlers/variations_service_policy_browsertest.cc", "../browser/ash/profiles/profile_helper_browsertest.cc", "../browser/ash/remote_apps/remote_apps_impl_browsertest.cc", "../browser/ash/remote_apps/remote_apps_manager_browsertest.cc", @@ -3340,14 +3348,6 @@ "../browser/chromeos/platform_keys/platform_keys_service_browsertest.cc", "../browser/chromeos/platform_keys/platform_keys_service_test_util.cc", "../browser/chromeos/platform_keys/platform_keys_service_test_util.h", - "../browser/chromeos/policy/handlers/device_quirks_policy_browsertest.cc", - "../browser/chromeos/policy/handlers/device_system_use_24hour_clock_browsertest.cc", - "../browser/chromeos/policy/handlers/device_system_wide_tracing_enabled_browsertest.cc", - "../browser/chromeos/policy/handlers/minimum_version_policy_handler_browsertest.cc", - "../browser/chromeos/policy/handlers/power_policy_browsertest.cc", - "../browser/chromeos/policy/handlers/restore_on_startup_browsertest_chromeos.cc", - "../browser/chromeos/policy/handlers/site_isolation_flag_handling_browsertest.cc", - "../browser/chromeos/policy/handlers/variations_service_policy_browsertest.cc", "../browser/chromeos/policy/login/blocking_login_browsertest.cc", "../browser/chromeos/policy/login/device_login_screen_policy_browsertest.cc", "../browser/chromeos/policy/login/force_maximize_on_first_run_chromeos_browsertest.cc",
diff --git a/chrome/test/data/webshare/index.html b/chrome/test/data/webshare/index.html index 6bf587d7..b62a167 100644 --- a/chrome/test/data/webshare/index.html +++ b/chrome/test/data/webshare/index.html
@@ -155,6 +155,16 @@ } } + async function share_pdf_file() { + try { + const pdf_file = create_file('sample.pdf', 'application/pdf', 12); + await navigator.share({files: [pdf_file]}); + return 'share succeeded'; + } catch(error) { + return ('share failed: ' + error); + } + } + </script> </head> <body>
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 927bd42f..ac20234 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -371,6 +371,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_files_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/app_notifications_subpage_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_settings_main_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_settings_ui_test_2.m.js",
diff --git a/chrome/test/data/webui/chromeos/BUILD.gn b/chrome/test/data/webui/chromeos/BUILD.gn index cd48371..ccd3b5e 100644 --- a/chrome/test/data/webui/chromeos/BUILD.gn +++ b/chrome/test/data/webui/chromeos/BUILD.gn
@@ -18,7 +18,6 @@ js_library("fake_network_config_mojom") { deps = [ - "//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:promise_resolver", @@ -35,13 +34,6 @@ if (is_chromeos_ash) { sources += [ "$root_gen_dir/chrome/test/data/webui/chromeos/fake_network_config_mojom.m.js" ] } - if (is_chromeos_ash) { - deps = [ - "//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile", - "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m", - "//ui/webui/resources/js:promise_resolver.m", - ] - } extra_deps = [ ":modulize" ] }
diff --git a/chrome/test/data/webui/chromeos/fake_network_config_mojom.js b/chrome/test/data/webui/chromeos/fake_network_config_mojom.js index 8b88d4c..3f9b36e 100644 --- a/chrome/test/data/webui/chromeos/fake_network_config_mojom.js +++ b/chrome/test/data/webui/chromeos/fake_network_config_mojom.js
@@ -23,28 +23,33 @@ this.resolverMap_ = new Map(); /** - * @type {!Map<chromeos.networkConfig.mojom.NetworkType, + * @private {!Map<chromeos.networkConfig.mojom.NetworkType, * !chromeos.networkConfig.mojom.DeviceStateProperties>} */ this.deviceStates_ = new Map(); - /** @type {!Array<!chromeos.networkConfig.mojom.NetworkStateProperties>} */ + /** + * @private {!Array<!chromeos.networkConfig.mojom.NetworkStateProperties>} + */ this.networkStates_ = []; - /** @type {!Map<string, !chromeos.networkConfig.mojom.ManagedProperties>} */ + /** + * @private {!Map<string, !chromeos.networkConfig.mojom.ManagedProperties>} + */ this.managedProperties_ = new Map(); - /** @type {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */ + /** @private {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */ this.globalPolicy_ = undefined; - /** @type {!Array<!chromeos.networkConfig.mojom.NetworkCertificate>} */ + /** @private {!Array<!chromeos.networkConfig.mojom.NetworkCertificate>} */ this.serverCas_ = []; - /** @type {!Array<!chromeos.networkConfig.mojom.NetworkCertificate>} */ + /** @private {!Array<!chromeos.networkConfig.mojom.NetworkCertificate>} */ this.userCerts_ = []; /** - * @type {!Array<!chromeos.networkConfig.mojom.CrosNetworkConfigObserver>} + * @private {!Array< + * !chromeos.networkConfig.mojom.CrosNetworkConfigObserverRemote>} */ this.observers_ = []; @@ -57,7 +62,7 @@ this.testPin = ''; /** - * @type {chromeos.networkConfig.mojom.AlwaysOnVpnProperties} + * @private {chromeos.networkConfig.mojom.AlwaysOnVpnProperties} */ this.alwaysOnVpnProperties_ = { mode: chromeos.networkConfig.mojom.AlwaysOnVpnMode.kOff, @@ -67,7 +72,7 @@ /** @type {Function} */ this.beforeGetDeviceStateList = null; - /** @type {!Array<chromeos.networkConfig.mojom.VpnProvider>} */ + /** @private {!Array<chromeos.networkConfig.mojom.VpnProvider>} */ this.vpnProviders_ = []; this.resetForTest(); @@ -295,12 +300,7 @@ this.onNetworkCertificatesChanged(); } - /** - * networkConfig observers - * TODO(joonbug): Remove the suppress when CrosNetworkConfigObserver is - * properly discoverable. - * @suppress {missingProperties} - */ + // networkConfig observers onActiveNetworksChanged() { const activeNetworks = this.networkStates_.filter(state => { // Calling onActiveNetworksChanged will trigger mojo checks on all @@ -316,38 +316,18 @@ this.observers_.forEach(o => o.onActiveNetworksChanged(activeNetworks)); } - /** - * TODO(joonbug): Remove the suppress when CrosNetworkConfigObserver is - * properly discoverable. - * @suppress {missingProperties} - */ onNetworkStateListChanged() { this.observers_.forEach(o => o.onNetworkStateListChanged()); } - /** - * TODO(joonbug): Remove the suppress when CrosNetworkConfigObserver is - * properly discoverable. - * @suppress {missingProperties} - */ onDeviceStateListChanged() { this.observers_.forEach(o => o.onDeviceStateListChanged()); } - /** - * TODO(joonbug): Remove the suppress when CrosNetworkConfigObserver is - * properly discoverable. - * @suppress {missingProperties} - */ onVpnProvidersChanged() { this.observers_.forEach(o => o.onVpnProvidersChanged()); } - /** - * TODO(joonbug): Remove the suppress when CrosNetworkConfigObserver is - * properly discoverable. - * @suppress {missingProperties} - */ onNetworkCertificatesChanged() { this.observers_.forEach(o => o.onNetworkCertificatesChanged()); } @@ -355,7 +335,7 @@ // networkConfig methods /** - * @param {!chromeos.networkConfig.mojom.CrosNetworkConfigObserver} + * @param {!chromeos.networkConfig.mojom.CrosNetworkConfigObserverRemote} * observer */ addObserver(observer) {
diff --git a/chrome/test/data/webui/chromeos/scanning/BUILD.gn b/chrome/test/data/webui/chromeos/scanning/BUILD.gn index 389b87f..85625ec6 100644 --- a/chrome/test/data/webui/chromeos/scanning/BUILD.gn +++ b/chrome/test/data/webui/chromeos/scanning/BUILD.gn
@@ -12,6 +12,7 @@ "js_module_root=./gen/chrome/test/data/webui/", ] deps = [ + ":action_toolbar_test", ":color_mode_select_test", ":file_type_select_test", ":loading_page_test", @@ -31,6 +32,14 @@ ] } +js_library("action_toolbar_test") { + deps = [ + "../..:chai_assert", + "//ash/webui/scanning/resources:action_toolbar", + ] + externs_list = [ "$externs_path/mocha-2.5.js" ] +} + js_library("color_mode_select_test") { deps = [ ":scanning_app_test_utils",
diff --git a/chrome/test/data/webui/chromeos/scanning/action_toolbar_test.js b/chrome/test/data/webui/chromeos/scanning/action_toolbar_test.js new file mode 100644 index 0000000..7c43da0d --- /dev/null +++ b/chrome/test/data/webui/chromeos/scanning/action_toolbar_test.js
@@ -0,0 +1,43 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://scanning/action_toolbar.js'; + +import {assertEquals, assertTrue} from '../../chai_assert.js'; + +export function actionToolbarTest() { + /** @type {?ActionToolbarElement} */ + let actionToolbar = null; + + setup(() => { + actionToolbar = /** @type {!ActionToolbarElement} */ ( + document.createElement('action-toolbar')); + assertTrue(!!actionToolbar); + document.body.appendChild(actionToolbar); + }); + + teardown(() => { + if (actionToolbar) { + actionToolbar.remove(); + } + actionToolbar = null; + }); + + // Verify the page count text updates when the number of scanned images + // changes. + test('totalPageCountIncrements', () => { + assertEquals('', actionToolbar.$$('#pageNumbers').textContent.trim()); + + actionToolbar.numTotalPages = 3; + assertEquals('', actionToolbar.$$('#pageNumbers').textContent.trim()); + + actionToolbar.numTotalPages = 3; + actionToolbar.currentPageInView = 1; + assertEquals('1 of 3', actionToolbar.$$('#pageNumbers').textContent.trim()); + + actionToolbar.numTotalPages = 4; + actionToolbar.currentPageInView = 2; + assertEquals('2 of 4', actionToolbar.$$('#pageNumbers').textContent.trim()); + }); +}
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js index 7f789ef..8bcc447 100644 --- a/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js +++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js
@@ -48,9 +48,9 @@ // You must register all suites in unified test here as well for consistency, // although technically is not necessary. const debug_suites_list = [ - 'ColorModeSelect', 'FileTypeSelect', 'LoadingPage', 'MultiPageCheckbox', - 'MultiPageScan', 'PageSizeSelect', 'ResolutionSelect', 'ScanApp', - 'ScanDoneSection', 'ScannerSelect', 'ScanPreview', 'ScanToSelect', + 'ActionToolbar', 'ColorModeSelect', 'FileTypeSelect', 'LoadingPage', + 'MultiPageCheckbox', 'MultiPageScan', 'PageSizeSelect', 'ResolutionSelect', + 'ScanApp', 'ScanDoneSection', 'ScannerSelect', 'ScanPreview', 'ScanToSelect', 'SourceSelect' ];
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js index 5eb5004..bcf1ee0 100644 --- a/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js
@@ -10,6 +10,7 @@ import 'chrome://scanning/file_path.mojom-lite.js'; import 'chrome://scanning/scanning.mojom-lite.js'; +import {actionToolbarTest} from './action_toolbar_test.js'; import {colorModeSelectTest} from './color_mode_select_test.js'; import {fileTypeSelectTest} from './file_type_select_test.js'; import {loadingPageTest} from './loading_page_test.js'; @@ -31,6 +32,7 @@ suite(suiteName, testFn); } +runSuite('ActionToolbar', actionToolbarTest); runSuite('ColorModeSelect', colorModeSelectTest); runSuite('FileTypeSelect', fileTypeSelectTest); runSuite('LoadingPage', loadingPageTest);
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 067201dc..34e9ef6 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -141,6 +141,7 @@ "personalization_page_test.js", "search_subpage_test.js", "search_engine_test.js", + "settings_scheduler_slider_test.js", "smart_inputs_page_test.js", "smb_shares_page_tests.js", "switch_access_action_assignment_dialog_test.js",
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 8009299..cb4c680 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -369,6 +369,7 @@ ['PersonalizationPage', 'personalization_page_test.m.js'], ['PrintingPage', 'os_printing_page_tests.m.js'], ['ResetPage', 'os_reset_page_test.m.js'], + ['SettingsSchedulerSlider', 'settings_scheduler_slider_test.m.js'], ['SearchEngine', 'search_engine_test.m.js'], ['SearchSubpage', 'search_subpage_test.m.js'], ['SmartInputsPage', 'smart_inputs_page_test.m.js'],
diff --git a/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.js b/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.js new file mode 100644 index 0000000..35e8edbf --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.js
@@ -0,0 +1,97 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// clang-format off +// #import 'chrome://os-settings/chromeos/os_settings.js'; +// #import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {keyDownOn, keyUpOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; +// clang-format on + +/** @fileoverview Suite of tests for settings-scheduler-slider. */ +suite('SettingsSchedulerSlider', function() { + /** @type {!SettingsSchedulerSliderElement} */ + let slider; + + setup(function() { + PolymerTest.clearBody(); + slider = document.createElement('settings-scheduler-slider'); + slider.prefStartTime = { + key: 'ash.night_light.custom_start_time', + type: chrome.settingsPrivate.PrefType.NUMBER, + value: 60, + }; + slider.prefEndTime = { + key: 'ash.night_light.custom_end_time', + type: chrome.settingsPrivate.PrefType.NUMBER, + value: 120, + }; + assertTrue(!!slider); + slider.prefs = { + ash: { + night_light: { + custom_start_time: { + key: 'ash.night_light.custom_start_time', + type: chrome.settingsPrivate.PrefType.NUMBER, + value: 60, + }, + custom_end_time: { + key: 'ash.night_light.custom_start_time', + type: chrome.settingsPrivate.PrefType.NUMBER, + value: 120, + }, + } + }, + settings: { + clock: { + use_24hour_clock: { + key: 'settings.clock.use_24hour_clock', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: false, + }, + }, + } + }; + document.body.appendChild(slider); + }); + + async function flushAsync() { + Polymer.dom.flush(); + // Use setTimeout to wait for the next macrotask. + return new Promise(resolve => setTimeout(resolve)); + } + + test('pref value update time string', async function() { + // Test that the slider time string is updated after the pref is + // saved. + assertTrue(!!slider.$$('#startLabel')); + assertTrue(!!slider.$$('#endLabel')); + + const getStartTimeString = () => { + return slider.$$('#startLabel').innerHTML.trim(); + }; + + const getEndTimeString = () => { + return slider.$$('#endLabel').innerHTML.trim(); + }; + + assertEquals('1:00 AM', getStartTimeString()); + assertEquals('2:00 AM', getEndTimeString()); + + slider.prefStartTime.value = 70; + slider.setPrefValue( + 'ash.night_light.custom_start_time', slider.prefStartTime.value); + await flushAsync(); + + assertEquals('1:10 AM', getStartTimeString()); + assertEquals('2:00 AM', getEndTimeString()); + + slider.prefEndTime.value = 900; + slider.setPrefValue( + 'ash.night_light.custom_end_time', slider.prefEndTime.value); + await flushAsync(); + assertEquals('1:10 AM', getStartTimeString()); + assertEquals('3:00 PM', getEndTimeString()); + }); +});
diff --git a/chrome/updater/crash_reporter.cc b/chrome/updater/crash_reporter.cc index 01cc97c..808f5c1 100644 --- a/chrome/updater/crash_reporter.cc +++ b/chrome/updater/crash_reporter.cc
@@ -15,7 +15,6 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/path_service.h" -#include "base/stl_util.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h"
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 67a500e..681a37b 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -690,6 +690,9 @@ <message name="IDS_SCANNING_APP_MULTI_PAGE_SCAN_INSTRUCTIONS_TEXT" desc="The text instructions for a multi-page scan job to tell the user to scan another page from their scanner."> Place another page on the scanner and select Scan to add page. </message> + <message name="IDS_SCANNING_APP_ACTION_TOOLBAR_PAGE_COUNT_TEXT" desc="The text in the action toolbar that shows the current page number and the total number of pages scanned."> + <ph name="CURRENT_PAGE">$1<ex>2</ex></ph> of <ph name="TOTAL_PAGES">$2<ex>4</ex></ph> + </message> <!-- Diagnostics App --> <message name="IDS_DIAGNOSTICS_TITLE" desc="The title of the diagnostics app.">
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_ACTION_TOOLBAR_PAGE_COUNT_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_ACTION_TOOLBAR_PAGE_COUNT_TEXT.png.sha1 new file mode 100644 index 0000000..3ed1f04 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_ACTION_TOOLBAR_PAGE_COUNT_TEXT.png.sha1
@@ -0,0 +1 @@ +81be40760a238836d3b1dc51d6e9c249b9afc6b3 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/js/mojo/chrome_helper.js b/chromeos/components/camera_app_ui/resources/js/mojo/chrome_helper.js index 3d4111a..1b60ec3 100644 --- a/chromeos/components/camera_app_ui/resources/js/mojo/chrome_helper.js +++ b/chromeos/components/camera_app_ui/resources/js/mojo/chrome_helper.js
@@ -262,6 +262,17 @@ } /** + * Returns true if the document mode is supported on the device. + * @return {!Promise<boolean>} + */ + async isDocumentModeSupported() { + // TODO(b/180564352): Switch to the actual implementation once it is ready. + const {isSupported} = + await MockDocumentScanner.getInstance().isDocumentModeSupported(); + return isSupported; + } + + /** * Scans the blob data and returns the detected document corners. * @param {!Blob} blob * @return {!Promise<!Array<!gfx.mojom.PointF>>}
diff --git a/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js b/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js index 860d1b2..c4a846fd 100644 --- a/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js +++ b/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js
@@ -613,18 +613,6 @@ } /** - * Returns true if the document mode is supported on the device. - * @param {string} deviceId The id of target camera device. - * @return {!Promise<boolean>} - */ - async isDocumentModeSupported(deviceId) { - // TODO(b/180564352): Switch to the actual implementation once it is ready. - const {isSupported} = - await MockDocumentScanner.getInstance().isDocumentModeSupported(); - return isSupported; - } - - /** * Registers a document corners detector and triggers |callback| if the * detected corners are updated. * @param {string} deviceId The id of target camera device.
diff --git a/chromeos/components/media_app_ui/resources/js/launch.js b/chromeos/components/media_app_ui/resources/js/launch.js index d48c8fc..aa0e4c7 100644 --- a/chromeos/components/media_app_ui/resources/js/launch.js +++ b/chromeos/components/media_app_ui/resources/js/launch.js
@@ -899,28 +899,37 @@ let relatedFiles = []; // TODO(b/158149714): Clear out old tokens as well? Care needs to be taken to // ensure any file currently open with unsaved changes can still be saved. - for await (const /** !FileSystemHandle */ handle of directory.values()) { - if (localLaunchNumber !== globalLaunchNumber) { - // Abort, another more up to date launch in progress. - return ProcessOtherFilesResult.ABORT; - } + try { + for await (const /** !FileSystemHandle */ handle of directory.values()) { + if (localLaunchNumber !== globalLaunchNumber) { + // Abort, another more up to date launch in progress. + return ProcessOtherFilesResult.ABORT; + } - if (handle.kind !== 'file') { - continue; + if (handle.kind !== 'file') { + continue; + } + const fileHandle = /** @type {!FileSystemFileHandle} */ (handle); + // Only allow traversal of related file types. + if (isFileRelated(focusFile, handle.name)) { + // Note: The focus file will be processed here again but will be skipped + // over when added to `currentFiles`. + relatedFiles.push({ + token: generateToken(fileHandle), + // This will get populated by refreshFile before the file gets opened. + file: null, + handle: fileHandle, + inCurrentDirectory: true, + }); + } } - const fileHandle = /** @type {!FileSystemFileHandle} */ (handle); - // Only allow traversal of related file types. - if (isFileRelated(focusFile, handle.name)) { - // Note: The focus file will be processed here again but will be skipped - // over when added to `currentFiles`. - relatedFiles.push({ - token: generateToken(fileHandle), - // This will get populated by refreshFile before the file gets opened. - file: null, - handle: fileHandle, - inCurrentDirectory: true, - }); - } + } catch (e) { + // Likely source of b/163639398 crashes. This can probably be turned into a + // "console.warn()". Attempting to re-open the directory is probably not + // worth the added complexity, given the crash rate. + console.error(e, '(failed to traverse directory)'); + // It's unlikely traversal can "resume", but try to continue with anything + // obtained so far. } if (currentFiles.length > 1) { @@ -1191,19 +1200,19 @@ * @param {?LaunchParams} params * @return {!Promise<undefined>} */ -function launchConsumer(params) { +async function launchConsumer(params) { // The MediaApp sets `include_launch_directory = true` in its SystemAppInfo // struct compiled into Chrome. That means files[0] is guaranteed to be a // directory, with remaining launch files following it. Validate that this is // true and abort the launch if is is not. if (!params || !params.files || params.files.length < 2) { console.error('Invalid launch (missing files): ', params); - return Promise.resolve(); + return; } if (assertCast(params.files[0]).kind !== 'directory') { console.error('Invalid launch: files[0] is not a directory: ', params); - return Promise.resolve(); + return; } const directory = /** @type {!FileSystemDirectoryHandle} */ (params.files[0]); @@ -1213,13 +1222,33 @@ // the launch directory itself) as navigation candidates. if (params.files.length === 2) { const focusEntry = assertCast(params.files[1]); - return launchWithDirectory(directory, focusEntry); + try { + await launchWithDirectory(directory, focusEntry); + } catch (e) { + console.error(e, '(launchWithDirectory aborted)'); + } } else { - return launchWithMultipleSelection(directory, params.files.slice(1)); + try { + await launchWithMultipleSelection(directory, params.files.slice(1)); + } catch (e) { + console.error(e, '(launchWithMultipleSelection aborted)'); + } } } /** + * Wrapper for the launch consumer to ensure it doesn't return a Promise, nor + * propagate exceptions. Tests will want to target `launchConsumer` directly so + * that they can properly await launch results. + * @param {?LaunchParams} params + */ +function wrappedLaunchConsumer(params) { + launchConsumer(params).catch(e => { + console.error(e, '(launch aborted)'); + }); +} + +/** * Installs the handler for launch files, if window.launchQueue is available. */ function installLaunchHandler() { @@ -1227,7 +1256,7 @@ console.error('FileHandling API missing.'); return; } - window.launchQueue.setConsumer(launchConsumer); + window.launchQueue.setConsumer(wrappedLaunchConsumer); } installLaunchHandler();
diff --git a/chromeos/components/phonehub/BUILD.gn b/chromeos/components/phonehub/BUILD.gn index 0ca708d..577f8c47 100644 --- a/chromeos/components/phonehub/BUILD.gn +++ b/chromeos/components/phonehub/BUILD.gn
@@ -19,6 +19,9 @@ "camera_roll_item.h", "camera_roll_manager.cc", "camera_roll_manager.h", + "camera_roll_thumbnail_decoder.h", + "camera_roll_thumbnail_decoder_impl.cc", + "camera_roll_thumbnail_decoder_impl.h", "connection_scheduler.h", "connection_scheduler_impl.cc", "connection_scheduler_impl.h", @@ -193,6 +196,7 @@ "browser_tabs_model_controller_unittest.cc", "browser_tabs_model_unittest.cc", "camera_roll_manager_unittest.cc", + "camera_roll_thumbnail_decoder_impl_unittest.cc", "connection_scheduler_impl_unittest.cc", "cros_state_sender_unittest.cc", "do_not_disturb_controller_impl_unittest.cc",
diff --git a/chromeos/components/phonehub/camera_roll_item.cc b/chromeos/components/phonehub/camera_roll_item.cc index 95fec61..a1d20b9 100644 --- a/chromeos/components/phonehub/camera_roll_item.cc +++ b/chromeos/components/phonehub/camera_roll_item.cc
@@ -5,12 +5,18 @@ #include "chromeos/components/phonehub/camera_roll_item.h" #include "base/strings/utf_string_conversions.h" #include "chromeos/components/phonehub/proto/phonehub_api.pb.h" +#include "ui/gfx/image/image.h" namespace chromeos { namespace phonehub { -CameraRollItem::CameraRollItem(const proto::CameraRollItemMetadata& metadata) - : metadata_(metadata) {} +CameraRollItem::CameraRollItem(const proto::CameraRollItemMetadata& metadata, + const gfx::Image& thumbnail) + : metadata_(metadata), thumbnail_(thumbnail) {} + +CameraRollItem::CameraRollItem(const CameraRollItem&) = default; + +CameraRollItem& CameraRollItem::operator=(const CameraRollItem&) = default; CameraRollItem::~CameraRollItem() = default;
diff --git a/chromeos/components/phonehub/camera_roll_item.h b/chromeos/components/phonehub/camera_roll_item.h index 61d5c73..4a201e1b 100644 --- a/chromeos/components/phonehub/camera_roll_item.h +++ b/chromeos/components/phonehub/camera_roll_item.h
@@ -6,6 +6,7 @@ #define CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_ITEM_H_ #include "chromeos/components/phonehub/proto/phonehub_api.pb.h" +#include "ui/gfx/image/image.h" namespace chromeos { namespace phonehub { @@ -14,16 +15,20 @@ // metadata and thumbnail. class CameraRollItem { public: - CameraRollItem(const proto::CameraRollItemMetadata& metadata); - CameraRollItem(const CameraRollItem&) = delete; - CameraRollItem& operator=(const CameraRollItem&) = delete; + CameraRollItem(const proto::CameraRollItemMetadata& metadata, + const gfx::Image& thumbnail); + CameraRollItem(const CameraRollItem&); + CameraRollItem& operator=(const CameraRollItem&); virtual ~CameraRollItem(); // Returns the metadata of this item. const proto::CameraRollItemMetadata& metadata() const { return metadata_; } + // Returns the decoded thumbnail of this item. + const gfx::Image& thumbnail() const { return thumbnail_; } private: proto::CameraRollItemMetadata metadata_; + gfx::Image thumbnail_; }; } // namespace phonehub
diff --git a/chromeos/components/phonehub/camera_roll_manager.cc b/chromeos/components/phonehub/camera_roll_manager.cc index 6698047..1802d4c 100644 --- a/chromeos/components/phonehub/camera_roll_manager.cc +++ b/chromeos/components/phonehub/camera_roll_manager.cc
@@ -4,8 +4,11 @@ #include "chromeos/components/phonehub/camera_roll_manager.h" +#include "base/bind.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "chromeos/components/phonehub/camera_roll_item.h" +#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h" #include "chromeos/components/phonehub/message_receiver.h" #include "chromeos/components/phonehub/message_sender.h" #include "chromeos/components/phonehub/proto/phonehub_api.pb.h" @@ -24,7 +27,9 @@ CameraRollManager::CameraRollManager(MessageReceiver* message_receiver, MessageSender* message_sender) - : message_receiver_(message_receiver), message_sender_(message_sender) { + : message_receiver_(message_receiver), + message_sender_(message_sender), + thumbnail_decoder_(std::make_unique<CameraRollThumbnailDecoderImpl>()) { message_receiver->AddObserver(this); } @@ -37,6 +42,7 @@ if (!IsCameraRollSupportedOnAndroidDevice( phone_status_snapshot.properties().camera_roll_access_state())) { ClearCurrentItems(); + CancelPendingThumbnailRequests(); return; } @@ -48,6 +54,7 @@ if (!IsCameraRollSupportedOnAndroidDevice( phone_status_update.properties().camera_roll_access_state())) { ClearCurrentItems(); + CancelPendingThumbnailRequests(); return; } @@ -57,9 +64,14 @@ } void CameraRollManager::SendFetchCameraRollItemsRequest() { + // Clears pending thumbnail decode requests to avoid changing the current item + // set after sending it with the |FetchCameraRollItemsRequest|. These pending + // thumbnails will be invalidated anyway when the new response is received. + CancelPendingThumbnailRequests(); + proto::FetchCameraRollItemsRequest request; - for (const std::unique_ptr<CameraRollItem>& current_item : current_items_) { - *request.add_current_item_metadata() = current_item->metadata(); + for (const CameraRollItem& current_item : current_items_) { + *request.add_current_item_metadata() = current_item.metadata(); } message_sender_->SendFetchCameraRollItemsRequest(request); } @@ -77,29 +89,28 @@ void CameraRollManager::OnFetchCameraRollItemsResponseReceived( const proto::FetchCameraRollItemsResponse& response) { - current_items_.clear(); - - // TODO(http://crbug.com/1221297): Decode thumbnail data. Existing items that - // haven't changed won't have thumbnail data from the new proto. They need to - // be copied from the old vector into the new one. - for (const proto::CameraRollItem& item_proto : response.items()) { - current_items_.push_back( - std::make_unique<CameraRollItem>(item_proto.metadata())); - } - - // The phone only sends FetchCameraRollItemsResponse when the set of items has - // changed. Always alert the observers in this case. - for (auto& observer : observer_list_) { - observer.OnCameraRollItemsChanged(); - } + thumbnail_decoder_->BatchDecode( + response, current_items(), + base::BindOnce(&CameraRollManager::OnItemThumbnailsDecoded, + weak_ptr_factory_.GetWeakPtr())); } -std::vector<const CameraRollItem*> CameraRollManager::GetCurrentItems() const { - std::vector<const CameraRollItem*> items; - for (const std::unique_ptr<CameraRollItem>& current_item : current_items_) { - items.push_back(current_item.get()); +void CameraRollManager::OnItemThumbnailsDecoded( + CameraRollThumbnailDecoder::BatchDecodeResult result, + const std::vector<CameraRollItem>& items) { + if (result == CameraRollThumbnailDecoder::BatchDecodeResult::kSuccess) { + current_items_ = items; + // The phone only sends FetchCameraRollItemsResponse when the set of items + // has changed. Always alert the observers in this case. + for (auto& observer : observer_list_) { + observer.OnCameraRollItemsChanged(); + } } - return items; + // TODO(http://crbug.com/1221297): log and handle failed decode requests. +} + +void CameraRollManager::CancelPendingThumbnailRequests() { + weak_ptr_factory_.InvalidateWeakPtrs(); } void CameraRollManager::AddObserver(Observer* observer) {
diff --git a/chromeos/components/phonehub/camera_roll_manager.h b/chromeos/components/phonehub/camera_roll_manager.h index b6cfb36..0e97fbd 100644 --- a/chromeos/components/phonehub/camera_roll_manager.h +++ b/chromeos/components/phonehub/camera_roll_manager.h
@@ -5,8 +5,10 @@ #ifndef CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_MANAGER_H_ #define CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_MANAGER_H_ +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/observer_list_types.h" +#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder.h" #include "chromeos/components/phonehub/message_receiver.h" #include "chromeos/components/phonehub/proto/phonehub_api.pb.h" @@ -35,13 +37,17 @@ ~CameraRollManager() override; // Returns the set of current camera roll items in the order in which they - // should be displayed/ - std::vector<const CameraRollItem*> GetCurrentItems() const; + // should be displayed + const std::vector<CameraRollItem>& current_items() const { + return current_items_; + } void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); private: + friend class CameraRollManagerTest; + // MessageReceiver::Observer void OnPhoneStatusSnapshotReceived( proto::PhoneStatusSnapshot phone_status_snapshot) override; @@ -52,11 +58,21 @@ void SendFetchCameraRollItemsRequest(); void ClearCurrentItems(); + void OnItemThumbnailsDecoded( + CameraRollThumbnailDecoder::BatchDecodeResult result, + const std::vector<CameraRollItem>& items); + void CancelPendingThumbnailRequests(); MessageReceiver* message_receiver_; MessageSender* message_sender_; - std::vector<std::unique_ptr<CameraRollItem>> current_items_; + + std::vector<CameraRollItem> current_items_; + base::ObserverList<Observer> observer_list_; + + std::unique_ptr<CameraRollThumbnailDecoder> thumbnail_decoder_; + // Contains pending callbacks passed to the |CameraRollThumbnailDecoder|. + base::WeakPtrFactory<CameraRollManager> weak_ptr_factory_{this}; }; } // namespace phonehub
diff --git a/chromeos/components/phonehub/camera_roll_manager_unittest.cc b/chromeos/components/phonehub/camera_roll_manager_unittest.cc index 5e80da6f..4070eae 100644 --- a/chromeos/components/phonehub/camera_roll_manager_unittest.cc +++ b/chromeos/components/phonehub/camera_roll_manager_unittest.cc
@@ -4,17 +4,26 @@ #include "chromeos/components/phonehub/camera_roll_manager.h" +#include "base/callback.h" #include "base/strings/utf_string_conversions.h" #include "chromeos/components/phonehub/camera_roll_item.h" +#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h" #include "chromeos/components/phonehub/fake_message_receiver.h" #include "chromeos/components/phonehub/fake_message_sender.h" #include "chromeos/components/phonehub/proto/phonehub_api.pb.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" namespace chromeos { namespace phonehub { namespace { +using BatchDecodeResult = CameraRollThumbnailDecoder::BatchDecodeResult; +using BatchDecodeCallback = + base::OnceCallback<void(BatchDecodeResult, + const std::vector<CameraRollItem>&)>; + class FakeObserver : public CameraRollManager::Observer { public: FakeObserver() = default; @@ -47,7 +56,6 @@ // Verifies that the metadata of a generated item matches the corresponding // proto input. -// TODO(http://crbug.com/1221297): verify thumbnail data when implemented void VerifyMetadataEqual(const proto::CameraRollItemMetadata& expected, const proto::CameraRollItemMetadata& actual) { EXPECT_EQ(expected.key(), actual.key()); @@ -58,6 +66,42 @@ } // namespace +class FakeThumbnailDecoder : public CameraRollThumbnailDecoder { + public: + FakeThumbnailDecoder() = default; + ~FakeThumbnailDecoder() override = default; + + void BatchDecode(const proto::FetchCameraRollItemsResponse& response, + const std::vector<CameraRollItem>& current_items, + BatchDecodeCallback callback) override { + if (!pending_callback_.is_null()) { + CompletePendingCallback(BatchDecodeResult::kCancelled); + } + last_response_ = response; + pending_callback_ = std::move(callback); + } + + void CompletePendingCallback(BatchDecodeResult result) { + std::vector<CameraRollItem> items; + if (result == BatchDecodeResult::kSuccess) { + for (const proto::CameraRollItem& item_proto : last_response_.items()) { + SkBitmap test_bitmap; + test_bitmap.allocN32Pixels(1, 1); + gfx::ImageSkia image_skia = + gfx::ImageSkia::CreateFrom1xBitmap(test_bitmap); + image_skia.MakeThreadSafe(); + gfx::Image thumbnail(image_skia); + items.emplace_back(item_proto.metadata(), thumbnail); + } + } + std::move(pending_callback_).Run(result, items); + } + + private: + proto::FetchCameraRollItemsResponse last_response_; + BatchDecodeCallback pending_callback_; +}; + class CameraRollManagerTest : public testing::Test { protected: CameraRollManagerTest() = default; @@ -68,23 +112,21 @@ void SetUp() override { camera_roll_manager_ = std::make_unique<CameraRollManager>( &fake_message_receiver_, &fake_message_sender_); - camera_roll_manager_.get()->AddObserver(&fake_observer_); + camera_roll_manager_->thumbnail_decoder_ = + std::make_unique<FakeThumbnailDecoder>(); + camera_roll_manager_->AddObserver(&fake_observer_); } void TearDown() override { - camera_roll_manager_.get()->RemoveObserver(&fake_observer_); + camera_roll_manager_->RemoveObserver(&fake_observer_); } int GetOnCameraRollItemChangedCallCount() const { return fake_observer_.GetOnCameraRollItemChangedCallCount(); } - const CameraRollItem* GetReceivedItemAtIndex(int index) const { - return camera_roll_manager_.get()->GetCurrentItems()[index]; - } - - size_t GetCurrentItemsCount() const { - return camera_roll_manager_.get()->GetCurrentItems().size(); + int GetCurrentItemsCount() const { + return camera_roll_manager_->current_items().size(); } size_t GetSentFetchCameraRollItemsRequestCount() const { @@ -96,6 +138,27 @@ return fake_message_sender_.GetRecentFetchCameraRollItemsRequest(); } + // Verifies current items match the list of items in the last received + // |FetchCameraRollItemsResponse|, and their thumbnails have been properly + // decoded. + void VerifyCurrentItemsMatchResponse( + const proto::FetchCameraRollItemsResponse& response) const { + EXPECT_EQ(response.items_size(), GetCurrentItemsCount()); + for (int i = 0; i < GetCurrentItemsCount(); i++) { + const CameraRollItem& current_item = + camera_roll_manager_->current_items()[i]; + VerifyMetadataEqual(response.items(i).metadata(), + current_item.metadata()); + EXPECT_FALSE(current_item.thumbnail().IsEmpty()); + } + } + + void CompleteThumbnailDecoding(BatchDecodeResult result) { + static_cast<FakeThumbnailDecoder*>( + camera_roll_manager_->thumbnail_decoder_.get()) + ->CompletePendingCallback(result); + } + FakeMessageReceiver fake_message_receiver_; private: @@ -111,15 +174,45 @@ PopulateItemProto(response.add_items(), "key1"); fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); EXPECT_EQ(1, GetOnCameraRollItemChangedCallCount()); - EXPECT_EQ(3UL, GetCurrentItemsCount()); - VerifyMetadataEqual(response.items(0).metadata(), - GetReceivedItemAtIndex(0)->metadata()); - VerifyMetadataEqual(response.items(1).metadata(), - GetReceivedItemAtIndex(1)->metadata()); - VerifyMetadataEqual(response.items(2).metadata(), - GetReceivedItemAtIndex(2)->metadata()); + VerifyCurrentItemsMatchResponse(response); +} + +TEST_F(CameraRollManagerTest, + OnCameraRollItemsReceivedWithThumbnailDecodingError) { + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key3"); + PopulateItemProto(response.add_items(), "key2"); + PopulateItemProto(response.add_items(), "key1"); + + fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kError); + + EXPECT_EQ(0, GetOnCameraRollItemChangedCallCount()); + EXPECT_EQ(0, GetCurrentItemsCount()); +} + +TEST_F(CameraRollManagerTest, + OnCameraRollItemsReceivedWithPendingThumbnailDecodedRequest) { + proto::FetchCameraRollItemsResponse first_response; + PopulateItemProto(first_response.add_items(), "key2"); + PopulateItemProto(first_response.add_items(), "key1"); + fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived( + first_response); + + proto::FetchCameraRollItemsResponse second_response; + PopulateItemProto(second_response.add_items(), "key4"); + PopulateItemProto(second_response.add_items(), "key3"); + fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived( + second_response); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); + + // The first thumbnail decode request should be cancelled and the current item + // set should be updated only once after the second request completes. + EXPECT_EQ(1, GetOnCameraRollItemChangedCallCount()); + VerifyCurrentItemsMatchResponse(second_response); } TEST_F(CameraRollManagerTest, OnCameraRollItemsReceivedWithExistingItems) { @@ -130,8 +223,8 @@ fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived( first_response); - - EXPECT_EQ(3UL, GetCurrentItemsCount()); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); + VerifyCurrentItemsMatchResponse(first_response); proto::FetchCameraRollItemsResponse second_response; PopulateItemProto(second_response.add_items(), "key4"); @@ -144,15 +237,9 @@ fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived( second_response); - + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); EXPECT_EQ(2, GetOnCameraRollItemChangedCallCount()); - EXPECT_EQ(3UL, GetCurrentItemsCount()); - VerifyMetadataEqual(second_response.items(0).metadata(), - GetReceivedItemAtIndex(0)->metadata()); - VerifyMetadataEqual(second_response.items(1).metadata(), - GetReceivedItemAtIndex(1)->metadata()); - VerifyMetadataEqual(second_response.items(2).metadata(), - GetReceivedItemAtIndex(2)->metadata()); + VerifyCurrentItemsMatchResponse(second_response); } TEST_F(CameraRollManagerTest, @@ -191,6 +278,7 @@ PopulateItemProto(response.add_items(), "key2"); PopulateItemProto(response.add_items(), "key1"); fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); proto::PhoneStatusUpdate update; update.set_has_camera_roll_updates(true); @@ -220,6 +308,7 @@ PopulateItemProto(response.add_items(), "key2"); PopulateItemProto(response.add_items(), "key1"); fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); proto::PhoneStatusUpdate update; proto::CameraRollAccessState* access_state = @@ -230,7 +319,7 @@ EXPECT_EQ(0UL, GetSentFetchCameraRollItemsRequestCount()); EXPECT_EQ(2, GetOnCameraRollItemChangedCallCount()); - EXPECT_EQ(0UL, GetCurrentItemsCount()); + EXPECT_EQ(0, GetCurrentItemsCount()); } TEST_F(CameraRollManagerTest, @@ -239,6 +328,7 @@ PopulateItemProto(response.add_items(), "key2"); PopulateItemProto(response.add_items(), "key1"); fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); proto::PhoneStatusUpdate update; proto::CameraRollAccessState* access_state = @@ -249,7 +339,7 @@ EXPECT_EQ(0UL, GetSentFetchCameraRollItemsRequestCount()); EXPECT_EQ(2, GetOnCameraRollItemChangedCallCount()); - EXPECT_EQ(0UL, GetCurrentItemsCount()); + EXPECT_EQ(0, GetCurrentItemsCount()); } TEST_F(CameraRollManagerTest, OnPhoneStatusSnapshotReceived) { @@ -270,6 +360,7 @@ PopulateItemProto(response.add_items(), "key2"); PopulateItemProto(response.add_items(), "key1"); fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); proto::PhoneStatusSnapshot snapshot; proto::CameraRollAccessState* access_state = @@ -280,7 +371,7 @@ EXPECT_EQ(0UL, GetSentFetchCameraRollItemsRequestCount()); EXPECT_EQ(2, GetOnCameraRollItemChangedCallCount()); - EXPECT_EQ(0UL, GetCurrentItemsCount()); + EXPECT_EQ(0, GetCurrentItemsCount()); } TEST_F(CameraRollManagerTest, @@ -289,6 +380,7 @@ PopulateItemProto(response.add_items(), "key2"); PopulateItemProto(response.add_items(), "key1"); fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kSuccess); proto::PhoneStatusSnapshot snapshot; proto::CameraRollAccessState* access_state = @@ -299,7 +391,7 @@ EXPECT_EQ(0UL, GetSentFetchCameraRollItemsRequestCount()); EXPECT_EQ(2, GetOnCameraRollItemChangedCallCount()); - EXPECT_EQ(0UL, GetCurrentItemsCount()); + EXPECT_EQ(0, GetCurrentItemsCount()); } } // namespace phonehub
diff --git a/chromeos/components/phonehub/camera_roll_thumbnail_decoder.h b/chromeos/components/phonehub/camera_roll_thumbnail_decoder.h new file mode 100644 index 0000000..9854a470 --- /dev/null +++ b/chromeos/components/phonehub/camera_roll_thumbnail_decoder.h
@@ -0,0 +1,57 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_THUMBNAIL_DECODER_H_ +#define CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_THUMBNAIL_DECODER_H_ + +#include "base/callback.h" +#include "chromeos/components/phonehub/proto/phonehub_api.pb.h" + +namespace chromeos { +namespace phonehub { + +class CameraRollItem; + +// Decodes camera roll item thumbnails received from +// |FetchCameraRollItemsResponse| in batches, and converts decoded items into +// |CameraRollItem| objects that can be displayed on the UI. +class CameraRollThumbnailDecoder { + public: + // Result of a |BatchDecode| operation. + enum class BatchDecodeResult { + // All items in the batch have been successfully decoded. + kSuccess = 0, + // Failed to decode at least one item in the batch. + kError = 1, + // The decode requests for this batch has been cancelled. + kCancelled = 2, + kMaxValue = kCancelled + }; + + CameraRollThumbnailDecoder(const CameraRollThumbnailDecoder&) = delete; + CameraRollThumbnailDecoder& operator=(const CameraRollThumbnailDecoder&) = + delete; + virtual ~CameraRollThumbnailDecoder() = default; + + // Loads thumbnails of the batch of camera roll items either using encoded + // thumbnail bytes in the |FetchCameraRollItemsResponse|, or from existing + // images in |current_items| if an item has not changed. + // + // Returns decoded items through |callback| if the full batch can be decoded; + // otherwise an empty list will be returned with appropriate result code. + virtual void BatchDecode( + const proto::FetchCameraRollItemsResponse& response, + const std::vector<CameraRollItem>& current_items, + base::OnceCallback<void(BatchDecodeResult result, + const std::vector<CameraRollItem>&)> + callback) = 0; + + protected: + CameraRollThumbnailDecoder() = default; +}; + +} // namespace phonehub +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_THUMBNAIL_DECODER_H_
diff --git a/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.cc b/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.cc new file mode 100644 index 0000000..770397c --- /dev/null +++ b/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.cc
@@ -0,0 +1,168 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/components/phonehub/camera_roll_item.h" +#include "chromeos/components/phonehub/proto/phonehub_api.pb.h" +#include "services/data_decoder/public/cpp/decode_image.h" +#include "services/data_decoder/public/mojom/image_decoder.mojom.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" + +namespace chromeos { +namespace phonehub { +namespace { +using BatchDecodeCallback = + base::OnceCallback<void(CameraRollThumbnailDecoder::BatchDecodeResult, + const std::vector<CameraRollItem>&)>; +} // namespace + +CameraRollThumbnailDecoderImpl::DecodeRequest::DecodeRequest( + const proto::CameraRollItem& item_proto) + : item_proto_(item_proto) {} + +CameraRollThumbnailDecoderImpl::DecodeRequest::~DecodeRequest() = default; + +const proto::CameraRollItemMetadata& +CameraRollThumbnailDecoderImpl::DecodeRequest::GetMetadata() const { + return item_proto_.metadata(); +} + +void CameraRollThumbnailDecoderImpl::DecodeRequest::CompleteWithDecodedBitmap( + const SkBitmap& bitmap) { + gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); + if (!image_skia.isNull()) { + image_skia.MakeThreadSafe(); + decoded_thumbnail_ = gfx::Image(image_skia); + } +} + +void CameraRollThumbnailDecoderImpl::DecodeRequest::CompleteWithExistingImage( + const gfx::Image& image) { + decoded_thumbnail_ = image; +} + +const std::string& +CameraRollThumbnailDecoderImpl::DecodeRequest::GetEncodedThumbnail() const { + return item_proto_.thumbnail().data(); +} + +CameraRollThumbnailDecoderImpl::DecoderDelegate::DecoderDelegate() = default; + +CameraRollThumbnailDecoderImpl::DecoderDelegate::~DecoderDelegate() = default; + +void CameraRollThumbnailDecoderImpl::DecoderDelegate::DecodeThumbnail( + const DecodeRequest& request, + data_decoder::mojom::ImageDecoder::DecodeImageCallback callback) { + const std::string& encoded_thumbnail = request.GetEncodedThumbnail(); + std::vector<uint8_t> thumbnail_bytes(encoded_thumbnail.begin(), + encoded_thumbnail.end()); + data_decoder::DecodeImage( + &data_decoder_, thumbnail_bytes, + data_decoder::mojom::ImageCodec::kDefault, + /*shrink_to_fit=*/true, data_decoder::kDefaultMaxSizeInBytes, + /*desired_image_frame_size=*/gfx::Size(), std::move(callback)); +} + +CameraRollThumbnailDecoderImpl::CameraRollThumbnailDecoderImpl() + : decoder_delegate_(std::make_unique<DecoderDelegate>()) {} + +CameraRollThumbnailDecoderImpl::~CameraRollThumbnailDecoderImpl() = default; + +void CameraRollThumbnailDecoderImpl::BatchDecode( + const proto::FetchCameraRollItemsResponse& response, + const std::vector<CameraRollItem>& current_items, + BatchDecodeCallback callback) { + CompletePendingRequestsWithResult(BatchDecodeResult::kCancelled); + + for (const proto::CameraRollItem& item_proto : response.items()) { + pending_requests_.emplace_back(item_proto); + } + pending_callback_ = std::move(callback); + + base::flat_map<std::string, const gfx::Image*> existing_thumbnail_map; + for (const CameraRollItem& item : current_items) { + existing_thumbnail_map[item.metadata().key()] = &item.thumbnail(); + } + + for (DecodeRequest& request : pending_requests_) { + if (!request.GetEncodedThumbnail().empty()) { + // Thumbnail of this item is sent by the phone either because it is new or + // has been changed. + decoder_delegate_->DecodeThumbnail( + request, base::BindOnce( + &CameraRollThumbnailDecoderImpl::OnThumbnailDecoded, + weak_ptr_factory_.GetWeakPtr(), request.GetMetadata())); + } else if (existing_thumbnail_map.contains(request.GetMetadata().key())) { + // Existing items that have not changed should have their thumbnails + // already decoded. + request.CompleteWithExistingImage( + *(existing_thumbnail_map.at(request.GetMetadata().key()))); + } else { + // Thumbnail for this item is not already available but it is not sent by + // the phone. Most likely that this is an outdated response. Ignore it and + // wait for the next response. + CompletePendingRequestsWithResult(BatchDecodeResult::kError); + return; + } + } + // Check if all requests are already completed at this point. + CheckPendingThumbnailRequests(); +} + +void CameraRollThumbnailDecoderImpl::OnThumbnailDecoded( + const proto::CameraRollItemMetadata& metadata, + const SkBitmap& thumbnail_bitmap) { + for (DecodeRequest& request : pending_requests_) { + if (request.GetMetadata().key() != metadata.key()) { + continue; + } + + request.CompleteWithDecodedBitmap(thumbnail_bitmap); + if (request.decoded_thumbnail().IsEmpty()) { + // The decode thumbnail image will be null if the thumbnail bytes cannot + // be decoded. + CompletePendingRequestsWithResult(BatchDecodeResult::kError); + } else { + CheckPendingThumbnailRequests(); + } + break; + } +} + +void CameraRollThumbnailDecoderImpl::CheckPendingThumbnailRequests() { + for (const DecodeRequest& request : pending_requests_) { + if (request.decoded_thumbnail().IsEmpty()) { + return; + } + } + + // All pending requests have been completed. Replace current items with this + // new batch. + std::vector<CameraRollItem> new_items; + for (const DecodeRequest& request : pending_requests_) { + new_items.emplace_back(request.GetMetadata(), request.decoded_thumbnail()); + } + pending_requests_.clear(); + + std::move(pending_callback_).Run(BatchDecodeResult::kSuccess, new_items); +} + +void CameraRollThumbnailDecoderImpl::CompletePendingRequestsWithResult( + BatchDecodeResult result) { + weak_ptr_factory_.InvalidateWeakPtrs(); + pending_requests_.clear(); + if (!pending_callback_.is_null()) { + std::vector<CameraRollItem> empty_items; + std::move(pending_callback_).Run(result, empty_items); + } +} + +} // namespace phonehub +} // namespace chromeos
diff --git a/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h b/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h new file mode 100644 index 0000000..8ea799a1 --- /dev/null +++ b/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h
@@ -0,0 +1,102 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_THUMBNAIL_DECODER_IMPL_H_ +#define CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_THUMBNAIL_DECODER_IMPL_H_ + +#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder.h" + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/components/phonehub/proto/phonehub_api.pb.h" +#include "services/data_decoder/public/cpp/data_decoder.h" +#include "services/data_decoder/public/mojom/image_decoder.mojom.h" +#include "ui/gfx/image/image.h" + +namespace chromeos { +namespace phonehub { + +class CameraRollThumbnailDecoderImpl : public CameraRollThumbnailDecoder { + public: + CameraRollThumbnailDecoderImpl(); + ~CameraRollThumbnailDecoderImpl() override; + + void BatchDecode(const proto::FetchCameraRollItemsResponse& response, + const std::vector<CameraRollItem>& current_items, + base::OnceCallback<void(BatchDecodeResult result, + const std::vector<CameraRollItem>&)> + callback) override; + + private: + friend class CameraRollThumbnailDecoderImplTest; + friend class FakeDecoderDelegate; + + // A pending request to decode the thumbnail of a camera roll item. + class DecodeRequest { + public: + DecodeRequest(const proto::CameraRollItem& item_proto); + virtual ~DecodeRequest(); + + const proto::CameraRollItemMetadata& GetMetadata() const; + + // Completes this request with thumbnail bitmap decoded from the raw bytes + // in the proto. + void CompleteWithDecodedBitmap(const SkBitmap& bitmap); + // Completes this request with an existing image that has already been + // decoded for the same item. + void CompleteWithExistingImage(const gfx::Image& image); + + // Returns the encoded raw bytes of the thumbnail. May return an empty + // string if the thumbnail is not sent with the camera roll item proto. + const std::string& GetEncodedThumbnail() const; + // Returns an empty image when the request is not completed or a non-empty + // image when the requests is complete. + const gfx::Image& decoded_thumbnail() const { return decoded_thumbnail_; } + + private: + const proto::CameraRollItem item_proto_; + gfx::Image decoded_thumbnail_; + }; + + // Delegate class that decodes camera roll item thumbnails. Can be overridden + // in tests. + class DecoderDelegate { + public: + DecoderDelegate(); + virtual ~DecoderDelegate(); + + virtual void DecodeThumbnail( + const DecodeRequest& request, + data_decoder::mojom::ImageDecoder::DecodeImageCallback callback); + + private: + // The instance of DataDecoder to decode thumbnail images. The underlying + // service instance is started lazily when needed and torn down when not in + // use. + data_decoder::DataDecoder data_decoder_; + }; + + void OnThumbnailDecoded(const proto::CameraRollItemMetadata& item_metadata, + const SkBitmap& thumbnail_bitmap); + // Checks whether all requests to decode thumbnails have been completed for + // the latest items received, and invoke the pending callback if so. + void CheckPendingThumbnailRequests(); + // Marks the pending requests as complete with the given result code and an + // empty item list when the requests are cancelled or when an error occurs. + void CompletePendingRequestsWithResult( + CameraRollThumbnailDecoder::BatchDecodeResult result); + + std::unique_ptr<DecoderDelegate> decoder_delegate_; + std::vector<DecodeRequest> pending_requests_; + base::OnceCallback<void(BatchDecodeResult result, + const std::vector<CameraRollItem>&)> + pending_callback_; + // Contains weak pointers to callbacks passed to the |DecoderDelegate|. + base::WeakPtrFactory<CameraRollThumbnailDecoderImpl> weak_ptr_factory_{this}; +}; + +} // namespace phonehub +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_THUMBNAIL_DECODER_IMPL_H_
diff --git a/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl_unittest.cc b/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl_unittest.cc new file mode 100644 index 0000000..280e2612 --- /dev/null +++ b/chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl_unittest.cc
@@ -0,0 +1,316 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h" + +#include "base/bind.h" +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/components/phonehub/camera_roll_item.h" +#include "chromeos/components/phonehub/proto/phonehub_api.pb.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" + +namespace chromeos { +namespace phonehub { +namespace { + +using BatchDecodeResult = CameraRollThumbnailDecoder::BatchDecodeResult; + +void PopulateItemProto(proto::CameraRollItem* item_proto, + const std::string& key) { + proto::CameraRollItemMetadata* metadata = item_proto->mutable_metadata(); + metadata->set_key(key); + metadata->set_mime_type("image/png"); + metadata->set_last_modified_millis(123456789L); + metadata->set_file_size_bytes(123456789L); + + proto::CameraRollItemThumbnail* thumbnail = item_proto->mutable_thumbnail(); + thumbnail->set_format(proto::CameraRollItemThumbnail_Format_JPEG); + thumbnail->set_data("encoded_thumbnail_data"); +} + +const CameraRollItem CreateItem(const std::string& key) { + proto::CameraRollItemMetadata metadata; + metadata.set_key(key); + metadata.set_mime_type("image/png"); + metadata.set_last_modified_millis(123456789L); + metadata.set_file_size_bytes(123456789L); + + SkBitmap test_bitmap; + test_bitmap.allocN32Pixels(1, 1); + gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(test_bitmap); + image_skia.MakeThreadSafe(); + gfx::Image thumbnail(image_skia); + + return CameraRollItem(metadata, thumbnail); +} + +// Verifies that the metadata of a generated item matches the corresponding +// proto input. +void VerifyMetadataEqual(const proto::CameraRollItemMetadata& expected, + const proto::CameraRollItemMetadata& actual) { + EXPECT_EQ(expected.key(), actual.key()); + EXPECT_EQ(expected.mime_type(), actual.mime_type()); + EXPECT_EQ(expected.last_modified_millis(), actual.last_modified_millis()); + EXPECT_EQ(expected.file_size_bytes(), actual.file_size_bytes()); +} + +} // namespace + +class FakeDecoderDelegate + : public CameraRollThumbnailDecoderImpl::DecoderDelegate { + public: + FakeDecoderDelegate() = default; + ~FakeDecoderDelegate() override = default; + + void DecodeThumbnail( + const CameraRollThumbnailDecoderImpl::DecodeRequest& request, + data_decoder::mojom::ImageDecoder::DecodeImageCallback callback) + override { + pending_callbacks_[request.GetMetadata().key()] = std::move(callback); + } + + void CompleteRequest(const std::string& key) { + SkBitmap test_bitmap; + test_bitmap.allocN32Pixels(1, 1); + std::move(pending_callbacks_.at(key)).Run(test_bitmap); + pending_callbacks_.erase(key); + } + + void FailRequest(const std::string& key) { + SkBitmap test_bitmap; + std::move(pending_callbacks_.at(key)).Run(test_bitmap); + pending_callbacks_.erase(key); + } + + void CompleteAllRequests() { + SkBitmap test_bitmap; + test_bitmap.allocN32Pixels(1, 1); + for (auto& it : pending_callbacks_) + std::move(it.second).Run(test_bitmap); + pending_callbacks_.clear(); + } + + private: + base::flat_map<std::string, + data_decoder::mojom::ImageDecoder::DecodeImageCallback> + pending_callbacks_; +}; + +class CameraRollThumbnailDecoderImplTest : public testing::Test { + protected: + CameraRollThumbnailDecoderImplTest() = default; + CameraRollThumbnailDecoderImplTest( + const CameraRollThumbnailDecoderImplTest&) = delete; + CameraRollThumbnailDecoderImplTest& operator=( + const CameraRollThumbnailDecoderImplTest&) = delete; + ~CameraRollThumbnailDecoderImplTest() override = default; + + void SetUp() override { + decoder_.decoder_delegate_ = std::make_unique<FakeDecoderDelegate>(); + } + + void BatchDecode(const proto::FetchCameraRollItemsResponse& response, + const std::vector<CameraRollItem>& current_items) { + decoder_.BatchDecode( + response, current_items, + base::BindOnce(&CameraRollThumbnailDecoderImplTest::OnItemsDecoded, + weak_ptr_factory_.GetWeakPtr())); + } + + void CompleteDecodeRequest(const std::string& key) { + static_cast<FakeDecoderDelegate*>(decoder_.decoder_delegate_.get()) + ->CompleteRequest(key); + } + + void FailDecodeRequest(const std::string& key) { + static_cast<FakeDecoderDelegate*>(decoder_.decoder_delegate_.get()) + ->FailRequest(key); + } + + void CompleteAllDecodeRequests() { + static_cast<FakeDecoderDelegate*>(decoder_.decoder_delegate_.get()) + ->CompleteAllRequests(); + } + + int completed_batch_count() const { return completed_batch_count_; } + + BatchDecodeResult last_decode_result() const { return last_decode_result_; } + + // Verifies decoded items match the list of items in the provided + // |FetchCameraRollItemsResponse|, and their thumbnails have been properly + // decoded. + void VerifyDecodedItemsMatchResponse( + const proto::FetchCameraRollItemsResponse& response) const { + int decoded_item_count = last_decoded_items_.size(); + EXPECT_EQ(response.items_size(), decoded_item_count); + for (int i = 0; i < decoded_item_count; i++) { + const CameraRollItem& decoded_item = last_decoded_items_.at(i); + VerifyMetadataEqual(response.items(i).metadata(), + decoded_item.metadata()); + EXPECT_FALSE(decoded_item.thumbnail().IsEmpty()); + } + } + + void OnItemsDecoded(BatchDecodeResult result, + const std::vector<CameraRollItem>& items) { + completed_batch_count_++; + last_decode_result_ = result; + last_decoded_items_ = items; + } + + private: + CameraRollThumbnailDecoderImpl decoder_; + int completed_batch_count_ = 0; + BatchDecodeResult last_decode_result_; + std::vector<CameraRollItem> last_decoded_items_; + base::WeakPtrFactory<CameraRollThumbnailDecoderImplTest> weak_ptr_factory_{ + this}; +}; + +TEST_F(CameraRollThumbnailDecoderImplTest, BatchDecodeWithNoExistingItems) { + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key3"); + PopulateItemProto(response.add_items(), "key2"); + PopulateItemProto(response.add_items(), "key1"); + + BatchDecode(response, {}); + + CompleteDecodeRequest("key3"); + CompleteDecodeRequest("key2"); + EXPECT_EQ(0, completed_batch_count()); + + // The batch of items won't be added until decode request are completed for + // all items. + CompleteDecodeRequest("key1"); + EXPECT_EQ(1, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kSuccess, last_decode_result()); + VerifyDecodedItemsMatchResponse(response); +} + +TEST_F(CameraRollThumbnailDecoderImplTest, + BatchDecodeWithOutOfOrderCompletions) { + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key3"); + PopulateItemProto(response.add_items(), "key2"); + PopulateItemProto(response.add_items(), "key1"); + + BatchDecode(response, {}); + + CompleteDecodeRequest("key2"); + CompleteDecodeRequest("key1"); + CompleteDecodeRequest("key3"); + EXPECT_EQ(1, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kSuccess, last_decode_result()); + // Verify that the order in which the thumbnails are decoded does not affect + // the final display order of the items. + VerifyDecodedItemsMatchResponse(response); +} + +TEST_F(CameraRollThumbnailDecoderImplTest, BatchDecodeWithErrors) { + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key3"); + PopulateItemProto(response.add_items(), "key2"); + PopulateItemProto(response.add_items(), "key1"); + + BatchDecode(response, {}); + + CompleteDecodeRequest("key3"); + CompleteDecodeRequest("key1"); + FailDecodeRequest("key2"); + EXPECT_EQ(1, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kError, last_decode_result()); +} + +TEST_F(CameraRollThumbnailDecoderImplTest, + BatchDecodeWithMissingThumbnailData) { + std::vector<CameraRollItem> existing_items; + existing_items.push_back(CreateItem("key2")); + existing_items.push_back(CreateItem("key1")); + proto::FetchCameraRollItemsResponse response; + // This is a new item but its thumbnail data is missing. + PopulateItemProto(response.add_items(), "key3"); + response.mutable_items(0)->clear_thumbnail(); + PopulateItemProto(response.add_items(), "key2"); + + BatchDecode(response, existing_items); + CompleteAllDecodeRequests(); + + EXPECT_EQ(1, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kError, last_decode_result()); +} + +TEST_F(CameraRollThumbnailDecoderImplTest, BatchDecodeWithExistingItems) { + std::vector<CameraRollItem> existing_items; + existing_items.push_back(CreateItem("key3")); + existing_items.push_back(CreateItem("key2")); + existing_items.push_back(CreateItem("key1")); + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key4"); + // Thumbnails won't be sent with the proto if an item's data is already + // available and up-to-date. + PopulateItemProto(response.add_items(), "key3"); + response.mutable_items(1)->clear_thumbnail(); + PopulateItemProto(response.add_items(), "key2"); + response.mutable_items(2)->clear_thumbnail(); + + BatchDecode(response, existing_items); + EXPECT_EQ(0, completed_batch_count()); + + // Only need to decode thumbnail of this new item. + CompleteDecodeRequest("key4"); + EXPECT_EQ(1, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kSuccess, last_decode_result()); + VerifyDecodedItemsMatchResponse(response); +} + +TEST_F(CameraRollThumbnailDecoderImplTest, + BatchDecodeWithExistingItemsInDifferentOrder) { + std::vector<CameraRollItem> existing_items; + existing_items.push_back(CreateItem("key3")); + existing_items.push_back(CreateItem("key2")); + existing_items.push_back(CreateItem("key1")); + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key2"); + response.mutable_items(0)->clear_thumbnail(); + PopulateItemProto(response.add_items(), "key3"); + response.mutable_items(1)->clear_thumbnail(); + PopulateItemProto(response.add_items(), "key1"); + response.mutable_items(2)->clear_thumbnail(); + + BatchDecode(response, existing_items); + + // No additional thumbnail decoding is needed because the items are already + // available. + EXPECT_EQ(1, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kSuccess, last_decode_result()); + VerifyDecodedItemsMatchResponse(response); +} + +TEST_F(CameraRollThumbnailDecoderImplTest, BatchDecodeWithInProgresRequests) { + proto::FetchCameraRollItemsResponse first_response; + PopulateItemProto(first_response.add_items(), "key2"); + PopulateItemProto(first_response.add_items(), "key1"); + + BatchDecode(first_response, {}); + CompleteDecodeRequest("key1"); + + proto::FetchCameraRollItemsResponse second_response; + PopulateItemProto(second_response.add_items(), "key3"); + PopulateItemProto(second_response.add_items(), "key2"); + BatchDecode(second_response, {}); + // The first in-progress request should be cancelled + EXPECT_EQ(1, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kCancelled, last_decode_result()); + + CompleteAllDecodeRequests(); + EXPECT_EQ(2, completed_batch_count()); + EXPECT_EQ(BatchDecodeResult::kSuccess, last_decode_result()); + VerifyDecodedItemsMatchResponse(second_response); +} + +} // namespace phonehub +} // namespace chromeos
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index e78ddee..64223823 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -629,9 +629,24 @@ // split files. // This interface is used to register BrowserService provided by a // crosapi client. +// +// Next MinVersion: 2. +// Next ID: 2 +// [Stable, Uuid="7864a7d6-c74d-4e5f-8589-8cdb99d0c92e"] interface BrowserServiceHost { // Registers the remote as a BrowserService. Crosapi host (ash-chrome) // can make requests to control the registered browser. AddBrowserService@0(pending_remote<BrowserService> browser); + + // Requests to relaunch the browser again, soon after its shutdown. + // The browser is expected to be terminated sometime soon by itself, + // i.e., Crosapi host (ash-chrome) will not forcibly kill the process. + // It is important to terminate soon, because otherwise the users may be + // surprised of unexpected relaunching on later termination. + // If there's multiple requests before termination, they'll be degenerated + // into one relaunching. + // Added in M93. + [MinVersion=1] + RequestRelaunch@1(); };
diff --git a/chromeos/dbus/easy_unlock_client.cc b/chromeos/dbus/easy_unlock_client.cc index 5d4024f..aae99b9 100644 --- a/chromeos/dbus/easy_unlock_client.cc +++ b/chromeos/dbus/easy_unlock_client.cc
@@ -45,6 +45,8 @@ class EasyUnlockClientImpl : public EasyUnlockClient { public: EasyUnlockClientImpl() : proxy_(nullptr) {} + EasyUnlockClientImpl(const EasyUnlockClientImpl&) = delete; + EasyUnlockClientImpl& operator=(const EasyUnlockClientImpl&) = delete; ~EasyUnlockClientImpl() override = default; @@ -180,8 +182,6 @@ // Note: This should remain the last member so it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. base::WeakPtrFactory<EasyUnlockClientImpl> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(EasyUnlockClientImpl); }; } // namespace
diff --git a/chromeos/dbus/easy_unlock_client.h b/chromeos/dbus/easy_unlock_client.h index efc4994..6e9f5c84 100644 --- a/chromeos/dbus/easy_unlock_client.h +++ b/chromeos/dbus/easy_unlock_client.h
@@ -42,6 +42,10 @@ // Parameters used to create a secure message. struct CreateSecureMessageOptions { CreateSecureMessageOptions(); + CreateSecureMessageOptions(const CreateSecureMessageOptions&) = delete; + CreateSecureMessageOptions& operator=(const CreateSecureMessageOptions&) = + delete; + ~CreateSecureMessageOptions(); // The key used to sign, and if needed, encrypt the message. If encryption @@ -70,14 +74,15 @@ // The algorithm to use to sign the message. std::string signature_type; - - private: - DISALLOW_COPY_AND_ASSIGN(CreateSecureMessageOptions); }; // Parameters used to unwrap a securemessage. struct UnwrapSecureMessageOptions { UnwrapSecureMessageOptions(); + UnwrapSecureMessageOptions(const UnwrapSecureMessageOptions&) = delete; + UnwrapSecureMessageOptions& operator=(const UnwrapSecureMessageOptions&) = + delete; + ~UnwrapSecureMessageOptions(); // The key used to authenticate message signature and, if needed, decrypt @@ -93,9 +98,6 @@ // The algorithm that should be used to verify the message signature. std::string signature_type; - - private: - DISALLOW_COPY_AND_ASSIGN(UnwrapSecureMessageOptions); }; // Generates ECDSA key pair using P256 curve. @@ -148,9 +150,8 @@ protected: // Create() should be used instead. EasyUnlockClient(); - - private: - DISALLOW_COPY_AND_ASSIGN(EasyUnlockClient); + EasyUnlockClient(const EasyUnlockClient&) = delete; + EasyUnlockClient& operator=(const EasyUnlockClient&) = delete; }; } // namespace chromeos
diff --git a/chromeos/dbus/federated/fake_federated_client.h b/chromeos/dbus/federated/fake_federated_client.h index ef9ee975..bbe7809 100644 --- a/chromeos/dbus/federated/fake_federated_client.h +++ b/chromeos/dbus/federated/fake_federated_client.h
@@ -7,7 +7,6 @@ #include "base/callback_forward.h" #include "base/files/scoped_file.h" -#include "base/macros.h" #include "chromeos/dbus/federated/federated_client.h" namespace chromeos { @@ -17,14 +16,13 @@ public: FakeFederatedClient(); ~FakeFederatedClient() override; + FakeFederatedClient(const FakeFederatedClient&) = delete; + FakeFederatedClient& operator=(const FakeFederatedClient&) = delete; // FederatedClient: void BootstrapMojoConnection( base::ScopedFD fd, base::OnceCallback<void(bool success)> result_callback) override; - - private: - DISALLOW_COPY_AND_ASSIGN(FakeFederatedClient); }; } // namespace chromeos
diff --git a/chromeos/dbus/federated/federated_client.cc b/chromeos/dbus/federated/federated_client.cc index fa64774..3f1ef11 100644 --- a/chromeos/dbus/federated/federated_client.cc +++ b/chromeos/dbus/federated/federated_client.cc
@@ -25,6 +25,8 @@ public: FederatedClientImpl() = default; ~FederatedClientImpl() override = default; + FederatedClientImpl(const FederatedClientImpl&) = delete; + FederatedClientImpl& operator=(const FederatedClientImpl&) = delete; // FederatedClient: void BootstrapMojoConnection( @@ -48,8 +50,6 @@ } private: - dbus::ObjectProxy* federated_service_proxy_ = nullptr; - // Passes the success/failure of `dbus_response` on to `result_callback`. void OnBootstrapMojoConnectionResponse( base::OnceCallback<void(bool success)> result_callback, @@ -58,10 +58,9 @@ std::move(result_callback).Run(success); } + dbus::ObjectProxy* federated_service_proxy_ = nullptr; // Must be last class member. base::WeakPtrFactory<FederatedClientImpl> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(FederatedClientImpl); }; } // namespace
diff --git a/chromeos/dbus/federated/federated_client.h b/chromeos/dbus/federated/federated_client.h index 1294cb0..c4407c6 100644 --- a/chromeos/dbus/federated/federated_client.h +++ b/chromeos/dbus/federated/federated_client.h
@@ -38,7 +38,7 @@ // * Upon completion of the D-Bus call, `result_callback` will be invoked to // indicate success or failure. // * This method will first wait for the federated service to become - // available. + // available. virtual void BootstrapMojoConnection( base::ScopedFD fd, base::OnceCallback<void(bool success)> result_callback) = 0; @@ -47,9 +47,8 @@ // Initialize/Shutdown should be used instead. FederatedClient(); virtual ~FederatedClient(); - - private: - DISALLOW_COPY_AND_ASSIGN(FederatedClient); + FederatedClient(const FederatedClient&) = delete; + FederatedClient& operator=(const FederatedClient&) = delete; }; } // namespace chromeos
diff --git a/chromeos/dbus/permission_broker/BUILD.gn b/chromeos/dbus/permission_broker/BUILD.gn index 9bcda06..56756df 100644 --- a/chromeos/dbus/permission_broker/BUILD.gn +++ b/chromeos/dbus/permission_broker/BUILD.gn
@@ -4,7 +4,8 @@ import("//third_party/protobuf/proto_library.gni") -assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") +assert(is_chromeos_ash || is_chromeos_lacros, + "Non-Chrome-OS or Lacros builds must not depend on //chromeos") component("permission_broker") { defines = [ "IS_PERMISSION_BROKER_IMPL" ]
diff --git a/chromeos/login/auth/BUILD.gn b/chromeos/login/auth/BUILD.gn index 199df30..94cb169 100644 --- a/chromeos/login/auth/BUILD.gn +++ b/chromeos/login/auth/BUILD.gn
@@ -24,6 +24,7 @@ "//chromeos/dbus/userdataauth", "//chromeos/dbus/userdataauth:userdataauth_proto", "//chromeos/login/login_state", + "//chromeos/metrics", "//chromeos/tpm", "//components/account_id", "//components/device_event_log", @@ -62,8 +63,6 @@ "extended_authenticator_impl.h", "key.cc", "key.h", - "login_event_recorder.cc", - "login_event_recorder.h", "login_performer.cc", "login_performer.h", "password_visibility_utils.cc",
diff --git a/chromeos/login/auth/DEPS b/chromeos/login/auth/DEPS index 3a5b2ad..774c24f 100644 --- a/chromeos/login/auth/DEPS +++ b/chromeos/login/auth/DEPS
@@ -10,6 +10,7 @@ "+base/component_export.h", "+chromeos/cryptohome", "+chromeos/dbus", + "+chromeos/metrics", "+chromeos/login/login_state", "+chromeos/tpm", "+components/account_id",
diff --git a/chromeos/login/auth/cryptohome_authenticator.cc b/chromeos/login/auth/cryptohome_authenticator.cc index 76d91df..7c878063 100644 --- a/chromeos/login/auth/cryptohome_authenticator.cc +++ b/chromeos/login/auth/cryptohome_authenticator.cc
@@ -26,9 +26,9 @@ #include "chromeos/login/auth/cryptohome_key_constants.h" #include "chromeos/login/auth/cryptohome_parameter_utils.h" #include "chromeos/login/auth/key.h" -#include "chromeos/login/auth/login_event_recorder.h" #include "chromeos/login/auth/user_context.h" #include "chromeos/login/login_state/login_state.h" +#include "chromeos/metrics/login_event_recorder.h" #include "components/account_id/account_id.h" #include "components/device_event_log/device_event_log.h" #include "components/user_manager/known_user.h"
diff --git a/chromeos/login/auth/extended_authenticator_impl.cc b/chromeos/login/auth/extended_authenticator_impl.cc index 11af3d0b..32c1d95 100644 --- a/chromeos/login/auth/extended_authenticator_impl.cc +++ b/chromeos/login/auth/extended_authenticator_impl.cc
@@ -17,8 +17,8 @@ #include "chromeos/login/auth/auth_status_consumer.h" #include "chromeos/login/auth/cryptohome_parameter_utils.h" #include "chromeos/login/auth/key.h" -#include "chromeos/login/auth/login_event_recorder.h" #include "chromeos/login/auth/user_context.h" +#include "chromeos/metrics/login_event_recorder.h" #include "components/account_id/account_id.h" #include "crypto/sha2.h" #include "google_apis/gaia/gaia_auth_util.h"
diff --git a/chromeos/login/auth/login_performer.cc b/chromeos/login/auth/login_performer.cc index 98cc0e1..3ba66a3a 100644 --- a/chromeos/login/auth/login_performer.cc +++ b/chromeos/login/auth/login_performer.cc
@@ -15,7 +15,7 @@ #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "chromeos/dbus/session_manager/session_manager_client.h" -#include "chromeos/login/auth/login_event_recorder.h" +#include "chromeos/metrics/login_event_recorder.h" #include "components/account_id/account_id.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_names.h"
diff --git a/chromeos/metrics/BUILD.gn b/chromeos/metrics/BUILD.gn new file mode 100644 index 0000000..f4615463 --- /dev/null +++ b/chromeos/metrics/BUILD.gn
@@ -0,0 +1,23 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chromeos/ui_mode.gni") + +assert(is_chromeos_ash) + +component("metrics") { + defines = [ "IS_CHROMEOS_METRICS_IMPL" ] + + sources = [ + "login_event_recorder.cc", + "login_event_recorder.h", + ] + + output_name = "chromeos_metrics" + + deps = [ + "//base", + "//build:chromeos_buildflags", + ] +}
diff --git a/chromeos/metrics/login_event_recorder.cc b/chromeos/metrics/login_event_recorder.cc new file mode 100644 index 0000000..0ad641e1 --- /dev/null +++ b/chromeos/metrics/login_event_recorder.cc
@@ -0,0 +1,372 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/metrics/login_event_recorder.h" + +#include <vector> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/sequenced_task_runner.h" +#include "base/strings/stringprintf.h" +#include "base/system/sys_info.h" +#include "base/task/current_thread.h" +#include "base/task/thread_pool.h" +#include "base/threading/thread.h" +#include "base/threading/thread_restrictions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "base/trace_event/trace_event.h" +#include "base/values.h" + +namespace chromeos { + +namespace { + +constexpr char kUptime[] = "uptime"; +constexpr char kDisk[] = "disk"; + +// The pointer to this object is used as a perfetto async event id. +constexpr char kBootTimes[] = "BootTimes"; + +#define FPL(value) FILE_PATH_LITERAL(value) + +// Dir uptime & disk logs are located in. +constexpr const base::FilePath::CharType kLogPath[] = FPL("/tmp"); + +// Dir log{in,out} logs are located in. +constexpr base::FilePath::CharType kLoginLogPath[] = FPL("/home/chronos/user"); + +// Prefix for the time measurement files. +constexpr base::FilePath::CharType kUptimePrefix[] = FPL("uptime-"); + +// Prefix for the disk usage files. +constexpr base::FilePath::CharType kDiskPrefix[] = FPL("disk-"); + +// Names of login stats files. +constexpr base::FilePath::CharType kLoginSuccess[] = FPL("login-success"); + +// Delay in milliseconds before writing the login times to disk. +constexpr int64_t kLoginTimeWriteDelayMs = 3000; + +// Appends the given buffer into the file. Returns the number of bytes +// written, or -1 on error.< +// TODO(satorux): Move this to file_util. +int AppendFile(const base::FilePath& file_path, const char* data, int size) { + // Appending boot times to (probably) a symlink in /tmp is a security risk for + // developers with chromeos=1 builds. + if (!base::SysInfo::IsRunningOnChromeOS()) + return -1; + + FILE* file = base::OpenFile(file_path, "a"); + if (!file) + return -1; + + const int num_bytes_written = fwrite(data, 1, size, file); + base::CloseFile(file); + return num_bytes_written; +} + +void WriteTimes(const std::string base_name, + const std::string uma_name, + const std::string uma_prefix, + std::vector<LoginEventRecorder::TimeMarker> times) { + DCHECK(times.size()); + const int kMinTimeMillis = 1; + const int kMaxTimeMillis = 30000; + const int kNumBuckets = 100; + const base::FilePath log_path(kLoginLogPath); + + // Need to sort by time since the entries may have been pushed onto the + // vector (on the UI thread) in a different order from which they were + // created (potentially on other threads). + std::sort(times.begin(), times.end()); + + base::Time first = times.front().time(); + base::Time last = times.back().time(); + base::TimeDelta total = last - first; + base::HistogramBase* total_hist = base::Histogram::FactoryTimeGet( + uma_name, base::TimeDelta::FromMilliseconds(kMinTimeMillis), + base::TimeDelta::FromMilliseconds(kMaxTimeMillis), kNumBuckets, + base::HistogramBase::kUmaTargetedHistogramFlag); + total_hist->AddTime(total); + std::string output = + base::StringPrintf("%s: %.2f", uma_name.c_str(), total.InSecondsF()); + base::Time prev = first; + // Convert base::Time to base::TimeTicks for tracing. + auto time2timeticks = [](const base::Time& ts) { + return base::TimeTicks::Now() - (base::Time::Now() - ts); + }; + // Send first event to name the track: + // "In Chrome, we usually don't bother setting explicit track names. If none + // is provided, the track is named after the first event on the track." + TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( + "startup", kBootTimes, TRACE_ID_LOCAL(kBootTimes), time2timeticks(prev)); + + for (unsigned int i = 0; i < times.size(); ++i) { + const LoginEventRecorder::TimeMarker& tm = times[i]; + + if (tm.url().has_value()) { + TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1( + "startup", tm.name(), TRACE_ID_LOCAL(kBootTimes), + time2timeticks(prev), "url", *tm.url()); + TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1( + "startup", tm.name(), TRACE_ID_LOCAL(kBootTimes), + time2timeticks(tm.time()), "url", *tm.url()); + } else { + TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( + "startup", tm.name(), TRACE_ID_LOCAL(kBootTimes), + time2timeticks(prev)); + TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0("startup", tm.name(), + TRACE_ID_LOCAL(kBootTimes), + time2timeticks(tm.time())); + } + + base::TimeDelta since_first = tm.time() - first; + base::TimeDelta since_prev = tm.time() - prev; + std::string name; + + if (tm.send_to_uma()) { + name = uma_prefix + tm.name(); + base::HistogramBase* prev_hist = base::Histogram::FactoryTimeGet( + name, base::TimeDelta::FromMilliseconds(kMinTimeMillis), + base::TimeDelta::FromMilliseconds(kMaxTimeMillis), kNumBuckets, + base::HistogramBase::kUmaTargetedHistogramFlag); + prev_hist->AddTime(since_prev); + } else { + name = tm.name(); + } + output += base::StringPrintf("\n%.2f +%.4f %s", since_first.InSecondsF(), + since_prev.InSecondsF(), name.data()); + if (tm.url().has_value()) { + output += ": "; + output += *tm.url(); + } + prev = tm.time(); + } + output += '\n'; + TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( + "startup", kBootTimes, TRACE_ID_LOCAL(kBootTimes), time2timeticks(prev)); + + base::WriteFile(log_path.Append(base_name), output.data(), output.size()); +} + +} // namespace + +LoginEventRecorder::TimeMarker::TimeMarker(const char* name, + absl::optional<std::string> url, + bool send_to_uma) + : name_(name), url_(url), send_to_uma_(send_to_uma) {} + +LoginEventRecorder::TimeMarker::TimeMarker(const TimeMarker& other) = default; + +LoginEventRecorder::TimeMarker::~TimeMarker() = default; + +// static +LoginEventRecorder::Stats LoginEventRecorder::Stats::GetCurrentStats() { + const base::FilePath kProcUptime(FPL("/proc/uptime")); + const base::FilePath kDiskStat(FPL("/sys/block/sda/stat")); + Stats stats; + // Callers of this method expect synchronous behavior. + // It's safe to allow IO here, because only virtual FS are accessed. + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ReadFileToString(kProcUptime, &stats.uptime_); + base::ReadFileToString(kDiskStat, &stats.disk_); + return stats; +} + +std::string LoginEventRecorder::Stats::SerializeToString() const { + if (uptime_.empty() && disk_.empty()) + return std::string(); + base::DictionaryValue dictionary; + dictionary.SetString(kUptime, uptime_); + dictionary.SetString(kDisk, disk_); + + std::string result; + if (!base::JSONWriter::Write(dictionary, &result)) { + LOG(WARNING) << "LoginEventRecorder::Stats::SerializeToString(): failed."; + return std::string(); + } + + return result; +} + +// static +LoginEventRecorder::Stats LoginEventRecorder::Stats::DeserializeFromString( + const std::string& source) { + if (source.empty()) + return Stats(); + + std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(source); + base::DictionaryValue* dictionary; + if (!value || !value->GetAsDictionary(&dictionary)) { + LOG(ERROR) << "LoginEventRecorder::Stats::DeserializeFromString(): not a " + "dictionary: '" + << source << "'"; + return Stats(); + } + + Stats result; + if (!dictionary->GetString(kUptime, &result.uptime_) || + !dictionary->GetString(kDisk, &result.disk_)) { + LOG(ERROR) + << "LoginEventRecorder::Stats::DeserializeFromString(): format error: '" + << source << "'"; + return Stats(); + } + + return result; +} + +bool LoginEventRecorder::Stats::UptimeDouble(double* result) const { + std::string uptime = uptime_; + const size_t space_at = uptime.find_first_of(' '); + if (space_at == std::string::npos) + return false; + + uptime.resize(space_at); + + if (base::StringToDouble(uptime, result)) + return true; + + return false; +} + +void LoginEventRecorder::Stats::RecordStats(const std::string& name) const { + base::ThreadPool::PostTask( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(&LoginEventRecorder::Stats::RecordStatsAsync, + base::Owned(new Stats(*this)), name)); +} + +void LoginEventRecorder::Stats::RecordStatsWithCallback( + const std::string& name, + base::OnceClosure callback) const { + base::ThreadPool::PostTaskAndReply( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(&LoginEventRecorder::Stats::RecordStatsAsync, + base::Owned(new Stats(*this)), name), + std::move(callback)); +} + +void LoginEventRecorder::Stats::RecordStatsAsync( + const base::FilePath::StringType& name) const { + const base::FilePath log_path(kLogPath); + const base::FilePath uptime_output = + log_path.Append(base::FilePath(kUptimePrefix + name)); + const base::FilePath disk_output = + log_path.Append(base::FilePath(kDiskPrefix + name)); + + // Append numbers to the files. + AppendFile(uptime_output, uptime_.data(), uptime_.size()); + AppendFile(disk_output, disk_.data(), disk_.size()); +} + +static base::LazyInstance<LoginEventRecorder>::DestructorAtExit + g_login_event_recorder = LAZY_INSTANCE_INITIALIZER; + +LoginEventRecorder::LoginEventRecorder() + : task_runner_(base::SequencedTaskRunnerHandle::Get()) { + DCHECK(base::CurrentUIThread::IsSet()); + login_time_markers_.reserve(30); + logout_time_markers_.reserve(30); +} + +LoginEventRecorder::~LoginEventRecorder() = default; + +// static +LoginEventRecorder* LoginEventRecorder::Get() { + return g_login_event_recorder.Pointer(); +} + +void LoginEventRecorder::AddLoginTimeMarker(const char* marker_name, + bool send_to_uma) { + AddLoginTimeMarkerWithURL(marker_name, absl::optional<std::string>(), + send_to_uma); +} + +void LoginEventRecorder::AddLoginTimeMarkerWithURL( + const char* marker_name, + absl::optional<std::string> url, + bool send_to_uma) { + // Do not contaminate the UMA in the field. + if (write_login_requested_ && send_to_uma) { + LOG(WARNING) << "LoginTime Marker was requested after LoginDone()"; + return; + } + + AddMarker(&login_time_markers_, TimeMarker(marker_name, url, send_to_uma)); +} + +void LoginEventRecorder::AddLogoutTimeMarker(const char* marker_name, + bool send_to_uma) { + AddMarker( + &logout_time_markers_, + TimeMarker(marker_name, absl::optional<std::string>(), send_to_uma)); +} + +void LoginEventRecorder::RecordAuthenticationSuccess() { + AddLoginTimeMarker("Authenticate", true); + RecordCurrentStats(kLoginSuccess); +} + +void LoginEventRecorder::RecordAuthenticationFailure() { + // no nothing for now. +} + +void LoginEventRecorder::RecordCurrentStats(const std::string& name) { + Stats::GetCurrentStats().RecordStats(name); +} + +void LoginEventRecorder::ClearLoginTimeMarkers() { + login_time_markers_.clear(); +} + +void LoginEventRecorder::WriteLoginTimes(const std::string base_name, + const std::string uma_name, + const std::string uma_prefix) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + write_login_requested_ = true; + base::ThreadPool::PostDelayedTask( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(&LoginEventRecorder::WriteLoginTimesDelayed, + weak_ptr_factory_.GetWeakPtr(), base_name, uma_name, + uma_prefix), + base::TimeDelta::FromMilliseconds(kLoginTimeWriteDelayMs)); +} + +void LoginEventRecorder::WriteLogoutTimes(const std::string base_name, + const std::string uma_name, + const std::string uma_prefix) { + WriteTimes(base_name, uma_name, uma_prefix, std::move(logout_time_markers_)); +} + +void LoginEventRecorder::AddMarker(std::vector<TimeMarker>* vector, + TimeMarker&& marker) { + // The marker vectors can only be safely manipulated on the main thread. + // If we're late in the process of shutting down (eg. as can be the case at + // logout), then we have to assume we're on the main thread already. + if (task_runner_->RunsTasksInCurrentSequence()) { + vector->push_back(marker); + } else { + // Add the marker on the UI thread. + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&LoginEventRecorder::AddMarker, + weak_ptr_factory_.GetWeakPtr(), + base::Unretained(vector), marker)); + } +} + +void LoginEventRecorder::WriteLoginTimesDelayed(const std::string base_name, + const std::string uma_name, + const std::string uma_prefix) { + WriteTimes(base_name, uma_name, uma_prefix, std::move(login_time_markers_)); +} + +} // namespace chromeos
diff --git a/chromeos/metrics/login_event_recorder.h b/chromeos/metrics/login_event_recorder.h new file mode 100644 index 0000000..81a91f6 --- /dev/null +++ b/chromeos/metrics/login_event_recorder.h
@@ -0,0 +1,142 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_METRICS_LOGIN_EVENT_RECORDER_H_ +#define CHROMEOS_METRICS_LOGIN_EVENT_RECORDER_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/component_export.h" +#include "base/memory/ref_counted.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace base { +class SequencedTaskRunner; +} + +namespace chromeos { + +// LoginEventRecorder is a utility class used to save the bootimes of Chrome OS. +class COMPONENT_EXPORT(CHROMEOS_METRICS) LoginEventRecorder { + public: + class TimeMarker { + public: + TimeMarker(const char* name, + absl::optional<std::string> url, + bool send_to_uma); + TimeMarker(const TimeMarker& other); + ~TimeMarker(); + + const char* name() const { return name_; } + base::Time time() const { return time_; } + const absl::optional<std::string>& url() const { return url_; } + bool send_to_uma() const { return send_to_uma_; } + + // comparator for sorting + bool operator<(const TimeMarker& other) const { + return time_ < other.time_; + } + + private: + friend class std::vector<TimeMarker>; + const char* name_; + base::Time time_ = base::Time::NowFromSystemTime(); + absl::optional<std::string> url_; + bool send_to_uma_; + }; + + class Stats { + public: + // Initializes stats with current /proc values. + static Stats GetCurrentStats(); + + // Returns JSON representation. + std::string SerializeToString() const; + + // Creates new object from JSON representation. + static Stats DeserializeFromString(const std::string& value); + + const std::string& uptime() const { return uptime_; } + const std::string& disk() const { return disk_; } + + // Writes "uptime in seconds" to result. (This is first field in uptime_.) + // Returns true on successful conversion. + bool UptimeDouble(double* result) const; + + void RecordStats(const std::string& name) const; + void RecordStatsWithCallback(const std::string& name, + base::OnceClosure callback) const; + + private: + // Runs asynchronously when RecordStats(WithCallback) is called. + void RecordStatsAsync(const std::string& name) const; + + std::string uptime_; + std::string disk_; + }; + + LoginEventRecorder(); + LoginEventRecorder(const LoginEventRecorder&) = delete; + LoginEventRecorder& operator=(const LoginEventRecorder&) = delete; + virtual ~LoginEventRecorder(); + + static LoginEventRecorder* Get(); + + // Add a time marker for login. A timeline will be dumped to + // /tmp/login-times-sent after login is done. If |send_to_uma| is true + // the time between this marker and the last will be sent to UMA with + // the identifier BootTime.|marker_name|. + void AddLoginTimeMarker(const char* marker_name, bool send_to_uma); + + void AddLoginTimeMarkerWithURL(const char* marker_name, + absl::optional<std::string> url, + bool send_to_uma); + + // Add a time marker for logout. A timeline will be dumped to + // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true + // the time between this marker and the last will be sent to UMA with + // the identifier ShutdownTime.|marker_name|. + void AddLogoutTimeMarker(const char* marker_name, bool send_to_uma); + + // Record events for successful authentication. + void RecordAuthenticationSuccess(); + + // Record events for authentication failure. + void RecordAuthenticationFailure(); + + void ClearLoginTimeMarkers(); + + // Records current uptime and disk usage for metrics use. + // Posts task to file thread. + // name will be used as part of file names in /tmp. + // Existing stats files will not be overwritten. + void RecordCurrentStats(const std::string& name); + + // Write login and logout times to logs. + void WriteLoginTimes(const std::string base_name, + const std::string uma_name, + const std::string uma_prefix); + + void WriteLogoutTimes(const std::string base_name, + const std::string uma_name, + const std::string uma_prefix); + + private: + void AddMarker(std::vector<TimeMarker>* vector, TimeMarker&& marker); + + void WriteLoginTimesDelayed(const std::string base_name, + const std::string uma_name, + const std::string uma_prefix); + std::vector<TimeMarker> login_time_markers_; + std::vector<TimeMarker> logout_time_markers_; + bool write_login_requested_ = false; + scoped_refptr<base::SequencedTaskRunner> task_runner_; + + base::WeakPtrFactory<LoginEventRecorder> weak_ptr_factory_{this}; +}; + +} // namespace chromeos + +#endif // CHROMEOS_METRICS_LOGIN_EVENT_RECORDER_H_
diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc index 81161b9b..e5893e2 100644 --- a/chromeos/network/onc/onc_utils.cc +++ b/chromeos/network/onc/onc_utils.cc
@@ -495,43 +495,38 @@ // Returns the NetworkConfiugration with |guid| from |network_configs|, or // nullptr if no such NetworkConfiguration is found. -const base::DictionaryValue* GetNetworkConfigByGUID( - const base::Value& network_configs, - const std::string& guid) { - for (const auto& entry : network_configs.GetList()) { - const base::DictionaryValue* network = nullptr; - entry.GetAsDictionary(&network); - DCHECK(network); +const base::Value* GetNetworkConfigByGUID(const base::Value& network_configs, + const std::string& guid) { + for (const auto& network : network_configs.GetList()) { + DCHECK(network.is_dict()); - std::string current_guid = - GetString(*network, ::onc::network_config::kGUID); + std::string current_guid = GetString(network, ::onc::network_config::kGUID); if (current_guid == guid) - return network; + return &network; } return nullptr; } // Returns the first Ethernet NetworkConfiguration from |network_configs| with // "Authentication: None", or nullptr if no such NetworkConfiguration is found. -const base::DictionaryValue* GetNetworkConfigForEthernetWithoutEAP( +const base::Value* GetNetworkConfigForEthernetWithoutEAP( const base::Value& network_configs) { VLOG(2) << "Search for ethernet policy without EAP."; - for (const auto& entry : network_configs.GetList()) { - const base::DictionaryValue* network = nullptr; - entry.GetAsDictionary(&network); - DCHECK(network); + for (const auto& network : network_configs.GetList()) { + DCHECK(network.is_dict()); - std::string type = GetString(*network, ::onc::network_config::kType); + std::string type = GetString(network, ::onc::network_config::kType); if (type != ::onc::network_type::kEthernet) continue; - const base::DictionaryValue* ethernet = nullptr; - network->GetDictionaryWithoutPathExpansion(::onc::network_config::kEthernet, - ðernet); + const base::Value* ethernet = + network.FindDictKey(::onc::network_config::kEthernet); + if (!ethernet) + continue; std::string auth = GetString(*ethernet, ::onc::ethernet::kAuthentication); if (auth == ::onc::ethernet::kAuthenticationNone) - return network; + return &network; } return nullptr; } @@ -542,7 +537,7 @@ // is an Ethernet network, tries lookup of the GUID of the shared EthernetEAP // service, or otherwise returns the first Ethernet NetworkConfiguration with // "Authentication: None". -const base::DictionaryValue* GetNetworkConfigForNetworkFromOnc( +const base::Value* GetNetworkConfigForNetworkFromOnc( const base::Value& network_configs, const NetworkState& network) { // In all cases except Ethernet, we use the GUID of |network|. @@ -576,10 +571,9 @@ // Returns the NetworkConfiguration ONC object for |network| from this ONC, or // nullptr if no configuration is found. See |GetNetworkConfigForNetworkFromOnc| // for the NetworkConfiguration lookup rules. -const base::DictionaryValue* GetPolicyForNetworkFromPref( - const PrefService* pref_service, - const char* pref_name, - const NetworkState& network) { +const base::Value* GetPolicyForNetworkFromPref(const PrefService* pref_service, + const char* pref_name, + const NetworkState& network) { if (!pref_service) { VLOG(2) << "No pref service"; return nullptr; @@ -615,7 +609,7 @@ // Returns the global network configuration dictionary from the ONC policy of // the active user if |for_active_user| is true, or from device policy if it is // false. -const base::DictionaryValue* GetGlobalConfigFromPolicy(bool for_active_user) { +const base::Value* GetGlobalConfigFromPolicy(bool for_active_user) { std::string username_hash; if (for_active_user) { const user_manager::User* user = @@ -768,7 +762,8 @@ void ExpandStringsInOncObject(const OncValueSignature& signature, const VariableExpander& variable_expander, - base::DictionaryValue* onc_object) { + base::Value* onc_object) { + DCHECK(onc_object->is_dict()); if (&signature == &kEAPSignature) { ExpandField(::onc::eap::kAnonymousIdentity, variable_expander, onc_object); ExpandField(::onc::eap::kIdentity, variable_expander, onc_object); @@ -778,30 +773,26 @@ } // Recurse into nested objects. - for (base::DictionaryValue::Iterator it(*onc_object); !it.IsAtEnd(); - it.Advance()) { - base::DictionaryValue* inner_object = nullptr; - if (!onc_object->GetDictionaryWithoutPathExpansion(it.key(), &inner_object)) + for (auto it : onc_object->DictItems()) { + if (!it.second.is_dict()) continue; const OncFieldSignature* field_signature = - GetFieldSignature(signature, it.key()); + GetFieldSignature(signature, it.first); if (!field_signature) continue; ExpandStringsInOncObject(*field_signature->value_signature, - variable_expander, inner_object); + variable_expander, &it.second); } } void ExpandStringsInNetworks(const VariableExpander& variable_expander, - base::ListValue* network_configs) { - for (auto& entry : network_configs->GetList()) { - base::DictionaryValue* network = nullptr; - entry.GetAsDictionary(&network); - DCHECK(network); + base::Value* network_configs) { + for (auto& network : network_configs->GetList()) { + DCHECK(network.is_dict()); ExpandStringsInOncObject(kNetworkConfigurationSignature, variable_expander, - network); + &network); } } @@ -906,15 +897,15 @@ bool ParseAndValidateOncForImport(const std::string& onc_blob, ::onc::ONCSource onc_source, const std::string& passphrase, - base::ListValue* network_configs, - base::DictionaryValue* global_network_config, - base::ListValue* certificates) { + base::Value* network_configs, + base::Value* global_network_config, + base::Value* certificates) { if (network_configs) - network_configs->Clear(); + network_configs->ClearList(); if (global_network_config) - global_network_config->Clear(); + global_network_config->DictClear(); if (certificates) - certificates->Clear(); + certificates->ClearList(); if (onc_blob.empty()) return true; @@ -950,6 +941,7 @@ validator.SetOncSource(onc_source); Validator::Result validation_result; + // TODO(crbug.com/1226202): Use base::Value once onc::Validator is converted. std::unique_ptr<base::DictionaryValue> validated_toplevel_onc = validator.ValidateAndRepairObject(&kToplevelConfigurationSignature, toplevel_onc, &validation_result); @@ -972,21 +964,19 @@ } if (certificates) { - base::Value* validated_certs = validated_toplevel_onc->FindKeyOfType( - ::onc::toplevel_config::kCertificates, base::Value::Type::LIST); + base::Value* validated_certs = validated_toplevel_onc->FindListKey( + ::onc::toplevel_config::kCertificates); if (validated_certs) - *certificates = base::ListValue(std::move(*validated_certs).TakeList()); + *certificates = std::move(*validated_certs); } // Note that this processing is performed even if |network_configs| is // nullptr, because ResolveServerCertRefsInNetworks could affect the return // value of the function (which is supposed to aggregate validation issues in // all segments of the ONC blob). - base::Value* validated_networks = validated_toplevel_onc->FindKeyOfType( - ::onc::toplevel_config::kNetworkConfigurations, base::Value::Type::LIST); - base::ListValue* validated_networks_list; - if (validated_networks && - validated_networks->GetAsList(&validated_networks_list)) { + base::Value* validated_networks_list = validated_toplevel_onc->FindListKey( + ::onc::toplevel_config::kNetworkConfigurations); + if (validated_networks_list) { FillInHexSSIDFieldsInNetworks(validated_networks_list); // Set HiddenSSID to default value to solve the issue crbug.com/1171837 SetHiddenSSIDFieldsInNetworks(validated_networks_list); @@ -1003,20 +993,14 @@ } if (network_configs) - network_configs->Swap(validated_networks_list); + *network_configs = std::move(*validated_networks_list); } if (global_network_config) { - base::Value* validated_global_config = - validated_toplevel_onc->FindKeyOfType( - ::onc::toplevel_config::kGlobalNetworkConfiguration, - base::Value::Type::DICTIONARY); + base::Value* validated_global_config = validated_toplevel_onc->FindDictKey( + ::onc::toplevel_config::kGlobalNetworkConfiguration); if (validated_global_config) { - base::DictionaryValue* validated_global_config_dict = nullptr; - if (validated_global_config->GetAsDictionary( - &validated_global_config_dict)) { - global_network_config->Swap(validated_global_config_dict); - } + *global_network_config = std::move(*validated_global_config); } } @@ -1035,14 +1019,13 @@ } bool ResolveServerCertRefsInNetworks(const CertPEMsByGUIDMap& certs_by_guid, - base::ListValue* network_configs) { + base::Value* network_configs) { bool success = true; base::Value::ListStorage filtered_configs; - for (base::Value& config : network_configs->GetList()) { - base::DictionaryValue* network = nullptr; - config.GetAsDictionary(&network); - if (!ResolveServerCertRefsInNetwork(certs_by_guid, network)) { - std::string* guid = network->FindStringKey(::onc::network_config::kGUID); + for (base::Value& network : network_configs->GetList()) { + DCHECK(network.is_dict()); + if (!ResolveServerCertRefsInNetwork(certs_by_guid, &network)) { + std::string* guid = network.FindStringKey(::onc::network_config::kGUID); // This might happen even with correct validation, if the referenced // certificate couldn't be imported. LOG(ERROR) << "Couldn't resolve some certificate reference of network " @@ -1051,14 +1034,14 @@ continue; } - filtered_configs.push_back(std::move(config)); + filtered_configs.push_back(std::move(network)); } - *network_configs = base::ListValue(std::move(filtered_configs)); + *network_configs = base::Value(std::move(filtered_configs)); return success; } bool ResolveServerCertRefsInNetwork(const CertPEMsByGUIDMap& certs_by_guid, - base::DictionaryValue* network_config) { + base::Value* network_config) { return ResolveServerCertRefsInObject( certs_by_guid, kNetworkConfigurationSignature, network_config); } @@ -1132,7 +1115,7 @@ // Create a ProxyConfigDictionary from the dictionary. ProxyConfigDictionary proxy_config(proxy_config_value.Clone()); - // Create the result DictionaryValue and populate it. + // Create the result Value and populate it. base::Value proxy_settings(base::Value::Type::DICTIONARY); ProxyPrefs::ProxyMode mode; if (!proxy_config.GetMode(&mode)) @@ -1159,7 +1142,7 @@ case ProxyPrefs::MODE_FIXED_SERVERS: { proxy_settings.SetKey(::onc::proxy::kType, base::Value(::onc::proxy::kManual)); - base::DictionaryValue manual; + base::Value manual(base::Value::Type::DICTIONARY); std::string proxy_rules_string; if (proxy_config.GetProxyServer(&proxy_rules_string)) { net::ProxyConfig::ProxyRules proxy_rules; @@ -1180,9 +1163,9 @@ if (proxy_config.GetBypassList(&bypass_rules_string)) { net::ProxyBypassRules bypass_rules; bypass_rules.ParseFromString(bypass_rules_string); - base::ListValue exclude_domains; + base::Value exclude_domains(base::Value::Type::LIST); for (const auto& rule : bypass_rules.rules()) - exclude_domains.AppendString(rule->ToString()); + exclude_domains.Append(rule->ToString()); if (!exclude_domains.GetList().empty()) { proxy_settings.SetKey(::onc::proxy::kExcludeDomains, std::move(exclude_domains)); @@ -1198,9 +1181,9 @@ return proxy_settings; } -void ExpandStringPlaceholdersInNetworksForUser( - const user_manager::User* user, - base::ListValue* network_configs) { +void ExpandStringPlaceholdersInNetworksForUser(const user_manager::User* user, + base::Value* network_configs) { + DCHECK(network_configs->is_list()); if (!user) { // In tests no user may be logged in. It's not harmful if we just don't // expand the strings. @@ -1218,13 +1201,13 @@ } int ImportNetworksForUser(const user_manager::User* user, - const base::ListValue& network_configs, + const base::Value& network_configs, std::string* error) { + DCHECK(network_configs.is_list()); error->clear(); - std::unique_ptr<base::ListValue> expanded_networks( - network_configs.DeepCopy()); - ExpandStringPlaceholdersInNetworksForUser(user, expanded_networks.get()); + base::Value expanded_networks(network_configs.Clone()); + ExpandStringPlaceholdersInNetworksForUser(user, &expanded_networks); const NetworkProfile* profile = NetworkHandler::Get()->network_profile_handler()->GetProfileForUserhash( @@ -1236,7 +1219,9 @@ bool ethernet_not_found = false; int networks_created = 0; - for (const auto& entry : expanded_networks->GetList()) { + for (const auto& entry : expanded_networks.GetList()) { + // TODO(crbug.com/1226202): Remove DictionaryValue conversion once + // onc::Normalizer is converted. const base::DictionaryValue* network = nullptr; entry.GetAsDictionary(&network); DCHECK(network); @@ -1288,20 +1273,8 @@ return networks_created; } -const base::DictionaryValue* FindPolicyForActiveUser( - const std::string& guid, - ::onc::ONCSource* onc_source) { - const user_manager::User* user = - user_manager::UserManager::Get()->GetActiveUser(); - std::string username_hash = user ? user->username_hash() : std::string(); - return NetworkHandler::Get() - ->managed_network_configuration_handler() - ->FindPolicyByGUID(username_hash, guid, onc_source); -} - bool PolicyAllowsOnlyPolicyNetworksToAutoconnect(bool for_active_user) { - const base::DictionaryValue* global_config = - GetGlobalConfigFromPolicy(for_active_user); + const base::Value* global_config = GetGlobalConfigFromPolicy(for_active_user); if (!global_config) return false; // By default, all networks are allowed to autoconnect. @@ -1311,15 +1284,14 @@ .value_or(false); } -const base::DictionaryValue* GetPolicyForNetwork( - const PrefService* profile_prefs, - const PrefService* local_state_prefs, - const NetworkState& network, - ::onc::ONCSource* onc_source) { +const base::Value* GetPolicyForNetwork(const PrefService* profile_prefs, + const PrefService* local_state_prefs, + const NetworkState& network, + ::onc::ONCSource* onc_source) { VLOG(2) << "GetPolicyForNetwork: " << network.path(); *onc_source = ::onc::ONC_SOURCE_NONE; - const base::DictionaryValue* network_policy = GetPolicyForNetworkFromPref( + const base::Value* network_policy = GetPolicyForNetworkFromPref( profile_prefs, ::onc::prefs::kOpenNetworkConfiguration, network); if (network_policy) { VLOG(1) << "Network " << network.path() << " is managed by user policy."; @@ -1342,58 +1314,49 @@ const PrefService* local_state_prefs, const NetworkState& network) { ::onc::ONCSource ignored_onc_source; - const base::DictionaryValue* policy = onc::GetPolicyForNetwork( + const base::Value* policy = onc::GetPolicyForNetwork( profile_prefs, local_state_prefs, network, &ignored_onc_source); return policy != nullptr; } bool HasUserPasswordSubsitutionVariable(const OncValueSignature& signature, - base::DictionaryValue* onc_object) { + base::Value* onc_object) { + DCHECK(onc_object->is_dict()); if (&signature == &kEAPSignature) { std::string* password_field = onc_object->FindStringKey(::onc::eap::kPassword); - if (!password_field) { + if (!password_field) return false; - } - - if (*password_field == ::onc::substitutes::kPasswordPlaceholderVerbatim) { + if (*password_field == ::onc::substitutes::kPasswordPlaceholderVerbatim) return true; - } } // Recurse into nested objects. - for (base::DictionaryValue::Iterator it(*onc_object); !it.IsAtEnd(); - it.Advance()) { - base::DictionaryValue* inner_object = nullptr; - if (!onc_object->GetDictionaryWithoutPathExpansion(it.key(), &inner_object)) + for (auto it : onc_object->DictItems()) { + if (!it.second.is_dict()) continue; const OncFieldSignature* field_signature = - GetFieldSignature(signature, it.key()); + GetFieldSignature(signature, it.first); if (!field_signature) continue; bool result = HasUserPasswordSubsitutionVariable( - *field_signature->value_signature, inner_object); - if (result) { + *field_signature->value_signature, &it.second); + if (result) return true; - } } return false; } -bool HasUserPasswordSubsitutionVariable(base::ListValue* network_configs) { - for (auto& entry : network_configs->GetList()) { - base::DictionaryValue* network = nullptr; - entry.GetAsDictionary(&network); - DCHECK(network); - +bool HasUserPasswordSubsitutionVariable(base::Value* network_configs) { + for (auto& network : network_configs->GetList()) { + DCHECK(network.is_dict()); bool result = HasUserPasswordSubsitutionVariable( - kNetworkConfigurationSignature, network); - if (result) { + kNetworkConfigurationSignature, &network); + if (result) return true; - } } return false; }
diff --git a/chromeos/network/onc/onc_utils.h b/chromeos/network/onc/onc_utils.h index 9bb5298..cd25e9c 100644 --- a/chromeos/network/onc/onc_utils.h +++ b/chromeos/network/onc/onc_utils.h
@@ -20,8 +20,7 @@ class PrefService; namespace base { -class DictionaryValue; -class ListValue; +class Value; } namespace user_manager { @@ -66,13 +65,13 @@ COMPONENT_EXPORT(CHROMEOS_NETWORK) void ExpandStringsInOncObject(const OncValueSignature& signature, const VariableExpander& variable_expander, - base::DictionaryValue* onc_object); + base::Value* onc_object); // Replaces expandable fields in the networks of |network_configs|, which must // be a list of ONC NetworkConfigurations. See ExpandStringsInOncObject above. COMPONENT_EXPORT(CHROMEOS_NETWORK) void ExpandStringsInNetworks(const VariableExpander& variable_expander, - base::ListValue* network_configs); + base::Value* network_configs); // Fills in all missing HexSSID fields that are mentioned in the ONC // specification. The object of |onc_object| is modified in place. @@ -118,9 +117,9 @@ bool ParseAndValidateOncForImport(const std::string& onc_blob, ::onc::ONCSource onc_source, const std::string& passphrase, - base::ListValue* network_configs, - base::DictionaryValue* global_network_config, - base::ListValue* certificates); + base::Value* network_configs, + base::Value* global_network_config, + base::Value* certificates); // Parse the given PEM encoded certificate |pem_encoded| and return the // contained DER encoding. Returns an empty string on failure. @@ -138,14 +137,14 @@ // NetworkConfiguration dictionaries. COMPONENT_EXPORT(CHROMEOS_NETWORK) bool ResolveServerCertRefsInNetworks(const CertPEMsByGUIDMap& certs_by_guid, - base::ListValue* network_configs); + base::Value* network_configs); // Replaces all references by GUID to Server or CA certs by their PEM // encoding. Returns true if all references could be resolved. |network_config| // must be a ONC NetworkConfiguration. COMPONENT_EXPORT(CHROMEOS_NETWORK) bool ResolveServerCertRefsInNetwork(const CertPEMsByGUIDMap& certs_by_guid, - base::DictionaryValue* network_config); + base::Value* network_config); // Returns a network type pattern for matching the ONC type string. COMPONENT_EXPORT(CHROMEOS_NETWORK) @@ -167,25 +166,15 @@ // be a list of ONC NetworkConfigurations. Currently only user name placeholders // are implemented, which are replaced by attributes from |user|. COMPONENT_EXPORT(CHROMEOS_NETWORK) -void ExpandStringPlaceholdersInNetworksForUser( - const user_manager::User* user, - base::ListValue* network_configs); +void ExpandStringPlaceholdersInNetworksForUser(const user_manager::User* user, + base::Value* network_configs); // Returns the number of networks successfully imported. COMPONENT_EXPORT(CHROMEOS_NETWORK) int ImportNetworksForUser(const user_manager::User* user, - const base::ListValue& network_configs, + const base::Value& network_configs, std::string* error); -// Looks up the policy for |guid| for the current active user and sets -// |global_config| (if not NULL) and |onc_source| (if not NULL) accordingly. If -// |guid| is empty, returns NULL and sets the |global_config| and |onc_source| -// if a policy is found. -COMPONENT_EXPORT(CHROMEOS_NETWORK) -const base::DictionaryValue* FindPolicyForActiveUser( - const std::string& guid, - ::onc::ONCSource* onc_source); - // Convenvience function to retrieve the "AllowOnlyPolicyNetworksToAutoconnect" // setting from the global network configuration (see // GetGlobalConfigFromPolicy). @@ -196,11 +185,10 @@ // |profile_prefs| and |local_state_prefs| might be NULL. Returns NULL if no // applicable policy is found. Sets |onc_source| accordingly. COMPONENT_EXPORT(CHROMEOS_NETWORK) -const base::DictionaryValue* GetPolicyForNetwork( - const PrefService* profile_prefs, - const PrefService* local_state_prefs, - const NetworkState& network, - ::onc::ONCSource* onc_source); +const base::Value* GetPolicyForNetwork(const PrefService* profile_prefs, + const PrefService* local_state_prefs, + const NetworkState& network, + ::onc::ONCSource* onc_source); // Convenience function to check only whether a policy for a network exists. COMPONENT_EXPORT(CHROMEOS_NETWORK) @@ -212,12 +200,12 @@ // variable set as the password. COMPONENT_EXPORT(CHROMEOS_NETWORK) bool HasUserPasswordSubsitutionVariable(const OncValueSignature& signature, - base::DictionaryValue* onc_object); + base::Value* onc_object); // Checks whether a list of network objects has at least one network with the // ${PASSWORD} substitution variable set as the password. COMPONENT_EXPORT(CHROMEOS_NETWORK) -bool HasUserPasswordSubsitutionVariable(base::ListValue* network_configs); +bool HasUserPasswordSubsitutionVariable(base::Value* network_configs); } // namespace onc } // namespace chromeos
diff --git a/chromeos/network/onc/onc_utils_unittest.cc b/chromeos/network/onc/onc_utils_unittest.cc index f07d6eb..f9309d1 100644 --- a/chromeos/network/onc/onc_utils_unittest.cc +++ b/chromeos/network/onc/onc_utils_unittest.cc
@@ -142,14 +142,11 @@ bool expected_success = (networks_with_cert_refs->GetSize() == expected_resolved_onc->GetSize()); - std::unique_ptr<base::ListValue> actual_resolved_onc( - networks_with_cert_refs->DeepCopy()); - - bool success = - ResolveServerCertRefsInNetworks(certs, actual_resolved_onc.get()); + base::Value actual_resolved_onc(networks_with_cert_refs->Clone()); + bool success = ResolveServerCertRefsInNetworks(certs, &actual_resolved_onc); EXPECT_EQ(expected_success, success); EXPECT_TRUE( - test_utils::Equals(expected_resolved_onc, actual_resolved_onc.get())); + test_utils::Equals(expected_resolved_onc, &actual_resolved_onc)); } }
diff --git a/chromeos/network/proxy/proxy_config_handler.cc b/chromeos/network/proxy/proxy_config_handler.cc index 59c9fc6..fff40d4 100644 --- a/chromeos/network/proxy/proxy_config_handler.cc +++ b/chromeos/network/proxy/proxy_config_handler.cc
@@ -47,13 +47,11 @@ const NetworkState& network, const NetworkProfileHandler* network_profile_handler, ::onc::ONCSource* onc_source) { - const base::DictionaryValue* network_policy = onc::GetPolicyForNetwork( + const base::Value* network_policy = onc::GetPolicyForNetwork( profile_prefs, local_state_prefs, network, onc_source); - if (network_policy) { - const base::DictionaryValue* proxy_policy = NULL; - network_policy->GetDictionaryWithoutPathExpansion( - ::onc::network_config::kProxySettings, &proxy_policy); + const base::Value* proxy_policy = + network_policy->FindDictKey(::onc::network_config::kProxySettings); if (!proxy_policy) { // This policy doesn't set a proxy for this network. Nonetheless, this // disallows changes by the user.
diff --git a/chromeos/services/device_sync/cryptauth_feature_type.cc b/chromeos/services/device_sync/cryptauth_feature_type.cc index 1ca0115..49d9e13 100644 --- a/chromeos/services/device_sync/cryptauth_feature_type.cc +++ b/chromeos/services/device_sync/cryptauth_feature_type.cc
@@ -8,7 +8,6 @@ #include "base/base64url.h" #include "base/containers/flat_map.h" #include "base/no_destructor.h" -#include "base/stl_util.h" #include "crypto/sha2.h" namespace chromeos {
diff --git a/chromeos/ui/frame/caption_buttons/frame_center_button.cc b/chromeos/ui/frame/caption_buttons/frame_center_button.cc index d91b4ab3..3122a7cf 100644 --- a/chromeos/ui/frame/caption_buttons/frame_center_button.cc +++ b/chromeos/ui/frame/caption_buttons/frame_center_button.cc
@@ -9,6 +9,7 @@ #include "ui/aura/window_tree_host.h" #include "ui/base/hit_test.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/paint_vector_icon.h" @@ -189,4 +190,7 @@ text_->SetColor(GetButtonColor(GetBackgroundColor())); } +BEGIN_METADATA(FrameCenterButton, views::FrameCaptionButton) +END_METADATA + } // namespace chromeos
diff --git a/chromeos/ui/frame/caption_buttons/frame_center_button.h b/chromeos/ui/frame/caption_buttons/frame_center_button.h index 1d5ba47..0f0b98f 100644 --- a/chromeos/ui/frame/caption_buttons/frame_center_button.h +++ b/chromeos/ui/frame/caption_buttons/frame_center_button.h
@@ -7,6 +7,7 @@ #include "base/component_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/base/metadata/metadata_header_macros.h" #include "ui/gfx/render_text.h" #include "ui/views/window/frame_caption_button.h" @@ -18,6 +19,8 @@ class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) FrameCenterButton : public views::FrameCaptionButton { public: + METADATA_HEADER(FrameCenterButton); + FrameCenterButton(PressedCallback callback); FrameCenterButton(const FrameCenterButton&) = delete; FrameCenterButton& operator=(const FrameCenterButton&) = delete;
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index 193ab2dc..68c0162 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -22,6 +22,8 @@ "compat_mode/arc_resize_lock_pref_delegate.h", "compat_mode/arc_splash_screen_dialog_view.cc", "compat_mode/arc_splash_screen_dialog_view.h", + "compat_mode/arc_window_property_util.cc", + "compat_mode/arc_window_property_util.h", "compat_mode/overlay_dialog.cc", "compat_mode/overlay_dialog.h", "compat_mode/resize_confirmation_dialog_view.cc",
diff --git a/components/arc/compat_mode/arc_resize_lock_manager.cc b/components/arc/compat_mode/arc_resize_lock_manager.cc index fa072c570..9072f31 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager.cc +++ b/components/arc/compat_mode/arc_resize_lock_manager.cc
@@ -15,10 +15,13 @@ #include "base/bind.h" #include "base/callback_forward.h" #include "base/memory/singleton.h" +#include "base/memory/weak_ptr.h" +#include "base/notreached.h" #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/default_frame_header.h" #include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/compat_mode/arc_splash_screen_dialog_view.h" +#include "components/arc/compat_mode/arc_window_property_util.h" #include "components/arc/compat_mode/resize_toggle_menu.h" #include "components/arc/compat_mode/resize_util.h" #include "components/arc/vector_icons/vector_icons.h" @@ -114,6 +117,62 @@ base::ScopedObservation<aura::Window, aura::WindowObserver> observer_{this}; }; +// A self-deleting window property observer that runs the given callback when +// its ash::kAppIDKey is set to non-null value. +class AppIdObserver : public aura::WindowObserver { + public: + AppIdObserver(const AppIdObserver&) = delete; + AppIdObserver& operator=(const AppIdObserver&) = delete; + + static void RunOnReady(aura::Window* window, + base::OnceCallback<void(aura::Window*)> on_ready) { + if (GetAppId(window)) { + std::move(on_ready).Run(window); + return; + } + + // The following instance self-destructs when the window gets activated or + // destroyed before getting activated. + new AppIdObserver(window, std::move(on_ready)); + } + + // aura::WindowObserver: + void OnWindowDestroying(aura::Window* window) override { + DCHECK(observer_.IsObservingSource(window)); + delete this; + } + void OnWindowPropertyChanged(aura::Window* window, + const void* key, + intptr_t old) override { + DCHECK(observer_.IsObservingSource(window)); + if (key != ash::kAppIDKey) + return; + if (!GetAppId(window)) + return; + observer_.Reset(); + std::move(on_ready_).Run(window); + delete this; + } + + private: + AppIdObserver(aura::Window* window, + base::OnceCallback<void(aura::Window*)> on_ready) + : window_(window), on_ready_(std::move(on_ready)) { + DCHECK(!on_ready_.is_null()); + observer_.Observe(window_); + } + + ~AppIdObserver() override { observer_.Reset(); } + + aura::Window* const window_; + base::OnceCallback<void(aura::Window*)> on_ready_; + base::ScopedObservation<aura::Window, aura::WindowObserver> observer_{this}; +}; + +bool ShouldEnableResizeLock(ash::ArcResizeLockType type) { + return type != ash::ArcResizeLockType::RESIZABLE; +} + } // namespace // static @@ -144,31 +203,37 @@ void ArcResizeLockManager::OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) { - if (key != ash::kArcResizeLockTypeKey && key != ash::kAppIDKey) + if (key != ash::kArcResizeLockTypeKey) return; - if (window->GetProperty(ash::kAppIDKey) == nullptr) + const auto new_value = window->GetProperty(ash::kArcResizeLockTypeKey); + const auto old_value = static_cast<ash::ArcResizeLockType>(old); + + if (new_value == old_value) return; - UpdateCompatModeButton(window); + AppIdObserver::RunOnReady( + window, base::BindOnce(&ArcResizeLockManager::UpdateCompatModeButton, + weak_ptr_factory_.GetWeakPtr())); - const ash::ArcResizeLockType current_resize_lock_value = - window->GetProperty(ash::kArcResizeLockTypeKey); - const bool resize_lock_changed = - (key == ash::kArcResizeLockTypeKey && - current_resize_lock_value != static_cast<ash::ArcResizeLockType>(old)); - const bool app_id_changed = key == ash::kAppIDKey; - - // Both the resize lock value and app id are needed to enable resize lock. - if (current_resize_lock_value != ash::ArcResizeLockType::RESIZABLE && - (app_id_changed || resize_lock_changed)) { - window->SetProperty(ash::kResizeShadowTypeKey, - ash::ResizeShadowType::kLock); - EnableResizeLock(window); - } - - if (resize_lock_changed && - current_resize_lock_value == ash::ArcResizeLockType::RESIZABLE) { + if (ShouldEnableResizeLock(new_value)) { + // Both the resize lock value and app id are needed to enable resize lock. + AppIdObserver::RunOnReady( + window, base::BindOnce( + [](base::WeakPtr<ArcResizeLockManager> manager, + aura::Window* window) { + if (!manager) + return; + if (!ShouldEnableResizeLock(window->GetProperty( + ash::kArcResizeLockTypeKey))) { + return; + } + window->SetProperty(ash::kResizeShadowTypeKey, + ash::ResizeShadowType::kLock); + manager->EnableResizeLock(window); + }, + weak_ptr_factory_.GetWeakPtr())); + } else { window->SetProperty(ash::kResizeShadowTypeKey, ash::ResizeShadowType::kUnlock); DisableResizeLock(window); @@ -184,20 +249,38 @@ } void ArcResizeLockManager::OnWindowDestroying(aura::Window* window) { + resize_lock_enabled_windows_.erase(window); if (window_observations_.IsObservingSource(window)) window_observations_.RemoveObservation(window); } void ArcResizeLockManager::EnableResizeLock(aura::Window* window) { + const bool inserted = resize_lock_enabled_windows_.insert(window).second; + if (!inserted) + return; + bool is_first_launch = false; - const std::string* app_id = window->GetProperty(ash::kAppIDKey); + const auto app_id = GetAppId(window); DCHECK(app_id); // The state is |ArcResizeLockState::READY| only when we enable the resize // lock for an app for the first time. if (pref_delegate_->GetResizeLockState(*app_id) == mojom::ArcResizeLockState::READY) { - pref_delegate_->SetResizeLockState(*app_id, mojom::ArcResizeLockState::ON); + const ash::ArcResizeLockType resize_lock_value = + window->GetProperty(ash::kArcResizeLockTypeKey); + switch (resize_lock_value) { + case ash::ArcResizeLockType::RESIZE_LIMITED: + pref_delegate_->SetResizeLockState(*app_id, + mojom::ArcResizeLockState::ON); + break; + case ash::ArcResizeLockType::FULLY_LOCKED: + pref_delegate_->SetResizeLockState( + *app_id, mojom::ArcResizeLockState::FULLY_LOCKED); + break; + case ash::ArcResizeLockType::RESIZABLE: + NOTREACHED(); + } is_first_launch = true; } @@ -220,6 +303,10 @@ } void ArcResizeLockManager::DisableResizeLock(aura::Window* window) { + const bool erased = resize_lock_enabled_windows_.erase(window); + if (!erased) + return; + // Hide shadow effect on window. ash::Shell may not exist in tests. if (ash::Shell::HasInstance()) ash::Shell::Get()->resize_shadow_controller()->HideShadow(window); @@ -228,7 +315,7 @@ void ArcResizeLockManager::UpdateCompatModeButton(aura::Window* window) { DCHECK(ash::IsArcWindow(window)); - const std::string* app_id = window->GetProperty(ash::kAppIDKey); + const auto app_id = GetAppId(window); if (!app_id) return; auto* frame_view = ash::NonClientFrameViewAsh::Get(window);
diff --git a/components/arc/compat_mode/arc_resize_lock_manager.h b/components/arc/compat_mode/arc_resize_lock_manager.h index 516b8028..84a7f38d 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager.h +++ b/components/arc/compat_mode/arc_resize_lock_manager.h
@@ -63,24 +63,26 @@ void ToggleResizeToggleMenu(views::Widget* widget); - protected: - // protected and virtual for testing. - virtual void EnableResizeLock(aura::Window* window); - virtual void DisableResizeLock(aura::Window* window); - private: friend class ArcResizeLockManagerTest; + void EnableResizeLock(aura::Window* window); + void DisableResizeLock(aura::Window* window); + void UpdateCompatModeButton(aura::Window* window); ArcResizeLockPrefDelegate* pref_delegate_{nullptr}; std::unique_ptr<ResizeToggleMenu> resize_toggle_menu_; + base::flat_set<aura::Window*> resize_lock_enabled_windows_; + base::ScopedObservation<aura::Env, aura::EnvObserver> env_observation{this}; base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver> window_observations_{this}; + + base::WeakPtrFactory<ArcResizeLockManager> weak_ptr_factory_{this}; }; } // namespace arc
diff --git a/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc b/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc index ca30ff3..3561df94 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc +++ b/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc
@@ -22,30 +22,6 @@ namespace arc { namespace { -class FakeArcResizeLockManager : public ArcResizeLockManager { - public: - FakeArcResizeLockManager() : ArcResizeLockManager(nullptr, nullptr) {} - - bool IsResizeLockEnabled(aura::Window* window) const { - return base::Contains(resize_lock_enabled_windows_, window); - } - - // ArcResizeLockManager: - void EnableResizeLock(aura::Window* window) override { - ArcResizeLockManager::EnableResizeLock(window); - DCHECK(!base::Contains(resize_lock_enabled_windows_, window)); - resize_lock_enabled_windows_.push_back(window); - } - void DisableResizeLock(aura::Window* window) override { - ArcResizeLockManager::DisableResizeLock(window); - DCHECK(base::Contains(resize_lock_enabled_windows_, window)); - base::Erase(resize_lock_enabled_windows_, window); - } - - private: - std::vector<aura::Window*> resize_lock_enabled_windows_; -}; - class TestArcResizeLockPrefDelegate : public ArcResizeLockPrefDelegate { public: ~TestArcResizeLockPrefDelegate() override = default; @@ -84,7 +60,7 @@ // views::ViewsTestBase: void SetUp() override { views::ViewsTestBase::SetUp(); - fake_arc_resize_lock_manager_.SetPrefDelegate( + arc_resize_lock_manager_.SetPrefDelegate( &test_arc_resize_lock_pref_delegate); } @@ -101,11 +77,8 @@ } bool IsResizeLockEnabled(aura::Window* window) const { - return fake_arc_resize_lock_manager_.IsResizeLockEnabled(window); - } - - bool IsToggleMenuShown() { - return !!fake_arc_resize_lock_manager_.resize_toggle_menu_; + return arc_resize_lock_manager_.resize_lock_enabled_windows_.contains( + window); } TestArcResizeLockPrefDelegate* pref_delegate() { @@ -113,14 +86,14 @@ } private: - FakeArcResizeLockManager fake_arc_resize_lock_manager_; + ArcResizeLockManager arc_resize_lock_manager_{nullptr, nullptr}; TestArcResizeLockPrefDelegate test_arc_resize_lock_pref_delegate; }; TEST_F(ArcResizeLockManagerTest, ConstructDestruct) {} // Tests that resize lock state is properly sync'ed with the window property. -TEST_F(ArcResizeLockManagerTest, TestArcWindowPropertyChange) { +TEST_F(ArcResizeLockManagerTest, TestPropertyChange) { auto* arc_window = CreateFakeWindow(true); EXPECT_FALSE(IsResizeLockEnabled(arc_window)); @@ -163,8 +136,48 @@ EXPECT_FALSE(IsResizeLockEnabled(arc_window)); } +// Test resize lock will not be enabled right after property change but +// will be after the app id is set to the non-null value. +TEST_F(ArcResizeLockManagerTest, TestPropertyChangeWithDelayedAppId) { + auto* arc_window = CreateFakeWindow(true); + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); + + arc_window->SetProperty(ash::kArcResizeLockTypeKey, + ash::ArcResizeLockType::RESIZE_LIMITED); + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); + // Should ignore null. + arc_window->ClearProperty(ash::kAppIDKey); + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); + // Should ignore uninterested property change. + arc_window->SetProperty(kNonInterestedPropKey, true); + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); + // Should not ignore non-null value. + arc_window->SetProperty(ash::kAppIDKey, new std::string("app-id")); + EXPECT_TRUE(IsResizeLockEnabled(arc_window)); +} + +// Tests that resize lock will not be enabled if the resize lock type is changed +// to RESIZABLE while we're waiting for the valid app id. +TEST_F(ArcResizeLockManagerTest, TestPropertyChangeWithDelayedAppIdCancel) { + auto* arc_window = CreateFakeWindow(true); + std::string app_id = "app-id"; + + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); + + arc_window->SetProperty(ash::kArcResizeLockTypeKey, + ash::ArcResizeLockType::RESIZE_LIMITED); + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); + + arc_window->SetProperty(ash::kArcResizeLockTypeKey, + ash::ArcResizeLockType::RESIZABLE); + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); + + arc_window->SetProperty(ash::kAppIDKey, &app_id); + EXPECT_FALSE(IsResizeLockEnabled(arc_window)); +} + // Test that resize lock will NOT be enabled for non ARC windows. -TEST_F(ArcResizeLockManagerTest, TestNonArcWindowPropertyChange) { +TEST_F(ArcResizeLockManagerTest, TestNonArcWindow) { auto* non_arc_window = CreateFakeWindow(false); EXPECT_FALSE(IsResizeLockEnabled(non_arc_window)); non_arc_window->SetProperty(ash::kArcResizeLockTypeKey, @@ -202,7 +215,7 @@ arc_window->SetProperty(ash::kArcResizeLockTypeKey, ash::ArcResizeLockType::FULLY_LOCKED); EXPECT_EQ(pref_delegate()->GetResizeLockState(app_id), - mojom::ArcResizeLockState::ON); + mojom::ArcResizeLockState::FULLY_LOCKED); } } // namespace arc
diff --git a/components/arc/compat_mode/arc_window_property_util.cc b/components/arc/compat_mode/arc_window_property_util.cc new file mode 100644 index 0000000..7713be7 --- /dev/null +++ b/components/arc/compat_mode/arc_window_property_util.cc
@@ -0,0 +1,24 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/arc/compat_mode/arc_window_property_util.h" + +#include <string> + +#include "ash/public/cpp/window_properties.h" +#include "ui/aura/window.h" +#include "ui/views/widget/widget.h" + +namespace arc { + +absl::optional<std::string> GetAppId(const aura::Window* window) { + const std::string* app_id = window->GetProperty(ash::kAppIDKey); + return base::OptionalFromPtr(app_id); +} + +absl::optional<std::string> GetAppId(const views::Widget* widget) { + return GetAppId(widget->GetNativeWindow()); +} + +} // namespace arc
diff --git a/components/arc/compat_mode/arc_window_property_util.h b/components/arc/compat_mode/arc_window_property_util.h new file mode 100644 index 0000000..bfe4115 --- /dev/null +++ b/components/arc/compat_mode/arc_window_property_util.h
@@ -0,0 +1,25 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_ +#define COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_ + +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace views { +class Widget; +} // namespace views + +namespace aura { +class Window; +} // namespace aura + +namespace arc { + +absl::optional<std::string> GetAppId(const aura::Window* window); +absl::optional<std::string> GetAppId(const views::Widget* widget); + +} // namespace arc + +#endif // COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_
diff --git a/components/arc/compat_mode/resize_util.cc b/components/arc/compat_mode/resize_util.cc index 362a760..d0881cd 100644 --- a/components/arc/compat_mode/resize_util.cc +++ b/components/arc/compat_mode/resize_util.cc
@@ -8,14 +8,13 @@ #include "ash/public/cpp/toast_data.h" #include "ash/public/cpp/toast_manager.h" -#include "ash/public/cpp/window_properties.h" #include "base/callback_forward.h" #include "base/callback_helpers.h" #include "base/stl_util.h" #include "components/arc/compat_mode/arc_resize_lock_pref_delegate.h" +#include "components/arc/compat_mode/arc_window_property_util.h" #include "components/arc/compat_mode/resize_confirmation_dialog_view.h" #include "components/strings/grit/components_strings.h" -#include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/widget/widget.h" @@ -40,11 +39,6 @@ widget->CenterWindow(kLandscapeTabletDp); } -absl::optional<std::string> GetAppId(views::Widget* widget) { - const auto* app_id = widget->GetNativeWindow()->GetProperty(ash::kAppIDKey); - return base::OptionalFromPtr(app_id); -} - void TurnOnResizeLock(views::Widget* widget, ArcResizeLockPrefDelegate* pref_delegate) { const auto app_id = GetAppId(widget); @@ -139,12 +133,16 @@ // We don't use the exact size here to predict tablet or phone size because // the window size might be bigger than it due to the ARC app-side minimum // size constraints. - if (app_id && pref_delegate->GetResizeLockState(*app_id) != - mojom::ArcResizeLockState::ON) + if (!app_id) + return absl::nullopt; + const auto resize_lock_state = pref_delegate->GetResizeLockState(*app_id); + if (resize_lock_state != mojom::ArcResizeLockState::ON && + resize_lock_state != mojom::ArcResizeLockState::FULLY_LOCKED) { return ResizeCompatMode::kResizable; - else if (width < height) + } + if (width < height) return ResizeCompatMode::kPhone; - else if (width > height) + if (width > height) return ResizeCompatMode::kTablet; return absl::nullopt; }
diff --git a/components/arc/compat_mode/resize_util_unittest.cc b/components/arc/compat_mode/resize_util_unittest.cc index a919d8a..48f0db2 100644 --- a/components/arc/compat_mode/resize_util_unittest.cc +++ b/components/arc/compat_mode/resize_util_unittest.cc
@@ -169,4 +169,12 @@ EXPECT_FALSE(ShouldShowSplashScreenDialog(pref_delegate())); } +// Test that an unresizable app is not in resizable mode. +TEST_F(ResizeUtilTest, TestPredictCurrentModeForUnresizable) { + widget()->widget_delegate()->SetCanResize(false); + ResizeLockToPhone(widget(), pref_delegate()); + EXPECT_EQ(PredictCurrentMode(widget(), pref_delegate()), + ResizeCompatMode::kPhone); +} + } // namespace arc
diff --git a/components/arc/mojom/compatibility_mode.mojom b/components/arc/mojom/compatibility_mode.mojom index 13fa65a..46a86fdd 100644 --- a/components/arc/mojom/compatibility_mode.mojom +++ b/components/arc/mojom/compatibility_mode.mojom
@@ -19,6 +19,9 @@ ON = 2, // Resize lock is disabled via the Chrome OS settings. OFF = 3, + // Resize lock is enabled, and even resize/resizability toggle is not + // available. + FULLY_LOCKED = 4, }; // Interface for synchronizing the Chrome OS setting value for compatibility
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc index 7f4d6ce3..e1d18acd 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.cc +++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -102,7 +102,8 @@ if (!factory) return; - ContentAutofillDriver* driver = factory->DriverForFrame(render_frame_host); + ContentAutofillDriver* driver = + factory->GetOrCreateDriverForFrame(render_frame_host); if (driver) driver->BindPendingReceiver(std::move(pending_receiver)); } @@ -125,6 +126,15 @@ ContentAutofillDriver* ContentAutofillDriverFactory::DriverForFrame( content::RenderFrameHost* render_frame_host) { AutofillDriver* driver = DriverForKey(render_frame_host); + // This cast is safe because AutofillDriverFactory::AddForKey is protected + // and always called with ContentAutofillDriver instances within + // ContentAutofillDriverFactory. + return static_cast<ContentAutofillDriver*>(driver); +} + +ContentAutofillDriver* ContentAutofillDriverFactory::GetOrCreateDriverForFrame( + content::RenderFrameHost* render_frame_host) { + AutofillDriver* driver = DriverForKey(render_frame_host); // ContentAutofillDriver are created on demand here. if (!driver) { @@ -142,6 +152,12 @@ return static_cast<ContentAutofillDriver*>(driver); } +void ContentAutofillDriverFactory::RenderFrameCreated( + content::RenderFrameHost* render_frame_host) { + // Create the driver at the earliest possible opportunity. + GetOrCreateDriverForFrame(render_frame_host); +} + void ContentAutofillDriverFactory::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { ContentAutofillDriver* driver = @@ -181,7 +197,7 @@ content::RenderFrameHost* render_frame_host = content::RenderFrameHost::FromID(id); if (render_frame_host) { - DriverForFrame(render_frame_host)->ProbablyFormSubmitted(); + GetOrCreateDriverForFrame(render_frame_host)->ProbablyFormSubmitted(); } } } @@ -192,7 +208,7 @@ (navigation_handle->IsInMainFrame() || navigation_handle->HasSubframeNavigationEntryCommitted())) { ContentAutofillDriver* driver = - DriverForFrame(navigation_handle->GetRenderFrameHost()); + GetOrCreateDriverForFrame(navigation_handle->GetRenderFrameHost()); if (!navigation_handle->IsSameDocument() && !navigation_handle->IsServedFromBackForwardCache()) { if (navigation_handle->IsInMainFrame()) { @@ -229,7 +245,7 @@ navigation_handle->GetPreviousRenderFrameHostId()) { return; } - AutofillDriver* driver = DriverForFrame(render_frame_host); + AutofillDriver* driver = GetOrCreateDriverForFrame(render_frame_host); if (!driver) return; static_cast<ContentAutofillDriver*>(driver)
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.h b/components/autofill/content/browser/content_autofill_driver_factory.h index e4a1303..374788c 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.h +++ b/components/autofill/content/browser/content_autofill_driver_factory.h
@@ -75,6 +75,7 @@ content::RenderFrameHost* render_frame_host); // content::WebContentsObserver: + void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; void DidStartNavigation( content::NavigationHandle* navigation_handle) override; @@ -85,6 +86,12 @@ content::NavigationHandle* navigation_handle) override; private: + // The creation of a driver is private to ensure that we don't accidentally + // register drivers while a frame is already deleted. Such a driver would not + // be unregistered properly. + ContentAutofillDriver* GetOrCreateDriverForFrame( + content::RenderFrameHost* render_frame_host); + std::string app_locale_; BrowserAutofillManager::AutofillDownloadManagerState enable_download_manager_; AutofillManager::AutofillManagerFactoryCallback
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc index 0780018..bc00934f 100644 --- a/components/autofill/core/browser/autofill_download_manager.cc +++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -746,12 +746,10 @@ request_data.payload = std::move(payload); DVLOG(1) << "Sending Autofill Upload Request:\n" << upload; - if (log_manager_) { - log_manager_->Log() << LoggingScope::kAutofillServer + SafeLog(log_manager_) << LoggingScope::kAutofillServer << LogMessage::kSendAutofillUpload << Br{} << "Allow upload?: " << allow_upload << Br{} << "Data: " << Br{} << upload; - } if (!allow_upload) return false;
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc index 419c126..c4c7fa3 100644 --- a/components/autofill/core/browser/autofill_experiments.cc +++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -38,18 +38,14 @@ namespace autofill { namespace { void LogCardUploadDisabled(LogManager* log_manager, std::string context) { - if (log_manager) { - log_manager->Log() << LoggingScope::kCreditCardUploadStatus + SafeLog(log_manager) << LoggingScope::kCreditCardUploadStatus << LogMessage::kCreditCardUploadDisabled << context << CTag{}; - } } void LogCardUploadEnabled(LogManager* log_manager) { - if (log_manager) { - log_manager->Log() << LoggingScope::kCreditCardUploadStatus + SafeLog(log_manager) << LoggingScope::kCreditCardUploadStatus << LogMessage::kCreditCardUploadEnabled << CTag{}; - } } } // namespace
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index ccdc323..94888beb5 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -406,10 +406,8 @@ FormStructure* AutofillManager::ParseForm(const FormData& form, const FormStructure* cached_form) { if (form_structures_.size() >= kAutofillManagerMaxFormCacheSize) { - if (log_manager_) { - log_manager_->Log() << LoggingScope::kAbortParsing + SafeLog(log_manager_) << LoggingScope::kAbortParsing << LogMessage::kAbortParsingTooManyForms << form; - } return nullptr; }
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index f224c6d..a5e36bb3 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -379,11 +379,9 @@ // Logs the reason for suppressing autofill suggestions to // chrome://autofill-internals. void LogSuppressReason(LogManager* log_manager, const std::string& reason) { - if (!log_manager) - return; - log_manager->Log() << LoggingScope::kFilling - << LogMessage::kSuggestionSuppressed - << " Reason: " << reason; + SafeLog(log_manager) << LoggingScope::kFilling + << LogMessage::kSuggestionSuppressed + << " Reason: " << reason; } } // namespace @@ -658,13 +656,11 @@ SubmissionSource source) { base::UmaHistogramEnumeration("Autofill.FormSubmission.PerProfileType", client()->GetProfileType()); - if (log_manager()) { - log_manager()->Log() << LoggingScope::kSubmission + SafeLog(log_manager()) << LoggingScope::kSubmission << LogMessage::kFormSubmissionDetected << Br{} << "known_success: " << known_success << Br{} << "source: " << SubmissionSourceToString(source) << Br{} << form; - } // Always upload page language metrics. LogLanguageMetrics(client()->GetLanguageState()); @@ -1681,6 +1677,7 @@ DCHECK(autofill_field); LogBuffer buffer; + buffer.set_active(log_manager() && log_manager()->IsLoggingActive()); buffer << "is credit card section: " << is_credit_card << Br{}; buffer << "is refill: " << is_refill << Br{}; buffer << *form_structure << Br{}; @@ -1868,11 +1865,9 @@ if (action == AutofillDriver::FORM_DATA_ACTION_FILL && !is_refill) personal_data_->RecordUseOf(profile_or_credit_card); - if (log_manager()) { - log_manager()->Log() << LoggingScope::kFilling + SafeLog(log_manager()) << LoggingScope::kFilling << LogMessage::kSendFillingData << Br{} << std::move(buffer); - } driver()->SendFormDataToRenderer(query_id, action, result, field.origin, field_type_map); }
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index ceaab046..e4ebd66 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -20,7 +20,6 @@ #include "base/memory/ref_counted.h" #include "base/metrics/field_trial.h" #include "base/metrics/metrics_hashes.h" -#include "base/stl_util.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h"
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index 665d60e..f14d00ff4 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -55,7 +55,7 @@ bool IsValidFieldTypeAndValue(const ServerFieldTypeSet types_seen, ServerFieldType field_type, const std::u16string& value, - LogBuffer* import_log_buffer) { + LogBuffer& import_log_buffer) { // Abandon the import if two fields of the same type are encountered. // This indicates ambiguous data or miscategorization of types. // Make an exception for: @@ -74,23 +74,19 @@ ? field_type_group != FieldTypeGroup::kPhoneBilling && field_type_group != FieldTypeGroup::kPhoneHome : field_type != PHONE_HOME_NUMBER)) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Multiple fields of type " - << AutofillType::ServerFieldTypeToString(field_type) - << "." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Multiple fields of type " + << AutofillType::ServerFieldTypeToString(field_type) + << "." << CTag{}; return false; } // Abandon the import if an email address value shows up in a field that is // not an email address. if (field_type != EMAIL_ADDRESS && IsValidEmailAddress(value)) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Email address found in field of different type: " - << AutofillType::ServerFieldTypeToString(field_type) - << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Email address found in field of different type: " + << AutofillType::ServerFieldTypeToString(field_type) + << CTag{}; return false; } @@ -105,21 +101,21 @@ bool IsMinimumAddress(const AutofillProfile& profile, const std::string& variation_country_code, const std::string& app_locale, - LogBuffer* import_log_buffer) { + LogBuffer& import_log_buffer) { // Try to acquire the country code form the filled form. std::string country_code = base::UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); - if (import_log_buffer && !country_code.empty()) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource - << "Country entry in form." << CTag{}; + if (!country_code.empty()) { + import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource + << "Country entry in form." << CTag{}; } // As a fallback, use the finch state to get a country code. if (country_code.empty() && !variation_country_code.empty()) { country_code = variation_country_code; - if (import_log_buffer && !country_code.empty()) { - *import_log_buffer + if (!country_code.empty()) { + import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource << "Variations service." << CTag{}; } @@ -128,8 +124,8 @@ // As the last resort, derive the country code from the app_locale. if (country_code.empty()) { country_code = AutofillCountry::CountryCodeForLocale(app_locale); - if (import_log_buffer && !country_code.empty()) { - *import_log_buffer + if (!country_code.empty()) { + import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource << "App locale." << CTag{}; } @@ -138,18 +134,15 @@ AutofillCountry country(country_code, app_locale); // Include the details of the country to the log. - if (import_log_buffer) - *import_log_buffer << country; + import_log_buffer << country; // Check the |ADDRESS_HOME_LINE1| requirement. bool is_line1_missing = false; if (country.requires_line1() && profile.GetRawInfo(ADDRESS_HOME_LINE1).empty() && profile.GetRawInfo(ADDRESS_HOME_STREET_NAME).empty()) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_LINE1." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_LINE1." << CTag{}; is_line1_missing = true; } @@ -157,10 +150,8 @@ bool is_city_missing = false; if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty()) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_CITY." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_CITY." << CTag{}; is_city_missing = true; } @@ -168,20 +159,16 @@ bool is_state_missing = false; if (country.requires_state() && profile.GetRawInfo(ADDRESS_HOME_STATE).empty()) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_STATE." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_STATE." << CTag{}; is_state_missing = true; } // Check the |ADDRESS_HOME_ZIP| requirement. bool is_zip_missing = false; if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty()) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_ZIP." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_ZIP." << CTag{}; is_zip_missing = true; } @@ -189,12 +176,9 @@ if (country.requires_zip_or_state() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty() && profile.GetRawInfo(ADDRESS_HOME_STATE).empty()) { - if (import_log_buffer) { - *import_log_buffer - << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_ZIP or ADDRESS_HOME_STATE." - << CTag{}; - } + import_log_buffer + << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_ZIP or ADDRESS_HOME_STATE." << CTag{}; is_zip_or_state_requirement_violated = true; } @@ -356,7 +340,7 @@ const AutofillProfile& profile, const std::string& variation_country_code, const std::string& app_locale, - LogBuffer* import_log_buffer) { + LogBuffer& import_log_buffer) { // Check if the imported address qualifies as a minimum address. bool is_not_minimum_address = false; if (!IsMinimumAddress(profile, variation_country_code, app_locale, @@ -368,32 +352,28 @@ bool is_email_invalid = false; std::u16string email = profile.GetRawInfo(EMAIL_ADDRESS); if (!email.empty() && !IsValidEmailAddress(email)) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid email address." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid email address." << CTag{}; is_email_invalid = true; } // Reject profiles with an invalid |HOME_ADDRESS_STATE| entry. bool is_state_invalid = false; if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE)) { - if (import_log_buffer) - *import_log_buffer - << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid state as of AutofillProfile::IsPresentButInvalid()." - << CTag{}; + import_log_buffer + << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid state as of AutofillProfile::IsPresentButInvalid()." + << CTag{}; is_state_invalid = true; } // Reject profiles with an invalid |HOME_ADDRESS_ZIP| entry. bool is_zip_invalid = false; if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP)) { - if (import_log_buffer) - *import_log_buffer - << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid ZIP as of AutofillProfile::IsPresentButInvalid()." - << CTag{}; + import_log_buffer + << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid ZIP as of AutofillProfile::IsPresentButInvalid()." + << CTag{}; is_zip_invalid = true; } @@ -463,6 +443,8 @@ bool FormDataImporter::ImportAddressProfiles(const FormStructure& form) { // Create a buffer to collect logging output for the autofill-internals. LogBuffer import_log_buffer; + LogManager* log_manager = client_->GetLogManager(); + import_log_buffer.set_active(log_manager && log_manager->IsLoggingActive()); import_log_buffer << LoggingScope::kAddressProfileFormImport; // Print the full form into the logging scope. import_log_buffer << LogMessage::kImportAddressProfileFromForm << form @@ -493,7 +475,7 @@ import_log_buffer << LogMessage::kImportAddressProfileFromFormSection << section << CTag{}; // Try to import an address profile from the form fields of this section. - if (ImportAddressProfileForSection(form, section, &import_log_buffer)) + if (ImportAddressProfileForSection(form, section, import_log_buffer)) num_complete_profiles++; // And close the div of the section import log. import_log_buffer << CTag{"div"}; @@ -505,7 +487,7 @@ AutofillMetrics::AddressProfileImportStatusMetric::REGULAR_IMPORT); } else if (sections.size() > 1) { // Try to import by combining all sections. - if (ImportAddressProfileForSection(form, "", &import_log_buffer)) { + if (ImportAddressProfileForSection(form, "", import_log_buffer)) { num_complete_profiles++; AutofillMetrics::LogAddressFormImportStatustMetric( AutofillMetrics::AddressProfileImportStatusMetric:: @@ -521,9 +503,7 @@ << num_complete_profiles << CTag{}; // Write log buffer to autofill-internals. - LogManager* log_manager = client_->GetLogManager(); - if (log_manager) - log_manager->Log() << std::move(import_log_buffer); + SafeLog(log_manager) << std::move(import_log_buffer); return num_complete_profiles > 0; } @@ -531,7 +511,7 @@ bool FormDataImporter::ImportAddressProfileForSection( const FormStructure& form, const std::string& section, - LogBuffer* import_log_buffer) { + LogBuffer& import_log_buffer) { // The candidate for profile import. There are many ways for the candidate to // be rejected (see everywhere this function returns false). AutofillProfile candidate_profile; @@ -610,11 +590,9 @@ if (server_field_type == EMAIL_ADDRESS && types_seen.count(server_field_type) && candidate_profile.GetRawInfo(EMAIL_ADDRESS) != value) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Multiple different email addresses present." - << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Multiple different email addresses present." + << CTag{}; has_multiple_distinct_email_addresses = true; } @@ -674,10 +652,8 @@ } // Check if the country code was still not determined correctly. if (candidate_profile.GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing country." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing country." << CTag{}; has_invalid_country = true; } } @@ -692,10 +668,8 @@ !candidate_profile.SetInfoWithVerificationStatus( AutofillType(PHONE_HOME_WHOLE_NUMBER), constructed_number, app_locale_, VerificationStatus::kObserved)) { - if (import_log_buffer) { - *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid phone number." << CTag{}; - } + import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid phone number." << CTag{}; has_invalid_phone_number = true; } }
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index ddba86c..f1c997c 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -67,7 +67,7 @@ static bool IsValidLearnableProfile(const AutofillProfile& profile, const std::string& finch_country_code, const std::string& app_locale, - LogBuffer* import_log_buffer); + LogBuffer& import_log_buffer); // Cache the last four of the fetched virtual card so we don't offer saving // them. @@ -126,7 +126,7 @@ // performed on the union of all sections. bool ImportAddressProfileForSection(const FormStructure& form, const std::string& section, - LogBuffer* import_log_buffer); + LogBuffer& import_log_buffer); // Go through the |form| fields and attempt to extract a new credit card in // |imported_credit_card|, or update an existing card.
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 469e68d..b8cbcac 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -539,13 +539,17 @@ } LogBufferSubmitter LogRationalization(LogManager* log_manager) { - if (!log_manager) - return LogManager::DevNull(); - LogBufferSubmitter submitter = log_manager->Log(); + LogBufferSubmitter submitter = SafeLog(log_manager); submitter << LoggingScope::kRationalization << LogMessage::kRationalization; return submitter; } +LogBufferSubmitter LogAbortParsing(LogManager* log_manager) { + LogBufferSubmitter submitter = SafeLog(log_manager); + submitter << LoggingScope::kAbortParsing; + return submitter; +} + } // namespace class FormStructure::SectionedFieldsIndexes { @@ -1014,10 +1018,8 @@ bool FormStructure::ShouldBeParsed(LogManager* log_manager) const { // Exclude URLs not on the web via HTTP(S). if (!HasAllowedScheme(source_url_)) { - if (log_manager) { - log_manager->Log() << LoggingScope::kAbortParsing - << LogMessage::kAbortParsingNotAllowedScheme << *this; - } + LogAbortParsing(log_manager) + << LogMessage::kAbortParsingNotAllowedScheme << *this; return false; } @@ -1028,22 +1030,16 @@ (!all_fields_are_passwords() || active_field_count() < kRequiredFieldsForFormsWithOnlyPasswordFields) && !has_author_specified_types_) { - if (log_manager) { - log_manager->Log() << LoggingScope::kAbortParsing - << LogMessage::kAbortParsingNotEnoughFields - << active_field_count() << *this; - } + LogAbortParsing(log_manager) << LogMessage::kAbortParsingNotEnoughFields + << active_field_count() << *this; return false; } // Rule out search forms. if (MatchesPattern(base::UTF8ToUTF16(target_url_.path_piece()), kUrlSearchActionRe)) { - if (log_manager) { - log_manager->Log() << LoggingScope::kAbortParsing - << LogMessage::kAbortParsingUrlMatchesSearchRegex - << *this; - } + LogAbortParsing(log_manager) + << LogMessage::kAbortParsingUrlMatchesSearchRegex << *this; return false; } @@ -1053,8 +1049,8 @@ } if (!has_text_field && log_manager) { - log_manager->Log() << LoggingScope::kAbortParsing - << LogMessage::kAbortParsingFormHasNoTextfield << *this; + LogAbortParsing(log_manager) + << LogMessage::kAbortParsingFormHasNoTextfield << *this; } return has_text_field; @@ -2618,6 +2614,8 @@ } LogBuffer& operator<<(LogBuffer& buffer, const FormStructure& form) { + if (!buffer.active()) + return buffer; buffer << Tag{"div"} << Attrib{"class", "form"}; buffer << Tag{"table"}; buffer << Tr{} << "Form signature:"
diff --git a/components/autofill/core/browser/geo/autofill_country.cc b/components/autofill/core/browser/geo/autofill_country.cc index 2dc8e979..e034ba5 100644 --- a/components/autofill/core/browser/geo/autofill_country.cc +++ b/components/autofill/core/browser/geo/autofill_country.cc
@@ -82,6 +82,8 @@ // Prints a formatted log of a |AutofillCountry| to a |LogBuffer|. LogBuffer& operator<<(LogBuffer& buffer, const AutofillCountry& country) { + if (!buffer.active()) + return buffer; buffer << LogMessage::kImportAddressProfileFromFormAddressRequirements; buffer << Tag{"div"} << Attrib{"class", "country_data"}; buffer << Tag{"table"};
diff --git a/components/autofill/core/browser/logging/log_manager.cc b/components/autofill/core/browser/logging/log_manager.cc index 41fe08d..6664ed9 100644 --- a/components/autofill/core/browser/logging/log_manager.cc +++ b/components/autofill/core/browser/logging/log_manager.cc
@@ -111,4 +111,8 @@ return LogBufferSubmitter(nullptr, false); } +LogBufferSubmitter SafeLog(LogManager* log_manager) { + return log_manager ? log_manager->Log() : LogManager::DevNull(); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/logging/log_manager.h b/components/autofill/core/browser/logging/log_manager.h index 1794f6a..7bd12bb 100644 --- a/components/autofill/core/browser/logging/log_manager.h +++ b/components/autofill/core/browser/logging/log_manager.h
@@ -56,12 +56,30 @@ base::RepeatingClosure notification_callback); // This is the preferred way to submitting log entries. + // + // In case you often find yourself writing the following code: + // if (log_manager) { + // log_manager->Log() << ...; + // } + // You can use + // SafeLog(log_manager) << ...; + // + // If you want to prefix all log messages, you can write the following: + // LogBufferSubmitter LogWithScope(LogManager* log_manager) { + // LogBufferSubmitter submitter = SafeLog(log_manager); + // submitter << LoggingScope::kMyLoggingScope; + // return submitter; + // } virtual LogBufferSubmitter Log() = 0; // Returns a LogBufferSubmitter that ignores all input. static LogBufferSubmitter DevNull(); }; +// Returns a LogBufferSubmitter for |log_buffer| if it is not null, otherwise +// LogManager::DevNull(); +LogBufferSubmitter SafeLog(LogManager* log_manager); + } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LOGGING_LOG_MANAGER_H_
diff --git a/components/autofill/core/browser/metrics/form_event_logger_base.cc b/components/autofill/core/browser/metrics/form_event_logger_base.cc index e7672cc..a099968 100644 --- a/components/autofill/core/browser/metrics/form_event_logger_base.cc +++ b/components/autofill/core/browser/metrics/form_event_logger_base.cc
@@ -258,6 +258,8 @@ void FormEventLoggerBase::RecordFunnelAndKeyMetrics() { LogBuffer funnel_rows; LogBuffer key_metrics_rows; + for (LogBuffer* buffer : {&funnel_rows, &key_metrics_rows}) + buffer->set_active(log_manager_ && log_manager_->IsLoggingActive()); funnel_rows << Tr{} << "Form Type: " << form_type_name_; key_metrics_rows << Tr{} << "Form Type: " << form_type_name_; @@ -351,14 +353,12 @@ << has_logged_will_submit_; } - if (log_manager_) { - log_manager_->Log() << LoggingScope::kMetrics << LogMessage::kFunnelMetrics + SafeLog(log_manager_) << LoggingScope::kMetrics << LogMessage::kFunnelMetrics << Tag{"table"} << std::move(funnel_rows) << CTag{"table"}; - log_manager_->Log() << LoggingScope::kMetrics << LogMessage::kKeyMetrics + SafeLog(log_manager_) << LoggingScope::kMetrics << LogMessage::kKeyMetrics << Tag{"table"} << std::move(key_metrics_rows) << CTag{"table"}; - } } void FormEventLoggerBase::RecordAblationMetrics() {
diff --git a/components/autofill/core/common/form_data.cc b/components/autofill/core/common/form_data.cc index a80491b..8597717 100644 --- a/components/autofill/core/common/form_data.cc +++ b/components/autofill/core/common/form_data.cc
@@ -268,6 +268,8 @@ } LogBuffer& operator<<(LogBuffer& buffer, const FormData& form) { + if (!buffer.active()) + return buffer; buffer << Tag{"div"} << Attrib{"class", "form"}; buffer << Tag{"table"}; buffer << Tr{} << "Form name:" << form.name;
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc index bdf2d18..38c8a75d 100644 --- a/components/autofill/core/common/form_field_data.cc +++ b/components/autofill/core/common/form_field_data.cc
@@ -484,6 +484,8 @@ } LogBuffer& operator<<(LogBuffer& buffer, const FormFieldData& field) { + if (!buffer.active()) + return buffer; buffer << Tag{"table"}; buffer << Tr{} << "Name:" << field.name; buffer << Tr{} << "Unique id:" << field.global_id();
diff --git a/components/autofill/core/common/logging/log_buffer.h b/components/autofill/core/common/logging/log_buffer.h index baf86250..5be9c65 100644 --- a/components/autofill/core/common/logging/log_buffer.h +++ b/components/autofill/core/common/logging/log_buffer.h
@@ -46,6 +46,14 @@ // LogBuffer buffer; // for (...) { buffer << something; } // LogBuffer() << std::move(buffer); +// +// You can override the streaming operator for your own class as follows: +// LogBuffer& operator<<(LogBuffer& buffer, const YourClass& obj) { +// if (!buffer.active()) +// return buf; +// buffer << obj.something; +// return buffer; +// } namespace autofill {
diff --git a/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java b/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java index c437255..b26dd63 100644 --- a/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java +++ b/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java
@@ -95,6 +95,7 @@ "ogm", // video/ogg "ogv", // video/ogg "opus", // audio/ogg + "pdf", // application/pdf "pjp", // image/jpeg "pjpeg", // image/jpeg "png", // image/png @@ -116,6 +117,7 @@ private static final Set<String> PERMITTED_MIME_TYPES = Collections.unmodifiableSet(CollectionUtil.newHashSet( "audio/flac", + "application/pdf", "audio/mp3", "audio/mpeg", "audio/ogg",
diff --git a/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java b/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java index ed2d7a68..26cc0fd 100644 --- a/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java +++ b/components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java
@@ -74,6 +74,7 @@ @Test @SmallTest public void testSupportedMime() { + Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("application/pdf")); Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("audio/mp3")); Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("audio/mpeg")); Assert.assertFalse(ShareServiceImpl.isDangerousMimeType("audio/wav"));
diff --git a/components/content_creation/notes/core/templates/template_types.h b/components/content_creation/notes/core/templates/template_types.h index abcd241..2b054c3 100644 --- a/components/content_creation/notes/core/templates/template_types.h +++ b/components/content_creation/notes/core/templates/template_types.h
@@ -11,7 +11,8 @@ using ARGBColor = uint32_t; -// Represents all currently known templates. +// Represents all currently known templates. Keep this enum in sync with its +// Java counterpart of the same name (in NoteCreationMetrics.java). enum class NoteTemplateIds { kUnknown = 0, kClassic = 1,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc index 1e3f187..40f58e4 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -174,10 +174,10 @@ // Create daily pref list of |kNumDaysInHistory| zero values. void CreatePrefList(const char* pref) { - base::ListValue* update = compression_stats_->GetList(pref); - update->Clear(); + base::Value* update = compression_stats_->GetList(pref); + update->ClearList(); for (size_t i = 0; i < kNumDaysInHistory; ++i) { - update->Insert(0, std::make_unique<base::Value>(base::NumberToString(0))); + update->Append(base::Value(base::NumberToString(0))); } } @@ -417,19 +417,17 @@ } TEST_F(DataReductionProxyCompressionStatsTest, StatsRestoredOnOnRestart) { - base::ListValue list_value; - list_value.Insert(0, - std::make_unique<base::Value>(base::NumberToString(1234))); + base::Value list_value(base::Value::Type::LIST); + list_value.Append(base::Value(base::NumberToString(1234))); pref_service()->Set(prefs::kDailyHttpOriginalContentLength, list_value); ResetCompressionStatsWithDelay( base::TimeDelta::FromMinutes(kWriteDelayMinutes)); - const base::ListValue* value = pref_service()->GetList( - prefs::kDailyHttpOriginalContentLength); - std::string string_value; - value->GetString(0, &string_value); - EXPECT_EQ("1234", string_value); + const base::Value* value = + pref_service()->GetList(prefs::kDailyHttpOriginalContentLength); + const std::string* string_value = value->GetList()[0].GetIfString(); + EXPECT_EQ("1234", *string_value); } TEST_F(DataReductionProxyCompressionStatsTest, TotalLengths) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc index c6aec35..4180ef9 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -57,10 +57,10 @@ ListPrefUpdate received_update(test_context_->pref_service(), prefs::kDailyHttpReceivedContentLength); for (int64_t i = 0; i < kNumDaysInHistory; i++) { - original_update->Insert( - 0, std::make_unique<base::Value>(base::NumberToString(2 * i))); - received_update->Insert( - 0, std::make_unique<base::Value>(base::NumberToString(i))); + original_update->Insert(original_update->GetList().begin(), + base::Value(base::NumberToString(2 * i))); + received_update->Insert(received_update->GetList().begin(), + base::Value(base::NumberToString(i))); } last_update_time_ = base::Time::Now().LocalMidnight(); pref_service->SetInt64(prefs::kDailyHttpContentLengthLastUpdateDate,
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc index 697dadd..dd1dfe27 100644 --- a/components/download/internal/common/download_item_impl.cc +++ b/components/download/internal/common/download_item_impl.cc
@@ -988,7 +988,7 @@ } DownloadItemRenameHandler* DownloadItemImpl::GetRenameHandler() { - if (reroute_info_.IsInitialized() && !rename_handler_) { + if (!rename_handler_) { rename_handler_ = delegate_->GetRenameHandlerForDownload(this); } return rename_handler_.get();
diff --git a/components/feed/BUILD.gn b/components/feed/BUILD.gn index e52d96c..9a08ab0 100644 --- a/components/feed/BUILD.gn +++ b/components/feed/BUILD.gn
@@ -27,8 +27,5 @@ source_set("unit_tests") { testonly = true - deps = [ - "core/v2:core_unit_tests", - "core/v2/public/ios:feed_ios_unit_tests", - ] + deps = [ "core/v2:core_unit_tests" ] }
diff --git a/components/feed/core/v2/api_test/feed_api_notice_card_unittest.cc b/components/feed/core/v2/api_test/feed_api_notice_card_unittest.cc index 2991770..c9a4a39c 100644 --- a/components/feed/core/v2/api_test/feed_api_notice_card_unittest.cc +++ b/components/feed/core/v2/api_test/feed_api_notice_card_unittest.cc
@@ -38,9 +38,6 @@ }; TEST_F(FeedApiNoticeCardTest, LoadStreamSendsNoticeCardAcknowledgement) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - feed::kInterestFeedNoticeCardAutoDismiss); response_translator_.InjectResponse(model_generator_.MakeFirstPage()); TestForYouSurface surface(stream_.get());
diff --git a/components/feed/core/v2/stream/notice_card_tracker.cc b/components/feed/core/v2/stream/notice_card_tracker.cc index d090ea7..2bbfc58 100644 --- a/components/feed/core/v2/stream/notice_card_tracker.cc +++ b/components/feed/core/v2/stream/notice_card_tracker.cc
@@ -15,6 +15,10 @@ namespace feed { namespace { +// The number of views of the notice card to consider it acknowledged by the +// user. +const int kViewsCountThreshold = 3; + bool IsPrivacyNoticeCard(const feedwire::ContentId& id) { // TODO(b/192015346): This is a less than ideal solution. We're relying on // the server to continue serving the notice card with this domain (and not @@ -30,25 +34,7 @@ : profile_prefs_(profile_prefs) { DCHECK(profile_prefs_); views_count_ = prefs::GetNoticeCardViewsCount(*profile_prefs_); - clicks_count_ = prefs::GetNoticeCardClicksCount(*profile_prefs_); - - views_count_threshold_ = base::GetFieldTrialParamByFeatureAsInt( - feed::kInterestFeedNoticeCardAutoDismiss, - kNoticeCardViewsCountThresholdParamName, 3); - DLOG_IF(ERROR, views_count_threshold_ < 0) - << "views_count_threshold_<0, views_count_threshold_=" - << views_count_threshold_; - - clicks_count_threshold_ = base::GetFieldTrialParamByFeatureAsInt( - feed::kInterestFeedNoticeCardAutoDismiss, - kNoticeCardClicksCountThresholdParamName, 1); - DLOG_IF(ERROR, clicks_count_threshold_ < 0) - << "clicks_count_threshold_<0, clicks_count_threshold_=" - << clicks_count_threshold_; - - DLOG_IF(ERROR, views_count_threshold_ <= 0 && clicks_count_threshold_ <= 0) - << "all notice card auto-dismiss thresholds are set to 0 when there " - "should be at least one threshold above 0"; + has_clicked_ = prefs::GetNoticeCardClicksCount(*profile_prefs_) > 0; } void NoticeCardTracker::OnCardViewed(bool is_signed_in, @@ -69,9 +55,6 @@ *profile_prefs_, true); } - if (!base::FeatureList::IsEnabled(feed::kInterestFeedNoticeCardAutoDismiss)) - return; - auto now = base::TimeTicks::Now(); if (now - last_view_time_ < base::TimeDelta::FromMinutes(5)) return; @@ -84,23 +67,16 @@ void NoticeCardTracker::OnOpenAction(const feedwire::ContentId& content_id) { if (!IsPrivacyNoticeCard(content_id) || - !base::FeatureList::IsEnabled(feed::kInterestFeedNoticeCardAutoDismiss) || - !prefs::GetLastFetchHadNoticeCard(*profile_prefs_)) { + !prefs::GetLastFetchHadNoticeCard(*profile_prefs_) || has_clicked_) { return; } prefs::IncrementNoticeCardClicksCount(*profile_prefs_); - clicks_count_++; + has_clicked_ = true; } bool NoticeCardTracker::HasAcknowledgedNoticeCard() const { - if (!base::FeatureList::IsEnabled(feed::kInterestFeedNoticeCardAutoDismiss)) - return false; - - return (views_count_threshold_ > 0 && - views_count_ >= views_count_threshold_) || - (clicks_count_threshold_ > 0 && - clicks_count_ >= clicks_count_threshold_); + return has_clicked_ || (views_count_ >= kViewsCountThreshold); } } // namespace feed
diff --git a/components/feed/core/v2/stream/notice_card_tracker.h b/components/feed/core/v2/stream/notice_card_tracker.h index f26c309..fc2b758 100644 --- a/components/feed/core/v2/stream/notice_card_tracker.h +++ b/components/feed/core/v2/stream/notice_card_tracker.h
@@ -14,11 +14,6 @@ } namespace feed { -constexpr char kNoticeCardViewsCountThresholdParamName[] = - "notice-card-views-count-threshold"; -constexpr char kNoticeCardClicksCountThresholdParamName[] = - "notice-card-clicks-count-threshold"; - // Tracker for the notice card related actions that also provide signals based // on those. class NoticeCardTracker { @@ -50,15 +45,7 @@ int views_count_; // The number of clicks/taps of the notice card. - int clicks_count_; - - // The number of views of the notice card to consider it acknowledged by the - // user. - int views_count_threshold_; - - // The number of clicks/taps of the notice card to consider it acknowledged by - // the user. - int clicks_count_threshold_; + bool has_clicked_; // Whether there was previously a notice card view reported this session. base::TimeTicks last_view_time_;
diff --git a/components/feed/core/v2/stream/notice_card_tracker_unittest.cc b/components/feed/core/v2/stream/notice_card_tracker_unittest.cc index d1afa43f..98b77edc 100644 --- a/components/feed/core/v2/stream/notice_card_tracker_unittest.cc +++ b/components/feed/core/v2/stream/notice_card_tracker_unittest.cc
@@ -46,9 +46,6 @@ TEST_F(NoticeCardTrackerTest, TrackingNoticeCardActionsDoesntUpdateCountsForNonNoticeCard) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - feed::kInterestFeedNoticeCardAutoDismiss); NoticeCardTracker tracker(&profile_prefs_); // Generate enough views to reach the acknowlegement threshold, but the views @@ -63,9 +60,6 @@ } TEST_F(NoticeCardTrackerTest, AcknowledgedNoticeCardWhenEnoughViews) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - feed::kInterestFeedNoticeCardAutoDismiss); NoticeCardTracker tracker(&profile_prefs_); tracker.OnCardViewed(/*is_signed_in=*/true, NoticeCardContentId()); @@ -78,9 +72,6 @@ } TEST_F(NoticeCardTrackerTest, ViewsAreIgnoredIfNotEnoughTimeElapsed) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - feed::kInterestFeedNoticeCardAutoDismiss); NoticeCardTracker tracker(&profile_prefs_); tracker.OnCardViewed(/*is_signed_in=*/true, NoticeCardContentId()); @@ -94,9 +85,6 @@ TEST_F(NoticeCardTrackerTest, DontAcknowledgedNoticeCardWhenNotEnoughViewsNorClicks) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - feed::kInterestFeedNoticeCardAutoDismiss); NoticeCardTracker tracker(&profile_prefs_); // Generate views but not enough to reach the threshold. @@ -107,41 +95,5 @@ EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard()); } -TEST_F(NoticeCardTrackerTest, DontAcknowledgedNoticeCardWhenFeatureDisabled) { - // Generate enough views and clicks on the notice card to reach the threshold, - // but the feature is disabled. - prefs::IncrementNoticeCardClicksCount(profile_prefs_); - prefs::IncrementNoticeCardViewsCount(profile_prefs_); - prefs::IncrementNoticeCardViewsCount(profile_prefs_); - prefs::IncrementNoticeCardViewsCount(profile_prefs_); - - NoticeCardTracker tracker(&profile_prefs_); - EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard()); -} - -TEST_F(NoticeCardTrackerTest, - DontAcknowledgedNoticeCardFromViewsCountWhenThresholdIsZero) { - base::FieldTrialParams params; - params[kNoticeCardViewsCountThresholdParamName] = "0"; - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeatureWithParameters( - feed::kInterestFeedNoticeCardAutoDismiss, params); - - NoticeCardTracker tracker(&profile_prefs_); - EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard()); -} - -TEST_F(NoticeCardTrackerTest, - DontAcknowledgedNoticeCardFromClicksCountWhenThresholdIsZero) { - base::FieldTrialParams params; - params[kNoticeCardClicksCountThresholdParamName] = "0"; - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeatureWithParameters( - feed::kInterestFeedNoticeCardAutoDismiss, params); - - NoticeCardTracker tracker(&profile_prefs_); - EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard()); -} - } // namespace } // namespace feed
diff --git a/components/feed/feed_feature_list.cc b/components/feed/feed_feature_list.cc index bd8afc4..e27d248 100644 --- a/components/feed/feed_feature_list.cc +++ b/components/feed/feed_feature_list.cc
@@ -7,6 +7,7 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "build/build_config.h" namespace feed { @@ -46,8 +47,10 @@ "InterestFeedV2ClickAndViewActionsConditionalUpload", base::FEATURE_DISABLED_BY_DEFAULT}; +#if defined(OS_IOS) const base::Feature kInterestFeedNoticeCardAutoDismiss{ "InterestFeedNoticeCardAutoDismiss", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif const base::Feature kInterestFeedSpinnerAlwaysAnimate{ "InterestFeedSpinnerAlwaysAnimate", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/feed/feed_feature_list.h b/components/feed/feed_feature_list.h index d431bb5..1a2cc0f 100644 --- a/components/feed/feed_feature_list.h +++ b/components/feed/feed_feature_list.h
@@ -9,6 +9,7 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "build/build_config.h" // TODO(crbug.com/1165828): Clean up feedv1 features. @@ -35,7 +36,9 @@ // Feature that allows the client to automatically dismiss the notice card based // on the clicks and views on the notice card. +#if defined(OS_IOS) extern const base::Feature kInterestFeedNoticeCardAutoDismiss; +#endif // Used for A:B testing of a bug fix (crbug.com/1151391). extern const base::Feature kInterestFeedSpinnerAlwaysAnimate;
diff --git a/components/full_restore/arc_read_handler.cc b/components/full_restore/arc_read_handler.cc index 9ae4fc113..dbc5153b 100644 --- a/components/full_restore/arc_read_handler.cc +++ b/components/full_restore/arc_read_handler.cc
@@ -76,11 +76,18 @@ return window->GetProperty(::full_restore::kWindowIdKey) == task_id; }); if (window_it != arc_window_candidates_.end()) { - std::unique_ptr<WindowInfo> window_info = GetWindowInfo(restore_window_id); - WindowInfo* window_info_ptr = window_info->Clone(); - (*window_it)->SetProperty(full_restore::kWindowInfoKey, window_info_ptr); (*window_it) ->SetProperty(full_restore::kRestoreWindowIdKey, restore_window_id); + + // When the window was created, there was not any window info due to there + // being no task. Apply properties to the window now that there is window + // info. + std::unique_ptr<WindowInfo> window_info = GetWindowInfo(restore_window_id); + if (window_info) { + FullRestoreReadHandler::GetInstance()->ApplyProperties(window_info.get(), + *window_it); + } + FullRestoreInfo::GetInstance()->OnARCTaskReadyForUnparentedWindow( *window_it); arc_window_candidates_.erase(*window_it);
diff --git a/components/full_restore/full_restore_read_handler.cc b/components/full_restore/full_restore_read_handler.cc index 6f6d281..bb814568 100644 --- a/components/full_restore/full_restore_read_handler.cc +++ b/components/full_restore/full_restore_read_handler.cc
@@ -5,6 +5,7 @@ #include "components/full_restore/full_restore_read_handler.h" #include <cstdint> +#include <memory> #include <utility> #include "ash/constants/app_types.h" @@ -231,23 +232,8 @@ if (!window_info) return; - WindowInfo* window_info_ptr = window_info->Clone(); - out_params->init_properties_container.SetProperty(kWindowInfoKey, - window_info_ptr); + ApplyProperties(window_info.get(), &out_params->init_properties_container); - if (window_info->activation_index) { - const int32_t index = *window_info->activation_index; - // kActivationIndexKey is owned, which allows for passing in this raw - // pointer. - out_params->init_properties_container.SetProperty(kActivationIndexKey, - new int32_t(index)); - // Windows opened from full restore should not be activated. Widgets that - // are shown are activated by default. Force the widget to not be - // activatable; the activation will be restored in ash once the window is - // launched. - out_params->init_properties_container.SetProperty( - kLaunchedFromFullRestoreKey, true); - } if (window_info->desk_id) out_params->workspace = base::NumberToString(*window_info->desk_id); out_params->visible_on_all_workspaces = @@ -261,11 +247,6 @@ out_params->show_state = chromeos::ToWindowShowState(*window_info->window_state_type); } - if (window_info->pre_minimized_show_state_type) { - out_params->init_properties_container.SetProperty( - aura::client::kPreMinimizedShowStateKey, - *window_info->pre_minimized_show_state_type); - } // Register to track when the widget has initialized. If a delegate is not // set, then the widget creator is responsible for calling @@ -289,6 +270,34 @@ arc_read_handler_->SetArcSessionIdForWindowId(arc_session_id, window_id); } +void FullRestoreReadHandler::ApplyProperties( + WindowInfo* window_info, + ui::PropertyHandler* property_handler) { + DCHECK(window_info); + DCHECK(property_handler); + + // Create a clone so `property_handler` can have complete ownership of a copy + // of WindowInfo. + WindowInfo* window_info_clone = window_info->Clone(); + property_handler->SetProperty(kWindowInfoKey, window_info_clone); + + if (window_info->activation_index) { + const int32_t index = *window_info->activation_index; + // kActivationIndexKey is owned, which allows for passing in this raw + // pointer. + property_handler->SetProperty(kActivationIndexKey, new int32_t(index)); + // Windows opened from full restore should not be activated. Widgets that + // are shown are activated by default. Force the widget to not be + // activatable; the activation will be restored in ash once the window is + // launched. + property_handler->SetProperty(kLaunchedFromFullRestoreKey, true); + } + if (window_info->pre_minimized_show_state_type) { + property_handler->SetProperty(aura::client::kPreMinimizedShowStateKey, + *window_info->pre_minimized_show_state_type); + } +} + void FullRestoreReadHandler::AddChromeBrowserLaunchInfoForTesting( const base::FilePath& profile_path) { auto session_id = SessionID::NewUnique();
diff --git a/components/full_restore/full_restore_read_handler.h b/components/full_restore/full_restore_read_handler.h index aa45c3ee..bf83b710 100644 --- a/components/full_restore/full_restore_read_handler.h +++ b/components/full_restore/full_restore_read_handler.h
@@ -130,6 +130,13 @@ // |arc session id| is assigned when ARC apps are restored. void SetArcSessionIdForWindowId(int32_t arc_session_id, int32_t window_id); + // Applies properties from `window_info` to the given `property_handler`. This + // is called from `GetWindowInfo()` when a full restore window is created, or + // from `arc_read_handler_` when a task is ready for a full restore window + // that has already been created. + void ApplyProperties(WindowInfo* window_info, + ui::PropertyHandler* property_handler); + void AddChromeBrowserLaunchInfoForTesting(const base::FilePath& profile_path); private:
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java index 8f373e2..b73ff87 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java
@@ -79,6 +79,8 @@ return "AddToHomescreenIPH"; case MessageIdentifier.SEND_TAB_TO_SELF: return "SendTabToSelf"; + case MessageIdentifier.READER_MODE: + return "ReaderMode"; default: return "Unknown"; }
diff --git a/components/messages/android/message_enums.h b/components/messages/android/message_enums.h index aeea66a..9768c55 100644 --- a/components/messages/android/message_enums.h +++ b/components/messages/android/message_enums.h
@@ -80,6 +80,7 @@ MERCHANT_TRUST = 7, ADD_TO_HOMESCREEN_IPH = 8, SEND_TAB_TO_SELF = 9, + READER_MODE = 10, // Insert new values before this line. COUNT
diff --git a/components/messages/android/messages_feature.cc b/components/messages/android/messages_feature.cc index 7529e19..1348a425 100644 --- a/components/messages/android/messages_feature.cc +++ b/components/messages/android/messages_feature.cc
@@ -12,13 +12,16 @@ const base::Feature kMessagesForAndroidPasswords{ "MessagesForAndroidPasswords", base::FEATURE_DISABLED_BY_DEFAULT}; -extern const base::Feature kMessagesForAndroidPopupBlocked{ +const base::Feature kMessagesForAndroidPopupBlocked{ "MessagesForAndroidPopupBlocked", base::FEATURE_DISABLED_BY_DEFAULT}; -extern const base::Feature kMessagesForAndroidSafetyTip{ +const base::Feature kMessagesForAndroidReaderMode{ + "MessagesForAndroidReaderMode", base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::Feature kMessagesForAndroidSafetyTip{ "MessagesForAndroidSafetyTip", base::FEATURE_DISABLED_BY_DEFAULT}; -extern const base::Feature kMessagesForAndroidSaveCard{ +const base::Feature kMessagesForAndroidSaveCard{ "MessagesForAndroidSaveCard", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kMessagesForAndroidUpdatePassword{
diff --git a/components/messages/android/messages_feature.h b/components/messages/android/messages_feature.h index 6dfef8ab..8bbb3f4 100644 --- a/components/messages/android/messages_feature.h +++ b/components/messages/android/messages_feature.h
@@ -22,6 +22,10 @@ // Infobars infrastructure. extern const base::Feature kMessagesForAndroidPopupBlocked; +// Feature that controls whether "reader mode" prompts use Messages or +// Infobars infrastructure. +extern const base::Feature kMessagesForAndroidReaderMode; + // Feature that controls whether "safety tip" prompts use Messages or // Infobars infrastructure. extern const base::Feature kMessagesForAndroidSafetyTip;
diff --git a/components/mirroring/service/session.cc b/components/mirroring/service/session.cc index dc6e3ce..11878c0 100644 --- a/components/mirroring/service/session.cc +++ b/components/mirroring/service/session.cc
@@ -17,7 +17,6 @@ #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" #include "base/rand_util.h" -#include "base/stl_util.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h"
diff --git a/components/new_or_sad_tab_strings.grdp b/components/new_or_sad_tab_strings.grdp index d67433b..eeab443 100644 --- a/components/new_or_sad_tab_strings.grdp +++ b/components/new_or_sad_tab_strings.grdp
@@ -184,56 +184,4 @@ When on, sites can't use cookies that track you across the web. Features on some sites may break. </message> - <!-- Ephemeral Guest Tab strings --> - <!-- TODO(crbug.com/1125474): Rename strings to *GUEST* instead of *EPHEMERAL_GUEST* once all audit is done and all instances of non-ephemeral Guest profiles are deprecated.--> - - <message name="IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_OUT" - desc="This is a greeting message that apprears when the user opens a new ephemeral guest tab while they are signed out of chrome guest session."> - You’re browsing as a Guest - </message> - <message name="IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_IN" - desc="This is greeting message with the user's name, appears when user opens a new ephemeral guest tab while they are signed in to chrome guest session."> - Hi <ph name="USERNAME">%s<ex>Mariam</ex></ph>, - <ph name="BR"><br></ph> - You’re browsing as a Guest - </message> - <message name="IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_OUT" - desc="This is a message displayed on the ephemeral guest NTP when the user is signed out of chrome guest session emphasing that no chrome profile info will be available unless the user chooses to sign in. The user can click on 'sign in' to start the sign in to chrome guest session flow."> - You won't see any Chrome profile's info in Guest mode. You can <ph name="LINK_BEGIN"><a id="change-sign-in-status"></ph>sign in<ph name="LINK_END"></a></ph> to access your Google account info like passwords and payment methods. - </message> - <message name="IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_IN" - desc="This is a message displayed on the ephemeral guest NTP when the user is signed in to chrome guest session to encourage closing all open guest windows in order to delete their browsing activity from the device in use."> - Close all Guest windows so your browsing activity is deleted from this device. - </message> - <message name="IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_OUT" - desc="A list of bullet points that appears on the ephemeral guest NTP listing data that won't be saved on the device after closing all guest windows. This shows when the user is signed out of chrome guest session."> - <ph name="BEGIN_BOLD"><b></ph> - Activity that won't stay on this device: - <ph name="END_BOLD"></b></ph> - <ph name="BEGIN_LIST"><ul></ph> - <ph name="LIST_ITEM"><li></ph>Pages you view in this window - <ph name="LIST_ITEM"><li></ph>Cookies and site data - <ph name="END_LIST"></ul></ph> - </message> - <message name="IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_IN" - desc="A list of bullet points that appears on the ephemeral guest NTP listing data that won't be saved on the device after closing all guest windows. The user can click 'sign out' to sign out of the guest session. This shows when the user is signed in to chrome guest session."> - <ph name="BEGIN_BOLD"><b></ph> - Activity that won't stay on this device: - <ph name="END_BOLD"></b></ph> - <ph name="BEGIN_LIST"><ul></ph> - <ph name="LIST_ITEM"><li></ph>Pages you view in this window - <ph name="LIST_ITEM"><li></ph>Cookies and site data - <ph name="LIST_ITEM"><li></ph>Account information (<ph name="LINK_BEGIN"><a id="change-sign-in-status"></ph>sign out<ph name="LINK_END"></a></ph>) - <ph name="END_LIST"></ul></ph> - </message> - <message name="IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED" - desc="A list of bullet points that appears on the ephemeral guest NTP listing data that will be saved on the device after closing all guest windows."> - <ph name="BEGIN_BOLD"><b></ph> - Your activity that stays on this device: - <ph name="END_BOLD"></b></ph> - <ph name="BEGIN_LIST"><ul></ph> - <ph name="LIST_ITEM"><li></ph>Any files you download in this window - <ph name="END_LIST"></ul></ph> - </message> - </grit-part>
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_IN.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_IN.png.sha1 deleted file mode 100644 index 2dcfe7b3..0000000 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_IN.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -86bfc1bb0860fe4e7c5087945f3aaa62c3bc4b67 \ No newline at end of file
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_OUT.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_OUT.png.sha1 deleted file mode 100644 index b6f8535..0000000 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_OUT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -3cd7f2320f25ed84487cbcd1cc1b0680daa9f0cd \ No newline at end of file
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED.png.sha1 deleted file mode 100644 index 459b37d..0000000 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e73c15ea0f9910de922dc6dc8d06eac889489fcc \ No newline at end of file
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_IN.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_IN.png.sha1 deleted file mode 100644 index 1bf51ed..0000000 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_IN.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -d731e5c7c6e773abe9af1af80049eb500548d53e \ No newline at end of file
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_OUT.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_OUT.png.sha1 deleted file mode 100644 index 2959fd4..0000000 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_OUT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -ef61e15824eef4f640f141dfd77d53816632b5b4 \ No newline at end of file
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_IN.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_IN.png.sha1 deleted file mode 100644 index 7842be74..0000000 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_IN.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -cedc5f231aa87da951a6304cda2a4c8691731df8 \ No newline at end of file
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_OUT.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_OUT.png.sha1 deleted file mode 100644 index dd4fa4ad..0000000 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_OUT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -37cbba8cdf1208db309f787af580f30dc981ccca \ No newline at end of file
diff --git a/components/openscreen_platform/message_port_tls_connection.cc b/components/openscreen_platform/message_port_tls_connection.cc index cf87e742..d03615b 100644 --- a/components/openscreen_platform/message_port_tls_connection.cc +++ b/components/openscreen_platform/message_port_tls_connection.cc
@@ -32,10 +32,6 @@ base::StringPiece(static_cast<const char*>(data), len)); } -openscreen::IPEndpoint MessagePortTlsConnection::GetLocalEndpoint() const { - return openscreen::IPEndpoint{openscreen::IPAddress::kV4LoopbackAddress()}; -} - openscreen::IPEndpoint MessagePortTlsConnection::GetRemoteEndpoint() const { return openscreen::IPEndpoint{openscreen::IPAddress::kV6LoopbackAddress()}; }
diff --git a/components/openscreen_platform/message_port_tls_connection.h b/components/openscreen_platform/message_port_tls_connection.h index d7bef37b..b28fa1f 100644 --- a/components/openscreen_platform/message_port_tls_connection.h +++ b/components/openscreen_platform/message_port_tls_connection.h
@@ -38,7 +38,6 @@ // TlsConnection overrides. void SetClient(TlsConnection::Client* client) final; bool Send(const void* data, size_t len) final; - openscreen::IPEndpoint GetLocalEndpoint() const final; openscreen::IPEndpoint GetRemoteEndpoint() const final; private:
diff --git a/components/openscreen_platform/tls_client_connection.cc b/components/openscreen_platform/tls_client_connection.cc index 7d78220..71d91886 100644 --- a/components/openscreen_platform/tls_client_connection.cc +++ b/components/openscreen_platform/tls_client_connection.cc
@@ -72,10 +72,6 @@ Error::Code::kNone; } -openscreen::IPEndpoint TlsClientConnection::GetLocalEndpoint() const { - return local_address_; -} - openscreen::IPEndpoint TlsClientConnection::GetRemoteEndpoint() const { return remote_address_; }
diff --git a/components/openscreen_platform/tls_client_connection.h b/components/openscreen_platform/tls_client_connection.h index b124ae4..55e1e97 100644 --- a/components/openscreen_platform/tls_client_connection.h +++ b/components/openscreen_platform/tls_client_connection.h
@@ -33,7 +33,6 @@ // TlsConnection overrides. void SetClient(Client* client) final; bool Send(const void* data, size_t len) final; - openscreen::IPEndpoint GetLocalEndpoint() const final; openscreen::IPEndpoint GetRemoteEndpoint() const final; // The maximum size of the vector in any single Client::OnRead() callback.
diff --git a/components/openscreen_platform/tls_client_connection_unittest.cc b/components/openscreen_platform/tls_client_connection_unittest.cc index 0c171068..026d391 100644 --- a/components/openscreen_platform/tls_client_connection_unittest.cc +++ b/components/openscreen_platform/tls_client_connection_unittest.cc
@@ -268,7 +268,6 @@ } TEST_F(TlsClientConnectionTest, CanRetrieveAddresses) { - EXPECT_EQ(kValidEndpointOne, connection()->GetLocalEndpoint()); EXPECT_EQ(kValidEndpointTwo, connection()->GetRemoteEndpoint()); }
diff --git a/components/optimization_guide/core/optimization_guide_util.cc b/components/optimization_guide/core/optimization_guide_util.cc index 183f676..11e2ff1 100644 --- a/components/optimization_guide/core/optimization_guide_util.cc +++ b/components/optimization_guide/core/optimization_guide_util.cc
@@ -32,6 +32,8 @@ return "SegmentationShare"; case proto::OPTIMIZATION_TARGET_SEGMENTATION_VOICE: return "SegmentationVoice"; + case proto::OPTIMIZATION_TARGET_MODEL_VALIDATION: + return "ModelValidation"; } NOTREACHED(); return std::string();
diff --git a/components/optimization_guide/proto/models.proto b/components/optimization_guide/proto/models.proto index 6fb4825..fd4f6c6 100644 --- a/components/optimization_guide/proto/models.proto +++ b/components/optimization_guide/proto/models.proto
@@ -252,6 +252,8 @@ OPTIMIZATION_TARGET_SEGMENTATION_SHARE = 5; // Target for segmentation: Voice user. OPTIMIZATION_TARGET_SEGMENTATION_VOICE = 6; + // Target for model validation. + OPTIMIZATION_TARGET_MODEL_VALIDATION = 7; } // The types of models that can be evaluated.
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 2a3f906..ce4ab20 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -21,7 +21,6 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/ranges/algorithm.h" -#include "base/stl_util.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/task_runner_util.h"
diff --git a/components/permissions/android/permissions_android_feature_list.cc b/components/permissions/android/permissions_android_feature_list.cc index e6402a0..3712456 100644 --- a/components/permissions/android/permissions_android_feature_list.cc +++ b/components/permissions/android/permissions_android_feature_list.cc
@@ -4,7 +4,6 @@ #include "components/permissions/android/permissions_android_feature_list.h" #include "base/android/jni_string.h" -#include "base/stl_util.h" #include "components/permissions/android/jni_headers/PermissionsAndroidFeatureList_jni.h" using base::android::ConvertJavaStringToUTF8;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 93630fd..3f029541 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -4695,7 +4695,7 @@ }, { 'name': 'ExtensionInstallBlacklist', - 'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'], + 'owners': ['lazyboy@chromium.org', 'file://extensions/OWNERS'], 'type': 'list', 'schema': { 'type': 'array', @@ -4721,7 +4721,7 @@ { 'name': 'ExtensionInstallBlocklist', - 'owners': ['file://components/policy/resources/OWNERS', 'poromov@chromium.org'], + 'owners': ['lazyboy@chromium.org', 'file://extensions/OWNERS'], 'type': 'list', 'schema': { 'type': 'array', @@ -4745,7 +4745,7 @@ }, { 'name': 'ExtensionInstallAllowlist', - 'owners': ['file://components/policy/resources/OWNERS', 'emaxx@chromium.org'], + 'owners': ['rdevlin.cronin@chromium.org', 'file://extensions/OWNERS'], 'type': 'list', 'schema': { 'type': 'array', @@ -4769,7 +4769,7 @@ }, { 'name': 'ExtensionInstallWhitelist', - 'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'], + 'owners': ['rdevlin.cronin@chromium.org', 'file://extensions/OWNERS'], 'type': 'list', 'schema': { 'type': 'array', @@ -4792,7 +4792,7 @@ }, { 'name': 'ExtensionInstallForcelist', - 'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'], + 'owners': ['karandeepb@chromium.org', 'file://extensions/OWNERS'], 'type': 'list', 'schema': { 'type': 'array', @@ -4827,7 +4827,7 @@ }, { 'name': 'ExtensionInstallSources', - 'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'], + 'owners': ['dbertoni@chromium.org', 'file://extensions/OWNERS'], 'type': 'list', 'schema': { 'type': 'array', @@ -4873,7 +4873,7 @@ }, { 'name': 'ExtensionAllowedTypes', - 'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'], + 'owners': ['benwells@chromium.org', 'file://extensions/OWNERS'], 'type': 'list', 'schema': { 'type': 'array', @@ -4926,7 +4926,7 @@ }, { 'name': 'ExtensionSettings', - 'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'], + 'owners': ['finnur@chromium.org', 'file://extensions/OWNERS'], 'type': 'dict', 'schema': { 'type': 'object', @@ -5084,7 +5084,7 @@ }, { 'name': 'BlockExternalExtensions', - 'owners': ['file://components/policy/resources/OWNERS', 'pastarmovj@chromium.org'], + 'owners': ['reillyg@chromium.org', 'file://extensions/OWNERS'], 'type': 'main', 'schema': { 'type': 'boolean' }, 'supported_on': ['chrome.*:80-'], @@ -26246,7 +26246,7 @@ 'caption': 'Use default icons for secure connections', }, ], - 'future_on': ['chrome.*', 'chrome_os', 'android'], + 'supported_on': ['chrome.*:93-', 'chrome_os:93-', 'android:93-'], 'features': { 'dynamic_refresh': True, 'per_profile': True,
diff --git a/components/prefs/json_pref_store.cc b/components/prefs/json_pref_store.cc index d76f348..893e8ec 100644 --- a/components/prefs/json_pref_store.cc +++ b/components/prefs/json_pref_store.cc
@@ -243,7 +243,7 @@ void JsonPrefStore::RemoveValue(const std::string& key, uint32_t flags) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (prefs_->RemovePath(key, nullptr)) + if (prefs_->RemovePath(key)) ReportValueChanged(key, flags); } @@ -251,7 +251,7 @@ uint32_t flags) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - prefs_->RemovePath(key, nullptr); + prefs_->RemovePath(key); ScheduleWrite(flags); }
diff --git a/components/remote_cocoa/app_shim/select_file_dialog_bridge.h b/components/remote_cocoa/app_shim/select_file_dialog_bridge.h index 90f23f0..99b5180 100644 --- a/components/remote_cocoa/app_shim/select_file_dialog_bridge.h +++ b/components/remote_cocoa/app_shim/select_file_dialog_bridge.h
@@ -50,10 +50,12 @@ private: // Sets the accessory view for |dialog_| and sets - // |extension_dropdown_handler_|. + // |extension_dropdown_handler_|. |is_save_panel| specifies whether this is + // for a save panel or not. void SetAccessoryView(mojom::SelectFileTypeInfoPtr file_types, int file_type_index, - const base::FilePath::StringType& default_extension); + const base::FilePath::StringType& default_extension, + bool is_save_panel); // Called when the panel completes. void OnPanelEnded(bool did_cancel);
diff --git a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm b/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm index 537c6bb..215ef86 100644 --- a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm +++ b/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm
@@ -26,7 +26,7 @@ CFStringRef CreateUTIFromExtension(const base::FilePath::StringType& ext) { base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(ext)); return UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, - ext_cf.get(), NULL); + ext_cf.get(), nullptr); } NSString* GetDescriptionFromExtension(const base::FilePath::StringType& ext) { @@ -288,8 +288,9 @@ type_ != SelectFileDialogType::kUploadFolder && type_ != SelectFileDialogType::kExistingFolder) { if (file_types) { - SetAccessoryView(std::move(file_types), file_type_index, - default_extension); + SetAccessoryView( + std::move(file_types), file_type_index, default_extension, + /*is_save_panel=*/type_ == SelectFileDialogType::kSaveAsFile); } else { // If no type_ info is specified, anything goes. [dialog setAllowsOtherFileTypes:YES]; @@ -362,11 +363,11 @@ void SelectFileDialogBridge::SetAccessoryView( SelectFileTypeInfoPtr file_types, int file_type_index, - const base::FilePath::StringType& default_extension) { + const base::FilePath::StringType& default_extension, + bool is_save_panel) { DCHECK(file_types); base::scoped_nsobject<NSView> accessory_view = CreateAccessoryView(); NSSavePanel* dialog = panel_.get(); - [dialog setAccessoryView:accessory_view.get()]; NSPopUpButton* popup = [accessory_view viewWithTag:kFileTypePopupTag]; DCHECK(popup); @@ -425,8 +426,13 @@ } if (file_types->include_all_files || file_types->extensions.empty()) { - [popup addItemWithTitle:l10n_util::GetNSString(IDS_APP_SAVEAS_ALL_FILES)]; - [dialog setAllowsOtherFileTypes:YES]; + dialog.allowsOtherFileTypes = YES; + // If "all files" is specified for a save panel, allow the user to add an + // alternate non-suggested extension, but don't add it to the popup. It + // makes no sense to save as an "all files" file type. + if (!is_save_panel) { + [popup addItemWithTitle:l10n_util::GetNSString(IDS_APP_SAVEAS_ALL_FILES)]; + } } extension_dropdown_handler_.reset([[ExtensionDropdownHandler alloc] @@ -454,6 +460,10 @@ [popup selectItemAtIndex:0]; [extension_dropdown_handler_ popupAction:popup]; } + + // There's no need for a popup unless there are at least two choices. + if (popup.numberOfItems >= 2) + dialog.accessoryView = accessory_view.get(); } void SelectFileDialogBridge::OnPanelEnded(bool did_cancel) { @@ -464,8 +474,9 @@ std::vector<base::FilePath> paths; if (!did_cancel) { if (type_ == SelectFileDialogType::kSaveAsFile) { - if ([[panel_ URL] isFileURL]) { - paths.push_back(base::mac::NSStringToFilePath([[panel_ URL] path])); + NSURL* url = [panel_ URL]; + if ([url isFileURL]) { + paths.push_back(base::mac::NSStringToFilePath([url path])); } NSView* accessoryView = [panel_ accessoryView]; @@ -482,7 +493,7 @@ NSArray* urls = [static_cast<NSOpenPanel*>(panel_) URLs]; for (NSURL* url in urls) if ([url isFileURL]) - paths.push_back(base::FilePath(base::SysNSStringToUTF8([url path]))); + paths.push_back(base::mac::NSStringToFilePath([url path])); } }
diff --git a/components/safe_browsing/content/browser/base_ui_manager.cc b/components/safe_browsing/content/browser/base_ui_manager.cc index b3ea5a1ef..fe3b79ce 100644 --- a/components/safe_browsing/content/browser/base_ui_manager.cc +++ b/components/safe_browsing/content/browser/base_ui_manager.cc
@@ -127,10 +127,16 @@ if (resource.is_subresource) { entry = GetNavigationEntryForResource(resource); } + + WebContents* web_contents = resource.web_contents_getter.Run(); + // |web_contents_getter| can return null after RenderFrameHost is destroyed. + if (!web_contents) + return false; + SBThreatType unused_threat_type; return IsUrlAllowlistedOrPendingForWebContents( - resource.url, resource.is_subresource, entry, - resource.web_contents_getter.Run(), true, &unused_threat_type); + resource.url, resource.is_subresource, entry, web_contents, true, + &unused_threat_type); } // Check if the user has already seen and/or ignored a SB warning for this
diff --git a/components/safe_browsing/core/browser/db/fake_database_manager.cc b/components/safe_browsing/core/browser/db/fake_database_manager.cc index 6a8c6373..18265d4b 100644 --- a/components/safe_browsing/core/browser/db/fake_database_manager.cc +++ b/components/safe_browsing/core/browser/db/fake_database_manager.cc
@@ -53,6 +53,30 @@ return false; } +bool FakeSafeBrowsingDatabaseManager::CheckDownloadUrl( + const std::vector<GURL>& url_chain, + Client* client) { + for (size_t i = 0; i < url_chain.size(); i++) { + GURL url = url_chain[i]; + + const auto it = dangerous_urls_.find(url); + if (it == dangerous_urls_.end()) + continue; + + const SBThreatType result_threat_type = it->second; + if (result_threat_type == SB_THREAT_TYPE_SAFE) + continue; + + io_task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&FakeSafeBrowsingDatabaseManager::CheckDownloadURLAsync, + url_chain, result_threat_type, client)); + return false; + } + + return true; +} + bool FakeSafeBrowsingDatabaseManager::CheckExtensionIDs( const std::set<std::string>& extension_ids, Client* client) { @@ -83,4 +107,12 @@ safe_browsing::ThreatMetadata()); } +// static +void FakeSafeBrowsingDatabaseManager::CheckDownloadURLAsync( + const std::vector<GURL>& url_chain, + SBThreatType result_threat_type, + Client* client) { + client->OnCheckDownloadUrlResult(url_chain, result_threat_type); +} + } // namespace safe_browsing
diff --git a/components/safe_browsing/core/browser/db/fake_database_manager.h b/components/safe_browsing/core/browser/db/fake_database_manager.h index 23096c4..23d64c8 100644 --- a/components/safe_browsing/core/browser/db/fake_database_manager.h +++ b/components/safe_browsing/core/browser/db/fake_database_manager.h
@@ -30,6 +30,8 @@ bool CheckBrowseUrl(const GURL& url, const SBThreatTypeSet& threat_types, Client* client) override; + bool CheckDownloadUrl(const std::vector<GURL>& url_chain, + Client* client) override; bool CheckExtensionIDs(const std::set<std::string>& extension_ids, Client* client) override; bool CheckUrlForSubresourceFilter(const GURL& url, Client* client) override; @@ -42,6 +44,9 @@ static void CheckBrowseURLAsync(GURL url, SBThreatType result_threat_type, Client* client); + static void CheckDownloadURLAsync(const std::vector<GURL>& url_chain, + SBThreatType result_threat_type, + Client* client); base::flat_map<GURL, SBThreatType> dangerous_urls_; };
diff --git a/components/signin/ios/browser/account_consistency_service.mm b/components/signin/ios/browser/account_consistency_service.mm index 2038360c..a04ebfc1 100644 --- a/components/signin/ios/browser/account_consistency_service.mm +++ b/components/signin/ios/browser/account_consistency_service.mm
@@ -125,16 +125,15 @@ web::PageLoadCompletionStatus load_completion_status) override; // web::WebStatePolicyDecider override. - void ShouldAllowRequest( + WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + const web::WebStatePolicyDecider::RequestInfo& request_info) override; // Decides on navigation corresponding to |response| whether the navigation // should continue and updates authentication cookies on Google domains. void ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + base::OnceCallback<void(PolicyDecision)> callback) override; void WebStateDestroyed() override; // Loads |url| in the current tab. @@ -165,10 +164,10 @@ web_state->AddObserver(this); } -void AccountConsistencyService::AccountConsistencyHandler::ShouldAllowRequest( +web::WebStatePolicyDecider::PolicyDecision +AccountConsistencyService::AccountConsistencyHandler::ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + const web::WebStatePolicyDecider::RequestInfo& request_info) { GURL url = net::GURLWithNSURL(request.URL); if (base::FeatureList::IsEnabled(signin::kRestoreGaiaCookiesOnUserAction) && signin::IsUrlEligibleForMirrorCookie(url) && @@ -180,13 +179,13 @@ // necessary. account_consistency_service_->AddChromeConnectedCookies(); } - std::move(callback).Run(PolicyDecision::Allow()); + return PolicyDecision::Allow(); } void AccountConsistencyService::AccountConsistencyHandler::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + base::OnceCallback<void(PolicyDecision)> callback) { NSHTTPURLResponse* http_response = base::mac::ObjCCast<NSHTTPURLResponse>(response); if (!http_response) {
diff --git a/components/sync/base/unique_position.cc b/components/sync/base/unique_position.cc index 27df76b..d732c27 100644 --- a/components/sync/base/unique_position.cc +++ b/components/sync/base/unique_position.cc
@@ -10,7 +10,6 @@ #include "base/logging.h" #include "base/notreached.h" #include "base/rand_util.h" -#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/trace_event/memory_usage_estimator.h" #include "components/sync/protocol/unique_position.pb.h"
diff --git a/components/sync/nigori/nigori.cc b/components/sync/nigori/nigori.cc index 32b0b81..513f9347 100644 --- a/components/sync/nigori/nigori.cc +++ b/components/sync/nigori/nigori.cc
@@ -15,7 +15,6 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" #include "base/notreached.h" -#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/sys_byteorder.h"
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index b7d937e..d0009e91 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -113,6 +113,14 @@ const base::Feature kOverrideSitePrefsForHrefTranslate{ "OverrideSitePrefsForHrefTranslate", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kOverrideUnsupportedPageLanguageForHrefTranslate{ + "OverrideUnsupportedPageLanguageForHrefTranslate", + base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::Feature kOverrideSimilarLanguagesForHrefTranslate{ + "OverrideSimilarLanguagesForHrefTranslate", + base::FEATURE_DISABLED_BY_DEFAULT}; + const char kForceAutoTranslateKey[] = "force-auto-translate"; TranslateManager::~TranslateManager() = default; @@ -761,20 +769,24 @@ translate_driver_->GetUkmSourceId(), translate_event_.get()); } -bool TranslateManager::ShouldSuppressBubbleUI() { - // Suppress the UI if the user navigates to a page with - // the same language as the previous page. In the new UI, - // continue offering translation after the user navigates - // to another page. - if (!language_state_.HasLanguageChanged() && - !ShouldOverrideMatchesPreviousLanguageDecision()) { - TranslateBrowserMetrics::ReportInitiationStatus( - TranslateBrowserMetrics:: - INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE); - return true; +bool TranslateManager::ShouldSuppressBubbleUI( + const std::string& target_language) { + // Suppress the UI if the user navigates to a page with the same language as + // the previous page, unless the page was loaded from a link click with + // hrefTranslate attached that matches the target language, since in that case + // the site might have a good reason to show the translate UI regardless of + // the source language of the previous page. In the new UI, continue offering + // translation after the user navigates to another page. + DCHECK(!target_language.empty()); + if (language_state_.href_translate() == target_language || + language_state_.HasLanguageChanged() || + ShouldOverrideMatchesPreviousLanguageDecision()) { + return false; } - - return false; + TranslateBrowserMetrics::ReportInitiationStatus( + TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE); + return true; } void TranslateManager::AddTargetLanguageToAcceptLanguages( @@ -1095,6 +1107,7 @@ decision->PreventAutoHrefTranslate(); } + decision->href_translate_source = page_language_code; decision->href_translate_target = language_state_.href_translate(); if (language_state_.navigation_from_google()) { @@ -1102,13 +1115,56 @@ !decision->href_translate_target.empty()); } - // Can't honor hrefTranslate if there's no specified target, the source or - // the target aren't supported, or the source and target match. - if (!IsTranslatableLanguagePair(page_language_code, - decision->href_translate_target)) { + // Can't honor hrefTranslate if there's no specified target or the target + // language isn't supported. + if (decision->href_translate_target.empty() || + !TranslateDownloadManager::IsSupportedLanguage( + decision->href_translate_target)) { decision->PreventAutoHrefTranslate(); decision->PreventShowingHrefTranslateUI(); } + + if (!TranslateDownloadManager::IsSupportedLanguage(page_language_code)) { + // If the page language is unsupported or unknown, but hrefTranslate is + // present and the Feature is set such that translation should be attempted + // anyways, then as a last ditch effort assume that language detection was + // incorrect and send "und" as the source language to make the translate + // service attempt to detect the language as it processes the page content. + if (language_state_.navigation_from_google() && + base::FeatureList::IsEnabled( + kOverrideUnsupportedPageLanguageForHrefTranslate)) { + decision->href_translate_source = translate::kUnknownLanguageCode; + if (!base::GetFieldTrialParamByFeatureAsBool( + kOverrideUnsupportedPageLanguageForHrefTranslate, + "force-auto-translate-for-unsupported-page-language", false)) { + decision->PreventAutoHrefTranslate(); + } + } else { + decision->PreventAutoHrefTranslate(); + decision->PreventShowingHrefTranslateUI(); + } + } + + if (page_language_code == decision->href_translate_target) { + // If the page language seems to match the hrefTranslate target language and + // the Feature is set such that translation should be attempted anyways, + // then as a last ditch effort assume that language detection was incorrect + // and send "und" as the source language to make the translate service + // attempt to detect the language as it processes the page content. + if (language_state_.navigation_from_google() && + base::FeatureList::IsEnabled( + kOverrideSimilarLanguagesForHrefTranslate)) { + decision->href_translate_source = translate::kUnknownLanguageCode; + if (!base::GetFieldTrialParamByFeatureAsBool( + kOverrideSimilarLanguagesForHrefTranslate, + "force-auto-translate-for-similar-languages", false)) { + decision->PreventAutoHrefTranslate(); + } + } else { + decision->PreventAutoHrefTranslate(); + decision->PreventShowingHrefTranslateUI(); + } + } } void TranslateManager::FilterForPredefinedTarget( @@ -1157,7 +1213,8 @@ } if (decision.can_auto_href_translate()) { - TranslatePage(page_language_code, decision.href_translate_target, false, + TranslatePage(decision.href_translate_source, + decision.href_translate_target, false, GetLanguageState()->InTranslateNavigation() ? TranslationType::kAutomaticTranslationByLink : TranslationType::kAutomaticTranslationByPref); @@ -1201,8 +1258,9 @@ // hrefTranslate attribute if it was present on the originating link. if (!did_show_ui && decision.can_show_href_translate_ui()) { did_show_ui = translate_client_->ShowTranslateUI( - translate::TRANSLATE_STEP_BEFORE_TRANSLATE, page_language_code, - decision.href_translate_target, TranslateErrors::NONE, false); + translate::TRANSLATE_STEP_BEFORE_TRANSLATE, + decision.href_translate_source, decision.href_translate_target, + TranslateErrors::NONE, false); GetActiveTranslateMetricsLogger()->LogTriggerDecision( TriggerDecision::kShowUIFromHref); }
diff --git a/components/translate/core/browser/translate_manager.h b/components/translate/core/browser/translate_manager.h index faae855..1e9a796 100644 --- a/components/translate/core/browser/translate_manager.h +++ b/components/translate/core/browser/translate_manager.h
@@ -49,6 +49,8 @@ extern const base::Feature kOverrideLanguagePrefsForHrefTranslate; extern const base::Feature kOverrideSitePrefsForHrefTranslate; +extern const base::Feature kOverrideUnsupportedPageLanguageForHrefTranslate; +extern const base::Feature kOverrideSimilarLanguagesForHrefTranslate; extern const char kForceAutoTranslateKey[]; // The TranslateManager class is responsible for showing an info-bar when a page @@ -220,8 +222,9 @@ // and logs the event appropriately. bool ShouldOverrideMatchesPreviousLanguageDecision(); - // Returns true if the BubbleUI should be suppressed. - bool ShouldSuppressBubbleUI(); + // Returns true if the BubbleUI should be suppressed, where |target_language| + // is the target language that would be shown in the UI. + bool ShouldSuppressBubbleUI(const std::string& target_language); // Sets target language. void SetPredefinedTargetLanguage(const std::string& language_code);
diff --git a/components/translate/core/browser/translate_manager_unittest.cc b/components/translate/core/browser/translate_manager_unittest.cc index a2addfd..568a08a 100644 --- a/components/translate/core/browser/translate_manager_unittest.cc +++ b/components/translate/core/browser/translate_manager_unittest.cc
@@ -449,9 +449,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, false /* triggered_from_menu */)) .WillByDefault(Return(true)); @@ -487,9 +487,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)) .WillByDefault(Return(true)); @@ -533,9 +533,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)) .WillByDefault(Return(true)); @@ -582,9 +582,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)) .WillByDefault(Return(true)); @@ -626,9 +626,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)) .WillByDefault(Return(true)); @@ -665,9 +665,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)) .WillByDefault(Return(true)); @@ -708,9 +708,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)) .WillByDefault(Return(true)); @@ -878,7 +878,7 @@ PrepareTranslateManager(); SetHasLanguageChanged(true); base::HistogramTester histogram_tester; - EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI()); + EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI("fr")); histogram_tester.ExpectTotalCount(kInitiationStatusName, 0); } @@ -889,7 +889,7 @@ ShouldOverrideMatchesPreviousLanguageDecision(_, _)) .WillOnce(Return(false)); base::HistogramTester histogram_tester; - EXPECT_TRUE(translate_manager_->ShouldSuppressBubbleUI()); + EXPECT_TRUE(translate_manager_->ShouldSuppressBubbleUI("fr")); histogram_tester.ExpectUniqueSample( kInitiationStatusName, metrics::INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE, 1); @@ -902,10 +902,58 @@ ShouldOverrideMatchesPreviousLanguageDecision(_, _)) .WillOnce(Return(true)); SetHasLanguageChanged(false); - EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI()); + EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI("fr")); histogram_tester.ExpectTotalCount(kInitiationStatusName, 0); } +TEST_F(TranslateManagerTest, + ShouldSuppressBubbleUI_HrefTranslateMatchesTarget) { + PrepareTranslateManager(); + const std::string source_language = "de"; + const std::string target_language = "fr"; + + // Set the LanguageState such that the language has not changed ("de" -> + // "de"), but there is a hrefTranslate attribute that matches the target + // language. + translate_manager_->GetLanguageState()->LanguageDetermined(source_language, + true); + translate_manager_->GetLanguageState()->DidNavigate( + false, true, false, + /*href_translate=*/target_language, false); + translate_manager_->GetLanguageState()->LanguageDetermined(source_language, + true); + EXPECT_FALSE(translate_manager_->GetLanguageState()->HasLanguageChanged()); + + base::HistogramTester histogram_tester; + EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI(target_language)); + histogram_tester.ExpectTotalCount(kInitiationStatusName, 0); +} + +TEST_F(TranslateManagerTest, + ShouldSuppressBubbleUI_HrefTranslateMismatchTarget) { + PrepareTranslateManager(); + const std::string source_language = "de"; + const std::string target_language = "fr"; + + // Set the LanguageState such that the language has not changed ("de" -> + // "de"), and there is a hrefTranslate attribute that does not match the + // target language. + translate_manager_->GetLanguageState()->LanguageDetermined(source_language, + true); + translate_manager_->GetLanguageState()->DidNavigate(false, true, false, + /*href_translate=*/"id", + false); + translate_manager_->GetLanguageState()->LanguageDetermined(source_language, + true); + EXPECT_FALSE(translate_manager_->GetLanguageState()->HasLanguageChanged()); + + base::HistogramTester histogram_tester; + EXPECT_TRUE(translate_manager_->ShouldSuppressBubbleUI(target_language)); + histogram_tester.ExpectUniqueSample( + kInitiationStatusName, + metrics::INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE, 1); +} + TEST_F(TranslateManagerTest, RecordInitilizationError) { PrepareTranslateManager(); const std::string target_lang = "en"; @@ -1095,9 +1143,9 @@ ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); ON_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)) .WillByDefault(Return(true)); network_notifier_.SimulateOnline(); @@ -1195,9 +1243,9 @@ }; ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); - TranslateAcceptLanguages accept_langugages(&prefs_, accept_languages_prefs); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) - .WillByDefault(Return(&accept_langugages)); + .WillByDefault(Return(&accept_languages)); EXPECT_CALL(mock_translate_client_, ShowTranslateUI).WillOnce(Return(true)); translate_manager_ = std::make_unique<translate::TranslateManager>( @@ -1250,6 +1298,278 @@ null_translate_metrics_logger()); } +TEST_F(TranslateManagerTest, + HrefTranslateUnknownPageLanguage_OverrideDisabled) { + scoped_feature_list_.InitAndDisableFeature( + kOverrideUnsupportedPageLanguageForHrefTranslate); + + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_ = std::make_unique<translate::TranslateManager>( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_); + + manager_->set_application_locale("en"); + ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); + + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); + ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) + .WillByDefault(Return(&accept_languages)); + EXPECT_CALL(mock_translate_client_, + ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, "und", + "ru", TranslateErrors::NONE, false)) + .Times(0); + network_notifier_.SimulateOnline(); + + translate_manager_->GetLanguageState()->LanguageDetermined("und", true); + translate_manager_->GetLanguageState()->DidNavigate( + false, true, false, + /*href_translate=*/"ru", + /*navigation_from_google=*/true); + translate_manager_->GetLanguageState()->LanguageDetermined("und", true); + + std::unique_ptr<TranslateMetricsLogger> translate_metrics_logger = + std::make_unique<TranslateMetricsLoggerImpl>( + translate_manager_->GetWeakPtr()); + translate_metrics_logger->OnPageLoadStart(true); + + base::HistogramTester histogram_tester; + translate_manager_->InitiateTranslation("und"); + translate_metrics_logger->RecordMetrics(true); + + EXPECT_THAT( + histogram_tester.GetAllSamples(kTranslatePageLoadTriggerDecision), + ElementsAre(Bucket( + static_cast<int>(TriggerDecision::kDisabledUnsupportedLanguage), 1))); +} + +TEST_F(TranslateManagerTest, + HrefTranslateUnknownPageLanguage_OverrideEnabledShowUI) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + kOverrideUnsupportedPageLanguageForHrefTranslate, + {{"force-auto-translate-for-unsupported-page-language", "false"}}); + + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_ = std::make_unique<translate::TranslateManager>( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_); + + manager_->set_application_locale("en"); + ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); + + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); + ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) + .WillByDefault(Return(&accept_languages)); + EXPECT_CALL(mock_translate_client_, + ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, "und", + "ru", TranslateErrors::NONE, false)) + .Times(1) + .WillOnce(Return(true)); + network_notifier_.SimulateOnline(); + + translate_manager_->GetLanguageState()->LanguageDetermined("und", true); + translate_manager_->GetLanguageState()->DidNavigate( + false, true, false, + /*href_translate=*/"ru", + /*navigation_from_google=*/true); + translate_manager_->GetLanguageState()->LanguageDetermined("und", true); + + std::unique_ptr<TranslateMetricsLogger> translate_metrics_logger = + std::make_unique<TranslateMetricsLoggerImpl>( + translate_manager_->GetWeakPtr()); + translate_metrics_logger->OnPageLoadStart(true); + + base::HistogramTester histogram_tester; + translate_manager_->InitiateTranslation("und"); + translate_metrics_logger->RecordMetrics(true); + + EXPECT_THAT(histogram_tester.GetAllSamples(kTranslatePageLoadTriggerDecision), + ElementsAre(Bucket( + static_cast<int>(TriggerDecision::kShowUIFromHref), 1))); +} + +TEST_F(TranslateManagerTest, + HrefTranslateUnknownPageLanguage_OverrideEnabledAutoTranslate) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + kOverrideUnsupportedPageLanguageForHrefTranslate, + {{"force-auto-translate-for-unsupported-page-language", "true"}}); + + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_ = std::make_unique<translate::TranslateManager>( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_); + + manager_->set_application_locale("en"); + ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); + + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); + ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) + .WillByDefault(Return(&accept_languages)); + EXPECT_CALL(mock_translate_client_, + ShowTranslateUI(translate::TRANSLATE_STEP_TRANSLATING, "und", + "ru", TranslateErrors::NONE, false)) + .Times(1) + .WillOnce(Return(true)); + network_notifier_.SimulateOnline(); + + translate_manager_->GetLanguageState()->LanguageDetermined("und", true); + translate_manager_->GetLanguageState()->DidNavigate( + false, true, false, + /*href_translate=*/"ru", + /*navigation_from_google=*/true); + translate_manager_->GetLanguageState()->LanguageDetermined("und", true); + + std::unique_ptr<TranslateMetricsLogger> translate_metrics_logger = + std::make_unique<TranslateMetricsLoggerImpl>( + translate_manager_->GetWeakPtr()); + translate_metrics_logger->OnPageLoadStart(true); + + base::HistogramTester histogram_tester; + translate_manager_->InitiateTranslation("und"); + translate_metrics_logger->RecordMetrics(true); + + EXPECT_THAT( + histogram_tester.GetAllSamples(kTranslatePageLoadTriggerDecision), + ElementsAre(Bucket( + static_cast<int>(TriggerDecision::kAutomaticTranslationByHref), 1))); +} + +TEST_F(TranslateManagerTest, HrefTranslateSimilarLanguages_OverrideDisabled) { + scoped_feature_list_.InitAndDisableFeature( + kOverrideSimilarLanguagesForHrefTranslate); + + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_ = std::make_unique<translate::TranslateManager>( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_); + + manager_->set_application_locale("en"); + ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); + + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); + ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) + .WillByDefault(Return(&accept_languages)); + EXPECT_CALL(mock_translate_client_, ShowTranslateUI(_, _, _, _, _)).Times(0); + network_notifier_.SimulateOnline(); + + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); + translate_manager_->GetLanguageState()->DidNavigate( + false, true, false, + /*href_translate=*/"en", + /*navigation_from_google=*/true); + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); + + std::unique_ptr<TranslateMetricsLogger> translate_metrics_logger = + std::make_unique<TranslateMetricsLoggerImpl>( + translate_manager_->GetWeakPtr()); + translate_metrics_logger->OnPageLoadStart(true); + + base::HistogramTester histogram_tester; + translate_manager_->InitiateTranslation("en"); + translate_metrics_logger->RecordMetrics(true); + + EXPECT_THAT( + histogram_tester.GetAllSamples(kTranslatePageLoadTriggerDecision), + ElementsAre(Bucket( + static_cast<int>(TriggerDecision::kDisabledSimilarLanguages), 1))); +} + +TEST_F(TranslateManagerTest, + HrefTranslateSimilarLanguages_OverrideEnabledShowUI) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + kOverrideSimilarLanguagesForHrefTranslate, + {{"force-auto-translate-for-similar-languages", "false"}}); + + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_ = std::make_unique<translate::TranslateManager>( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_); + + manager_->set_application_locale("en"); + ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); + + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); + ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) + .WillByDefault(Return(&accept_languages)); + EXPECT_CALL(mock_translate_client_, + ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, "und", + "en", TranslateErrors::NONE, false)) + .Times(1) + .WillOnce(Return(true)); + network_notifier_.SimulateOnline(); + + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); + translate_manager_->GetLanguageState()->DidNavigate( + false, true, false, + /*href_translate=*/"en", + /*navigation_from_google=*/true); + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); + + std::unique_ptr<TranslateMetricsLogger> translate_metrics_logger = + std::make_unique<TranslateMetricsLoggerImpl>( + translate_manager_->GetWeakPtr()); + translate_metrics_logger->OnPageLoadStart(true); + + base::HistogramTester histogram_tester; + translate_manager_->InitiateTranslation("en"); + translate_metrics_logger->RecordMetrics(true); + + EXPECT_THAT(histogram_tester.GetAllSamples(kTranslatePageLoadTriggerDecision), + ElementsAre(Bucket( + static_cast<int>(TriggerDecision::kShowUIFromHref), 1))); +} + +TEST_F(TranslateManagerTest, + HrefTranslateSimilarLanguages_OverrideEnabledAutoTranslate) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + kOverrideSimilarLanguagesForHrefTranslate, + {{"force-auto-translate-for-similar-languages", "true"}}); + + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_ = std::make_unique<translate::TranslateManager>( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_); + + manager_->set_application_locale("en"); + ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); + + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + TranslateAcceptLanguages accept_languages(&prefs_, accept_languages_prefs); + ON_CALL(mock_translate_client_, GetTranslateAcceptLanguages()) + .WillByDefault(Return(&accept_languages)); + EXPECT_CALL(mock_translate_client_, + ShowTranslateUI(translate::TRANSLATE_STEP_TRANSLATING, "und", + "en", TranslateErrors::NONE, false)) + .Times(1) + .WillOnce(Return(true)); + network_notifier_.SimulateOnline(); + + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); + translate_manager_->GetLanguageState()->DidNavigate( + false, true, false, + /*href_translate=*/"en", + /*navigation_from_google=*/true); + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); + + std::unique_ptr<TranslateMetricsLogger> translate_metrics_logger = + std::make_unique<TranslateMetricsLoggerImpl>( + translate_manager_->GetWeakPtr()); + translate_metrics_logger->OnPageLoadStart(true); + + base::HistogramTester histogram_tester; + translate_manager_->InitiateTranslation("en"); + translate_metrics_logger->RecordMetrics(true); + + EXPECT_THAT( + histogram_tester.GetAllSamples(kTranslatePageLoadTriggerDecision), + ElementsAre(Bucket( + static_cast<int>(TriggerDecision::kAutomaticTranslationByHref), 1))); +} + } // namespace testing } // namespace translate
diff --git a/components/translate/core/browser/translate_trigger_decision.h b/components/translate/core/browser/translate_trigger_decision.h index de38fd1b..23a7c5c 100644 --- a/components/translate/core/browser/translate_trigger_decision.h +++ b/components/translate/core/browser/translate_trigger_decision.h
@@ -57,6 +57,7 @@ initiation_statuses; std::vector<int> ranker_events; std::string auto_translate_target; + std::string href_translate_source; std::string href_translate_target; std::string predefined_translate_target;
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc index 0aa1182..a1fd14a 100644 --- a/components/user_manager/user_manager_base.cc +++ b/components/user_manager/user_manager_base.cc
@@ -889,8 +889,8 @@ void UserManagerBase::AddUserRecord(User* user) { // Add the user to the front of the user list. ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsersPref); - prefs_users_update->Insert( - 0, std::make_unique<base::Value>(user->GetAccountId().GetUserEmail())); + prefs_users_update->Insert(prefs_users_update->GetList().begin(), + base::Value(user->GetAccountId().GetUserEmail())); users_.insert(users_.begin(), user); }
diff --git a/components/viz/common/display/renderer_settings.h b/components/viz/common/display/renderer_settings.h index b7c9b29..e58b402 100644 --- a/components/viz/common/display/renderer_settings.h +++ b/components/viz/common/display/renderer_settings.h
@@ -36,6 +36,7 @@ int highp_threshold_min = 0; bool auto_resize_output_surface = true; bool requires_alpha_channel = false; + bool disable_render_pass_bypassing = false; int slow_down_compositing_scale_factor = 1;
diff --git a/components/viz/service/display/skia_output_surface.h b/components/viz/service/display/skia_output_surface.h index bec2da2..23d66677 100644 --- a/components/viz/service/display/skia_output_surface.h +++ b/components/viz/service/display/skia_output_surface.h
@@ -116,7 +116,8 @@ const gfx::Size& size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) = 0; + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) = 0; // Finish painting the current frame or current render pass, depends on which // BeginPaint function is called last. This method will schedule a GPU task to @@ -135,7 +136,8 @@ const gfx::Size& size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) = 0; + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) = 0; // Remove cached resources generated by BeginPaintRenderPass and // FinishPaintRenderPass. @@ -147,7 +149,8 @@ virtual void CopyOutput(AggregatedRenderPassId id, const copy_output::RenderPassGeometry& geometry, const gfx::ColorSpace& color_space, - std::unique_ptr<CopyOutputRequest> request) = 0; + std::unique_ptr<CopyOutputRequest> request, + const gpu::Mailbox& mailbox) = 0; // Schedule drawing overlays at next SwapBuffers() call. Waits on // |sync_tokens| for the overlay textures to be ready before scheduling. @@ -179,6 +182,9 @@ // the GPU main thread. virtual gpu::SyncToken Flush() = 0; + // Only used for creating and destroying shared images for render passes + virtual gpu::SharedImageInterface* GetSharedImageInterface() = 0; + #if defined(OS_APPLE) || defined(USE_OZONE) virtual SkCanvas* BeginPaintRenderPassOverlay( const gfx::Size& size,
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 7b8b211..911a6ae 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -43,6 +43,8 @@ #include "components/viz/service/display/resource_fence.h" #include "components/viz/service/display/skia_output_surface.h" #include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/command_buffer/client/shared_image_interface.h" +#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/common/sync_token.h" #include "skia/ext/opacity_filter_canvas.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -900,7 +902,7 @@ RenderPassBacking& backing = iter->second; current_canvas_ = skia_output_surface_->BeginPaintRenderPass( render_pass_id, backing.size, backing.format, backing.generate_mipmap, - backing.color_space.ToSkColorSpace()); + backing.color_space.ToSkColorSpace(), backing.mailbox); } void SkiaRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) { @@ -1391,6 +1393,10 @@ const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectly( const AggregatedRenderPass* pass) { + // If render pass bypassing is disabled for testing + if (settings_->disable_render_pass_bypassing) + return nullptr; + // TODO(michaelludwig) - For now, this only supports opaque, src-over quads // with invertible transforms and simple content (image or color only). // Can only collapse a single tile quad. @@ -2612,7 +2618,8 @@ sk_sp<SkImage> content_image = skia_output_surface_->MakePromiseSkImageFromRenderPass( quad->render_pass_id, backing.size, backing.format, - backing.generate_mipmap, backing.color_space.ToSkColorSpace()); + backing.generate_mipmap, backing.color_space.ToSkColorSpace(), + backing.mailbox); DLOG_IF(ERROR, !content_image) << "MakePromiseSkImageFromRenderPass() failed for render pass"; @@ -2656,13 +2663,18 @@ // Root framebuffer uses id 0 in SkiaOutputSurface. AggregatedRenderPassId render_pass_id; + gpu::Mailbox mailbox; const auto* const render_pass = current_frame()->current_render_pass; if (render_pass != current_frame()->root_render_pass) { render_pass_id = render_pass->id; + auto it = render_pass_backings_.find(render_pass_id); + DCHECK(it != render_pass_backings_.end()); + mailbox = it->second.mailbox; } + skia_output_surface_->CopyOutput(render_pass_id, geometry, CurrentRenderPassColorSpace(), - std::move(request)); + std::move(request), mailbox); } void SkiaRenderer::DidChangeVisibility() { @@ -2741,6 +2753,8 @@ // again. for (size_t i = 0; i < passes_to_delete.size(); ++i) { auto it = render_pass_backings_.find(passes_to_delete[i]); + skia_output_surface_->GetSharedImageInterface()->DestroySharedImage( + gpu::SyncToken(), it->second.mailbox); render_pass_backings_.erase(it); } @@ -2765,10 +2779,18 @@ auto format = color_space.IsHDR() ? RGBA_F16 : PlatformColor::BestSupportedTextureFormat(caps); + uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY; + if (requirements.generate_mipmap) + usage |= gpu::SHARED_IMAGE_USAGE_MIPMAP; + auto mailbox = + skia_output_surface_->GetSharedImageInterface()->CreateSharedImage( + format, requirements.size, color_space, + GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin, + SkAlphaType::kPremul_SkAlphaType, usage, gpu::kNullSurfaceHandle); render_pass_backings_.emplace( render_pass_id, RenderPassBacking({requirements.size, requirements.generate_mipmap, - color_space, format})); + color_space, format, mailbox})); } void SkiaRenderer::FlushOutputSurface() { @@ -2942,7 +2964,8 @@ DCHECK(backing); auto content_image = skia_output_surface_->MakePromiseSkImageFromRenderPass( quad->render_pass_id, backing->size, backing->format, - backing->generate_mipmap, backing->color_space.ToSkColorSpace()); + backing->generate_mipmap, backing->color_space.ToSkColorSpace(), + backing->mailbox); if (!content_image) { DLOG(ERROR) << "MakePromiseSkImageFromRenderPass() failed for render pass";
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index 939d787e..0cf2a14 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -267,6 +267,7 @@ bool generate_mipmap; gfx::ColorSpace color_space; ResourceFormat format; + gpu::Mailbox mailbox; }; base::flat_map<AggregatedRenderPassId, RenderPassBacking> render_pass_backings_;
diff --git a/components/viz/service/display_embedder/image_context_impl.cc b/components/viz/service/display_embedder/image_context_impl.cc index cf445e1..cc47728 100644 --- a/components/viz/service/display_embedder/image_context_impl.cc +++ b/components/viz/service/display_embedder/image_context_impl.cc
@@ -24,26 +24,15 @@ ResourceFormat resource_format, bool maybe_concurrent_reads, const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info, - sk_sp<SkColorSpace> color_space) + sk_sp<SkColorSpace> color_space, + const bool allow_keeping_read_access) : ImageContext(mailbox_holder, size, resource_format, ycbcr_info, color_space), - maybe_concurrent_reads_(maybe_concurrent_reads) {} - -ImageContextImpl::ImageContextImpl(AggregatedRenderPassId render_pass_id, - const gfx::Size& size, - ResourceFormat resource_format, - bool mipmap, - sk_sp<SkColorSpace> color_space) - : ImageContext(gpu::MailboxHolder(), - size, - resource_format, - /*ycbcr_info=*/absl::nullopt, - std::move(color_space)), - render_pass_id_(render_pass_id), - mipmap_(mipmap ? GrMipMapped::kYes : GrMipMapped::kNo) {} + maybe_concurrent_reads_(maybe_concurrent_reads), + allow_keeping_read_access_(allow_keeping_read_access) {} ImageContextImpl::~ImageContextImpl() { if (fallback_context_state_) @@ -267,7 +256,8 @@ // Avoid unnecessary read access churn for representations that // support multiple readers. - if (representation_->SupportsMultipleConcurrentReadAccess()) + if (representation_->SupportsMultipleConcurrentReadAccess() && + allow_keeping_read_access_) return; representation_scoped_read_access_.reset();
diff --git a/components/viz/service/display_embedder/image_context_impl.h b/components/viz/service/display_embedder/image_context_impl.h index 83c5dd6f..2bdc5b8 100644 --- a/components/viz/service/display_embedder/image_context_impl.h +++ b/components/viz/service/display_embedder/image_context_impl.h
@@ -51,17 +51,9 @@ ResourceFormat resource_format, bool maybe_concurrent_reads, const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info, - sk_sp<SkColorSpace> color_space); + sk_sp<SkColorSpace> color_space, + const bool allow_keeping_read_access = true); - // TODO(https://crbug.com/991659): The use of ImageContext for - // SkiaOutputSurfaceImplOnGpu::OffscreenSurface can be factored out. This - // would make ImageContextImpl cleaner and handling of render passes less - // confusing. - ImageContextImpl(AggregatedRenderPassId render_pass_id, - const gfx::Size& size, - ResourceFormat resource_format, - bool mipmap, - sk_sp<SkColorSpace> color_space); ~ImageContextImpl() final; void OnContextLost() final; @@ -69,9 +61,6 @@ // Returns true if there might be concurrent reads to the backing texture. bool maybe_concurrent_reads() const { return maybe_concurrent_reads_; } - AggregatedRenderPassId render_pass_id() const { return render_pass_id_; } - GrMipMapped mipmap() const { return mipmap_; } - void set_promise_image_texture( sk_sp<SkPromiseImageTexture> promise_image_texture) { owned_promise_image_texture_ = std::move(promise_image_texture); @@ -108,10 +97,8 @@ bool BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base, gfx::Size* size); - const AggregatedRenderPassId render_pass_id_; - const GrMipMapped mipmap_ = GrMipMapped::kNo; - const bool maybe_concurrent_reads_ = false; + const bool allow_keeping_read_access_ = true; // Fallback in case we cannot produce a |representation_|. gpu::SharedContextState* fallback_context_state_ = nullptr;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index e6e9100..c4e792b 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -19,6 +19,7 @@ #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_util.h" #include "components/viz/common/resources/resource_format_utils.h" +#include "components/viz/service/display/external_use_client.h" #include "components/viz/service/display/output_surface_client.h" #include "components/viz/service/display/output_surface_frame.h" #include "components/viz/service/display/overlay_candidate.h" @@ -78,12 +79,14 @@ SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint( SkSurfaceCharacterization characterization) - : ScopedPaint(characterization, AggregatedRenderPassId(0)) {} + : ScopedPaint(characterization, AggregatedRenderPassId(0), gpu::Mailbox()) { +} SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint( SkSurfaceCharacterization characterization, - AggregatedRenderPassId render_pass_id) - : render_pass_id_(render_pass_id) { + AggregatedRenderPassId render_pass_id, + gpu::Mailbox mailbox) + : render_pass_id_(render_pass_id), mailbox_(mailbox) { recorder_storage_.emplace(characterization); recorder_ = &recorder_storage_.value(); } @@ -562,7 +565,8 @@ const gfx::Size& surface_size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) { + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Make sure there is no unsubmitted PaintFrame or PaintRenderPass. DCHECK(!current_paint_); @@ -574,7 +578,7 @@ if (!characterization.isValid()) return nullptr; - current_paint_.emplace(characterization, id); + current_paint_.emplace(characterization, id, mailbox); return current_paint_->recorder()->getCanvas(); } @@ -632,7 +636,7 @@ auto task = base::BindOnce( &SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass, - base::Unretained(impl_on_gpu_.get()), current_paint_->render_pass_id(), + base::Unretained(impl_on_gpu_.get()), current_paint_->mailbox(), std::move(ddl), std::move(images_in_current_paint_), resource_sync_tokens_, std::move(on_finished)); EnqueueGpuTask(std::move(task), std::move(resource_sync_tokens_), @@ -672,14 +676,18 @@ const gfx::Size& size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) { + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_paint_); auto& image_context = render_pass_image_cache_[id]; if (!image_context) { - image_context = std::make_unique<ImageContextImpl>(id, size, format, mipmap, - std::move(color_space)); + gpu::MailboxHolder mailbox_holder(mailbox, gpu::SyncToken(), 0); + image_context = std::make_unique<ImageContextImpl>( + mailbox_holder, size, format, /*maybe_concurrent_reads=*/false, + /*ycbcr_info=*/absl::nullopt, std::move(color_space), + /*allow_keeping_read_access=*/false); } if (!image_context->has_image()) { SkColorType color_type = @@ -689,7 +697,8 @@ image_context->SetImage( current_paint_->recorder()->makePromiseTexture( backend_format, image_context->size().width(), - image_context->size().height(), image_context->mipmap(), + image_context->size().height(), + mipmap ? GrMipMapped::kYes : GrMipMapped::kNo, image_context->origin(), color_type, image_context->alpha_type(), image_context->color_space(), Fulfill, /*releaseTextureProc=*/nullptr, image_context.get()), @@ -707,7 +716,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!ids.empty()); - std::vector<std::unique_ptr<ImageContextImpl>> image_contexts; + std::vector<std::unique_ptr<ExternalUseClient::ImageContext>> image_contexts; image_contexts.reserve(ids.size()); for (const auto id : ids) { auto it = render_pass_image_cache_.find(id); @@ -720,26 +729,29 @@ } } - // impl_on_gpu_ is released on the GPU thread by a posted task from - // SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained. - auto callback = - base::BindOnce(&SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource, - base::Unretained(impl_on_gpu_.get()), std::move(ids), - std::move(image_contexts)); - // RemoveRenderPassResources will delete gpu resources and needs MakeCurrent. - EnqueueGpuTask(std::move(callback), {}, /*make_current=*/true, - /*need_framebuffer=*/false); + if (!image_contexts.empty()) { + // impl_on_gpu_ is released on the GPU thread by a posted task from + // SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained. + auto callback = base::BindOnce( + &SkiaOutputSurfaceImplOnGpu::ReleaseImageContexts, + base::Unretained(impl_on_gpu_.get()), std::move(image_contexts)); + // ReleaseImageContexts will delete gpu resources and needs MakeCurrent. + EnqueueGpuTask(std::move(callback), {}, /*make_current=*/true, + /*need_framebuffer=*/false); + } } void SkiaOutputSurfaceImpl::CopyOutput( AggregatedRenderPassId id, const copy_output::RenderPassGeometry& geometry, const gfx::ColorSpace& color_space, - std::unique_ptr<CopyOutputRequest> request) { + std::unique_ptr<CopyOutputRequest> request, + const gpu::Mailbox& mailbox) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - auto callback = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::CopyOutput, - base::Unretained(impl_on_gpu_.get()), id, - geometry, color_space, std::move(request)); + auto callback = + base::BindOnce(&SkiaOutputSurfaceImplOnGpu::CopyOutput, + base::Unretained(impl_on_gpu_.get()), id, geometry, + color_space, std::move(request), mailbox); EnqueueGpuTask(std::move(callback), std::move(resource_sync_tokens_), /*make_current=*/true, /*need_framebuffer=*/!id); } @@ -1178,6 +1190,10 @@ return dependency_->CacheGLSurface(impl_on_gpu_->gl_surface()); } +gpu::SharedImageInterface* SkiaOutputSurfaceImpl::GetSharedImageInterface() { + return display_compositor_controller_->shared_image_interface(); +} + void SkiaOutputSurfaceImpl::AddContextLostObserver( ContextLostObserver* observer) { observers_.AddObserver(observer);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index cca7b58..bd8d8c3 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -115,7 +115,8 @@ const gfx::Size& surface_size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) override; + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) override; void EndPaint(base::OnceClosure on_finished) override; void MakePromiseSkImage(ImageContext* image_context) override; sk_sp<SkImage> MakePromiseSkImageFromRenderPass( @@ -123,7 +124,8 @@ const gfx::Size& size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) override; + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) override; void RemoveRenderPassResource( std::vector<AggregatedRenderPassId> ids) override; @@ -134,10 +136,12 @@ void CopyOutput(AggregatedRenderPassId id, const copy_output::RenderPassGeometry& geometry, const gfx::ColorSpace& color_space, - std::unique_ptr<CopyOutputRequest> request) override; + std::unique_ptr<CopyOutputRequest> request, + const gpu::Mailbox& mailbox) override; void AddContextLostObserver(ContextLostObserver* observer) override; void RemoveContextLostObserver(ContextLostObserver* observer) override; void PreserveChildSurfaceControls() override; + gpu::SharedImageInterface* GetSharedImageInterface() override; gpu::SyncToken Flush() override; #if defined(OS_APPLE) || defined(USE_OZONE) @@ -240,11 +244,13 @@ explicit ScopedPaint(SkDeferredDisplayListRecorder* root_recorder); explicit ScopedPaint(SkSurfaceCharacterization characterization); ScopedPaint(SkSurfaceCharacterization characterization, - AggregatedRenderPassId render_pass_id); + AggregatedRenderPassId render_pass_id, + gpu::Mailbox mailbox); ~ScopedPaint(); SkDeferredDisplayListRecorder* recorder() { return recorder_; } AggregatedRenderPassId render_pass_id() { return render_pass_id_; } + gpu::Mailbox mailbox() { return mailbox_; } private: // This is recorder being used for current paint @@ -253,6 +259,7 @@ // it's stored here absl::optional<SkDeferredDisplayListRecorder> recorder_storage_; const AggregatedRenderPassId render_pass_id_; + const gpu::Mailbox mailbox_; }; // Tracks damage across at most `number_of_buffers`. Note this implementation
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 8e9038ab..64138557 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -3,11 +3,11 @@ // found in the LICENSE file. #include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h" +#include <memory> #include "base/atomic_sequence_num.h" #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/containers/cxx20_erase.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" @@ -41,6 +41,7 @@ #include "gpu/ipc/common/gpu_surface_lookup.h" #include "gpu/vulkan/buildflags.h" #include "skia/buildflags.h" +#include "skia/ext/legacy_display_globals.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/libyuv/include/libyuv/planar_functions.h" #include "third_party/skia/include/core/SkDeferredDisplayList.h" @@ -444,44 +445,6 @@ } // namespace -// Offscreen surfaces for render passes. It can only be accessed on GPU -// thread. -class SkiaOutputSurfaceImplOnGpu::OffscreenSurface { - public: - OffscreenSurface() = default; - OffscreenSurface(const OffscreenSurface& offscreen_surface) = delete; - OffscreenSurface(OffscreenSurface&& offscreen_surface) = default; - OffscreenSurface& operator=(const OffscreenSurface& offscreen_surface) = - delete; - OffscreenSurface& operator=(OffscreenSurface&& offscreen_surface) = default; - ~OffscreenSurface() = default; - - SkSurface* surface() { return surface_.get(); } - void set_surface(sk_sp<SkSurface> surface) { - surface_ = std::move(surface); - promise_texture_ = {}; - } - - SkPromiseImageTexture* fulfill() { - DCHECK(surface_); - if (!promise_texture_) { - promise_texture_ = - SkPromiseImageTexture::Make(surface_->getBackendTexture( - SkSurface::kFlushRead_BackendHandleAccess)); - } - return promise_texture_.get(); - } - - sk_sp<SkSurface> TakeSurface() { - promise_texture_ = {}; - return std::move(surface_); - } - - private: - sk_sp<SkSurface> surface_; - sk_sp<SkPromiseImageTexture> promise_texture_; -}; - SkiaOutputSurfaceImplOnGpu::ReleaseCurrent::ReleaseCurrent( scoped_refptr<gl::GLSurface> gl_surface, scoped_refptr<gpu::SharedContextState> context_state) @@ -709,7 +672,7 @@ if (!begin_semaphores.empty()) { auto result = scoped_output_device_paint_->Wait( begin_semaphores.size(), begin_semaphores.data(), - /*deleteSemaphoresAfterWait=*/false); + /*delete_semaphores_after_wait=*/false); DCHECK(result); } @@ -789,7 +752,7 @@ } void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass( - AggregatedRenderPassId id, + const gpu::Mailbox& mailbox, sk_sp<SkDeferredDisplayList> ddl, std::vector<ImageContextImpl*> image_contexts, std::vector<gpu::SyncToken> sync_tokens, @@ -806,30 +769,41 @@ return; } - auto& offscreen = offscreen_surfaces_[id]; - if (!offscreen.surface()) { - offscreen.set_surface(SkSurface::MakeRenderTarget( - gr_context(), ddl->characterization(), SkBudgeted::kNo)); - DCHECK(offscreen.surface()); + auto backing_representation = + shared_image_representation_factory_->ProduceSkia(mailbox, + context_state_.get()); + DCHECK(backing_representation); + + std::vector<GrBackendSemaphore> begin_semaphores; + std::vector<GrBackendSemaphore> end_semaphores; + auto scoped_access = backing_representation->BeginScopedWriteAccess( + /*final_msaa_count=*/0, ddl->characterization().surfaceProps(), + &begin_semaphores, &end_semaphores, + gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes); + if (!scoped_access) { + MarkContextLost(CONTEXT_LOST_UNKNOWN); + return; } + SkSurface* surface = scoped_access->surface(); + DCHECK(surface); + { absl::optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use; if (dependency_->GetGrShaderCache()) { cache_use.emplace(dependency_->GetGrShaderCache(), gpu::kDisplayCompositorClientId); } - std::vector<GrBackendSemaphore> begin_semaphores; - std::vector<GrBackendSemaphore> end_semaphores; promise_image_access_helper_.BeginAccess( std::move(image_contexts), &begin_semaphores, &end_semaphores); if (!begin_semaphores.empty()) { - auto result = offscreen.surface()->wait( - begin_semaphores.size(), begin_semaphores.data(), - /*deleteSemaphoresAfterWait=*/false); + auto result = + surface->wait(begin_semaphores.size(), begin_semaphores.data(), + /*deleteSemaphoresAfterWait=*/false); DCHECK(result); } - offscreen.surface()->draw(ddl); + surface->draw(ddl); + backing_representation->SetCleared(); destroy_after_swap_.emplace_back(std::move(ddl)); GrFlushInfo flush_info = { @@ -840,7 +814,7 @@ &flush_info); if (on_finished) gpu::AddCleanupTaskForSkiaFlush(std::move(on_finished), &flush_info); - auto result = offscreen.surface()->flush(flush_info); + auto result = surface->flush(flush_info); if (result != GrSemaphoresSubmitted::kYes && !(begin_semaphores.empty() && end_semaphores.empty())) { // TODO(penghuang): handle vulkan device lost. @@ -855,26 +829,6 @@ } } -void SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource( - std::vector<AggregatedRenderPassId> ids, - std::vector<std::unique_ptr<ImageContextImpl>> image_contexts) { - TRACE_EVENT0("viz", "SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource"); - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(!ids.empty()); - - for (AggregatedRenderPassId id : ids) { - // It's possible that |offscreen_surfaces_| won't contain an entry for the - // render pass if draw failed early. - auto it = offscreen_surfaces_.find(id); - if (it != offscreen_surfaces_.end()) { - DeleteSkSurface(context_state_.get(), it->second.TakeSurface()); - offscreen_surfaces_.erase(it); - } - } - - // |image_contexts| will go out of scope and be destroyed now. -} - static void PostTaskFromMainToImplThread( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, ReleaseCallback callback, @@ -888,7 +842,8 @@ AggregatedRenderPassId id, copy_output::RenderPassGeometry geometry, const gfx::ColorSpace& color_space, - std::unique_ptr<CopyOutputRequest> request) { + std::unique_ptr<CopyOutputRequest> request, + const gpu::Mailbox& mailbox) { TRACE_EVENT0("viz", "SkiaOutputSurfaceImplOnGpu::CopyOutput"); // TODO(crbug.com/898595): Do this on the GPU instead of CPU with Vulkan. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -899,11 +854,33 @@ bool from_framebuffer = !id; DCHECK(scoped_output_device_paint_ || !from_framebuffer); - DCHECK(from_framebuffer || - offscreen_surfaces_.find(id) != offscreen_surfaces_.end()); - SkSurface* surface = from_framebuffer - ? scoped_output_device_paint_->sk_surface() - : offscreen_surfaces_[id].surface(); + SkSurface* surface; + std::unique_ptr<gpu::SharedImageRepresentationSkia> backing_representation; + std::unique_ptr<gpu::SharedImageRepresentationSkia::ScopedWriteAccess> + scoped_access; + std::vector<GrBackendSemaphore> begin_semaphores; + std::vector<GrBackendSemaphore> end_semaphores; + if (from_framebuffer) { + surface = scoped_output_device_paint_->sk_surface(); + } else { + backing_representation = shared_image_representation_factory_->ProduceSkia( + mailbox, context_state_.get()); + DCHECK(backing_representation); + + // TODO(crbug.com/1226672): Use BeginScopedReadAccess instead + scoped_access = backing_representation->BeginScopedWriteAccess( + /*final_msaa_count=*/0, skia::LegacyDisplayGlobals::GetSkSurfaceProps(), + &begin_semaphores, &end_semaphores, + gpu::SharedImageRepresentation::AllowUnclearedAccess::kNo); + surface = scoped_access->surface(); + if (!begin_semaphores.empty()) { + auto result = + surface->wait(begin_semaphores.size(), begin_semaphores.data(), + /*deleteSemaphoresAfterWait=*/false); + DCHECK(result); + } + } + // Do not support reading back from vulkan secondary command buffer. if (!surface) return; @@ -1080,6 +1057,23 @@ } else { NOTREACHED(); } + + if (!end_semaphores.empty()) { + GrFlushInfo flush_info; + flush_info.fNumSemaphores = end_semaphores.size(); + flush_info.fSignalSemaphores = end_semaphores.data(); + gpu::AddVulkanCleanupTaskForSkiaFlush(vulkan_context_provider_, + &flush_info); + auto flush_result = + surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flush_info); + if (flush_result != GrSemaphoresSubmitted::kYes && + !(begin_semaphores.empty() && end_semaphores.empty())) { + // TODO(penghuang): handle vulkan device lost. + DLOG(ERROR) << "surface->flush() failed."; + return; + } + } + ScheduleCheckReadbackCompletion(); } @@ -1103,32 +1097,19 @@ for (auto* context : image_contexts) { // Prepare for accessing render pass. - if (context->render_pass_id()) { - // We don't cache promise image for render pass, so the it should always - // be nullptr. - auto it = offscreen_surfaces_.find(context->render_pass_id()); - DCHECK(it != offscreen_surfaces_.end()); - context->set_promise_image_texture(sk_ref_sp(it->second.fulfill())); - if (!context->promise_image_texture()) { - DLOG(ERROR) << "Failed to fulfill the promise texture created from " - "CompositorRenderPassId:" - << context->render_pass_id(); - } - } else { - context->BeginAccessIfNecessary( - context_state_.get(), shared_image_representation_factory_.get(), - dependency_->GetMailboxManager(), begin_semaphores, end_semaphores); - if (context->end_access_state()) - image_contexts_with_end_access_state_.emplace(context); + context->BeginAccessIfNecessary( + context_state_.get(), shared_image_representation_factory_.get(), + dependency_->GetMailboxManager(), begin_semaphores, end_semaphores); + if (context->end_access_state()) + image_contexts_with_end_access_state_.emplace(context); - // Texture parameters can be modified by concurrent reads so reset them - // before compositing from the texture. See https://crbug.com/1092080. - if (is_gl && context->maybe_concurrent_reads()) { - auto* promise_texture = context->promise_image_texture(); - if (promise_texture) { - GrBackendTexture backend_texture = promise_texture->backendTexture(); - backend_texture.glTextureParametersModified(); - } + // Texture parameters can be modified by concurrent reads so reset them + // before compositing from the texture. See https://crbug.com/1092080. + if (is_gl && context->maybe_concurrent_reads()) { + auto* promise_texture = context->promise_image_texture(); + if (promise_texture) { + GrBackendTexture backend_texture = promise_texture->backendTexture(); + backend_texture.glTextureParametersModified(); } } }
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index 64878ae..2eea042 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -147,7 +147,7 @@ void SwapBuffersSkipped(); void EnsureBackbuffer() { output_device_->EnsureBackbuffer(); } void DiscardBackbuffer() { output_device_->DiscardBackbuffer(); } - void FinishPaintRenderPass(AggregatedRenderPassId id, + void FinishPaintRenderPass(const gpu::Mailbox& mailbox, sk_sp<SkDeferredDisplayList> ddl, std::vector<ImageContextImpl*> image_contexts, std::vector<gpu::SyncToken> sync_tokens, @@ -160,7 +160,8 @@ void CopyOutput(AggregatedRenderPassId id, copy_output::RenderPassGeometry geometry, const gfx::ColorSpace& color_space, - std::unique_ptr<CopyOutputRequest> request); + std::unique_ptr<CopyOutputRequest> request, + const gpu::Mailbox& mailbox); void BeginAccessImages(const std::vector<ImageContextImpl*>& image_contexts, std::vector<GrBackendSemaphore>* begin_semaphores, @@ -228,7 +229,6 @@ pending_receiver); private: - class OffscreenSurface; class DisplayContext; bool Initialize(); @@ -355,8 +355,6 @@ absl::optional<OverlayProcessorInterface::OutputSurfaceOverlayPlane> output_surface_plane_; - base::flat_map<AggregatedRenderPassId, OffscreenSurface> offscreen_surfaces_; - // Micro-optimization to get to issuing GPU SwapBuffers as soon as possible. std::vector<sk_sp<SkDeferredDisplayList>> destroy_after_swap_;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc index 1801a6d..4947f51 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc
@@ -164,7 +164,7 @@ geometry.readback_offset = gfx::Vector2d(0, 0); output_surface_->CopyOutput(AggregatedRenderPassId{0}, geometry, color_space, - std::move(request)); + std::move(request), gpu::Mailbox()); output_surface_->SwapBuffersSkipped(kSurfaceRect); output_surface_->Flush(); BlockMainThread(); @@ -231,7 +231,7 @@ PaintRootRenderPass(kSurfaceRect, base::DoNothing::Once()); output_surface_->CopyOutput(AggregatedRenderPassId{0}, geometry, color_space, - std::move(request)); + std::move(request), gpu::Mailbox()); output_surface_->SwapBuffersSkipped(kSurfaceRect); output_surface_->Flush(); run_loop.Run(); @@ -270,7 +270,7 @@ PaintRootRenderPass(kSurfaceRect, base::DoNothing::Once()); output_surface_->CopyOutput(AggregatedRenderPassId{0}, geometry, color_space, - std::move(request)); + std::move(request), gpu::Mailbox()); output_surface_->SwapBuffersSkipped(kSurfaceRect); output_surface_->Flush(); run_loop.Run();
diff --git a/components/viz/test/fake_skia_output_surface.cc b/components/viz/test/fake_skia_output_surface.cc index 813831a7..2af359c 100644 --- a/components/viz/test/fake_skia_output_surface.cc +++ b/components/viz/test/fake_skia_output_surface.cc
@@ -193,7 +193,8 @@ const gfx::Size& surface_size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) { + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Make sure there is no unsubmitted PaintFrame or PaintRenderPass. DCHECK_EQ(current_render_pass_id_, AggregatedRenderPassId{0u}); @@ -225,7 +226,8 @@ const gfx::Size& size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) { + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); auto it = sk_surfaces_.find(id); @@ -249,7 +251,8 @@ AggregatedRenderPassId id, const copy_output::RenderPassGeometry& geometry, const gfx::ColorSpace& color_space, - std::unique_ptr<CopyOutputRequest> request) { + std::unique_ptr<CopyOutputRequest> request, + const gpu::Mailbox& mailbox) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(sk_surfaces_.find(id) != sk_surfaces_.end()); @@ -305,6 +308,10 @@ geometry.result_bounds, std::move(bitmap))); } +gpu::SharedImageInterface* FakeSkiaOutputSurface::GetSharedImageInterface() { + return context_provider_->SharedImageInterface(); +} + void FakeSkiaOutputSurface::AddContextLostObserver( ContextLostObserver* observer) { NOTIMPLEMENTED();
diff --git a/components/viz/test/fake_skia_output_surface.h b/components/viz/test/fake_skia_output_surface.h index 18f6605d..68e3ab00 100644 --- a/components/viz/test/fake_skia_output_surface.h +++ b/components/viz/test/fake_skia_output_surface.h
@@ -79,7 +79,8 @@ const gfx::Size& surface_size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) override; + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) override; void EndPaint(base::OnceClosure on_finished) override; void MakePromiseSkImage(ImageContext* image_context) override; sk_sp<SkImage> MakePromiseSkImageFromRenderPass( @@ -87,7 +88,8 @@ const gfx::Size& size, ResourceFormat format, bool mipmap, - sk_sp<SkColorSpace> color_space) override; + sk_sp<SkColorSpace> color_space, + const gpu::Mailbox& mailbox) override; void RemoveRenderPassResource( std::vector<AggregatedRenderPassId> ids) override; void ScheduleOverlays(OverlayList overlays, @@ -99,9 +101,11 @@ void CopyOutput(AggregatedRenderPassId id, const copy_output::RenderPassGeometry& geometry, const gfx::ColorSpace& color_space, - std::unique_ptr<CopyOutputRequest> request) override; + std::unique_ptr<CopyOutputRequest> request, + const gpu::Mailbox& mailbox) override; void AddContextLostObserver(ContextLostObserver* observer) override; void RemoveContextLostObserver(ContextLostObserver* observer) override; + gpu::SharedImageInterface* GetSharedImageInterface() override; gpu::SyncToken Flush() override; #if defined(OS_APPLE) || defined(USE_OZONE) SkCanvas* BeginPaintRenderPassOverlay(
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc index 9fa38e6..7fb29527 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -800,8 +800,8 @@ break; } case base::Value::Type::DOUBLE: { - double double_value = 0.0; - value->GetAsDouble(&double_value); + double double_value; + double_value = value->GetIfDouble().value_or(0.0); WriteAttribute( false, base::StringPrintf("%s=%.2f", attribute_name, double_value), &line);
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index a1a08ea..0940758 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -795,8 +795,16 @@ RunAriaTest(FILE_PATH_LITERAL("aria-hidden-labelled-by.html")); } +// TODO(https://crbug.com/1227569): This test is flaky on linux. +#if defined(OS_LINUX) +#define MAYBE_AccessibilityAriaHiddenIframeBody \ + DISABLED_AccessibilityAriaHiddenIframeBody +#else +#define MAYBE_AccessibilityAriaHiddenIframeBody \ + AccessibilityAriaHiddenIframeBody +#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - AccessibilityAriaHiddenIframeBody) { + MAYBE_AccessibilityAriaHiddenIframeBody) { RunAriaTest(FILE_PATH_LITERAL("aria-hidden-iframe-body.html")); }
diff --git a/content/browser/accessibility/hit_testing_browsertest.cc b/content/browser/accessibility/hit_testing_browsertest.cc index a6ad6dfd..2257051 100644 --- a/content/browser/accessibility/hit_testing_browsertest.cc +++ b/content/browser/accessibility/hit_testing_browsertest.cc
@@ -344,8 +344,14 @@ ::testing::Combine(::testing::Values(1, 2), ::testing::Bool()), AccessibilityHitTestingBrowserTest::TestPassToString()); +#if defined(THREAD_SANITIZER) +// TODO(https://crbug.com/1224979): Times out flakily on TSAN builds. +#define MAYBE_CachingAsyncHitTest DISABLED_CachingAsyncHitTest +#else +#define MAYBE_CachingAsyncHitTest CachingAsyncHitTest +#endif IN_PROC_BROWSER_TEST_P(AccessibilityHitTestingBrowserTest, - CachingAsyncHitTest) { + MAYBE_CachingAsyncHitTest) { ASSERT_TRUE(embedded_test_server()->Start()); EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); @@ -380,7 +386,13 @@ } } -IN_PROC_BROWSER_TEST_P(AccessibilityHitTestingBrowserTest, HitTest) { +#if defined(THREAD_SANITIZER) +// TODO(https://crbug.com/1224938): Times out flakily on TSAN builds. +#define MAYBE_HitTest DISABLED_HitTest +#else +#define MAYBE_HitTest HitTest +#endif +IN_PROC_BROWSER_TEST_P(AccessibilityHitTestingBrowserTest, MAYBE_HitTest) { ASSERT_TRUE(embedded_test_server()->Start()); EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); @@ -635,8 +647,14 @@ } } +#if defined(THREAD_SANITIZER) +// TODO(https://crbug.com/1224978): Times out flakily on TSAN builds. +#define MAYBE_HitTest_WithPinchZoom DISABLED_HitTest_WithPinchZoom +#else +#define MAYBE_HitTest_WithPinchZoom HitTest_WithPinchZoom +#endif IN_PROC_BROWSER_TEST_P(AccessibilityHitTestingBrowserTest, - HitTest_WithPinchZoom) { + MAYBE_HitTest_WithPinchZoom) { ASSERT_TRUE(embedded_test_server()->Start()); EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
diff --git a/content/browser/android/content_feature_list.cc b/content/browser/android/content_feature_list.cc index 4299769..8943350 100644 --- a/content/browser/android/content_feature_list.cc +++ b/content/browser/android/content_feature_list.cc
@@ -20,6 +20,8 @@ // this array may either refer to features defined in the header of this file or // in other locations in the code base (e.g. content_features.h). const base::Feature* const kFeaturesExposedToJava[] = { + &features::kAccessibilityPageZoom, + &features::kAccessibilityPageZoomUpdatedUI, &features::kBackgroundMediaRendererHasModerateBinding, &features::kBindingManagementWaiveCpu, &features::kExperimentalAccessibilityLabels,
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index da775d1e..180d52c0 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -5207,8 +5207,7 @@ // 1) Navigate to. EXPECT_TRUE(NavigateToURL(shell(), test_case.url)); - RenderFrameHostImpl* rfh = current_frame_host(); - RenderFrameDeletedObserver delete_observer(rfh); + RenderFrameHostImplWrapper rfh(current_frame_host()); // 2) Navigate away. hostname[0]++; @@ -5216,22 +5215,22 @@ EXPECT_TRUE(NavigateToURL(shell(), reset_url)); if (test_case.expectation == STORED) { - EXPECT_FALSE(delete_observer.deleted()); + EXPECT_FALSE(rfh.IsRenderFrameDeleted()); EXPECT_TRUE(rfh->IsInBackForwardCache()); continue; } - // On Android, navigations to about:blank keeps the same RenderFrameHost. - // Obviously, it can't enter the BackForwardCache, because it is still used - // to display the current document. - if (test_case.url == blank_url && !AreStrictSiteInstancesEnabled()) { - EXPECT_FALSE(delete_observer.deleted()); + if (rfh.get() == current_frame_host()) { + // If the RenderFrameHost is reused, it won't be deleted, so don't wait + // for deletion. Just check that it's not saved in the back-forward cache. + EXPECT_FALSE(rfh.IsRenderFrameDeleted()); EXPECT_FALSE(rfh->IsInBackForwardCache()); - EXPECT_EQ(rfh, current_frame_host()); continue; } - delete_observer.WaitUntilDeleted(); + // When the RenderFrameHost is not reused and it's not stored in the + // back-forward cache, it will eventually be deleted. + rfh.WaitUntilRenderFrameDeleted(); } } @@ -10768,9 +10767,9 @@ {}, {ShouldSwapBrowsingInstance::kNo_DoesNotHaveSite}, {}, FROM_HERE); } -// Check that the page is not cached when navigating to about:blank. +// Check that an eligible page is cached when navigating to about:blank. IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, - NavigatingToAboutBlankPreventsCaching) { + NavigatingToAboutBlankDoesNotPreventCaching) { ASSERT_TRUE(embedded_test_server()->Start()); // 1) Navigate to a.com, @@ -10785,16 +10784,7 @@ web_contents()->GetController().GoBack(); EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); - // about:blank doesn't have a scheme http or https, and then this navigation - // doesn't swapt the browsing instance. - ExpectNotRestored( - { - BackForwardCacheMetrics::NotRestoredReason:: - kBrowsingInstanceNotSwapped, - }, - {}, - {ShouldSwapBrowsingInstance::kNo_DestinationURLSchemeIsNotHTTPOrHTTPS}, - {}, FROM_HERE); + ExpectRestored(FROM_HERE); } // Check that browsing instances are not swapped when a navigation redirects
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 4e7094c9..7c211b13 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -274,12 +274,7 @@ void BindConversionInternalsHandler( content::RenderFrameHost* host, mojo::PendingReceiver<::mojom::ConversionInternalsHandler> receiver) { - auto* contents = WebContents::FromRenderFrameHost(host); - DCHECK_EQ(contents->GetLastCommittedURL().host_piece(), - kChromeUIConversionInternalsHost); - DCHECK(contents->GetLastCommittedURL().SchemeIs(kChromeUIScheme)); - - content::WebUI* web_ui = contents->GetWebUI(); + content::WebUI* web_ui = host->GetWebUI(); // Performs a safe downcast to the concrete ConversionInternalsUI subclass. ConversionInternalsUI* conversion_internals_ui = @@ -295,17 +290,17 @@ return; } + DCHECK_EQ(host->GetLastCommittedURL().host_piece(), + kChromeUIConversionInternalsHost); + DCHECK(host->GetLastCommittedURL().SchemeIs(kChromeUIScheme)); + conversion_internals_ui->BindInterface(std::move(receiver)); } void BindProcessInternalsHandler( content::RenderFrameHost* host, mojo::PendingReceiver<::mojom::ProcessInternalsHandler> receiver) { - auto* contents = WebContents::FromRenderFrameHost(host); - DCHECK_EQ(contents->GetLastCommittedURL().host_piece(), - kChromeUIProcessInternalsHost); - - content::WebUI* web_ui = contents->GetWebUI(); + content::WebUI* web_ui = host->GetWebUI(); // Performs a safe downcast to the concrete ProcessInternalsUI subclass. ProcessInternalsUI* process_internals_ui = @@ -320,6 +315,10 @@ return; } + DCHECK_EQ(host->GetLastCommittedURL().host_piece(), + kChromeUIProcessInternalsHost); + DCHECK(host->GetLastCommittedURL().SchemeIs(kChromeUIScheme)); + process_internals_ui->BindProcessInternalsHandler(std::move(receiver), host); } @@ -601,8 +600,10 @@ map->Add<blink::mojom::FileSystemManager>(base::BindRepeating( &RenderFrameHostImpl::GetFileSystemManager, base::Unretained(host))); - map->Add<blink::mojom::FontAccessManager>(base::BindRepeating( - &RenderFrameHostImpl::GetFontAccessManager, base::Unretained(host))); + if (base::FeatureList::IsEnabled(blink::features::kFontAccess)) { + map->Add<blink::mojom::FontAccessManager>(base::BindRepeating( + &RenderFrameHostImpl::GetFontAccessManager, base::Unretained(host))); + } map->Add<device::mojom::GamepadHapticsManager>( base::BindRepeating(&device::GamepadHapticsManager::Create));
diff --git a/content/browser/conversions/conversion_storage_sql.cc b/content/browser/conversions/conversion_storage_sql.cc index f8c3309..a981427 100644 --- a/content/browser/conversions/conversion_storage_sql.cc +++ b/content/browser/conversions/conversion_storage_sql.cc
@@ -276,7 +276,6 @@ int num_conversions, int64_t conversion_priority, base::Time report_time) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(impression.impression_id().has_value()); DCHECK_GE(num_conversions, 0); @@ -536,8 +535,6 @@ bool ConversionStorageSql::StoreConversionReport(const ConversionReport& report, int64_t impression_id, int64_t priority) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const char kStoreConversionSql[] = "INSERT INTO conversions " "(impression_id, conversion_data, conversion_time, report_time, " @@ -1004,7 +1001,6 @@ } bool ConversionStorageSql::LazyInit(DbCreationPolicy creation_policy) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!db_init_status_) { if (g_run_in_memory_) { db_init_status_ = DbStatus::kDeferringCreation; @@ -1110,8 +1106,6 @@ } bool ConversionStorageSql::CreateSchema() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::ThreadTicks start_timestamp = base::ThreadTicks::Now(); // TODO(johnidel, csharrison): Many impressions will share a target origin and // a reporting origin, so it makes sense to make a "shared string" table for @@ -1276,8 +1270,6 @@ bool ConversionStorageSql::EnsureCapacityForPendingDestinationLimit( const StorableImpression& impression) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(apaseltiner): Add metrics for how this behaves so we can see how often // sites are hitting the limit.
diff --git a/content/browser/conversions/conversion_storage_sql.h b/content/browser/conversions/conversion_storage_sql.h index b99879c..5701697 100644 --- a/content/browser/conversions/conversion_storage_sql.h +++ b/content/browser/conversions/conversion_storage_sql.h
@@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "base/thread_annotations.h" #include "base/time/clock.h" #include "content/browser/conversions/conversion_report.h" #include "content/browser/conversions/conversion_storage.h" @@ -89,11 +90,14 @@ base::RepeatingCallback<bool(const url::Origin&)> filter) override; // Variants of ClearData that assume all Origins match the filter. - void ClearAllDataInRange(base::Time delete_begin, base::Time delete_end); - void ClearAllDataAllTime(); + void ClearAllDataInRange(base::Time delete_begin, base::Time delete_end) + VALID_CONTEXT_REQUIRED(sequence_checker_); + void ClearAllDataAllTime() VALID_CONTEXT_REQUIRED(sequence_checker_); - bool HasCapacityForStoringImpression(const std::string& serialized_origin); - int GetCapacityForStoringConversion(const std::string& serialized_origin); + bool HasCapacityForStoringImpression(const std::string& serialized_origin) + VALID_CONTEXT_REQUIRED(sequence_checker_); + int GetCapacityForStoringConversion(const std::string& serialized_origin) + VALID_CONTEXT_REQUIRED(sequence_checker_); enum class MaybeReplaceLowerPriorityReportResult { kError, @@ -105,27 +109,32 @@ const StorableImpression& impression, int num_conversions, int64_t conversion_priority, - base::Time report_time); + base::Time report_time) VALID_CONTEXT_REQUIRED(sequence_checker_); // When storing an event-source impression, deletes active event-source // impressions in order by |impression_time| until there are sufficiently few // unique conversion destinations for the same |impression_site|. bool EnsureCapacityForPendingDestinationLimit( - const StorableImpression& impression); + const StorableImpression& impression) + VALID_CONTEXT_REQUIRED(sequence_checker_); // Stores |report| in the database, but uses |impression_id| rather than // |ConversionReport::impression::impression_id()|, which may be null. bool StoreConversionReport(const ConversionReport& report, int64_t impression_id, - int64_t priority); + int64_t priority) + VALID_CONTEXT_REQUIRED(sequence_checker_); // Initializes the database if necessary, and returns whether the database is // open. |should_create| indicates whether the database should be created if // it is not already. - bool LazyInit(DbCreationPolicy creation_policy); - bool InitializeSchema(bool db_empty); - bool CreateSchema(); - void HandleInitializationFailure(const InitStatus status); + bool LazyInit(DbCreationPolicy creation_policy) + VALID_CONTEXT_REQUIRED(sequence_checker_); + bool InitializeSchema(bool db_empty) + VALID_CONTEXT_REQUIRED(sequence_checker_); + bool CreateSchema() VALID_CONTEXT_REQUIRED(sequence_checker_); + void HandleInitializationFailure(const InitStatus status) + VALID_CONTEXT_REQUIRED(sequence_checker_); void DatabaseErrorCallback(int extended_error, sql::Statement* stmt); @@ -140,24 +149,25 @@ // at for lazy initialization, and used as a signal for if the database is // closed. This is initialized in the first call to LazyInit() to avoid doing // additional work in the constructor, see https://crbug.com/1121307. - absl::optional<DbStatus> db_init_status_; + absl::optional<DbStatus> db_init_status_ + GUARDED_BY_CONTEXT(sequence_checker_); // May be null if the database: // - could not be opened // - table/index initialization failed - std::unique_ptr<sql::Database> db_; + std::unique_ptr<sql::Database> db_ GUARDED_BY_CONTEXT(sequence_checker_); // Table which stores timestamps of sent reports, and checks if new reports // can be created given API rate limits. The underlying table is created in // |db_|, but only accessed within |RateLimitTable|. - RateLimitTable rate_limit_table_; + RateLimitTable rate_limit_table_ GUARDED_BY_CONTEXT(sequence_checker_); - sql::MetaTable meta_table_; + sql::MetaTable meta_table_ GUARDED_BY_CONTEXT(sequence_checker_); // Must outlive |this|. const base::Clock* clock_; - std::unique_ptr<Delegate> delegate_; + std::unique_ptr<Delegate> delegate_ GUARDED_BY_CONTEXT(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<ConversionStorageSql> weak_factory_;
diff --git a/content/browser/conversions/rate_limit_table.cc b/content/browser/conversions/rate_limit_table.cc index 58958d7..8bf95c96 100644 --- a/content/browser/conversions/rate_limit_table.cc +++ b/content/browser/conversions/rate_limit_table.cc
@@ -213,8 +213,6 @@ } int RateLimitTable::DeleteExpiredRateLimits(sql::Database* db) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Time timestamp = clock_->Now() - delegate_->GetRateLimits().time_window; const char kDeleteExpiredRateLimits[] =
diff --git a/content/browser/conversions/rate_limit_table.h b/content/browser/conversions/rate_limit_table.h index 09c83aa..71bd2cd 100644 --- a/content/browser/conversions/rate_limit_table.h +++ b/content/browser/conversions/rate_limit_table.h
@@ -8,6 +8,7 @@ #include "base/callback.h" #include "base/containers/flat_set.h" #include "base/sequence_checker.h" +#include "base/thread_annotations.h" #include "base/time/time.h" #include "content/browser/conversions/conversion_report.h" #include "content/browser/conversions/conversion_storage.h" @@ -69,17 +70,19 @@ // Deletes data in the table older than the window determined by |clock_| and // |delegate_->GetRateLimits()|. // Returns the number of deleted rows. - int DeleteExpiredRateLimits(sql::Database* db); + int DeleteExpiredRateLimits(sql::Database* db) + VALID_CONTEXT_REQUIRED(sequence_checker_); // Must outlive |this|. - const ConversionStorage::Delegate* delegate_; + const ConversionStorage::Delegate* delegate_ + GUARDED_BY_CONTEXT(sequence_checker_); // Must outlive |this|. const base::Clock* clock_; // Time at which `DeleteExpiredRateLimits()` was last called. Initialized to // the NULL time. - base::Time last_cleared_; + base::Time last_cleared_ GUARDED_BY_CONTEXT(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_); };
diff --git a/content/browser/font_access/font_access_manager_impl_browsertest.cc b/content/browser/font_access/font_access_manager_impl_browsertest.cc index 88cc67f..218bfc2 100644 --- a/content/browser/font_access/font_access_manager_impl_browsertest.cc +++ b/content/browser/font_access/font_access_manager_impl_browsertest.cc
@@ -78,8 +78,9 @@ #if defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL) +// Disabled test: https://crbug.com/1224238 IN_PROC_BROWSER_TEST_F(FontAccessManagerImplBrowserBase, - RendererInterfaceIsBound) { + DISABLED_RendererInterfaceIsBound) { ASSERT_TRUE(NavigateToURL(shell(), GetTestUrl(nullptr, "simple_page.html"))); // This tests that the renderer interface is bound even if the kFontAccess // feature flag is disabled.
diff --git a/content/browser/loader/cached_navigation_url_loader.cc b/content/browser/loader/cached_navigation_url_loader.cc index 08e0ed32..a57a95c 100644 --- a/content/browser/loader/cached_navigation_url_loader.cc +++ b/content/browser/loader/cached_navigation_url_loader.cc
@@ -24,17 +24,7 @@ network::mojom::URLResponseHeadPtr cached_response_head) : request_info_(std::move(request_info)), delegate_(delegate), - cached_response_head_(std::move(cached_response_head)) { - // Respond with a fake response. We use PostTask here to mimic the flow of - // a normal navigation. - // - // Normal navigations never call OnResponseStarted on the same message loop - // iteration that the NavigationURLLoader is created, because they have to - // make a network request. - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&CachedNavigationURLLoader::OnResponseStarted, - weak_factory_.GetWeakPtr())); -} + cached_response_head_(std::move(cached_response_head)) {} void CachedNavigationURLLoader::OnResponseStarted() { GlobalRequestID global_id = GlobalRequestID::MakeBrowserInitiated(); @@ -58,6 +48,18 @@ std::move(request_info), delegate, std::move(cached_response_head)); } +void CachedNavigationURLLoader::Start() { + // Respond with a fake response. We use PostTask here to mimic the flow of + // a normal navigation. + // + // Normal navigations never call OnResponseStarted on the same message loop + // iteration that the NavigationURLLoader is created, because they have to + // make a network request. + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CachedNavigationURLLoader::OnResponseStarted, + weak_factory_.GetWeakPtr())); +} + void CachedNavigationURLLoader::FollowRedirect( const std::vector<std::string>& removed_headers, const net::HttpRequestHeaders& modified_headers,
diff --git a/content/browser/loader/cached_navigation_url_loader.h b/content/browser/loader/cached_navigation_url_loader.h index a481bfab..fbe0803b 100644 --- a/content/browser/loader/cached_navigation_url_loader.h +++ b/content/browser/loader/cached_navigation_url_loader.h
@@ -28,6 +28,7 @@ network::mojom::URLResponseHeadPtr cached_response_head); // NavigationURLLoader implementation. + void Start() override; void FollowRedirect( const std::vector<std::string>& removed_headers, const net::HttpRequestHeaders& modified_headers,
diff --git a/content/browser/loader/navigation_url_loader.h b/content/browser/loader/navigation_url_loader.h index bc8b87d..8f565cd1 100644 --- a/content/browser/loader/navigation_url_loader.h +++ b/content/browser/loader/navigation_url_loader.h
@@ -80,6 +80,9 @@ virtual ~NavigationURLLoader() {} + // Called right after the loader is constructed. + virtual void Start() = 0; + // Called in response to OnRequestRedirected to continue processing the // request. |new_previews_state| will be updated for newly created URLLoaders, // but the existing default URLLoader will not see |new_previews_state| unless
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 4e53d8d1..f8befefe 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -326,7 +326,7 @@ } } -void NavigationURLLoaderImpl::Start( +void NavigationURLLoaderImpl::StartImpl( scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory, AppCacheNavigationHandle* appcache_handle, scoped_refptr<PrefetchedSignedExchangeCache> @@ -1284,11 +1284,17 @@ std::move(factory_remote)); } - Start(network_factory, appcache_handle, - std::move(prefetched_signed_exchange_cache), - std::move(signed_exchange_prefetch_metric_recorder), - std::move(factory_for_webui), std::move(accept_langs), - needs_loader_factory_interceptor); + start_closure_ = + base::BindOnce(&NavigationURLLoaderImpl::StartImpl, + base::Unretained(this), network_factory, appcache_handle, + std::move(prefetched_signed_exchange_cache), + std::move(signed_exchange_prefetch_metric_recorder), + std::move(factory_for_webui), std::move(accept_langs), + needs_loader_factory_interceptor); +} + +void NavigationURLLoaderImpl::Start() { + std::move(start_closure_).Run(); } void NavigationURLLoaderImpl::FollowRedirect(
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index 02d0838..5e45787 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -68,20 +68,6 @@ // TODO(kinuko): Some method parameters can probably be just kept as // member variables rather than being passed around. - // Starts the loader by finalizing loader factories initialization and - // calling Restart(). - // This is called only once (while Restart can be called multiple times). - // Sets |started_| true. - void Start( - scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory, - AppCacheNavigationHandle* appcache_handle, - scoped_refptr<PrefetchedSignedExchangeCache> - prefetched_signed_exchange_cache, - scoped_refptr<SignedExchangePrefetchMetricRecorder> - signed_exchange_prefetch_metric_recorder, - mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_for_webui, - std::string accept_langs, - bool needs_loader_factory_interceptor); void CreateInterceptors(AppCacheNavigationHandle* appcache_handle, scoped_refptr<PrefetchedSignedExchangeCache> prefetched_signed_exchange_cache, @@ -160,6 +146,7 @@ base::OnceClosure continuation); // NavigationURLLoader implementation: + void Start() override; void FollowRedirect( const std::vector<std::string>& removed_headers, const net::HttpRequestHeaders& modified_headers, @@ -195,6 +182,21 @@ StoragePartitionImpl* partition); private: + // Starts the loader by finalizing loader factories initialization and + // calling Restart(). + // This is called only once (while Restart can be called multiple times). + // Sets |started_| true. + void StartImpl( + scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory, + AppCacheNavigationHandle* appcache_handle, + scoped_refptr<PrefetchedSignedExchangeCache> + prefetched_signed_exchange_cache, + scoped_refptr<SignedExchangePrefetchMetricRecorder> + signed_exchange_prefetch_metric_recorder, + mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_for_webui, + std::string accept_langs, + bool needs_loader_factory_interceptor); + void BindNonNetworkURLLoaderFactoryReceiver( const GURL& url, mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver); @@ -311,6 +313,10 @@ std::unique_ptr<NavigationEarlyHintsManager> early_hints_manager_; + // Set on the constructor and runs in Start(). This is used for transferring + // parameters prepared in the constructor to Start(). + base::OnceClosure start_closure_; + base::WeakPtrFactory<NavigationURLLoaderImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(NavigationURLLoaderImpl);
diff --git a/content/browser/loader/navigation_url_loader_impl_unittest.cc b/content/browser/loader/navigation_url_loader_impl_unittest.cc index 950a76c..be34ce78 100644 --- a/content/browser/loader/navigation_url_loader_impl_unittest.cc +++ b/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -254,6 +254,7 @@ base::StringPrintf("%s: %s", net::HttpRequestHeaders::kOrigin, redirect_url.GetOrigin().spec().c_str()), request_method, &delegate); + loader->Start(); delegate.WaitForRequestRedirected(); loader->FollowRedirect({}, {}, {}, blink::PreviewsTypes::PREVIEWS_OFF); @@ -293,6 +294,7 @@ url.GetOrigin().spec().c_str()), "GET", &delegate, blink::NavigationDownloadPolicy(), true /*is_main_frame*/, upgrade_if_insecure); + loader->Start(); delegate.WaitForRequestRedirected(); loader->FollowRedirect({}, {}, {}, blink::PreviewsTypes::PREVIEWS_OFF); if (expect_request_fail) { @@ -325,6 +327,7 @@ url.GetOrigin().spec().c_str()), "GET", &delegate, blink::NavigationDownloadPolicy(), true /*is_main_frame*/, false /*upgrade_if_insecure*/); + loader->Start(); delegate.WaitForResponseStarted(); ASSERT_TRUE(most_recent_resource_request_); @@ -434,6 +437,7 @@ TestNavigationURLLoaderDelegate delegate; std::unique_ptr<NavigationURLLoader> loader = CreateTestLoader( redirect_url, "Header1: Value1\r\nHeader2: Value2", "GET", &delegate); + loader->Start(); delegate.WaitForRequestRedirected(); ASSERT_TRUE(most_recent_resource_request_);
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc index ced37865..573698e 100644 --- a/content/browser/loader/navigation_url_loader_unittest.cc +++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -117,6 +117,7 @@ TestNavigationURLLoaderDelegate delegate; std::unique_ptr<NavigationURLLoader> loader = MakeTestLoader(GURL("bogus:bogus"), &delegate); + loader->Start(); // Wait for the request to fail as expected. delegate.WaitForRequestFailed(); @@ -136,6 +137,7 @@ TestNavigationURLLoaderDelegate delegate; std::unique_ptr<NavigationURLLoader> loader = MakeTestLoader(https_server.GetURL("/"), &delegate); + loader->Start(); // Wait for the request to fail as expected. delegate.WaitForRequestFailed(); @@ -169,6 +171,7 @@ TestNavigationURLLoaderDelegate delegate; std::unique_ptr<NavigationURLLoader> loader = MakeTestLoader(url, &delegate); + loader->Start(); // Wait for the request to fail as expected. delegate.WaitForRequestFailed();
diff --git a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc index ad62a5a1..121ba31f 100644 --- a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc +++ b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
@@ -106,6 +106,10 @@ return media::GpuVideoAcceleratorFactories::Supported::kTrue; } +media::VideoDecoderType BrowserGpuVideoAcceleratorFactories::GetDecoderType() { + return media::VideoDecoderType::kMediaCodec; +} + bool BrowserGpuVideoAcceleratorFactories::IsDecoderSupportKnown() { return true; }
diff --git a/content/browser/media/android/browser_gpu_video_accelerator_factories.h b/content/browser/media/android/browser_gpu_video_accelerator_factories.h index 61b06df1..30b9b46 100644 --- a/content/browser/media/android/browser_gpu_video_accelerator_factories.h +++ b/content/browser/media/android/browser_gpu_video_accelerator_factories.h
@@ -30,6 +30,7 @@ int32_t GetCommandBufferRouteId() override; Supported IsDecoderConfigSupported( const media::VideoDecoderConfig& config) override; + media::VideoDecoderType GetDecoderType() override; bool IsDecoderSupportKnown() override; void NotifyDecoderSupportKnown(base::OnceClosure) override; std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
diff --git a/content/browser/native_io/native_io_host.cc b/content/browser/native_io/native_io_host.cc index c9be013f..4350a20 100644 --- a/content/browser/native_io/native_io_host.cc +++ b/content/browser/native_io/native_io_host.cc
@@ -69,8 +69,8 @@ // Creates a task runner suitable for running file I/O tasks. scoped_refptr<base::TaskRunner> CreateFileTaskRunner() { - // We use a SequencedTaskRunner so that there is a global ordering to an - // origin's directory operations. + // We use a SequencedTaskRunner so that there is a global ordering to a + // storage key's directory operations. return base::ThreadPool::CreateSequencedTaskRunner({ // Needed for file I/O. base::MayBlock(), @@ -92,7 +92,7 @@ DCHECK(IsValidNativeIOName(name)); DCHECK(!root_path.empty()); - // Lazily create the origin's directory. + // Lazily create the storage key's directory. base::File::Error error; if (!base::CreateDirectoryAndGetError(root_path, &error)) return {base::File(), /*file_length=*/0}; @@ -115,7 +115,8 @@ DCHECK(IsValidNativeIOName(name)); DCHECK(!root_path.empty()); - // If the origin's directory wasn't created yet, there's nothing to delete. + // If the storage key's directory wasn't created yet, there's nothing to + // delete. if (!base::PathExists(root_path)) return {NativeIOError::New(NativeIOErrorType::kSuccess, ""), /*deleted_file_length=*/0}; @@ -149,7 +150,8 @@ std::vector<std::string> result; - // If the origin's directory wasn't created yet, there's no file to report. + // If the storage key's directory wasn't created yet, there's no file to + // report. if (!base::PathExists(root_path)) return {base::File::FILE_OK, std::move(result)}; @@ -208,9 +210,10 @@ DCHECK(IsValidNativeIOName(new_name)); base::File::Error error = base::File::FILE_OK; - // If the origin's directory wasn't created yet, there's nothing to rename. - // This error cannot be used to determine the existence of files outside of - // the origin's directory, as |old_name| is a valid NativeIO name. + // If the storage key's directory wasn't created yet, there's nothing to + // rename. This error cannot be used to determine the existence of files + // outside of the storage key's directory, as |old_name| is a valid NativeIO + // name. if (!base::PathExists(root_path) || !base::PathExists(GetNativeIOFilePath(root_path, old_name))) { return NativeIOError::New(NativeIOErrorType::kNotFound, @@ -218,8 +221,8 @@ } // Do not overwrite an existing file. This error cannot be used to determine - // the existence of files outside of the origin's directory, as `new_name` is - // a valid NativeIO name. + // the existence of files outside of the storage key's directory, as + // `new_name` is a valid NativeIO name. if (base::PathExists(GetNativeIOFilePath(root_path, new_name))) return NativeIOError::New(NativeIOErrorType::kNoModificationAllowed, "Target file exists"); @@ -230,11 +233,11 @@ } // Performs the file I/O work in DeleteAllData(). -base::File::Error DoDeleteAllData(const base::FilePath& origin_dir) { - DCHECK(!origin_dir.empty()); - CHECK(!origin_dir.ReferencesParent()) +base::File::Error DoDeleteAllData(const base::FilePath& storage_key_dir) { + DCHECK(!storage_key_dir.empty()); + CHECK(!storage_key_dir.ReferencesParent()) << "Removing a parent directory is disallowed."; - bool delete_success = base::DeletePathRecursively(origin_dir); + bool delete_success = base::DeletePathRecursively(storage_key_dir); if (!delete_success) { return base::File::GetLastFileError(); } @@ -243,13 +246,13 @@ } // namespace -NativeIOHost::NativeIOHost(const url::Origin& origin, +NativeIOHost::NativeIOHost(const blink::StorageKey& storage_key, base::FilePath root_path, #if defined(OS_MAC) bool allow_set_length_ipc, #endif // defined(OS_MAC) NativeIOManager* manager) - : origin_(origin), + : storage_key_(storage_key), root_path_(std::move(root_path)), #if defined(OS_MAC) allow_set_length_ipc_(allow_set_length_ipc), @@ -294,7 +297,7 @@ std::move(callback).Run( base::File(), /*file_length=*/0, NativeIOError::New(NativeIOErrorType::kInvalidState, - "Data removal pending on origin")); + "Data removal pending on storage key")); return; } @@ -345,7 +348,7 @@ if (delete_all_data_in_progress()) { std::move(callback).Run( NativeIOError::New(NativeIOErrorType::kInvalidState, - "Data removal pending on origin"), + "Data removal pending on storage key"), /*granted_capacity_delta=*/0); return; } @@ -377,11 +380,10 @@ } manager_->quota_manager_proxy()->NotifyStorageAccessed( - blink::StorageKey(origin_), blink::mojom::StorageType::kTemporary, - base::Time::Now()); + storage_key(), blink::mojom::StorageType::kTemporary, base::Time::Now()); // The deletion task runs on the file_task_runner and is skipped on shutdown, - // as is ok for origin data deletion. + // as is ok for storage key data deletion. file_task_runner_->PostTaskAndReplyWithResult( FROM_HERE, base::BindOnce(&DoDeleteFile, root_path_, name), base::BindOnce(&NativeIOHost::DidDeleteFile, weak_factory_.GetWeakPtr(), @@ -402,8 +404,7 @@ } manager_->quota_manager_proxy()->NotifyStorageAccessed( - blink::StorageKey(origin_), blink::mojom::StorageType::kTemporary, - base::Time::Now()); + storage_key(), blink::mojom::StorageType::kTemporary, base::Time::Now()); file_task_runner_->PostTaskAndReplyWithResult( FROM_HERE, base::BindOnce(&DoGetAllFileNames, root_path_), @@ -423,8 +424,9 @@ } if (delete_all_data_in_progress()) { - std::move(callback).Run(NativeIOError::New( - NativeIOErrorType::kInvalidState, "Data removal pending on origin")); + std::move(callback).Run( + NativeIOError::New(NativeIOErrorType::kInvalidState, + "Data removal pending on storage key")); return; } @@ -543,7 +545,7 @@ // DoOpenFile may create a file if none exists, which justifies // NotifyStorageModified. manager_->quota_manager_proxy()->NotifyStorageModified( - storage::QuotaClientType::kNativeIO, blink::StorageKey(origin_), + storage::QuotaClientType::kNativeIO, storage_key(), blink::mojom::StorageType::kTemporary, 0, base::Time::Now()); open_file_hosts_.insert({ @@ -569,7 +571,7 @@ io_pending_files_.erase(name); manager_->quota_manager_proxy()->NotifyStorageModified( - storage::QuotaClientType::kNativeIO, blink::StorageKey(origin_), + storage::QuotaClientType::kNativeIO, storage_key(), blink::mojom::StorageType::kTemporary, 0, base::Time::Now()); std::move(callback).Run(std::move(delete_result.first), delete_result.second); @@ -588,7 +590,7 @@ io_pending_files_.erase(new_name); manager_->quota_manager_proxy()->NotifyStorageModified( - storage::QuotaClientType::kNativeIO, blink::StorageKey(origin_), + storage::QuotaClientType::kNativeIO, storage_key(), blink::mojom::StorageType::kTemporary, 0, base::Time::Now()); std::move(callback).Run(std::move(rename_error));
diff --git a/content/browser/native_io/native_io_host.h b/content/browser/native_io/native_io_host.h index 65a37f9..8ac285a 100644 --- a/content/browser/native_io/native_io_host.h +++ b/content/browser/native_io/native_io_host.h
@@ -15,8 +15,8 @@ #include "build/build_config.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/native_io/native_io.mojom.h" -#include "url/origin.h" namespace base { class TaskRunner; @@ -27,14 +27,14 @@ class NativeIOManager; class NativeIOFileHost; -// Implements the NativeIO Web Platform feature for an origin. +// Implements the NativeIO Web Platform feature for a storage key. // -// NativeIOManager owns an instance of this class for each origin that is +// NativeIOManager owns an instance of this class for each storage key that is // actively using NativeIO. // // This class is not thread-safe, so all access to an instance must happen on -// the same sequence. However, origins are completely isolated from each other, -// so different NativeIOHost instances can safely be used on different +// the same sequence. However, storage keys are completely isolated from each +// other, so different NativeIOHost instances can safely be used on different // sequences, if desired. class NativeIOHost : public blink::mojom::NativeIOHost { public: @@ -44,7 +44,7 @@ // `allow_set_length_ipc` gates NativeIOFileHost::SetLength(), which works // around a sandboxing limitation on macOS < 10.15. This is plumbed as a flag // all the from NativeIOManager to facilitate testing. - explicit NativeIOHost(const url::Origin& origin, + explicit NativeIOHost(const blink::StorageKey& storage_key, base::FilePath root_path, #if defined(OS_MAC) bool allow_set_length_ipc, @@ -57,7 +57,7 @@ ~NativeIOHost() override; // Binds |receiver| to the NativeIOHost. The |receiver| must belong to a frame - // or worker for this host's origin. + // or worker for this host's storage key. void BindReceiver(mojo::PendingReceiver<blink::mojom::NativeIOHost> receiver); // True if there are no receivers connected to this host. @@ -66,8 +66,8 @@ // when it isn't serving any receivers. bool has_empty_receiver_set() const { return receivers_.empty(); } - // The origin served by this host. - const url::Origin& origin() const { return origin_; } + // The storage key served by this host. + const blink::StorageKey& storage_key() const { return storage_key_; } // True if this host's data is currently being deleted. bool delete_all_data_in_progress() const { @@ -90,14 +90,14 @@ void RequestCapacityChange(int64_t capacity_delta, RequestCapacityChangeCallback callback) override; - // Removes all data stored for the host's origin from disk. All mojo + // Removes all data stored for the host's storage key from disk. All mojo // connections for open files are closed. void DeleteAllData(DeleteAllDataCallback callback); - // Called when one of the open files for this origin closes. + // Called when one of the open files for this storage key closes. // - // |file_host| must be owned by this origin host. This method should only be - // called by NativeIOFileHost. + // |file_host| must be owned by this storage key host. This method should only + // be called by NativeIOFileHost. void OnFileClose(NativeIOFileHost* file_host); private: @@ -127,15 +127,15 @@ SEQUENCE_CHECKER(sequence_checker_); - // The origin served by this host. - const url::Origin origin_; + // The storage key served by this host. + const blink::StorageKey storage_key_; // Deletion requests issued during an ongoing deletion are coalesced with that // deletion request. All coalesced callbacks are stored and invoked // together. std::vector<DeleteAllDataCallback> delete_all_data_callbacks_; - // The directory holding all the files for this origin. + // The directory holding all the files for this storage key. const base::FilePath root_path_; #if defined(OS_MAC) @@ -149,8 +149,8 @@ // Schedules all operations involving file I/O done by this NativeIOHost. const scoped_refptr<base::TaskRunner> file_task_runner_; - // All receivers for frames and workers whose origin is `origin_` associated - // with the StoragePartition that owns `manager_`. + // All receivers for frames and workers whose storage key is `storage_key_` + // associated with the StoragePartition that owns `manager_`. mojo::ReceiverSet<blink::mojom::NativeIOHost> receivers_; // The names of files that have pending I/O tasks.
diff --git a/content/browser/native_io/native_io_manager.cc b/content/browser/native_io/native_io_manager.cc index 227ead9..f8f0673 100644 --- a/content/browser/native_io/native_io_manager.cc +++ b/content/browser/native_io/native_io_manager.cc
@@ -27,7 +27,6 @@ #include "third_party/blink/public/common/native_io/native_io_utils.h" #include "third_party/blink/public/mojom/native_io/native_io.mojom.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" -#include "url/origin.h" namespace content { @@ -153,7 +152,7 @@ bool insert_succeeded; std::tie(it, insert_succeeded) = hosts_.emplace( storage_key, std::make_unique<NativeIOHost>( - storage_key.origin(), std::move(storage_key_root_path), + storage_key, std::move(storage_key_root_path), #if defined(OS_MAC) allow_set_length_ipc_, #endif // defined(OS_MAC) @@ -173,14 +172,13 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(host != nullptr); - const blink::StorageKey& storage_key = blink::StorageKey(host->origin()); - DCHECK(hosts_.count(storage_key) > 0); - DCHECK_EQ(hosts_[storage_key].get(), host); + DCHECK(hosts_.count(host->storage_key()) > 0); + DCHECK_EQ(hosts_[host->storage_key()].get(), host); if (!host->has_empty_receiver_set() || host->delete_all_data_in_progress()) return; - hosts_.erase(storage_key); + hosts_.erase(host->storage_key()); } void NativeIOManager::OnDeleteStorageKeyDataCompleted( @@ -222,7 +220,7 @@ // the removal process. std::tie(it, insert_succeeded) = hosts_.emplace( storage_key, std::make_unique<NativeIOHost>( - storage_key.origin(), std::move(storage_key_root_path), + storage_key, std::move(storage_key_root_path), #if defined(OS_MAC) allow_set_length_ipc_, #endif // defined(OS_MAC)
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index fd0902c..095a93f 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -49,6 +49,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/network_service_util.h" #include "content/public/common/url_constants.h" +#include "content/public/test/back_forward_cache_util.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -4025,6 +4026,11 @@ GURL url(embedded_test_server()->GetURL("/target.html")); RenderFrameSubmissionObserver frame_observer(web_contents()); TestNavigationManager navigation_manager(web_contents(), url); + // This test expects the document is freshly loaded on the back navigation + // so that the document policy to force-load-at-top will run. This will not + // happen if the document is back-forward cached, so we need to disable it. + DisableBackForwardCacheForTesting(web_contents(), + BackForwardCache::TEST_ASSUMES_NO_CACHING); // Load the document with document policy force-load-at-top shell()->LoadURL(url);
diff --git a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc index 2ce26fb..66f6c79 100644 --- a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc +++ b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
@@ -43,8 +43,6 @@ return "BI not swapped - current SiteInstance does not have site"; case ShouldSwapBrowsingInstance::kNo_SourceURLSchemeIsNotHTTPOrHTTPS: return "BI not swapped - source URL scheme is not HTTP(S)"; - case ShouldSwapBrowsingInstance::kNo_DestinationURLSchemeIsNotHTTPOrHTTPS: - return "BI not swapped - destination URL scheme is not HTTP(S)"; case ShouldSwapBrowsingInstance::kNo_SameSiteNavigation: return "BI not swapped - same site navigation"; case ShouldSwapBrowsingInstance::kNo_ReloadingErrorPage:
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.cc b/content/browser/renderer_host/back_forward_cache_metrics.cc index 59e46ca..6f955c0 100644 --- a/content/browser/renderer_host/back_forward_cache_metrics.cc +++ b/content/browser/renderer_host/back_forward_cache_metrics.cc
@@ -477,7 +477,6 @@ case ShouldSwapBrowsingInstance::kNo_HasRelatedActiveContents: case ShouldSwapBrowsingInstance::kNo_DoesNotHaveSite: case ShouldSwapBrowsingInstance::kNo_SourceURLSchemeIsNotHTTPOrHTTPS: - case ShouldSwapBrowsingInstance::kNo_DestinationURLSchemeIsNotHTTPOrHTTPS: case ShouldSwapBrowsingInstance::kNo_SameSiteNavigation: case ShouldSwapBrowsingInstance::kNo_ReloadingErrorPage: case ShouldSwapBrowsingInstance::kNo_AlreadyHasMatchingBrowsingInstance:
diff --git a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc index 0905270..fb946d6e 100644 --- a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc +++ b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
@@ -22,6 +22,7 @@ #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/prerender_test_util.h" #include "content/public/test/test_navigation_observer.h" #include "content/shell/browser/shell.h" #include "content/test/content_browser_test_utils_internal.h" @@ -894,4 +895,70 @@ .empty()); } +class BackForwardCacheMetricsPrerenderingBrowserTest + : public BackForwardCacheMetricsBrowserTest { + public: + BackForwardCacheMetricsPrerenderingBrowserTest() + : prerender_helper_(base::BindRepeating( + &BackForwardCacheMetricsPrerenderingBrowserTest::web_contents, + base::Unretained(this))) {} + ~BackForwardCacheMetricsPrerenderingBrowserTest() override = default; + + test::PrerenderTestHelper* prerender_helper() { return &prerender_helper_; } + + WebContents* web_contents() { return shell()->web_contents(); } + + private: + test::PrerenderTestHelper prerender_helper_; +}; + +// Tests that activating a prerender works correctly when navigated +// back. +IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsPrerenderingBrowserTest, + MainFrameNavigation) { + ukm::TestAutoSetUkmRecorder recorder; + + const GURL url1(embedded_test_server()->GetURL( + "/back_forward_cache/page_with_pageshow.html")); + const GURL prerender_url(embedded_test_server()->GetURL("/title1.html")); + const GURL url2(embedded_test_server()->GetURL("/title2.html")); + + EXPECT_TRUE(NavigateToURL(shell(), url1)); + + // Loads a page in the prerender. + int host_id = prerender_helper()->AddPrerender(prerender_url); + test::PrerenderHostObserver host_observer(*web_contents(), host_id); + RenderFrameHost* prerender_rfh = + prerender_helper()->GetPrerenderedMainFrameHost(host_id); + EXPECT_TRUE(WaitForRenderFrameReady(prerender_rfh)); + + // Activates the page from the prerendering. + prerender_helper()->NavigatePrimaryPage(prerender_url); + // Makes sure that the page is activated from the prerendering. + EXPECT_TRUE(host_observer.was_activated()); + EXPECT_TRUE(WaitForRenderFrameReady(web_contents()->GetMainFrame())); + + EXPECT_TRUE(NavigateToURL(shell(), url2)); + + { + TestNavigationObserver navigation_observer(shell()->web_contents()); + shell()->GoBackOrForward(-1); + navigation_observer.WaitForNavigationFinished(); + } + + // The navigations observed should be: + // 1) url1 + // 2) prerender_url (prerender) + // 3) prerender_url (activate prerender) + // 4) url2 + // 5) prerender_url (back navigation) + + ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(5)); + ukm::SourceId id5 = ToSourceId(navigation_ids_[4]); + + // We should only record metrics for the last navigation. + EXPECT_THAT(GetFeatureUsageMetrics(&recorder), + testing::ElementsAre(FeatureUsage{id5, 0, 0, 0})); +} + } // namespace content
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc index 6873b11..e04121dc 100644 --- a/content/browser/renderer_host/navigation_controller_impl.cc +++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -1146,17 +1146,24 @@ } } + bool is_main_frame_navigation = !rfh->GetParent(); + // TODO(altimin, crbug.com/933147): Remove this logic after we are done with // implementing back-forward cache. - - // Create a new metrics object or reuse the previous one depending on whether - // it's a main frame navigation or not. - scoped_refptr<BackForwardCacheMetrics> back_forward_cache_metrics = - BackForwardCacheMetrics::CreateOrReuseBackForwardCacheMetrics( - GetLastCommittedEntry(), !rfh->GetParent(), - params.document_sequence_number); + // For primary frame tree navigations, choose an appropriate + // BackForwardCacheMetrics to be associated with the NavigationEntry, by + // either creating a new object or reusing the previous one depending on + // whether it's a main frame navigation or not. + scoped_refptr<BackForwardCacheMetrics> back_forward_cache_metrics; + if (navigation_request->frame_tree_node()->frame_tree()->type() == + FrameTree::Type::kPrimary) { + back_forward_cache_metrics = + BackForwardCacheMetrics::CreateOrReuseBackForwardCacheMetrics( + GetLastCommittedEntry(), is_main_frame_navigation, + params.document_sequence_number); + } // Notify the last active entry that we have navigated away. - if (!rfh->GetParent() && !is_same_document_navigation) { + if (is_main_frame_navigation && !is_same_document_navigation) { if (NavigationEntryImpl* navigation_entry = GetLastCommittedEntry()) { if (auto* metrics = navigation_entry->back_forward_cache_metrics()) { metrics->MainFrameDidNavigateAwayFromDocument(rfh, navigation_request); @@ -1279,13 +1286,19 @@ active_entry->SetHttpStatusCode(params.http_status_code); // TODO(altimin, crbug.com/933147): Remove this logic after we are done with // implementing back-forward cache. - if (!active_entry->back_forward_cache_metrics()) { + if (back_forward_cache_metrics && + !active_entry->back_forward_cache_metrics()) { active_entry->set_back_forward_cache_metrics( std::move(back_forward_cache_metrics)); } - active_entry->back_forward_cache_metrics()->DidCommitNavigation( - navigation_request, - back_forward_cache_.IsAllowed(navigation_request->GetURL())); + + // `back_forward_cache_metrics()` may return null as we do not record + // back-forward cache metrics for navigations in non-primary frame trees. + if (active_entry->back_forward_cache_metrics()) { + active_entry->back_forward_cache_metrics()->DidCommitNavigation( + navigation_request, + back_forward_cache_.IsAllowed(navigation_request->GetURL())); + } // Grab the corresponding FrameNavigationEntry for a few updates, but only if // the SiteInstance matches (to avoid updating the wrong entry by mistake).
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 3206b28..fa2c7d49 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -3485,6 +3485,7 @@ frame_tree_node_->frame_tree_node_id()), NetworkServiceDevToolsObserver::MakeSelfOwned(frame_tree_node_), std::move(cached_response_head), std::move(interceptor)); + loader_->Start(); DCHECK(!render_frame_host_); } @@ -5247,6 +5248,9 @@ if (base::FeatureList::IsEnabled( features::kBlockInsecurePrivateNetworkRequestsDeprecationTrial) && + // If there is no response or no headers in the response, there are + // definitely no trial token headers. + response_head_ && response_head_->headers && blink::TrialTokenValidator().RequestEnablesFeature( common_params_->url, response_head_->headers.get(), "PrivateNetworkAccessNonSecureContextsAllowed", base::Time::Now())) { @@ -5438,10 +5442,6 @@ if (use_opaque_origin) origin = origin.DeriveNewOpaqueOrigin(); - // MHTML documents should commit as an opaque origin. They should not be able - // to make network request on behalf of the real origin. - DCHECK(!IsMhtmlOrSubframe() || origin.opaque()); - return origin; } @@ -5455,6 +5455,10 @@ url::Origin origin = GetOriginForURLLoaderFactoryWithoutFinalFrameHost(); + // MHTML documents should commit as an opaque origin. They should not be able + // to make network request on behalf of the real origin. + DCHECK(!IsMhtmlOrSubframe() || origin.opaque()); + // https://crbug.com/1041376) of the origin that will be committed because of // |this| NavigationRequest.
diff --git a/content/browser/renderer_host/navigation_request_browsertest.cc b/content/browser/renderer_host/navigation_request_browsertest.cc index e1cce54..ba40134 100644 --- a/content/browser/renderer_host/navigation_request_browsertest.cc +++ b/content/browser/renderer_host/navigation_request_browsertest.cc
@@ -2490,9 +2490,15 @@ } { base::HistogramTester histograms; + int previous_process_id = + shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(); EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); - check_navigation(histograms, ProcessType::kSame, FrameType::kMain, - TransitionType::kNew); + bool process_changed = + (previous_process_id != + shell()->web_contents()->GetMainFrame()->GetProcess()->GetID()); + check_navigation(histograms, + process_changed ? ProcessType::kCross : ProcessType::kSame, + FrameType::kMain, TransitionType::kNew); } // Subframe tests. All of these tests just navigate a frame within
diff --git a/content/browser/renderer_host/navigator_unittest.cc b/content/browser/renderer_host/navigator_unittest.cc index 160cbc80d..ca894395 100644 --- a/content/browser/renderer_host/navigator_unittest.cc +++ b/content/browser/renderer_host/navigator_unittest.cc
@@ -1168,7 +1168,6 @@ navigation_to_data_url->Start(); EXPECT_FALSE(main_test_rfh()->is_loading()); EXPECT_TRUE(node->navigation_request()); - EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); } // Tests several cases for converting SiteInstanceDescriptors into
diff --git a/content/browser/renderer_host/policy_container_navigation_bundle_browsertest.cc b/content/browser/renderer_host/policy_container_navigation_bundle_browsertest.cc index 288284ed..bcd2d5f4 100644 --- a/content/browser/renderer_host/policy_container_navigation_bundle_browsertest.cc +++ b/content/browser/renderer_host/policy_container_navigation_bundle_browsertest.cc
@@ -212,15 +212,14 @@ // are ignored in favor of the policies from the entry. IN_PROC_BROWSER_TEST_F(PolicyContainerNavigationBundleBrowserTest, FinalPoliciesAboutSrcDocWithParentAndHistory) { - RenderFrameHostImpl* root = root_frame_host(); - // First navigate to a local scheme with non-default policies. To do that, we // first navigate to a document with a public address space, then have that // document navigate itself to `about:blank`. The final blank document // inherits its policies from the first document, and stores them in its // frame navigation entry for restoring later. EXPECT_TRUE(NavigateToURL(shell()->web_contents(), PublicUrl())); - EXPECT_TRUE(NavigateToURLFromRenderer(root, AboutBlankUrl())); + EXPECT_TRUE(NavigateToURLFromRenderer(root_frame_host(), AboutBlankUrl())); + RenderFrameHostImpl* root = root_frame_host(); // Embed another frame with different policies, to use as the "parent". std::string script_template = R"(
diff --git a/content/browser/renderer_host/private_network_access_browsertest.cc b/content/browser/renderer_host/private_network_access_browsertest.cc index edd00bae..8b97071 100644 --- a/content/browser/renderer_host/private_network_access_browsertest.cc +++ b/content/browser/renderer_host/private_network_access_browsertest.cc
@@ -2340,20 +2340,21 @@ }; // Test with insecure private network requests blocked, excluding navigations. -class PrivateNetworkAccessDeprecationTrialBrowserTest +class PrivateNetworkAccessDeprecationTrialDisabledBrowserTest : public PrivateNetworkAccessBrowserTestBase { public: - PrivateNetworkAccessDeprecationTrialBrowserTest() + PrivateNetworkAccessDeprecationTrialDisabledBrowserTest() : PrivateNetworkAccessBrowserTestBase( { features::kBlockInsecurePrivateNetworkRequests, - features::kBlockInsecurePrivateNetworkRequestsDeprecationTrial, }, - {}) {} + { + features::kBlockInsecurePrivateNetworkRequestsDeprecationTrial, + }) {} }; -IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessBrowserTest, - DeprecationTrialDisabled) { +IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessDeprecationTrialDisabledBrowserTest, + OriginEnabledDoesNothing) { OriginTrialURLLoaderInterceptor interceptor; EXPECT_TRUE(NavigateToURL(shell(), interceptor.EnabledUrl())); @@ -2366,8 +2367,7 @@ network::mojom::PrivateNetworkRequestPolicy::kBlock); } -IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessDeprecationTrialBrowserTest, - OriginEnabled) { +IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessBrowserTest, OriginEnabled) { OriginTrialURLLoaderInterceptor interceptor; EXPECT_TRUE(NavigateToURL(shell(), interceptor.EnabledUrl())); @@ -2382,8 +2382,7 @@ network::mojom::PrivateNetworkRequestPolicy::kBlock); } -IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessDeprecationTrialBrowserTest, - OriginDisabled) { +IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessBrowserTest, OriginDisabled) { OriginTrialURLLoaderInterceptor interceptor; EXPECT_TRUE(NavigateToURL(shell(), interceptor.DisabledUrl()));
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 6b6bf0a..06ba84b 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2370,6 +2370,12 @@ FRIEND_TEST_ALL_PREFIXES( RenderFrameHostManagerUnloadBrowserTest, PendingDeleteRFHProcessShutdownDoesNotRemoveSubframes); + FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, + AttemptDuplicateRenderViewHost); + FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, + AttemptDuplicateRenderWidgetHost); + FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, + BindToWebUIFromWebViaMojo); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, RenderViewHostIsNotReusedAfterDelayedUnloadACK); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, @@ -2386,8 +2392,6 @@ RenderFrameProxyNotRecreatedDuringProcessShutdown); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, UnloadACKArrivesPriorToProcessShutdownRequest); - FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, - AttemptDuplicateRenderViewHost); FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FullscreenAfterFrameUnload); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, UnloadHandlerSubframes); @@ -2414,8 +2418,6 @@ FRIEND_TEST_ALL_PREFIXES(SitePerProcessSSLBrowserTest, UnloadHandlersArePowerfulGrandChild); FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplTest, ExpectedMainWorldOrigin); - FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, - AttemptDuplicateRenderWidgetHost); FRIEND_TEST_ALL_PREFIXES(RenderDocumentHostUserDataTest, CheckInPendingDeletionState); FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FrozenAndUnfrozenIPC);
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc index aad8d509..4d5fa6c 100644 --- a/content/browser/renderer_host/render_frame_host_manager.cc +++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -239,9 +239,6 @@ case ShouldSwapBrowsingInstance::kNo_SourceURLSchemeIsNotHTTPOrHTTPS: return ProtoLevel:: SHOULD_SWAP_BROWSING_INSTANCE_NO_SOURCE_URL_SCHEME_NOT_HTTP_OR_HTTPS; - case ShouldSwapBrowsingInstance::kNo_DestinationURLSchemeIsNotHTTPOrHTTPS: - return ProtoLevel:: - SHOULD_SWAP_BROWSING_INSTANCE_NO_DESTINATION_URL_SCHEME_NOT_HTTP_OR_HTTPS; case ShouldSwapBrowsingInstance::kNo_SameSiteNavigation: return ProtoLevel::SHOULD_SWAP_BROWSING_INSTANCE_NO_SAME_SITE_NAVIGATION; case ShouldSwapBrowsingInstance::kNo_ReloadingErrorPage: @@ -1697,17 +1694,13 @@ if (!current_instance->HasSite()) return ShouldSwapBrowsingInstance::kNo_DoesNotHaveSite; - // Exclude non http(s) schemes. Some tests don't expect navigations to - // data-URL or to about:blank to switch to a different BrowsingInstance. + // Do not do a proactive BrowsingInstance swap when the previous document's + // scheme is not HTTP/HTTPS, since only HTTP/HTTPS documents are eligible for + // back-forward cache. const GURL& current_url = render_frame_host_->GetLastCommittedURL(); if (!current_url.SchemeIsHTTPOrHTTPS()) return ShouldSwapBrowsingInstance::kNo_SourceURLSchemeIsNotHTTPOrHTTPS; - const GURL& destination_effective_url = SiteInstanceImpl::GetEffectiveURL( - current_instance->GetBrowserContext(), destination_url_info.url); - if (!destination_effective_url.SchemeIsHTTPOrHTTPS()) - return ShouldSwapBrowsingInstance::kNo_DestinationURLSchemeIsNotHTTPOrHTTPS; - // WebView guests currently need to stay in the same SiteInstance and // BrowsingInstance. if (current_instance->IsGuest())
diff --git a/content/browser/renderer_host/should_swap_browsing_instance.h b/content/browser/renderer_host/should_swap_browsing_instance.h index 3e5e1744..e18d2d1 100644 --- a/content/browser/renderer_host/should_swap_browsing_instance.h +++ b/content/browser/renderer_host/should_swap_browsing_instance.h
@@ -18,7 +18,9 @@ kNo_HasRelatedActiveContents = 3, kNo_DoesNotHaveSite = 4, kNo_SourceURLSchemeIsNotHTTPOrHTTPS = 5, - kNo_DestinationURLSchemeIsNotHTTPOrHTTPS = 6, + // 6: kNo_DestinationURLSchemeIsNotHTTPOrHTTPS was removed as the scheme of + // the destination URL should not affect back-forward cache eligibility, so + // we don't need to avoid doing a proactive BrowsingInstance swap due to it. kNo_SameSiteNavigation = 7, kNo_ReloadingErrorPage = 8, kNo_AlreadyHasMatchingBrowsingInstance = 9,
diff --git a/content/browser/screen_enumeration/screen_enumeration_browsertest.cc b/content/browser/screen_enumeration/screen_enumeration_browsertest.cc index 0172976..e3c9469e 100644 --- a/content/browser/screen_enumeration/screen_enumeration_browsertest.cc +++ b/content/browser/screen_enumeration/screen_enumeration_browsertest.cc
@@ -46,11 +46,6 @@ })(); )"; -// Used to get the async result of isMultiScreen(). -constexpr char kIsMultiScreenScript[] = R"( - (async () => { return await self.isMultiScreen(); })(); -)"; - // Returns a list of dictionary values from native screen information, intended // for comparison with the result of kGetScreensScript. base::ListValue GetExpectedScreens() { @@ -120,16 +115,6 @@ EXPECT_EQ(GetExpectedScreens(), base::Value::AsListValue(result.value)); } -// TODO(crbug.com/1205676): Remove this test in favor of IsExtendedBasic. -// window.isMultiScreen() is deprecated in favor of screen.isExtended. -IN_PROC_BROWSER_TEST_F(ScreenEnumerationTest, IsMultiScreenBasic) { - ASSERT_TRUE(NavigateToURL(shell(), GetTestUrl(nullptr, "empty.html"))); - ASSERT_EQ(true, EvalJs(shell(), "'isMultiScreen' in self")); - auto result = EvalJs(shell(), kIsMultiScreenScript); - EXPECT_EQ(display::Screen::GetScreen()->GetNumDisplays() > 1, - result.ExtractBool()); -} - IN_PROC_BROWSER_TEST_F(ScreenEnumerationTest, IsExtendedBasic) { ASSERT_TRUE(NavigateToURL(shell(), GetTestUrl(nullptr, "empty.html"))); ASSERT_EQ(true, EvalJs(shell(), "'isExtended' in screen")); @@ -193,28 +178,6 @@ EXPECT_EQ(GetExpectedScreens(), base::Value::AsListValue(result.value)); } -// TODO(crbug.com/1205676): Remove this test in favor of IsExtendedFaked. -// window.isMultiScreen() is deprecated in favor of screen.isExtended. -// TODO(crbug.com/1042990): Windows crashes static casting to ScreenWin. -// TODO(crbug.com/1042990): Android requires a GetDisplayNearestView overload. -#if defined(OS_ANDROID) || defined(OS_WIN) -#define MAYBE_IsMultiScreenFaked DISABLED_IsMultiScreenFaked -#else -#define MAYBE_IsMultiScreenFaked IsMultiScreenFaked -#endif -IN_PROC_BROWSER_TEST_F(FakeScreenEnumerationTest, MAYBE_IsMultiScreenFaked) { - ASSERT_TRUE(NavigateToURL(test_shell(), GetTestUrl(nullptr, "empty.html"))); - ASSERT_EQ(true, EvalJs(test_shell(), "'isMultiScreen' in self")); - EXPECT_EQ(false, EvalJs(test_shell(), kIsMultiScreenScript)); - - screen()->display_list().AddDisplay({1, gfx::Rect(100, 100, 801, 802)}, - display::DisplayList::Type::NOT_PRIMARY); - EXPECT_EQ(true, EvalJs(test_shell(), kIsMultiScreenScript)); - - screen()->display_list().RemoveDisplay(1); - EXPECT_EQ(false, EvalJs(test_shell(), kIsMultiScreenScript)); -} - // TODO(crbug.com/1042990): Windows crashes static casting to ScreenWin. // TODO(crbug.com/1042990): Android requires a GetDisplayNearestView overload. #if defined(OS_ANDROID) || defined(OS_WIN)
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index 4edd6f1..5073d38c 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -1305,6 +1305,50 @@ EXPECT_EQ(bad_message::RFH_CAN_COMMIT_URL_BLOCKED, kill_waiter.Wait()); } +// Tests that a web page cannot bind to a WebUI interface if a WebUI page is the +// currently committed RenderFrameHost in the tab (https://crbug.com/1225929). +IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, BindToWebUIFromWebViaMojo) { + // Navigate to a non-privileged web page, and simulate a renderer compromise + // by granting MojoJS. + GURL web_url(embedded_test_server()->GetURL("a.com", "/title1.html")); + TestNavigationManager navigation(shell()->web_contents(), web_url); + shell()->LoadURL(web_url); + EXPECT_TRUE(navigation.WaitForResponse()); + RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>( + shell()->web_contents()->GetMainFrame()); + main_frame->GetFrameBindingsControl()->EnableMojoJsBindings(); + navigation.WaitForNavigationFinished(); + + // Open a popup so that the process won't exit on its own when leaving. + OpenBlankWindow(static_cast<WebContentsImpl*>(shell()->web_contents())); + + // When the page unloads (after the cross-process navigation to an actual + // WebUI page below), try to bind to a WebUI interface from the web + // RenderFrameHost. Ensure the unload timer and bfcache are disabled so that + // the handler has a chance to run. + main_frame->DisableUnloadTimerForTesting(); + DisableBackForwardCacheForTesting(shell()->web_contents(), + BackForwardCache::TEST_USES_UNLOAD_EVENT); + ASSERT_TRUE(ExecJs(main_frame, R"( + // Intentionally leak pipe as a global so it doesn't get GCed. + newMessagePipe = Mojo.createMessagePipe(); + onunload = function () { + Mojo.bindInterface('mojom.ProcessInternalsHandler', + newMessagePipe.handle0); + }; + )")); + + // Now navigate to a WebUI page and expect the previous renderer process to be + // killed when asking to bind to the WebUI interface. + GURL webui_url( + GetWebUIURL(kChromeUIProcessInternalsHost).Resolve("#general")); + RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame->GetProcess()); + EXPECT_TRUE(NavigateToURL(shell(), webui_url)); + + // Verify that the previous renderer was terminated. + EXPECT_EQ(bad_message::RFH_INVALID_WEB_UI_CONTROLLER, kill_waiter.Wait()); +} + class BeginNavigationTransitionReplacer : public FrameHostInterceptor { public: BeginNavigationTransitionReplacer(WebContents* web_contents,
diff --git a/content/browser/text_fragment_browsertest.cc b/content/browser/text_fragment_browsertest.cc index fe29ba8..f32d36da 100644 --- a/content/browser/text_fragment_browsertest.cc +++ b/content/browser/text_fragment_browsertest.cc
@@ -12,6 +12,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" +#include "content/public/test/back_forward_cache_util.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -815,6 +816,12 @@ ASSERT_NO_FATAL_FAILURE(LoadScrollablePageWithContent("/index.html")); WebContents* main_contents = shell()->web_contents(); + // This test expects the document is freshly loaded on the back navigation + // so that the document policy to force-load-at-top will run. This will not + // happen if the document is back-forward cached, so we need to disable it. + DisableBackForwardCacheForTesting(main_contents, + BackForwardCache::TEST_ASSUMES_NO_CACHING); + RenderFrameSubmissionObserver frame_observer(main_contents); EXPECT_TRUE(WaitForRenderFrameReady(main_contents->GetMainFrame()));
diff --git a/content/browser/web_package/web_bundle_browsertest.cc b/content/browser/web_package/web_bundle_browsertest.cc index 6e543b3..8421201a 100644 --- a/content/browser/web_package/web_bundle_browsertest.cc +++ b/content/browser/web_package/web_bundle_browsertest.cc
@@ -1843,7 +1843,13 @@ DISALLOW_COPY_AND_ASSIGN(WebBundleTrustableFileNotFoundBrowserTest); }; -IN_PROC_BROWSER_TEST_F(WebBundleTrustableFileNotFoundBrowserTest, NotFound) { +// TODO(https://crbug.com/1227439): flaky +#if defined(OS_LINUX) +#define MAYBE_NotFound DISABLED_NotFound +#else +#define MAYBE_NotFound NotFound +#endif +IN_PROC_BROWSER_TEST_F(WebBundleTrustableFileNotFoundBrowserTest, MAYBE_NotFound) { std::string console_message = ExpectNavigationFailureAndReturnConsoleMessage( shell()->web_contents(), test_data_url());
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 2604937..40137119 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -534,9 +534,10 @@ FederatedIdentityRequestPermissionContextDelegate* FederatedAuthRequestImpl::GetRequestPermissionContext() { if (!request_permission_delegate_) { - render_frame_host() - ->GetBrowserContext() - ->GetFederatedIdentityRequestPermissionContext(); + request_permission_delegate_ = + render_frame_host() + ->GetBrowserContext() + ->GetFederatedIdentityRequestPermissionContext(); } return request_permission_delegate_; } @@ -544,9 +545,10 @@ FederatedIdentitySharingPermissionContextDelegate* FederatedAuthRequestImpl::GetSharingPermissionContext() { if (!sharing_permission_delegate_) { - render_frame_host() - ->GetBrowserContext() - ->GetFederatedIdentitySharingPermissionContext(); + sharing_permission_delegate_ = + render_frame_host() + ->GetBrowserContext() + ->GetFederatedIdentitySharingPermissionContext(); } return sharing_permission_delegate_; }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 14605b1..63b56f90 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -206,6 +206,9 @@ features::kEnableAccessibilityExposeHTMLElement}, {wf::EnableAccessibilityExposeIgnoredNodes, features::kEnableAccessibilityExposeIgnoredNodes}, +#if defined(OS_ANDROID) + {wf::EnableAccessibilityPageZoom, features::kAccessibilityPageZoom}, +#endif {wf::EnableAccessibilityUseAXPositionForDocumentMarkers, features::kUseAXPositionForDocumentMarkers}, {wf::EnableAllowActivationDelegationAttr,
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java index f2c78f8..f21ce62 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java
@@ -26,6 +26,11 @@ } // Alphabetical: + public static final String ACCESSIBILITY_PAGE_ZOOM = "AccessibilityPageZoom"; + + public static final String ACCESSIBILITY_PAGE_ZOOM_UPDATED_UI = + "AccessibilityPageZoomUpdatedUI"; + public static final String BACKGROUND_MEDIA_RENDERER_HAS_MODERATE_BINDING = "BackgroundMediaRendererHasModerateBinding";
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java index f66b9e9..832eb9f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
@@ -18,7 +18,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.UrlUtils; @@ -85,6 +84,31 @@ /** * Perform a single test which will: * 1. Open the given HTML file + * 2. Execute the javascript method "go()" + * 3. Repeat above step a total of |count| times + * 4. Read expectations file and compare with results + * + * @param inputFile HTML test input file + * @param expectationFile TXT expectations file + * @param count Number of times to run method. + */ + private void performTestWithRepeatCounter(String inputFile, String expectationFile, int count) { + // Build page from given file and enable testing framework, set a tracker. + setupTestFromFile(BASE_FILE_PATH + inputFile); + + // Execute method a given number of times. + for (int i = 0; i < count; i++) { + mActivityTestRule.executeJS("go()"); + } + + // Send an "end of test" signal, then check results. + mActivityTestRule.sendEndOfTestSignal(); + assertResults(expectationFile); + } + + /** + * Perform a single test which will: + * 1. Open the given HTML file * 2. Execute the given javascript method * 3. Read expectations file and compare with results * @@ -124,7 +148,9 @@ String actualResults = getTrackerResults(); Assert.assertNotNull(RESULTS_NULL, actualResults); - Assert.assertEquals(EVENTS_ERROR, expectedResults, actualResults); + Assert.assertEquals(EVENTS_ERROR + "\n\nExpected:\n" + expectedResults + "\n\nActual:\n" + + actualResults + "\n\n", + expectedResults, actualResults); } /** @@ -275,9 +301,9 @@ @Test @SmallTest - @DisabledTest(message = "https://crbug.com/1215897") public void test_ariaComboboxExpand() { - performTest("aria-combo-box-expand.html", "aria-combo-box-expand-expected-android.txt"); + performTestWithRepeatCounter( + "aria-combo-box-expand.html", "aria-combo-box-expand-expected-android.txt", 3); } @Test
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index f80399a..78528feb 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -124,7 +124,7 @@ // make use of the trial must additionally serve a valid origin trial token. const base::Feature kBlockInsecurePrivateNetworkRequestsDeprecationTrial{ "BlockInsecurePrivateNetworkRequestsDeprecationTrial", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // When both kBlockInsecurePrivateNetworkRequestsForNavigations and // kBlockInsecurePrivateNetworkRequests are enabled, navigations initiated @@ -1000,6 +1000,14 @@ base::FEATURE_ENABLED_BY_DEFAULT}; #if defined(OS_ANDROID) +// Allows the use of page zoom in place of accessibility text autosizing, and +// updated UI to replace existing Chrome Accessibility Settings. +const base::Feature kAccessibilityPageZoom{"AccessibilityPageZoom", + base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::Feature kAccessibilityPageZoomUpdatedUI{ + "AccessibilityPageZoomUpdatedUI", base::FEATURE_DISABLED_BY_DEFAULT}; + // Sets moderate binding to background renderers playing media, when enabled. // Else the renderer will have strong binding. const base::Feature kBackgroundMediaRendererHasModerateBinding{
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 80840a56..bcb4fdb55 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -254,6 +254,8 @@ CONTENT_EXPORT extern const base::Feature kWebXrArModule; #if defined(OS_ANDROID) +CONTENT_EXPORT extern const base::Feature kAccessibilityPageZoom; +CONTENT_EXPORT extern const base::Feature kAccessibilityPageZoomUpdatedUI; CONTENT_EXPORT extern const base::Feature kBackgroundMediaRendererHasModerateBinding; CONTENT_EXPORT extern const base::Feature kBindingManagementWaiveCpu;
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc index 8b553fd3..88a68a3 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -177,8 +177,6 @@ // Note: This is a bit of a hack, since we don't specify the implementation // before asking for the map of supported configs. We do this because it // (a) saves an ipc call, and (b) makes the return of those configs atomic. - // Otherwise, we might have received configs for kDefault but not yet - // kAlternate, for example. interface_factory_->CreateVideoDecoder( video_decoder_.BindNewPipeAndPassReceiver()); video_decoder_.set_disconnect_handler( @@ -205,10 +203,12 @@ } void GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs( - const media::SupportedVideoDecoderConfigs& supported_configs) { + const media::SupportedVideoDecoderConfigs& supported_configs, + media::VideoDecoderType decoder_type) { base::AutoLock lock(supported_profiles_lock_); video_decoder_.reset(); supported_decoder_configs_ = supported_configs; + video_decoder_type_ = decoder_type; decoder_support_notifier_.Notify(); } @@ -324,6 +324,11 @@ return Supported::kFalse; } +media::VideoDecoderType GpuVideoAcceleratorFactoriesImpl::GetDecoderType() { + base::AutoLock lock(supported_profiles_lock_); + return video_decoder_type_; +} + std::unique_ptr<media::VideoDecoder> GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder( media::MediaLog* media_log,
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h index 30d969fc..591aa7a4 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
@@ -79,6 +79,7 @@ int32_t GetCommandBufferRouteId() override; Supported IsDecoderConfigSupported( const media::VideoDecoderConfig& config) override; + media::VideoDecoderType GetDecoderType() override; bool IsDecoderSupportKnown() override; void NotifyDecoderSupportKnown(base::OnceClosure callback) override; std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( @@ -170,7 +171,8 @@ void SetContextProviderLostOnMainThread(); void OnSupportedDecoderConfigs( - const media::SupportedVideoDecoderConfigs& supported_configs); + const media::SupportedVideoDecoderConfigs& supported_configs, + media::VideoDecoderType decoder_type); void OnDecoderSupportFailed(); void OnGetVideoEncodeAcceleratorSupportedProfiles( @@ -217,6 +219,8 @@ // are no supported configs. absl::optional<media::SupportedVideoDecoderConfigs> supported_decoder_configs_ GUARDED_BY(supported_profiles_lock_); + media::VideoDecoderType video_decoder_type_ + GUARDED_BY(supported_profiles_lock_) = media::VideoDecoderType::kUnknown; Notifier decoder_support_notifier_ GUARDED_BY(supported_profiles_lock_); absl::optional<media::VideoEncodeAccelerator::SupportedProfiles>
diff --git a/content/test/data/accessibility/event/aria-combo-box-expand-expected-android.txt b/content/test/data/accessibility/event/aria-combo-box-expand-expected-android.txt index dc29210..4682f5e8 100644 --- a/content/test/data/accessibility/event/aria-combo-box-expand-expected-android.txt +++ b/content/test/data/accessibility/event/aria-combo-box-expand-expected-android.txt
@@ -1 +1,2 @@ +TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0] TYPE_ANNOUNCEMENT - [expanded.] \ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index 678c3b32..4a06ed9 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -408,7 +408,7 @@ crbug.com/852089 [ win7 ] Pixel_WebGPU* [ Skip ] # Flaky on Pixel 4 -crbug.com/1215747 [ android android-pixel-4 skia-renderer-gl ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ] crbug.com/1215747 [ android android-pixel-4 skia-renderer-gl ] Pixel_OffscreenCanvasWebGLDefault [ RetryOnFailure ] -# Failure on Nexus 5 -crbug.com/1221258 [ android android-nexus-5 skia-renderer-gl ] Pixel_OffscreenCanvas2DResizeOnWorker [ Failure ] + +# Flaky on Android, haven't investigated why yet. +crbug.com/1221258 [ android ] Pixel_OffscreenCanvas2DResizeOnWorker [ Failure ]
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc index 3514c85..9f93724 100644 --- a/content/test/test_navigation_url_loader.cc +++ b/content/test/test_navigation_url_loader.cc
@@ -31,6 +31,10 @@ redirect_count_(0), loader_type_(loader_type) {} +void TestNavigationURLLoader::Start() { + // Do nothing. +} + void TestNavigationURLLoader::FollowRedirect( const std::vector<std::string>& removed_headers, const net::HttpRequestHeaders& modified_headers,
diff --git a/content/test/test_navigation_url_loader.h b/content/test/test_navigation_url_loader.h index 104c06e..424052d 100644 --- a/content/test/test_navigation_url_loader.h +++ b/content/test/test_navigation_url_loader.h
@@ -31,6 +31,7 @@ NavigationURLLoader::LoaderType loader_type); // NavigationURLLoader implementation. + void Start() override; void FollowRedirect( const std::vector<std::string>& removed_headers, const net::HttpRequestHeaders& modified_headers,
diff --git a/crypto/sha2.cc b/crypto/sha2.cc index cde2a977..b69add6 100644 --- a/crypto/sha2.cc +++ b/crypto/sha2.cc
@@ -8,7 +8,6 @@ #include <memory> -#include "base/stl_util.h" #include "crypto/secure_hash.h" #include "third_party/boringssl/src/include/openssl/sha.h"
diff --git a/docs/threading_and_tasks.md b/docs/threading_and_tasks.md index c552860..f75b397 100644 --- a/docs/threading_and_tasks.md +++ b/docs/threading_and_tasks.md
@@ -18,7 +18,10 @@ threads. Our approach is to use message passing as the way of communicating between threads. We discourage locking and thread-safe objects. Instead, objects live on only one (often virtual -- we'll get to that later!) thread and we pass -messages between those threads for communication. +messages between those threads for communication. Absent external requirements +about latency or workload, Chrome attempts to be a [highly concurrent, but not +necessarily parallel](https://stackoverflow.com/questions/1050222/what-is-the-difference-between-concurrency-and-parallelism#:~:text=Concurrency%20is%20when%20two%20or,e.g.%2C%20on%20a%20multicore%20processor.) +, system. This documentation assumes familiarity with computer science [threading concepts](https://en.wikipedia.org/wiki/Thread_(computing)). @@ -85,8 +88,8 @@ Note that `base::SingleThreadTaskRunner` is-a `base::SequencedTaskRunner` so thread-affine is a subset of thread-unsafe. Thread-affine is also sometimes referred to as **thread-hostile**. - * **Thread-safe**: Such types/methods can be safely accessed concurrently. - * **Thread-compatible**: Such types provide safe concurrent access to const + * **Thread-safe**: Such types/methods can be safely accessed in parallel. + * **Thread-compatible**: Such types provide safe parallel access to const methods but require synchronization for non-const (or mixed const/non-const access). Chrome doesn't expose reader-writer locks; as such, the only use case for this is objects (typically globals) which are initialized once in a @@ -632,7 +635,7 @@ The [`base::PostJob`](https://cs.chromium.org/chromium/src/base/task/post_job.h) is a power user API to be able to schedule a single base::RepeatingCallback -worker task and request that ThreadPool workers invoke it concurrently. +worker task and request that ThreadPool workers invoke it in parallel. This avoids degenerate cases: * Calling `PostTask()` for each work item, causing significant overhead. * Fixed number of `PostTask()` calls that split the work and might run for a @@ -678,7 +681,7 @@ ### Adding additional work to a running job. When new work items are added and the API user wants additional threads to -invoke the worker task concurrently, +invoke the worker task in parallel, `JobHandle/JobDelegate::NotifyConcurrencyIncrease()` *must* be invoked shortly after max concurrency increases.
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index b925b36d..11f44309 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -716,6 +716,10 @@ "api/sockets_udp/test_udp_echo_server.h", "browsertest_util.cc", "browsertest_util.h", + "mock_display_info_provider.cc", + "mock_display_info_provider.h", + "mock_screen.cc", + "mock_screen.h", "preload_check_test_util.cc", "preload_check_test_util.h", "service_worker/service_worker_test_utils.cc",
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index 3845583..5f5fa931 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn
@@ -72,6 +72,7 @@ "clipboard/clipboard_api.h", ] deps += [ + "//chromeos/dbus/permission_broker", "//components/prefs:prefs", "//ui/base/clipboard", ] @@ -103,7 +104,6 @@ "//chromeos/dbus", "//chromeos/dbus/media_analytics", "//chromeos/dbus/media_analytics:media_perception_proto", - "//chromeos/dbus/permission_broker", "//chromeos/dbus/upstart", "//chromeos/login/login_state", "//chromeos/services/media_perception/public/mojom",
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc index f3482c1..3d7ac6f 100644 --- a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc +++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -256,7 +256,7 @@ const std::string* name = array[i]; const std::string* value = array[i+1]; if (dictionary->HasKey(*name)) { - std::unique_ptr<base::Value> entry_owned; + absl::optional<base::Value> entry_owned; base::Value* entry = dictionary->FindKey(*name); if (!entry) return nullptr; @@ -264,9 +264,9 @@ case base::Value::Type::STRING: { // Replace the present string with a list. auto list = std::make_unique<base::ListValue>(); - // Ignoring return value, we already verified the entry is there. - dictionary->RemoveWithoutPathExpansion(*name, &entry_owned); - list->Append(std::move(entry_owned)); + // No need to check again, we already verified the entry is there. + entry_owned = dictionary->ExtractKey(*name); + list->Append(base::Value::ToUniquePtrValue(std::move(*entry_owned))); list->AppendString(*value); dictionary->SetKey(*name, base::Value::FromUniquePtrValue(std::move(list)));
diff --git a/extensions/browser/api/device_permissions_prompt.cc b/extensions/browser/api/device_permissions_prompt.cc index 8642c23..d546818 100644 --- a/extensions/browser/api/device_permissions_prompt.cc +++ b/extensions/browser/api/device_permissions_prompt.cc
@@ -29,9 +29,9 @@ #include "services/device/public/mojom/usb_enumeration_options.mojom.h" #include "ui/base/l10n/l10n_util.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chromeos/dbus/permission_broker/permission_broker_client.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chromeos/dbus/permission_broker/permission_broker_client.h" // nogncheck +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) using device::HidDeviceFilter; using device::mojom::UsbDeviceFilterPtr; @@ -149,7 +149,7 @@ remaining_initial_devices_++; auto device_info = std::make_unique<UsbDeviceInfo>(device.Clone()); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) auto* device_manager = UsbDeviceManager::Get(browser_context()); DCHECK(device_manager); device_manager->CheckAccess( @@ -159,7 +159,7 @@ #else AddCheckedDevice(std::move(device_info), initial_enumeration, /*allowed=*/true); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) } void AddCheckedDevice(std::unique_ptr<UsbDeviceInfo> device_info, @@ -335,6 +335,7 @@ remaining_initial_devices_++; auto device_info = std::make_unique<HidDeviceInfo>(std::move(device)); + // TODO(huangs): Enable this for Lacros (crbug.com/1217124). #if BUILDFLAG(IS_CHROMEOS_ASH) chromeos::PermissionBrokerClient::Get()->CheckPathAccess( device_info.get()->device()->device_node,
diff --git a/extensions/browser/api/execute_code_function.cc b/extensions/browser/api/execute_code_function.cc index 36e193c..3c08925 100644 --- a/extensions/browser/api/execute_code_function.cc +++ b/extensions/browser/api/execute_code_function.cc
@@ -30,7 +30,6 @@ "at the same time in the second argument."; const char kBadFileEncodingError[] = "Could not load file '*' for content script. It isn't UTF-8 encoded."; -const char kLoadFileError[] = "Failed to load file: \"*\". "; const char kCSSOriginForNonCSSError[] = "CSS origin should be specified only for CSS code."; @@ -48,22 +47,24 @@ void ExecuteCodeFunction::DidLoadAndLocalizeFile( const std::string& file, - bool success, - std::unique_ptr<std::string> data) { - if (!success) { + std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> load_error) { + if (load_error) { // TODO(viettrungluu): bug: there's no particular reason the path should be // UTF-8, in which case this may fail. - Respond(Error(ErrorUtils::FormatErrorMessage(kLoadFileError, file))); + Respond(Error(std::move(*load_error))); return; } - if (!base::IsStringUTF8(*data)) { + DCHECK_EQ(1u, data.size()); + auto& file_data = data.front(); + if (!base::IsStringUTF8(*file_data)) { Respond(Error(ErrorUtils::FormatErrorMessage(kBadFileEncodingError, file))); return; } std::string error; - if (!Execute(*data, &error)) + if (!Execute(*file_data, &error)) Respond(Error(std::move(error))); // If Execute() succeeds, the function will respond in @@ -189,10 +190,11 @@ bool might_require_localization = ShouldInsertCSS() || ShouldRemoveCSS(); - LoadAndLocalizeResource( - *extension(), resource, might_require_localization, + std::string relative_path = resource.relative_path().AsUTF8Unsafe(); + LoadAndLocalizeResources( + *extension(), {std::move(resource)}, might_require_localization, base::BindOnce(&ExecuteCodeFunction::DidLoadAndLocalizeFile, this, - resource.relative_path().AsUTF8Unsafe())); + relative_path)); return true; }
diff --git a/extensions/browser/api/execute_code_function.h b/extensions/browser/api/execute_code_function.h index 265f78e7..f7f455d 100644 --- a/extensions/browser/api/execute_code_function.h +++ b/extensions/browser/api/execute_code_function.h
@@ -5,6 +5,10 @@ #ifndef EXTENSIONS_BROWSER_API_EXECUTE_CODE_FUNCTION_H_ #define EXTENSIONS_BROWSER_API_EXECUTE_CODE_FUNCTION_H_ +#include <memory> +#include <string> +#include <vector> + #include "base/macros.h" #include "extensions/browser/extension_function.h" #include "extensions/browser/script_executor.h" @@ -54,8 +58,8 @@ // Called when contents from the loaded file have been localized. void DidLoadAndLocalizeFile(const std::string& file, - bool success, - std::unique_ptr<std::string> data); + std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> load_error); const mojom::HostID& host_id() const { return host_id_; } void set_host_id(const mojom::HostID& host_id) { host_id_ = host_id; }
diff --git a/extensions/browser/api/extensions_api_client.cc b/extensions/browser/api/extensions_api_client.cc index 49cc8e6..11286a44 100644 --- a/extensions/browser/api/extensions_api_client.cc +++ b/extensions/browser/api/extensions_api_client.cc
@@ -110,11 +110,11 @@ return nullptr; } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) bool ExtensionsAPIClient::ShouldAllowDetachingUsb(int vid, int pid) const { return false; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) std::unique_ptr<VirtualKeyboardDelegate> ExtensionsAPIClient::CreateVirtualKeyboardDelegate(
diff --git a/extensions/browser/api/extensions_api_client.h b/extensions/browser/api/extensions_api_client.h index 5fcca48..441e5b7 100644 --- a/extensions/browser/api/extensions_api_client.h +++ b/extensions/browser/api/extensions_api_client.h
@@ -161,10 +161,10 @@ virtual std::unique_ptr<DevicePermissionsPrompt> CreateDevicePermissionsPrompt(content::WebContents* web_contents) const; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) // Returns true if device policy allows detaching a given USB device. virtual bool ShouldAllowDetachingUsb(int vid, int pid) const; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) // Returns a delegate for some of VirtualKeyboardAPI's behavior. virtual std::unique_ptr<VirtualKeyboardDelegate>
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc index 9c73d87b..9d8b2b22 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -523,14 +523,30 @@ return true; } +void WebViewInternalExecuteCodeFunction::DidLoadFileForWebUI( + const std::string& file, + bool success, + std::unique_ptr<std::string> data) { + std::vector<std::unique_ptr<std::string>> data_list; + absl::optional<std::string> error; + if (success) { + DCHECK(data); + data_list.push_back(std::move(data)); + } else { + error = base::StringPrintf("Failed to load file '%s'.", file.c_str()); + } + + DidLoadAndLocalizeFile(file, std::move(data_list), std::move(error)); +} + bool WebViewInternalExecuteCodeFunction::LoadFile(const std::string& file, std::string* error) { if (!extension()) { if (LoadFileForWebUI( *details_->file, base::BindOnce( - &WebViewInternalExecuteCodeFunction::DidLoadAndLocalizeFile, - this, file))) + &WebViewInternalExecuteCodeFunction::DidLoadFileForWebUI, this, + file))) return true; *error = ErrorUtils::FormatErrorMessage(kLoadFileError, file);
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h index d9e35c6..741bbee 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
@@ -110,6 +110,9 @@ // Loads a file url on WebUI. bool LoadFileForWebUI(const std::string& file_src, WebUIURLFetcher::WebUILoadFileCallback callback); + void DidLoadFileForWebUI(const std::string& file, + bool success, + std::unique_ptr<std::string> data); // Contains extension resource built from path of file which is // specified in JSON arguments.
diff --git a/extensions/browser/api/messaging/extension_message_port.cc b/extensions/browser/api/messaging/extension_message_port.cc index a94b8fe..8fcc08e 100644 --- a/extensions/browser/api/messaging/extension_message_port.cc +++ b/extensions/browser/api/messaging/extension_message_port.cc
@@ -8,7 +8,7 @@ #include <utility> #include "base/bind.h" -#include "base/containers/contains.h" +#include "base/notreached.h" #include "base/scoped_observation.h" #include "base/strings/strcat.h" #include "components/back_forward_cache/back_forward_cache_disable.h" @@ -157,40 +157,12 @@ base::WeakPtr<ChannelDelegate> channel_delegate, const PortId& port_id, const std::string& extension_id, - content::RenderProcessHost* extension_process) - : weak_channel_delegate_(channel_delegate), - port_id_(port_id), - extension_id_(extension_id), - browser_context_(extension_process->GetBrowserContext()), - extension_process_(extension_process), - did_create_port_(false), - background_host_ptr_(nullptr), - frame_tracker_(new FrameTracker(this)) { - auto all_hosts = ProcessManager::Get(browser_context_) - ->GetRenderFrameHostsForExtension(extension_id); - for (content::RenderFrameHost* rfh : all_hosts) - RegisterFrame(rfh); - - std::vector<WorkerId> running_workers_in_process = - ProcessManager::Get(browser_context_) - ->GetServiceWorkers(extension_id_, extension_process_->GetID()); - for (const WorkerId& running_worker_id : running_workers_in_process) - RegisterWorker(running_worker_id); - - frame_tracker_->TrackExtensionProcessFrames(); -} - -ExtensionMessagePort::ExtensionMessagePort( - base::WeakPtr<ChannelDelegate> channel_delegate, - const PortId& port_id, - const std::string& extension_id, content::RenderFrameHost* rfh, bool include_child_frames) : weak_channel_delegate_(channel_delegate), port_id_(port_id), extension_id_(extension_id), browser_context_(rfh->GetProcess()->GetBrowserContext()), - extension_process_(nullptr), did_create_port_(false), background_host_ptr_(nullptr), frame_tracker_(new FrameTracker(this)) { @@ -205,6 +177,33 @@ } } +// static +std::unique_ptr<ExtensionMessagePort> ExtensionMessagePort::CreateForExtension( + base::WeakPtr<ChannelDelegate> channel_delegate, + const PortId& port_id, + const ExtensionId& extension_id, + content::BrowserContext* browser_context) { + std::unique_ptr<ExtensionMessagePort> port(new ExtensionMessagePort( + channel_delegate, port_id, extension_id, browser_context)); + port->frame_tracker_ = std::make_unique<FrameTracker>(port.get()); + port->frame_tracker_->TrackExtensionProcessFrames(); + + port->for_all_extension_contexts_ = true; + + auto* process_manager = ProcessManager::Get(browser_context); + auto all_hosts = + process_manager->GetRenderFrameHostsForExtension(extension_id); + for (content::RenderFrameHost* rfh : all_hosts) + port->RegisterFrame(rfh); + + std::vector<WorkerId> running_workers = + process_manager->GetServiceWorkersForExtension(extension_id); + for (const WorkerId& running_worker_id : running_workers) + port->RegisterWorker(running_worker_id); + + return port; +} + ExtensionMessagePort::ExtensionMessagePort( base::WeakPtr<ChannelDelegate> channel_delegate, const PortId& port_id, @@ -284,12 +283,10 @@ // Only opener ports need to be revalidated, because these are created in the // renderer before the browser knows about them. - if (service_workers_.empty()) - DCHECK(!extension_process_); - DCHECK_LE(frames_.size() + service_workers_.size(), 1U); - - DCHECK(frames_.empty() ^ service_workers_.empty()) - << "Either frame or Service Worker should be present."; + DCHECK(!for_all_extension_contexts_); + DCHECK_EQ(frames_.size() + service_workers_.size(), 1U) + << "RevalidatePort() should only be called for opener ports which " + "correspond to a single 'context'."; // If the port is unknown, the renderer will respond by closing the port. // NOTE: There is only one opener target. @@ -386,7 +383,7 @@ port_context.frame->routing_id != MSG_ROUTING_NONE) || (port_context.is_for_service_worker() && port_context.worker->thread_id != kMainThreadId) || - extension_process_); + for_all_extension_contexts_); did_create_port_ = true; } @@ -398,7 +395,7 @@ if (!is_for_service_worker && routing_id == MSG_ROUTING_NONE) { // The only non-frame-specific message is the response to an unhandled // onConnect event in the extension process. - DCHECK(extension_process_); + DCHECK(for_all_extension_contexts_); ClearFrames(); if (!HasReceivers()) CloseChannel(); @@ -488,25 +485,14 @@ void ExtensionMessagePort::SendToPort(IPCBuilderCallback ipc_builder) { std::vector<IPCTarget> targets; - { - // Build the list of targets. - if (extension_process_) { - // All extension frames reside in the same process, so we can just send a - // single IPC message to the extension process as an optimization if - // there are not Service Worker recipient for this port. - // The frame tracking is then only used to make sure that the port gets - // closed when all frames have closed / reloaded. - targets.push_back({extension_process_, nullptr, kMainThreadId}); - } else { - for (content::RenderFrameHost* frame : frames_) - targets.push_back({nullptr, frame, kMainThreadId}); - } + // Build the list of targets. + for (content::RenderFrameHost* frame : frames_) + targets.push_back({nullptr, frame, kMainThreadId}); - for (const auto& running_worker : service_workers_) { - targets.push_back( - {content::RenderProcessHost::FromID(running_worker.render_process_id), - nullptr, running_worker.thread_id}); - } + for (const auto& running_worker : service_workers_) { + targets.push_back( + {content::RenderProcessHost::FromID(running_worker.render_process_id), + nullptr, running_worker.thread_id}); } for (const IPCTarget& target : targets) { @@ -529,9 +515,7 @@ return; } - DCHECK(extension_process_); - msg->set_routing_id(MSG_ROUTING_CONTROL); - extension_process_->Send(msg.release()); + NOTREACHED(); } std::unique_ptr<IPC::Message> ExtensionMessagePort::BuildDispatchOnConnectIPC(
diff --git a/extensions/browser/api/messaging/extension_message_port.h b/extensions/browser/api/messaging/extension_message_port.h index 0a31317b..838ac93 100644 --- a/extensions/browser/api/messaging/extension_message_port.h +++ b/extensions/browser/api/messaging/extension_message_port.h
@@ -25,7 +25,6 @@ namespace content { class BrowserContext; class RenderFrameHost; -class RenderProcessHost; } // namespace content namespace IPC { @@ -48,12 +47,14 @@ const std::string& extension_id, content::RenderFrameHost* rfh, bool include_child_frames); - // Create a port that is tied to all frames of an extension, possibly spanning - // multiple tabs, including the invisible background page, popups, etc. - ExtensionMessagePort(base::WeakPtr<ChannelDelegate> channel_delegate, - const PortId& port_id, - const std::string& extension_id, - content::RenderProcessHost* extension_process); + + // Create a port that is tied to all frames and service workers of an + // extension. + static std::unique_ptr<ExtensionMessagePort> CreateForExtension( + base::WeakPtr<ChannelDelegate> channel_delegate, + const PortId& port_id, + const std::string& extension_id, + content::BrowserContext* browser_context); // Creates a port for any ChannelEndpoint which can be for a render frame or // Service Worker. @@ -150,8 +151,10 @@ const PortId port_id_; std::string extension_id_; content::BrowserContext* browser_context_ = nullptr; - // Only for receivers in an extension process. - content::RenderProcessHost* extension_process_ = nullptr; + + // Whether this port corresponds to *all* extension contexts. Should only be + // true for a receiver port. + bool for_all_extension_contexts_ = false; // When the port is used as a sender, this set contains only one element. // If used as a receiver, it may contain any number of frames.
diff --git a/extensions/browser/api/messaging/message_port.h b/extensions/browser/api/messaging/message_port.h index de64b4eb..1921768e 100644 --- a/extensions/browser/api/messaging/message_port.h +++ b/extensions/browser/api/messaging/message_port.h
@@ -56,7 +56,8 @@ virtual bool IsValidPort() = 0; // Triggers the check of whether the port is still valid. If the port is - // determined to be invalid, the channel will be closed. + // determined to be invalid, the channel will be closed. This should only be + // called for opener ports. virtual void RevalidatePort(); // Notifies the port that the channel has been opened.
diff --git a/extensions/browser/api/messaging/message_service.cc b/extensions/browser/api/messaging/message_service.cc index f1efcf6..2a02eb24 100644 --- a/extensions/browser/api/messaging/message_service.cc +++ b/extensions/browser/api/messaging/message_service.cc
@@ -161,19 +161,6 @@ DISALLOW_COPY_AND_ASSIGN(OpenChannelParams); }; -namespace { - -static content::RenderProcessHost* GetExtensionProcess( - BrowserContext* context, - const std::string& extension_id) { - scoped_refptr<SiteInstance> site_instance = - ProcessManager::Get(context)->GetSiteInstanceForURL( - Extension::GetBaseURLFromExtensionId(extension_id)); - return site_instance->HasProcess() ? site_instance->GetProcess() : NULL; -} - -} // namespace - MessageService::MessageService(BrowserContext* context) : context_(context), messaging_delegate_(ExtensionsAPIClient::Get()->GetMessagingDelegate()) { @@ -327,7 +314,6 @@ source_port_id.GetOppositePortId(), source_endpoint, std::move(opener_port), target_extension_id, source_url, std::move(source_origin), channel_name, include_guest_process_info)); - pending_incognito_channels_[params->receiver_port_id.GetChannelId()] = PendingMessagesQueue(); if (context->IsOffTheRecord() && @@ -805,7 +791,7 @@ return false; // If the extension uses spanning incognito mode, make sure we're always - // using the original profile since that is what the extension process + // using the original profile since that is what the extension processes // will use. if (!IncognitoInfo::IsSplitMode(extension)) context = ExtensionsBrowserClient::Get()->GetOriginalContext(context); @@ -862,19 +848,6 @@ BrowserContext* context = source.browser_context(); DCHECK(ExtensionsBrowserClient::Get()->IsSameContext(context, context_)); - // Note: we use the source's profile here. If the source is an incognito - // process, we will use the incognito EPM to find the right extension process, - // which depends on whether the extension uses spanning or split mode. - if (content::RenderProcessHost* extension_process = - GetExtensionProcess(context, params->target_extension_id)) { - params->receiver = std::make_unique<ExtensionMessagePort>( - - weak_factory_.GetWeakPtr(), params->receiver_port_id, - params->target_extension_id, extension_process); - } else { - params->receiver.reset(); - } - ExtensionRegistry* registry = ExtensionRegistry::Get(context); const Extension* target_extension = registry->enabled_extensions().GetByID(params->target_extension_id); @@ -883,6 +856,14 @@ return; } + BrowserContext* context_to_use_for_extension = + IncognitoInfo::IsSplitMode(target_extension) + ? context + : ExtensionsBrowserClient::Get()->GetOriginalContext(context); + params->receiver = ExtensionMessagePort::CreateForExtension( + weak_factory_.GetWeakPtr(), params->receiver_port_id, + params->target_extension_id, context_to_use_for_extension); + // The target might be a lazy background page or a Service Worker. In that // case, we have to check if it is loaded and ready, and if not, queue up the // task and load the page. @@ -902,9 +883,9 @@ if (context_info == nullptr) return; // TODO(mpcomplete): notify source of disconnect? - params->receiver = std::make_unique<ExtensionMessagePort>( + params->receiver = ExtensionMessagePort::CreateForExtension( weak_factory_.GetWeakPtr(), params->receiver_port_id, - params->target_extension_id, context_info->render_process_host); + params->target_extension_id, context_info->browser_context); const Extension* const extension = extensions::ExtensionRegistry::Get(context_info->browser_context) ->enabled_extensions()
diff --git a/extensions/browser/api/system_display/system_display_apitest.cc b/extensions/browser/api/system_display/system_display_apitest.cc index f0e63ca4b..bf4ff474 100644 --- a/extensions/browser/api/system_display/system_display_apitest.cc +++ b/extensions/browser/api/system_display/system_display_apitest.cc
@@ -2,23 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <stdint.h> - #include <memory> -#include <set> -#include <utility> +#include <string> #include "base/bind.h" -#include "base/containers/contains.h" #include "base/debug/leak_annotations.h" #include "base/macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "extensions/browser/api/system_display/display_info_provider.h" #include "extensions/browser/api/system_display/system_display_api.h" #include "extensions/browser/api_test_utils.h" +#include "extensions/browser/mock_display_info_provider.h" +#include "extensions/browser/mock_screen.h" #include "extensions/common/api/system_display.h" #include "extensions/common/extension_builder.h" #include "extensions/shell/test/shell_apitest.h" @@ -29,194 +25,9 @@ namespace extensions { -using api::system_display::Bounds; -using api::system_display::DisplayUnitInfo; using display::Screen; using display::test::ScopedScreenOverride; -class MockScreen : public Screen { - public: - MockScreen() { - for (int i = 0; i < 4; i++) { - gfx::Rect bounds(0, 0, 1280, 720); - gfx::Rect work_area(0, 0, 960, 720); - display::Display display(i, bounds); - display.set_work_area(work_area); - displays_.push_back(display); - } - } - ~MockScreen() override {} - - protected: - // Overridden from display::Screen: - gfx::Point GetCursorScreenPoint() override { return gfx::Point(); } - bool IsWindowUnderCursor(gfx::NativeWindow window) override { return false; } - gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override { - return gfx::NativeWindow(); - } - gfx::NativeWindow GetLocalProcessWindowAtPoint( - const gfx::Point& point, - const std::set<gfx::NativeWindow>& ignore) override { - return nullptr; - } - int GetNumDisplays() const override { - return static_cast<int>(displays_.size()); - } - const std::vector<display::Display>& GetAllDisplays() const override { - return displays_; - } - display::Display GetDisplayNearestWindow( - gfx::NativeWindow window) const override { - return display::Display(0); - } - display::Display GetDisplayNearestPoint( - const gfx::Point& point) const override { - return display::Display(0); - } - display::Display GetDisplayMatching( - const gfx::Rect& match_rect) const override { - return display::Display(0); - } - display::Display GetPrimaryDisplay() const override { return displays_[0]; } - void AddObserver(display::DisplayObserver* observer) override {} - void RemoveObserver(display::DisplayObserver* observer) override {} - - private: - std::vector<display::Display> displays_; - - DISALLOW_COPY_AND_ASSIGN(MockScreen); -}; - -class MockDisplayInfoProvider : public DisplayInfoProvider { - public: - MockDisplayInfoProvider() {} - - ~MockDisplayInfoProvider() override {} - - void SetDisplayProperties( - const std::string& display_id, - const api::system_display::DisplayProperties& properties, - ErrorCallback callback) override { - // Should get called only once per test case. - EXPECT_FALSE(set_info_value_); - set_info_value_ = properties.ToValue(); - set_info_display_id_ = display_id; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt)); - } - - void EnableUnifiedDesktop(bool enable) override { - unified_desktop_enabled_ = enable; - } - - bool OverscanCalibrationStart(const std::string& id) override { - if (base::Contains(overscan_started_, id)) - return false; - overscan_started_.insert(id); - return true; - } - - bool OverscanCalibrationAdjust( - const std::string& id, - const api::system_display::Insets& delta) override { - if (!base::Contains(overscan_started_, id)) - return false; - overscan_adjusted_.insert(id); - return true; - } - - bool OverscanCalibrationReset(const std::string& id) override { - if (!base::Contains(overscan_started_, id)) - return false; - overscan_adjusted_.erase(id); - return true; - } - - bool OverscanCalibrationComplete(const std::string& id) override { - if (!base::Contains(overscan_started_, id)) - return false; - overscan_started_.erase(id); - return true; - } - - std::unique_ptr<base::DictionaryValue> GetSetInfoValue() { - return std::move(set_info_value_); - } - - std::string GetSetInfoDisplayId() const { return set_info_display_id_; } - - bool unified_desktop_enabled() const { return unified_desktop_enabled_; } - - bool calibration_started(const std::string& id) const { - return base::Contains(overscan_started_, id); - } - - bool calibration_changed(const std::string& id) const { - return base::Contains(overscan_adjusted_, id); - } - - const api::system_display::MirrorMode& mirror_mode() const { - return mirror_mode_; - } - - void SetTouchCalibrationWillSucceed(bool success) { - native_touch_calibration_success_ = success; - } - - void ShowNativeTouchCalibration(const std::string& id, - ErrorCallback callback) override { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), - native_touch_calibration_success_ - ? absl::nullopt - : absl::optional<std::string>("failed"))); - } - - void SetMirrorMode(const api::system_display::MirrorModeInfo& info, - ErrorCallback callback) override { - mirror_mode_ = info.mode; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt)); - } - - private: - // Update the content of the |unit| obtained for |display| using - // platform specific method. - void UpdateDisplayUnitInfoForPlatform( - const display::Display& display, - extensions::api::system_display::DisplayUnitInfo* unit) override { - int64_t id = display.id(); - unit->name = "DISPLAY NAME FOR " + base::NumberToString(id); - if (id == 1) - unit->mirroring_source_id = "0"; - unit->is_primary = id == 0 ? true : false; - unit->is_internal = id == 0 ? true : false; - unit->is_enabled = true; - unit->rotation = (90 * id) % 360; - unit->dpi_x = 96.0; - unit->dpi_y = 96.0; - if (id == 0) { - unit->overscan.left = 20; - unit->overscan.top = 40; - unit->overscan.right = 60; - unit->overscan.bottom = 80; - } - } - - std::unique_ptr<base::DictionaryValue> set_info_value_; - std::string set_info_display_id_; - bool unified_desktop_enabled_ = false; - std::set<std::string> overscan_started_; - std::set<std::string> overscan_adjusted_; - - bool native_touch_calibration_success_ = false; - - api::system_display::MirrorMode mirror_mode_ = - api::system_display::MIRROR_MODE_OFF; - - DISALLOW_COPY_AND_ASSIGN(MockDisplayInfoProvider); -}; - class SystemDisplayApiTest : public ShellApiTest { public: SystemDisplayApiTest()
diff --git a/extensions/browser/api/usb/usb_apitest.cc b/extensions/browser/api/usb/usb_apitest.cc index 6290db8e..436d0e7d 100644 --- a/extensions/browser/api/usb/usb_apitest.cc +++ b/extensions/browser/api/usb/usb_apitest.cc
@@ -114,11 +114,11 @@ return std::make_unique<TestDevicePermissionsPrompt>(web_contents); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) bool ShouldAllowDetachingUsb(int vid, int pid) const override { return vid == 1 && pid == 2; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) }; class UsbApiTest : public ShellApiTest { @@ -365,7 +365,7 @@ ASSERT_TRUE(result_listener.WaitUntilSatisfied()); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) IN_PROC_BROWSER_TEST_F(UsbApiTest, MassStorage) { ExtensionTestMessageListener ready_listener("ready", false); ready_listener.set_failure_message("failure"); @@ -397,6 +397,6 @@ ASSERT_TRUE(result_listener.WaitUntilSatisfied()); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) } // namespace extensions
diff --git a/extensions/browser/api/usb/usb_device_manager.cc b/extensions/browser/api/usb/usb_device_manager.cc index a0b7ccd..31c4c0a 100644 --- a/extensions/browser/api/usb/usb_device_manager.cc +++ b/extensions/browser/api/usb/usb_device_manager.cc
@@ -52,12 +52,12 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) if (ExtensionsAPIClient::Get()->ShouldAllowDetachingUsb( device_info.vendor_id, device_info.product_id)) { return true; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) return false; } @@ -212,14 +212,14 @@ return true; } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void UsbDeviceManager::CheckAccess( const std::string& guid, device::mojom::UsbDeviceManager::CheckAccessCallback callback) { EnsureConnectionWithDeviceManager(); device_manager_->CheckAccess(guid, std::move(callback)); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void UsbDeviceManager::EnsureConnectionWithDeviceManager() { if (device_manager_)
diff --git a/extensions/browser/api/usb/usb_device_manager.h b/extensions/browser/api/usb/usb_device_manager.h index 13eacd11..3183209 100644 --- a/extensions/browser/api/usb/usb_device_manager.h +++ b/extensions/browser/api/usb/usb_device_manager.h
@@ -70,11 +70,11 @@ const device::mojom::UsbDeviceInfo* GetDeviceInfo(const std::string& guid); bool UpdateActiveConfig(const std::string& guid, uint8_t config_value); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void CheckAccess( const std::string& guid, device::mojom::UsbDeviceManager::CheckAccessCallback callback); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void EnsureConnectionWithDeviceManager();
diff --git a/extensions/browser/computed_hashes.cc b/extensions/browser/computed_hashes.cc index 282e4587..3bb3395 100644 --- a/extensions/browser/computed_hashes.cc +++ b/extensions/browser/computed_hashes.cc
@@ -15,7 +15,6 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/logging.h" -#include "base/stl_util.h" #include "base/timer/elapsed_timer.h" #include "base/values.h" #include "build/build_config.h"
diff --git a/extensions/browser/content_hash_tree.cc b/extensions/browser/content_hash_tree.cc index a8fa8d5..5df4677 100644 --- a/extensions/browser/content_hash_tree.cc +++ b/extensions/browser/content_hash_tree.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "base/stl_util.h" #include "crypto/secure_hash.h" #include "crypto/sha2.h"
diff --git a/extensions/browser/content_hash_tree_unittest.cc b/extensions/browser/content_hash_tree_unittest.cc index 9f7281e..2b7d22b 100644 --- a/extensions/browser/content_hash_tree_unittest.cc +++ b/extensions/browser/content_hash_tree_unittest.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "base/stl_util.h" #include "crypto/secure_hash.h" #include "crypto/sha2.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc index 6dfe498b..498fe0d 100644 --- a/extensions/browser/content_verify_job.cc +++ b/extensions/browser/content_verify_job.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/lazy_instance.h" #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/timer/elapsed_timer.h"
diff --git a/extensions/browser/file_reader.cc b/extensions/browser/file_reader.cc index 5489a88..256ab15 100644 --- a/extensions/browser/file_reader.cc +++ b/extensions/browser/file_reader.cc
@@ -7,39 +7,54 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/files/file_util.h" +#include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "extensions/browser/extension_file_task_runner.h" -FileReader::FileReader(const extensions::ExtensionResource& resource, +FileReader::FileReader(std::vector<extensions::ExtensionResource> resources, OptionalFileSequenceTask optional_file_sequence_task, DoneCallback done_callback) - : resource_(resource), + : resources_(std::move(resources)), optional_file_sequence_task_(std::move(optional_file_sequence_task)), done_callback_(std::move(done_callback)), origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} void FileReader::Start() { extensions::GetExtensionFileTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&FileReader::ReadFileOnFileSequence, this)); + FROM_HERE, base::BindOnce(&FileReader::ReadFilesOnFileSequence, this)); } FileReader::~FileReader() {} -void FileReader::ReadFileOnFileSequence() { +void FileReader::ReadFilesOnFileSequence() { DCHECK( extensions::GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence()); - std::unique_ptr<std::string> data(new std::string()); - bool success = base::ReadFileToString(resource_.GetFilePath(), data.get()); + std::vector<std::unique_ptr<std::string>> data; + data.reserve(resources_.size()); + absl::optional<std::string> error; + for (const auto& resource : resources_) { + data.push_back(std::make_unique<std::string>()); + std::string* file_data = data.back().get(); + bool success = base::ReadFileToString(resource.GetFilePath(), file_data); + if (!success) { + error = + base::StringPrintf("Could not load file: '%s'.", + resource.relative_path().AsUTF8Unsafe().c_str()); + // Clear `data` to avoid passing a partial result. + data.clear(); - if (optional_file_sequence_task_) { - if (success) - std::move(optional_file_sequence_task_).Run(data.get()); - else - optional_file_sequence_task_.Reset(); + break; + } + + if (optional_file_sequence_task_) + optional_file_sequence_task_.Run(file_data); } + // Release any potentially-bound references from the file sequence task. + optional_file_sequence_task_.Reset(); + origin_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(done_callback_), success, std::move(data))); + FROM_HERE, base::BindOnce(std::move(done_callback_), std::move(data), + std::move(error))); }
diff --git a/extensions/browser/file_reader.h b/extensions/browser/file_reader.h index 236749c3..144e173 100644 --- a/extensions/browser/file_reader.h +++ b/extensions/browser/file_reader.h
@@ -6,32 +6,37 @@ #define EXTENSIONS_BROWSER_FILE_READER_H_ #include <string> +#include <vector> #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "extensions/common/extension_resource.h" +#include "third_party/abseil-cpp/absl/types/optional.h" -// This file defines an interface for reading a file asynchronously on a +// This file defines an interface for reading files asynchronously on a // background sequence. // Consider abstracting out a FilePathProvider (ExtensionResource) and moving // back to chrome/browser/net if other subsystems want to use it. class FileReader : public base::RefCountedThreadSafe<FileReader> { public: - // Reports success or failure and the data of the file upon success. + // Passes the result of loading the files in `data`, or reports the + // encountered error in `error`. If there was an error, `data` will be empty. using DoneCallback = - base::OnceCallback<void(bool, std::unique_ptr<std::string>)>; - // Lets the caller accomplish tasks on the file data, after the file content - // has been read. - // If the file reading doesn't succeed, this will be ignored. - using OptionalFileSequenceTask = base::OnceCallback<void(std::string*)>; + base::OnceCallback<void(std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> error)>; - FileReader(const extensions::ExtensionResource& resource, + // Lets the caller accomplish tasks on the file data, after the file content + // has been read. This is called once per file successfully read (it is not + // invoked if a file read fails). + using OptionalFileSequenceTask = base::RepeatingCallback<void(std::string*)>; + + FileReader(std::vector<extensions::ExtensionResource> resources, OptionalFileSequenceTask file_sequence_task, DoneCallback done_callback); - // Called to start reading the file on a background sequence. Upon completion, - // the callback will be notified of the results. + // Called to start reading the files on a background sequence. Upon + // completion, the callback will be notified of the results. void Start(); private: @@ -39,9 +44,9 @@ ~FileReader(); - void ReadFileOnFileSequence(); + void ReadFilesOnFileSequence(); - extensions::ExtensionResource resource_; + std::vector<extensions::ExtensionResource> resources_; OptionalFileSequenceTask optional_file_sequence_task_; DoneCallback done_callback_; const scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
diff --git a/extensions/browser/file_reader_unittest.cc b/extensions/browser/file_reader_unittest.cc index 8a312f1..a795f0c 100644 --- a/extensions/browser/file_reader_unittest.cc +++ b/extensions/browser/file_reader_unittest.cc
@@ -14,7 +14,9 @@ #include "components/crx_file/id_util.h" #include "extensions/common/extension_paths.h" #include "extensions/common/extension_resource.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace extensions { @@ -30,10 +32,9 @@ class Receiver { public: - Receiver(const ExtensionResource& resource) - : succeeded_(false), - file_reader_(new FileReader( - resource, + explicit Receiver(std::vector<ExtensionResource> resources) + : file_reader_(base::MakeRefCounted<FileReader>( + std::move(resources), FileReader::OptionalFileSequenceTask(), base::BindOnce(&Receiver::DidReadFile, base::Unretained(this)))) {} @@ -42,48 +43,77 @@ run_loop_.Run(); } - bool succeeded() const { return succeeded_; } - const std::string& data() const { return *data_; } + // Removes the pointer indirection from the read data for use with + // comparators. + std::vector<std::string> GetStringData() const { + std::vector<std::string> string_data; + string_data.reserve(data_.size()); + for (const auto& entry : data_) { + EXPECT_TRUE(entry); + string_data.push_back(*entry); + } + return string_data; + } + + const absl::optional<std::string>& error() const { return error_; } + bool succeeded() const { return !error_; } + const std::vector<std::unique_ptr<std::string>>& data() const { + return data_; + } private: - void DidReadFile(bool success, std::unique_ptr<std::string> data) { - succeeded_ = success; + void DidReadFile(std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> error) { + error_ = std::move(error); data_ = std::move(data); run_loop_.QuitWhenIdle(); } - bool succeeded_; - std::unique_ptr<std::string> data_; + absl::optional<std::string> error_; + std::vector<std::unique_ptr<std::string>> data_; scoped_refptr<FileReader> file_reader_; base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(Receiver); }; -void RunBasicTest(const char* filename) { - base::FilePath path; - base::PathService::Get(DIR_TEST_DATA, &path); +void RunBasicTest(const std::vector<std::string>& filenames) { + base::FilePath root_path; + base::PathService::Get(DIR_TEST_DATA, &root_path); std::string extension_id = crx_file::id_util::GenerateId("test"); - ExtensionResource resource( - extension_id, path, base::FilePath().AppendASCII(filename)); - path = path.AppendASCII(filename); - std::string file_contents; - ASSERT_TRUE(base::ReadFileToString(path, &file_contents)); + std::vector<ExtensionResource> resources; + resources.reserve(filenames.size()); + std::vector<std::string> expected_contents; + expected_contents.reserve(filenames.size()); + for (const auto& filename : filenames) { + resources.emplace_back(extension_id, root_path, + base::FilePath().AppendASCII(filename)); - Receiver receiver(resource); + base::FilePath path = root_path.AppendASCII(filename); + std::string file_contents; + ASSERT_TRUE(base::ReadFileToString(path, &file_contents)); + expected_contents.push_back(std::move(file_contents)); + } + + Receiver receiver(resources); receiver.Run(); - EXPECT_TRUE(receiver.succeeded()); - EXPECT_EQ(file_contents, receiver.data()); + EXPECT_TRUE(receiver.succeeded()) << *receiver.error(); + EXPECT_THAT(receiver.GetStringData(), + ::testing::ElementsAreArray(expected_contents)); } TEST_F(FileReaderTest, SmallFile) { - RunBasicTest("smallfile"); + RunBasicTest({"smallfile"}); } TEST_F(FileReaderTest, BiggerFile) { - RunBasicTest("bigfile"); + RunBasicTest({"bigfile"}); +} + +TEST_F(FileReaderTest, MultiFile) { + RunBasicTest({"smallfile", "bigfile"}); } TEST_F(FileReaderTest, NonExistentFile) { @@ -94,10 +124,12 @@ FILE_PATH_LITERAL("file_that_does_not_exist"))); path = path.AppendASCII("file_that_does_not_exist"); - Receiver receiver(resource); + Receiver receiver({resource}); receiver.Run(); EXPECT_FALSE(receiver.succeeded()); + EXPECT_EQ("Could not load file: 'file_that_does_not_exist'.", + *receiver.error()); } } // namespace extensions
diff --git a/extensions/browser/load_and_localize_file.cc b/extensions/browser/load_and_localize_file.cc index ff797175..f3450e2d 100644 --- a/extensions/browser/load_and_localize_file.cc +++ b/extensions/browser/load_and_localize_file.cc
@@ -50,27 +50,55 @@ // A simple wrapper around MaybeLocalizeInBackground() that returns |data| to // serve as an adapter for PostTaskAndReply. -std::unique_ptr<std::string> LocalizeComponentResourceInBackground( - std::unique_ptr<std::string> data, +std::vector<std::unique_ptr<std::string>> +LocalizeComponentResourcesInBackground( + std::vector<std::unique_ptr<std::string>> data, const ExtensionId& extension_id, const base::FilePath& extension_path, const std::string& extension_default_locale, extension_l10n_util::GzippedMessagesPermission gzip_permission) { - MaybeLocalizeInBackground(extension_id, extension_path, - extension_default_locale, gzip_permission, - data.get()); + for (auto& resource : data) { + MaybeLocalizeInBackground(extension_id, extension_path, + extension_default_locale, gzip_permission, + resource.get()); + } + + return data; +} + +// A helper function to load component resources. +std::vector<std::unique_ptr<std::string>> LoadComponentResources( + const ComponentExtensionResourceManager& resource_manager, + const std::vector<ExtensionResource>& resources) { + std::vector<std::unique_ptr<std::string>> data; + data.reserve(resources.size()); + for (const auto& resource : resources) { + int resource_id = 0; + bool is_component_resource = resource_manager.IsComponentExtensionResource( + resource.extension_root(), resource.relative_path(), &resource_id); + DCHECK(is_component_resource) + << "If any resources passed to LoadAndLocalizeResources() " + "are component resources, they all must be."; + auto resource_data = std::make_unique<std::string>( + ui::ResourceBundle::GetSharedInstance().LoadDataResourceString( + resource_id)); + data.push_back(std::move(resource_data)); + } return data; } } // namespace -void LoadAndLocalizeResource(const Extension& extension, - const ExtensionResource& resource, - bool localize_file, - LoadAndLocalizeResourceCallback callback) { - DCHECK(!resource.extension_root().empty()); - DCHECK(!resource.relative_path().empty()); +void LoadAndLocalizeResources(const Extension& extension, + std::vector<ExtensionResource> resources, + bool localize_file, + LoadAndLocalizeResourcesCallback callback) { + DCHECK(!resources.empty()); + DCHECK(base::ranges::all_of(resources, [](const ExtensionResource& resource) { + return !resource.extension_root().empty() && + !resource.relative_path().empty(); + })); std::string extension_default_locale; extension.manifest()->GetString(manifest_keys::kDefaultLocale, @@ -80,47 +108,60 @@ // Check whether the resource should be loaded as a component resource (from // the resource bundle) or read from disk. - int resource_id = 0; + // We assume (and assert) that if any resource is a component extension + // resource, they all must be. Read the first resource passed to check if it + // is a component resource, and treat them all as such if it is. const ComponentExtensionResourceManager* component_extension_resource_manager = ExtensionsBrowserClient::Get() ->GetComponentExtensionResourceManager(); - if (component_extension_resource_manager && + int unused_resource_id = 0; + bool are_component_resources = + component_extension_resource_manager && component_extension_resource_manager->IsComponentExtensionResource( - resource.extension_root(), resource.relative_path(), &resource_id)) { - auto data = std::make_unique<std::string>( - ui::ResourceBundle::GetSharedInstance().LoadDataResourceString( - resource_id)); - - // We assume this call always succeeds. - constexpr bool kSuccess = true; + resources.front().extension_root(), resources.front().relative_path(), + &unused_resource_id); + if (are_component_resources) { + std::vector<std::unique_ptr<std::string>> data = LoadComponentResources( + *component_extension_resource_manager, resources); + // Even if no localization is necessary, we post the task asynchronously + // so that |callback| is not run re-entrantly. if (!localize_file) { - // Even if no localization is necessary, we post the task asynchronously - // so that |callback| is not run re-entrantly. base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::BindOnce(std::move(callback), kSuccess, std::move(data))); + base::BindOnce(std::move(callback), std::move(data), absl::nullopt)); } else { + auto callback_adapter = + [](LoadAndLocalizeResourcesCallback callback, + std::vector<std::unique_ptr<std::string>> data) { + std::move(callback).Run(std::move(data), absl::nullopt); + }; base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&LocalizeComponentResourceInBackground, + base::BindOnce(&LocalizeComponentResourcesInBackground, std::move(data), extension.id(), extension.path(), extension_default_locale, gzip_permission), - base::BindOnce(std::move(callback), kSuccess)); - } - } else { - FileReader::OptionalFileSequenceTask get_file_and_l10n_callback; - if (localize_file) { - get_file_and_l10n_callback = base::BindOnce( - &MaybeLocalizeInBackground, extension.id(), extension.path(), - extension_default_locale, gzip_permission); + base::BindOnce(callback_adapter, std::move(callback))); } - auto file_reader = base::MakeRefCounted<FileReader>( - resource, std::move(get_file_and_l10n_callback), std::move(callback)); - file_reader->Start(); + return; } + + // Otherwise, it's not a set of component resources, and we need to load them + // from disk. + + FileReader::OptionalFileSequenceTask get_file_and_l10n_callback; + if (localize_file) { + get_file_and_l10n_callback = base::BindRepeating( + &MaybeLocalizeInBackground, extension.id(), extension.path(), + extension_default_locale, gzip_permission); + } + + auto file_reader = base::MakeRefCounted<FileReader>( + std::move(resources), std::move(get_file_and_l10n_callback), + std::move(callback)); + file_reader->Start(); } } // namespace extensions
diff --git a/extensions/browser/load_and_localize_file.h b/extensions/browser/load_and_localize_file.h index 50c232bc..593a37440 100644 --- a/extensions/browser/load_and_localize_file.h +++ b/extensions/browser/load_and_localize_file.h
@@ -7,29 +7,30 @@ #include <memory> #include <string> +#include <vector> #include "base/callback.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace extensions { class Extension; class ExtensionResource; -// Invoked with the result of the file read and localization. The bool -// indicates success and failure. On success, |data| contains the -// localized content of the file. -// TODO(devlin): Update this to just pass |data| and have null indicate -// failure once FileReader's callback signature is updated. -using LoadAndLocalizeResourceCallback = - base::OnceCallback<void(bool success, std::unique_ptr<std::string> data)>; +// Invoked with the result of the file read and localization. +// `data` is a vector that contains the result of the localized content of the +// files. `error` indicates the error, if any. +using LoadAndLocalizeResourcesCallback = + base::OnceCallback<void(std::vector<std::unique_ptr<std::string>> data, + absl::optional<std::string> error)>; -// Loads |resource| from |extension|, optionally localizing the content, and +// Loads |resources| from |extension|, optionally localizing the content, and // invokes |callback| with the result. Handles both component and non-component -// extension resources. |resource| must be valid. Note: |callback| is always +// extension resources. |resources| must be valid. Note: |callback| is always // invoked asynchronously. -void LoadAndLocalizeResource(const Extension& extension, - const ExtensionResource& resource, - bool localize_file, - LoadAndLocalizeResourceCallback callback); +void LoadAndLocalizeResources(const Extension& extension, + std::vector<ExtensionResource> resources, + bool localize_files, + LoadAndLocalizeResourcesCallback callback); } // namespace extensions
diff --git a/extensions/browser/mock_display_info_provider.cc b/extensions/browser/mock_display_info_provider.cc new file mode 100644 index 0000000..56ae05d --- /dev/null +++ b/extensions/browser/mock_display_info_provider.cc
@@ -0,0 +1,117 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/mock_display_info_provider.h" + +#include <stdint.h> + +#include "base/bind.h" +#include "base/check.h" +#include "base/containers/contains.h" +#include "base/strings/string_number_conversions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" + +namespace extensions { + +MockDisplayInfoProvider::MockDisplayInfoProvider() = default; + +MockDisplayInfoProvider::~MockDisplayInfoProvider() = default; + +void MockDisplayInfoProvider::SetDisplayProperties( + const std::string& display_id, + const api::system_display::DisplayProperties& properties, + ErrorCallback callback) { + // Should get called only once per test case. + DCHECK(!set_info_value_); + set_info_value_ = properties.ToValue(); + set_info_display_id_ = display_id; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt)); +} + +void MockDisplayInfoProvider::EnableUnifiedDesktop(bool enable) { + unified_desktop_enabled_ = enable; +} + +bool MockDisplayInfoProvider::OverscanCalibrationStart(const std::string& id) { + if (base::Contains(overscan_started_, id)) + return false; + overscan_started_.insert(id); + return true; +} + +bool MockDisplayInfoProvider::OverscanCalibrationAdjust( + const std::string& id, + const api::system_display::Insets& delta) { + if (!base::Contains(overscan_started_, id)) + return false; + overscan_adjusted_.insert(id); + return true; +} + +bool MockDisplayInfoProvider::OverscanCalibrationReset(const std::string& id) { + if (!base::Contains(overscan_started_, id)) + return false; + overscan_adjusted_.erase(id); + return true; +} + +bool MockDisplayInfoProvider::OverscanCalibrationComplete( + const std::string& id) { + if (!base::Contains(overscan_started_, id)) + return false; + overscan_started_.erase(id); + return true; +} + +bool MockDisplayInfoProvider::calibration_started(const std::string& id) const { + return base::Contains(overscan_started_, id); +} + +bool MockDisplayInfoProvider::calibration_changed(const std::string& id) const { + return base::Contains(overscan_adjusted_, id); +} + +void MockDisplayInfoProvider::ShowNativeTouchCalibration( + const std::string& id, + ErrorCallback callback) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), + native_touch_calibration_success_ + ? absl::nullopt + : absl::optional<std::string>("failed"))); +} + +void MockDisplayInfoProvider::SetMirrorMode( + const api::system_display::MirrorModeInfo& info, + ErrorCallback callback) { + mirror_mode_ = info.mode; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt)); +} + +void MockDisplayInfoProvider::UpdateDisplayUnitInfoForPlatform( + const display::Display& display, + extensions::api::system_display::DisplayUnitInfo* unit) { + int64_t id = display.id(); + unit->name = "DISPLAY NAME FOR " + base::NumberToString(id); + if (id == 1) + unit->mirroring_source_id = "0"; + unit->is_primary = id == 0 ? true : false; + unit->is_internal = id == 0 ? true : false; + unit->is_enabled = true; + unit->rotation = (90 * id) % 360; + unit->dpi_x = 96.0; + unit->dpi_y = 96.0; + if (id == 0) { + unit->overscan.left = 20; + unit->overscan.top = 40; + unit->overscan.right = 60; + unit->overscan.bottom = 80; + } +} + +} // namespace extensions
diff --git a/extensions/browser/mock_display_info_provider.h b/extensions/browser/mock_display_info_provider.h new file mode 100644 index 0000000..4e6fba2 --- /dev/null +++ b/extensions/browser/mock_display_info_provider.h
@@ -0,0 +1,94 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_MOCK_DISPLAY_INFO_PROVIDER_H_ +#define EXTENSIONS_BROWSER_MOCK_DISPLAY_INFO_PROVIDER_H_ + +#include <memory> +#include <set> +#include <string> +#include <utility> +#include <vector> + +#include "base/values.h" +#include "extensions/browser/api/system_display/display_info_provider.h" +#include "extensions/common/api/system_display.h" + +namespace extensions { + +class MockDisplayInfoProvider : public DisplayInfoProvider { + public: + MockDisplayInfoProvider(); + ~MockDisplayInfoProvider() override; + MockDisplayInfoProvider(const MockDisplayInfoProvider&) = delete; + MockDisplayInfoProvider& operator=(const MockDisplayInfoProvider&) = delete; + + // DisplayInfoProvider overrides. + void SetDisplayProperties( + const std::string& display_id, + const api::system_display::DisplayProperties& properties, + ErrorCallback callback) override; + + void EnableUnifiedDesktop(bool enable) override; + + bool OverscanCalibrationStart(const std::string& id) override; + + bool OverscanCalibrationAdjust( + const std::string& id, + const api::system_display::Insets& delta) override; + + bool OverscanCalibrationReset(const std::string& id) override; + + bool OverscanCalibrationComplete(const std::string& id) override; + + void ShowNativeTouchCalibration(const std::string& id, + ErrorCallback callback) override; + + void SetMirrorMode(const api::system_display::MirrorModeInfo& info, + ErrorCallback callback) override; + + // Helpers, accessors. + std::unique_ptr<base::DictionaryValue> GetSetInfoValue() { + return std::move(set_info_value_); + } + + std::string GetSetInfoDisplayId() const { return set_info_display_id_; } + + bool unified_desktop_enabled() const { return unified_desktop_enabled_; } + + bool calibration_started(const std::string& id) const; + + bool calibration_changed(const std::string& id) const; + + const api::system_display::MirrorMode& mirror_mode() const { + return mirror_mode_; + } + + void SetTouchCalibrationWillSucceed(bool success) { + native_touch_calibration_success_ = success; + } + + private: + // DisplayInfoProvider override. + // Update the content of the |unit| obtained for |display| using + // platform specific method. + void UpdateDisplayUnitInfoForPlatform( + const display::Display& display, + extensions::api::system_display::DisplayUnitInfo* unit) override; + + std::unique_ptr<base::DictionaryValue> set_info_value_; + std::string set_info_display_id_; + bool unified_desktop_enabled_ = false; + std::set<std::string> overscan_started_; + std::set<std::string> overscan_adjusted_; + + bool native_touch_calibration_success_ = false; + + api::system_display::MirrorMode mirror_mode_ = + api::system_display::MIRROR_MODE_OFF; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_MOCK_DISPLAY_INFO_PROVIDER_H_
diff --git a/extensions/browser/mock_screen.cc b/extensions/browser/mock_screen.cc new file mode 100644 index 0000000..20a47b9e --- /dev/null +++ b/extensions/browser/mock_screen.cc
@@ -0,0 +1,66 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/mock_screen.h" + +namespace extensions { + +MockScreen::MockScreen() { + for (int i = 0; i < 4; i++) { + gfx::Rect bounds(0, 0, 1280, 720); + gfx::Rect work_area(0, 0, 960, 720); + display::Display display(i, bounds); + display.set_work_area(work_area); + displays_.push_back(display); + } +} + +MockScreen::~MockScreen() = default; + +gfx::Point MockScreen::GetCursorScreenPoint() { + return gfx::Point(); +} + +bool MockScreen::IsWindowUnderCursor(gfx::NativeWindow window) { + return false; +} + +gfx::NativeWindow MockScreen::GetWindowAtScreenPoint(const gfx::Point& point) { + return gfx::NativeWindow(); +} + +gfx::NativeWindow MockScreen::GetLocalProcessWindowAtPoint( + const gfx::Point& point, + const std::set<gfx::NativeWindow>& ignore) { + return nullptr; +} + +int MockScreen::GetNumDisplays() const { + return static_cast<int>(displays_.size()); +} + +const std::vector<display::Display>& MockScreen::GetAllDisplays() const { + return displays_; +} + +display::Display MockScreen::GetDisplayNearestWindow( + gfx::NativeWindow window) const { + return display::Display(0); +} + +display::Display MockScreen::GetDisplayNearestPoint( + const gfx::Point& point) const { + return display::Display(0); +} + +display::Display MockScreen::GetDisplayMatching( + const gfx::Rect& match_rect) const { + return display::Display(0); +} + +display::Display MockScreen::GetPrimaryDisplay() const { + return displays_[0]; +} + +} // namespace extensions
diff --git a/extensions/browser/mock_screen.h b/extensions/browser/mock_screen.h new file mode 100644 index 0000000..82f4a5c7 --- /dev/null +++ b/extensions/browser/mock_screen.h
@@ -0,0 +1,47 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_MOCK_SCREEN_H_ +#define EXTENSIONS_BROWSER_MOCK_SCREEN_H_ + +#include <vector> + +#include "ui/display/screen.h" + +namespace extensions { + +class MockScreen : public display::Screen { + public: + MockScreen(); + ~MockScreen() override; + MockScreen(const MockScreen&) = delete; + MockScreen& operator=(const MockScreen&) = delete; + + protected: + // Overridden from display::Screen: + gfx::Point GetCursorScreenPoint() override; + bool IsWindowUnderCursor(gfx::NativeWindow window) override; + gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override; + gfx::NativeWindow GetLocalProcessWindowAtPoint( + const gfx::Point& point, + const std::set<gfx::NativeWindow>& ignore) override; + int GetNumDisplays() const override; + const std::vector<display::Display>& GetAllDisplays() const override; + display::Display GetDisplayNearestWindow( + gfx::NativeWindow window) const override; + display::Display GetDisplayNearestPoint( + const gfx::Point& point) const override; + display::Display GetDisplayMatching( + const gfx::Rect& match_rect) const override; + display::Display GetPrimaryDisplay() const override; + void AddObserver(display::DisplayObserver* observer) override {} + void RemoveObserver(display::DisplayObserver* observer) override {} + + private: + std::vector<display::Display> displays_; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_MOCK_SCREEN_H_
diff --git a/extensions/browser/process_manager.h b/extensions/browser/process_manager.h index 36d30cb0..7b86cd26 100644 --- a/extensions/browser/process_manager.h +++ b/extensions/browser/process_manager.h
@@ -78,6 +78,9 @@ void UnregisterServiceWorker(const WorkerId& worker_id); // Returns the SiteInstance that the given URL belongs to. + // NOTE: Usage of this method is potentially error-prone. An extension can + // correspond to multiple SiteInstances (e.g. consider a cross origin isolated + // extension with non-cross-origin-isolated contexts). // TODO(aa): This only returns correct results for extensions and packaged // apps, not hosted apps. virtual scoped_refptr<content::SiteInstance> GetSiteInstanceForURL(
diff --git a/extensions/browser/process_map.h b/extensions/browser/process_map.h index 1a82975..c991db2d 100644 --- a/extensions/browser/process_map.h +++ b/extensions/browser/process_map.h
@@ -26,14 +26,17 @@ // The relationship between extensions and processes is complex: // // - Extensions can be either "split" mode or "spanning" mode. -// - In spanning mode, extensions share a single process between all incognito -// and normal windows. This was the original mode for extensions. +// - In spanning mode, extensions *generally* share a single process between all +// incognito and normal windows. This was the original mode for extensions. // - In split mode, extensions have separate processes in incognito windows. // - There are also hosted apps, which are a kind of extensions, and those // usually have a process model similar to normal web sites: multiple // processes per-profile. // - A single hosted app can have more than one SiteInstance in the same process // if we're over the process limit and force them to share a process. +// - An extension can also opt into Cross Origin Isolation in which case it can +// have multiple processes per profile since cross-origin-isolated and +// non-cross-origin-isolated contexts don't share a process. // // In general, we seem to play with the process model of extensions a lot, so // it is safest to assume it is many-to-many in most places in the codebase. @@ -55,14 +58,12 @@ // hosted apps. See crbug.com/102533. // // 2. An extension can show up in multiple processes. That is why there is no -// GetExtensionProcess() method here. There are two cases: a) The extension -// is actually a hosted app, in which case this is normal, or b) there is an -// incognito window open and the extension is "split mode". It is *not safe* -// to assume that there is one process per extension. If you only care about -// extensions (not hosted apps), and you are on the UI thread, and you don't -// care about incognito version of this extension (or vice versa if you're in -// an incognito profile) then use -// extensions::ProcessManager::GetSiteInstanceForURL()->[Has|Get]Process(). +// GetExtensionProcess() method here. There are multiple such cases: +// a) The extension is actually a hosted app. +// b) There is an incognito window open and the extension is "split mode". +// c) The extension is cross origin isolated but has +// non-cross-origin-isolated contexts. +// It is *not safe* to assume that there is one process per extension. // // 3. The process ids contained in this class are *not limited* to the Profile // you got this map from. They can also be associated with that profile's @@ -71,9 +72,9 @@ // // TODO(aa): The above warnings suggest this class could use improvement :). // -// TODO(kalman): This class is not threadsafe, but is used on both the UI and -// IO threads. Somebody should fix that, either make it -// threadsafe or enforce single thread. Investigation required. +// TODO(kalman): This class is not threadsafe, but is used on both the UI and IO +// threads. Somebody should fix that, either make it threadsafe or +// enforce single thread. Investigation required. class ProcessMap : public KeyedService { public: ProcessMap();
diff --git a/extensions/browser/value_store/leveldb_value_store.cc b/extensions/browser/value_store/leveldb_value_store.cc index 383998f..01f573a 100644 --- a/extensions/browser/value_store/leveldb_value_store.cc +++ b/extensions/browser/value_store/leveldb_value_store.cc
@@ -206,8 +206,7 @@ base::DictionaryValue& whole_db = read_result.settings(); while (!whole_db.DictEmpty()) { std::string next_key = base::DictionaryValue::Iterator(whole_db).key(); - std::unique_ptr<base::Value> next_value; - whole_db.RemoveWithoutPathExpansion(next_key, &next_value); + absl::optional<base::Value> next_value = whole_db.ExtractKey(next_key); changes.emplace_back(next_key, std::move(*next_value), absl::nullopt); }
diff --git a/extensions/browser/value_store/testing_value_store.cc b/extensions/browser/value_store/testing_value_store.cc index e1710f0..52b31a77 100644 --- a/extensions/browser/value_store/testing_value_store.cc +++ b/extensions/browser/value_store/testing_value_store.cc
@@ -115,10 +115,10 @@ return WriteResult(CreateStatusCopy(status_)); ValueStoreChangeList changes; - for (auto it = keys.cbegin(); it != keys.cend(); ++it) { - std::unique_ptr<base::Value> old_value; - if (storage_.RemoveWithoutPathExpansion(*it, &old_value)) { - changes.emplace_back(*it, std::move(*old_value), absl::nullopt); + for (auto const& key : keys) { + absl::optional<base::Value> old_value = storage_.ExtractKey(key); + if (old_value.has_value()) { + changes.emplace_back(key, std::move(*old_value), absl::nullopt); } } return WriteResult(std::move(changes), CreateStatusCopy(status_));
diff --git a/extensions/browser/value_store/value_store_frontend.cc b/extensions/browser/value_store/value_store_frontend.cc index c06ee7d..ce63844 100644 --- a/extensions/browser/value_store/value_store_frontend.cc +++ b/extensions/browser/value_store/value_store_frontend.cc
@@ -38,17 +38,21 @@ // Extract the value from the ReadResult and pass ownership of it to the // callback. - std::unique_ptr<base::Value> value; + absl::optional<base::Value> value; if (result.status().ok()) { - result.settings().RemoveWithoutPathExpansion(key, &value); + value = result.settings().ExtractKey(key); } else { LOG(WARNING) << "Reading " << key << " from " << db_path_.value() << " failed: " << result.status().message; } content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&ValueStoreFrontend::Backend::RunCallback, - this, std::move(callback), std::move(value))); + FROM_HERE, + base::BindOnce(&ValueStoreFrontend::Backend::RunCallback, this, + std::move(callback), + value.has_value() + ? base::Value::ToUniquePtrValue(std::move(*value)) + : nullptr)); } void Set(const std::string& key, std::unique_ptr<base::Value> value) {
diff --git a/fuchsia/engine/browser/virtual_keyboard_browsertest.cc b/fuchsia/engine/browser/virtual_keyboard_browsertest.cc index 7f39182..37f714a 100644 --- a/fuchsia/engine/browser/virtual_keyboard_browsertest.cc +++ b/fuchsia/engine/browser/virtual_keyboard_browsertest.cc
@@ -130,7 +130,8 @@ // Verifies that RequestShow() is not called redundantly if the virtual // keyboard is reported as visible. -IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, ShowAndHideWithVisibility) { +// TODO(https://crbug.com/1226757): Flaky on Fuchsia-x64. +IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, DISABLED_ShowAndHideWithVisibility) { testing::InSequence s; // Alphanumeric field click.
diff --git a/fuchsia/engine/common/web_engine_content_client.cc b/fuchsia/engine/common/web_engine_content_client.cc index 9545d81..bf9410d 100644 --- a/fuchsia/engine/common/web_engine_content_client.cc +++ b/fuchsia/engine/common/web_engine_content_client.cc
@@ -20,7 +20,7 @@ base::StringPiece WebEngineContentClient::GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) { + ui::ResourceScaleFactor scale_factor) { return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( resource_id, scale_factor); }
diff --git a/fuchsia/engine/common/web_engine_content_client.h b/fuchsia/engine/common/web_engine_content_client.h index 2383b079..f9816121 100644 --- a/fuchsia/engine/common/web_engine_content_client.h +++ b/fuchsia/engine/common/web_engine_content_client.h
@@ -15,8 +15,9 @@ // content::ContentClient implementation. std::u16string GetLocalizedString(int message_id) override; - base::StringPiece GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) override; + base::StringPiece GetDataResource( + int resource_id, + ui::ResourceScaleFactor scale_factor) override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; gfx::Image& GetNativeImageNamed(int resource_id) override; blink::OriginTrialPolicy* GetOriginTrialPolicy() override;
diff --git a/gin/cppgc.cc b/gin/cppgc.cc index d56ab2f..62842785 100644 --- a/gin/cppgc.cc +++ b/gin/cppgc.cc
@@ -3,19 +3,33 @@ // found in the LICENSE file. #include "gin/public/cppgc.h" + +#include "base/check_op.h" #include "gin/public/v8_platform.h" #include "v8/include/cppgc/platform.h" namespace gin { +namespace { + +int g_init_count = 0; + +} // namespace + void InitializeCppgcFromV8Platform() { - static bool cppgc_is_initialized = false; - if (cppgc_is_initialized) + DCHECK_GE(g_init_count, 0); + if (g_init_count++ > 0) return; cppgc::InitializeProcess(gin::V8Platform::Get()->GetPageAllocator()); +} - cppgc_is_initialized = true; +void MaybeShutdownCppgc() { + DCHECK_GT(g_init_count, 0); + if (--g_init_count > 0) + return; + + cppgc::ShutdownProcess(); } } // namespace gin
diff --git a/gin/public/cppgc.h b/gin/public/cppgc.h index f89a58b..8844f94 100644 --- a/gin/public/cppgc.h +++ b/gin/public/cppgc.h
@@ -9,8 +9,17 @@ namespace gin { +// A wrapper around `cppgc::InitializeProcess()` which helps to guarantee that +// cppgc is initialized only once when there are multiple users of cppgc in same +// process. GIN_EXPORT void InitializeCppgcFromV8Platform(); +// Calls `cppgc::ShutdownProcess()` only after being called as many times as +// `InitializeCppgcFromV8Platform()`. Helps to guarantee that cppgc is shutdown +// only after all users in the same process are done using it. Number of calls +// cannot exceed that of `InitializeCppgcFromV8Platform()`. +GIN_EXPORT void MaybeShutdownCppgc(); + } // namespace gin -#endif // GIN_PUBLIC_CPPGC_H_ \ No newline at end of file +#endif // GIN_PUBLIC_CPPGC_H_
diff --git a/gpu/command_buffer/common/shared_image_usage.h b/gpu/command_buffer/common/shared_image_usage.h index ff788eb..413b629 100644 --- a/gpu/command_buffer/common/shared_image_usage.h +++ b/gpu/command_buffer/common/shared_image_usage.h
@@ -43,6 +43,8 @@ // GLImage::DisableInUseByWindowServer should be called on any GLImages that // use this SharedImage. SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX = 1 << 12, + // Image will be used with mipmap enabled + SHARED_IMAGE_USAGE_MIPMAP = 1 << 13, }; } // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc index 2599c4f..6d3f2f2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc
@@ -8,7 +8,6 @@ #include <stdint.h> #include "base/command_line.h" -#include "base/stl_util.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index a62f594..0df7d28 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -21,6 +21,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/numerics/checked_math.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" @@ -2979,27 +2980,66 @@ return; } - size_t y_size = dst_height * y_stride; - uint8_t* y_out = - GetSharedMemoryAs<uint8_t*>(shm_id, shm_offset + y_offset, y_size); + // Large plane strides or heights could potentially overflow the unsigned int + // parameters of GetSharedMemoryAs() below. We use base::CheckedNumeric to + // prevent using any values that overflowed which could cause us to request + // incorrect shared memory regions. + base::CheckedNumeric<unsigned int> checked_shm_offset(shm_offset); + base::CheckedNumeric<unsigned int> checked_dst_height(dst_height); + + base::CheckedNumeric<unsigned int> y_size = checked_dst_height * y_stride; + base::CheckedNumeric<unsigned int> y_plane_offset = + checked_shm_offset + y_offset; + if (!y_size.IsValid() || !y_plane_offset.IsValid()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, "glReadbackYUVImagePixels", + "y plane size or offset too large. Both must fit in unsigned int."); + return; + } + + // |y_plane_offset| and |y_size| are guaranteed valid by the checks above and + // won't die here. Same with the u and v planes below. + uint8_t* y_out = GetSharedMemoryAs<uint8_t*>( + shm_id, y_plane_offset.ValueOrDie(), y_size.ValueOrDie()); if (!y_out) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackYUVImagePixels", "Failed to get memory for y plane output"); return; } - size_t u_size = ((dst_height + 1) / 2) * u_stride; - uint8_t* u_out = - GetSharedMemoryAs<uint8_t*>(shm_id, shm_offset + u_offset, u_size); + base::CheckedNumeric<unsigned int> checked_uv_plane_height = + (checked_dst_height + 1) / 2; + + base::CheckedNumeric<unsigned int> u_size = + checked_uv_plane_height * u_stride; + base::CheckedNumeric<unsigned int> u_plane_offset = + checked_shm_offset + u_offset; + if (!u_size.IsValid() || !u_plane_offset.IsValid()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, "glReadbackYUVImagePixels", + "u plane size or offset too large. Both must fit in unsigned int."); + return; + } + uint8_t* u_out = GetSharedMemoryAs<uint8_t*>( + shm_id, u_plane_offset.ValueOrDie(), u_size.ValueOrDie()); if (!u_out) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackYUVImagePixels", "Failed to get memory for u plane output"); return; } - size_t v_size = ((dst_height + 1) / 2) * v_stride; - uint8_t* v_out = - GetSharedMemoryAs<uint8_t*>(shm_id, shm_offset + v_offset, v_size); + base::CheckedNumeric<unsigned int> v_size = + checked_uv_plane_height * v_stride; + base::CheckedNumeric<unsigned int> v_plane_offset = + checked_shm_offset + v_offset; + if (!v_size.IsValid() || !v_plane_offset.IsValid()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, "glReadbackYUVImagePixels", + "v plane size or offset too large. Both must fit in unsigned int."); + return; + } + uint8_t* v_out = GetSharedMemoryAs<uint8_t*>( + shm_id, v_plane_offset.ValueOrDie(), v_size.ValueOrDie()); if (!v_out) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackYUVImagePixels", "Failed to get memory for v plane output");
diff --git a/gpu/command_buffer/service/scheduler.cc b/gpu/command_buffer/service/scheduler.cc index 2fe4798..0b99abb 100644 --- a/gpu/command_buffer/service/scheduler.cc +++ b/gpu/command_buffer/service/scheduler.cc
@@ -14,7 +14,6 @@ #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" -#include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/timer/elapsed_timer.h"
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index 8ff21ed..6ae8714 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -500,10 +500,18 @@ } bool SharedImageFactory::IsSharedBetweenThreads(uint32_t usage) { - // If |shared_image_manager_| is thread safe, it means the display is running - // on a separate thread (which uses a separate GL context or VkDeviceQueue). - return shared_image_manager_->display_context_on_another_thread() && - (usage & SHARED_IMAGE_USAGE_DISPLAY); + // Ignore for mipmap usage. + usage &= ~SHARED_IMAGE_USAGE_MIPMAP; + // If |shared_image_manager_| is thread safe, it means the display is + // running on a separate thread (which uses a separate GL context or + // VkDeviceQueue). + const bool used_by_display_compositor_gpu_thread = + (usage & SHARED_IMAGE_USAGE_DISPLAY) && + shared_image_manager_->display_context_on_another_thread(); + // If it has usage other than DISPLAY, it means that it is used by the + // gpu main thread. + const bool used_by_main_gpu_thread = usage & ~SHARED_IMAGE_USAGE_DISPLAY; + return used_by_display_compositor_gpu_thread && used_by_main_gpu_thread; } SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage(
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc index 59015ea..aedafe1 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.cc +++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -178,9 +178,10 @@ } bool InitializeGMB(const SkImageInfo& info, - SharedMemoryRegionWrapper shm_wrapper) { - if (Initialize(info, shm_wrapper.GetMemoryAsSpan(), - shm_wrapper.GetStride())) { + SharedMemoryRegionWrapper shm_wrapper, + GrMipMapped mipmap) { + if (Initialize(info, shm_wrapper.GetMemoryAsSpan(), shm_wrapper.GetStride(), + mipmap)) { shared_memory_wrapper_ = std::move(shm_wrapper); return true; } @@ -194,7 +195,8 @@ // data must be provided since updating compressed textures is not supported. bool Initialize(const SkImageInfo& info, base::span<const uint8_t> pixels, - size_t stride) { + size_t stride, + GrMipMapped mipmap) { if (context_state_->context_lost()) return false; @@ -230,10 +232,10 @@ // We don't do this on release builds because there is a slight overhead. backend_texture_ = context_state_->gr_context()->createBackendTexture( size().width(), size().height(), GetSkColorType(), SkColors::kBlue, - GrMipMapped::kNo, GrRenderable::kYes, GrProtected::kNo); + mipmap, GrRenderable::kYes, GrProtected::kNo); #else backend_texture_ = context_state_->gr_context()->createBackendTexture( - size().width(), size().height(), GetSkColorType(), GrMipMapped::kNo, + size().width(), size().height(), GetSkColorType(), mipmap, GrRenderable::kYes, GrProtected::kNo); #endif @@ -422,7 +424,9 @@ std::unique_ptr<WrappedSkImage> texture( new WrappedSkImage(mailbox, format, size, color_space, surface_origin, alpha_type, usage, estimated_size, context_state_)); - if (!texture->Initialize(info, data, /*stride=*/0)) + GrMipMapped mipmap = + usage & SHARED_IMAGE_USAGE_MIPMAP ? GrMipMapped::kYes : GrMipMapped::kNo; + if (!texture->Initialize(info, data, /*stride=*/0, mipmap)) return nullptr; return texture; } @@ -469,7 +473,9 @@ std::unique_ptr<WrappedSkImage> texture(new WrappedSkImage( mailbox, format, size, color_space, surface_origin, alpha_type, usage, info.computeMinByteSize(), context_state_)); - if (!texture->InitializeGMB(info, std::move(shm_wrapper))) + GrMipMapped mipmap = (usage & SHARED_IMAGE_USAGE_MIPMAP) ? GrMipMapped::kYes + : GrMipMapped::kNo; + if (!texture->InitializeGMB(info, std::move(shm_wrapper), mipmap)) return nullptr; return texture; @@ -483,9 +489,12 @@ bool WrappedSkImageFactory::CanUseWrappedSkImage( uint32_t usage, GrContextType gr_context_type) const { - constexpr auto kWrappedSkImageUsage = SHARED_IMAGE_USAGE_RASTER | - SHARED_IMAGE_USAGE_OOP_RASTERIZATION | - SHARED_IMAGE_USAGE_DISPLAY; + // Ignore for mipmap usage. + usage &= ~SHARED_IMAGE_USAGE_MIPMAP; + auto kWrappedSkImageUsage = SHARED_IMAGE_USAGE_DISPLAY | + SHARED_IMAGE_USAGE_RASTER | + SHARED_IMAGE_USAGE_OOP_RASTERIZATION; + if (gr_context_type != GrContextType::kGL) { // For SkiaRenderer/Vulkan+Dawn use WrappedSkImage if the usage is only // raster and/or display. @@ -493,7 +502,8 @@ } else { // For d SkiaRenderer/GL only use WrappedSkImages for OOP-R because // CopySubTexture() doesn't use Skia. https://crbug.com/984045 - return usage == kWrappedSkImageUsage; + return (usage == kWrappedSkImageUsage) || + (usage == SHARED_IMAGE_USAGE_DISPLAY); } }
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc index 893f139..5721b40 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -13,7 +13,6 @@ #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" #include "base/timer/elapsed_timer.h" #include "base/trace_event/trace_event.h"
diff --git a/gpu/vulkan/vulkan_image.cc b/gpu/vulkan/vulkan_image.cc index b5013df..ff55bf06 100644 --- a/gpu/vulkan/vulkan_image.cc +++ b/gpu/vulkan/vulkan_image.cc
@@ -10,7 +10,6 @@ #include "base/logging.h" #include "base/macros.h" -#include "base/stl_util.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "gpu/vulkan/vulkan_device_queue.h"
diff --git a/infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb b/infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb index cae7e2c0..480a1ff 100644 --- a/infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb +++ b/infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb
@@ -19,6 +19,5 @@ "v.test_suite" ] }, - "builder_group": "infra", "recipe": "chromium" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-bootstrap/properties.textpb b/infra/config/generated/builders/ci/linux-bootstrap/properties.textpb index cae7e2c0..480a1ff 100644 --- a/infra/config/generated/builders/ci/linux-bootstrap/properties.textpb +++ b/infra/config/generated/builders/ci/linux-bootstrap/properties.textpb
@@ -19,6 +19,5 @@ "v.test_suite" ] }, - "builder_group": "infra", "recipe": "chromium" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-bootstrap/properties.textpb b/infra/config/generated/builders/try/linux-bootstrap/properties.textpb index 600926d..bda0727f 100644 --- a/infra/config/generated/builders/try/linux-bootstrap/properties.textpb +++ b/infra/config/generated/builders/try/linux-bootstrap/properties.textpb
@@ -19,6 +19,5 @@ "v.test_suite" ] }, - "builder_group": "tryserver.infra", "recipe": "chromium_trybot" } \ No newline at end of file
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index af982016..350dec0 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -182,6 +182,10 @@ includable_only: true } builders { + name: "chromium/try/android-12-x64-fyi-rel" + includable_only: true + } + builders { name: "chromium/try/android-angle-chromium-try" includable_only: true }
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 3100175..c97ea4f 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -20182,6 +20182,74 @@ } } builders { + name: "android-12-x64-fyi-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "luciexe" + } + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.android.fyi\",\"recipe\":\"chromium\"}" + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.gtests_local" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "android-androidx-packager" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -27839,7 +27907,7 @@ cipd_version: "latest" cmd: "bootstrapper" } - properties: "{\"$bootstrap\":{\"exe\":{\"cipd_package\":\"infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build\",\"cipd_version\":\"refs/heads/master\",\"cmd\":[\"luciexe\"]},\"properties_file\":\"infra/config/generated/builders/ci/linux-bootstrap/properties.textpb\",\"top_level_project\":{\"ref\":\"refs/heads/main\",\"repo\":{\"host\":\"chromium.googlesource.com\",\"project\":\"chromium/src\"}}}}" + properties: "{\"$bootstrap\":{\"exe\":{\"cipd_package\":\"infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build\",\"cipd_version\":\"refs/heads/master\",\"cmd\":[\"luciexe\"]},\"properties_file\":\"infra/config/generated/builders/ci/linux-bootstrap/properties.textpb\",\"top_level_project\":{\"ref\":\"refs/heads/main\",\"repo\":{\"host\":\"chromium.googlesource.com\",\"project\":\"chromium/src\"}}},\"builder_group\":\"infra\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -27907,7 +27975,7 @@ cipd_version: "latest" cmd: "bootstrapper" } - properties: "{\"$bootstrap\":{\"exe\":{\"cipd_package\":\"infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build\",\"cipd_version\":\"refs/heads/master\",\"cmd\":[\"luciexe\"]},\"properties_file\":\"infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb\",\"top_level_project\":{\"ref\":\"refs/heads/main\",\"repo\":{\"host\":\"chromium.googlesource.com\",\"project\":\"chromium/src\"}}}}" + properties: "{\"$bootstrap\":{\"exe\":{\"cipd_package\":\"infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build\",\"cipd_version\":\"refs/heads/master\",\"cmd\":[\"luciexe\"]},\"properties_file\":\"infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb\",\"top_level_project\":{\"ref\":\"refs/heads/main\",\"repo\":{\"host\":\"chromium.googlesource.com\",\"project\":\"chromium/src\"}}},\"builder_group\":\"infra\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -38620,6 +38688,85 @@ } } builders { + name: "android-12-x64-fyi-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "luciexe" + } + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium.chromium_tests.use_rbe_cas" + value: 5 + } + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "android-angle-chromium-try" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -52514,7 +52661,7 @@ cipd_version: "latest" cmd: "bootstrapper" } - properties: "{\"$bootstrap\":{\"exe\":{\"cipd_package\":\"infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build\",\"cipd_version\":\"refs/heads/master\",\"cmd\":[\"luciexe\"]},\"properties_file\":\"infra/config/generated/builders/try/linux-bootstrap/properties.textpb\",\"top_level_project\":{\"ref\":\"refs/heads/main\",\"repo\":{\"host\":\"chromium.googlesource.com\",\"project\":\"chromium/src\"}}}}" + properties: "{\"$bootstrap\":{\"exe\":{\"cipd_package\":\"infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build\",\"cipd_version\":\"refs/heads/master\",\"cmd\":[\"luciexe\"]},\"properties_file\":\"infra/config/generated/builders/try/linux-bootstrap/properties.textpb\",\"top_level_project\":{\"ref\":\"refs/heads/main\",\"repo\":{\"host\":\"chromium.googlesource.com\",\"project\":\"chromium/src\"}}},\"builder_group\":\"tryserver.infra\"}" execution_timeout_secs: 14400 expiration_secs: 7200 grace_period {
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index bbc9cb1d..a98eb15 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -3483,6 +3483,11 @@ short_name: "rel" } builders { + name: "buildbucket/luci.chromium.ci/android-12-x64-fyi-rel" + category: "emulator|12|x64" + short_name: "rel" + } + builders { name: "buildbucket/luci.chromium.ci/android-pie-x86-fyi-rel" category: "emulator|P|x86" short_name: "rel" @@ -13448,6 +13453,9 @@ name: "buildbucket/luci.chromium.try/android-11-x86-fyi-rel" } builders { + name: "buildbucket/luci.chromium.try/android-12-x64-fyi-rel" + } + builders { name: "buildbucket/luci.chromium.try/android-angle-chromium-try" } builders { @@ -14493,6 +14501,9 @@ name: "buildbucket/luci.chromium.try/android-11-x86-fyi-rel" } builders { + name: "buildbucket/luci.chromium.try/android-12-x64-fyi-rel" + } + builders { name: "buildbucket/luci.chromium.try/android-asan" } builders {
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index e13fb34..79d9189 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -4228,6 +4228,16 @@ } } job { + id: "android-12-x64-fyi-rel" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "android-12-x64-fyi-rel" + } +} +job { id: "android-androidx-packager" realm: "ci" schedule: "0 7,14,22 * * * *" @@ -7203,6 +7213,7 @@ triggers: "Windows deterministic" triggers: "android-10-arm64-rel" triggers: "android-11-x86-fyi-rel" + triggers: "android-12-x64-fyi-rel" triggers: "android-angle-arm64-builder" triggers: "android-angle-chromium-arm64-builder" triggers: "android-archive-dbg"
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 31fe377a..b637cce 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -783,6 +783,15 @@ ("try", "linux-bootstrap"), ]} +_NON_BOOTSTRAPPED_PROPERTIES = [ + # Sheriff-o-Matic queries for builder_group in the input properties to find + # builds for the main sheriff rotation. Bootstrapped properties don't appear + # in the build's input properties, so don't bootstrap this property. + # TODO(gbeaty) When finalized input properties are exported to BQ, remove + # this. + "builder_group", +] + def _bootstrap_key(bucket_name, builder_name): return graph.key("@chromium", "", "bootstrap", "{}/{}".format(bucket_name, builder_name)) @@ -822,11 +831,8 @@ fail("{}/{} is not approved for bootstrapping at this time" .format(bucket_name, builder_name)) - builder_properties = json.decode(builder.properties) properties_file = "builders/{}/{}/properties.textpb".format(bucket_name, builder_name) - ctx.output[properties_file] = json.indent(json.encode(builder_properties), indent = " ") - - builder.properties = json.encode({ + non_bootstrapped_properties = { "$bootstrap": { "top_level_project": { "repo": { @@ -838,7 +844,14 @@ "properties_file": "infra/config/generated/{}".format(properties_file), "exe": builder.exe, }, - }) + } + builder_properties = json.decode(builder.properties) + for p in _NON_BOOTSTRAPPED_PROPERTIES: + if p in builder_properties: + non_bootstrapped_properties[p] = builder_properties.pop(p) + ctx.output[properties_file] = json.indent(json.encode(builder_properties), indent = " ") + + builder.properties = json.encode(non_bootstrapped_properties) builder.exe.cipd_package = "infra/chromium/bootstrapper/${platform}" builder.exe.cipd_version = "latest"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index a42d450..e9237cb 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -1150,6 +1150,15 @@ os = os.LINUX_BIONIC_REMOVE, ) +ci.android_fyi_builder( + name = "android-12-x64-fyi-rel", + console_view_entry = consoles.console_view_entry( + category = "emulator|12|x64", + short_name = "rel", + ), + os = os.LINUX_BIONIC_REMOVE, +) + ci.angle_linux_builder( name = "android-angle-arm64-builder", console_view_entry = consoles.console_view_entry(
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 130db17d..2711686 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -293,6 +293,10 @@ ) try_.chromium_android_builder( + name = "android-12-x64-fyi-rel", +) + +try_.chromium_android_builder( name = "android-asan", )
diff --git a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h index 1b0e1713..56fc265 100644 --- a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h +++ b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h
@@ -46,10 +46,9 @@ bool link_transition); // web::WebStatePolicyDecider implementation - void ShouldAllowRequest( + web::WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + const web::WebStatePolicyDecider::RequestInfo& request_info) override; private: friend class web::WebStateUserData<AppLauncherTabHelper>;
diff --git a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm index 1b29d92..986abdc7 100644 --- a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm +++ b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm
@@ -161,16 +161,15 @@ } } -void AppLauncherTabHelper::ShouldAllowRequest( +web::WebStatePolicyDecider::PolicyDecision +AppLauncherTabHelper::ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + const web::WebStatePolicyDecider::RequestInfo& request_info) { GURL request_url = net::GURLWithNSURL(request.URL); if (!IsAppUrl(request_url)) { // This URL can be handled by the WebState and doesn't require App launcher // handling. - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } if (IsURLBlocklistEnabled()) { @@ -180,17 +179,15 @@ web_state()->GetBrowserState()); if (blocklistService->GetURLBlocklistState(request_url) == policy::URLBlocklist::URLBlocklistState::URL_IN_BLOCKLIST) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::CancelAndDisplayError( - policy_url_blocking_util::CreateBlockedUrlError())); + return web::WebStatePolicyDecider::PolicyDecision::CancelAndDisplayError( + policy_url_blocking_util::CreateBlockedUrlError()); } } // Disallow navigations to tel: URLs from cross-origin frames. if (request_url.SchemeIs(url::kTelScheme) && request_info.target_frame_is_cross_origin) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Cancel()); + return web::WebStatePolicyDecider::PolicyDecision::Cancel(); } ExternalURLRequestStatus request_status = @@ -208,15 +205,11 @@ UMA_HISTOGRAM_ENUMERATION("WebController.ExternalURLRequestBlocking", request_status, ExternalURLRequestStatus::kCount); // Request is blocked. - if (request_status == ExternalURLRequestStatus::kSubFrameRequestBlocked) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Cancel()); - } + if (request_status == ExternalURLRequestStatus::kSubFrameRequestBlocked) + return web::WebStatePolicyDecider::PolicyDecision::Cancel(); - if (!IsValidAppUrl(request_url)) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Cancel()); - } + if (!IsValidAppUrl(request_url)) + return web::WebStatePolicyDecider::PolicyDecision::Cancel(); // If this is a Universal 2nd Factor (U2F) call, the origin needs to be // checked to make sure it's secure and then update the |request_url| with @@ -229,10 +222,8 @@ U2FTabHelper* u2f_helper = U2FTabHelper::FromWebState(web_state_); request_url = u2f_helper->GetXCallbackUrl(request_url, origin); // If the URL was rejected by the U2F handler, |request_url| will be empty. - if (!request_url.is_valid()) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Cancel()); - } + if (!request_url.is_valid()) + return web::WebStatePolicyDecider::PolicyDecision::Cancel(); } GURL last_committed_url = web_state_->GetLastCommittedURL(); @@ -261,7 +252,7 @@ // tab. RequestToLaunchApp(request_url, last_committed_url, is_link_transition); } - std::move(callback).Run(web::WebStatePolicyDecider::PolicyDecision::Cancel()); + return web::WebStatePolicyDecider::PolicyDecision::Cancel(); } WEB_STATE_USER_DATA_KEY_IMPL(AppLauncherTabHelper)
diff --git a/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm b/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm index fb622d53c..a52cd4c 100644 --- a/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm +++ b/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm
@@ -126,19 +126,9 @@ web::WebStatePolicyDecider::RequestInfo request_info( transition_type, target_frame_is_main, target_frame_is_cross_origin, has_user_gesture); - __block bool callback_called = false; - __block web::WebStatePolicyDecider::PolicyDecision policy_decision = - web::WebStatePolicyDecider::PolicyDecision::Allow(); - auto callback = - base::BindOnce(^(web::WebStatePolicyDecider::PolicyDecision decision) { - policy_decision = decision; - callback_called = true; - }); - tab_helper_->ShouldAllowRequest([NSURLRequest requestWithURL:url], - request_info, std::move(callback)); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); - return policy_decision.ShouldAllowNavigation(); + return tab_helper_ + ->ShouldAllowRequest([NSURLRequest requestWithURL:url], request_info) + .ShouldAllowNavigation(); } // Initialize reading list model and its required tab helpers. @@ -185,19 +175,10 @@ transition_type, /*target_frame_is_main=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/true); - __block bool callback_called = false; - __block web::WebStatePolicyDecider::PolicyDecision policy_decision = - web::WebStatePolicyDecider::PolicyDecision::Allow(); - auto callback = - base::BindOnce(^(web::WebStatePolicyDecider::PolicyDecision decision) { - policy_decision = decision; - callback_called = true; - }); - tab_helper_->ShouldAllowRequest([NSURLRequest requestWithURL:url], - request_info, std::move(callback)); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); - EXPECT_TRUE(policy_decision.ShouldCancelNavigation()); + EXPECT_TRUE(tab_helper_ + ->ShouldAllowRequest([NSURLRequest requestWithURL:url], + request_info) + .ShouldCancelNavigation()); const ReadingListEntry* entry = model->GetEntryByURL(pending_url); return entry->IsRead() == expected_read_status;
diff --git a/ios/chrome/browser/application_context_impl.mm b/ios/chrome/browser/application_context_impl.mm index c1d234f2..38ee2a3 100644 --- a/ios/chrome/browser/application_context_impl.mm +++ b/ios/chrome/browser/application_context_impl.mm
@@ -226,6 +226,7 @@ gcm_driver_->Shutdown(); if (local_state_) { + SetLastSessionExitedCleanly(local_state_.get(), true); local_state_->CommitPendingWrite(); sessions::SessionIdGenerator::GetInstance()->Shutdown(); }
diff --git a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h index 894c23a..5ac01b5 100644 --- a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h +++ b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h
@@ -44,10 +44,9 @@ static bool CanHandleUrl(const GURL& url); // web::WebStatePolicyDecider implementation - void ShouldAllowRequest( + web::WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + const web::WebStatePolicyDecider::RequestInfo& request_info) override; private: friend class web::WebStateUserData<ITunesUrlsHandlerTabHelper>;
diff --git a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.mm b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.mm index edb0282..f7ffb32 100644 --- a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.mm +++ b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.mm
@@ -111,27 +111,24 @@ return path_components[media_type_index] == kITunesAppPathIdentifier; } -void ITunesUrlsHandlerTabHelper::ShouldAllowRequest( +web::WebStatePolicyDecider::PolicyDecision +ITunesUrlsHandlerTabHelper::ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + const web::WebStatePolicyDecider::RequestInfo& request_info) { // Don't Handle URLS in Off The record mode as this will open StoreKit with // Users' iTunes account. Also don't Handle navigations in iframe because they // may be spam, and they will be handled by other policy deciders. if (web_state()->GetBrowserState()->IsOffTheRecord() || !request_info.target_frame_is_main) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } GURL request_url = net::GURLWithNSURL(request.URL); - if (!CanHandleUrl(request_url)) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Allow()); - } + if (!CanHandleUrl(request_url)) + return web::WebStatePolicyDecider::PolicyDecision::Allow(); HandleITunesUrl(request_url); - std::move(callback).Run(web::WebStatePolicyDecider::PolicyDecision::Cancel()); + return web::WebStatePolicyDecider::PolicyDecision::Cancel(); } // private
diff --git a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm index 9396c460..603204a1 100644 --- a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm +++ b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm
@@ -46,19 +46,10 @@ ui::PageTransition::PAGE_TRANSITION_LINK, main_frame, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - __block bool callback_called = false; - __block web::WebStatePolicyDecider::PolicyDecision request_policy = - web::WebStatePolicyDecider::PolicyDecision::Allow(); - auto callback = - base::BindOnce(^(web::WebStatePolicyDecider::PolicyDecision decision) { - request_policy = decision; - callback_called = true; - }); - web_state_.ShouldAllowRequest( - [NSURLRequest requestWithURL:[NSURL URLWithString:url_string]], - request_info, std::move(callback)); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); + web::WebStatePolicyDecider::PolicyDecision request_policy = + web_state_.ShouldAllowRequest( + [NSURLRequest requestWithURL:[NSURL URLWithString:url_string]], + request_info); return request_policy.ShouldCancelNavigation() && (fake_launcher_.launchedProductID != nil || fake_launcher_.launchedProductParams != nil);
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h index cadd8d6..1fee183 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h
@@ -31,10 +31,8 @@ public: ~WellKnownChangePasswordTabHelper() override; // web::WebStatePolicyDecider: - void ShouldAllowRequest( - NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + PolicyDecision ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) override; void ShouldAllowResponse( NSURLResponse* response, bool for_main_frame,
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm index ed6badc..45026342 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm
@@ -48,10 +48,10 @@ } } -void WellKnownChangePasswordTabHelper::ShouldAllowRequest( +web::WebStatePolicyDecider::PolicyDecision +WellKnownChangePasswordTabHelper::ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + const RequestInfo& request_info) { GURL request_url = net::GURLWithNSURL(request.URL); // The custom behaviour is only used if the .well-known/change-password // request if the request is the main frame opened in a new tab. @@ -76,7 +76,7 @@ } } - std::move(callback).Run(web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } void WellKnownChangePasswordTabHelper::ShouldAllowResponse(
diff --git a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.h b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.h index 8767854..2c39a063 100644 --- a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.h +++ b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.h
@@ -17,10 +17,9 @@ ~PolicyUrlBlockingTabHelper() override; // web::WebStatePolicyDecider - void ShouldAllowRequest( + web::WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + const web::WebStatePolicyDecider::RequestInfo& request_info) override; private: friend class web::WebStateUserData<PolicyUrlBlockingTabHelper>;
diff --git a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.mm b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.mm index ff0b2f7b..59e936e9 100644 --- a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.mm +++ b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_tab_helper.mm
@@ -18,22 +18,22 @@ PolicyUrlBlockingTabHelper::PolicyUrlBlockingTabHelper(web::WebState* web_state) : web::WebStatePolicyDecider(web_state) {} -void PolicyUrlBlockingTabHelper::ShouldAllowRequest( +web::WebStatePolicyDecider::PolicyDecision +PolicyUrlBlockingTabHelper::ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + const web::WebStatePolicyDecider::RequestInfo& request_info) { + GURL gurl = net::GURLWithNSURL(request.URL); PolicyBlocklistService* blocklistService = PolicyBlocklistServiceFactory::GetForBrowserState( web_state()->GetBrowserState()); if (blocklistService->GetURLBlocklistState(gurl) == policy::URLBlocklist::URLBlocklistState::URL_IN_BLOCKLIST) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::CancelAndDisplayError( - policy_url_blocking_util::CreateBlockedUrlError())); + return web::WebStatePolicyDecider::PolicyDecision::CancelAndDisplayError( + policy_url_blocking_util::CreateBlockedUrlError()); } - std::move(callback).Run(web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } WEB_STATE_USER_DATA_KEY_IMPL(PolicyUrlBlockingTabHelper)
diff --git a/ios/chrome/browser/prerender/preload_controller.mm b/ios/chrome/browser/prerender/preload_controller.mm index 2e60d5e..14b14ddf 100644 --- a/ios/chrome/browser/prerender/preload_controller.mm +++ b/ios/chrome/browser/prerender/preload_controller.mm
@@ -566,20 +566,18 @@ } #pragma mark - CRWWebStatePolicyDecider -- (void)shouldAllowRequest:(NSURLRequest*)request - requestInfo: - (const WebStatePolicyDecider::RequestInfo&)requestInfo - decisionHandler:(PolicyDecisionHandler)decisionHandler { +- (WebStatePolicyDecider::PolicyDecision) + shouldAllowRequest:(NSURLRequest*)request + requestInfo:(const WebStatePolicyDecider::RequestInfo&)info { GURL requestURL = net::GURLWithNSURL(request.URL); // Don't allow preloading for requests that are handled by opening another // application or by presenting a native UI. if (AppLauncherTabHelper::IsAppUrl(requestURL) || ITunesUrlsHandlerTabHelper::CanHandleUrl(requestURL)) { [self schedulePrerenderCancel]; - decisionHandler(WebStatePolicyDecider::PolicyDecision::Cancel()); - return; + return WebStatePolicyDecider::PolicyDecision::Cancel(); } - decisionHandler(WebStatePolicyDecider::PolicyDecision::Allow()); + return WebStatePolicyDecider::PolicyDecision::Allow(); } #pragma mark - ManageAccountsDelegate
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h index a8773f85..f07bf08 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h
@@ -98,10 +98,9 @@ }; // web::WebStatePolicyDecider implementation - void ShouldAllowRequest( + web::WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + const web::WebStatePolicyDecider::RequestInfo& request_info) override; void ShouldAllowResponse( NSURLResponse* response, bool for_main_frame,
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm index ce5fb8b..55f09f9 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm
@@ -132,18 +132,16 @@ #pragma mark web::WebStatePolicyDecider -void SafeBrowsingTabHelper::PolicyDecider::ShouldAllowRequest( +web::WebStatePolicyDecider::PolicyDecision +SafeBrowsingTabHelper::PolicyDecider::ShouldAllowRequest( NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + const web::WebStatePolicyDecider::RequestInfo& request_info) { // Allow navigations for URLs that cannot be checked by the service. GURL request_url = GetCanonicalizedUrl(net::GURLWithNSURL(request.URL)); SafeBrowsingService* safe_browsing_service = GetApplicationContext()->GetSafeBrowsingService(); - if (!safe_browsing_service->CanCheckUrl(request_url)) { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Allow()); - } + if (!safe_browsing_service->CanCheckUrl(request_url)) + return web::WebStatePolicyDecider::PolicyDecision::Allow(); // Track all pending URL queries. bool is_main_frame = request_info.target_frame_is_main; @@ -172,8 +170,7 @@ // error decision once error pages for cancelled requests are supported. // For now, only cancelled response errors are displayed properly. pending_main_frame_query_->decision = CreateSafeBrowsingErrorDecision(); - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } // Error pages for unsafe subframes are triggered by associating an @@ -193,8 +190,7 @@ // error decision once error pages for cancelled requests are supported. // For now, only cancelled response errors are displayed properly. pending_main_frame_query_->decision = CreateSafeBrowsingErrorDecision(); - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } } @@ -205,8 +201,7 @@ web_state()->GetNavigationManager()->GetLastCommittedItem()) { main_frame_item_id = item->GetUniqueID(); } else { - return std::move(callback).Run( - web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } } @@ -216,20 +211,22 @@ // Allow all requests to continue. If a safe browsing error is detected, the // navigation will be cancelled for using the response policy decision. - std::move(callback).Run(web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } void SafeBrowsingTabHelper::PolicyDecider::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { + base::OnceCallback<void(web::WebStatePolicyDecider::PolicyDecision)> + callback) { // Allow navigations for URLs that cannot be checked by the service. SafeBrowsingService* safe_browsing_service = GetApplicationContext()->GetSafeBrowsingService(); GURL response_url = GetCanonicalizedUrl(net::GURLWithNSURL(response.URL)); if (!safe_browsing_service->CanCheckUrl(response_url)) { - return std::move(callback).Run( + std::move(callback).Run( web::WebStatePolicyDecider::PolicyDecision::Allow()); + return; } if (for_main_frame) {
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm index 5af00e4..a3e27ba5 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm
@@ -72,19 +72,8 @@ web::WebStatePolicyDecider::RequestInfo request_info( transition, for_main_frame, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - __block bool callback_called = false; - __block web::WebStatePolicyDecider::PolicyDecision policy_decision = - web::WebStatePolicyDecider::PolicyDecision::Allow(); - auto callback = - base::BindOnce(^(web::WebStatePolicyDecider::PolicyDecision decision) { - policy_decision = decision; - callback_called = true; - }); - web_state_.ShouldAllowRequest( - [NSURLRequest requestWithURL:net::NSURLWithGURL(url)], request_info, - std::move(callback)); - EXPECT_TRUE(callback_called); - return policy_decision; + return web_state_.ShouldAllowRequest( + [NSURLRequest requestWithURL:net::NSURLWithGURL(url)], request_info); } // Helper function that calls into WebState::ShouldAllowResponse with the
diff --git a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_view_controller.mm b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_view_controller.mm index 3118d573..9ad47aa 100644 --- a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_view_controller.mm
@@ -70,11 +70,8 @@ - (ConsistencyAccountChooserTableViewController*)tableViewController { if (!_tableViewController) { - UITableViewStyle style = base::FeatureList::IsEnabled(kSettingsRefresh) - ? ChromeTableViewStyle() - : UITableViewStylePlain; _tableViewController = [[ConsistencyAccountChooserTableViewController alloc] - initWithStyle:style]; + initWithStyle:UITableViewStyleInsetGrouped]; } return _tableViewController; }
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index 24f82a6..84e006d 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -3845,10 +3845,19 @@ // TODO(crbug.com/1140387): Share action. } + // Truncate context meny titles that originate from URLs, leaving text titles + // untruncated. + NSString* menuTitle = params.menu_title; + if (params.menu_title_origin != web::ContextMenuTitleOrigin::kImageTitle && + menuTitle.length > kContextMenuMaxURLTitleLength + 1) { + menuTitle = [[menuTitle substringToIndex:kContextMenuMaxURLTitleLength] + stringByAppendingString:kContextMenuEllipsis]; + } + UIContextMenuActionProvider actionProvider = ^(NSArray<UIMenuElement*>* suggestedActions) { RecordMenuShown(MenuScenario::kContextMenuLink); - return [UIMenu menuWithTitle:@"" children:menuElements]; + return [UIMenu menuWithTitle:menuTitle children:menuElements]; }; UIContextMenuConfiguration* configuration =
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm index 30243aa..5584cdc7 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -260,7 +260,12 @@ weakSelf.collectionView.contentOffset = CGPointMake(0, pinnedOffsetY); } }; - [coordinator animateAlongsideTransition:alongsideBlock completion:nil]; + [coordinator + animateAlongsideTransition:alongsideBlock + completion:^( + id<UIViewControllerTransitionCoordinatorContext>) { + [self updateFeedInsetsForContentSuggestions]; + }]; } - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_app_interface.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_app_interface.mm index df681421..0e0b7f8 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_app_interface.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_app_interface.mm
@@ -27,10 +27,9 @@ NavigationBlockerDecider(web::WebState* web_state) : web::WebStatePolicyDecider(web_state) {} - void ShouldAllowRequest(NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) override { - std::move(callback).Run(PolicyDecision::Cancel()); + PolicyDecision ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) override { + return PolicyDecision::Cancel(); } WEB_STATE_USER_DATA_KEY_DECL();
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn index a55bb81..1a73e763 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -222,6 +222,7 @@ deps = [ ":tab_grid_ui_constants", "//base", + "//components/bookmarks/common", "//ios/chrome/app/strings", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/fullscreen:feature_flags",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm index f0af69e..62cd0cf 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -420,6 +420,10 @@ if (!GetFirstResponder()) { // It is possible to already have a first responder (for example the // omnibox). In that case, we don't want to mark BVC as first responder. + // TODO(crbug.com/1223090): Adding DCHECK below to confirm hypothesis + // that |-becomeFirstResponder| is crashing due to |currentBVC| not + // being in the view hierarchy. + DCHECK(self.bvcContainer.currentBVC.view.window); [self.bvcContainer.currentBVC becomeFirstResponder]; } if (completion) {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm index 4ac742b..8191bab 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -6,6 +6,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #import "base/test/ios/wait_util.h" +#import "components/bookmarks/common/bookmark_pref_names.h" #import "ios/chrome/browser/ui/start_surface/start_surface_features.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" @@ -13,6 +14,7 @@ #import "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_xcui_actions.h" @@ -378,6 +380,36 @@ assertWithMatcher:grey_notNil()]; } +// Tests that Add to Bookmarks action is greyed out when editBookmarksEnabled +// pref is set to false. +- (void)testTabGridItemContextMenuAddToBookmarkGreyed { + if (!base::ios::IsRunningOnIOS14OrLater()) { + EARL_GREY_TEST_SKIPPED( + @"Context menu item traits are only set correctly after iOS 14."); + } + [ChromeEarlGreyAppInterface + setBoolValue:NO + forUserPref:base::SysUTF8ToNSString( + bookmarks::prefs::kEditBookmarksEnabled)]; + + [ChromeEarlGrey loadURL:_URL1]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + + [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; + [[EarlGrey selectElementWithMatcher:AddToBookmarksButton()] + assertWithMatcher:grey_allOf(grey_notNil(), + grey_accessibilityTrait( + UIAccessibilityTraitNotEnabled), + nil)]; + [ChromeEarlGreyAppInterface + setBoolValue:YES + forUserPref:base::SysUTF8ToNSString( + bookmarks::prefs::kEditBookmarksEnabled)]; +} + // Tests the Share action on a tab grid item's context menu. - (void)testTabGridItemContextCloseTab { if (!base::ios::IsRunningOnIOS13OrLater()) {
diff --git a/ios/chrome/browser/web/invalid_url_tab_helper.h b/ios/chrome/browser/web/invalid_url_tab_helper.h index 8f4e822..4e70a8d 100644 --- a/ios/chrome/browser/web/invalid_url_tab_helper.h +++ b/ios/chrome/browser/web/invalid_url_tab_helper.h
@@ -23,10 +23,8 @@ private: explicit InvalidUrlTabHelper(web::WebState* web_state); - void ShouldAllowRequest( - NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) override; + PolicyDecision ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) override; friend class web::WebStateUserData<InvalidUrlTabHelper>; WEB_STATE_USER_DATA_KEY_DECL();
diff --git a/ios/chrome/browser/web/invalid_url_tab_helper.mm b/ios/chrome/browser/web/invalid_url_tab_helper.mm index 2d2d6c9..17daad5 100644 --- a/ios/chrome/browser/web/invalid_url_tab_helper.mm +++ b/ios/chrome/browser/web/invalid_url_tab_helper.mm
@@ -47,12 +47,11 @@ : web::WebStatePolicyDecider(web_state) {} InvalidUrlTabHelper::~InvalidUrlTabHelper() = default; -void InvalidUrlTabHelper::ShouldAllowRequest( - NSURLRequest* request, - const web::WebStatePolicyDecider::RequestInfo& request_info, - web::WebStatePolicyDecider::PolicyDecisionCallback callback) { +web::WebStatePolicyDecider::PolicyDecision +InvalidUrlTabHelper::ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) { if (IsUrlRequestValid(request)) { - return std::move(callback).Run(PolicyDecision::Allow()); + return PolicyDecision::Allow(); } // URL is invalid. Show error for certain browser-initiated navigations (f.e. @@ -65,12 +64,12 @@ if (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) || PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_GENERATED) || PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { - return std::move(callback).Run(PolicyDecision::CancelAndDisplayError( - [NSError errorWithDomain:net::kNSErrorDomain - code:net::ERR_INVALID_URL - userInfo:nil])); + return PolicyDecision::CancelAndDisplayError([NSError + errorWithDomain:net::kNSErrorDomain + code:net::ERR_INVALID_URL + userInfo:nil]); } - std::move(callback).Run(PolicyDecision::Cancel()); + return PolicyDecision::Cancel(); } WEB_STATE_USER_DATA_KEY_IMPL(InvalidUrlTabHelper)
diff --git a/ios/chrome/browser/web/invalid_url_tab_helper_unittest.mm b/ios/chrome/browser/web/invalid_url_tab_helper_unittest.mm index 6b5b15e..62fa19c1 100644 --- a/ios/chrome/browser/web/invalid_url_tab_helper_unittest.mm +++ b/ios/chrome/browser/web/invalid_url_tab_helper_unittest.mm
@@ -35,17 +35,7 @@ /*target_frame_is_main=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - __block bool callback_called = false; - __block web::WebStatePolicyDecider::PolicyDecision policy_decision = - web::WebStatePolicyDecider::PolicyDecision::Allow(); - auto callback = - base::BindOnce(^(web::WebStatePolicyDecider::PolicyDecision decision) { - policy_decision = decision; - callback_called = true; - }); - web_state_.ShouldAllowRequest(request, info, std::move(callback)); - EXPECT_TRUE(callback_called); - return policy_decision; + return web_state_.ShouldAllowRequest(request, info); } web::FakeWebState web_state_;
diff --git a/ios/chrome/browser/web/lookalike_url_app_interface.mm b/ios/chrome/browser/web/lookalike_url_app_interface.mm index aef313b4..1c1e8b1 100644 --- a/ios/chrome/browser/web/lookalike_url_app_interface.mm +++ b/ios/chrome/browser/web/lookalike_url_app_interface.mm
@@ -69,7 +69,7 @@ std::move(callback).Run(CreateLookalikeErrorDecision()); return; } - std::move(callback).Run( + return std::move(callback).Run( web::WebStatePolicyDecider::PolicyDecision::Allow()); }
diff --git a/ios/chrome/common/credential_provider/multi_store_credential_store.mm b/ios/chrome/common/credential_provider/multi_store_credential_store.mm index 19008cd..976a9bbf 100644 --- a/ios/chrome/common/credential_provider/multi_store_credential_store.mm +++ b/ios/chrome/common/credential_provider/multi_store_credential_store.mm
@@ -14,13 +14,13 @@ @interface MultiStoreCredentialStore () -@property(nonatomic, strong) NSArray<NSArray<id<CredentialStore>>*>* stores; +@property(nonatomic, strong) NSArray<id<CredentialStore>>* stores; @end @implementation MultiStoreCredentialStore -- (instancetype)initWithStores:(NSArray<NSArray<id<CredentialStore>>*>*)stores { +- (instancetype)initWithStores:(NSArray<id<CredentialStore>>*)stores { DCHECK(stores); self = [super init]; if (self) { @@ -33,7 +33,7 @@ - (NSArray<id<Credential>>*)credentials { return - [self.stores valueForKeyPath:@"credentials.@distinctUnionOfObjects.self"]; + [self.stores valueForKeyPath:@"credentials.@distinctUnionOfArrays.self"]; } - (id<Credential>)credentialWithRecordIdentifier:(NSString*)recordIdentifier {
diff --git a/ios/chrome/common/credential_provider/multi_store_credential_store_unittests.mm b/ios/chrome/common/credential_provider/multi_store_credential_store_unittests.mm index 18bd502..f7af3b11 100644 --- a/ios/chrome/common/credential_provider/multi_store_credential_store_unittests.mm +++ b/ios/chrome/common/credential_provider/multi_store_credential_store_unittests.mm
@@ -54,6 +54,12 @@ MultiStoreCredentialStore* credentialStore = [[MultiStoreCredentialStore alloc] initWithStores:TestStoreArray()]; EXPECT_EQ(2u, credentialStore.credentials.count); + + id<Credential> firstCredential = + TestStoreArray().firstObject.credentials.firstObject; + + EXPECT_NSEQ(credentialStore.credentials[0], firstCredential); + EXPECT_NSEQ(credentialStore.credentials[0].user, @"store1user"); } // Tests that MultiStoreCredentialStore don't duplicate data from stores.
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index dbda422..e834dca 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -1d3cbc4b32fba0228b5db707f1f504ae0c2157ea \ No newline at end of file +fc814ff7d7569c14b3c70c96b43a76179794b2c7 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index 2b669c4..8907989 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -86007a1fb3848c1cd552b57518def06d7b3edcfd \ No newline at end of file +b873f027997bd7782939d77537aac698fac72d21 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 index 00f0159..21c1dde 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -9684faeec1d36fef3f2cec3b4f01d24ea3ed6383 \ No newline at end of file +67584985bee51e3eabb9fd0263424e149dd2c246 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 index e780608..196ea61 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -140d0d717bcb692dc9994381354d059d00735389 \ No newline at end of file +c240beea5ac858723cb538870dfe61e9b0517a72 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 0f3d331..ffed8db 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -1d0763fe119f08b4a93d456cb69df06d94e4788b \ No newline at end of file +436b2808ce1ddb3409de03228d0b19e690aa936c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index 7c4986d5..972a756 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -ae6a449db9138ce5a1ee7c8471caac5954558acd \ No newline at end of file +86febbfcf053683e2a665efa63d73656b7d93822 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index 6be5b36..45260a8 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -5e55685a766ef52368dc353112bb3c763e77fcef \ No newline at end of file +347ea27807d911d5516b9ae7cf79cca5cceb27ba \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index a247a50..31afa94 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -c6ae716784b21494948f3e220f5fa37ff1e2d753 \ No newline at end of file +4e7511b60afcaf1f675e3b6bf4d22260b8e1f072 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index 6fb68887..c4332196 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -5832ef39efd328b552116df636b65d1a1155c2d7 \ No newline at end of file +51c9debce061fc8dfb52d261c6d48c0a987cfb4c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index 338e057..6f47fa8 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -91dbdf47a13d5bb85934a3a165a42a22220e372f \ No newline at end of file +bbad05ae7e758bdabebd2800f5b03079188360ee \ No newline at end of file
diff --git a/ios/web/navigation/crw_wk_navigation_handler.mm b/ios/web/navigation/crw_wk_navigation_handler.mm index 8de69e52..f492074b 100644 --- a/ios/web/navigation/crw_wk_navigation_handler.mm +++ b/ios/web/navigation/crw_wk_navigation_handler.mm
@@ -406,51 +406,122 @@ requestURL.SchemeIs(url::kAboutScheme) || requestURL.SchemeIs(url::kBlobScheme); + if (policyDecision.ShouldAllowNavigation()) { + BOOL userInteractedWithRequestMainFrame = + self.userInteractionState->HasUserTappedRecently(webView) && + net::GURLWithNSURL(action.request.mainDocumentURL) == + self.userInteractionState->LastUserInteraction()->main_document_url; + BOOL isCrossOriginTargetFrame = NO; + if (action.sourceFrame && action.targetFrame && + action.sourceFrame != action.targetFrame) { + url::Origin sourceOrigin = + url::Origin::Create(web::GURLOriginWithWKSecurityOrigin( + action.sourceFrame.securityOrigin)); + url::Origin targetOrigin = + url::Origin::Create(web::GURLOriginWithWKSecurityOrigin( + action.targetFrame.securityOrigin)); + isCrossOriginTargetFrame = !sourceOrigin.IsSameOriginWith(targetOrigin); + } + web::WebStatePolicyDecider::RequestInfo requestInfo( + transition, isMainFrameNavigationAction, isCrossOriginTargetFrame, + userInteractedWithRequestMainFrame); + + policyDecision = + self.webStateImpl->ShouldAllowRequest(action.request, requestInfo); + + // The WebState may have been closed in the ShouldAllowRequest callback. + if (self.beingDestroyed) { + decisionHandler(WKNavigationActionPolicyCancel); + return; + } + } + if (!webControllerCanShow) { policyDecision = web::WebStatePolicyDecider::PolicyDecision::Cancel(); } - __weak CRWWKNavigationHandler* weakSelf = self; - auto callback = base::BindOnce( - ^(web::WebStatePolicyDecider::PolicyDecision policyDecision) { - __strong CRWWKNavigationHandler* strongSelf = weakSelf; - // The WebState may have been closed in the ShouldAllowRequest callback. - if (!strongSelf || strongSelf.beingDestroyed) { - decisionHandler(WKNavigationActionPolicyCancel); + if (policyDecision.ShouldAllowNavigation()) { + if ([[action.request HTTPMethod] isEqualToString:@"POST"]) { + // Display the confirmation dialog if a form repost is detected. + if (action.navigationType == WKNavigationTypeFormResubmitted) { + self.webStateImpl->ShowRepostFormWarningDialog( + base::BindOnce(^(bool shouldContinue) { + if (self.beingDestroyed) { + decisionHandler(WKNavigationActionPolicyCancel); + } else if (shouldContinue) { + decisionHandler(WKNavigationActionPolicyAllow); + } else { + decisionHandler(WKNavigationActionPolicyCancel); + if (action.targetFrame.mainFrame) { + [self.pendingNavigationInfo setCancelled:YES]; + } + } + })); + return; + } + + web::NavigationItemImpl* item = + self.navigationManagerImpl->GetCurrentItemImpl(); + // TODO(crbug.com/570699): Remove this check once it's no longer possible + // to have no current entries. + if (item) + [self cachePOSTDataForRequest:action.request inNavigationItem:item]; + } + } else { + if (action.targetFrame.mainFrame) { + if (!self.beingDestroyed && policyDecision.ShouldDisplayError()) { + DCHECK(policyDecision.GetDisplayError()); + + // Navigation was blocked by |ShouldProvisionallyFailRequest|. Cancel + // load of page. + decisionHandler(WKNavigationActionPolicyCancel); + + // Handling presentation of policy decision error is dependent on + // |web::features::kUseJSForErrorPage| feature. + if (!base::FeatureList::IsEnabled(web::features::kUseJSForErrorPage)) { return; } - [strongSelf answerDecisionHandler:decisionHandler - forNavigationAction:action - withPolicyDecision:policyDecision - webView:webView - forceBlockUniversalLinks:forceBlockUniversalLinks]; - }); + [self displayError:policyDecision.GetDisplayError() + forCancelledNavigationToURL:action.request.URL + inWebView:webView + withTransition:transition]; + return; + } - if (!policyDecision.ShouldAllowNavigation()) { - std::move(callback).Run(policyDecision); + [self.pendingNavigationInfo setCancelled:YES]; + if (self.navigationManagerImpl->GetPendingItemIndex() == -1) { + // Discard the new pending item to ensure that the current URL is not + // different from what is displayed on the view. There is no need to + // reset pending item index for a different pending back-forward + // navigation. + self.navigationManagerImpl->DiscardNonCommittedItems(); + } + + web::NavigationContextImpl* context = + [self contextForPendingMainFrameNavigationWithURL:requestURL]; + if (context) { + // Destroy associated pending item, because this will be the last + // WKWebView callback for this navigation context. + context->ReleaseItem(); + } + + if (!self.beingDestroyed && + [self shouldClosePageOnNativeApplicationLoad]) { + self.webStateImpl->CloseWebState(); + decisionHandler(WKNavigationActionPolicyCancel); + return; + } + } + } + + if (policyDecision.ShouldCancelNavigation()) { + decisionHandler(WKNavigationActionPolicyCancel); return; } - - BOOL userInteractedWithRequestMainFrame = - self.userInteractionState->HasUserTappedRecently(webView) && - net::GURLWithNSURL(action.request.mainDocumentURL) == - self.userInteractionState->LastUserInteraction()->main_document_url; - BOOL isCrossOriginTargetFrame = NO; - if (action.sourceFrame && action.targetFrame && - action.sourceFrame != action.targetFrame) { - url::Origin sourceOrigin = url::Origin::Create( - web::GURLOriginWithWKSecurityOrigin(action.sourceFrame.securityOrigin)); - url::Origin targetOrigin = url::Origin::Create( - web::GURLOriginWithWKSecurityOrigin(action.targetFrame.securityOrigin)); - isCrossOriginTargetFrame = !sourceOrigin.IsSameOriginWith(targetOrigin); - } - web::WebStatePolicyDecider::RequestInfo requestInfo( - transition, isMainFrameNavigationAction, isCrossOriginTargetFrame, - userInteractedWithRequestMainFrame); - - self.webStateImpl->ShouldAllowRequest(action.request, requestInfo, - std::move(callback)); + BOOL isOffTheRecord = self.webStateImpl->GetBrowserState()->IsOffTheRecord(); + decisionHandler(web::GetAllowNavigationActionPolicy( + isOffTheRecord || forceBlockUniversalLinks)); } - (void)webView:(WKWebView*)webView @@ -1573,105 +1644,6 @@ [self.navigationStates removeNavigation:navigation]; } -// This method should be called on deciding policy for navigation action. It -// Answers the |decisionHandler| with a final decision caculated with passed -// |policyDecision|. The passed |policyDecision| should be determined by some -// conditions and policy deciders -- (void)answerDecisionHandler: - (void (^)(WKNavigationActionPolicy))decisionHandler - forNavigationAction:(WKNavigationAction*)action - withPolicyDecision: - (web::WebStatePolicyDecider::PolicyDecision)policyDecision - webView:(WKWebView*)webView - forceBlockUniversalLinks:(BOOL)forceBlockUniversalLinks { - if (policyDecision.ShouldAllowNavigation()) { - if ([[action.request HTTPMethod] isEqualToString:@"POST"]) { - // Display the confirmation dialog if a form repost is detected. - if (action.navigationType == WKNavigationTypeFormResubmitted) { - self.webStateImpl->ShowRepostFormWarningDialog( - base::BindOnce(^(bool shouldContinue) { - if (self.beingDestroyed) { - decisionHandler(WKNavigationActionPolicyCancel); - } else if (shouldContinue) { - decisionHandler(WKNavigationActionPolicyAllow); - } else { - decisionHandler(WKNavigationActionPolicyCancel); - if (action.targetFrame.mainFrame) { - [self.pendingNavigationInfo setCancelled:YES]; - } - } - })); - return; - } - - web::NavigationItemImpl* item = - self.navigationManagerImpl->GetCurrentItemImpl(); - // TODO(crbug.com/570699): Remove this check once it's no longer - // possible to have no current entries. - if (item) - [self cachePOSTDataForRequest:action.request inNavigationItem:item]; - } - } else { - if (action.targetFrame.mainFrame) { - if (!self.beingDestroyed && policyDecision.ShouldDisplayError()) { - DCHECK(policyDecision.GetDisplayError()); - - // Navigation was blocked by |ShouldProvisionallyFailRequest|. Cancel - // load of page. - decisionHandler(WKNavigationActionPolicyCancel); - - // Handling presentation of policy decision error is dependent on - // |web::features::kUseJSForErrorPage| feature. - if (!base::FeatureList::IsEnabled(web::features::kUseJSForErrorPage)) { - return; - } - - ui::PageTransition transition = - [self pageTransitionFromNavigationType:action.navigationType]; - - [self displayError:policyDecision.GetDisplayError() - forCancelledNavigationToURL:action.request.URL - inWebView:webView - withTransition:transition]; - return; - } - - [self.pendingNavigationInfo setCancelled:YES]; - if (self.navigationManagerImpl->GetPendingItemIndex() == -1) { - // Discard the new pending item to ensure that the current URL is not - // different from what is displayed on the view. There is no need to - // reset pending item index for a different pending back-forward - // navigation. - self.navigationManagerImpl->DiscardNonCommittedItems(); - } - - web::NavigationContextImpl* context = [self - contextForPendingMainFrameNavigationWithURL:net::GURLWithNSURL( - action.request.URL)]; - if (context) { - // Destroy associated pending item, because this will be the last - // WKWebView callback for this navigation context. - context->ReleaseItem(); - } - - if (!self.beingDestroyed && - [self shouldClosePageOnNativeApplicationLoad]) { - self.webStateImpl->CloseWebState(); - decisionHandler(WKNavigationActionPolicyCancel); - return; - } - } - } - - if (policyDecision.ShouldCancelNavigation()) { - decisionHandler(WKNavigationActionPolicyCancel); - return; - } - BOOL isOffTheRecord = self.webStateImpl->GetBrowserState()->IsOffTheRecord(); - decisionHandler(web::GetAllowNavigationActionPolicy( - isOffTheRecord || forceBlockUniversalLinks)); -} - #pragma mark - Auth Challenge // Used in webView:didReceiveAuthenticationChallenge:completionHandler: to
diff --git a/ios/web/public/navigation/web_state_policy_decider.h b/ios/web/public/navigation/web_state_policy_decider.h index 1125318..3501166 100644 --- a/ios/web/public/navigation/web_state_policy_decider.h +++ b/ios/web/public/navigation/web_state_policy_decider.h
@@ -106,13 +106,18 @@ virtual ~WebStatePolicyDecider(); // Asks the decider whether the navigation corresponding to |request| should - // be allowed to continue. Defaults to PolicyDecision::Allow() if not - // overridden. Called before WebStateObserver::DidStartNavigation. Calls - // |callback| with the decision. Never called in the following cases: + // be allowed to continue. The first policy decider returning a PolicyDecision + // where ShouldCancelNavigation() is true will be the PolicyDecision used for + // the navigation. This means that a policy decider may not be called and have + // its expected decision performed for a given navigation. As such, the + // highest priority policy deciders should be added first to ensure those + // decisions are prioritized. + // Called before WebStateObserver::DidStartNavigation. + // Defaults to PolicyDecision::Allow() if not overridden. + // Never called in the following cases: // - same-document back-forward and state change navigations - virtual void ShouldAllowRequest(NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback); + virtual PolicyDecision ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info); // Asks the decider whether the navigation corresponding to |response| should // be allowed to display an error page if an error occurs. Defaults to
diff --git a/ios/web/public/navigation/web_state_policy_decider_bridge.h b/ios/web/public/navigation/web_state_policy_decider_bridge.h index 9e8276c1..97fa402e 100644 --- a/ios/web/public/navigation/web_state_policy_decider_bridge.h +++ b/ios/web/public/navigation/web_state_policy_decider_bridge.h
@@ -9,28 +9,27 @@ #import "ios/web/public/navigation/web_state_policy_decider.h" -typedef void (^PolicyDecisionHandler)( - web::WebStatePolicyDecider::PolicyDecision); - // Objective-C interface for web::WebStatePolicyDecider. @protocol CRWWebStatePolicyDecider <NSObject> @optional // Invoked by |WebStatePolicyDeciderBridge::ShouldAllowRequest|. -- (void)shouldAllowRequest:(NSURLRequest*)request - requestInfo: - (const web::WebStatePolicyDecider::RequestInfo&)requestInfo - decisionHandler:(PolicyDecisionHandler)decisionHandler; +- (web::WebStatePolicyDecider::PolicyDecision) + shouldAllowRequest:(NSURLRequest*)request + requestInfo: + (const web::WebStatePolicyDecider::RequestInfo&)requestInfo; // Invoked by |WebStatePolicyDeciderBridge::ShouldAllowRequest|. - (bool)shouldAllowErrorPageToBeDisplayed:(NSURLResponse*)response forMainFrame:(BOOL)forMainFrame; // Invoked by |WebStatePolicyDeciderBridge::ShouldAllowResponse|. -- (void)decidePolicyForNavigationResponse:(NSURLResponse*)response - forMainFrame:(BOOL)forMainFrame - decisionHandler: - (PolicyDecisionHandler)decisionHandler; +- (void) + decidePolicyForNavigationResponse:(NSURLResponse*)response + forMainFrame:(BOOL)forMainFrame + completionHandler: + (void (^)(web::WebStatePolicyDecider::PolicyDecision)) + completionHandler; @end namespace web { @@ -44,13 +43,13 @@ ~WebStatePolicyDeciderBridge() override; // web::WebStatePolicyDecider methods. - void ShouldAllowRequest(NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) override; + PolicyDecision ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) override; - void ShouldAllowResponse(NSURLResponse* response, - bool for_main_frame, - PolicyDecisionCallback callback) override; + void ShouldAllowResponse( + NSURLResponse* response, + bool for_main_frame, + base::OnceCallback<void(PolicyDecision)> callback) override; bool ShouldAllowErrorPageToBeDisplayed(NSURLResponse* response, bool for_main_frame) override;
diff --git a/ios/web/public/test/fakes/crw_fake_web_state_policy_decider.mm b/ios/web/public/test/fakes/crw_fake_web_state_policy_decider.mm index ad568b3..2a8d9597 100644 --- a/ios/web/public/test/fakes/crw_fake_web_state_policy_decider.mm +++ b/ios/web/public/test/fakes/crw_fake_web_state_policy_decider.mm
@@ -41,25 +41,27 @@ #pragma mark CRWWebStatePolicyDecider methods - -- (void)shouldAllowRequest:(NSURLRequest*)request - requestInfo: - (const web::WebStatePolicyDecider::RequestInfo&)requestInfo - decisionHandler:(PolicyDecisionHandler)decisionHandler { +- (web::WebStatePolicyDecider::PolicyDecision) + shouldAllowRequest:(NSURLRequest*)request + requestInfo: + (const web::WebStatePolicyDecider::RequestInfo&)requestInfo { _shouldAllowRequestInfo = std::make_unique<web::FakeShouldAllowRequestInfo>(); _shouldAllowRequestInfo->request = request; _shouldAllowRequestInfo->request_info = requestInfo; - decisionHandler(web::WebStatePolicyDecider::PolicyDecision::Allow()); + return web::WebStatePolicyDecider::PolicyDecision::Allow(); } -- (void)decidePolicyForNavigationResponse:(NSURLResponse*)response - forMainFrame:(BOOL)forMainFrame - decisionHandler: - (PolicyDecisionHandler)decisionHandler { +- (void) + decidePolicyForNavigationResponse:(NSURLResponse*)response + forMainFrame:(BOOL)forMainFrame + completionHandler: + (void (^)(web::WebStatePolicyDecider::PolicyDecision)) + completionHandler { _decidePolicyForNavigationResponseInfo = std::make_unique<web::FakeDecidePolicyForNavigationResponseInfo>(); _decidePolicyForNavigationResponseInfo->response = response; _decidePolicyForNavigationResponseInfo->for_main_frame = forMainFrame; - decisionHandler(web::WebStatePolicyDecider::PolicyDecision::Allow()); + completionHandler(web::WebStatePolicyDecider::PolicyDecision::Allow()); } @end
diff --git a/ios/web/public/test/fakes/fake_web_state.h b/ios/web/public/test/fakes/fake_web_state.h index 47bd077e..41fad446 100644 --- a/ios/web/public/test/fakes/fake_web_state.h +++ b/ios/web/public/test/fakes/fake_web_state.h
@@ -118,20 +118,18 @@ void SetCanTakeSnapshot(bool can_take_snapshot); // Getters for test data. - // Uses |policy_deciders| to determine whether the navigation corresponding to - // |request| should be allowed. Calls |callback| with the decision. Defaults - // to PolicyDecision::Allow(). - void ShouldAllowRequest( + // Uses |policy_deciders| to return whether the navigation corresponding to + // |request| should be allowed. Defaults to PolicyDecision::Allow(). + WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback); + const WebStatePolicyDecider::RequestInfo& request_info); // Uses |policy_deciders| to determine whether the navigation corresponding to // |response| should be allowed. Calls |callback| with the decision. Defaults // to PolicyDecision::Allow(). void ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback); + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> callback); std::u16string GetLastExecutedJavascript() const; // Returns a copy of the last added callback, if one has been added. absl::optional<ScriptCommandCallback> GetLastAddedCallback() const;
diff --git a/ios/web/public/test/fakes/fake_web_state.mm b/ios/web/public/test/fakes/fake_web_state.mm index 17e5435..a91c36e 100644 --- a/ios/web/public/test/fakes/fake_web_state.mm +++ b/ios/web/public/test/fakes/fake_web_state.mm
@@ -354,34 +354,23 @@ } } -void FakeWebState::ShouldAllowRequest( +WebStatePolicyDecider::PolicyDecision FakeWebState::ShouldAllowRequest( NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback) { - auto request_state_tracker = - std::make_unique<PolicyDecisionStateTracker>(std::move(callback)); - PolicyDecisionStateTracker* request_state_tracker_ptr = - request_state_tracker.get(); - auto policy_decider_callback = base::BindRepeating( - &PolicyDecisionStateTracker::OnSinglePolicyDecisionReceived, - base::Owned(std::move(request_state_tracker))); - int num_decisions_requested = 0; + const WebStatePolicyDecider::RequestInfo& request_info) { for (auto& policy_decider : policy_deciders_) { - policy_decider.ShouldAllowRequest(request, request_info, - policy_decider_callback); - num_decisions_requested++; - if (request_state_tracker_ptr->DeterminedFinalResult()) - break; + WebStatePolicyDecider::PolicyDecision result = + policy_decider.ShouldAllowRequest(request, request_info); + if (result.ShouldCancelNavigation()) { + return result; + } } - - request_state_tracker_ptr->FinishedRequestingDecisions( - num_decisions_requested); + return WebStatePolicyDecider::PolicyDecision::Allow(); } void FakeWebState::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback) { + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> callback) { auto response_state_tracker = std::make_unique<PolicyDecisionStateTracker>(std::move(callback)); PolicyDecisionStateTracker* response_state_tracker_ptr =
diff --git a/ios/web/public/test/fakes/fake_web_state_policy_decider.h b/ios/web/public/test/fakes/fake_web_state_policy_decider.h index 4df20d1..8cded2d 100644 --- a/ios/web/public/test/fakes/fake_web_state_policy_decider.h +++ b/ios/web/public/test/fakes/fake_web_state_policy_decider.h
@@ -24,14 +24,15 @@ WebStatePolicyDecider::PolicyDecision should_allow_request); // WebStatePolicyDecider overrides + // Returns the value set with |SetShouldAllowRequest|. Defaults to true. + WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( + NSURLRequest* request, + const RequestInfo& request_info) override; // Always calls |callback| with PolicyDecision::Allow(). - void ShouldAllowRequest(NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) override; - // Always calls |callback| with PolicyDecision::Allow(). - void ShouldAllowResponse(NSURLResponse* response, - bool for_main_frame, - PolicyDecisionCallback callback) override; + void ShouldAllowResponse( + NSURLResponse* response, + bool for_main_frame, + base::OnceCallback<void(PolicyDecision)> callback) override; void WebStateDestroyed() override {} private:
diff --git a/ios/web/public/test/fakes/fake_web_state_policy_decider.mm b/ios/web/public/test/fakes/fake_web_state_policy_decider.mm index 3df6b75..e3cbb2e 100644 --- a/ios/web/public/test/fakes/fake_web_state_policy_decider.mm +++ b/ios/web/public/test/fakes/fake_web_state_policy_decider.mm
@@ -18,17 +18,16 @@ should_allow_request_ = should_allow_request; } -void FakeWebStatePolicyDecider::ShouldAllowRequest( - NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) { - std::move(callback).Run(should_allow_request_); +WebStatePolicyDecider::PolicyDecision +FakeWebStatePolicyDecider::ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) { + return should_allow_request_; } void FakeWebStatePolicyDecider::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - PolicyDecisionCallback callback) { + base::OnceCallback<void(PolicyDecision)> callback) { std::move(callback).Run(PolicyDecision::Allow()); }
diff --git a/ios/web/web_state/error_page_inttest.mm b/ios/web/web_state/error_page_inttest.mm index ed646613..112f818 100644 --- a/ios/web/web_state/error_page_inttest.mm +++ b/ios/web/web_state/error_page_inttest.mm
@@ -92,14 +92,13 @@ const std::string& allowed_page_text() const { return allowed_query_; } // WebStatePolicyDecider overrides - void ShouldAllowRequest(NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) override { + PolicyDecision ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) override { PolicyDecision decision = PolicyDecision::Allow(); GURL URL = net::GURLWithNSURL(request.URL); if (URL.path() != path_ || URL.query() == blocked_request_query_) decision = PolicyDecision::CancelAndDisplayError(CreateEmbedderError()); - std::move(callback).Run(decision); + return decision; } void ShouldAllowResponse(NSURLResponse* response, bool for_main_frame,
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index ff8ae41b..6b8e6f1 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -981,15 +981,16 @@ ~TestWebStatePolicyDecider() override = default; // WebStatePolicyDecider overrides - void ShouldAllowRequest(NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) override { + PolicyDecision ShouldAllowRequest( + NSURLRequest* request, + const RequestInfo& request_info) override { test_fixture->DestroyWebState(); - std::move(callback).Run(PolicyDecision::Allow()); + return PolicyDecision::Allow(); } - void ShouldAllowResponse(NSURLResponse* response, - bool for_main_frame, - PolicyDecisionCallback callback) override { + void ShouldAllowResponse( + NSURLResponse* response, + bool for_main_frame, + base::OnceCallback<void(PolicyDecision)> callback) override { std::move(callback).Run(PolicyDecision::Allow()); } void WebStateDestroyed() override {}
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index 8ce1478..5803d09 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -135,18 +135,12 @@ // that is the point where MIME type is set from HTTP headers. void SetContentsMimeType(const std::string& mime_type); - // Decides whether the navigation corresponding to |request| should be - // allowed to continue by asking its policy deciders, and calls |callback| - // with the decision. Defaults to PolicyDecision::Allow(). If at least one - // policy decider's decision is PolicyDecision::Cancel(), the final result is - // PolicyDecision::Cancel(). Otherwise, if at least one policy decider's - // decision is PolicyDecision::CancelAndDisplayError(), the final result is - // PolicyDecision::CancelAndDisplayError(), with the error corresponding to - // the first PolicyDecision::CancelAndDisplayError() result that was received. - void ShouldAllowRequest( + // Returns whether the navigation corresponding to |request| should be allowed + // to continue by asking its policy deciders. Defaults to + // PolicyDecision::Allow(). + WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback); + const WebStatePolicyDecider::RequestInfo& request_info); // Decides whether the navigation corresponding to |response| should // be allowed to display an error page if an error occurs, by asking its @@ -166,7 +160,7 @@ void ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback); + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> callback); // Determines whether the given link with |link_url| should show a preview on // force touch.
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index 08edda6..9270381 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -465,28 +465,17 @@ mime_type_ = mime_type; } -void WebStateImpl::ShouldAllowRequest( +WebStatePolicyDecider::PolicyDecision WebStateImpl::ShouldAllowRequest( NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback) { - auto request_state_tracker = - std::make_unique<PolicyDecisionStateTracker>(std::move(callback)); - PolicyDecisionStateTracker* request_state_tracker_ptr = - request_state_tracker.get(); - auto policy_decider_callback = base::BindRepeating( - &PolicyDecisionStateTracker::OnSinglePolicyDecisionReceived, - base::Owned(std::move(request_state_tracker))); - int num_decisions_requested = 0; + const WebStatePolicyDecider::RequestInfo& request_info) { for (auto& policy_decider : policy_deciders_) { - policy_decider.ShouldAllowRequest(request, request_info, - policy_decider_callback); - num_decisions_requested++; - if (request_state_tracker_ptr->DeterminedFinalResult()) - break; + WebStatePolicyDecider::PolicyDecision result = + policy_decider.ShouldAllowRequest(request, request_info); + if (result.ShouldCancelNavigation()) { + return result; + } } - - request_state_tracker_ptr->FinishedRequestingDecisions( - num_decisions_requested); + return WebStatePolicyDecider::PolicyDecision::Allow(); } bool WebStateImpl::ShouldAllowErrorPageToBeDisplayed(NSURLResponse* response, @@ -503,7 +492,7 @@ void WebStateImpl::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback) { + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> callback) { auto response_state_tracker = std::make_unique<PolicyDecisionStateTracker>(std::move(callback)); PolicyDecisionStateTracker* response_state_tracker_ptr =
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm index 1da78d7..45f1a336 100644 --- a/ios/web/web_state/web_state_impl_unittest.mm +++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -118,17 +118,19 @@ : WebStatePolicyDecider(web_state) {} virtual ~MockWebStatePolicyDecider() {} - MOCK_METHOD3(ShouldAllowRequest, - void(NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback)); + MOCK_METHOD2(ShouldAllowRequest, + WebStatePolicyDecider::PolicyDecision( + NSURLRequest* request, + const WebStatePolicyDecider::RequestInfo& request_info)); MOCK_METHOD2(ShouldAllowErrorPageToBeDisplayed, bool(NSURLResponse* response, bool for_main_frame)); - MOCK_METHOD3(ShouldAllowResponse, - void(NSURLResponse* response, - bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback)); + MOCK_METHOD3( + ShouldAllowResponse, + void(NSURLResponse* response, + bool for_main_frame, + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> + callback)); MOCK_METHOD0(WebStateDestroyed, void()); }; @@ -618,28 +620,17 @@ /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL( - decider, - ShouldAllowRequest(request, RequestInfoMatch(request_info_main_frame), _)) + EXPECT_CALL(decider, ShouldAllowRequest( + request, RequestInfoMatch(request_info_main_frame))) .Times(1) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); - EXPECT_CALL( - decider2, - ShouldAllowRequest(request, RequestInfoMatch(request_info_main_frame), _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(decider2, ShouldAllowRequest( + request, RequestInfoMatch(request_info_main_frame))) .Times(1) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); WebStatePolicyDecider::PolicyDecision policy_decision = - WebStatePolicyDecider::PolicyDecision::Cancel(); - auto callback = base::BindRepeating( - [](WebStatePolicyDecider::PolicyDecision* policy_decision, - WebStatePolicyDecider::PolicyDecision result) { - *policy_decision = result; - }, - base::Unretained(&policy_decision)); - web_state_->ShouldAllowRequest(request, request_info_main_frame, callback); + web_state_->ShouldAllowRequest(request, request_info_main_frame); EXPECT_TRUE(policy_decision.ShouldAllowNavigation()); EXPECT_FALSE(policy_decision.ShouldCancelNavigation()); @@ -649,17 +640,16 @@ /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); EXPECT_CALL(decider, ShouldAllowRequest( - request, RequestInfoMatch(request_info_iframe), _)) + request, RequestInfoMatch(request_info_iframe))) .Times(1) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(decider2, ShouldAllowRequest( - request, RequestInfoMatch(request_info_iframe), _)) + request, RequestInfoMatch(request_info_iframe))) .Times(1) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); - web_state_->ShouldAllowRequest(request, request_info_iframe, callback); + policy_decision = + web_state_->ShouldAllowRequest(request, request_info_iframe); EXPECT_TRUE(policy_decision.ShouldAllowNavigation()); EXPECT_FALSE(policy_decision.ShouldCancelNavigation()); @@ -668,22 +658,23 @@ { bool decider_called = false; bool decider2_called = false; - EXPECT_CALL(decider, - ShouldAllowRequest( - request, RequestInfoMatch(request_info_main_frame), _)) + EXPECT_CALL( + decider, + ShouldAllowRequest(request, RequestInfoMatch(request_info_main_frame))) .Times(AtMost(1)) - .WillOnce(DoAll(Assign(&decider_called, true), - RunOnceCallback<2>( - WebStatePolicyDecider::PolicyDecision::Cancel()))); - EXPECT_CALL(decider2, - ShouldAllowRequest( - request, RequestInfoMatch(request_info_main_frame), _)) + .WillOnce( + DoAll(Assign(&decider_called, true), + Return(WebStatePolicyDecider::PolicyDecision::Cancel()))); + EXPECT_CALL( + decider2, + ShouldAllowRequest(request, RequestInfoMatch(request_info_main_frame))) .Times(AtMost(1)) - .WillOnce(DoAll(Assign(&decider2_called, true), - RunOnceCallback<2>( - WebStatePolicyDecider::PolicyDecision::Cancel()))); + .WillOnce( + DoAll(Assign(&decider2_called, true), + Return(WebStatePolicyDecider::PolicyDecision::Cancel()))); - web_state_->ShouldAllowRequest(request, request_info_main_frame, callback); + WebStatePolicyDecider::PolicyDecision policy_decision = + web_state_->ShouldAllowRequest(request, request_info_main_frame); EXPECT_FALSE(policy_decision.ShouldAllowNavigation()); EXPECT_TRUE(policy_decision.ShouldCancelNavigation()); EXPECT_FALSE(decider_called && decider2_called); @@ -699,6 +690,13 @@ .WillOnce( RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + policy_decision = WebStatePolicyDecider::PolicyDecision::Cancel(); + auto callback = base::BindRepeating( + [](WebStatePolicyDecider::PolicyDecision* policy_decision, + WebStatePolicyDecider::PolicyDecision result) { + *policy_decision = result; + }, + base::Unretained(&policy_decision)); web_state_->ShouldAllowResponse(response, true, callback); EXPECT_TRUE(policy_decision.ShouldAllowNavigation()); EXPECT_FALSE(policy_decision.ShouldCancelNavigation());
diff --git a/ios/web/web_state/web_state_observer_inttest.mm b/ios/web/web_state/web_state_observer_inttest.mm index 94a18d0..fd8d47ae 100644 --- a/ios/web/web_state/web_state_observer_inttest.mm +++ b/ios/web/web_state/web_state_observer_inttest.mm
@@ -65,7 +65,6 @@ using base::test::RunOnceCallback; using wk_navigation_util::CreateRedirectUrl; -using ::testing::WithArgs; const char kExpectedMimeType[] = "text/html"; @@ -94,10 +93,7 @@ dispatch_async(dispatch_get_main_queue(), ^{ web_state->Stop(); }); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(std::move(arg0), - WebStatePolicyDecider::PolicyDecision::Allow())); + return WebStatePolicyDecider::PolicyDecision::Allow(); } // Verifies correctness of WebState's title. @@ -773,21 +769,16 @@ class PolicyDeciderMock : public WebStatePolicyDecider { public: PolicyDeciderMock(WebState* web_state) : WebStatePolicyDecider(web_state) {} - - void ShouldAllowRequest( - NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback) override { - MockShouldAllowRequest(request, request_info, callback); - } - MOCK_METHOD3(MockShouldAllowRequest, - void(NSURLRequest*, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback& callback)); - MOCK_METHOD3(ShouldAllowResponse, - void(NSURLResponse*, - bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback)); + MOCK_METHOD2(ShouldAllowRequest, + WebStatePolicyDecider::PolicyDecision( + NSURLRequest*, + const WebStatePolicyDecider::RequestInfo& request_info)); + MOCK_METHOD3( + ShouldAllowResponse, + void(NSURLResponse*, + bool for_main_frame, + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> + callback)); }; } // namespace @@ -874,11 +865,10 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) .InSequence(callbacks_sequence) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .InSequence(callbacks_sequence) .WillOnce(VerifyPageStartedContext( @@ -926,10 +916,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -971,10 +960,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStopLoading(web_state())); EXPECT_CALL(observer_, DidStartLoading(web_state())); @@ -993,10 +981,9 @@ PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS)); // Load |second_url|. - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartLoading(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( @@ -1041,10 +1028,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1077,10 +1063,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1136,10 +1121,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1159,7 +1143,7 @@ // Navigate to an invalid URL using JavaScript. // There should be no calls to WebStatePolicyDecider, since the navigation // should get cancelled before that is reached. - EXPECT_CALL(*decider_, MockShouldAllowRequest(_, _, _)).Times(0); + EXPECT_CALL(*decider_, ShouldAllowRequest(_, _)).Times(0); ExecuteJavaScript(@"window.location.pathname = '/%00%50'"); } @@ -1180,10 +1164,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, @@ -1218,10 +1201,9 @@ ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); // WKWebView.URL changes from |url| nil and then to rewritten URL, while // WKWebView.loading changes from true to false and then back to true. @@ -1260,10 +1242,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1310,10 +1291,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1359,6 +1339,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStopLoading(web_state())); test::LoadUrl(web_state(), url); @@ -1378,10 +1361,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -1401,10 +1383,9 @@ /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(reload_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(reload_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce( VerifyReloadStartedContext(web_state(), url, &context, &nav_id)); @@ -1434,10 +1415,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -1456,11 +1436,9 @@ ui::PageTransition::PAGE_TRANSITION_RELOAD, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(expected_reload_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest( + _, RequestInfoMatch(expected_reload_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_RELOAD, @@ -1491,10 +1469,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1519,11 +1496,10 @@ /*has_user_gesture=*/false); EXPECT_CALL(observer_, DidStartLoading(web_state())); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(hash_url_expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL( + *decider_, + ShouldAllowRequest(_, RequestInfoMatch(hash_url_expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())); EXPECT_CALL(observer_, DidStopLoading(web_state())); @@ -1586,10 +1562,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1612,11 +1587,9 @@ ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(expected_hash_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest( + _, RequestInfoMatch(expected_hash_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) @@ -1648,10 +1621,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -1714,10 +1686,9 @@ ui::PageTransition::PAGE_TRANSITION_GENERATED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPostStartedContext( web_state(), url, /*has_user_gesture=*/true, &context, &nav_id, @@ -1753,10 +1724,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -1777,9 +1747,8 @@ /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); EXPECT_CALL(*decider_, - MockShouldAllowRequest(_, RequestInfoMatch(form_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + ShouldAllowRequest(_, RequestInfoMatch(form_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartLoading(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPostStartedContext( @@ -1812,10 +1781,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -1834,9 +1802,8 @@ /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); EXPECT_CALL(*decider_, - MockShouldAllowRequest(_, RequestInfoMatch(form_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + ShouldAllowRequest(_, RequestInfoMatch(form_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartLoading(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) @@ -1860,10 +1827,9 @@ ui::PageTransition::PAGE_TRANSITION_RELOAD, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(form_reload_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(form_reload_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPostStartedContext( @@ -1901,10 +1867,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -1923,9 +1888,8 @@ /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); EXPECT_CALL(*decider_, - MockShouldAllowRequest(_, RequestInfoMatch(form_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + ShouldAllowRequest(_, RequestInfoMatch(form_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartLoading(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) @@ -1950,9 +1914,8 @@ EXPECT_CALL(observer_, DidStartLoading(web_state())); EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())).Times(2); EXPECT_CALL(*decider_, - MockShouldAllowRequest(_, RequestInfoMatch(back_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + ShouldAllowRequest(_, RequestInfoMatch(back_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _)); @@ -1974,10 +1937,9 @@ int32_t nav_id = 0; EXPECT_CALL(observer_, DidStartLoading(web_state())); EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())).Times(2); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(forward_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(forward_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPostStartedContext(web_state(), action, @@ -2021,10 +1983,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2035,35 +1996,30 @@ ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(expected_redirect_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL( + *decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_redirect_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidRedirectNavigation(web_state(), _)); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(expected_redirect_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL( + *decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_redirect_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidRedirectNavigation(web_state(), _)); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(expected_redirect_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL( + *decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_redirect_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidRedirectNavigation(web_state(), _)); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(expected_redirect_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL( + *decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_redirect_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidRedirectNavigation(web_state(), _)); - EXPECT_CALL(*decider_, - MockShouldAllowRequest( - _, RequestInfoMatch(expected_redirect_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL( + *decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_redirect_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidRedirectNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) @@ -2091,10 +2047,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2123,10 +2078,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2175,10 +2129,8 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, - MockShouldAllowRequest(_, RequestInfoMatch(request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(_, RequestInfoMatch(request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2212,10 +2164,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Cancel())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Cancel())); EXPECT_CALL(observer_, DidStopLoading(web_state())); test::LoadUrl(web_state(), test_server_->GetURL("/echo")); ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state())); @@ -2239,9 +2190,9 @@ NSError* error = [NSError errorWithDomain:net::kNSErrorDomain code:net::ERR_BLOCKED_BY_ADMINISTRATOR userInfo:nil]; - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce(RunOnceCallback<2>( + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return( WebStatePolicyDecider::PolicyDecision::CancelAndDisplayError(error))); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); @@ -2275,10 +2226,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2319,10 +2269,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2353,10 +2302,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2390,10 +2338,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); test::LoadUrl(web_state(), test_server_->GetURL("/hung")); web_state()->Stop(); ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state())); @@ -2421,9 +2368,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce(WithArgs<2>(ReturnAllowRequestAndStopNavigation(web_state()))); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(ReturnAllowRequestAndStopNavigation(web_state())); EXPECT_CALL(observer_, DidStopLoading(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyAbortedNavigationStartedContext( @@ -2454,10 +2401,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2499,10 +2445,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -2514,10 +2459,9 @@ ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*target_main_frame=*/false, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(iframe_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(iframe_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/false, _)) .WillOnce( RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); @@ -2533,10 +2477,9 @@ ui::PageTransition::PAGE_TRANSITION_LINK, /*target_main_frame=*/false, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/true); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(link_clicked_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest( + _, RequestInfoMatch(link_clicked_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/false, _)) .WillOnce( RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); @@ -2562,10 +2505,9 @@ /*has_user_gesture=*/true); EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())) .Times(2); // called once each for canGoBack and canGoForward - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(forward_back_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest( + _, RequestInfoMatch(forward_back_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStopLoading(web_state())); @@ -2583,10 +2525,9 @@ ASSERT_FALSE(web_state()->GetNavigationManager()->CanGoBack()); // Trigger same-document load in iframe. - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(link_clicked_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest( + _, RequestInfoMatch(link_clicked_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); // ShouldAllowResponse() is not called for same-document navigation. EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())) .Times(2); // called once each for canGoBack and canGoForward @@ -2612,10 +2553,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -2627,10 +2567,9 @@ ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*target_main_frame=*/false, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(iframe_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(iframe_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/false, _)) .WillOnce( RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); @@ -2649,10 +2588,9 @@ ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*target_main_frame=*/false, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(iframe_request_info2), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(iframe_request_info2))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/false, _)) .WillOnce( RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); @@ -2670,10 +2608,9 @@ ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*target_main_frame=*/false, /*target_frame_is_cross_origin=*/true, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(iframe_request_info3), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(iframe_request_info3))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/false, _)) .WillOnce( RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); @@ -2690,9 +2627,8 @@ // Perform first navigation. const GURL first_url = test_server_->GetURL("/echoall"); EXPECT_CALL(observer_, DidStartLoading(web_state())); - EXPECT_CALL(*decider_, MockShouldAllowRequest(_, _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(_, _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -2706,9 +2642,8 @@ // Perform second navigation. const GURL hash_url = test_server_->GetURL("/echoall#1"); EXPECT_CALL(observer_, DidStartLoading(web_state())); - EXPECT_CALL(*decider_, MockShouldAllowRequest(_, _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(_, _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())); EXPECT_CALL(observer_, DidStopLoading(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); @@ -2742,9 +2677,8 @@ // New page load destroys forward navigation entries. const GURL url = test_server_->GetURL("/echo"); EXPECT_CALL(observer_, DidStartLoading(web_state())); - EXPECT_CALL(*decider_, MockShouldAllowRequest(_, _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(_, _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( @@ -2783,9 +2717,8 @@ EXPECT_CALL(observer_, DidStartLoading(web_state())); - EXPECT_CALL(*decider_, MockShouldAllowRequest(_, _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(_, _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true, _)) .WillOnce( RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); @@ -2800,9 +2733,8 @@ // Client-side redirect to restore_session.html?targetUrl=url1. EXPECT_CALL(*decider_, - MockShouldAllowRequest(URLMatch(CreateRedirectUrl(url1)), _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + ShouldAllowRequest(URLMatch(CreateRedirectUrl(url1)), _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartLoading(web_state())); @@ -2814,9 +2746,8 @@ EXPECT_CALL(observer_, DidStopLoading(web_state())); // Client-side redirect to |url1|. - EXPECT_CALL(*decider_, MockShouldAllowRequest(URLMatch(url1), _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(URLMatch(url1), _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartLoading(web_state())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)); @@ -2848,9 +2779,8 @@ // Load restore_session.html?targetUrl=url0. EXPECT_CALL(*decider_, - MockShouldAllowRequest(URLMatch(CreateRedirectUrl(url0)), _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + ShouldAllowRequest(URLMatch(CreateRedirectUrl(url0)), _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(*decider_, ShouldAllowResponse(URLMatch(CreateRedirectUrl(url0)), /*for_main_frame=*/true, _)) .WillOnce( @@ -2859,9 +2789,8 @@ EXPECT_CALL(observer_, DidStopLoading(web_state())); // Client-side redirect to |url0|. - EXPECT_CALL(*decider_, MockShouldAllowRequest(URLMatch(url0), _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(URLMatch(url0), _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartLoading(web_state())); @@ -2939,10 +2868,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyPageStartedContext( web_state(), url, ui::PageTransition::PAGE_TRANSITION_TYPED, &context, @@ -2972,10 +2900,9 @@ ui::PageTransition::PAGE_TRANSITION_TYPED, /*target_main_frame=*/true, /*target_frame_is_cross_origin=*/false, /*has_user_gesture=*/false); - EXPECT_CALL(*decider_, MockShouldAllowRequest( - _, RequestInfoMatch(expected_request_info), _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, + ShouldAllowRequest(_, RequestInfoMatch(expected_request_info))) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); NavigationContext* context = nullptr; int32_t nav_id = 0; EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) @@ -2998,9 +2925,8 @@ GURL data_url("https://www.chromium.test"); EXPECT_CALL(observer_, DidStartLoading(web_state())); - EXPECT_CALL(*decider_, MockShouldAllowRequest(_, _, _)) - .WillOnce( - RunOnceCallback<2>(WebStatePolicyDecider::PolicyDecision::Allow())); + EXPECT_CALL(*decider_, ShouldAllowRequest(_, _)) + .WillOnce(Return(WebStatePolicyDecider::PolicyDecision::Allow())); // ShouldAllowResponse is not called on loadData navigation. EXPECT_CALL(observer_, DidStartNavigation(web_state(), _)) .WillOnce(VerifyDataStartedContext(
diff --git a/ios/web/web_state/web_state_policy_decider.mm b/ios/web/web_state/web_state_policy_decider.mm index c33216ee..00dca39 100644 --- a/ios/web/web_state/web_state_policy_decider.mm +++ b/ios/web/web_state/web_state_policy_decider.mm
@@ -64,11 +64,10 @@ } } -void WebStatePolicyDecider::ShouldAllowRequest( +WebStatePolicyDecider::PolicyDecision WebStatePolicyDecider::ShouldAllowRequest( NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) { - std::move(callback).Run(PolicyDecision::Allow()); + const WebStatePolicyDecider::RequestInfo& request_info) { + return WebStatePolicyDecider::PolicyDecision::Allow(); } bool WebStatePolicyDecider::ShouldAllowErrorPageToBeDisplayed( @@ -80,7 +79,7 @@ void WebStatePolicyDecider::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - PolicyDecisionCallback callback) { + base::OnceCallback<void(PolicyDecision)> callback) { std::move(callback).Run(PolicyDecision::Allow()); }
diff --git a/ios/web/web_state/web_state_policy_decider_bridge.mm b/ios/web/web_state/web_state_policy_decider_bridge.mm index fbf3adf..b420ceb 100644 --- a/ios/web/web_state/web_state_policy_decider_bridge.mm +++ b/ios/web/web_state/web_state_policy_decider_bridge.mm
@@ -17,21 +17,15 @@ WebStatePolicyDeciderBridge::~WebStatePolicyDeciderBridge() = default; -void WebStatePolicyDeciderBridge::ShouldAllowRequest( +WebStatePolicyDecider::PolicyDecision +WebStatePolicyDeciderBridge::ShouldAllowRequest( NSURLRequest* request, - const RequestInfo& request_info, - PolicyDecisionCallback callback) { - if ([decider_ respondsToSelector:@selector - (shouldAllowRequest:requestInfo:decisionHandler:)]) { - __block PolicyDecisionCallback block_callback = std::move(callback); - [decider_ shouldAllowRequest:request - requestInfo:request_info - decisionHandler:^(PolicyDecision result) { - std::move(block_callback).Run(result); - }]; - return; + const WebStatePolicyDecider::RequestInfo& request_info) { + if ([decider_ + respondsToSelector:@selector(shouldAllowRequest:requestInfo:)]) { + return [decider_ shouldAllowRequest:request requestInfo:request_info]; } - std::move(callback).Run(PolicyDecision::Allow()); + return WebStatePolicyDecider::PolicyDecision::Allow(); } bool WebStatePolicyDeciderBridge::ShouldAllowErrorPageToBeDisplayed( @@ -48,16 +42,17 @@ void WebStatePolicyDeciderBridge::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - PolicyDecisionCallback callback) { + base::OnceCallback<void(PolicyDecision)> callback) { if ([decider_ respondsToSelector:@selector (decidePolicyForNavigationResponse: - forMainFrame:decisionHandler:)]) { - __block PolicyDecisionCallback block_callback = std::move(callback); + forMainFrame:completionHandler:)]) { + __block base::OnceCallback<void(PolicyDecision)> block_callback = + std::move(callback); [decider_ decidePolicyForNavigationResponse:response forMainFrame:for_main_frame - decisionHandler:^(PolicyDecision result) { - std::move(block_callback).Run(result); - }]; + completionHandler:^(PolicyDecision result) { + std::move(block_callback).Run(result); + }]; return; } std::move(callback).Run(PolicyDecision::Allow());
diff --git a/ios/web/web_state/web_state_policy_decider_bridge_unittest.mm b/ios/web/web_state/web_state_policy_decider_bridge_unittest.mm index c11705d..54a71602 100644 --- a/ios/web/web_state/web_state_policy_decider_bridge_unittest.mm +++ b/ios/web/web_state/web_state_policy_decider_bridge_unittest.mm
@@ -40,7 +40,7 @@ WebStatePolicyDecider::RequestInfo request_info( transition_type, target_frame_is_main, target_frame_is_cross_origin, has_user_gesture); - decider_bridge_.ShouldAllowRequest(request, request_info, base::DoNothing()); + decider_bridge_.ShouldAllowRequest(request, request_info); FakeShouldAllowRequestInfo* should_allow_request_info = [decider_ shouldAllowRequestInfo]; ASSERT_TRUE(should_allow_request_info);
diff --git a/ios/web_view/internal/web_view_web_state_policy_decider.h b/ios/web_view/internal/web_view_web_state_policy_decider.h index 43c478b..eeebaadf 100644 --- a/ios/web_view/internal/web_view_web_state_policy_decider.h +++ b/ios/web_view/internal/web_view_web_state_policy_decider.h
@@ -25,14 +25,14 @@ WebViewWebStatePolicyDecider(web::WebState* web_state, CWVWebView* web_view); // web::WebStatePolicyDecider overrides: - void ShouldAllowRequest( + web::WebStatePolicyDecider::PolicyDecision ShouldAllowRequest( NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback) override; + const web::WebStatePolicyDecider::RequestInfo& request_info) override; void ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback) override; + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> callback) + override; private: // Delegates to |delegate| property of this web view.
diff --git a/ios/web_view/internal/web_view_web_state_policy_decider.mm b/ios/web_view/internal/web_view_web_state_policy_decider.mm index 37722d44..4072ca4 100644 --- a/ios/web_view/internal/web_view_web_state_policy_decider.mm +++ b/ios/web_view/internal/web_view_web_state_policy_decider.mm
@@ -19,10 +19,10 @@ CWVWebView* web_view) : web::WebStatePolicyDecider(web_state), web_view_(web_view) {} -void WebViewWebStatePolicyDecider::ShouldAllowRequest( +web::WebStatePolicyDecider::PolicyDecision +WebViewWebStatePolicyDecider::ShouldAllowRequest( NSURLRequest* request, - const WebStatePolicyDecider::RequestInfo& request_info, - WebStatePolicyDecider::PolicyDecisionCallback callback) { + const web::WebStatePolicyDecider::RequestInfo& request_info) { id<CWVNavigationDelegate> delegate = web_view_.navigationDelegate; if ([delegate respondsToSelector:@selector (webView:shouldStartLoadWithRequest:navigationType:)]) { @@ -36,18 +36,16 @@ shouldStartLoadWithRequest:request navigationType:navigation_type]; if (!allow) { - return std::move(callback).Run( - web::WebStatePolicyDecider::WebStatePolicyDecider::PolicyDecision:: - Cancel()); + return WebStatePolicyDecider::PolicyDecision::Cancel(); } } - std::move(callback).Run(web::WebStatePolicyDecider::PolicyDecision::Allow()); + return WebStatePolicyDecider::PolicyDecision::Allow(); } void WebViewWebStatePolicyDecider::ShouldAllowResponse( NSURLResponse* response, bool for_main_frame, - WebStatePolicyDecider::PolicyDecisionCallback callback) { + base::OnceCallback<void(WebStatePolicyDecider::PolicyDecision)> callback) { id<CWVNavigationDelegate> delegate = web_view_.navigationDelegate; if ([delegate respondsToSelector:@selector (webView:shouldContinueLoadWithResponse:forMainFrame:)]) { @@ -55,8 +53,8 @@ shouldContinueLoadWithResponse:response forMainFrame:for_main_frame]; if (!allow) { - return std::move(callback).Run( - WebStatePolicyDecider::PolicyDecision::Cancel()); + std::move(callback).Run(WebStatePolicyDecider::PolicyDecision::Cancel()); + return; }; } std::move(callback).Run(WebStatePolicyDecider::PolicyDecision::Allow());
diff --git a/media/cast/net/cast_transport_config.h b/media/cast/net/cast_transport_config.h index 5042241..5e7ab64 100644 --- a/media/cast/net/cast_transport_config.h +++ b/media/cast/net/cast_transport_config.h
@@ -12,7 +12,6 @@ #include <string> #include "base/callback.h" -#include "base/stl_util.h" #include "media/cast/cast_config.h" #include "media/cast/common/rtp_time.h" #include "media/cast/net/cast_transport_defines.h"
diff --git a/media/cast/sender/audio_encoder.cc b/media/cast/sender/audio_encoder.cc index ed2bbe6..c5b221f 100644 --- a/media/cast/sender/audio_encoder.cc +++ b/media/cast/sender/audio_encoder.cc
@@ -16,7 +16,6 @@ #include "base/location.h" #include "base/logging.h" #include "base/macros.h" -#include "base/stl_util.h" #include "base/sys_byteorder.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h"
diff --git a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc index 68381ea..8a893cd 100644 --- a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc +++ b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc
@@ -202,7 +202,7 @@ return curr_params_.max_num_ref_frames; } -std::vector<gfx::Size> H264VaapiVideoEncoderDelegate::GetSVCLayerResoltuions() { +std::vector<gfx::Size> H264VaapiVideoEncoderDelegate::GetSVCLayerResolutions() { return {visible_size_}; }
diff --git a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.h b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.h index eedbe65b6..b19b7fce 100644 --- a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.h +++ b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.h
@@ -79,7 +79,7 @@ uint32_t framerate) override; gfx::Size GetCodedSize() const override; size_t GetMaxNumOfRefFrames() const override; - std::vector<gfx::Size> GetSVCLayerResoltuions() override; + std::vector<gfx::Size> GetSVCLayerResolutions() override; bool PrepareEncodeJob(EncodeJob* encode_job) override; private:
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc index 8a36fa1..a18a09b 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -772,9 +772,9 @@ DVLOGF(4); std::vector<gfx::Size> spatial_layer_resolutions = - encoder_->GetSVCLayerResoltuions(); + encoder_->GetSVCLayerResolutions(); if (spatial_layer_resolutions.empty()) { - VLOGF(1) << " Failed to get SVC layer resoltuions"; + VLOGF(1) << " Failed to get SVC layer resolutions"; return; }
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc index 72754ab1a..485f9e82 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc
@@ -194,7 +194,7 @@ MOCK_METHOD2(GetMetadata, BitstreamBufferMetadata(EncodeJob*, size_t)); MOCK_METHOD1(PrepareEncodeJob, bool(EncodeJob*)); MOCK_METHOD1(BitrateControlUpdate, void(uint64_t)); - MOCK_METHOD0(GetSVCLayerResoltuions, std::vector<gfx::Size>()); + MOCK_METHOD0(GetSVCLayerResolutions, std::vector<gfx::Size>()); bool UpdateRates(const VideoBitrateAllocation&, uint32_t) override { return false; } @@ -255,7 +255,7 @@ } else { svc_resolutions = {kDefaultEncodeSize}; } - ON_CALL(*mock_encoder_, GetSVCLayerResoltuions()) + ON_CALL(*mock_encoder_, GetSVCLayerResolutions()) .WillByDefault(Return(svc_resolutions)); }
diff --git a/media/gpu/vaapi/vaapi_video_encoder_delegate.h b/media/gpu/vaapi/vaapi_video_encoder_delegate.h index e1ddb50..5bdb6c2 100644 --- a/media/gpu/vaapi/vaapi_video_encoder_delegate.h +++ b/media/gpu/vaapi/vaapi_video_encoder_delegate.h
@@ -205,10 +205,10 @@ virtual BitstreamBufferMetadata GetMetadata(EncodeJob* encode_job, size_t payload_size); - // Gets the active spatial layer resoltuions for K-SVC encoding, VaapiVEA + // Gets the active spatial layer resolutions for K-SVC encoding, VaapiVEA // can get this info from the encoder delegate. Returns empty vector on // failure. - virtual std::vector<gfx::Size> GetSVCLayerResoltuions() = 0; + virtual std::vector<gfx::Size> GetSVCLayerResolutions() = 0; // Submits |buffer| of |type| to the driver. void SubmitBuffer(VABufferType type,
diff --git a/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.cc index bfb9e74a..76d80594 100644 --- a/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.cc +++ b/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.cc
@@ -134,7 +134,7 @@ return kNumVp8ReferenceBuffers; } -std::vector<gfx::Size> VP8VaapiVideoEncoderDelegate::GetSVCLayerResoltuions() { +std::vector<gfx::Size> VP8VaapiVideoEncoderDelegate::GetSVCLayerResolutions() { return {visible_size_}; }
diff --git a/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h b/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h index 771c45e..5e38feb3 100644 --- a/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h +++ b/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h
@@ -58,7 +58,7 @@ uint32_t framerate) override; gfx::Size GetCodedSize() const override; size_t GetMaxNumOfRefFrames() const override; - std::vector<gfx::Size> GetSVCLayerResoltuions() override; + std::vector<gfx::Size> GetSVCLayerResolutions() override; bool PrepareEncodeJob(EncodeJob* encode_job) override; private:
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc index 65b1fc1..892135a4 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc
@@ -363,7 +363,7 @@ return metadata; } -std::vector<gfx::Size> VP9VaapiVideoEncoderDelegate::GetSVCLayerResoltuions() { +std::vector<gfx::Size> VP9VaapiVideoEncoderDelegate::GetSVCLayerResolutions() { if (!ApplyPendingUpdateRates()) { DLOG(ERROR) << __func__ << " ApplyPendingUpdateRates failed"; return {};
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h index b165bfa..b9c5a77 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h
@@ -60,7 +60,7 @@ void BitrateControlUpdate(uint64_t encoded_chunk_size_bytes) override; BitstreamBufferMetadata GetMetadata(EncodeJob* encode_job, size_t payload_size) override; - std::vector<gfx::Size> GetSVCLayerResoltuions() override; + std::vector<gfx::Size> GetSVCLayerResolutions() override; private: friend class VP9VaapiVideoEncoderDelegateTest;
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc index c48b67d0..321d825 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
@@ -348,7 +348,7 @@ EXPECT_TRUE(encoder_->Initialize(config, ave_config)); EXPECT_EQ(num_temporal_layers > 1u || num_spatial_layers > 1u, !!encoder_->svc_layers_); - EXPECT_EQ(encoder_->GetSVCLayerResoltuions(), svc_layer_size); + EXPECT_EQ(encoder_->GetSVCLayerResolutions(), svc_layer_size); } void VP9VaapiVideoEncoderDelegateTest::
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc index 2b79916..2dde9217 100644 --- a/media/mojo/clients/mojo_video_decoder.cc +++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -158,6 +158,9 @@ DVLOG(1) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (gpu_factories_) + decoder_type_ = gpu_factories_->GetDecoderType(); + // Fail immediately if we know that the remote side cannot support |config|. if (gpu_factories_ && gpu_factories_->IsDecoderConfigSupported(config) == GpuVideoAcceleratorFactories::Supported::kFalse) {
diff --git a/media/mojo/mojom/video_decoder.mojom b/media/mojo/mojom/video_decoder.mojom index 929ae3c1..aeb46ff 100644 --- a/media/mojo/mojom/video_decoder.mojom +++ b/media/mojo/mojom/video_decoder.mojom
@@ -57,12 +57,14 @@ // hardware decode offloading; in this case the client is a <video> tag running // in a renderer, and the implementation is running in the GPU process. interface VideoDecoder { - // Returns a list of supported configs. It is expected that Initialize() will - // fail for any config that does not match an entry in this list. + // Returns a list of supported configs as well as the decoder ID for the decoder + // which supports them. It is expected that Initialize() will fail for any config + // that does not match an entry in this list. // // May be called before Construct(). GetSupportedConfigs() => - (array<SupportedVideoDecoderConfig> supported_configs); + (array<SupportedVideoDecoderConfig> supported_configs, + VideoDecoderType decoder_type); // Initialize the decoder. This must be called before any method other than // GetSupportedConfigs().
diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc index 6d90e469..73061707 100644 --- a/media/mojo/services/gpu_mojo_media_client.cc +++ b/media/mojo/services/gpu_mojo_media_client.cc
@@ -106,6 +106,11 @@ return CreatePlatformAudioDecoder(task_runner); } +VideoDecoderType GpuMojoMediaClient::GetDecoderImplementationType() { + return GetPlatformDecoderImplementationType(gpu_workarounds_, + gpu_preferences_); +} + SupportedVideoDecoderConfigs GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() { if (!supported_config_cache_)
diff --git a/media/mojo/services/gpu_mojo_media_client.h b/media/mojo/services/gpu_mojo_media_client.h index dbdc8e44..bbcb3e6 100644 --- a/media/mojo/services/gpu_mojo_media_client.h +++ b/media/mojo/services/gpu_mojo_media_client.h
@@ -96,6 +96,11 @@ std::unique_ptr<CdmFactory> CreatePlatformCdmFactory( mojom::FrameInterfaceFactory* frame_interfaces); +// Queries the platform decoder type. +VideoDecoderType GetPlatformDecoderImplementationType( + gpu::GpuDriverBugWorkarounds gpu_workarounds, + gpu::GpuPreferences gpu_preferences); + class GpuMojoMediaClient final : public MojoMediaClient { public: // |media_gpu_channel_manager| must only be used on |gpu_task_runner|, which @@ -112,6 +117,7 @@ // MojoMediaClient implementation. SupportedVideoDecoderConfigs GetSupportedVideoDecoderConfigs() final; + VideoDecoderType GetDecoderImplementationType() final; std::unique_ptr<AudioDecoder> CreateAudioDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner) final; std::unique_ptr<VideoDecoder> CreateVideoDecoder(
diff --git a/media/mojo/services/gpu_mojo_media_client_android.cc b/media/mojo/services/gpu_mojo_media_client_android.cc index d8f5546a..04316dd2 100644 --- a/media/mojo/services/gpu_mojo_media_client_android.cc +++ b/media/mojo/services/gpu_mojo_media_client_android.cc
@@ -80,4 +80,10 @@ base::BindRepeating(&CreateMediaDrmStorage, frame_interfaces)); } +VideoDecoderType GetPlatformDecoderImplementationType( + gpu::GpuDriverBugWorkarounds gpu_workarounds, + gpu::GpuPreferences gpu_preferences) { + return VideoDecoderType::kMediaCodec; +} + } // namespace media \ No newline at end of file
diff --git a/media/mojo/services/gpu_mojo_media_client_cros.cc b/media/mojo/services/gpu_mojo_media_client_cros.cc index f13c55d..a98ad239 100644 --- a/media/mojo/services/gpu_mojo_media_client_cros.cc +++ b/media/mojo/services/gpu_mojo_media_client_cros.cc
@@ -54,6 +54,15 @@ return std::move(get_vda_configs).Run(); } +VideoDecoderType GetPlatformDecoderImplementationType( + gpu::GpuDriverBugWorkarounds gpu_workarounds, + gpu::GpuPreferences gpu_preferences) { + if (ShouldUseChromeOSDirectVideoDecoder(gpu_preferences)) { + return VideoDecoderType::kVaapi; + } + return VideoDecoderType::kVda; +} + std::unique_ptr<AudioDecoder> CreatePlatformAudioDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner) { return nullptr;
diff --git a/media/mojo/services/gpu_mojo_media_client_mac.cc b/media/mojo/services/gpu_mojo_media_client_mac.cc index f88d7fd..68c1f5c 100644 --- a/media/mojo/services/gpu_mojo_media_client_mac.cc +++ b/media/mojo/services/gpu_mojo_media_client_mac.cc
@@ -36,4 +36,10 @@ return nullptr; } +VideoDecoderType GetPlatformDecoderImplementationType( + gpu::GpuDriverBugWorkarounds gpu_workarounds, + gpu::GpuPreferences gpu_preferences) { + return VideoDecoderType::kVda; +} + } // namespace media \ No newline at end of file
diff --git a/media/mojo/services/gpu_mojo_media_client_stubs.cc b/media/mojo/services/gpu_mojo_media_client_stubs.cc index 36eb4348..c3264fb 100644 --- a/media/mojo/services/gpu_mojo_media_client_stubs.cc +++ b/media/mojo/services/gpu_mojo_media_client_stubs.cc
@@ -33,4 +33,10 @@ return nullptr; } +VideoDecoderType GetPlatformDecoderImplementationType( + gpu::GpuDriverBugWorkarounds gpu_workarounds, + gpu::GpuPreferences gpu_preferences) { + return VideoDecoderType::kUnknown; +} + } // namespace media \ No newline at end of file
diff --git a/media/mojo/services/gpu_mojo_media_client_win.cc b/media/mojo/services/gpu_mojo_media_client_win.cc index 8184d48..7449bc75 100644 --- a/media/mojo/services/gpu_mojo_media_client_win.cc +++ b/media/mojo/services/gpu_mojo_media_client_win.cc
@@ -21,13 +21,22 @@ []() { return gl::QueryD3D11DeviceObjectFromANGLE(); }); } +bool ShouldUseD3D11VideoDecoder( + const gpu::GpuDriverBugWorkarounds& gpu_workarounds) { + if (!base::FeatureList::IsEnabled(kD3D11VideoDecoder)) + return false; + if (gpu_workarounds.disable_d3d11_video_decoder) + return false; + if (base::win::GetVersion() == base::win::Version::WIN7) + return false; + return true; +} + } // namespace std::unique_ptr<VideoDecoder> CreatePlatformVideoDecoder( const VideoDecoderTraits& traits) { - if (!base::FeatureList::IsEnabled(kD3D11VideoDecoder) || - traits.gpu_workarounds->disable_d3d11_video_decoder || - base::win::GetVersion() == base::win::Version::WIN7) { + if (!ShouldUseD3D11VideoDecoder(*traits.gpu_workarounds)) { if (traits.gpu_workarounds->disable_dxva_video_decoder) return nullptr; return VdaVideoDecoder::Create( @@ -50,14 +59,11 @@ gpu::GpuPreferences gpu_preferences, base::OnceCallback<SupportedVideoDecoderConfigs()> get_vda_configs) { SupportedVideoDecoderConfigs supported_configs; - if (!base::FeatureList::IsEnabled(kD3D11VideoDecoder) || - gpu_workarounds.disable_d3d11_video_decoder || - base::win::GetVersion() == base::win::Version::WIN7) { - if (!gpu_workarounds.disable_dxva_video_decoder) - supported_configs = std::move(get_vda_configs).Run(); - } else if (base::FeatureList::IsEnabled(kD3D11VideoDecoder)) { + if (ShouldUseD3D11VideoDecoder(gpu_workarounds)) { supported_configs = D3D11VideoDecoder::GetSupportedVideoDecoderConfigs( gpu_preferences, gpu_workarounds, GetD3D11DeviceCallback()); + } else if (!gpu_workarounds.disable_dxva_video_decoder) { + supported_configs = std::move(get_vda_configs).Run(); } return supported_configs; } @@ -67,6 +73,14 @@ return nullptr; } +VideoDecoderType GetPlatformDecoderImplementationType( + gpu::GpuDriverBugWorkarounds gpu_workarounds, + gpu::GpuPreferences gpu_preferences) { + if (!ShouldUseD3D11VideoDecoder(gpu_workarounds)) + return VideoDecoderType::kVda; + return VideoDecoderType::kD3D11; +} + // There is no CdmFactory on windows, so just stub it out. class CdmFactory {}; std::unique_ptr<CdmFactory> CreatePlatformCdmFactory(
diff --git a/media/mojo/services/mojo_media_client.cc b/media/mojo/services/mojo_media_client.cc index f7ba4018..c35168a 100644 --- a/media/mojo/services/mojo_media_client.cc +++ b/media/mojo/services/mojo_media_client.cc
@@ -29,6 +29,10 @@ return {}; } +VideoDecoderType MojoMediaClient::GetDecoderImplementationType() { + return VideoDecoderType::kUnknown; +} + std::unique_ptr<VideoDecoder> MojoMediaClient::CreateVideoDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner, MediaLog* media_log,
diff --git a/media/mojo/services/mojo_media_client.h b/media/mojo/services/mojo_media_client.h index 1c5649f..492ac4ee 100644 --- a/media/mojo/services/mojo_media_client.h +++ b/media/mojo/services/mojo_media_client.h
@@ -56,6 +56,8 @@ virtual std::vector<SupportedVideoDecoderConfig> GetSupportedVideoDecoderConfigs(); + virtual VideoDecoderType GetDecoderImplementationType(); + virtual std::unique_ptr<VideoDecoder> CreateVideoDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner, MediaLog* media_log,
diff --git a/media/mojo/services/mojo_video_decoder_service.cc b/media/mojo/services/mojo_video_decoder_service.cc index 0dd8538..582283ff 100644 --- a/media/mojo/services/mojo_video_decoder_service.cc +++ b/media/mojo/services/mojo_video_decoder_service.cc
@@ -150,8 +150,8 @@ DVLOG(3) << __func__; TRACE_EVENT0("media", "MojoVideoDecoderService::GetSupportedConfigs"); - std::move(callback).Run( - mojo_media_client_->GetSupportedVideoDecoderConfigs()); + std::move(callback).Run(mojo_media_client_->GetSupportedVideoDecoderConfigs(), + mojo_media_client_->GetDecoderImplementationType()); } void MojoVideoDecoderService::Construct(
diff --git a/media/mojo/test/mojo_video_decoder_integration_test.cc b/media/mojo/test/mojo_video_decoder_integration_test.cc index 2168bc4..ef786d2 100644 --- a/media/mojo/test/mojo_video_decoder_integration_test.cc +++ b/media/mojo/test/mojo_video_decoder_integration_test.cc
@@ -373,7 +373,7 @@ callback; // TODO(sandersd): Expect there to be an entry. - EXPECT_CALL(callback, Run(_)); + EXPECT_CALL(callback, Run(_, _)); remote_video_decoder->GetSupportedConfigs(callback.Get()); RunUntilIdle(); }
diff --git a/media/video/gpu_video_accelerator_factories.h b/media/video/gpu_video_accelerator_factories.h index ec12723c..3569fccc 100644 --- a/media/video/gpu_video_accelerator_factories.h +++ b/media/video/gpu_video_accelerator_factories.h
@@ -97,6 +97,11 @@ virtual Supported IsDecoderConfigSupported( const VideoDecoderConfig& config) = 0; + // Returns VideoDecoderType::kUnknown in cases where IsDecoderSupportKnown() + // is false. Otherwise, it returns the type of decoder that provided the + // configs for the config support check. + virtual VideoDecoderType GetDecoderType() = 0; + // Callers must verify IsDecoderSupportKnown() prior to using this, or they // will immediately receive a kUnknown. //
diff --git a/media/video/mock_gpu_video_accelerator_factories.h b/media/video/mock_gpu_video_accelerator_factories.h index 785098a..7aac0e6 100644 --- a/media/video/mock_gpu_video_accelerator_factories.h +++ b/media/video/mock_gpu_video_accelerator_factories.h
@@ -32,6 +32,7 @@ MOCK_METHOD0(GetCommandBufferRouteId, int32_t()); MOCK_METHOD1(IsDecoderConfigSupported, Supported(const VideoDecoderConfig&)); + MOCK_METHOD0(GetDecoderType, VideoDecoderType()); MOCK_METHOD0(IsDecoderSupportKnown, bool()); MOCK_METHOD1(NotifyDecoderSupportKnown, void(base::OnceClosure)); MOCK_METHOD2(CreateVideoDecoder,
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc index 4d58b52..4e8d1c3 100644 --- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc +++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -647,11 +647,18 @@ bool InterfaceEndpointClient::HandleIncomingMessage(Message* message) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!dispatcher_.Accept(message)) { - LOG(ERROR) << "Message " << message->name() << " rejected by interface " << interface_name_; - return false; - } - return true; + + // Accept() may invalidate `this` and `message` so we need to copy the + // members we need for logging in case of an error. + const char* interface_name = interface_name_; + uint32_t name = message->name(); + if (!dispatcher_.Accept(message)) { + LOG(ERROR) << "Message " << name << " rejected by interface " + << interface_name; + return false; + } + + return true; } void InterfaceEndpointClient::NotifyError(
diff --git a/net/cert/cert_verify_proc_blocklist.inc b/net/cert/cert_verify_proc_blocklist.inc index d43674f..e5f29423 100644 --- a/net/cert/cert_verify_proc_blocklist.inc +++ b/net/cert/cert_verify_proc_blocklist.inc
@@ -371,6 +371,10 @@ {0x39, 0x73, 0x65, 0x88, 0xb9, 0x4a, 0x4c, 0xe7, 0x67, 0xf7, 0x31, 0xca, 0xd5, 0x3f, 0x4c, 0xbe, 0x44, 0x13, 0x7e, 0x32, 0x1e, 0xad, 0xca, 0xef, 0x8c, 0xe7, 0x9a, 0x22, 0x9b, 0xbc, 0xa9, 0x89}, + // c95c133b68319ee516b5f41e377f589878af1556567cc2834ef03b1d10830fd3.pem + {0xea, 0x12, 0x70, 0x5d, 0xe7, 0xc4, 0x8f, 0x6f, 0xcc, 0xe2, 0xcb, + 0x8d, 0xbc, 0x54, 0x2e, 0x0f, 0xc3, 0x8a, 0xc3, 0x8e, 0x08, 0x88, + 0x0d, 0xd0, 0x4a, 0x02, 0xef, 0x67, 0xc9, 0x3a, 0xe1, 0x35}, }; // Hashes of SubjectPublicKeyInfos known to be used for interception by a @@ -404,4 +408,8 @@ {0x39, 0x73, 0x65, 0x88, 0xb9, 0x4a, 0x4c, 0xe7, 0x67, 0xf7, 0x31, 0xca, 0xd5, 0x3f, 0x4c, 0xbe, 0x44, 0x13, 0x7e, 0x32, 0x1e, 0xad, 0xca, 0xef, 0x8c, 0xe7, 0x9a, 0x22, 0x9b, 0xbc, 0xa9, 0x89}, + // c95c133b68319ee516b5f41e377f589878af1556567cc2834ef03b1d10830fd3.pem + {0xea, 0x12, 0x70, 0x5d, 0xe7, 0xc4, 0x8f, 0x6f, 0xcc, 0xe2, 0xcb, 0x8d, + 0xbc, 0x54, 0x2e, 0x0f, 0xc3, 0x8a, 0xc3, 0x8e, 0x08, 0x88, 0x0d, 0xd0, + 0x4a, 0x02, 0xef, 0x67, 0xc9, 0x3a, 0xe1, 0x35}, };
diff --git a/net/data/ssl/blocklist/README.md b/net/data/ssl/blocklist/README.md index 150b35f..612be98 100644 --- a/net/data/ssl/blocklist/README.md +++ b/net/data/ssl/blocklist/README.md
@@ -309,6 +309,7 @@ * [0230a604d99220e5612ee7862ab9f7a6e18e4f1ac4c9e27075788cc5220169ab.pem](0230a604d99220e5612ee7862ab9f7a6e18e4f1ac4c9e27075788cc5220169ab.pem) * [06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem](06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem) * [0bd39de4793cdc117138f47708aa4d583acf67adb059a0d91f668d1803bf6489.pem](0bd39de4793cdc117138f47708aa4d583acf67adb059a0d91f668d1803bf6489.pem) + * [c95c133b68319ee516b5f41e377f589878af1556567cc2834ef03b1d10830fd3.pem](c95c133b68319ee516b5f41e377f589878af1556567cc2834ef03b1d10830fd3.pem) ### revoked.badssl.com
diff --git a/net/data/ssl/blocklist/c95c133b68319ee516b5f41e377f589878af1556567cc2834ef03b1d10830fd3.pem b/net/data/ssl/blocklist/c95c133b68319ee516b5f41e377f589878af1556567cc2834ef03b1d10830fd3.pem new file mode 100644 index 0000000..819bbc2 --- /dev/null +++ b/net/data/ssl/blocklist/c95c133b68319ee516b5f41e377f589878af1556567cc2834ef03b1d10830fd3.pem
@@ -0,0 +1,128 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 10:89:fc:3f:19:c9:03:f3:83:9b:cf:70:b9:7d:c7:cf:aa:d3:d4:dd + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN = Information Security Certification Authority, O = ISCA, C = KZ + Validity + Not Before: Feb 28 06:48:23 2020 GMT + Not After : Feb 28 06:48:23 2040 GMT + Subject: CN = Information Security Certification Authority, O = ISCA, C = KZ + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (4096 bit) + Modulus: + 00:d2:91:1b:e3:25:24:6a:31:8b:64:d7:29:52:e7: + fd:07:42:8a:da:c1:51:5b:69:9e:40:34:96:0a:96: + 8d:80:77:7e:6a:ae:48:e7:51:03:8a:22:c3:13:a9: + 98:cf:47:de:45:d0:61:b7:41:90:b8:d2:45:27:09: + 4a:5f:71:9c:e8:ab:2a:b2:74:85:27:6a:e9:c3:eb: + 5c:a3:b3:3c:0a:0f:55:aa:de:30:a4:72:65:de:a7: + 44:1b:04:5a:19:41:a4:6c:8d:4b:8b:81:88:99:73: + 4e:48:a6:2b:c4:13:62:c6:07:74:b8:6a:9e:09:29: + a7:bf:87:f5:e6:97:7f:74:5b:40:f1:75:33:2f:39: + 7b:bf:81:c5:9d:2f:bb:99:f4:a0:4f:9f:87:c2:3e: + b4:73:8f:01:e8:05:5a:86:0f:fa:f1:40:17:c0:eb: + d5:32:8d:9f:05:52:52:8b:6c:d6:62:b1:9a:67:a5: + fc:a9:24:a0:08:ee:cb:c7:12:c8:57:09:72:8c:57: + 25:31:32:81:4c:35:d6:3d:0f:18:e6:d8:d9:6f:c7: + d6:42:41:78:54:16:f1:69:af:7f:d1:d2:8d:2c:62: + 36:7c:0d:08:d5:30:ce:20:43:86:cf:3d:c7:44:99: + 7f:0e:c8:81:71:d3:0c:03:b6:9a:f6:fc:2b:34:7c: + f4:7f:a5:88:97:1a:3e:32:a6:f2:de:20:6a:20:ff: + ef:e4:db:b7:0a:3e:2f:29:b9:b0:b1:cf:c5:6c:4c: + e1:59:5c:d7:6b:05:75:89:9a:37:d4:01:86:1b:5c: + 37:97:4f:34:48:a6:1f:78:d9:29:4f:0c:c5:d0:81: + d2:23:4a:5f:dd:f4:0a:2a:de:57:b6:14:89:f2:e8: + 45:db:4d:e5:5b:c3:8c:1c:5d:5b:ef:24:7f:5d:3b: + 05:90:1d:79:49:dc:8a:ac:c5:a1:cd:ce:ac:55:8a: + 15:1d:85:f4:bf:a7:15:d4:59:53:7a:35:85:35:df: + 0c:5b:67:17:54:d3:94:c6:df:f3:86:b3:91:22:09: + 2c:c0:e2:cd:dd:11:48:c2:5a:1b:5d:bb:5d:ba:c2: + 84:af:c8:3c:55:33:ab:a9:19:c2:ad:f1:9c:75:c4: + 2d:88:db:91:72:23:3a:1b:4e:af:01:76:a2:9b:93: + 56:cd:50:cd:5d:df:5f:67:54:7c:ae:9b:0c:b0:ef: + 14:71:17:35:a4:f1:3d:5a:84:22:7f:ce:89:72:80: + 84:51:eb:b3:49:b5:e9:15:08:b4:1c:36:50:6f:40: + 59:ee:ad:9f:25:bb:ee:59:f2:6d:9a:03:b2:11:4f: + f7:57:de:59:79:ac:37:e9:4c:93:38:de:86:b2:36: + e6:d8:e9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 90:89:FC:3F:19:C9:03:F3:83:9B:CF:70:B9:7D:C7:CF:AA:D3:D4:DD + X509v3 Authority Key Identifier: + keyid:90:89:FC:3F:19:C9:03:F3:83:9B:CF:70:B9:7D:C7:CF:AA:D3:D4:DD + DirName:/CN=Information Security Certification Authority/O=ISCA/C=KZ + serial:10:89:FC:3F:19:C9:03:F3:83:9B:CF:70:B9:7D:C7:CF:AA:D3:D4:DD + + Signature Algorithm: sha256WithRSAEncryption + 5e:88:9d:cc:e9:04:bc:4b:6c:03:6a:73:3b:48:a8:d4:bf:54: + 1e:68:43:dc:2e:cd:fe:07:51:9a:bb:bd:fb:ba:59:ce:c3:fd: + f9:dd:39:9f:52:59:e4:fa:2f:af:5b:4c:a1:4a:b8:c4:08:68: + f3:68:3c:44:eb:c4:18:90:05:5f:b5:37:5f:c3:8a:cd:6c:12: + 59:13:27:ca:3d:bf:ec:3c:18:92:2b:f6:32:34:6b:4f:7a:76: + c2:37:27:f4:4a:33:21:74:07:de:72:67:6e:52:e1:71:89:ab: + 74:15:94:b3:28:05:9d:8a:c2:0f:0f:c8:e6:3d:f5:68:e5:36: + 64:ca:c2:0d:e7:25:a9:b7:9e:cc:89:54:3b:7d:23:1c:d6:8e: + 79:b6:19:25:cb:65:a6:fc:fd:48:0d:dd:c0:f8:2e:ce:b8:c7: + 41:68:fe:4f:a5:31:4a:61:73:34:37:5d:71:46:8a:3d:be:15: + 18:cd:9b:29:10:80:30:35:a1:0a:df:35:ff:b4:ae:7f:5f:19: + 3f:93:f6:31:76:7b:e3:e7:5c:ee:7c:3f:ed:9b:37:d3:eb:94: + 59:ac:25:9b:2e:f3:e0:f5:45:5f:72:d9:67:bf:f8:a4:5b:b0: + a8:7c:17:dc:f2:b0:58:24:28:6d:47:cc:f9:8c:56:89:95:bc: + b7:5a:e3:15:e6:84:d6:28:9e:69:3f:e9:ee:6c:b2:9b:45:8f: + 3c:2a:33:8d:5e:9e:44:3a:c2:ea:6b:29:d2:b4:92:e3:0d:3c: + 68:c1:7c:1e:15:12:80:f5:85:fa:46:3d:e5:ed:43:4c:1e:85: + 39:78:01:a3:0f:ea:bd:de:7d:61:cb:7c:65:02:6e:72:d8:ba: + f6:b1:c9:49:4a:65:54:99:d3:76:01:bf:a9:bd:40:ac:7e:13: + b4:7d:97:a3:30:63:d3:7b:ab:7d:35:c3:52:a7:c2:9d:af:73: + f6:9c:4d:cf:ea:ee:66:28:45:a6:b5:59:c6:cf:fb:06:25:50: + d7:b2:fb:6d:1a:6c:5e:68:43:b4:ad:a8:38:05:00:c0:73:4d: + c5:9b:da:7b:a5:cf:17:f6:3c:81:13:83:ad:c3:7b:24:71:1a: + a9:88:fc:6c:5f:10:52:64:75:ed:c1:05:09:76:f8:b9:ac:32: + bc:61:37:df:2c:67:1b:8e:f3:d7:ae:af:19:7b:47:03:e1:c6: + 5e:c5:a7:e0:41:bf:e3:9f:5e:14:41:13:71:3f:1e:60:db:07: + bf:b7:a9:04:d7:57:32:a4:0e:ad:80:37:a9:e4:43:8d:89:5a: + bc:0d:ee:47:b0:38:72:c5:b5:fb:2f:b2:bc:f9:76:67:51:06: + f6:25:bb:03:7b:6d:74:02 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIUEIn8PxnJA/ODm89wuX3Hz6rT1N0wDQYJKoZIhvcNAQEL +BQAwUzE1MDMGA1UEAxMsSW5mb3JtYXRpb24gU2VjdXJpdHkgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxDTALBgNVBAoTBElTQ0ExCzAJBgNVBAYTAktaMB4XDTIwMDIy +ODA2NDgyM1oXDTQwMDIyODA2NDgyM1owUzE1MDMGA1UEAxMsSW5mb3JtYXRpb24g +U2VjdXJpdHkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAoTBElTQ0Ex +CzAJBgNVBAYTAktaMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0pEb +4yUkajGLZNcpUuf9B0KK2sFRW2meQDSWCpaNgHd+aq5I51EDiiLDE6mYz0feRdBh +t0GQuNJFJwlKX3Gc6KsqsnSFJ2rpw+tco7M8Cg9Vqt4wpHJl3qdEGwRaGUGkbI1L +i4GImXNOSKYrxBNixgd0uGqeCSmnv4f15pd/dFtA8XUzLzl7v4HFnS+7mfSgT5+H +wj60c48B6AVahg/68UAXwOvVMo2fBVJSi2zWYrGaZ6X8qSSgCO7LxxLIVwlyjFcl +MTKBTDXWPQ8Y5tjZb8fWQkF4VBbxaa9/0dKNLGI2fA0I1TDOIEOGzz3HRJl/DsiB +cdMMA7aa9vwrNHz0f6WIlxo+Mqby3iBqIP/v5Nu3Cj4vKbmwsc/FbEzhWVzXawV1 +iZo31AGGG1w3l080SKYfeNkpTwzF0IHSI0pf3fQKKt5XthSJ8uhF203lW8OMHF1b +7yR/XTsFkB15SdyKrMWhzc6sVYoVHYX0v6cV1FlTejWFNd8MW2cXVNOUxt/zhrOR +IgkswOLN3RFIwlobXbtdusKEr8g8VTOrqRnCrfGcdcQtiNuRciM6G06vAXaim5NW +zVDNXd9fZ1R8rpsMsO8UcRc1pPE9WoQif86JcoCEUeuzSbXpFQi0HDZQb0BZ7q2f +JbvuWfJtmgOyEU/3V95Zeaw36UyTON6Gsjbm2OkCAwEAAaOB1jCB0zAPBgNVHRMB +Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUkIn8PxnJA/ODm89w +uX3Hz6rT1N0wgZAGA1UdIwSBiDCBhYAUkIn8PxnJA/ODm89wuX3Hz6rT1N2hV6RV +MFMxNTAzBgNVBAMTLEluZm9ybWF0aW9uIFNlY3VyaXR5IENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MQ0wCwYDVQQKEwRJU0NBMQswCQYDVQQGEwJLWoIUEIn8PxnJA/OD +m89wuX3Hz6rT1N0wDQYJKoZIhvcNAQELBQADggIBAF6InczpBLxLbANqcztIqNS/ +VB5oQ9wuzf4HUZq7vfu6Wc7D/fndOZ9SWeT6L69bTKFKuMQIaPNoPETrxBiQBV+1 +N1/Dis1sElkTJ8o9v+w8GJIr9jI0a096dsI3J/RKMyF0B95yZ25S4XGJq3QVlLMo +BZ2Kwg8PyOY99WjlNmTKwg3nJam3nsyJVDt9IxzWjnm2GSXLZab8/UgN3cD4Ls64 +x0Fo/k+lMUphczQ3XXFGij2+FRjNmykQgDA1oQrfNf+0rn9fGT+T9jF2e+PnXO58 +P+2bN9PrlFmsJZsu8+D1RV9y2We/+KRbsKh8F9zysFgkKG1HzPmMVomVvLda4xXm +hNYonmk/6e5ssptFjzwqM41enkQ6wuprKdK0kuMNPGjBfB4VEoD1hfpGPeXtQ0we +hTl4AaMP6r3efWHLfGUCbnLYuvaxyUlKZVSZ03YBv6m9QKx+E7R9l6MwY9N7q301 +w1Knwp2vc/acTc/q7mYoRaa1WcbP+wYlUNey+20abF5oQ7StqDgFAMBzTcWb2nul +zxf2PIETg63DeyRxGqmI/GxfEFJkde3BBQl2+LmsMrxhN98sZxuO89eurxl7RwPh +xl7Fp+BBv+OfXhRBE3E/HmDbB7+3qQTXVzKkDq2AN6nkQ42JWrwN7kewOHLFtfsv +srz5dmdRBvYluwN7bXQC +-----END CERTIFICATE-----
diff --git a/net/reporting/reporting_browsing_data_remover.cc b/net/reporting/reporting_browsing_data_remover.cc index 084b8d6c..a68d8c8 100644 --- a/net/reporting/reporting_browsing_data_remover.cc +++ b/net/reporting/reporting_browsing_data_remover.cc
@@ -27,9 +27,7 @@ reports_to_remove.push_back(report); } - cache->RemoveReports( - reports_to_remove, - ReportingReport::Outcome::ERASED_BROWSING_DATA_REMOVED); + cache->RemoveReports(reports_to_remove); } if ((data_type_mask & DATA_TYPE_CLIENTS) != 0) { @@ -46,8 +44,7 @@ ReportingCache* cache, uint64_t data_type_mask) { if ((data_type_mask & DATA_TYPE_REPORTS) != 0) { - cache->RemoveAllReports( - ReportingReport::Outcome::ERASED_BROWSING_DATA_REMOVED); + cache->RemoveAllReports(); } if ((data_type_mask & DATA_TYPE_CLIENTS) != 0) { cache->RemoveAllClients();
diff --git a/net/reporting/reporting_cache.h b/net/reporting/reporting_cache.h index a8b885c6..6c5411e8 100644 --- a/net/reporting/reporting_cache.h +++ b/net/reporting/reporting_cache.h
@@ -106,12 +106,12 @@ // Removes a set of reports. Any reports that are pending will not be removed // immediately, but rather marked doomed and removed once they are no longer // pending. - virtual void RemoveReports(const std::vector<const ReportingReport*>& reports, - ReportingReport::Outcome outcome) = 0; + virtual void RemoveReports( + const std::vector<const ReportingReport*>& reports) = 0; // Removes all reports. Like |RemoveReports()|, pending reports are doomed // until no longer pending. - virtual void RemoveAllReports(ReportingReport::Outcome outcome) = 0; + virtual void RemoveAllReports() = 0; // Gets the count of reports in the cache, *including* doomed reports. //
diff --git a/net/reporting/reporting_cache_impl.cc b/net/reporting/reporting_cache_impl.cc index 8b742949..50cd465 100644 --- a/net/reporting/reporting_cache_impl.cc +++ b/net/reporting/reporting_cache_impl.cc
@@ -23,12 +23,7 @@ DCHECK(context_); } -ReportingCacheImpl::~ReportingCacheImpl() { - for (const auto& report : reports_) { - if (report->status != ReportingReport::Status::DOOMED) - report->outcome = ReportingReport::Outcome::ERASED_REPORTING_SHUT_DOWN; - } -} +ReportingCacheImpl::~ReportingCacheImpl() = default; void ReportingCacheImpl::AddReport( const NetworkIsolationKey& network_isolation_key, @@ -55,7 +50,6 @@ // The newly-added report isn't pending, so even if all other reports are // pending, the cache should have a report to evict. DCHECK(!to_evict->get()->IsUploadPending()); - to_evict->get()->outcome = ReportingReport::Outcome::ERASED_EVICTED; reports_.erase(to_evict); } @@ -175,14 +169,11 @@ } void ReportingCacheImpl::RemoveReports( - const std::vector<const ReportingReport*>& reports, - ReportingReport::Outcome outcome) { + const std::vector<const ReportingReport*>& reports) { for (const ReportingReport* report : reports) { auto it = reports_.find(report); DCHECK(it != reports_.end()); - it->get()->outcome = outcome; - if (it->get()->IsUploadPending()) { it->get()->status = ReportingReport::Status::DOOMED; } else { @@ -192,10 +183,10 @@ context_->NotifyCachedReportsUpdated(); } -void ReportingCacheImpl::RemoveAllReports(ReportingReport::Outcome outcome) { +void ReportingCacheImpl::RemoveAllReports() { std::vector<const ReportingReport*> reports_to_remove; GetReports(&reports_to_remove); - RemoveReports(reports_to_remove, outcome); + RemoveReports(reports_to_remove); } size_t ReportingCacheImpl::GetFullReportCountForTesting() const {
diff --git a/net/reporting/reporting_cache_impl.h b/net/reporting/reporting_cache_impl.h index 59b1ed8..83283da 100644 --- a/net/reporting/reporting_cache_impl.h +++ b/net/reporting/reporting_cache_impl.h
@@ -58,9 +58,9 @@ const GURL& url, int reports_delivered, bool successful) override; - void RemoveReports(const std::vector<const ReportingReport*>& reports, - ReportingReport::Outcome outcome) override; - void RemoveAllReports(ReportingReport::Outcome outcome) override; + void RemoveReports( + const std::vector<const ReportingReport*>& reports) override; + void RemoveAllReports() override; size_t GetFullReportCountForTesting() const override; bool IsReportPendingForTesting(const ReportingReport* report) const override; bool IsReportDoomedForTesting(const ReportingReport* report) const override;
diff --git a/net/reporting/reporting_cache_unittest.cc b/net/reporting/reporting_cache_unittest.cc index 681da4a..3f8515d14 100644 --- a/net/reporting/reporting_cache_unittest.cc +++ b/net/reporting/reporting_cache_unittest.cc
@@ -263,7 +263,7 @@ ASSERT_TRUE(report); EXPECT_EQ(1, report->attempts); - cache()->RemoveReports(reports, ReportingReport::Outcome::UNKNOWN); + cache()->RemoveReports(reports); EXPECT_EQ(3, observer()->cached_reports_update_count()); cache()->GetReports(&reports); @@ -285,7 +285,7 @@ cache()->GetReports(&reports); EXPECT_EQ(2u, reports.size()); - cache()->RemoveAllReports(ReportingReport::Outcome::UNKNOWN); + cache()->RemoveAllReports(); EXPECT_EQ(3, observer()->cached_reports_update_count()); cache()->GetReports(&reports); @@ -314,7 +314,7 @@ // pending, so another call to GetReportsToDeliver should return nothing. EXPECT_EQ(0u, cache()->GetReportsToDeliver().size()); - cache()->RemoveReports(reports, ReportingReport::Outcome::UNKNOWN); + cache()->RemoveReports(reports); EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0])); EXPECT_TRUE(cache()->IsReportDoomedForTesting(reports[0])); EXPECT_EQ(2, observer()->cached_reports_update_count()); @@ -352,7 +352,7 @@ // pending, so another call to GetReportsToDeliver should return nothing. EXPECT_EQ(0u, cache()->GetReportsToDeliver().size()); - cache()->RemoveAllReports(ReportingReport::Outcome::UNKNOWN); + cache()->RemoveAllReports(); EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0])); EXPECT_TRUE(cache()->IsReportDoomedForTesting(reports[0])); EXPECT_EQ(2, observer()->cached_reports_update_count()); @@ -385,7 +385,7 @@ EXPECT_THAT(cache()->GetReportsToDeliver(), ::testing::UnorderedElementsAre(report1, report2)); // Mark report2 as doomed. - cache()->RemoveReports({report2}, ReportingReport::Outcome::UNKNOWN); + cache()->RemoveReports({report2}); base::Value actual = cache()->GetReportsAsValue(); base::Value expected = base::test::ParseJson(base::StringPrintf(
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc index 1e815ab..7e195aa 100644 --- a/net/reporting/reporting_delivery_agent.cc +++ b/net/reporting/reporting_delivery_agent.cc
@@ -136,7 +136,7 @@ group_name_and_count.second, success); } if (success) { - cache->RemoveReports(reports_, ReportingReport::Outcome::DELIVERED); + cache->RemoveReports(reports_); } else { cache->IncrementReportsAttempts(reports_); }
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc index 17c6231..dc63387 100644 --- a/net/reporting/reporting_delivery_agent_unittest.cc +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -399,7 +399,7 @@ EXPECT_FALSE(cache()->IsReportDoomedForTesting(report)); // Report should appear removed, even though the cache has doomed it. - cache()->RemoveReports(reports, ReportingReport::Outcome::UNKNOWN); + cache()->RemoveReports(reports); cache()->GetReports(&reports); EXPECT_TRUE(reports.empty()); EXPECT_TRUE(cache()->IsReportDoomedForTesting(report)); @@ -431,7 +431,7 @@ EXPECT_FALSE(cache()->IsReportDoomedForTesting(report)); // Report should appear removed, even though the cache has doomed it. - cache()->RemoveReports(reports, ReportingReport::Outcome::UNKNOWN); + cache()->RemoveReports(reports); cache()->GetReports(&reports); EXPECT_TRUE(reports.empty()); EXPECT_TRUE(cache()->IsReportDoomedForTesting(report));
diff --git a/net/reporting/reporting_endpoint_manager_unittest.cc b/net/reporting/reporting_endpoint_manager_unittest.cc index 3c67771..b72935f5 100644 --- a/net/reporting/reporting_endpoint_manager_unittest.cc +++ b/net/reporting/reporting_endpoint_manager_unittest.cc
@@ -85,13 +85,11 @@ bool successful) override { NOTREACHED(); } - void RemoveReports(const std::vector<const ReportingReport*>& reports, - ReportingReport::Outcome outcome) override { + void RemoveReports( + const std::vector<const ReportingReport*>& reports) override { NOTREACHED(); } - void RemoveAllReports(ReportingReport::Outcome outcome) override { - NOTREACHED(); - } + void RemoveAllReports() override { NOTREACHED(); } size_t GetFullReportCountForTesting() const override { NOTREACHED(); return 0;
diff --git a/net/reporting/reporting_garbage_collector.cc b/net/reporting/reporting_garbage_collector.cc index be1cc86..e144c5f 100644 --- a/net/reporting/reporting_garbage_collector.cc +++ b/net/reporting/reporting_garbage_collector.cc
@@ -70,10 +70,8 @@ // Don't restart the timer on the garbage collector's own updates. context_->RemoveCacheObserver(this); - context_->cache()->RemoveReports(failed_reports, - ReportingReport::Outcome::ERASED_FAILED); - context_->cache()->RemoveReports(expired_reports, - ReportingReport::Outcome::ERASED_EXPIRED); + context_->cache()->RemoveReports(failed_reports); + context_->cache()->RemoveReports(expired_reports); context_->AddCacheObserver(this); }
diff --git a/net/reporting/reporting_network_change_observer.cc b/net/reporting/reporting_network_change_observer.cc index c7acb88..4e1d20ea 100644 --- a/net/reporting/reporting_network_change_observer.cc +++ b/net/reporting/reporting_network_change_observer.cc
@@ -39,8 +39,7 @@ return; if (!context_->policy().persist_reports_across_network_changes) - context_->cache()->RemoveAllReports( - ReportingReport::Outcome::ERASED_NETWORK_CHANGED); + context_->cache()->RemoveAllReports(); if (!context_->policy().persist_clients_across_network_changes) context_->cache()->RemoveAllClients();
diff --git a/net/reporting/reporting_report.cc b/net/reporting/reporting_report.cc index 3bc047d..297715a 100644 --- a/net/reporting/reporting_report.cc +++ b/net/reporting/reporting_report.cc
@@ -8,22 +8,12 @@ #include <string> #include <utility> -#include "base/metrics/histogram_macros.h" #include "base/time/time.h" #include "base/values.h" #include "url/gurl.h" namespace net { -namespace { - -void RecordReportOutcome(ReportingReport::Outcome outcome) { - UMA_HISTOGRAM_ENUMERATION("Net.Reporting.ReportOutcome", outcome, - ReportingReport::Outcome::MAX); -} - -} // namespace - ReportingReport::ReportingReport( const NetworkIsolationKey& network_isolation_key, const GURL& url, @@ -44,25 +34,13 @@ queued(queued), attempts(attempts) {} -ReportingReport::~ReportingReport() { - RecordReportOutcome(outcome); -} +ReportingReport::~ReportingReport() = default; ReportingEndpointGroupKey ReportingReport::GetGroupKey() const { return ReportingEndpointGroupKey(network_isolation_key, url::Origin::Create(url), group); } -// static -void ReportingReport::RecordReportDiscardedForNoURLRequestContext() { - RecordReportOutcome(Outcome::DISCARDED_NO_URL_REQUEST_CONTEXT); -} - -// static -void ReportingReport::RecordReportDiscardedForNoReportingService() { - RecordReportOutcome(Outcome::DISCARDED_NO_REPORTING_SERVICE); -} - bool ReportingReport::IsUploadPending() const { return status == Status::PENDING || status == Status::DOOMED; }
diff --git a/net/reporting/reporting_report.h b/net/reporting/reporting_report.h index 5da1dc2..3a71ad6 100644 --- a/net/reporting/reporting_report.h +++ b/net/reporting/reporting_report.h
@@ -24,22 +24,6 @@ // An undelivered report. struct NET_EXPORT ReportingReport { public: - // Used in histograms; please add new items at end and do not reorder. - enum class Outcome { - UNKNOWN = 0, - DISCARDED_NO_URL_REQUEST_CONTEXT = 1, - DISCARDED_NO_REPORTING_SERVICE = 2, - ERASED_FAILED = 3, - ERASED_EXPIRED = 4, - ERASED_EVICTED = 5, - ERASED_NETWORK_CHANGED = 6, - ERASED_BROWSING_DATA_REMOVED = 7, - ERASED_REPORTING_SHUT_DOWN = 8, - DELIVERED = 9, - - MAX - }; - enum class Status { // Report has been queued but no attempt has been made to deliver it yet. QUEUED, @@ -63,7 +47,6 @@ base::TimeTicks queued, int attempts); - // Records metrics about report outcome. ~ReportingReport(); // Bundles together the NIK, origin of the report URL, and group name. @@ -113,8 +96,6 @@ // attempt. (Not included in the delivered report.) int attempts = 0; - Outcome outcome = Outcome::UNKNOWN; - Status status = Status::QUEUED; DISALLOW_COPY_AND_ASSIGN(ReportingReport);
diff --git a/net/socket/udp_socket_unittest.cc b/net/socket/udp_socket_unittest.cc index 5129abea..91e7246 100644 --- a/net/socket/udp_socket_unittest.cc +++ b/net/socket/udp_socket_unittest.cc
@@ -657,8 +657,9 @@ socket.Close(); } -#if defined(OS_IOS) -// TODO(https://crbug.com/947115): failing on device on iOS 12.2. +// TODO(https://crbug.com/947115): failing on device on iOS 12.2. +// TODO(https://crbug.com/1227554): flaky on Mac 11. +#if defined(OS_IOS) || defined (OS_MAC) #define MAYBE_SharedMulticastAddress DISABLED_SharedMulticastAddress #else #define MAYBE_SharedMulticastAddress SharedMulticastAddress
diff --git a/net/spdy/spdy_stream_test_util.cc b/net/spdy/spdy_stream_test_util.cc index a8d17c7..ad00817 100644 --- a/net/spdy/spdy_stream_test_util.cc +++ b/net/spdy/spdy_stream_test_util.cc
@@ -7,7 +7,6 @@ #include <cstddef> #include <utility> -#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "net/spdy/spdy_stream.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc index ab5b44d21..302b6c4b 100644 --- a/net/websockets/websocket_basic_handshake_stream.cc +++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -15,7 +15,6 @@ #include "base/check_op.h" #include "base/compiler_specific.h" #include "base/metrics/histogram_functions.h" -#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h"
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index d416b409..81e344ea 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -31,7 +31,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "gin/array_buffer.h" -#include "gin/public/cppgc.h" #include "gin/public/gin_embedders.h" #include "gin/public/isolate_holder.h" #include "gin/public/v8_platform.h" @@ -81,7 +80,7 @@ #include "v8/include/v8.h" #if defined(PDF_ENABLE_XFA) -#include "v8/include/cppgc/platform.h" +#include "gin/public/cppgc.h" #endif #if defined(OS_LINUX) || defined(OS_CHROMEOS) @@ -266,7 +265,7 @@ void TearDownV8() { #if defined(PDF_ENABLE_XFA) - cppgc::ShutdownProcess(); + gin::MaybeShutdownCppgc(); #endif delete g_isolate_holder;
diff --git a/pdf/pdfium/pdfium_print_unittest.cc b/pdf/pdfium/pdfium_print_unittest.cc index d3a6225..128f109 100644 --- a/pdf/pdfium/pdfium_print_unittest.cc +++ b/pdf/pdfium/pdfium_print_unittest.cc
@@ -7,7 +7,6 @@ #include <memory> #include "base/files/file_path.h" -#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "cc/test/pixel_test_utils.h" #include "pdf/pdfium/pdfium_engine.h"
diff --git a/remoting/host/host_main.cc b/remoting/host/host_main.cc index 33283556..d50bf1f 100644 --- a/remoting/host/host_main.cc +++ b/remoting/host/host_main.cc
@@ -33,6 +33,8 @@ #endif // defined(OS_APPLE) #if defined(OS_WIN) +#include <windows.h> + #include <commctrl.h> #include <shellapi.h> #endif // defined(OS_WIN)
diff --git a/remoting/host/it2me/it2me_native_messaging_host_main.cc b/remoting/host/it2me/it2me_native_messaging_host_main.cc index 6d4e4053d..96074e3 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_main.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_main.cc
@@ -46,6 +46,8 @@ #endif // defined(OS_APPLE) #if defined(OS_WIN) +#include <windows.h> + #include <commctrl.h> #include "remoting/host/switches.h"
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc index df874b5..68b40b5 100644 --- a/sandbox/win/src/broker_services.cc +++ b/sandbox/win/src/broker_services.cc
@@ -29,6 +29,10 @@ #include "sandbox/win/src/threadpool.h" #include "sandbox/win/src/win_utils.h" +#if DCHECK_IS_ON() +#include "base/win/current_module.h" +#endif + namespace { // Utility function to associate a completion port to a job object. @@ -437,6 +441,14 @@ ResultCode* last_warning, DWORD* last_error, PROCESS_INFORMATION* target_info) { +#if DCHECK_IS_ON() + // This code should only be called from the exe, ensure that this is always + // the case. + HMODULE exe_module = nullptr; + CHECK(::GetModuleHandleEx(NULL, exe_path, &exe_module)); + DCHECK_EQ(CURRENT_MODULE(), exe_module); +#endif + if (!exe_path) return SBOX_ERROR_BAD_PARAMS;
diff --git a/sandbox/win/src/sandbox.h b/sandbox/win/src/sandbox.h index 9dfebfcc1..35996c1 100644 --- a/sandbox/win/src/sandbox.h +++ b/sandbox/win/src/sandbox.h
@@ -55,7 +55,10 @@ // // -- later you can call: // broker->WaitForAllTargets(option); // -class BrokerServices { +// We need [[clang::lto_visibility_public]] because instances of this class are +// passed across module boundaries. This means different modules must have +// compatible definitions of the class even when LTO is enabled. +class [[clang::lto_visibility_public]] BrokerServices { public: // Initializes the broker. Must be called before any other on this class. // returns ALL_OK if successful. All other return values imply failure.
diff --git a/services/device/hid/hid_service_linux.cc b/services/device/hid/hid_service_linux.cc index 9f18867..e574463 100644 --- a/services/device/hid/hid_service_linux.cc +++ b/services/device/hid/hid_service_linux.cc
@@ -36,6 +36,8 @@ #include "device/udev_linux/udev_watcher.h" #include "services/device/hid/hid_connection_linux.h" +// TODO(huangs): Enable for IS_CHROMEOS_LACROS. This will simplify crosapi so +// that it won't need to pass HidManager around (crbug.com/1109621). #if BUILDFLAG(IS_CHROMEOS_ASH) #include "base/system/sys_info.h" #include "chromeos/dbus/permission_broker/permission_broker_client.h" // nogncheck
diff --git a/services/device/public/cpp/test/fake_usb_device_manager.cc b/services/device/public/cpp/test/fake_usb_device_manager.cc index 39818ca..1a3868e 100644 --- a/services/device/public/cpp/test/fake_usb_device_manager.cc +++ b/services/device/public/cpp/test/fake_usb_device_manager.cc
@@ -84,7 +84,7 @@ } #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void FakeUsbDeviceManager::CheckAccess(const std::string& guid, CheckAccessCallback callback) { std::move(callback).Run(true); @@ -99,7 +99,7 @@ base::FilePath(FILE_PATH_LITERAL("/dev/null")), base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE)); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void FakeUsbDeviceManager::SetClient( mojo::PendingAssociatedRemote<mojom::UsbDeviceManagerClient> client) {
diff --git a/services/device/public/cpp/test/fake_usb_device_manager.h b/services/device/public/cpp/test/fake_usb_device_manager.h index d90eec1..7a91db7 100644 --- a/services/device/public/cpp/test/fake_usb_device_manager.h +++ b/services/device/public/cpp/test/fake_usb_device_manager.h
@@ -86,7 +86,7 @@ RefreshDeviceInfoCallback callback) override; #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void CheckAccess(const std::string& guid, CheckAccessCallback callback) override; @@ -94,7 +94,7 @@ uint32_t drop_privileges_mask, mojo::PlatformHandle lifeline_fd, OpenFileDescriptorCallback callback) override; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void SetClient(mojo::PendingAssociatedRemote<mojom::UsbDeviceManagerClient> client) override;
diff --git a/services/device/public/mojom/usb_manager.mojom b/services/device/public/mojom/usb_manager.mojom index d48d42cb..ec781900 100644 --- a/services/device/public/mojom/usb_manager.mojom +++ b/services/device/public/mojom/usb_manager.mojom
@@ -41,7 +41,7 @@ // Check whether permission_broker will allow a future Open call for // a given USB device to succeed. - [EnableIf=is_chromeos_ash] + [EnableIf=is_chromeos] CheckAccess(string guid) => (bool success); // Attempt to open a USB device using permission_broker and return @@ -49,7 +49,7 @@ // |allowed_interfaces_mask|. The |lifeline_fd| should be the remote end of // a pipe created locally, and when this pipe is closed permission_broker // reattaches any kernel drivers that may have been detached when opening. - [EnableIf=is_chromeos_ash] + [EnableIf=is_chromeos] OpenFileDescriptor(string guid, uint32 allowed_interfaces_mask, handle<platform> lifeline_fd) => (mojo_base.mojom.File? fd);
diff --git a/services/device/serial/serial_io_handler.cc b/services/device/serial/serial_io_handler.cc index c79a197..f6d8715 100644 --- a/services/device/serial/serial_io_handler.cc +++ b/services/device/serial/serial_io_handler.cc
@@ -19,9 +19,9 @@ #include "build/chromeos_buildflags.h" #include "components/device_event_log/device_event_log.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "chromeos/dbus/permission_broker/permission_broker_client.h" // nogncheck -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) namespace device { @@ -51,8 +51,7 @@ DCHECK(ui_thread_task_runner_.get()); MergeConnectionOptions(options); -// TODO(huangs): Enable for IS_CHROMEOS_LACROS for crbug.com/1195248. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) // Note: dbus clients are destroyed in PostDestroyThreads so passing |client| // as unretained is safe. auto* client = chromeos::PermissionBrokerClient::Get(); @@ -74,10 +73,10 @@ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&SerialIoHandler::StartOpen, this, base::ThreadTaskRunnerHandle::Get())); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void SerialIoHandler::OnPathOpened( scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner, @@ -106,7 +105,7 @@ std::move(open_complete_).Run(false); } -#endif +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void SerialIoHandler::MergeConnectionOptions( const mojom::SerialConnectionOptions& options) {
diff --git a/services/device/serial/serial_io_handler.h b/services/device/serial/serial_io_handler.h index bbc0426a..118e0ef 100644 --- a/services/device/serial/serial_io_handler.h +++ b/services/device/serial/serial_io_handler.h
@@ -44,7 +44,7 @@ virtual void Open(const mojom::SerialConnectionOptions& options, OpenCompleteCallback callback); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) // Signals that the port has been opened. void OnPathOpened( scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner, @@ -59,7 +59,7 @@ // Reports the open error from the permission broker. void ReportPathOpenError(const std::string& error_name, const std::string& error_message); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) // Performs an async read operation. Behavior is undefined if this is called // while a read is already pending. Otherwise, |callback| will eventually be
diff --git a/services/device/usb/BUILD.gn b/services/device/usb/BUILD.gn index 834c347..348e922 100644 --- a/services/device/usb/BUILD.gn +++ b/services/device/usb/BUILD.gn
@@ -149,7 +149,7 @@ ] } - if (is_chromeos_ash) { + if (is_chromeos_ash || is_chromeos_lacros) { deps += [ "//chromeos/dbus/permission_broker", "//dbus",
diff --git a/services/device/usb/mojo/device_manager_impl.cc b/services/device/usb/mojo/device_manager_impl.cc index 2856e42..2ba6ce1 100644 --- a/services/device/usb/mojo/device_manager_impl.cc +++ b/services/device/usb/mojo/device_manager_impl.cc
@@ -25,10 +25,10 @@ #include "services/device/usb/usb_device.h" #include "services/device/usb/usb_service.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "chromeos/dbus/permission_broker/permission_broker_client.h" // nogncheck #include "services/device/usb/usb_device_linux.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) namespace device { namespace usb { @@ -118,8 +118,7 @@ } #endif // defined(OS_ANDROID) -// TODO(huangs): Enable for IS_CHROMEOS_LACROS for crbug.com/1195247. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void DeviceManagerImpl::CheckAccess(const std::string& guid, CheckAccessCallback callback) { scoped_refptr<UsbDevice> device = usb_service_->GetDevice(guid); @@ -173,7 +172,7 @@ << message; std::move(callback).Run(base::File()); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void DeviceManagerImpl::SetClient( mojo::PendingAssociatedRemote<mojom::UsbDeviceManagerClient> client) {
diff --git a/services/device/usb/mojo/device_manager_impl.h b/services/device/usb/mojo/device_manager_impl.h index 38b7f9d..b57cdee 100644 --- a/services/device/usb/mojo/device_manager_impl.h +++ b/services/device/usb/mojo/device_manager_impl.h
@@ -71,7 +71,7 @@ bool granted); #endif // defined(OS_ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void CheckAccess(const std::string& guid, CheckAccessCallback callback) override; @@ -86,7 +86,7 @@ void OnOpenFileDescriptorError(OpenFileDescriptorCallback callback, const std::string& error_name, const std::string& message); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void SetClient(mojo::PendingAssociatedRemote<mojom::UsbDeviceManagerClient> client) override;
diff --git a/services/device/usb/usb_device_linux.cc b/services/device/usb/usb_device_linux.cc index a2697dd..ca5c5f8fb 100644 --- a/services/device/usb/usb_device_linux.cc +++ b/services/device/usb/usb_device_linux.cc
@@ -23,13 +23,13 @@ #include "services/device/usb/usb_device_handle_usbfs.h" #include "services/device/usb/usb_service.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "chromeos/dbus/permission_broker/permission_broker_client.h" // nogncheck namespace { constexpr uint32_t kAllInterfacesMask = ~0U; } // namespace -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) namespace device { @@ -40,8 +40,7 @@ UsbDeviceLinux::~UsbDeviceLinux() = default; -// TODO(huangs): Enable for IS_CHROMEOS_LACROS for crbug.com/1195247. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void UsbDeviceLinux::CheckUsbAccess(ResultCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -49,12 +48,12 @@ std::move(callback)); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void UsbDeviceLinux::Open(OpenCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) // create the pipe used as a lifetime to re-attach the original kernel driver // to the USB device in permission_broker. base::ScopedFD read_end, write_end; @@ -79,10 +78,10 @@ base::BindOnce(&UsbDeviceLinux::OpenOnBlockingThread, this, std::move(callback), base::ThreadTaskRunnerHandle::Get(), blocking_task_runner)); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void UsbDeviceLinux::OnOpenRequestComplete(OpenCallback callback, base::ScopedFD lifeline_fd, @@ -123,7 +122,7 @@ } } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void UsbDeviceLinux::Opened( base::ScopedFD fd,
diff --git a/services/device/usb/usb_device_linux.h b/services/device/usb/usb_device_linux.h index 70a1070..2ea0f61 100644 --- a/services/device/usb/usb_device_linux.h +++ b/services/device/usb/usb_device_linux.h
@@ -29,9 +29,9 @@ class UsbDeviceLinux : public UsbDevice { public: // UsbDevice implementation: -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void CheckUsbAccess(ResultCallback callback) override; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void Open(OpenCallback callback) override; const std::string& device_path() const { return device_path_; } @@ -52,7 +52,7 @@ ~UsbDeviceLinux() override; private: -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void OnOpenRequestComplete(OpenCallback callback, base::ScopedFD fd, base::ScopedFD lifeline_fd); @@ -64,7 +64,7 @@ OpenCallback callback, scoped_refptr<base::SequencedTaskRunner> task_runner, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) void Opened(base::ScopedFD fd, base::ScopedFD lifeline_fd, OpenCallback callback,
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 341db42..dc181e6f 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/base/load_flags.h"
diff --git a/services/network/mdns_responder.cc b/services/network/mdns_responder.cc index 43bbabf..b87d706 100644 --- a/services/network/mdns_responder.cc +++ b/services/network/mdns_responder.cc
@@ -18,7 +18,6 @@ #include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" #include "base/rand_util.h" -#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/sys_byteorder.h" #include "base/threading/sequenced_task_runner_handle.h"
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 8dcdcf89..9d900391 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -20,7 +20,6 @@ #include "base/memory/ref_counted.h" #include "base/metrics/histogram_functions.h" #include "base/sequenced_task_runner.h" -#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/task/current_thread.h" @@ -939,7 +938,6 @@ request_context->reporting_service(); // TODO(paulmeyer): Remove this once the network service ships everywhere. if (!reporting_service) { - net::ReportingReport::RecordReportDiscardedForNoReportingService(); return; }
diff --git a/services/preferences/public/cpp/dictionary_value_update.cc b/services/preferences/public/cpp/dictionary_value_update.cc index 32e9ca50..62fca1d 100644 --- a/services/preferences/public/cpp/dictionary_value_update.cc +++ b/services/preferences/public/cpp/dictionary_value_update.cc
@@ -296,9 +296,12 @@ bool DictionaryValueUpdate::RemoveWithoutPathExpansion( base::StringPiece key, std::unique_ptr<base::Value>* out_value) { - if (!value_->RemoveWithoutPathExpansion(key, out_value)) + absl::optional<base::Value> value = value_->ExtractKey(key); + if (!value) return false; + if (out_value) + *out_value = base::Value::ToUniquePtrValue(std::move(*value)); RecordKey(key); return true; } @@ -306,9 +309,12 @@ bool DictionaryValueUpdate::RemovePath( base::StringPiece path, std::unique_ptr<base::Value>* out_value) { - if (!value_->RemovePath(path, out_value)) + absl::optional<base::Value> value = value_->ExtractPath(path); + if (!value) return false; + if (out_value) + *out_value = base::Value::ToUniquePtrValue(std::move(*value)); std::vector<base::StringPiece> split_path = SplitPath(path); base::DictionaryValue* dict = value_; for (size_t i = 0; i < split_path.size() - 1; ++i) {
diff --git a/services/preferences/tracked/dictionary_hash_store_contents.cc b/services/preferences/tracked/dictionary_hash_store_contents.cc index f9c5f81..3f9768ab 100644 --- a/services/preferences/tracked/dictionary_hash_store_contents.cc +++ b/services/preferences/tracked/dictionary_hash_store_contents.cc
@@ -107,7 +107,7 @@ bool DictionaryHashStoreContents::RemoveEntry(const std::string& path) { base::DictionaryValue* macs_dict = GetMutableContents(false); if (macs_dict) - return macs_dict->RemovePath(path, NULL); + return macs_dict->RemovePath(path); return false; }
diff --git a/services/preferences/tracked/tracked_atomic_preference.cc b/services/preferences/tracked/tracked_atomic_preference.cc index f7252f3..c8d134f 100644 --- a/services/preferences/tracked/tracked_atomic_preference.cc +++ b/services/preferences/tracked/tracked_atomic_preference.cc
@@ -65,7 +65,7 @@ bool was_reset = false; if (reset_action == TrackedPreferenceHelper::DO_RESET) { - pref_store_contents->RemovePath(pref_path_, NULL); + pref_store_contents->RemovePath(pref_path_); was_reset = true; }
diff --git a/services/preferences/tracked/tracked_preferences_migration_unittest.cc b/services/preferences/tracked/tracked_preferences_migration_unittest.cc index 1577990..7d93724e 100644 --- a/services/preferences/tracked/tracked_preferences_migration_unittest.cc +++ b/services/preferences/tracked/tracked_preferences_migration_unittest.cc
@@ -329,11 +329,11 @@ switch (store_id) { case MOCK_UNPROTECTED_PREF_STORE: ASSERT_TRUE(unprotected_prefs_); - unprotected_prefs_->RemovePath(key, NULL); + unprotected_prefs_->RemovePath(key); break; case MOCK_PROTECTED_PREF_STORE: ASSERT_TRUE(protected_prefs_); - protected_prefs_->RemovePath(key, NULL); + protected_prefs_->RemovePath(key); break; } }
diff --git a/services/preferences/tracked/tracked_split_preference.cc b/services/preferences/tracked/tracked_split_preference.cc index a0f3392..49a47e7 100644 --- a/services/preferences/tracked/tracked_split_preference.cc +++ b/services/preferences/tracked/tracked_split_preference.cc
@@ -93,7 +93,7 @@ dict_value->RemoveKey(*it); } } else { - pref_store_contents->RemovePath(pref_path_, NULL); + pref_store_contents->RemovePath(pref_path_); } was_reset = true; }
diff --git a/services/service_manager/public/cpp/service_executable/main.cc b/services/service_manager/public/cpp/service_executable/main.cc index e493e33..745a09b 100644 --- a/services/service_manager/public/cpp/service_executable/main.cc +++ b/services/service_manager/public/cpp/service_executable/main.cc
@@ -27,6 +27,10 @@ #include "base/mac/bundle_locations.h" #endif +#if defined(OS_WIN) +#include <windows.h> +#endif + namespace { void WaitForDebuggerIfNecessary() {
diff --git a/services/service_manager/service_process_launcher.cc b/services/service_manager/service_process_launcher.cc index 05d4a7a2..72a2161 100644 --- a/services/service_manager/service_process_launcher.cc +++ b/services/service_manager/service_process_launcher.cc
@@ -43,6 +43,8 @@ #if defined(OS_WIN) #include "base/win/windows_version.h" + +#include <windows.h> #endif namespace service_manager {
diff --git a/sql/README.md b/sql/README.md index e4443ede..c32610df 100644 --- a/sql/README.md +++ b/sql/README.md
@@ -154,7 +154,9 @@ [`EXPLAIN`](https://www.sqlite.org/lang_explain.html) and [`EXPLAIN QUERY PLAN`](https://www.sqlite.org/eqp.html) statements show the results of SQLite's query planner and optimizer, which are very helpful for -reasoning about the performance of complex queries. +reasoning about the performance of complex queries. The SQLite shell directive +`.eqp on` automatically issues `EXPLAIN QUERY PLAN` for all future commands. + The following commands set up SQLite shells using Chrome's build of SQLite.
diff --git a/sql/statement.cc b/sql/statement.cc index d161fe3..56bcf296 100644 --- a/sql/statement.cc +++ b/sql/statement.cc
@@ -204,15 +204,23 @@ SQLITE_TRANSIENT)); } -bool Statement::BindString(int col, const std::string& val) { +bool Statement::BindString(int col, base::StringPiece value) { #if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); #endif // OS_ANDROID DCHECK(!stepped_); + // base::StringPiece::data() may return null for empty pieces. In particular, + // this may happen when the StringPiece is created from the default + // constructor. + // + // However, sqlite3_bind_text() always interprets a nullptr data argument as a + // NULL value, instead of an empty BLOB value. + static constexpr char kEmptyPlaceholder[] = {0x00}; + const char* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder; + return is_valid() && - CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val.data(), - base::checked_cast<int>(val.size()), + CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, data, value.size(), SQLITE_TRANSIENT)); }
diff --git a/sql/statement.h b/sql/statement.h index 4f997b9..11018d26 100644 --- a/sql/statement.h +++ b/sql/statement.h
@@ -128,7 +128,7 @@ bool BindInt64(int col, int64_t val); bool BindDouble(int col, double val); bool BindCString(int col, const char* val); - bool BindString(int col, const std::string& val); + bool BindString(int col, base::StringPiece val); bool BindString16(int col, base::StringPiece16 value); bool BindBlob(int col, base::span<const uint8_t> value);
diff --git a/sql/statement_unittest.cc b/sql/statement_unittest.cc index a153ffe3..8601dea 100644 --- a/sql/statement_unittest.cc +++ b/sql/statement_unittest.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/strings/string_piece_forward.h" #include "sql/database.h" #include "sql/statement.h" #include "sql/test/error_callback_support.h" @@ -181,5 +182,19 @@ EXPECT_FALSE(select.Step()); } +TEST_F(SQLStatementTest, BindString_NullData) { + ASSERT_TRUE(db_.Execute("CREATE TABLE strings (s TEXT NOT NULL)")); + + Statement insert(db_.GetUniqueStatement("INSERT INTO strings VALUES(?)")); + insert.BindString(0, base::StringPiece(nullptr, 0)); + ASSERT_TRUE(insert.Run()); + + Statement select(db_.GetUniqueStatement("SELECT s FROM strings")); + ASSERT_TRUE(select.Step()); + EXPECT_EQ(std::string(), select.ColumnString(0)); + + EXPECT_FALSE(select.Step()); +} + } // namespace } // namespace sql
diff --git a/testing/PRESUBMIT.py b/testing/PRESUBMIT.py index 6e4d2e1..d04a511 100644 --- a/testing/PRESUBMIT.py +++ b/testing/PRESUBMIT.py
@@ -18,7 +18,8 @@ gpu_path = input_api.os_path.join( input_api.PresubmitLocalPath(), '..', 'content', 'test', 'gpu') testing_env.update({ - 'PYTHONPATH': '%s:%s' % (input_api.PresubmitLocalPath(), gpu_path), + 'PYTHONPATH': input_api.os_path.pathsep.join( + [input_api.PresubmitLocalPath(), gpu_path]), 'PYTHONDONTWRITEBYTECODE': '1', })
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 2764100..3292e0a8 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -5125,7 +5125,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -5211,7 +5211,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -5383,7 +5383,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -5469,7 +5469,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index f1d05ba..10ef6401 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -53730,7 +53730,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -53817,7 +53817,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -53991,7 +53991,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54078,7 +54078,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54324,7 +54324,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54410,7 +54410,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54582,7 +54582,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54668,7 +54668,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -54914,7 +54914,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -55000,7 +55000,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -55172,7 +55172,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M91", - "revision": "version:91.0.4472.157" + "revision": "version:91.0.4472.158" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -55258,7 +55258,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M92", - "revision": "version:92.0.4515.93" + "revision": "version:92.0.4515.94" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index ee2a56c..9068c10a 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -416,7 +416,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M92', - 'revision': 'version:92.0.4515.93', + 'revision': 'version:92.0.4515.94', } ], }, @@ -440,7 +440,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M91', - 'revision': 'version:91.0.4472.157', + 'revision': 'version:91.0.4472.158', } ], }, @@ -488,7 +488,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M92', - 'revision': 'version:92.0.4515.93', + 'revision': 'version:92.0.4515.94', } ], }, @@ -512,7 +512,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M91', - 'revision': 'version:91.0.4472.157', + 'revision': 'version:91.0.4472.158', } ], }, @@ -560,7 +560,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M92', - 'revision': 'version:92.0.4515.93', + 'revision': 'version:92.0.4515.94', } ], }, @@ -584,7 +584,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M91', - 'revision': 'version:91.0.4472.157', + 'revision': 'version:91.0.4472.158', } ], },
diff --git a/testing/scripts/content_shell_crash_test.py b/testing/scripts/content_shell_crash_test.py index 70a5a0d2..20d5d99c9 100755 --- a/testing/scripts/content_shell_crash_test.py +++ b/testing/scripts/content_shell_crash_test.py
@@ -86,10 +86,8 @@ failures = json.load(f) with open(args.isolated_script_test_output, 'w') as fp: - json.dump({ - 'valid': True, - 'failures': failures, - }, fp) + common.record_local_script_results( + 'content_shell_crash_test', fp, failures, True) return rc
diff --git a/third_party/blink/public/platform/media/buffered_data_source_host_impl.h b/third_party/blink/public/platform/media/buffered_data_source_host_impl.h index e35f3171..34b042da 100644 --- a/third_party/blink/public/platform/media/buffered_data_source_host_impl.h +++ b/third_party/blink/public/platform/media/buffered_data_source_host_impl.h
@@ -52,7 +52,7 @@ // Translate the byte ranges to time ranges and append them to the list. // TODO(sandersd): This is a confusing name, find something better. void AddBufferedTimeRanges( - Ranges<base::TimeDelta>* buffered_time_ranges, + media::Ranges<base::TimeDelta>* buffered_time_ranges, base::TimeDelta media_duration) const; bool DidLoadingProgress();
diff --git a/third_party/blink/public/platform/media/key_system_config_selector.h b/third_party/blink/public/platform/media/key_system_config_selector.h index b8c4245..1318f104 100644 --- a/third_party/blink/public/platform/media/key_system_config_selector.h +++ b/third_party/blink/public/platform/media/key_system_config_selector.h
@@ -59,8 +59,8 @@ }; KeySystemConfigSelector( - KeySystems* key_systems, - MediaPermission* media_permission, + media::KeySystems* key_systems, + media::MediaPermission* media_permission, std::unique_ptr<WebLocalFrameDelegate> web_frame_delegate); KeySystemConfigSelector(const KeySystemConfigSelector&) = delete; KeySystemConfigSelector& operator=(const KeySystemConfigSelector&) = delete; @@ -78,8 +78,10 @@ // Callback for the result of `SelectConfig()`. The returned configs must be // non-null iff `status` is `kSupported`. - using SelectConfigCB = base::OnceCallback< - void(Status status, blink::WebMediaKeySystemConfiguration*, CdmConfig*)>; + using SelectConfigCB = + base::OnceCallback<void(Status status, + blink::WebMediaKeySystemConfiguration*, + media::CdmConfig*)>; void SelectConfig( const blink::WebString& key_system, @@ -119,7 +121,7 @@ bool GetSupportedCapabilities( const std::string& key_system, - EmeMediaType media_type, + media::EmeMediaType media_type, const blink::WebVector<blink::WebMediaKeySystemMediaCapability>& requested_media_capabilities, ConfigState* config_state, @@ -127,23 +129,23 @@ supported_media_capabilities); bool IsSupportedContentType(const std::string& key_system, - EmeMediaType media_type, + media::EmeMediaType media_type, const std::string& container_mime_type, const std::string& codecs, ConfigState* config_state); - EmeConfigRule GetEncryptionSchemeConfigRule( + media::EmeConfigRule GetEncryptionSchemeConfigRule( const std::string& key_system, const blink::WebMediaKeySystemMediaCapability::EncryptionScheme encryption_scheme); - KeySystems* const key_systems_; + media::KeySystems* const key_systems_; // This object is unowned but its pointer is always valid. It has the same // lifetime as RenderFrameImpl, and |this| also has the same lifetime // as RenderFrameImpl. RenderFrameImpl owns content::MediaFactory which owns // WebEncryptedMediaClientImpl which owns |this|. - MediaPermission* media_permission_; + media::MediaPermission* media_permission_; std::unique_ptr<WebLocalFrameDelegate> web_frame_delegate_;
diff --git a/third_party/blink/public/platform/media/learning_experiment_helper.h b/third_party/blink/public/platform/media/learning_experiment_helper.h index 20f91d2d..f960484 100644 --- a/third_party/blink/public/platform/media/learning_experiment_helper.h +++ b/third_party/blink/public/platform/media/learning_experiment_helper.h
@@ -20,7 +20,7 @@ public: // If |controller| is null, then everything else no-ops. LearningExperimentHelper( - std::unique_ptr<learning::LearningTaskController> controller); + std::unique_ptr<media::learning::LearningTaskController> controller); LearningExperimentHelper(const LearningExperimentHelper&) = delete; LearningExperimentHelper& operator=(const LearningExperimentHelper&) = delete; @@ -30,17 +30,17 @@ // Start a new observation. Any existing observation is cancelled. Does // nothing if there's no controller. - void BeginObservation(const learning::FeatureDictionary& dictionary); + void BeginObservation(const media::learning::FeatureDictionary& dictionary); // Complete any pending observation. Does nothing if none is in progress. - void CompleteObservationIfNeeded(const learning::TargetValue& target); + void CompleteObservationIfNeeded(const media::learning::TargetValue& target); // Cancel any pending observation. void CancelObservationIfNeeded(); private: // May be null. - std::unique_ptr<learning::LearningTaskController> controller_; + std::unique_ptr<media::learning::LearningTaskController> controller_; // May be null if no observation is in flight. Must be null if |controller_| // is null.
diff --git a/third_party/blink/public/platform/media/multi_buffer_data_source.h b/third_party/blink/public/platform/media/multi_buffer_data_source.h index 8bf52b6..e362c710 100644 --- a/third_party/blink/public/platform/media/multi_buffer_data_source.h +++ b/third_party/blink/public/platform/media/multi_buffer_data_source.h
@@ -35,7 +35,7 @@ // // MultiBufferDataSource must be created and destroyed on the thread associated // with the |task_runner| passed in the constructor. -class BLINK_PLATFORM_EXPORT MultiBufferDataSource : public DataSource { +class BLINK_PLATFORM_EXPORT MultiBufferDataSource : public media::DataSource { public: using DownloadingCB = base::RepeatingCallback<void(bool)>; using RedirectCB = base::RepeatingCallback<void()>; @@ -59,7 +59,7 @@ MultiBufferDataSource( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, scoped_refptr<UrlData> url_data, - MediaLog* media_log, + media::MediaLog* media_log, BufferedDataSourceHost* host, DownloadingCB downloading_cb); MultiBufferDataSource(const MultiBufferDataSource&) = delete; @@ -115,7 +115,7 @@ GURL GetUrlAfterRedirects() const; - // DataSource implementation. + // media::DataSource implementation. // Called from demuxer thread. void Stop() override; void Abort() override; @@ -123,7 +123,7 @@ void Read(int64_t position, int size, uint8_t* data, - DataSource::ReadCB read_cb) override; + media::DataSource::ReadCB read_cb) override; bool GetSize(int64_t* size_out) override; bool IsStreaming() override; void SetBitrate(int bitrate) override; @@ -265,7 +265,7 @@ // Current playback rate. double playback_rate_; - MediaLog* media_log_; + media::MediaLog* media_log_; bool is_client_audio_element_ = false;
diff --git a/third_party/blink/public/platform/media/smoothness_helper.h b/third_party/blink/public/platform/media/smoothness_helper.h index 101d969..e142a21 100644 --- a/third_party/blink/public/platform/media/smoothness_helper.h +++ b/third_party/blink/public/platform/media/smoothness_helper.h
@@ -37,7 +37,7 @@ virtual ~SmoothnessHelper(); // Return the features that we were constructed with. - const learning::FeatureVector& features() const { return features_; } + const media::learning::FeatureVector& features() const { return features_; } // Notify us that an NNR has occurred. virtual void NotifyNNR() = 0; @@ -46,9 +46,9 @@ // we create. They should be features that could be captured at the time a // prediction would be needed. static std::unique_ptr<SmoothnessHelper> Create( - std::unique_ptr<learning::LearningTaskController> bad_controller, - std::unique_ptr<learning::LearningTaskController> nnr_controller, - const learning::FeatureVector& features, + std::unique_ptr<media::learning::LearningTaskController> bad_controller, + std::unique_ptr<media::learning::LearningTaskController> nnr_controller, + const media::learning::FeatureVector& features, Client* player); // We split playbacks up into |kSegmentSize| units, and record the worst @@ -57,9 +57,9 @@ static base::TimeDelta SegmentSizeForTesting(); protected: - SmoothnessHelper(const learning::FeatureVector& features); + SmoothnessHelper(const media::learning::FeatureVector& features); - learning::FeatureVector features_; + media::learning::FeatureVector features_; }; } // namespace media
diff --git a/third_party/blink/public/platform/media/video_frame_compositor.h b/third_party/blink/public/platform/media/video_frame_compositor.h index 8ccc2e2..ee4044d20 100644 --- a/third_party/blink/public/platform/media/video_frame_compositor.h +++ b/third_party/blink/public/platform/media/video_frame_compositor.h
@@ -60,7 +60,7 @@ // VideoFrameCompositor must live on the same thread as the compositor, though // it may be constructed on any thread. class BLINK_PLATFORM_EXPORT VideoFrameCompositor - : public VideoRendererSink, + : public media::VideoRendererSink, public cc::VideoFrameProvider { public: // Used to report back the time when the new frame has been processed. @@ -92,10 +92,9 @@ // Signals the VideoFrameSubmitter to prepare to receive BeginFrames and // submit video frames given by VideoFrameCompositor. - virtual void EnableSubmission( - const viz::SurfaceId& id, - VideoRotation rotation, - bool force_submit); + virtual void EnableSubmission(const viz::SurfaceId& id, + media::VideoRotation rotation, + bool force_submit); // cc::VideoFrameProvider implementation. These methods must be called on the // |task_runner_|. @@ -104,7 +103,7 @@ bool UpdateCurrentFrame(base::TimeTicks deadline_min, base::TimeTicks deadline_max) override; bool HasCurrentFrame() override; - scoped_refptr<VideoFrame> GetCurrentFrame() override; + scoped_refptr<media::VideoFrame> GetCurrentFrame() override; void PutCurrentFrame() override; base::TimeDelta GetPreferredRenderInterval() override; @@ -112,13 +111,13 @@ // it was updated. In certain applications, one might need to periodically // call UpdateCurrentFrameIfStale on |task_runner_| to drive the updates. // Can be called from any thread. - virtual scoped_refptr<VideoFrame> GetCurrentFrameOnAnyThread(); + virtual scoped_refptr<media::VideoFrame> GetCurrentFrameOnAnyThread(); - // VideoRendererSink implementation. These methods must be called from the - // same thread (typically the media thread). + // media::VideoRendererSink implementation. These methods must be called from + // the same thread (typically the media thread). void Start(RenderCallback* callback) override; void Stop() override; - void PaintSingleFrame(scoped_refptr<VideoFrame> frame, + void PaintSingleFrame(scoped_refptr<media::VideoFrame> frame, bool repaint_duplicate_frame = false) override; // If |client_| is not set, |callback_| is set, and |is_background_rendering_| @@ -149,7 +148,7 @@ GetLastPresentedFrameMetadata(); // Updates the rotation information for frames given to |submitter_|. - void UpdateRotation(VideoRotation rotation); + void UpdateRotation(media::VideoRotation rotation); // Should be called when page visibility changes. Notifies |submitter_|. virtual void SetIsPageVisible(bool is_visible); @@ -193,11 +192,11 @@ void OnRendererStateUpdate(bool new_state); // Handles setting of |current_frame_|. - bool ProcessNewFrame(scoped_refptr<VideoFrame> frame, + bool ProcessNewFrame(scoped_refptr<media::VideoFrame> frame, base::TimeTicks presentation_time, bool repaint_duplicate_frame); - void SetCurrentFrame_Locked(scoped_refptr<VideoFrame> frame, + void SetCurrentFrame_Locked(scoped_refptr<media::VideoFrame> frame, base::TimeTicks expected_display_time); // Sets the ForceBeginFrames flag on |submitter_|, and resets @@ -214,8 +213,8 @@ // Called by |background_rendering_timer_| when enough time elapses where we // haven't seen a Render() call. void BackgroundRender( - VideoRendererSink::RenderCallback::RenderingMode mode = - VideoRendererSink::RenderCallback::RenderingMode::kBackground); + media::VideoRendererSink::RenderCallback::RenderingMode mode = + media::VideoRendererSink::RenderCallback::RenderingMode::kBackground); // If |callback_| is available, calls Render() with the provided properties. // Updates |is_background_rendering_|, |last_interval_|, and resets @@ -223,7 +222,7 @@ // available via GetCurrentFrame(). bool CallRender(base::TimeTicks deadline_min, base::TimeTicks deadline_max, - VideoRendererSink::RenderCallback::RenderingMode mode); + media::VideoRendererSink::RenderCallback::RenderingMode mode); // Returns |last_interval_| without acquiring a lock. // Can only be called from the compositor thread. @@ -266,7 +265,7 @@ // Set on the compositor thread, but also read on the media thread. Lock is // not used when reading |current_frame_| on the compositor thread. base::Lock current_frame_lock_; - scoped_refptr<VideoFrame> current_frame_; + scoped_refptr<media::VideoFrame> current_frame_; // Used to fulfill video.requestVideoFrameCallback() calls. // See https://wicg.github.io/video-rvfc/. @@ -276,8 +275,8 @@ // These values are updated and read from the media and compositor threads. base::Lock callback_lock_; - VideoRendererSink::RenderCallback* callback_ GUARDED_BY(callback_lock_) = - nullptr; + media::VideoRendererSink::RenderCallback* callback_ + GUARDED_BY(callback_lock_) = nullptr; // Assume 60Hz before the first UpdateCurrentFrame() call. // Updated/read by the compositor thread, but also read on the media thread.
diff --git a/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h b/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h index 6797eaf..7fa24d9 100644 --- a/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h +++ b/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h
@@ -34,8 +34,8 @@ : public blink::WebEncryptedMediaClient { public: WebEncryptedMediaClientImpl( - CdmFactory* cdm_factory, - MediaPermission* media_permission, + media::CdmFactory* cdm_factory, + media::MediaPermission* media_permission, std::unique_ptr<KeySystemConfigSelector::WebLocalFrameDelegate> web_frame_delegate); ~WebEncryptedMediaClientImpl() override; @@ -49,7 +49,7 @@ void CreateCdm( const blink::WebString& key_system, const blink::WebSecurityOrigin& security_origin, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, std::unique_ptr<blink::WebContentDecryptionModuleResult> result); private: @@ -66,7 +66,7 @@ blink::WebEncryptedMediaRequest request, KeySystemConfigSelector::Status status, blink::WebMediaKeySystemConfiguration* accumulated_configuration, - CdmConfig* cdm_config); + media::CdmConfig* cdm_config); // Gets the Reporter for |key_system|. If it doesn't already exist, // create one. @@ -75,7 +75,7 @@ // Reporter singletons. std::unordered_map<std::string, std::unique_ptr<Reporter>> reporters_; - CdmFactory* cdm_factory_; + media::CdmFactory* cdm_factory_; KeySystemConfigSelector key_system_config_selector_; base::WeakPtrFactory<WebEncryptedMediaClientImpl> weak_factory_{this}; };
diff --git a/third_party/blink/public/platform/media/web_media_player_impl.h b/third_party/blink/public/platform/media/web_media_player_impl.h index 25bebb81..2d4604c0 100644 --- a/third_party/blink/public/platform/media/web_media_player_impl.h +++ b/third_party/blink/public/platform/media/web_media_player_impl.h
@@ -97,8 +97,8 @@ class BLINK_PLATFORM_EXPORT WebMediaPlayerImpl : public blink::WebMediaPlayer, public blink::WebMediaPlayerDelegate::Observer, - public Pipeline::Client, - public MediaObserverClient, + public media::Pipeline::Client, + public media::MediaObserverClient, public blink::WebSurfaceLayerBridgeObserver, public SmoothnessHelper::Client { public: @@ -109,7 +109,7 @@ blink::WebMediaPlayerClient* client, blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, blink::WebMediaPlayerDelegate* delegate, - std::unique_ptr<RendererFactorySelector> renderer_factory_selector, + std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector, UrlIndex* url_index, std::unique_ptr<VideoFrameCompositor> compositor, std::unique_ptr<WebMediaPlayerParams> params); @@ -153,7 +153,7 @@ void Paint(cc::PaintCanvas* canvas, const gfx::Rect& rect, cc::PaintFlags& flags) override; - scoped_refptr<VideoFrame> GetCurrentFrame() override; + scoped_refptr<media::VideoFrame> GetCurrentFrame() override; media::PaintCanvasVideoRenderer* GetPaintCanvasVideoRenderer() override; // True if the loaded media has a playable video/audio track. @@ -245,14 +245,14 @@ // guaranteed, and it a best effort, which can always be fixed by the user by // tapping play/pause once. Attempts to enfore stronger consistency guarantees // have lead to unstable states, and a worse user experience. - void OnRemotePlayStateChange(MediaStatus::State state); + void OnRemotePlayStateChange(media::MediaStatus::State state); #endif - // MediaObserverClient implementation. + // media::MediaObserverClient implementation. void SwitchToRemoteRenderer( const std::string& remote_device_friendly_name) override; void SwitchToLocalRenderer( - MediaObserverClient::ReasonToSwitchToLocal reason) override; + media::MediaObserverClient::ReasonToSwitchToLocal reason) override; void UpdateRemotePlaybackCompatibility(bool is_compatible) override; // Test helper methods for exercising media suspension. Once called, when @@ -322,24 +322,25 @@ void OnPipelineSeeked(bool time_updated); void OnDemuxerOpened(); - // Pipeline::Client overrides. - void OnError(PipelineStatus status) override; + // media::Pipeline::Client overrides. + void OnError(media::PipelineStatus status) override; void OnEnded() override; - void OnMetadata(const PipelineMetadata& metadata) override; - void OnBufferingStateChange(BufferingState state, - BufferingStateChangeReason reason) override; + void OnMetadata(const media::PipelineMetadata& metadata) override; + void OnBufferingStateChange( + media::BufferingState state, + media::BufferingStateChangeReason reason) override; void OnDurationChange() override; - void OnAddTextTrack(const TextTrackConfig& config, - AddTextTrackDoneCB done_cb) override; - void OnWaiting(WaitingReason reason) override; - void OnAudioConfigChange(const AudioDecoderConfig& config) override; - void OnVideoConfigChange(const VideoDecoderConfig& config) override; + void OnAddTextTrack(const media::TextTrackConfig& config, + media::AddTextTrackDoneCB done_cb) override; + void OnWaiting(media::WaitingReason reason) override; + void OnAudioConfigChange(const media::AudioDecoderConfig& config) override; + void OnVideoConfigChange(const media::VideoDecoderConfig& config) override; void OnVideoNaturalSizeChange(const gfx::Size& size) override; void OnVideoOpacityChange(bool opaque) override; void OnVideoFrameRateChange(absl::optional<int> fps) override; void OnVideoAverageKeyframeDistanceUpdate() override; - void OnAudioPipelineInfoChange(const AudioPipelineInfo& info) override; - void OnVideoPipelineInfoChange(const VideoPipelineInfo& info) override; + void OnAudioPipelineInfoChange(const media::AudioPipelineInfo& info) override; + void OnVideoPipelineInfoChange(const media::VideoPipelineInfo& info) override; // Simplified watch time reporting. void OnSimpleWatchTimerTick(); @@ -369,14 +370,15 @@ // Called by GpuVideoDecoder on Android to request a surface to render to (if // necessary). - void OnOverlayInfoRequested(bool decoder_requires_restart_for_overlay, - ProvideOverlayInfoCB provide_overlay_info_cb); + void OnOverlayInfoRequested( + bool decoder_requires_restart_for_overlay, + media::ProvideOverlayInfoCB provide_overlay_info_cb); // Creates a Renderer via the |renderer_factory_selector_|. If the // |renderer_type| is absl::nullopt, create the base Renderer. Otherwise, set // the base type to be |renderer_type| and create a Renderer of that type. - std::unique_ptr<Renderer> CreateRenderer( - absl::optional<RendererType> renderer_type); + std::unique_ptr<media::Renderer> CreateRenderer( + absl::optional<media::RendererType> renderer_type); // Finishes starting the pipeline due to a call to load(). void StartPipeline(); @@ -394,16 +396,16 @@ // Returns the current video frame from |compositor_|, and asks the compositor // to update its frame if it is stale. // Can return a nullptr. - scoped_refptr<VideoFrame> GetCurrentFrameFromCompositor() const; + scoped_refptr<media::VideoFrame> GetCurrentFrameFromCompositor() const; // Called when the demuxer encounters encrypted streams. - void OnEncryptedMediaInitData(EmeInitDataType init_data_type, + void OnEncryptedMediaInitData(media::EmeInitDataType init_data_type, const std::vector<uint8_t>& init_data); // Called when the FFmpegDemuxer encounters new media tracks. This is only // invoked when using FFmpegDemuxer, since MSE/ChunkDemuxer handle media // tracks separately in WebSourceBufferImpl. - void OnFFmpegMediaTracksUpdated(std::unique_ptr<MediaTracks> tracks); + void OnFFmpegMediaTracksUpdated(std::unique_ptr<media::MediaTracks> tracks); // Sets CdmContext from |cdm| on the pipeline and calls OnCdmAttached() // when done. @@ -438,7 +440,7 @@ void SetMemoryReportingState(bool is_memory_reporting_enabled); void SetSuspendState(bool is_suspended); - void SetDemuxer(std::unique_ptr<Demuxer> demuxer); + void SetDemuxer(std::unique_ptr<media::Demuxer> demuxer); // Called at low frequency to tell external observers how much memory we're // using for video playback. Called by |memory_usage_reporting_timer_|. @@ -452,7 +454,7 @@ base::trace_event::ProcessMemoryDump* pmd); static void OnMediaThreadMemoryDump( int32_t id, - Demuxer* demuxer, + media::Demuxer* demuxer, const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd); @@ -535,10 +537,10 @@ // Overrides the pipeline statistics returned by GetPiplineStatistics() for // tests. - void SetPipelineStatisticsForTest(const PipelineStatistics& stats); + void SetPipelineStatisticsForTest(const media::PipelineStatistics& stats); // Returns the pipeline statistics or the value overridden by tests. - PipelineStatistics GetPipelineStatistics() const; + media::PipelineStatistics GetPipelineStatistics() const; // Overrides the pipeline media duration returned by // GetPipelineMediaDuration() for tests. @@ -547,7 +549,7 @@ // Returns the pipeline media duration or the value overridden by tests. base::TimeDelta GetPipelineMediaDuration() const; - MediaContentType GetMediaContentType() const; + media::MediaContentType GetMediaContentType() const; // Records |duration| to the appropriate metric based on whether we're // handling a src= or MSE based playback. @@ -565,8 +567,8 @@ // Internal implementation of Pipeline::Client::OnBufferingStateChange(). When // |for_suspended_start| is true, the given state will be set even if the // pipeline is not currently stable. - void OnBufferingStateChangeInternal(BufferingState state, - BufferingStateChangeReason reason, + void OnBufferingStateChangeInternal(media::BufferingState state, + media::BufferingStateChangeReason reason, bool for_suspended_start = false); // Records |natural_size| to MediaLog and video height to UMA. @@ -591,7 +593,7 @@ // Records the encryption scheme used by the stream |stream_name|. This is // only recorded when metadata is available. void RecordEncryptionScheme(const std::string& stream_name, - EncryptionScheme encryption_scheme); + media::EncryptionScheme encryption_scheme); // Returns whether the player is currently displayed in Picture-in-Picture. // It will return true even if the player is in AutoPIP mode. @@ -620,8 +622,8 @@ void UpdateSmoothnessHelper(); // Get the LearningTaskController for |task_name|. - std::unique_ptr<learning::LearningTaskController> GetLearningTaskController( - const char* task_name); + std::unique_ptr<media::learning::LearningTaskController> + GetLearningTaskController(const char* task_name); // Returns whether the player has an audio track and whether it should be // allowed to play it. @@ -650,16 +652,16 @@ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; const scoped_refptr<base::TaskRunner> worker_task_runner_; - std::unique_ptr<MediaLog> media_log_; + std::unique_ptr<media::MediaLog> media_log_; // |pipeline_controller_| owns an instance of Pipeline. - std::unique_ptr<PipelineController> pipeline_controller_; + std::unique_ptr<media::PipelineController> pipeline_controller_; // The LoadType passed in the |load_type| parameter of the load() call. LoadType load_type_ = kLoadTypeURL; // Cache of metadata for answering hasAudio(), hasVideo(), and naturalSize(). - PipelineMetadata pipeline_metadata_; + media::PipelineMetadata pipeline_metadata_; // Whether the video is known to be opaque or not. bool opaque_ = false; @@ -744,8 +746,8 @@ base::RepeatingTimer memory_usage_reporting_timer_; WebMediaPlayerParams::AdjustAllocatedMemoryCB adjust_allocated_memory_cb_; int64_t last_reported_memory_usage_ = 0; - std::unique_ptr<MemoryDumpProviderProxy> main_thread_mem_dumper_; - std::unique_ptr<MemoryDumpProviderProxy> media_thread_mem_dumper_; + std::unique_ptr<media::MemoryDumpProviderProxy> main_thread_mem_dumper_; + std::unique_ptr<media::MemoryDumpProviderProxy> media_thread_mem_dumper_; // Routes audio playback to either AudioRendererSink or WebAudio. scoped_refptr<blink::WebAudioSourceProviderImpl> audio_source_provider_; @@ -757,9 +759,9 @@ // |demuxer_| will contain the appropriate demuxer based on which resource // load strategy we're using. MultiBufferDataSource* mb_data_source_ = nullptr; - std::unique_ptr<DataSource> data_source_; - std::unique_ptr<Demuxer> demuxer_; - ChunkDemuxer* chunk_demuxer_ = nullptr; + std::unique_ptr<media::DataSource> data_source_; + std::unique_ptr<media::Demuxer> demuxer_; + media::ChunkDemuxer* chunk_demuxer_ = nullptr; std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; @@ -776,7 +778,7 @@ scoped_refptr<base::SingleThreadTaskRunner> vfc_task_runner_; std::unique_ptr<VideoFrameCompositor> compositor_; // Deleted on |vfc_task_runner_|. - PaintCanvasVideoRenderer video_renderer_; + media::PaintCanvasVideoRenderer video_renderer_; // The compositor layer for displaying the video content when using composited // playback. @@ -786,11 +788,11 @@ // If a CdmContext is attached keep a reference to the CdmContextRef, so that // it is not destroyed until after the pipeline is done with it. - std::unique_ptr<CdmContextRef> cdm_context_ref_; + std::unique_ptr<media::CdmContextRef> cdm_context_ref_; // Keep track of the CdmContextRef while it is in the process of attaching to // the pipeline. - std::unique_ptr<CdmContextRef> pending_cdm_context_ref_; + std::unique_ptr<media::CdmContextRef> pending_cdm_context_ref_; // True when encryption is detected, either by demuxer or by presence of a // ContentDecyprtionModule (CDM). @@ -798,7 +800,7 @@ // Captured once the cdm is provided to SetCdmInternal(). Used in creation of // |video_decode_stats_reporter_|. - absl::optional<CdmConfig> cdm_config_; + absl::optional<media::CdmConfig> cdm_config_; // String identifying the KeySystem described by |cdm_config_|. Empty until a // CDM has been attached. Used in creation |video_decode_stats_reporter_|. @@ -821,7 +823,7 @@ double volume_ = 1.0; double volume_multiplier_ = 1.0; - std::unique_ptr<RendererFactorySelector> renderer_factory_selector_; + std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector_; // For canceling AndroidOverlay routing token requests. base::CancelableOnceCallback<void(const base::UnguessableToken&)> @@ -831,7 +833,7 @@ // and satisfied once the overlay info is available. If the decoder does not // require restart to change surfaces, this is callback is kept until cleared // by the decoder. - ProvideOverlayInfoCB provide_overlay_info_cb_; + media::ProvideOverlayInfoCB provide_overlay_info_cb_; // On Android an overlay surface means using // SurfaceView instead of SurfaceTexture. @@ -876,8 +878,10 @@ // Monitors the watch time of the played content. std::unique_ptr<blink::WatchTimeReporter> watch_time_reporter_; - AudioDecoderType audio_decoder_type_ = AudioDecoderType::kUnknown; - VideoDecoderType video_decoder_type_ = VideoDecoderType::kUnknown; + media::AudioDecoderType audio_decoder_type_ = + media::AudioDecoderType::kUnknown; + media::VideoDecoderType video_decoder_type_ = + media::VideoDecoderType::kUnknown; // The time at which DoLoad() is executed. base::TimeTicks load_start_time_; @@ -903,7 +907,7 @@ base::TimeTicks preroll_attempt_start_time_; // Monitors the player events. - base::WeakPtr<MediaObserver> observer_; + base::WeakPtr<media::MediaObserver> observer_; // Owns the weblayer and obtains/maintains SurfaceIds. std::unique_ptr<blink::WebSurfaceLayerBridge> bridge_; @@ -932,7 +936,7 @@ bool disable_pipeline_auto_suspend_ = false; // Pipeline statistics overridden by tests. - absl::optional<PipelineStatistics> pipeline_statistics_for_test_; + absl::optional<media::PipelineStatistics> pipeline_statistics_for_test_; // Pipeline media duration overridden by tests. absl::optional<base::TimeDelta> pipeline_media_duration_for_test_; @@ -966,7 +970,7 @@ OverlayMode overlay_mode_ = OverlayMode::kNoOverlays; // Optional callback to request the routing token for AndroidOverlay. - RequestRoutingTokenCallback request_routing_token_cb_; + media::RequestRoutingTokenCallback request_routing_token_cb_; // If |overlay_routing_token_is_pending_| is false, then // |overlay_routing_token_| contains the routing token we should send, if any. @@ -974,9 +978,9 @@ // we have a request for the token that hasn't been answered yet; i.e., it // means that we don't know what, if any, token we should be using. bool overlay_routing_token_is_pending_ = false; - OverlayInfo::RoutingToken overlay_routing_token_; + media::OverlayInfo::RoutingToken overlay_routing_token_; - OverlayInfo overlay_info_; + media::OverlayInfo overlay_info_; base::CancelableOnceClosure update_background_status_cb_; @@ -986,8 +990,8 @@ // base::CancellableOnceClosure. bool is_background_status_change_cancelled_ = true; - mojo::Remote<mojom::MediaMetricsProvider> media_metrics_provider_; - mojo::Remote<mojom::PlaybackEventsRecorder> playback_events_recorder_; + mojo::Remote<media::mojom::MediaMetricsProvider> media_metrics_provider_; + mojo::Remote<media::mojom::PlaybackEventsRecorder> playback_events_recorder_; absl::optional<ReadyState> stale_state_override_for_testing_; @@ -1020,13 +1024,13 @@ base::CancelableOnceClosure have_enough_after_lazy_load_cb_; - RendererType renderer_type_ = RendererType::kDefault; - SimpleWatchTimer simple_watch_timer_; + media::RendererType renderer_type_ = media::RendererType::kDefault; + media::SimpleWatchTimer simple_watch_timer_; LearningExperimentHelper will_play_helper_; // Stores the optional override Demuxer until it is used in DoLoad(). - std::unique_ptr<Demuxer> demuxer_override_; + std::unique_ptr<media::Demuxer> demuxer_override_; std::unique_ptr<PowerStatusHelper> power_status_helper_;
diff --git a/third_party/blink/public/platform/media/web_media_player_params.h b/third_party/blink/public/platform/media/web_media_player_params.h index 2e8c8ae6..ff45034 100644 --- a/third_party/blink/public/platform/media/web_media_player_params.h +++ b/third_party/blink/public/platform/media/web_media_player_params.h
@@ -62,9 +62,10 @@ // |defer_load_cb|, |audio_renderer_sink|, |compositor_task_runner|, and // |context_3d_cb| may be null. WebMediaPlayerParams( - std::unique_ptr<MediaLog> media_log, + std::unique_ptr<media::MediaLog> media_log, const DeferLoadCB& defer_load_cb, - const scoped_refptr<SwitchableAudioRendererSink>& audio_renderer_sink, + const scoped_refptr<media::SwitchableAudioRendererSink>& + audio_renderer_sink, const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, const scoped_refptr<base::TaskRunner>& worker_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, @@ -72,18 +73,18 @@ video_frame_compositor_task_runner, const AdjustAllocatedMemoryCB& adjust_allocated_memory_cb, blink::WebContentDecryptionModule* initial_cdm, - RequestRoutingTokenCallback request_routing_token_cb, - base::WeakPtr<MediaObserver> media_observer, + media::RequestRoutingTokenCallback request_routing_token_cb, + base::WeakPtr<media::MediaObserver> media_observer, bool enable_instant_source_buffer_gc, bool embedded_media_experience_enabled, - mojo::PendingRemote<mojom::MediaMetricsProvider> metrics_provider, + mojo::PendingRemote<media::mojom::MediaMetricsProvider> metrics_provider, CreateSurfaceLayerBridgeCB bridge_callback, scoped_refptr<viz::RasterContextProvider> raster_context_provider, blink::WebMediaPlayer::SurfaceLayerMode use_surface_layer_for_video, bool is_background_suspend_enabled, bool is_background_video_play_enabled, bool is_background_video_track_optimization_supported, - std::unique_ptr<Demuxer> demuxer_override, + std::unique_ptr<media::Demuxer> demuxer_override, std::unique_ptr<PowerStatusHelper> power_status_helper); WebMediaPlayerParams(const WebMediaPlayerParams&) = delete; @@ -92,14 +93,17 @@ DeferLoadCB defer_load_cb() const { return defer_load_cb_; } - const scoped_refptr<SwitchableAudioRendererSink>& audio_renderer_sink() + const scoped_refptr<media::SwitchableAudioRendererSink>& audio_renderer_sink() const { return audio_renderer_sink_; } - std::unique_ptr<MediaLog> take_media_log() { return std::move(media_log_); } + std::unique_ptr<media::MediaLog> take_media_log() { + return std::move(media_log_); + } - mojo::PendingRemote<mojom::MediaMetricsProvider> take_metrics_provider() { + mojo::PendingRemote<media::mojom::MediaMetricsProvider> + take_metrics_provider() { return std::move(metrics_provider_); } @@ -129,7 +133,7 @@ return adjust_allocated_memory_cb_; } - base::WeakPtr<MediaObserver> media_observer() const { + base::WeakPtr<media::MediaObserver> media_observer() const { return media_observer_; } @@ -141,7 +145,7 @@ return embedded_media_experience_enabled_; } - RequestRoutingTokenCallback request_routing_token_cb() { + media::RequestRoutingTokenCallback request_routing_token_cb() { return request_routing_token_cb_; } @@ -169,7 +173,7 @@ return is_background_video_track_optimization_supported_; } - std::unique_ptr<Demuxer> TakeDemuxerOverride(); + std::unique_ptr<media::Demuxer> TakeDemuxerOverride(); std::unique_ptr<PowerStatusHelper> TakePowerStatusHelper() { return std::move(power_status_helper_); @@ -177,8 +181,8 @@ private: DeferLoadCB defer_load_cb_; - scoped_refptr<SwitchableAudioRendererSink> audio_renderer_sink_; - std::unique_ptr<MediaLog> media_log_; + scoped_refptr<media::SwitchableAudioRendererSink> audio_renderer_sink_; + std::unique_ptr<media::MediaLog> media_log_; scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; scoped_refptr<base::TaskRunner> worker_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; @@ -187,11 +191,11 @@ AdjustAllocatedMemoryCB adjust_allocated_memory_cb_; blink::WebContentDecryptionModule* initial_cdm_; - RequestRoutingTokenCallback request_routing_token_cb_; - base::WeakPtr<MediaObserver> media_observer_; + media::RequestRoutingTokenCallback request_routing_token_cb_; + base::WeakPtr<media::MediaObserver> media_observer_; bool enable_instant_source_buffer_gc_; const bool embedded_media_experience_enabled_; - mojo::PendingRemote<mojom::MediaMetricsProvider> metrics_provider_; + mojo::PendingRemote<media::mojom::MediaMetricsProvider> metrics_provider_; CreateSurfaceLayerBridgeCB create_bridge_callback_; scoped_refptr<viz::RasterContextProvider> raster_context_provider_; blink::WebMediaPlayer::SurfaceLayerMode use_surface_layer_for_video_; @@ -205,7 +209,7 @@ bool is_background_video_track_optimization_supported_ = true; // Optional custom demuxer to use instead of the standard demuxers. - std::unique_ptr<Demuxer> demuxer_override_; + std::unique_ptr<media::Demuxer> demuxer_override_; std::unique_ptr<PowerStatusHelper> power_status_helper_; };
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index ed7efccb..b8e40bd2 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -75,6 +75,7 @@ BLINK_PLATFORM_EXPORT static void EnableAccessibilityExposeHTMLElement(bool); BLINK_PLATFORM_EXPORT static void EnableAccessibilityExposeIgnoredNodes(bool); BLINK_PLATFORM_EXPORT static void EnableAccessibilityObjectModel(bool); + BLINK_PLATFORM_EXPORT static void EnableAccessibilityPageZoom(bool); BLINK_PLATFORM_EXPORT static void EnableAccessibilityUseAXPositionForDocumentMarkers(bool); BLINK_PLATFORM_EXPORT static void EnableAdTagging(bool);
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index 0679ac6..3cb7704 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -1543,8 +1543,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_documenttimeline_scrolltimeline.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_dommatrix_float32array_float64array.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_dommatrix_float32array_float64array.h", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_dompoint_unrestricteddouble.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_dompoint_unrestricteddouble.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_dompointinit_unrestricteddouble.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_dompointinit_unrestricteddouble.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_double_doubleornullsequence_null.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_double_doubleornullsequence_null.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_double_doublesequence.cc",
diff --git a/third_party/blink/renderer/build/win/precompile.h b/third_party/blink/renderer/build/win/precompile.h index fde39b8..519fdff 100644 --- a/third_party/blink/renderer/build/win/precompile.h +++ b/third_party/blink/renderer/build/win/precompile.h
@@ -18,8 +18,6 @@ #define _USE_MATH_DEFINES // Make math.h behave like other platforms. -#include <Windows.h> - #include <errno.h> #include <fcntl.h> #include <limits.h>
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index 09160263..d9ee626 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -300,9 +300,6 @@ document_ = timeline_->GetDocument(); DCHECK(document_); timeline_->AnimationAttached(this); - - if (content_) - content_->SetTimingTimelineDuration(timeline_->GetDuration()); } else { document_ = To<LocalDOMWindow>(execution_context)->document(); DCHECK(document_); @@ -328,12 +325,7 @@ } AnimationTimeDelta Animation::EffectEnd() const { - if (timeline_ && timeline_->IsProgressBasedTimeline()) { - // For progress based timelines, timeline times are mapped to be relative to - // Effect times, which means effect end maps to timeline duration. - return timeline_->GetDuration().value(); - } - return content_ ? content_->SpecifiedTiming().EndTimeInternal() + return content_ ? content_->NormalizedTiming().end_time : AnimationTimeDelta(); } @@ -883,7 +875,7 @@ // Update content timing to be based on new timeline type if (content_ && timeline_) - content_->SetTimingTimelineDuration(timeline_->GetDuration()); + content_->InvalidateNormalizedTiming(); reset_current_time_on_resume_ = false;
diff --git a/third_party/blink/renderer/core/animation/animation_effect.cc b/third_party/blink/renderer/core/animation/animation_effect.cc index 06b29a38..7d0acea 100644 --- a/third_party/blink/renderer/core/animation/animation_effect.cc +++ b/third_party/blink/renderer/core/animation/animation_effect.cc
@@ -50,6 +50,92 @@ needs_update_(true), cancel_time_(AnimationTimeDelta()) { timing_.AssertValid(); + InvalidateNormalizedTiming(); +} + +// Scales all timing values so that end_time == timeline_duration +void AnimationEffect::EnsureNormalizedTiming() const { + // Only run the normalization process if needed + if (normalized_) + return; + + normalized_ = Timing::NormalizedTiming(); + if (GetAnimation() && GetAnimation()->timeline() && + GetAnimation()->timeline()->IsProgressBasedTimeline()) { + // Normalize timings for progress based timelines + normalized_->timeline_duration = GetAnimation()->timeline()->GetDuration(); + DCHECK(normalized_->timeline_duration); + + if (timing_.iteration_duration) { + // Scaling up iteration_duration allows animation effect to be able to + // handle values produced by progress based timelines. At this point it + // can be assumed that EndTimeInternal() will give us a good value. + + const AnimationTimeDelta active_duration = MultiplyZeroAlwaysGivesZero( + timing_.iteration_duration.value(), timing_.iteration_count); + DCHECK_GE(active_duration, AnimationTimeDelta()); + + // Per the spec, the end time has a lower bound of 0.0: + // https://drafts.csswg.org/web-animations-1/#end-time + const AnimationTimeDelta end_time = + std::max(timing_.start_delay + active_duration + timing_.end_delay, + AnimationTimeDelta()); + + // Exceptions should have already been thrown when trying to input values + // that would result in an infinite end_time for progress based timelines. + DCHECK(!end_time.is_inf()); + + // Negative start_delay that is >= iteration_duration or iteration_count + // of 0 will cause end_time to be 0 or negative. + if (end_time.is_zero()) { + // end_time of zero causes division by zero so we handle it here + normalized_->start_delay = AnimationTimeDelta(); + normalized_->end_delay = AnimationTimeDelta(); + normalized_->iteration_duration = AnimationTimeDelta(); + } else { + // convert to percentages then multiply by the timeline_duration + normalized_->start_delay = (timing_.start_delay / end_time) * + normalized_->timeline_duration.value(); + + normalized_->end_delay = (timing_.end_delay / end_time) * + normalized_->timeline_duration.value(); + + normalized_->iteration_duration = + (timing_.iteration_duration.value() / end_time) * + normalized_->timeline_duration.value(); + } + } else { + // Handle iteration_duration value of "auto" + + // TODO(crbug.com/1216527) + // this will change to support percentage delays and possibly mixed + // delays. + DCHECK(normalized_->start_delay.is_zero() && + normalized_->end_delay.is_zero()); + + normalized_->iteration_duration = + GetAnimation()->timeline()->CalculateIntrinsicIterationDuration( + timing_); + // TODO: add support for progress based timelines and "auto" duration + // effects + } + } else { + // Populates normalized values for use with time based timelines. + normalized_->start_delay = timing_.start_delay; + normalized_->end_delay = timing_.end_delay; + normalized_->iteration_duration = + timing_.iteration_duration.value_or(AnimationTimeDelta()); + } + + normalized_->active_duration = MultiplyZeroAlwaysGivesZero( + normalized_->iteration_duration, timing_.iteration_count); + + // Per the spec, the end time has a lower bound of 0.0: + // https://drafts.csswg.org/web-animations-1/#end-time + normalized_->end_time = + std::max(normalized_->start_delay + normalized_->active_duration + + normalized_->end_delay, + AnimationTimeDelta()); } void AnimationEffect::UpdateSpecifiedTiming(const Timing& timing) { @@ -83,27 +169,10 @@ timing_.timing_function = timing.timing_function; } - // Changing timings can impact the intrinsic iteration duration. - if (GetAnimation() && GetAnimation()->timeline()) { - timing_.intrinsic_iteration_duration = - GetAnimation()->timeline()->CalculateIntrinsicIterationDuration( - timing_); - } + InvalidateNormalizedTiming(); InvalidateAndNotifyOwner(); } -void AnimationEffect::SetTimingTimelineDuration( - absl::optional<AnimationTimeDelta> timeline_duration) { - timing_.timeline_duration = timeline_duration; - if (timeline_duration) { - timing_.intrinsic_iteration_duration = - GetAnimation()->timeline()->CalculateIntrinsicIterationDuration( - timing_); - } else { - timing_.intrinsic_iteration_duration = AnimationTimeDelta(); - } -} - void AnimationEffect::SetIgnoreCssTimingProperties() { timing_.SetTimingOverride(Timing::kOverrideAll); } @@ -115,8 +184,8 @@ } ComputedEffectTiming* AnimationEffect::getComputedTiming() const { - return SpecifiedTiming().getComputedTiming(EnsureCalculated(), - IsA<KeyframeEffect>(this)); + return SpecifiedTiming().getComputedTiming( + EnsureCalculated(), NormalizedTiming(), IsA<KeyframeEffect>(this)); } void AnimationEffect::updateTiming(OptionalEffectTiming* optional_timing, @@ -169,12 +238,7 @@ if (!TimingInput::Update(timing_, optional_timing, nullptr, exception_state)) return; - // Changing timings can impact the intrinsic iteration duration. - if (GetAnimation() && GetAnimation()->timeline()) { - timing_.intrinsic_iteration_duration = - GetAnimation()->timeline()->CalculateIntrinsicIterationDuration( - timing_); - } + InvalidateNormalizedTiming(); InvalidateAndNotifyOwner(); } @@ -215,18 +279,6 @@ absl::optional<Timing::Phase> timeline_phase = TimelinePhaseToTimingPhase(inherited_timeline_phase); - // TODO (crbug.com/1222387): Once normalized timing values have been added, - // we will no longer need to convert inherited_time to be effect time relative - // since all effect times will be timeline relative based on the normalized - // timing values. - if (inherited_time && GetAnimation() && GetAnimation()->timeline() && - GetAnimation()->timeline()->IsProgressBasedTimeline()) { - // map inherited time [0,timeline_duration] to effect end time [0,end_time] - inherited_time = (inherited_time.value() / - GetAnimation()->timeline()->GetDuration().value()) * - SpecifiedTiming().EndTimeInternal(); - } - bool needs_update = needs_update_ || last_update_time_ != inherited_time || (owner_ && owner_->EffectSuppressed()) || last_update_phase_ != timeline_phase; @@ -236,8 +288,8 @@ if (needs_update) { Timing::CalculatedTiming calculated = SpecifiedTiming().CalculateTimings( - inherited_time, timeline_phase, direction, IsA<KeyframeEffect>(this), - playback_rate); + inherited_time, timeline_phase, NormalizedTiming(), direction, + IsA<KeyframeEffect>(this), playback_rate); const bool was_canceled = calculated.phase != calculated_.phase && calculated.phase == Timing::kPhaseNone;
diff --git a/third_party/blink/renderer/core/animation/animation_effect.h b/third_party/blink/renderer/core/animation/animation_effect.h index 5dbb99a..b04f02e3 100644 --- a/third_party/blink/renderer/core/animation/animation_effect.h +++ b/third_party/blink/renderer/core/animation/animation_effect.h
@@ -83,8 +83,6 @@ virtual bool IsKeyframeEffect() const { return false; } virtual bool IsInertEffect() const { return false; } - void SetTimingTimelineDuration(absl::optional<AnimationTimeDelta>); - Timing::Phase GetPhase() const { return EnsureCalculated().phase; } bool IsCurrent() const { return EnsureCalculated().is_current; } bool IsInEffect() const { return EnsureCalculated().is_in_effect; } @@ -106,6 +104,13 @@ } const Timing& SpecifiedTiming() const { return timing_; } + + const Timing::NormalizedTiming& NormalizedTiming() const { + EnsureNormalizedTiming(); + return normalized_.value(); + } + void InvalidateNormalizedTiming() { normalized_.reset(); } + void UpdateSpecifiedTiming(const Timing&); void SetIgnoreCssTimingProperties(); @@ -122,7 +127,10 @@ } // Attach/Detach the AnimationEffect from its owning animation. - virtual void Attach(AnimationEffectOwner* owner) { owner_ = owner; } + virtual void Attach(AnimationEffectOwner* owner) { + owner_ = owner; + InvalidateNormalizedTiming(); + } virtual void Detach() { DCHECK(owner_); owner_ = nullptr; @@ -171,11 +179,13 @@ Member<EventDelegate> event_delegate_; mutable Timing::CalculatedTiming calculated_; + mutable absl::optional<Timing::NormalizedTiming> normalized_; mutable bool needs_update_; mutable absl::optional<AnimationTimeDelta> last_update_time_; mutable absl::optional<Timing::Phase> last_update_phase_; AnimationTimeDelta cancel_time_; const Timing::CalculatedTiming& EnsureCalculated() const; + void EnsureNormalizedTiming() const; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/animation_effect_test.cc b/third_party/blink/renderer/core/animation/animation_effect_test.cc index 36289955..dd84e04 100644 --- a/third_party/blink/renderer/core/animation/animation_effect_test.cc +++ b/third_party/blink/renderer/core/animation/animation_effect_test.cc
@@ -140,7 +140,7 @@ EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(0, animation_node->Progress()); animation_node->UpdateInheritedTime(1); @@ -151,7 +151,7 @@ EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(0.5, animation_node->Progress()); animation_node->UpdateInheritedTime(2); @@ -162,7 +162,7 @@ EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); animation_node->UpdateInheritedTime(3); @@ -173,7 +173,7 @@ EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); } @@ -254,13 +254,13 @@ animation_node->UpdateInheritedTime(-1); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_FALSE(animation_node->CurrentIteration()); EXPECT_FALSE(animation_node->Progress()); animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(0, animation_node->Progress()); } @@ -277,7 +277,7 @@ EXPECT_FALSE(animation_node->Progress()); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); animation_node->UpdateInheritedTime(0); EXPECT_EQ(0, animation_node->CurrentIteration()); @@ -384,7 +384,7 @@ EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); animation_node->UpdateInheritedTime(1); @@ -395,7 +395,7 @@ EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); } @@ -487,13 +487,13 @@ animation_node->UpdateInheritedTime(-1); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_FALSE(animation_node->CurrentIteration()); EXPECT_FALSE(animation_node->Progress()); animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(std::numeric_limits<double>::infinity(), animation_node->CurrentIteration()); EXPECT_EQ(1, animation_node->Progress()); @@ -587,7 +587,7 @@ animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -598,7 +598,7 @@ animation_node->UpdateInheritedTime(1); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -617,7 +617,7 @@ animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseAfter, animation_node->GetPhase()); EXPECT_FALSE(animation_node->IsInPlay()); EXPECT_FALSE(animation_node->IsCurrent()); @@ -645,7 +645,7 @@ animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -656,7 +656,7 @@ animation_node->UpdateInheritedTime(1); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -673,7 +673,7 @@ timing.iteration_count = 2; auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(11), - animation_node->SpecifiedTiming().EndTimeInternal()); + animation_node->NormalizedTiming().end_time); } TEST(AnimationAnimationEffectTest, Events) {
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_update.h b/third_party/blink/renderer/core/animation/css/css_animation_update.h index 4f8fdd6f..e310f4918 100644 --- a/third_party/blink/renderer/core/animation/css/css_animation_update.h +++ b/third_party/blink/renderer/core/animation/css/css_animation_update.h
@@ -229,17 +229,17 @@ return active_interpolations_for_transitions_; } - bool IsEmpty() const { - return new_animations_.IsEmpty() && - cancelled_animation_indices_.IsEmpty() && - suppressed_animations_.IsEmpty() && - animation_indices_with_pause_toggled_.IsEmpty() && - animations_with_updates_.IsEmpty() && new_transitions_.IsEmpty() && - cancelled_transitions_.IsEmpty() && - finished_transitions_.IsEmpty() && - active_interpolations_for_animations_.IsEmpty() && - active_interpolations_for_transitions_.IsEmpty() && - updated_compositor_keyframes_.IsEmpty(); + bool IsEmpty() const { return !HasUpdates() && !HasActiveInterpolations(); } + + bool HasUpdates() const { + return !new_animations_.IsEmpty() || + !cancelled_animation_indices_.IsEmpty() || + !suppressed_animations_.IsEmpty() || + !animation_indices_with_pause_toggled_.IsEmpty() || + !animations_with_updates_.IsEmpty() || !new_transitions_.IsEmpty() || + !cancelled_transitions_.IsEmpty() || + !finished_transitions_.IsEmpty() || + !updated_compositor_keyframes_.IsEmpty(); } void Trace(Visitor* visitor) const { @@ -253,6 +253,11 @@ } private: + bool HasActiveInterpolations() const { + return !active_interpolations_for_animations_.IsEmpty() || + !active_interpolations_for_transitions_.IsEmpty(); + } + // Order is significant since it defines the order in which new animations // will be started. Note that there may be multiple animations present // with the same name, due to the way in which we split up animations with
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index e3cfa01..0597f39 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -405,9 +405,9 @@ // Timing functions for computing elapsed time of an event. AnimationTimeDelta IntervalStart(const AnimationEffect& effect) { - AnimationTimeDelta start_delay = effect.SpecifiedTiming().start_delay; + AnimationTimeDelta start_delay = effect.NormalizedTiming().start_delay; const AnimationTimeDelta active_duration = - effect.SpecifiedTiming().ActiveDuration(); + effect.NormalizedTiming().active_duration; // This fixes a problem where start_delay could be -0 if (!start_delay.is_zero()) { start_delay = -start_delay; @@ -416,10 +416,10 @@ } AnimationTimeDelta IntervalEnd(const AnimationEffect& effect) { - const AnimationTimeDelta start_delay = effect.SpecifiedTiming().start_delay; - const AnimationTimeDelta end_delay = effect.SpecifiedTiming().end_delay; + const AnimationTimeDelta start_delay = effect.NormalizedTiming().start_delay; + const AnimationTimeDelta end_delay = effect.NormalizedTiming().end_delay; const AnimationTimeDelta active_duration = - effect.SpecifiedTiming().ActiveDuration(); + effect.NormalizedTiming().active_duration; const AnimationTimeDelta target_effect_end = std::max(start_delay + active_duration + end_delay, AnimationTimeDelta()); return std::max(std::min(target_effect_end - start_delay, active_duration), @@ -434,7 +434,7 @@ : current_iteration; const double iteration_start = effect.SpecifiedTiming().iteration_start; const AnimationTimeDelta iteration_duration = - effect.SpecifiedTiming().IterationDuration(); + effect.NormalizedTiming().iteration_duration; return iteration_duration * (iteration_boundary - iteration_start); } @@ -832,6 +832,14 @@ previous_active_interpolations_for_animations_.swap( pending_update_.ActiveInterpolationsForAnimations()); + if (!pending_update_.HasUpdates()) { + ClearPendingUpdate(); + return; + } + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) + element->SetNeedsAnimationStyleRecalc(); + for (wtf_size_t paused_index : pending_update_.AnimationIndicesWithPauseToggled()) { CSSAnimation* animation = DynamicTo<CSSAnimation>( @@ -864,6 +872,14 @@ } running_animations_[entry.index]->Update(entry); + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // If the timing was updated, we need to update the animation to get the + // correct result the next time we resolve style. This is not needed + // if CSSIsolatedAnimationUpdates is disabled, since we're "faking" an + // updated animation with InertEffect. + entry.animation->Update(kTimingUpdateOnDemand); + } } const Vector<wtf_size_t>& cancelled_indices = @@ -937,14 +953,37 @@ } } + HashSet<PropertyHandle> suppressed_transitions; + if (!pending_update_.NewTransitions().IsEmpty()) { element->GetDocument() .GetDocumentAnimations() .IncrementTrasitionGeneration(); + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // We generally do not start transitions if there's an animation + // running for the same property. This is mainly handled by + // CanCalculateTransitionUpdateForProperty. However, that function + // will not take into account newly started or newly updated animations, + // hence we need to check against an updated set of affected properties + // from the EffectStack whenever an animation is created/updated. + if (auto* element_animations = element->GetElementAnimations()) { + if (!pending_update_.NewAnimations().IsEmpty() || + !pending_update_.AnimationsWithUpdates().IsEmpty()) { + suppressed_transitions = + element_animations->GetEffectStack().AffectedProperties( + KeyframeEffect::kDefaultPriority); + } + } + } } for (const auto& entry : pending_update_.NewTransitions()) { const CSSAnimationUpdate::NewTransition* new_transition = entry.value; + const PropertyHandle& property = new_transition->property; + + if (suppressed_transitions.Contains(property)) + continue; RunningTransition* running_transition = MakeGarbageCollected<RunningTransition>(); @@ -955,7 +994,6 @@ running_transition->reversing_shortening_factor = new_transition->reversing_shortening_factor; - const PropertyHandle& property = new_transition->property; const InertEffect* inert_animation = new_transition->effect.Get(); TransitionEventDelegate* event_delegate = MakeGarbageCollected<TransitionEventDelegate>(element, property); @@ -985,23 +1023,30 @@ ClearPendingUpdate(); } -void CSSAnimations::CalculateTransitionUpdateForPropertyHandle( +bool CSSAnimations::CanCalculateTransitionUpdateForProperty( TransitionUpdateState& state, - const PropertyHandle& property, - size_t transition_index) { - state.listed_properties.insert(property); - - // FIXME: We should transition if an !important property changes even when an - // animation is running, but this is a bit hard to do with the current - // applyMatchedProperties system. + const PropertyHandle& property) { + // TODO(crbug.com/1226772): We should transition if an !important property + // changes even when an animation is running. if (state.update.ActiveInterpolationsForAnimations().Contains(property) || (state.animating_element.GetElementAnimations() && state.animating_element.GetElementAnimations() ->CssAnimations() .previous_active_interpolations_for_animations_.Contains( property))) { - return; + return false; } + return true; +} + +void CSSAnimations::CalculateTransitionUpdateForPropertyHandle( + TransitionUpdateState& state, + const PropertyHandle& property, + size_t transition_index) { + state.listed_properties.insert(property); + + if (!CanCalculateTransitionUpdateForProperty(state, property)) + return; const RunningTransition* interrupted_transition = nullptr; if (state.active_transitions) { @@ -1424,6 +1469,15 @@ CSSAnimationUpdate& update, const HeapVector<Member<const InertEffect>>* new_animations, const HeapHashSet<Member<const Animation>>* suppressed_animations) { + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // The new/suppressed animations options are not used by + // CSSIsolatedAnimationUpdates. Eventually we want to avoid setting + // that up in the first place, but while this is behind a flag, the least + // intrusive approach is to just nullify here. + new_animations = nullptr; + suppressed_animations = nullptr; + } + ActiveInterpolationsMap interpolations(EffectStack::ActiveInterpolations( effect_stack, new_animations, suppressed_animations, KeyframeEffect::kDefaultPriority, IsCSSPropertyHandle)); @@ -1489,6 +1543,13 @@ } } + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // Eventually we should avoid building these in the first place, + // but for now it's less intrusive to clear them after-the-fact. + new_transitions.clear(); + cancelled_animations.clear(); + } + active_interpolations_for_transitions = EffectStack::ActiveInterpolations( effect_stack, &new_transitions, &cancelled_animations, KeyframeEffect::kTransitionPriority, IsCSSPropertyHandle); @@ -1622,7 +1683,7 @@ if (previous_phase_ == Timing::kPhaseNone) { EnqueueEvent( event_type_names::kTransitionrun, - StartTimeFromDelay(animation_node.SpecifiedTiming().start_delay)); + StartTimeFromDelay(animation_node.NormalizedTiming().start_delay)); } } @@ -1633,14 +1694,14 @@ previous_phase_ == Timing::kPhaseBefore)) { EnqueueEvent( event_type_names::kTransitionstart, - StartTimeFromDelay(animation_node.SpecifiedTiming().start_delay)); + StartTimeFromDelay(animation_node.NormalizedTiming().start_delay)); } else if ((current_phase == Timing::kPhaseActive || current_phase == Timing::kPhaseBefore) && previous_phase_ == Timing::kPhaseAfter) { // If the transition is progressing backwards it is considered to have // started at the end position. EnqueueEvent(event_type_names::kTransitionstart, - animation_node.SpecifiedTiming().IterationDuration()); + animation_node.NormalizedTiming().iteration_duration); } } @@ -1650,7 +1711,7 @@ previous_phase_ == Timing::kPhaseBefore || previous_phase_ == Timing::kPhaseNone)) { EnqueueEvent(event_type_names::kTransitionend, - animation_node.SpecifiedTiming().IterationDuration()); + animation_node.NormalizedTiming().iteration_duration); } else if (current_phase == Timing::kPhaseBefore && (previous_phase_ == Timing::kPhaseActive || previous_phase_ == Timing::kPhaseAfter)) { @@ -1658,7 +1719,7 @@ // ended at the start position. EnqueueEvent( event_type_names::kTransitionend, - StartTimeFromDelay(animation_node.SpecifiedTiming().start_delay)); + StartTimeFromDelay(animation_node.NormalizedTiming().start_delay)); } } @@ -1669,10 +1730,9 @@ // "active time of the animation at the moment it was cancelled, // calculated using a fill mode of both". absl::optional<AnimationTimeDelta> cancel_active_time = - CalculateActiveTime(animation_node.SpecifiedTiming().ActiveDuration(), + CalculateActiveTime(animation_node.NormalizedTiming(), Timing::FillMode::BOTH, - animation_node.LocalTime(), previous_phase_, - animation_node.SpecifiedTiming()); + animation_node.LocalTime(), previous_phase_); // Being the FillMode::BOTH the only possibility to get a null // cancel_active_time is that previous_phase_ is kPhaseNone. This cannot // happen because we know that current_phase == kPhaseNone and
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.h b/third_party/blink/renderer/core/animation/css/css_animations.h index 51edea5d..ccc8b99 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.h +++ b/third_party/blink/renderer/core/animation/css/css_animations.h
@@ -205,6 +205,10 @@ size_t transition_index, const ComputedStyle&); + static bool CanCalculateTransitionUpdateForProperty( + TransitionUpdateState& state, + const PropertyHandle& property); + static void CalculateTransitionUpdateForPropertyHandle( TransitionUpdateState&, const PropertyHandle&,
diff --git a/third_party/blink/renderer/core/animation/document_animations.cc b/third_party/blink/renderer/core/animation/document_animations.cc index 81a1298..6e5b4f9 100644 --- a/third_party/blink/renderer/core/animation/document_animations.cc +++ b/third_party/blink/renderer/core/animation/document_animations.cc
@@ -34,6 +34,7 @@ #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/css/css_scroll_timeline.h" +#include "third_party/blink/renderer/core/animation/element_animations.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/pending_animations.h" #include "third_party/blink/renderer/core/animation/worklet_animation_controller.h" @@ -181,10 +182,40 @@ unvalidated_timelines_.clear(); } +DocumentAnimations::AllowAnimationUpdatesScope::AllowAnimationUpdatesScope( + DocumentAnimations& document_animations, + bool value) + : allow_(&document_animations.allow_animation_updates_, + document_animations.allow_animation_updates_.value_or(true) && + value) {} + +void DocumentAnimations::AddElementWithPendingAnimationUpdate( + Element& element) { + DCHECK(AnimationUpdatesAllowed()); + elements_with_pending_updates_.insert(&element); +} + +void DocumentAnimations::ApplyPendingElementUpdates() { + HeapHashSet<WeakMember<Element>> pending; + std::swap(pending, elements_with_pending_updates_); + + for (auto& element : pending) { + ElementAnimations* element_animations = element->GetElementAnimations(); + if (!element_animations) + continue; + element_animations->CssAnimations().MaybeApplyPendingUpdate(element.Get()); + } + + DCHECK(elements_with_pending_updates_.IsEmpty()) + << "MaybeApplyPendingUpdate must not mark any elements as having a " + "pending update"; +} + void DocumentAnimations::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(timelines_); visitor->Trace(unvalidated_timelines_); + visitor->Trace(elements_with_pending_updates_); } void DocumentAnimations::GetAnimationsTargetingTreeScope(
diff --git a/third_party/blink/renderer/core/animation/document_animations.h b/third_party/blink/renderer/core/animation/document_animations.h index 15754c4e..b57c9b6 100644 --- a/third_party/blink/renderer/core/animation/document_animations.h +++ b/third_party/blink/renderer/core/animation/document_animations.h
@@ -31,6 +31,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATIONS_H_ +#include "base/auto_reset.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/dom/document_lifecycle.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -88,6 +90,40 @@ // https://github.com/w3c/csswg-drafts/issues/5261 void ValidateTimelines(); + // By default, animation updates are *implicitly* disallowed. This object + // can be used to allow or disallow animation updates as follows: + // + // AllowAnimationUpdatesScope(..., true): Allow animation updates, unless + // updates are currently *explicitly* disallowed. + // + // AllowAnimationUpdatesScope(..., false): Explicitly disallow animation + // updates. + class CORE_EXPORT AllowAnimationUpdatesScope { + STACK_ALLOCATED(); + + public: + AllowAnimationUpdatesScope(DocumentAnimations&, bool); + + private: + base::AutoReset<absl::optional<bool>> allow_; + }; + + // Add an element to the set of elements with a pending animation update. + // The elements in the set can be applied later using, + // ApplyPendingElementUpdates. + // + // It's invalid to call this function during if animation updates are not + // allowed (see AnimationUpdatesAllowed). + void AddElementWithPendingAnimationUpdate(Element&); + + // Apply pending updates for any elements previously added during AddElement- + // WithPendingAnimationUpdate + void ApplyPendingElementUpdates(); + + bool AnimationUpdatesAllowed() const { + return allow_animation_updates_.value_or(false); + } + const HeapHashSet<WeakMember<AnimationTimeline>>& GetTimelinesForTesting() const { return timelines_; @@ -99,18 +135,29 @@ uint64_t current_transition_generation_; void Trace(Visitor*) const; +#if DCHECK_IS_ON() + void AssertNoPendingUpdates() { + DCHECK(elements_with_pending_updates_.IsEmpty()); + } +#endif + protected: using ReplaceableAnimationsMap = HeapHashMap<Member<Element>, Member<HeapVector<Member<Animation>>>>; void RemoveReplacedAnimations(ReplaceableAnimationsMap*); private: + friend class AllowAnimationUpdatesScope; + friend class AnimationUpdateScope; + void MarkPendingIfCompositorPropertyAnimationChanges( const PaintArtifactCompositor*); Member<Document> document_; HeapHashSet<WeakMember<AnimationTimeline>> timelines_; HeapHashSet<WeakMember<AnimationTimeline>> unvalidated_timelines_; + HeapHashSet<WeakMember<Element>> elements_with_pending_updates_; + absl::optional<bool> allow_animation_updates_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/document_animations_test.cc b/third_party/blink/renderer/core/animation/document_animations_test.cc index 7dabd7c..16e40802 100644 --- a/third_party/blink/renderer/core/animation/document_animations_test.cc +++ b/third_party/blink/renderer/core/animation/document_animations_test.cc
@@ -142,4 +142,50 @@ EXPECT_EQ(5u, host->MainThreadAnimationsCount()); } +TEST_F(DocumentAnimationsTest, AllowAnimationUpdatesScope) { + DocumentAnimations& document_animations = document->GetDocumentAnimations(); + auto allowed = [&document_animations]() -> bool { + return document_animations.AnimationUpdatesAllowed(); + }; + + using AllowAnimationUpdatesScope = + DocumentAnimations::AllowAnimationUpdatesScope; + + // Implicitly disallowed by default: + EXPECT_FALSE(allowed()); + + { + AllowAnimationUpdatesScope scope(document_animations, true); + EXPECT_TRUE(allowed()); + + { + AllowAnimationUpdatesScope scope(document_animations, true); + EXPECT_TRUE(allowed()); + } + + { + // Disallow explicitly: + AllowAnimationUpdatesScope scope(document_animations, false); + EXPECT_FALSE(allowed()); + + { + // Allowing while explicitly disallowed has no effect: + AllowAnimationUpdatesScope scope(document_animations, true); + EXPECT_FALSE(allowed()); + } + + EXPECT_FALSE(allowed()); + } + + EXPECT_TRUE(allowed()); + } + + { + AllowAnimationUpdatesScope scope(document_animations, false); + EXPECT_FALSE(allowed()); + } + + EXPECT_FALSE(allowed()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/effect_stack.cc b/third_party/blink/renderer/core/animation/effect_stack.cc index 0b5911b..cee21c6 100644 --- a/third_party/blink/renderer/core/animation/effect_stack.cc +++ b/third_party/blink/renderer/core/animation/effect_stack.cc
@@ -140,6 +140,20 @@ return false; } +HashSet<PropertyHandle> EffectStack::AffectedProperties( + KeyframeEffect::Priority priority) const { + HashSet<PropertyHandle> affected; + + for (const auto& sampled_effect : sampled_effects_) { + if (sampled_effect->GetPriority() != priority) + continue; + for (const auto& interpolation : sampled_effect->Interpolations()) + affected.insert(interpolation->GetProperty()); + } + + return affected; +} + bool EffectStack::HasRevert() const { for (const auto& sampled_effect : sampled_effects_) { if (sampled_effect->Effect() && sampled_effect->Effect()->HasRevert())
diff --git a/third_party/blink/renderer/core/animation/effect_stack.h b/third_party/blink/renderer/core/animation/effect_stack.h index 3c58e3be..7a18409f 100644 --- a/third_party/blink/renderer/core/animation/effect_stack.h +++ b/third_party/blink/renderer/core/animation/effect_stack.h
@@ -68,6 +68,8 @@ bool AffectsProperties(PropertyHandleFilter) const; bool AffectsProperties(const CSSBitset&, KeyframeEffect::Priority priority) const; + HashSet<PropertyHandle> AffectedProperties( + KeyframeEffect::Priority priority) const; bool HasRevert() const; // Produces a map of properties to active effects.
diff --git a/third_party/blink/renderer/core/animation/effect_stack_test.cc b/third_party/blink/renderer/core/animation/effect_stack_test.cc index 55d9a0a..ce47be1 100644 --- a/third_party/blink/renderer/core/animation/effect_stack_test.cc +++ b/third_party/blink/renderer/core/animation/effect_stack_test.cc
@@ -287,4 +287,46 @@ KeyframeEffect::kTransitionPriority)); } +TEST_F(AnimationEffectStackTest, AffectedPropertiesDefaultPriority) { + Play(MakeKeyframeEffect(MakeEffectModel(CSSPropertyID::kColor, "red")), 10); + Play(MakeKeyframeEffect(MakeEffectModel(CSSPropertyID::kTop, "1px")), 10); + Play(MakeKeyframeEffect(MakeEffectModel(CSSPropertyID::kLeft, "1px")), 10); + + ASSERT_TRUE(element->GetElementAnimations()); + const EffectStack& effect_stack = + element->GetElementAnimations()->GetEffectStack(); + + EXPECT_TRUE( + effect_stack.AffectedProperties(KeyframeEffect::kTransitionPriority) + .IsEmpty()); + + auto set = effect_stack.AffectedProperties(KeyframeEffect::kDefaultPriority); + ASSERT_EQ(3u, set.size()); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyColor()))); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyTop()))); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyLeft()))); +} + +TEST_F(AnimationEffectStackTest, AffectedPropertiesTransitionPriority) { + Element* body = GetDocument().body(); + body->SetInlineStyleProperty(CSSPropertyID::kTransition, "color 10s"); + body->SetInlineStyleProperty(CSSPropertyID::kColor, "red"); + UpdateAllLifecyclePhasesForTest(); + + body->SetInlineStyleProperty(CSSPropertyID::kColor, "blue"); + UpdateAllLifecyclePhasesForTest(); + + ASSERT_TRUE(body->GetElementAnimations()); + const EffectStack& effect_stack = + body->GetElementAnimations()->GetEffectStack(); + + EXPECT_TRUE(effect_stack.AffectedProperties(KeyframeEffect::kDefaultPriority) + .IsEmpty()); + + auto set = + effect_stack.AffectedProperties(KeyframeEffect::kTransitionPriority); + ASSERT_EQ(1u, set.size()); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyColor()))); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/inert_effect.cc b/third_party/blink/renderer/core/animation/inert_effect.cc index 94a09d8..8a3e492 100644 --- a/third_party/blink/renderer/core/animation/inert_effect.cc +++ b/third_party/blink/renderer/core/animation/inert_effect.cc
@@ -56,7 +56,7 @@ DCHECK(iteration); DCHECK_GE(iteration.value(), 0); model_->Sample(clampTo<int>(iteration.value(), 0), Progress().value(), - SpecifiedTiming().IterationDuration(), result); + NormalizedTiming().iteration_duration, result); } AnimationTimeDelta InertEffect::CalculateTimeToEffectChange(
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.cc b/third_party/blink/renderer/core/animation/keyframe_effect.cc index 87707c6..3b1953b37 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -571,12 +571,12 @@ if (sampled_effect_) { changed = model_->Sample(clampTo<int>(iteration.value(), 0), Progress().value(), - SpecifiedTiming().IterationDuration(), + NormalizedTiming().iteration_duration, sampled_effect_->MutableInterpolations()); } else { HeapVector<Member<Interpolation>> interpolations; model_->Sample(clampTo<int>(iteration.value(), 0), Progress().value(), - SpecifiedTiming().IterationDuration(), interpolations); + NormalizedTiming().iteration_duration, interpolations); if (!interpolations.IsEmpty()) { auto* sampled_effect = MakeGarbageCollected<SampledEffect>(this, owner_->SequenceNumber()); @@ -658,11 +658,14 @@ bool forwards, absl::optional<AnimationTimeDelta> local_time, AnimationTimeDelta time_to_next_iteration) const { - const AnimationTimeDelta start_time = SpecifiedTiming().start_delay; + const AnimationTimeDelta start_time = NormalizedTiming().start_delay; + const AnimationTimeDelta end_time_minus_end_delay = - start_time + SpecifiedTiming().ActiveDuration(); + start_time + NormalizedTiming().active_duration; + const AnimationTimeDelta end_time = - end_time_minus_end_delay + SpecifiedTiming().end_delay; + end_time_minus_end_delay + NormalizedTiming().end_delay; + const AnimationTimeDelta after_time = std::min(end_time_minus_end_delay, end_time);
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc index ad92db4..ea6b1ae 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -426,8 +426,8 @@ // if iteration_duration == "auto" and iterations > 0 if (!timing.iteration_duration && timing.iteration_count > 0) { // duration represents 100% so we divide it by iteration count to - // calculate the iteration duration. Once delays can be percentages - // we will include them in the calculation: + // calculate the iteration duration. TODO: (crbug.com/1216527) Once + // delays can be percentages we will include them in the calculation: // ((100% - start_delay% - end_delay%) / iterations) * duration return duration.value() / timing.iteration_count; }
diff --git a/third_party/blink/renderer/core/animation/timing.cc b/third_party/blink/renderer/core/animation/timing.cc index 1a2221b..5138547f 100644 --- a/third_party/blink/renderer/core/animation/timing.cc +++ b/third_party/blink/renderer/core/animation/timing.cc
@@ -68,30 +68,10 @@ return Timing::FillMode::BOTH; } -AnimationTimeDelta Timing::IterationDuration() const { - AnimationTimeDelta result = - iteration_duration.value_or(intrinsic_iteration_duration); - DCHECK_GE(result, AnimationTimeDelta()); - return result; -} - -AnimationTimeDelta Timing::ActiveDuration() const { - const AnimationTimeDelta result = - MultiplyZeroAlwaysGivesZero(IterationDuration(), iteration_count); - DCHECK_GE(result, AnimationTimeDelta()); - return result; -} - -AnimationTimeDelta Timing::EndTimeInternal() const { - // Per the spec, the end time has a lower bound of 0.0: - // https://drafts.csswg.org/web-animations-1/#end-time - return std::max(start_delay + ActiveDuration() + end_delay, - AnimationTimeDelta()); -} - EffectTiming* Timing::ConvertToEffectTiming() const { EffectTiming* effect_timing = EffectTiming::Create(); + // Specified values used here so that inputs match outputs for JS API calls effect_timing->setDelay(start_delay.InMillisecondsF()); effect_timing->setEndDelay(end_delay.InMillisecondsF()); effect_timing->setFill(FillModeString(fill_mode)); @@ -113,20 +93,14 @@ // Converts values to CSSNumberish based on corresponding timeline type V8CSSNumberish* Timing::ToComputedValue( - absl::optional<AnimationTimeDelta> time) const { + absl::optional<AnimationTimeDelta> time, + absl::optional<AnimationTimeDelta> max_time) const { if (time) { // A valid timeline_duration indicates use of progress based timeline. We - // need to convert values to percentages using EndTimeInternal as 100% - if (timeline_duration) { - // EndTimeInternal() can be zero when using negative start delay that - // effectively negates the active duration of the effect. In such cases, - // we just return a progress of 0. - if (!EndTimeInternal().is_zero()) { - return MakeGarbageCollected<V8CSSNumberish>( - CSSUnitValues::percent((time.value() / EndTimeInternal()) * 100)); - } else { - return MakeGarbageCollected<V8CSSNumberish>(CSSUnitValues::percent(0)); - } + // need to convert values to percentages using timeline_duration as 100% + if (max_time) { + return MakeGarbageCollected<V8CSSNumberish>( + CSSUnitValues::percent((time.value() / max_time.value()) * 100)); } else { // For time based timeline, simply return the value in milliseconds. return MakeGarbageCollected<V8CSSNumberish>( @@ -138,13 +112,17 @@ ComputedEffectTiming* Timing::getComputedTiming( const CalculatedTiming& calculated_timing, + const NormalizedTiming& normalized_timing, bool is_keyframe_effect) const { ComputedEffectTiming* computed_timing = ComputedEffectTiming::Create(); // ComputedEffectTiming members. - computed_timing->setEndTime(ToComputedValue(EndTimeInternal())); - computed_timing->setActiveDuration(ToComputedValue(ActiveDuration())); - computed_timing->setLocalTime(ToComputedValue(calculated_timing.local_time)); + computed_timing->setEndTime(ToComputedValue( + normalized_timing.end_time, normalized_timing.timeline_duration)); + computed_timing->setActiveDuration(ToComputedValue( + normalized_timing.active_duration, normalized_timing.timeline_duration)); + computed_timing->setLocalTime(ToComputedValue( + calculated_timing.local_time, normalized_timing.timeline_duration)); if (calculated_timing.is_in_effect) { DCHECK(calculated_timing.current_iteration); @@ -173,7 +151,9 @@ // TODO(crbug.com/1219008): Animation effect computed iteration_duration // should return CSSNumberish, which will simplify this logic. - V8CSSNumberish* computed_duration = ToComputedValue(IterationDuration()); + V8CSSNumberish* computed_duration = + ToComputedValue(normalized_timing.iteration_duration, + normalized_timing.timeline_duration); if (computed_duration->IsCSSNumericValue()) { computed_timing->setDuration( MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( @@ -195,23 +175,24 @@ Timing::CalculatedTiming Timing::CalculateTimings( absl::optional<AnimationTimeDelta> local_time, absl::optional<Phase> timeline_phase, + const NormalizedTiming& normalized_timing, AnimationDirection animation_direction, bool is_keyframe_effect, absl::optional<double> playback_rate) const { - const AnimationTimeDelta active_duration = ActiveDuration(); + const AnimationTimeDelta active_duration = normalized_timing.active_duration; + const AnimationTimeDelta duration = normalized_timing.iteration_duration; Timing::Phase current_phase = CalculatePhase( - active_duration, local_time, timeline_phase, animation_direction, *this); + normalized_timing, local_time, timeline_phase, animation_direction); - const absl::optional<AnimationTimeDelta> active_time = - CalculateActiveTime(active_duration, ResolvedFillMode(is_keyframe_effect), - local_time, current_phase, *this); + const absl::optional<AnimationTimeDelta> active_time = CalculateActiveTime( + normalized_timing, ResolvedFillMode(is_keyframe_effect), local_time, + current_phase); absl::optional<double> progress; - const absl::optional<double> overall_progress = - CalculateOverallProgress(current_phase, active_time, IterationDuration(), - iteration_count, iteration_start); + const absl::optional<double> overall_progress = CalculateOverallProgress( + current_phase, active_time, duration, iteration_count, iteration_start); const absl::optional<double> simple_iteration_progress = CalculateSimpleIterationProgress(current_phase, overall_progress, iteration_start, active_time, @@ -231,20 +212,19 @@ AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max(); // Conditionally compute the time to next iteration, which is only // applicable if the iteration duration is non-zero. - if (!IterationDuration().is_zero()) { + if (!duration.is_zero()) { const AnimationTimeDelta start_offset = - MultiplyZeroAlwaysGivesZero(IterationDuration(), iteration_start); + MultiplyZeroAlwaysGivesZero(duration, iteration_start); DCHECK_GE(start_offset, AnimationTimeDelta()); const absl::optional<AnimationTimeDelta> offset_active_time = CalculateOffsetActiveTime(active_duration, active_time, start_offset); const absl::optional<AnimationTimeDelta> iteration_time = - CalculateIterationTime(IterationDuration(), active_duration, - offset_active_time, start_offset, current_phase, - *this); + CalculateIterationTime(duration, active_duration, offset_active_time, + start_offset, current_phase, *this); if (iteration_time) { // active_time cannot be null if iteration_time is not null. DCHECK(active_time); - time_to_next_iteration = IterationDuration() - iteration_time.value(); + time_to_next_iteration = duration - iteration_time.value(); if (active_duration - active_time.value() < time_to_next_iteration) time_to_next_iteration = AnimationTimeDelta::Max(); }
diff --git a/third_party/blink/renderer/core/animation/timing.h b/third_party/blink/renderer/core/animation/timing.h index d922dca..4ef4abf7 100644 --- a/third_party/blink/renderer/core/animation/timing.h +++ b/third_party/blink/renderer/core/animation/timing.h
@@ -102,13 +102,6 @@ DCHECK(timing_function); } - // https://drafts.csswg.org/web-animations-1/#iteration-duration - AnimationTimeDelta IterationDuration() const; - - // https://drafts.csswg.org/web-animations-1/#active-duration - AnimationTimeDelta ActiveDuration() const; - AnimationTimeDelta EndTimeInternal() const; - Timing::FillMode ResolvedFillMode(bool is_animation) const; EffectTiming* ConvertToEffectTiming() const; @@ -134,7 +127,8 @@ } bool HasTimingOverrides() { return timing_overrides != kOverrideNode; } - V8CSSNumberish* ToComputedValue(absl::optional<AnimationTimeDelta>) const; + V8CSSNumberish* ToComputedValue(absl::optional<AnimationTimeDelta>, + absl::optional<AnimationTimeDelta>) const; // TODO(crbug.com/1216527): Support CSSNumberish delays AnimationTimeDelta start_delay; @@ -145,10 +139,6 @@ // If empty, indicates the 'auto' value. absl::optional<AnimationTimeDelta> iteration_duration = absl::nullopt; - // A valid timeline_duration indicates use of a progress based timeline. - absl::optional<AnimationTimeDelta> timeline_duration; - AnimationTimeDelta intrinsic_iteration_duration; - PlaybackDirection direction = PlaybackDirection::NORMAL; scoped_refptr<TimingFunction> timing_function = LinearTimingFunction::Shared(); @@ -173,13 +163,31 @@ AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max(); }; + // Normalized values contain specified timing values after normalizing to + // timeline. + struct NormalizedTiming { + DISALLOW_NEW(); + // Value used in normalization math. Stored so that we can convert back if + // needed. + absl::optional<AnimationTimeDelta> timeline_duration; + AnimationTimeDelta start_delay; + AnimationTimeDelta end_delay; + AnimationTimeDelta iteration_duration; + // Calculated as (iteration_duration * iteration_count) + AnimationTimeDelta active_duration; + // Calculated as (start_delay + active_duration + end_delay) + AnimationTimeDelta end_time; + }; + CalculatedTiming CalculateTimings( absl::optional<AnimationTimeDelta> local_time, absl::optional<Phase> timeline_phase, + const NormalizedTiming& normalized_timing, AnimationDirection animation_direction, bool is_keyframe_effect, absl::optional<double> playback_rate) const; ComputedEffectTiming* getComputedTiming(const CalculatedTiming& calculated, + const NormalizedTiming& normalized, bool is_keyframe_effect) const; };
diff --git a/third_party/blink/renderer/core/animation/timing_calculations.h b/third_party/blink/renderer/core/animation/timing_calculations.h index 60b1370..de1059b 100644 --- a/third_party/blink/renderer/core/animation/timing_calculations.h +++ b/third_party/blink/renderer/core/animation/timing_calculations.h
@@ -109,20 +109,18 @@ // https://drafts.csswg.org/web-animations-1/#animation-effect-phases-and-states static inline Timing::Phase CalculatePhase( - AnimationTimeDelta active_duration, + const Timing::NormalizedTiming& normalized, absl::optional<AnimationTimeDelta> local_time, absl::optional<Timing::Phase> timeline_phase, - Timing::AnimationDirection direction, - const Timing& specified) { - DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_duration, + Timing::AnimationDirection direction) { + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(normalized.active_duration, AnimationTimeDelta())); if (!local_time) return Timing::kPhaseNone; - AnimationTimeDelta end_time = - std::max(specified.start_delay + active_duration + specified.end_delay, - AnimationTimeDelta()); + AnimationTimeDelta before_active_boundary_time = - std::max(std::min(specified.start_delay, end_time), AnimationTimeDelta()); + std::max(std::min(normalized.start_delay, normalized.end_time), + AnimationTimeDelta()); if (local_time.value() < before_active_boundary_time || (local_time.value() == before_active_boundary_time && timeline_phase && timeline_phase.value() == Timing::kPhaseBefore) || @@ -131,7 +129,8 @@ return Timing::kPhaseBefore; } AnimationTimeDelta active_after_boundary_time = - std::max(std::min(specified.start_delay + active_duration, end_time), + std::max(std::min(normalized.start_delay + normalized.active_duration, + normalized.end_time), AnimationTimeDelta()); if (local_time > active_after_boundary_time || (local_time.value() == active_after_boundary_time && timeline_phase && @@ -145,33 +144,31 @@ // https://drafts.csswg.org/web-animations/#calculating-the-active-time static inline absl::optional<AnimationTimeDelta> CalculateActiveTime( - AnimationTimeDelta active_duration, + const Timing::NormalizedTiming& normalized, Timing::FillMode fill_mode, absl::optional<AnimationTimeDelta> local_time, - Timing::Phase phase, - const Timing& specified) { - DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_duration, + Timing::Phase phase) { + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(normalized.active_duration, AnimationTimeDelta())); - switch (phase) { case Timing::kPhaseBefore: if (fill_mode == Timing::FillMode::BACKWARDS || fill_mode == Timing::FillMode::BOTH) { DCHECK(local_time.has_value()); - return std::max(local_time.value() - specified.start_delay, + return std::max(local_time.value() - normalized.start_delay, AnimationTimeDelta()); } return absl::nullopt; case Timing::kPhaseActive: DCHECK(local_time.has_value()); - return local_time.value() - specified.start_delay; + return local_time.value() - normalized.start_delay; case Timing::kPhaseAfter: if (fill_mode == Timing::FillMode::FORWARDS || fill_mode == Timing::FillMode::BOTH) { DCHECK(local_time.has_value()); return std::max(AnimationTimeDelta(), - std::min(active_duration, - local_time.value() - specified.start_delay)); + std::min(normalized.active_duration, + local_time.value() - normalized.start_delay)); } return absl::nullopt; case Timing::kPhaseNone:
diff --git a/third_party/blink/renderer/core/animation/timing_calculations_test.cc b/third_party/blink/renderer/core/animation/timing_calculations_test.cc index f07595c..4888dab 100644 --- a/third_party/blink/renderer/core/animation/timing_calculations_test.cc +++ b/third_party/blink/renderer/core/animation/timing_calculations_test.cc
@@ -36,66 +36,60 @@ namespace blink { TEST(AnimationTimingCalculationsTest, ActiveTime) { - Timing timing; + Timing::NormalizedTiming normalized_timing; // calculateActiveTime( // activeDuration, fillMode, localTime, parentPhase, phase, timing) // Before Phase - timing.start_delay = AnimationTimeDelta::FromSecondsD(10); - EXPECT_FALSE(CalculateActiveTime( - AnimationTimeDelta::FromSecondsD(20), Timing::FillMode::FORWARDS, - AnimationTimeDelta(), Timing::kPhaseBefore, timing)); - EXPECT_FALSE(CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::NONE, AnimationTimeDelta(), - Timing::kPhaseBefore, timing)); - EXPECT_EQ( - AnimationTimeDelta(), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::BACKWARDS, AnimationTimeDelta(), - Timing::kPhaseBefore, timing)); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.active_duration = AnimationTimeDelta::FromSecondsD(20); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, + Timing::FillMode::FORWARDS, + AnimationTimeDelta(), Timing::kPhaseBefore)); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, Timing::FillMode::NONE, + AnimationTimeDelta(), Timing::kPhaseBefore)); EXPECT_EQ(AnimationTimeDelta(), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::BOTH, AnimationTimeDelta(), - Timing::kPhaseBefore, timing)); - timing.start_delay = AnimationTimeDelta::FromSecondsD(-10); + CalculateActiveTime(normalized_timing, Timing::FillMode::BACKWARDS, + AnimationTimeDelta(), Timing::kPhaseBefore)); + EXPECT_EQ(AnimationTimeDelta(), + CalculateActiveTime(normalized_timing, Timing::FillMode::BOTH, + AnimationTimeDelta(), Timing::kPhaseBefore)); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(-10); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::BACKWARDS, + CalculateActiveTime(normalized_timing, Timing::FillMode::BACKWARDS, AnimationTimeDelta::FromSecondsD(-5), - Timing::kPhaseBefore, timing)); + Timing::kPhaseBefore)); // Active Phase - timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(10); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::FORWARDS, + CalculateActiveTime(normalized_timing, Timing::FillMode::FORWARDS, AnimationTimeDelta::FromSecondsD(15), - Timing::kPhaseActive, timing)); + Timing::kPhaseActive)); // After Phase - timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.active_duration = AnimationTimeDelta::FromSecondsD(21); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(21), - Timing::FillMode::FORWARDS, + CalculateActiveTime(normalized_timing, Timing::FillMode::FORWARDS, AnimationTimeDelta::FromSecondsD(45), - Timing::kPhaseAfter, timing)); + Timing::kPhaseAfter)); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(21), - Timing::FillMode::BOTH, + CalculateActiveTime(normalized_timing, Timing::FillMode::BOTH, AnimationTimeDelta::FromSecondsD(45), - Timing::kPhaseAfter, timing)); + Timing::kPhaseAfter)); EXPECT_FALSE(CalculateActiveTime( - AnimationTimeDelta::FromSecondsD(21), Timing::FillMode::BACKWARDS, - AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); - EXPECT_FALSE(CalculateActiveTime( - AnimationTimeDelta::FromSecondsD(21), Timing::FillMode::NONE, - AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); + normalized_timing, Timing::FillMode::BACKWARDS, + AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter)); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, Timing::FillMode::NONE, + AnimationTimeDelta::FromSecondsD(45), + Timing::kPhaseAfter)); // None - EXPECT_FALSE(CalculateActiveTime(AnimationTimeDelta::FromSecondsD(32), - Timing::FillMode::NONE, absl::nullopt, - Timing::kPhaseNone, timing)); + normalized_timing.active_duration = AnimationTimeDelta::FromSecondsD(32); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, Timing::FillMode::NONE, + absl::nullopt, Timing::kPhaseNone)); } TEST(AnimationTimingCalculationsTest, OffsetActiveTime) {
diff --git a/third_party/blink/renderer/core/animation/timing_test.cc b/third_party/blink/renderer/core/animation/timing_test.cc index 9ce6f352..fed9dfe 100644 --- a/third_party/blink/renderer/core/animation/timing_test.cc +++ b/third_party/blink/renderer/core/animation/timing_test.cc
@@ -18,8 +18,8 @@ playback_rate < 0 ? Timing::AnimationDirection::kBackwards : Timing::AnimationDirection::kForwards; return timing_.CalculateTimings( - local_time, /*timeline_phase*/ absl::nullopt, animation_direction, - is_keyframe_effect, playback_rate); + local_time, /*timeline_phase*/ absl::nullopt, normalized_timing_, + animation_direction, is_keyframe_effect, playback_rate); } bool IsCurrent(absl::optional<double> local_time, double playback_rate) { absl::optional<AnimationTimeDelta> local_time_delta; @@ -32,9 +32,14 @@ private: void SetUp() override { - timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(1); + normalized_timing_.start_delay = AnimationTimeDelta(); + normalized_timing_.end_delay = AnimationTimeDelta(); + normalized_timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(1); + normalized_timing_.active_duration = AnimationTimeDelta::FromSecondsD(1); + normalized_timing_.end_time = AnimationTimeDelta::FromSecondsD(1); } Timing timing_; + Timing::NormalizedTiming normalized_timing_; }; TEST_F(AnimationTimingTest, IsCurrent) {
diff --git a/third_party/blink/renderer/core/app_history/app_history.cc b/third_party/blink/renderer/core/app_history/app_history.cc index 5ae31b0..1306f428 100644 --- a/third_party/blink/renderer/core/app_history/app_history.cc +++ b/third_party/blink/renderer/core/app_history/app_history.cc
@@ -4,7 +4,12 @@ #include "third_party/blink/renderer/core/app_history/app_history.h" +#include <memory> + #include "third_party/blink/renderer/bindings/core/v8/script_function.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.h" #include "third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 19f0509..01e3ab4 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h" #include "third_party/blink/renderer/core/animation/css/css_animations.h" +#include "third_party/blink/renderer/core/animation/document_animations.h" #include "third_party/blink/renderer/core/animation/element_animations.h" #include "third_party/blink/renderer/core/animation/invalidatable_interpolation.h" #include "third_party/blink/renderer/core/css/container_query_evaluator.h" @@ -116,10 +117,20 @@ // If any changes to CSS Animations were detected, stash the update away for // application after the layout object is updated if we're in the appropriate // scope. - if (!state.AnimationUpdate().IsEmpty()) { - auto& element_animations = element.EnsureElementAnimations(); - element_animations.CssAnimations().SetPendingUpdate( - state.AnimationUpdate()); + if (state.AnimationUpdate().IsEmpty()) + return; + + auto& element_animations = element.EnsureElementAnimations(); + auto& document_animations = state.GetDocument().GetDocumentAnimations(); + + element_animations.CssAnimations().SetPendingUpdate(state.AnimationUpdate()); + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + if (document_animations.AnimationUpdatesAllowed()) { + state.GetDocument() + .GetDocumentAnimations() + .AddElementWithPendingAnimationUpdate(element); + } } }
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.cc b/third_party/blink/renderer/core/document_transition/document_transition.cc index 4a3fc7f..4c52d1a 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition.cc +++ b/third_party/blink/renderer/core/document_transition/document_transition.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/document_transition/document_transition.h" +#include "cc/document_transition/document_transition_request.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_prepare_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_start_options.h"
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.h b/third_party/blink/renderer/core/document_transition/document_transition.h index e40ee37..67a6863 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition.h +++ b/third_party/blink/renderer/core/document_transition/document_transition.h
@@ -5,21 +5,28 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_H_ -#include "cc/document_transition/document_transition_request.h" +#include <memory> + #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/graphics/document_transition_shared_element_id.h" +#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" + +namespace cc { +class DocumentTransitionRequest; +} namespace blink { class Document; class DocumentTransitionPrepareOptions; class DocumentTransitionStartOptions; +class Element; +class ExceptionState; +class ScriptPromise; +class ScriptPromiseResolver; class ScriptState; class CORE_EXPORT DocumentTransition
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_test.cc b/third_party/blink/renderer/core/document_transition/document_transition_test.cc index e87696894..06594b7 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_test.cc +++ b/third_party/blink/renderer/core/document_transition/document_transition_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/document_transition/document_transition.h" #include "base/test/scoped_feature_list.h" +#include "cc/document_transition/document_transition_request.h" #include "third_party/blink/public/web/web_settings.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 836647f7..570b3b3 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2140,10 +2140,26 @@ } void Document::UpdateStyle() { + UpdateStyleInternal(); + DCHECK_EQ(lifecycle_.GetState(), DocumentLifecycle::kStyleClean); + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + GetDocumentAnimations().ApplyPendingElementUpdates(); + if (lifecycle_.GetState() < DocumentLifecycle::kStyleClean) { + DocumentAnimations::AllowAnimationUpdatesScope allow_updates( + GetDocumentAnimations(), false); + UpdateStyleInternal(); + } + } +} + +void Document::UpdateStyleInternal() { DCHECK(!View()->ShouldThrottleRendering()); TRACE_EVENT_BEGIN0("blink,blink_style", "Document::updateStyle"); RUNTIME_CALL_TIMER_SCOPE(V8PerIsolateData::MainThreadIsolate(), RuntimeCallStats::CounterId::kUpdateStyle); + DocumentAnimations::AllowAnimationUpdatesScope allow_updates( + GetDocumentAnimations(), true); unsigned initial_element_count = GetStyleEngine().StyleForElementCount();
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 2ed94a1..535ed22e 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1776,6 +1776,7 @@ void UpdateStyleInvalidationIfNeeded(); void UpdateStyle(); + void UpdateStyleInternal(); void NotifyLayoutTreeOfSubtreeChanges(); bool ChildrenCanHaveStyle() const final;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 601069e..2377822 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2846,9 +2846,12 @@ return nullptr; } - // ResolveStyle() might add active animations so we need to get it again. if (ElementAnimations* element_animations = GetElementAnimations()) { - element_animations->CssAnimations().MaybeApplyPendingUpdate(this); + // With CSSIsolatedAnimationUpdates enabled, animation updates are not + // applied during an Element's style recalc, but during + // Document::UpdateStyle. + if (!RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) + element_animations->CssAnimations().MaybeApplyPendingUpdate(this); element_animations->UpdateAnimationFlags(*style); }
diff --git a/third_party/blink/renderer/core/exported/web_node.cc b/third_party/blink/renderer/core/exported/web_node.cc index 83c35101..137b8fa3 100644 --- a/third_party/blink/renderer/core/exported/web_node.cc +++ b/third_party/blink/renderer/core/exported/web_node.cc
@@ -53,6 +53,7 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/bindings/to_v8.h" namespace blink {
diff --git a/third_party/blink/renderer/core/fetch/bytes_uploader.cc b/third_party/blink/renderer/core/fetch/bytes_uploader.cc index 1cb306e4..eed6dde 100644 --- a/third_party/blink/renderer/core/fetch/bytes_uploader.cc +++ b/third_party/blink/renderer/core/fetch/bytes_uploader.cc
@@ -156,14 +156,21 @@ DVLOG(3) << this << " Close(). total_size=" << total_size_; DCHECK(get_size_callback_); std::move(get_size_callback_).Run(net::OK, total_size_); + consumer_->Cancel(); + Dispose(); } void BytesUploader::CloseOnError() { DVLOG(3) << this << " CloseOnError(). total_size=" << total_size_; - DCHECK(consumer_); - consumer_->Cancel(); DCHECK(get_size_callback_); std::move(get_size_callback_).Run(net::ERR_FAILED, total_size_); + consumer_->Cancel(); + Dispose(); +} + +void BytesUploader::Dispose() { + receiver_.reset(); + upload_pipe_watcher_.Cancel(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/bytes_uploader.h b/third_party/blink/renderer/core/fetch/bytes_uploader.h index 716e2cbc..c5f1d994 100644 --- a/third_party/blink/renderer/core/fetch/bytes_uploader.h +++ b/third_party/blink/renderer/core/fetch/bytes_uploader.h
@@ -24,6 +24,8 @@ : public GarbageCollected<BytesUploader>, public BytesConsumer::Client, public network::mojom::blink::ChunkedDataPipeGetter { + USING_PRE_FINALIZER(BytesUploader, Dispose); + public: BytesUploader( BytesConsumer* consumer, @@ -52,6 +54,8 @@ // TODO(yoichio): Add a string parameter and show it on console. void CloseOnError(); + void Dispose(); + Member<BytesConsumer> consumer_; mojo::Receiver<network::mojom::blink::ChunkedDataPipeGetter> receiver_; mojo::ScopedDataPipeProducerHandle upload_pipe_;
diff --git a/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc b/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc index 1d847e30..88bc060 100644 --- a/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc +++ b/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc
@@ -105,6 +105,7 @@ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting)); EXPECT_CALL(Mock(), BeginRead(_, _)) .WillOnce(Return(BytesConsumer::Result::kDone)); + EXPECT_CALL(Mock(), Cancel()); EXPECT_CALL(get_size_callback, Run(net::OK, 0u)); EXPECT_CALL(checkpoint, Call(3)); @@ -145,6 +146,7 @@ })); EXPECT_CALL(Mock(), EndRead(6u)) .WillOnce(Return(BytesConsumer::Result::kDone)); + EXPECT_CALL(Mock(), Cancel()); EXPECT_CALL(get_size_callback, Run(net::OK, 6u)); EXPECT_CALL(checkpoint, Call(3)); @@ -207,6 +209,7 @@ })); EXPECT_CALL(Mock(), EndRead(2u)) .WillOnce(Return(BytesConsumer::Result::kDone)); + EXPECT_CALL(Mock(), Cancel()); EXPECT_CALL(get_size_callback, Run(net::OK, 12u)); }
diff --git a/third_party/blink/renderer/core/frame/DEPS b/third_party/blink/renderer/core/frame/DEPS index 0f676c48..4a76975d 100644 --- a/third_party/blink/renderer/core/frame/DEPS +++ b/third_party/blink/renderer/core/frame/DEPS
@@ -29,6 +29,7 @@ ], "local_frame_view\.cc": [ "+base/timer/lap_timer.h", + "+cc/document_transition/document_transition_request.h", "+cc/tiles/frame_viewer_instrumentation.h", "+components/paint_preview/common/paint_preview_tracker.h", ],
diff --git a/third_party/blink/renderer/core/frame/build.gni b/third_party/blink/renderer/core/frame/build.gni index 794e557..c27f419 100644 --- a/third_party/blink/renderer/core/frame/build.gni +++ b/third_party/blink/renderer/core/frame/build.gni
@@ -97,6 +97,8 @@ "local_frame.cc", "local_frame.h", "local_frame_client.h", + "local_frame_mojo_receiver.cc", + "local_frame_mojo_receiver.h", "local_frame_ukm_aggregator.cc", "local_frame_ukm_aggregator.h", "local_frame_view.cc",
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h index 5ce7bc9..ecc1409e 100644 --- a/third_party/blink/renderer/core/frame/frame.h +++ b/third_party/blink/renderer/core/frame/frame.h
@@ -228,6 +228,12 @@ return lifecycle_.GetState() == FrameLifecycle::kAttached; } + // Note that IsAttached() and IsDetached() are not strict opposites: frames + // that are detaching are considered to be in neither state. + bool IsDetached() const { + return lifecycle_.GetState() == FrameLifecycle::kDetached; + } + // Whether the frame is considered to be an ad subframe by Ad Tagging. Returns // true for both root and child ad subframes. virtual bool IsAdSubframe() const = 0; @@ -395,12 +401,6 @@ // See `Detach()` for more information. virtual bool DetachImpl(FrameDetachType) = 0; - // Note that IsAttached() and IsDetached() are not strict opposites: frames - // that are detaching are considered to be in neither state. - bool IsDetached() const { - return lifecycle_.GetState() == FrameLifecycle::kDetached; - } - virtual void DidChangeVisibleToHitTesting() = 0; void FocusImpl();
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 3ee5e688..e1b721c 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -115,6 +115,7 @@ #include "third_party/blink/renderer/core/frame/intervention.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" +#include "third_party/blink/renderer/core/frame/local_frame_mojo_receiver.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h" #include "third_party/blink/renderer/core/frame/pausable_script_executor.h" @@ -134,7 +135,6 @@ #include "third_party/blink/renderer/core/frame/web_frame_widget_impl.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/frame/window_controls_overlay.h" -#include "third_party/blink/renderer/core/fullscreen/fullscreen.h" #include "third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h" #include "third_party/blink/renderer/core/html/html_frame_element_base.h" #include "third_party/blink/renderer/core/html/html_link_element.h" @@ -409,43 +409,6 @@ const Deque<SerializedResource> resources_; }; -class ActiveURLMessageFilter : public mojo::MessageFilter { - public: - explicit ActiveURLMessageFilter(LocalFrame* local_frame) - : local_frame_(local_frame) {} - - ~ActiveURLMessageFilter() override { - if (debug_url_set_) { - Platform::Current()->SetActiveURL(WebURL(), WebString()); - } - } - - // mojo::MessageFilter overrides. - bool WillDispatch(mojo::Message* message) override { - // We expect local_frame_ always to be set because this MessageFilter - // is owned by the LocalFrame. We do not want to introduce a Persistent - // reference so we don't cause a cycle. If you hit this CHECK then you - // likely didn't reset your mojo receiver in Detach. - CHECK(local_frame_); - debug_url_set_ = true; - Platform::Current()->SetActiveURL(local_frame_->GetDocument()->Url(), - local_frame_->Top() - ->GetSecurityContext() - ->GetSecurityOrigin() - ->ToString()); - return true; - } - - void DidDispatchOrReject(mojo::Message* message, bool accepted) override { - Platform::Current()->SetActiveURL(WebURL(), WebString()); - debug_url_set_ = false; - } - - private: - WeakPersistent<LocalFrame> local_frame_; - bool debug_url_set_ = false; -}; - v8::Local<v8::Context> MainWorldScriptContext(LocalFrame* local_frame) { ScriptState* script_state = ToScriptStateForMainWorld(local_frame); DCHECK(script_state); @@ -530,18 +493,13 @@ GetTaskRunner(blink::TaskType::kInternalDefault))); GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating( &LocalFrame::BindToReceiver, WrapWeakPersistent(this))); - GetInterfaceRegistry()->AddInterface( - WTF::BindRepeating(&LocalFrame::BindToHighPriorityReceiver, - WrapWeakPersistent(this)), - GetTaskRunner(blink::TaskType::kInternalHighPriorityLocalFrame)); - GetInterfaceRegistry()->AddAssociatedInterface( - WTF::BindRepeating(&LocalFrame::BindFullscreenVideoElementReceiver, - WrapWeakPersistent(this))); if (IsMainFrame()) { GetInterfaceRegistry()->AddInterface(WTF::BindRepeating( &LocalFrame::BindTextFragmentReceiver, WrapWeakPersistent(this))); } + DCHECK(!mojo_receiver_); + mojo_receiver_ = MakeGarbageCollected<LocalFrameMojoReceiver>(*this); SetOpenerDoNotNotify(opener); loader_.Init(std::move(policy_container)); @@ -639,8 +597,7 @@ visitor->Trace(back_forward_cache_controller_host_remote_); visitor->Trace(receiver_); visitor->Trace(main_frame_receiver_); - visitor->Trace(high_priority_frame_receiver_); - visitor->Trace(fullscreen_video_receiver_); + visitor->Trace(mojo_receiver_); visitor->Trace(text_fragment_handler_); visitor->Trace(saved_scroll_offsets_); visitor->Trace(background_color_paint_image_generator_); @@ -871,7 +828,7 @@ frame_scheduler_.reset(); receiver_.reset(); main_frame_receiver_.reset(); - high_priority_frame_receiver_.reset(); + mojo_receiver_->DidDetachFrame(); WeakIdentifierMap<LocalFrame>::NotifyObjectDestroyed(this); return true; @@ -3212,23 +3169,6 @@ } } -void LocalFrame::RequestFullscreenVideoElement() { - // Find the first video element of the frame. - for (auto* child = GetDocument()->documentElement(); child; - child = Traversal<HTMLElement>::Next(*child)) { - if (IsA<HTMLVideoElement>(child)) { - // This is always initiated from browser side (which should require the - // user interacting with ui) which suffices for a user gesture even though - // there will have been no input to the frame at this point. - NotifyUserActivation( - mojom::blink::UserActivationNotificationType::kInteraction); - - Fullscreen::RequestFullscreen(*child); - return; - } - } -} - HitTestResult LocalFrame::HitTestResultForVisualViewportPos( const IntPoint& pos_in_viewport) { IntPoint root_frame_point( @@ -3532,11 +3472,6 @@ before_unload_end_time); } -void LocalFrame::DispatchBeforeUnload(bool is_reload, - BeforeUnloadCallback callback) { - BeforeUnload(is_reload, std::move(callback)); -} - void LocalFrame::MediaPlayerActionAtViewportPoint( const IntPoint& viewport_position, const blink::mojom::blink::MediaPlayerActionType type, @@ -4123,30 +4058,6 @@ std::make_unique<ActiveURLMessageFilter>(frame)); } -void LocalFrame::BindToHighPriorityReceiver( - mojo::PendingReceiver<mojom::blink::HighPriorityLocalFrame> receiver) { - if (IsDetached()) - return; - - high_priority_frame_receiver_.Bind( - std::move(receiver), - GetTaskRunner(blink::TaskType::kInternalHighPriorityLocalFrame)); - high_priority_frame_receiver_.SetFilter( - std::make_unique<ActiveURLMessageFilter>(this)); -} - -void LocalFrame::BindFullscreenVideoElementReceiver( - mojo::PendingAssociatedReceiver<mojom::blink::FullscreenVideoElementHandler> - receiver) { - if (IsDetached()) - return; - - fullscreen_video_receiver_.Bind( - std::move(receiver), GetTaskRunner(blink::TaskType::kInternalDefault)); - fullscreen_video_receiver_.SetFilter( - std::make_unique<ActiveURLMessageFilter>(this)); -} - void LocalFrame::BindTextFragmentReceiver( mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> receiver) { if (IsDetached() || !text_fragment_handler_)
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 4f88528..76ff1458 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -50,7 +50,6 @@ #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h" #include "third_party/blink/public/mojom/link_to_text/link_to_text.mojom-blink-forward.h" #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink-forward.h" -#include "third_party/blink/public/mojom/media/fullscreen_video_element.mojom-blink.h" #include "third_party/blink/public/mojom/optimization_guide/optimization_guide.mojom-blink.h" #include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink-forward.h" @@ -119,6 +118,7 @@ class LocalDOMWindow; class LocalWindowProxy; class LocalFrameClient; +class LocalFrameMojoReceiver; class BackgroundColorPaintImageGenerator; class ClipPathPaintImageGenerator; class Node; @@ -142,14 +142,11 @@ extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<LocalFrame>; // A LocalFrame is a frame hosted inside this process. -class CORE_EXPORT LocalFrame final - : public Frame, - public FrameScheduler::Delegate, - public Supplementable<LocalFrame>, - public mojom::blink::LocalFrame, - public mojom::blink::LocalMainFrame, - public mojom::blink::FullscreenVideoElementHandler, - public mojom::blink::HighPriorityLocalFrame { +class CORE_EXPORT LocalFrame final : public Frame, + public FrameScheduler::Delegate, + public Supplementable<LocalFrame>, + public mojom::blink::LocalFrame, + public mojom::blink::LocalMainFrame { public: // Returns the LocalFrame instance for the given |frame_token|. static LocalFrame* FromFrameToken(const LocalFrameToken& frame_token); @@ -657,8 +654,6 @@ mojom::blink::ResourceTimingInfoPtr timing, const String& server_timing_values) final; void BeforeUnload(bool is_reload, BeforeUnloadCallback callback) final; - void DispatchBeforeUnload(bool is_reload, - BeforeUnloadCallback callback) final; void MediaPlayerActionAt( const gfx::Point& window_point, blink::mojom::blink::MediaPlayerActionPtr action) final; @@ -766,9 +761,6 @@ bool animate) override; void UpdateWindowControlsOverlay(const gfx::Rect& bounding_rect_in_dips); - // mojom::FullscreenVideoElementHandler implementation: - void RequestFullscreenVideoElement() final; - SystemClipboard* GetSystemClipboard(); RawSystemClipboard* GetRawSystemClipboard(); @@ -944,11 +936,6 @@ static void BindToMainFrameReceiver( blink::LocalFrame* frame, mojo::PendingAssociatedReceiver<mojom::blink::LocalMainFrame> receiver); - void BindToHighPriorityReceiver( - mojo::PendingReceiver<mojom::blink::HighPriorityLocalFrame> receiver); - void BindFullscreenVideoElementReceiver( - mojo::PendingAssociatedReceiver< - mojom::blink::FullscreenVideoElementHandler> receiver); void BindTextFragmentReceiver( mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> receiver); @@ -1076,13 +1063,9 @@ // LocalFrame can be reused by multiple ExecutionContext. HeapMojoAssociatedReceiver<mojom::blink::LocalMainFrame, LocalFrame> main_frame_receiver_{this, nullptr}; - // LocalFrame can be reused by multiple ExecutionContext. - HeapMojoReceiver<mojom::blink::HighPriorityLocalFrame, LocalFrame> - high_priority_frame_receiver_{this, nullptr}; - // LocalFrame can be reused by multiple ExecutionContext. - HeapMojoAssociatedReceiver<mojom::blink::FullscreenVideoElementHandler, - LocalFrame> - fullscreen_video_receiver_{this, nullptr}; + // TODO(crbug.com/1227229): Move the above HeapMojoReceivers to + // LocalFrameMojoReceiver. + Member<LocalFrameMojoReceiver> mojo_receiver_; // Variable to control burst of download requests. int num_burst_download_requests_ = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_receiver.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_receiver.cc new file mode 100644 index 0000000..efbe6be5 --- /dev/null +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_receiver.cc
@@ -0,0 +1,116 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/frame/local_frame_mojo_receiver.h" + +#include "third_party/blink/public/platform/interface_registry.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/core/dom/element_traversal.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/fullscreen/fullscreen.h" +#include "third_party/blink/renderer/core/html/html_element.h" +#include "third_party/blink/renderer/core/html/media/html_video_element.h" + +namespace blink { + +ActiveURLMessageFilter::~ActiveURLMessageFilter() { + if (debug_url_set_) { + Platform::Current()->SetActiveURL(WebURL(), WebString()); + } +} + +bool ActiveURLMessageFilter::WillDispatch(mojo::Message* message) { + // We expect local_frame_ always to be set because this MessageFilter + // is owned by the LocalFrame. We do not want to introduce a Persistent + // reference so we don't cause a cycle. If you hit this CHECK then you + // likely didn't reset your mojo receiver in Detach. + CHECK(local_frame_); + debug_url_set_ = true; + Platform::Current()->SetActiveURL(local_frame_->GetDocument()->Url(), + local_frame_->Top() + ->GetSecurityContext() + ->GetSecurityOrigin() + ->ToString()); + return true; +} + +void ActiveURLMessageFilter::DidDispatchOrReject(mojo::Message* message, + bool accepted) { + Platform::Current()->SetActiveURL(WebURL(), WebString()); + debug_url_set_ = false; +} + +LocalFrameMojoReceiver::LocalFrameMojoReceiver(LocalFrame& frame) + : frame_(frame) { + auto* registry = frame.GetInterfaceRegistry(); + registry->AddInterface( + WTF::BindRepeating(&LocalFrameMojoReceiver::BindToHighPriorityReceiver, + WrapWeakPersistent(this)), + frame.GetTaskRunner(TaskType::kInternalHighPriorityLocalFrame)); + registry->AddAssociatedInterface(WTF::BindRepeating( + &LocalFrameMojoReceiver::BindFullscreenVideoElementReceiver, + WrapWeakPersistent(this))); +} + +void LocalFrameMojoReceiver::Trace(Visitor* visitor) const { + visitor->Trace(frame_); + visitor->Trace(high_priority_frame_receiver_); + visitor->Trace(fullscreen_video_receiver_); +} + +void LocalFrameMojoReceiver::DidDetachFrame() { + // We reset receivers explicitly because HeapMojoReceiver does not + // automatically reset on context destruction. + high_priority_frame_receiver_.reset(); + // TODO(tkent): Should we reset other receivers? +} + +void LocalFrameMojoReceiver::BindToHighPriorityReceiver( + mojo::PendingReceiver<mojom::blink::HighPriorityLocalFrame> receiver) { + if (frame_->IsDetached()) + return; + + high_priority_frame_receiver_.Bind( + std::move(receiver), + frame_->GetTaskRunner(TaskType::kInternalHighPriorityLocalFrame)); + high_priority_frame_receiver_.SetFilter( + std::make_unique<ActiveURLMessageFilter>(frame_)); +} + +void LocalFrameMojoReceiver::BindFullscreenVideoElementReceiver( + mojo::PendingAssociatedReceiver<mojom::blink::FullscreenVideoElementHandler> + receiver) { + if (frame_->IsDetached()) + return; + + fullscreen_video_receiver_.Bind( + std::move(receiver), frame_->GetTaskRunner(TaskType::kInternalDefault)); + fullscreen_video_receiver_.SetFilter( + std::make_unique<ActiveURLMessageFilter>(frame_)); +} + +void LocalFrameMojoReceiver::DispatchBeforeUnload( + bool is_reload, + mojom::blink::LocalFrame::BeforeUnloadCallback callback) { + frame_->BeforeUnload(is_reload, std::move(callback)); +} + +void LocalFrameMojoReceiver::RequestFullscreenVideoElement() { + // Find the first video element of the frame. + for (auto* child = frame_->GetDocument()->documentElement(); child; + child = Traversal<HTMLElement>::Next(*child)) { + if (IsA<HTMLVideoElement>(child)) { + // This is always initiated from browser side (which should require the + // user interacting with ui) which suffices for a user gesture even though + // there will have been no input to the frame at this point. + frame_->NotifyUserActivation( + mojom::blink::UserActivationNotificationType::kInteraction); + + Fullscreen::RequestFullscreen(*child); + return; + } + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_receiver.h b/third_party/blink/renderer/core/frame/local_frame_mojo_receiver.h new file mode 100644 index 0000000..f50d34c --- /dev/null +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_receiver.h
@@ -0,0 +1,76 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_FRAME_MOJO_RECEIVER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_FRAME_MOJO_RECEIVER_H_ + +#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h" +#include "third_party/blink/public/mojom/media/fullscreen_video_element.mojom-blink.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" + +namespace blink { + +class LocalFrame; + +// LocalFrameMojoReceiver is responsible for providing Mojo receivers +// associated to blink::LocalFrame. +// +// A single LocalFrame instance owns a single LocalFrameMojoReceiver instance. +class LocalFrameMojoReceiver + : public GarbageCollected<LocalFrameMojoReceiver>, + public mojom::blink::HighPriorityLocalFrame, + public mojom::blink::FullscreenVideoElementHandler { + public: + explicit LocalFrameMojoReceiver(LocalFrame& frame); + void Trace(Visitor* visitor) const; + + void DidDetachFrame(); + + private: + void BindToHighPriorityReceiver( + mojo::PendingReceiver<mojom::blink::HighPriorityLocalFrame> receiver); + void BindFullscreenVideoElementReceiver( + mojo::PendingAssociatedReceiver< + mojom::blink::FullscreenVideoElementHandler> receiver); + + // mojom::blink::HighPriorityLocalFrame implementation: + void DispatchBeforeUnload( + bool is_reload, + mojom::blink::LocalFrame::BeforeUnloadCallback callback) final; + + // mojom::FullscreenVideoElementHandler implementation: + void RequestFullscreenVideoElement() final; + + Member<LocalFrame> frame_; + + // LocalFrameMojoReceiver can be reused by multiple ExecutionContext. + HeapMojoReceiver<mojom::blink::HighPriorityLocalFrame, LocalFrameMojoReceiver> + high_priority_frame_receiver_{this, nullptr}; + // LocalFrameMojoReceiver can be reused by multiple ExecutionContext. + HeapMojoAssociatedReceiver<mojom::blink::FullscreenVideoElementHandler, + LocalFrameMojoReceiver> + fullscreen_video_receiver_{this, nullptr}; +}; + +class ActiveURLMessageFilter : public mojo::MessageFilter { + public: + explicit ActiveURLMessageFilter(LocalFrame* local_frame) + : local_frame_(local_frame) {} + + ~ActiveURLMessageFilter() override; + + // mojo::MessageFilter overrides. + bool WillDispatch(mojo::Message* message) override; + void DidDispatchOrReject(mojo::Message* message, bool accepted) override; + + private: + WeakPersistent<LocalFrame> local_frame_; + bool debug_url_set_ = false; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_FRAME_MOJO_RECEIVER_H_
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 014d070..e4d8388 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -37,6 +37,7 @@ #include "base/numerics/safe_conversions.h" #include "base/timer/lap_timer.h" #include "cc/animation/animation_host.h" +#include "cc/document_transition/document_transition_request.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/picture_layer.h" #include "cc/tiles/frame_viewer_instrumentation.h" @@ -3273,6 +3274,7 @@ if (did_layout) GetLayoutView()->AssertSubtreeIsLaidOut(); } + frame_->GetDocument()->GetDocumentAnimations().AssertNoPendingUpdates(); #endif if (did_layout) {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc b/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc index 932a700..4b1fa07 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc
@@ -74,7 +74,7 @@ RenderingContextDescriptionCodec::RenderingContextDescriptionCodec( const CanvasRenderingContext* context) { - is_valid_ = context->Host() && context->Host()->ResourceProvider(); + is_valid_ = context->Host(); if (!is_valid_) return;
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.h b/third_party/blink/renderer/core/html/media/html_video_element.h index 0cca98d..4296694 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.h +++ b/third_party/blink/renderer/core/html/media/html_video_element.h
@@ -34,7 +34,6 @@ #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" -#include "third_party/khronos/GLES2/gl2.h" namespace blink { class ImageBitmapOptions;
diff --git a/third_party/blink/renderer/core/input/gesture_manager.cc b/third_party/blink/renderer/core/input/gesture_manager.cc index 62856d58..e61f1db 100644 --- a/third_party/blink/renderer/core/input/gesture_manager.cc +++ b/third_party/blink/renderer/core/input/gesture_manager.cc
@@ -328,8 +328,11 @@ click_event_result); if (RuntimeEnabledFeatures::TextFragmentTapOpensContextMenuEnabled() && - TextFragmentHandler::IsOverTextFragment(current_hit_test)) { - if (event_result == WebInputEventResult::kNotHandled) { + current_hit_test.InnerNodeFrame()) { + current_hit_test.InnerNodeFrame()->View()->UpdateLifecycleToPrePaintClean( + DocumentUpdateReason::kHitTest); + if (TextFragmentHandler::IsOverTextFragment(current_hit_test) && + event_result == WebInputEventResult::kNotHandled) { return SendContextMenuEventForGesture(targeted_event); } }
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc index c32f6c4..7edd19f 100644 --- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
@@ -56,9 +56,7 @@ /*default_value=*/WTF::String()), locale_override_(&agent_state_, /*default_value=*/WTF::String()), virtual_time_budget_(&agent_state_, /*default_value*/ 0.0), - virtual_time_budget_initial_offset_(&agent_state_, /*default_value=*/0.0), initial_virtual_time_(&agent_state_, /*default_value=*/0.0), - virtual_time_offset_(&agent_state_, /*default_value=*/0.0), virtual_time_policy_(&agent_state_, /*default_value=*/WTF::String()), virtual_time_task_starvation_count_(&agent_state_, /*default_value=*/0), wait_for_navigation_(&agent_state_, /*default_value=*/false), @@ -124,11 +122,6 @@ if (virtual_time_policy_.Get().IsNull()) return; - // Tell the scheduler about the saved virtual time progress to ensure that - // virtual time monotonically advances despite the cross origin navigation. - // This should be done regardless of the virtual time mode. - web_local_frame_->View()->Scheduler()->SetInitialVirtualTimeOffset( - base::TimeDelta::FromMillisecondsD(virtual_time_offset_.Get())); // Preserve wait for navigation in all modes. bool wait_for_navigation = wait_for_navigation_.Get(); @@ -147,9 +140,7 @@ } // Calculate remaining budget for the advancing modes. - double budget_remaining = virtual_time_budget_.Get() + - virtual_time_budget_initial_offset_.Get() - - virtual_time_offset_.Get(); + double budget_remaining = virtual_time_budget_.Get(); DCHECK_GE(budget_remaining, 0); setVirtualTimePolicy(virtual_time_policy_.Get(), budget_remaining, @@ -376,9 +367,6 @@ if (virtual_time_budget_ms.isJust()) { new_policy.virtual_time_budget_ms = virtual_time_budget_ms.fromJust(); virtual_time_budget_.Set(*new_policy.virtual_time_budget_ms); - // Record the current virtual time offset so Restore can compute how much - // budget is left. - virtual_time_budget_initial_offset_.Set(virtual_time_offset_.Get()); } else { virtual_time_budget_.Clear(); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h index c2cd8f28..8e0335f 100644 --- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h
@@ -151,9 +151,7 @@ InspectorAgentState::String accept_language_override_; InspectorAgentState::String locale_override_; InspectorAgentState::Double virtual_time_budget_; - InspectorAgentState::Double virtual_time_budget_initial_offset_; InspectorAgentState::Double initial_virtual_time_; - InspectorAgentState::Double virtual_time_offset_; InspectorAgentState::String virtual_time_policy_; InspectorAgentState::Integer virtual_time_task_starvation_count_; InspectorAgentState::Boolean wait_for_navigation_;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc index 9c1f8485..fd9b617 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
@@ -74,12 +74,10 @@ HeapVector<Member<IntersectionObservation>> observations_to_process; CopyToVector(tracked_implicit_root_observations_, observations_to_process); { - // TODO(pdr): This has been temporarily disabled to investigate the effect - // on metrics and should be re-enabled. See: https://crbug.com/1215345. - // LocalFrameUkmAggregator::IterativeTimer ukm_timer(ukm_aggregator); + LocalFrameUkmAggregator::IterativeTimer ukm_timer(ukm_aggregator); for (auto& observer : observers_to_process) { if (observer->HasObservations()) { - // ukm_timer.StartInterval(observer->GetUkmMetricId()); + ukm_timer.StartInterval(observer->GetUkmMetricId()); needs_occlusion_tracking_ |= observer->ComputeIntersections(flags, monotonic_time); } else { @@ -87,7 +85,7 @@ } } for (auto& observation : observations_to_process) { - // ukm_timer.StartInterval(observation->Observer()->GetUkmMetricId()); + ukm_timer.StartInterval(observation->Observer()->GetUkmMetricId()); observation->ComputeIntersection(flags, monotonic_time); needs_occlusion_tracking_ |= observation->Observer()->trackVisibility(); }
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc index dad70ce..dc95b3a 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h" #include "third_party/blink/renderer/core/dom/dom_exception.h"
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc index 9609cd0..99b9cbf 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h" #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h"
diff --git a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc index 3cb3d8dd..6cbce0f 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
@@ -17,6 +17,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h" +#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" namespace blink {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc index 9f2ce1e..6644bc94 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -438,49 +438,8 @@ LayoutUnit block_offset = line_info->BfcOffset().block_offset; if (Node().HasRuby()) { - NGAnnotationMetrics annotation_metrics = ComputeAnnotationOverflow( - *line_box, line_box_metrics, LayoutUnit(), line_info->LineStyle()); - LayoutUnit annotation_overflow_block_start; - LayoutUnit annotation_overflow_block_end; - LayoutUnit annotation_space_block_start; - LayoutUnit annotation_space_block_end; - if (!IsFlippedLinesWritingMode(line_info->LineStyle().GetWritingMode())) { - annotation_overflow_block_start = annotation_metrics.overflow_over; - annotation_overflow_block_end = annotation_metrics.overflow_under; - annotation_space_block_start = annotation_metrics.space_over; - annotation_space_block_end = annotation_metrics.space_under; - } else { - annotation_overflow_block_start = annotation_metrics.overflow_under; - annotation_overflow_block_end = annotation_metrics.overflow_over; - annotation_space_block_start = annotation_metrics.space_under; - annotation_space_block_end = annotation_metrics.space_over; - } - - LayoutUnit block_offset_shift = annotation_overflow_block_start; - // If the previous line has block-end annotation overflow and this line has - // block-start annotation space, shift up the block offset of this line. - if (ConstraintSpace().BlockStartAnnotationSpace() < LayoutUnit() && - annotation_space_block_start) { - const LayoutUnit overflow = - -ConstraintSpace().BlockStartAnnotationSpace(); - block_offset_shift = -std::min(annotation_space_block_start, overflow); - } - - // If this line has block-start annotation overflow and the previous line - // has block-end annotation space, borrow the block-end space of the - // previous line and shift down the block offset by |overflow - space|. - if (annotation_overflow_block_start && - ConstraintSpace().BlockStartAnnotationSpace() > LayoutUnit()) { - block_offset_shift = (annotation_overflow_block_start - - ConstraintSpace().BlockStartAnnotationSpace()) - .ClampNegativeToZero(); - } - block_offset += block_offset_shift; - - if (annotation_overflow_block_end) - container_builder_.SetAnnotationOverflow(annotation_overflow_block_end); - else if (annotation_space_block_end) - container_builder_.SetBlockEndAnnotationSpace(annotation_space_block_end); + block_offset += + SetAnnotationOverflow(*line_info, *line_box, line_box_metrics); } if (line_info->UseFirstLineStyle()) @@ -969,6 +928,55 @@ return LineOffsetForTextAlign(text_align, line_info->BaseDirection(), space); } +LayoutUnit NGInlineLayoutAlgorithm::SetAnnotationOverflow( + const NGLineInfo& line_info, + const NGLogicalLineItems& line_box, + const FontHeight& line_box_metrics) { + NGAnnotationMetrics annotation_metrics = ComputeAnnotationOverflow( + line_box, line_box_metrics, LayoutUnit(), line_info.LineStyle()); + LayoutUnit annotation_overflow_block_start; + LayoutUnit annotation_overflow_block_end; + LayoutUnit annotation_space_block_start; + LayoutUnit annotation_space_block_end; + if (!IsFlippedLinesWritingMode(line_info.LineStyle().GetWritingMode())) { + annotation_overflow_block_start = annotation_metrics.overflow_over; + annotation_overflow_block_end = annotation_metrics.overflow_under; + annotation_space_block_start = annotation_metrics.space_over; + annotation_space_block_end = annotation_metrics.space_under; + } else { + annotation_overflow_block_start = annotation_metrics.overflow_under; + annotation_overflow_block_end = annotation_metrics.overflow_over; + annotation_space_block_start = annotation_metrics.space_under; + annotation_space_block_end = annotation_metrics.space_over; + } + + LayoutUnit block_offset_shift = annotation_overflow_block_start; + // If the previous line has block-end annotation overflow and this line has + // block-start annotation space, shift up the block offset of this line. + if (ConstraintSpace().BlockStartAnnotationSpace() < LayoutUnit() && + annotation_space_block_start) { + const LayoutUnit overflow = -ConstraintSpace().BlockStartAnnotationSpace(); + block_offset_shift = -std::min(annotation_space_block_start, overflow); + } + + // If this line has block-start annotation overflow and the previous line + // has block-end annotation space, borrow the block-end space of the + // previous line and shift down the block offset by |overflow - space|. + if (annotation_overflow_block_start && + ConstraintSpace().BlockStartAnnotationSpace() > LayoutUnit()) { + block_offset_shift = (annotation_overflow_block_start - + ConstraintSpace().BlockStartAnnotationSpace()) + .ClampNegativeToZero(); + } + + if (annotation_overflow_block_end) + container_builder_.SetAnnotationOverflow(annotation_overflow_block_end); + else if (annotation_space_block_end) + container_builder_.SetBlockEndAnnotationSpace(annotation_space_block_end); + + return block_offset_shift; +} + LayoutUnit NGInlineLayoutAlgorithm::ComputeContentSize( const NGLineInfo& line_info, const NGExclusionSpace& exclusion_space,
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h index 78875b5..9e9ca7d 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
@@ -121,6 +121,10 @@ const NGExclusionSpace&, LayoutUnit line_height); + LayoutUnit SetAnnotationOverflow(const NGLineInfo& line_info, + const NGLogicalLineItems& line_box, + const FontHeight& line_box_metrics); + NGInlineLayoutStateStack* box_states_; NGInlineChildLayoutContext* context_;
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc index 6c12fe87..a8ade0d8 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -652,8 +652,12 @@ // If there is a text fragment at the same location as the click indicate that // the context menu is being opened from an existing highlight. - if (TextFragmentHandler::IsOverTextFragment(result)) { - data.opened_from_highlight = true; + if (result.InnerNodeFrame()) { + result.InnerNodeFrame()->View()->UpdateLifecycleToPrePaintClean( + DocumentUpdateReason::kHitTest); + if (TextFragmentHandler::IsOverTextFragment(result)) { + data.opened_from_highlight = true; + } } if (result.IsContentEditable()) {
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc index 266ff3dc..db00e4810 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
@@ -95,17 +95,27 @@ 0, WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now()); event.SetFrameScale(1); - GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event); + WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting( + WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing()); + } + + void SimulateRightClick(int x, int y) { + WebMouseEvent event(WebInputEvent::Type::kMouseDown, gfx::PointF(x, y), + gfx::PointF(x, y), WebPointerProperties::Button::kRight, + 0, WebInputEvent::Modifiers::kLeftButtonDown, + base::TimeTicks::Now()); + event.SetFrameScale(1); + WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting( + WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing()); } void SimulateTap(int x, int y) { - WebGestureEvent event(WebInputEvent::Type::kGestureTap, - WebInputEvent::kNoModifiers, base::TimeTicks::Now(), - WebGestureDevice::kTouchscreen); - event.SetPositionInWidget(gfx::PointF(x, y)); - event.SetPositionInScreen(gfx::PointF(x, y)); - event.SetFrameScale(1); - GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(event); + InjectEvent(WebInputEvent::Type::kTouchStart, x, y); + InjectEvent(WebInputEvent::Type::kTouchEnd, x, y); + InjectEvent(WebInputEvent::Type::kGestureTapDown, x, y); + InjectEvent(WebInputEvent::Type::kGestureTapUnconfirmed, x, y); + InjectEvent(WebInputEvent::Type::kGestureShowPress, x, y); + InjectEvent(WebInputEvent::Type::kGestureTap, x, y); } void LoadAhem() { @@ -124,6 +134,41 @@ FontFaceSetDocument::From(GetDocument()) ->addForBinding(script_state, ahem, exception_state); } + + private: + void InjectEvent(WebInputEvent::Type type, int x, int y) { + if (WebInputEvent::IsGestureEventType(type)) { + WebGestureEvent event(type, WebInputEvent::kNoModifiers, + base::TimeTicks::Now(), + WebGestureDevice::kTouchscreen); + event.SetPositionInWidget(gfx::PointF(x, y)); + event.SetPositionInScreen(gfx::PointF(x, y)); + event.SetFrameScale(1); + + WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting( + WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing()); + } else if (WebInputEvent::IsTouchEventType(type)) { + WebTouchEvent event(type, WebInputEvent::kNoModifiers, + base::TimeTicks::Now()); + event.SetFrameScale(1); + + WebPointerProperties pointer(0, WebPointerProperties::PointerType::kTouch, + WebPointerProperties::Button::kNoButton, + gfx::PointF(x, y), gfx::PointF(x, y)); + event.touches[0] = pointer; + if (type == WebInputEvent::Type::kTouchStart) + event.touches[0].state = WebTouchPoint::State::kStatePressed; + else if (type == WebInputEvent::Type::kTouchEnd) + event.touches[0].state = WebTouchPoint::State::kStateReleased; + + WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting( + WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing()); + WebView().MainFrameWidget()->DispatchBufferedTouchEvents(); + } else { + NOTREACHED() << "Only needed to support Gesture/Touch until now. " + "Implement others if new modality is needed."; + } + } }; // Basic test case, ensure we scroll the matching text into view. @@ -2617,6 +2662,76 @@ } #endif // BUILDFLAG(ENABLE_UNHANDLED_TAP) +TEST_F(TextFragmentAnchorTest, TapOpeningContextMenuWithDirtyLifecycleNoCrash) { + ScopedTextFragmentTapOpensContextMenuForTest tap_opens_context_menu(true); + base::test::ScopedFeatureList feature_list_; + feature_list_.InitAndEnableFeature( + shared_highlighting::kSharedHighlightingV2); + + SimRequest request( + "https://example.com/" + "test.html#:~:text=This%20is%20just%20example", + "text/html"); + LoadURL( + "https://example.com/" + "test.html#:~:text=This%20is%20just%20example"); + request.Complete(R"HTML( + <!DOCTYPE html> + <html> + <head> + <style> + .content { + width: 1000px; + height: 2000px; + background-color: silver; + } + </style> + <script> + // Dirty lifecycle inside the click event. + addEventListener('click', () => { + document.body.style.width = '500px'; + }); + // This prevents calling HandleMouseReleaseEvent which has an + // UpdateLifecycle call inside it but it also prevents showing the + // context menu. + addEventListener('mouseup', (e) => { e.preventDefault(); }); + </script> + </head> + + <body> + This is just example text that will wrap. + <div class="content"></div> + </body> + </html> + )HTML"); + RunAsyncMatchingTasks(); + ContextMenuAllowedScope context_menu_allowed_scope; + + Compositor().BeginFrame(); + + EXPECT_FALSE(GetDocument() + .GetPage() + ->GetContextMenuController() + .ContextMenuNodeForFrame(GetDocument().GetFrame())); + + Node* first_paragraph = GetDocument().body()->firstChild(); + const auto& start = Position(first_paragraph, 0); + const auto& end = Position(first_paragraph, 27); + ASSERT_EQ("This is just example", PlainText(EphemeralRange(start, end))); + + Range* range = CreateRange(EphemeralRange(start, end)); + + IntPoint tap_point = range->BoundingBox().Center(); + SimulateTap(tap_point.X(), tap_point.Y()); + + // Expect that we won't see the context menu because we preventDefaulted the + // mouseup but this test passes if it doesn't crash. + EXPECT_FALSE(GetDocument() + .GetPage() + ->GetContextMenuController() + .ContextMenuNodeForFrame(GetDocument().GetFrame())); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc index c996b543..aceb9cf 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc
@@ -104,6 +104,12 @@ return false; } + // Tree should be clean before accessing the position. + // |HitTestResult::GetPosition| calls |PositionForPoint()| which requires + // |kPrePaintClean|. + DCHECK_GE(result.InnerNodeFrame()->GetDocument()->Lifecycle().GetState(), + DocumentLifecycle::kPrePaintClean); + DocumentMarkerController& marker_controller = result.InnerNodeFrame()->GetDocument()->Markers(); PositionWithAffinity pos_with_affinity = result.GetPosition();
diff --git a/third_party/blink/renderer/core/paint/DEPS b/third_party/blink/renderer/core/paint/DEPS index 00b071d..6fb36eb 100644 --- a/third_party/blink/renderer/core/paint/DEPS +++ b/third_party/blink/renderer/core/paint/DEPS
@@ -8,7 +8,7 @@ ] specific_include_rules = { - "(theme_painter|theme_painter_default|object_painter_base)\.cc": [ + "(theme_painter|theme_painter_default|outline_painter)\.cc": [ "+ui/native_theme/native_theme.h", "+ui/native_theme/native_theme_base.h", "+ui/gfx/color_utils.h"
diff --git a/third_party/blink/renderer/core/paint/box_border_painter.cc b/third_party/blink/renderer/core/paint/box_border_painter.cc index 99c0b03c..7e68e62 100644 --- a/third_party/blink/renderer/core/paint/box_border_painter.cc +++ b/third_party/blink/renderer/core/paint/box_border_painter.cc
@@ -9,7 +9,6 @@ #include "base/cxx17_backports.h" #include "third_party/blink/renderer/core/paint/box_painter.h" #include "third_party/blink/renderer/core/paint/object_painter.h" -#include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/rounded_border_geometry.h" #include "third_party/blink/renderer/core/style/border_edge.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -86,20 +85,6 @@ return false; } -inline bool ColorsMatchAtCorner(BoxSide side, - BoxSide adjacent_side, - const BorderEdge edges[]) { - if (!edges[static_cast<unsigned>(adjacent_side)].ShouldRender()) - return false; - - if (!edges[static_cast<unsigned>(side)].SharesColorWith( - edges[static_cast<unsigned>(adjacent_side)])) - return false; - - return !BorderStyleHasUnmatchedColorsAtCorner( - edges[static_cast<unsigned>(side)].BorderStyle(), side, adjacent_side); -} - inline bool BorderWillArcInnerEdge(const FloatSize& first_radius, const FloatSize& second_radius) { return !first_radius.IsZero() || !second_radius.IsZero(); @@ -140,15 +125,15 @@ FloatRect CalculateSideRect(const FloatRoundedRect& outer_border, const BorderEdge& edge, - int side) { + BoxSide side) { FloatRect side_rect = outer_border.Rect(); float width = edge.Width(); - if (side == static_cast<unsigned>(BoxSide::kTop)) + if (side == BoxSide::kTop) side_rect.SetHeight(width); - else if (side == static_cast<unsigned>(BoxSide::kBottom)) + else if (side == BoxSide::kBottom) side_rect.ShiftYEdgeTo(side_rect.MaxY() - width); - else if (side == static_cast<unsigned>(BoxSide::kLeft)) + else if (side == BoxSide::kLeft) side_rect.SetWidth(width); else side_rect.ShiftXEdgeTo(side_rect.MaxX() - width); @@ -156,38 +141,6 @@ return side_rect; } -FloatRect CalculateSideRectIncludingInner(const FloatRoundedRect& outer_border, - const BorderEdge edges[], - BoxSide side) { - FloatRect side_rect = outer_border.Rect(); - float width; - - switch (side) { - case BoxSide::kTop: - width = side_rect.Height() - - edges[static_cast<unsigned>(BoxSide::kBottom)].Width(); - side_rect.SetHeight(width); - break; - case BoxSide::kBottom: - width = side_rect.Height() - - edges[static_cast<unsigned>(BoxSide::kTop)].Width(); - side_rect.ShiftYEdgeTo(side_rect.MaxY() - width); - break; - case BoxSide::kLeft: - width = side_rect.Width() - - edges[static_cast<unsigned>(BoxSide::kRight)].Width(); - side_rect.SetWidth(width); - break; - case BoxSide::kRight: - width = side_rect.Width() - - edges[static_cast<unsigned>(BoxSide::kLeft)].Width(); - side_rect.ShiftXEdgeTo(side_rect.MaxX() - width); - break; - } - - return side_rect; -} - FloatRoundedRect CalculateAdjustedInnerBorder( const FloatRoundedRect& inner_border, BoxSide side) { @@ -276,20 +229,6 @@ return FloatRoundedRect(new_rect, new_radii); } -LayoutRectOutsets DoubleStripeInsets(const BorderEdge edges[], - BorderEdge::DoubleBorderStripe stripe) { - // Insets are representes as negative outsets. - return LayoutRectOutsets( - -edges[static_cast<unsigned>(BoxSide::kTop)].GetDoubleBorderStripeWidth( - stripe), - -edges[static_cast<unsigned>(BoxSide::kRight)].GetDoubleBorderStripeWidth( - stripe), - -edges[static_cast<unsigned>(BoxSide::kBottom)] - .GetDoubleBorderStripeWidth(stripe), - -edges[static_cast<unsigned>(BoxSide::kLeft)].GetDoubleBorderStripeWidth( - stripe)); -} - void DrawSolidBorderRect(GraphicsContext& context, const FloatRect& border_rect, float border_width, @@ -383,20 +322,25 @@ // before solid edges (inset/outset/groove/ridge/solid) to maximize overdraw // opportunities. const unsigned kStylePriority[] = { - 0 /* BorderStyleNone */, 0 /* BorderStyleHidden */, - 2 /* BorderStyleInset */, 2 /* BorderStyleGroove */, - 2 /* BorderStyleOutset */, 2 /* BorderStyleRidge */, - 1 /* BorderStyleDotted */, 1 /* BorderStyleDashed */, - 3 /* BorderStyleSolid */, 1 /* BorderStyleDouble */ + 0, // EBorderStyle::kNone + 0, // EBorderStyle::kHidden + 2, // EBorderStyle::kInset + 2, // EBorderStyle::kGroove + 2, // EBorderStyle::kOutset + 2, // EBorderStyle::kRidge, + 1, // EBorderStyle::kDotted + 1, // EBorderStyle::kDashed + 3, // EBorderStyle::kSolid + 1, // EBorderStyle::kDouble }; // Given the same style, prefer drawing in non-adjacent order to minimize the // number of sides which require miters. const unsigned kSidePriority[] = { - 0, /* BSTop */ - 2, /* BSRight */ - 1, /* BSBottom */ - 3, /* BSLeft */ + 0, // BoxSide::kTop + 2, // BoxSide::kRight + 1, // BoxSide::kBottom + 3, // BoxSide::kLeft }; // Edges sharing the same opacity. Stores both a side list and an edge bitfield @@ -421,6 +365,292 @@ context.ClipPath(path.detach(), antialiased ? kAntiAliased : kNotAntiAliased); } +void DrawDashedOrDottedBoxSide(GraphicsContext& context, + int x1, + int y1, + int x2, + int y2, + BoxSide side, + Color color, + int thickness, + EBorderStyle style, + bool antialias) { + DCHECK_GT(thickness, 0); + + GraphicsContextStateSaver state_saver(context); + context.SetShouldAntialias(antialias); + context.SetStrokeColor(color); + context.SetStrokeThickness(thickness); + context.SetStrokeStyle(style == EBorderStyle::kDashed ? kDashedStroke + : kDottedStroke); + + switch (side) { + case BoxSide::kBottom: + case BoxSide::kTop: { + int mid_y = y1 + thickness / 2; + context.DrawLine(IntPoint(x1, mid_y), IntPoint(x2, mid_y)); + break; + } + case BoxSide::kRight: + case BoxSide::kLeft: { + int mid_x = x1 + thickness / 2; + context.DrawLine(IntPoint(mid_x, y1), IntPoint(mid_x, y2)); + break; + } + } +} + +void DrawDoubleBoxSide(GraphicsContext& context, + int x1, + int y1, + int x2, + int y2, + int length, + BoxSide side, + Color color, + float thickness, + int adjacent_width1, + int adjacent_width2, + bool antialias) { + int third_of_thickness = (thickness + 1) / 3; + DCHECK_GT(third_of_thickness, 0); + + if (!adjacent_width1 && !adjacent_width2) { + StrokeStyle old_stroke_style = context.GetStrokeStyle(); + context.SetStrokeStyle(kNoStroke); + context.SetFillColor(color); + + bool was_antialiased = context.ShouldAntialias(); + context.SetShouldAntialias(antialias); + + switch (side) { + case BoxSide::kTop: + case BoxSide::kBottom: + context.DrawRect(IntRect(x1, y1, length, third_of_thickness)); + context.DrawRect( + IntRect(x1, y2 - third_of_thickness, length, third_of_thickness)); + break; + case BoxSide::kLeft: + case BoxSide::kRight: + context.DrawRect(IntRect(x1, y1, third_of_thickness, length)); + context.DrawRect( + IntRect(x2 - third_of_thickness, y1, third_of_thickness, length)); + break; + } + + context.SetShouldAntialias(was_antialiased); + context.SetStrokeStyle(old_stroke_style); + return; + } + + int adjacent1_big_third = + ((adjacent_width1 > 0) ? adjacent_width1 + 1 : adjacent_width1 - 1) / 3; + int adjacent2_big_third = + ((adjacent_width2 > 0) ? adjacent_width2 + 1 : adjacent_width2 - 1) / 3; + + switch (side) { + case BoxSide::kTop: + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), y1, + x2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), + y1 + third_of_thickness, side, color, EBorderStyle::kSolid, + adjacent1_big_third, adjacent2_big_third, antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), + y2 - third_of_thickness, + x2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), y2, side, color, + EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, + antialias); + break; + case BoxSide::kLeft: + BoxBorderPainter::DrawLineForBoxSide( + context, x1, y1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), + x1 + third_of_thickness, + y2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), side, color, + EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, + antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, x2 - third_of_thickness, + y1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), x2, + y2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), side, color, + EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, + antialias); + break; + case BoxSide::kBottom: + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), y1, + x2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), + y1 + third_of_thickness, side, color, EBorderStyle::kSolid, + adjacent1_big_third, adjacent2_big_third, antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), + y2 - third_of_thickness, + x2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), y2, side, color, + EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, + antialias); + break; + case BoxSide::kRight: + BoxBorderPainter::DrawLineForBoxSide( + context, x1, y1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), + x1 + third_of_thickness, + y2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), side, color, + EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, + antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, x2 - third_of_thickness, + y1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), x2, + y2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), side, color, + EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, + antialias); + break; + default: + break; + } +} + +void DrawRidgeOrGrooveBoxSide(GraphicsContext& context, + int x1, + int y1, + int x2, + int y2, + BoxSide side, + Color color, + EBorderStyle style, + int adjacent_width1, + int adjacent_width2, + bool antialias) { + EBorderStyle s1; + EBorderStyle s2; + if (style == EBorderStyle::kGroove) { + s1 = EBorderStyle::kInset; + s2 = EBorderStyle::kOutset; + } else { + s1 = EBorderStyle::kOutset; + s2 = EBorderStyle::kInset; + } + + int adjacent1_big_half = + ((adjacent_width1 > 0) ? adjacent_width1 + 1 : adjacent_width1 - 1) / 2; + int adjacent2_big_half = + ((adjacent_width2 > 0) ? adjacent_width2 + 1 : adjacent_width2 - 1) / 2; + + switch (side) { + case BoxSide::kTop: + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max(-adjacent_width1, 0) / 2, y1, + x2 - std::max(-adjacent_width2, 0) / 2, (y1 + y2 + 1) / 2, side, + color, s1, adjacent1_big_half, adjacent2_big_half, antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max(adjacent_width1 + 1, 0) / 2, (y1 + y2 + 1) / 2, + x2 - std::max(adjacent_width2 + 1, 0) / 2, y2, side, color, s2, + adjacent_width1 / 2, adjacent_width2 / 2, antialias); + break; + case BoxSide::kLeft: + BoxBorderPainter::DrawLineForBoxSide( + context, x1, y1 + std::max(-adjacent_width1, 0) / 2, + (x1 + x2 + 1) / 2, y2 - std::max(-adjacent_width2, 0) / 2, side, + color, s1, adjacent1_big_half, adjacent2_big_half, antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, (x1 + x2 + 1) / 2, y1 + std::max(adjacent_width1 + 1, 0) / 2, + x2, y2 - std::max(adjacent_width2 + 1, 0) / 2, side, color, s2, + adjacent_width1 / 2, adjacent_width2 / 2, antialias); + break; + case BoxSide::kBottom: + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max(adjacent_width1, 0) / 2, y1, + x2 - std::max(adjacent_width2, 0) / 2, (y1 + y2 + 1) / 2, side, color, + s2, adjacent1_big_half, adjacent2_big_half, antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, x1 + std::max(-adjacent_width1 + 1, 0) / 2, + (y1 + y2 + 1) / 2, x2 - std::max(-adjacent_width2 + 1, 0) / 2, y2, + side, color, s1, adjacent_width1 / 2, adjacent_width2 / 2, antialias); + break; + case BoxSide::kRight: + BoxBorderPainter::DrawLineForBoxSide( + context, x1, y1 + std::max(adjacent_width1, 0) / 2, (x1 + x2 + 1) / 2, + y2 - std::max(adjacent_width2, 0) / 2, side, color, s2, + adjacent1_big_half, adjacent2_big_half, antialias); + BoxBorderPainter::DrawLineForBoxSide( + context, (x1 + x2 + 1) / 2, + y1 + std::max(-adjacent_width1 + 1, 0) / 2, x2, + y2 - std::max(-adjacent_width2 + 1, 0) / 2, side, color, s1, + adjacent_width1 / 2, adjacent_width2 / 2, antialias); + break; + } +} + +void FillQuad(GraphicsContext& context, + const FloatPoint quad[], + const Color& color, + bool antialias) { + SkPathBuilder path; + path.moveTo(FloatPointToSkPoint(quad[0])); + path.lineTo(FloatPointToSkPoint(quad[1])); + path.lineTo(FloatPointToSkPoint(quad[2])); + path.lineTo(FloatPointToSkPoint(quad[3])); + PaintFlags flags(context.FillFlags()); + flags.setAntiAlias(antialias); + flags.setColor(color.Rgb()); + + context.DrawPath(path.detach(), flags); +} + +void DrawSolidBoxSide(GraphicsContext& context, + int x1, + int y1, + int x2, + int y2, + BoxSide side, + Color color, + int adjacent_width1, + int adjacent_width2, + bool antialias) { + DCHECK_GE(x2, x1); + DCHECK_GE(y2, y1); + + if (!adjacent_width1 && !adjacent_width2) { + // Tweak antialiasing to match the behavior of fillQuad(); + // this matters for rects in transformed contexts. + bool was_antialiased = context.ShouldAntialias(); + if (antialias != was_antialiased) + context.SetShouldAntialias(antialias); + context.FillRect(IntRect(x1, y1, x2 - x1, y2 - y1), color); + if (antialias != was_antialiased) + context.SetShouldAntialias(was_antialiased); + return; + } + + FloatPoint quad[4]; + switch (side) { + case BoxSide::kTop: + quad[0] = FloatPoint(x1 + std::max(-adjacent_width1, 0), y1); + quad[1] = FloatPoint(x1 + std::max(adjacent_width1, 0), y2); + quad[2] = FloatPoint(x2 - std::max(adjacent_width2, 0), y2); + quad[3] = FloatPoint(x2 - std::max(-adjacent_width2, 0), y1); + break; + case BoxSide::kBottom: + quad[0] = FloatPoint(x1 + std::max(adjacent_width1, 0), y1); + quad[1] = FloatPoint(x1 + std::max(-adjacent_width1, 0), y2); + quad[2] = FloatPoint(x2 - std::max(-adjacent_width2, 0), y2); + quad[3] = FloatPoint(x2 - std::max(adjacent_width2, 0), y1); + break; + case BoxSide::kLeft: + quad[0] = FloatPoint(x1, y1 + std::max(-adjacent_width1, 0)); + quad[1] = FloatPoint(x1, y2 - std::max(-adjacent_width2, 0)); + quad[2] = FloatPoint(x2, y2 - std::max(adjacent_width2, 0)); + quad[3] = FloatPoint(x2, y1 + std::max(adjacent_width1, 0)); + break; + case BoxSide::kRight: + quad[0] = FloatPoint(x1, y1 + std::max(adjacent_width1, 0)); + quad[1] = FloatPoint(x1, y2 - std::max(adjacent_width2, 0)); + quad[2] = FloatPoint(x2, y2 - std::max(-adjacent_width2, 0)); + quad[3] = FloatPoint(x2, y1 + std::max(-adjacent_width1, 0)); + break; + } + + FillQuad(context, quad, color, antialias); +} + } // anonymous namespace // Holds edges grouped by opacity and sorted in paint order. @@ -442,10 +672,8 @@ // alpha, style, side. std::sort(sorted_sides.begin(), sorted_sides.end(), [&border_painter](BoxSide a, BoxSide b) -> bool { - const BorderEdge& edge_a = - border_painter.edges_[static_cast<unsigned>(a)]; - const BorderEdge& edge_b = - border_painter.edges_[static_cast<unsigned>(b)]; + const BorderEdge& edge_a = border_painter.Edge(a); + const BorderEdge& edge_b = border_painter.Edge(b); const unsigned alpha_a = edge_a.color.Alpha(); const unsigned alpha_b = edge_b.color.Alpha(); @@ -482,8 +710,7 @@ const Vector<BoxSide, 4>& sorted_sides) { unsigned current_alpha = 0; for (BoxSide side : sorted_sides) { - const BorderEdge& edge = - border_painter.edges_[static_cast<unsigned>(side)]; + const BorderEdge& edge = border_painter.Edge(side); const unsigned edge_alpha = edge.color.Alpha(); DCHECK_GT(edge_alpha, 0u); @@ -503,8 +730,7 @@ } }; -void BoxBorderPainter::DrawDoubleBorder(GraphicsContext& context, - const PhysicalRect& border_rect) const { +void BoxBorderPainter::DrawDoubleBorder() const { DCHECK(is_uniform_color_); DCHECK(is_uniform_style_); DCHECK(FirstEdge().BorderStyle() == EBorderStyle::kDouble); @@ -517,29 +743,27 @@ // outer stripe const LayoutRectOutsets outer_third_insets = - DoubleStripeInsets(edges_, BorderEdge::kDoubleBorderStripeOuter); + DoubleStripeInsets(BorderEdge::kDoubleBorderStripeOuter); FloatRoundedRect outer_third_rect = RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( - style_, border_rect, outer_third_insets, sides_to_include_); + style_, border_rect_, outer_third_insets, sides_to_include_); if (force_rectangular) outer_third_rect.SetRadii(FloatRoundedRect::Radii()); - DrawBleedAdjustedDRRect(context, bleed_avoidance_, outer_, outer_third_rect, + DrawBleedAdjustedDRRect(context_, bleed_avoidance_, outer_, outer_third_rect, color); // inner stripe const LayoutRectOutsets inner_third_insets = - DoubleStripeInsets(edges_, BorderEdge::kDoubleBorderStripeInner); + DoubleStripeInsets(BorderEdge::kDoubleBorderStripeInner); FloatRoundedRect inner_third_rect = RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( - style_, border_rect, inner_third_insets, sides_to_include_); + style_, border_rect_, inner_third_insets, sides_to_include_); if (force_rectangular) inner_third_rect.SetRadii(FloatRoundedRect::Radii()); - context.FillDRRect(inner_third_rect, inner_, color); + context_.FillDRRect(inner_third_rect, inner_, color); } -bool BoxBorderPainter::PaintBorderFastPath( - GraphicsContext& context, - const PhysicalRect& border_rect) const { +bool BoxBorderPainter::PaintBorderFastPath() const { if (!is_uniform_color_ || !is_uniform_style_ || !inner_.IsRenderable()) return false; @@ -551,17 +775,17 @@ if (FirstEdge().BorderStyle() == EBorderStyle::kSolid) { if (is_uniform_width_ && !outer_.IsRounded()) { // 4-side, solid, uniform-width, rectangular border => one drawRect() - DrawSolidBorderRect(context, outer_.Rect(), FirstEdge().Width(), + DrawSolidBorderRect(context_, outer_.Rect(), FirstEdge().Width(), FirstEdge().color); } else { // 4-side, solid border => one drawDRRect() - DrawBleedAdjustedDRRect(context, bleed_avoidance_, outer_, inner_, + DrawBleedAdjustedDRRect(context_, bleed_avoidance_, outer_, inner_, FirstEdge().color); } } else { // 4-side, double border => 2x drawDRRect() DCHECK(FirstEdge().BorderStyle() == EBorderStyle::kDouble); - DrawDoubleBorder(context, border_rect); + DrawDoubleBorder(); } return true; @@ -576,26 +800,29 @@ Path path; path.SetWindRule(RULE_NONZERO); - for (unsigned int i = static_cast<unsigned>(BoxSide::kTop); - i <= static_cast<unsigned>(BoxSide::kLeft); ++i) { - const BorderEdge& curr_edge = edges_[i]; + for (auto side : + {BoxSide::kTop, BoxSide::kRight, BoxSide::kBottom, BoxSide::kLeft}) { + const BorderEdge& curr_edge = Edge(side); if (curr_edge.ShouldRender()) - path.AddRect(CalculateSideRect(outer_, curr_edge, i)); + path.AddRect(CalculateSideRect(outer_, curr_edge, side)); } - context.SetFillColor(FirstEdge().color); - context.FillPath(path); + context_.SetFillColor(FirstEdge().color); + context_.FillPath(path); return true; } return false; } -BoxBorderPainter::BoxBorderPainter(const PhysicalRect& border_rect, +BoxBorderPainter::BoxBorderPainter(GraphicsContext& context, + const PhysicalRect& border_rect, const ComputedStyle& style, BackgroundBleedAvoidance bleed_avoidance, PhysicalBoxSides sides_to_include) - : style_(style), + : context_(context), + border_rect_(border_rect), + style_(style), bleed_avoidance_(bleed_avoidance), sides_to_include_(sides_to_include), visible_edge_count_(0), @@ -622,19 +849,24 @@ // can pixel snap smaller. float max_width = outer_.Rect().Width(); float max_height = outer_.Rect().Height(); - edges_[static_cast<unsigned>(BoxSide::kTop)].ClampWidth(max_height); - edges_[static_cast<unsigned>(BoxSide::kRight)].ClampWidth(max_width); - edges_[static_cast<unsigned>(BoxSide::kBottom)].ClampWidth(max_height); - edges_[static_cast<unsigned>(BoxSide::kLeft)].ClampWidth(max_width); + Edge(BoxSide::kTop).ClampWidth(max_height); + Edge(BoxSide::kRight).ClampWidth(max_width); + Edge(BoxSide::kBottom).ClampWidth(max_height); + Edge(BoxSide::kLeft).ClampWidth(max_width); is_rounded_ = outer_.IsRounded(); } -BoxBorderPainter::BoxBorderPainter(const ComputedStyle& style, +BoxBorderPainter::BoxBorderPainter(GraphicsContext& context, + const ComputedStyle& style, const PhysicalRect& outer, const PhysicalRect& inner, - const BorderEdge& uniform_edge_info) - : style_(style), + const BorderEdge& edge_info) + : context_(context), + // TODO(wangxianzhu): |outer| may not be the actual border rect, but this + // only matters when we support rounded outlines. + border_rect_(outer), + style_(style), bleed_avoidance_(kBackgroundBleedNone), sides_to_include_(PhysicalBoxSides()), outer_(FloatRect(outer)), @@ -648,7 +880,7 @@ is_rounded_(false), has_alpha_(false) { for (auto& edge : edges_) - edge = uniform_edge_info; + edge = edge_info; ComputeBorderProperties(); } @@ -685,30 +917,27 @@ } } -void BoxBorderPainter::PaintBorder(const PaintInfo& info, - const PhysicalRect& rect) const { +void BoxBorderPainter::Paint() const { if (!visible_edge_count_ || outer_.Rect().IsEmpty()) return; - GraphicsContext& graphics_context = info.context; - - if (PaintBorderFastPath(graphics_context, rect)) + if (PaintBorderFastPath()) return; bool clip_to_outer_border = outer_.IsRounded(); - GraphicsContextStateSaver state_saver(graphics_context, clip_to_outer_border); + GraphicsContextStateSaver state_saver(context_, clip_to_outer_border); if (clip_to_outer_border) { // For BackgroundBleedClip{Only,Layer}, the outer rrect clip is already // applied. if (!BleedAvoidanceIsClipping(bleed_avoidance_)) - graphics_context.ClipRoundedRect(outer_); + context_.ClipRoundedRect(outer_); if (inner_.IsRenderable() && !inner_.IsEmpty()) - graphics_context.ClipOutRoundedRect(inner_); + context_.ClipOutRoundedRect(inner_); } const ComplexBorderInfo border_info(*this, true); - PaintOpacityGroup(graphics_context, border_info, 0, 1); + PaintOpacityGroup(border_info, 0, 1); } // In order to maximize the use of overdraw as a corner seam avoidance @@ -756,7 +985,6 @@ // content - hence we can use overdraw to mask portions of the previous sides. // BorderEdgeFlags BoxBorderPainter::PaintOpacityGroup( - GraphicsContext& context, const ComplexBorderInfo& border_info, unsigned index, float effective_opacity) const { @@ -789,7 +1017,7 @@ const float group_opacity = static_cast<float>(group.alpha) / 255; DCHECK_LT(group_opacity, effective_opacity); - context.BeginLayer(group_opacity / effective_opacity); + context_.BeginLayer(group_opacity / effective_opacity); effective_opacity = group_opacity; // Group opacity is applied via a layer => we draw the members using opaque @@ -802,27 +1030,26 @@ // b) only triggers at all when mixing border sides with different opacities // c) it allows us to express the layer nesting algorithm more naturally BorderEdgeFlags completed_edges = - PaintOpacityGroup(context, border_info, index + 1, effective_opacity); + PaintOpacityGroup(border_info, index + 1, effective_opacity); // Paint the actual group edges with an alpha adjusted to account for // ancenstor layers opacity. for (BoxSide side : group.sides) { - PaintSide(context, border_info, side, paint_alpha, completed_edges); + PaintSide(border_info, side, paint_alpha, completed_edges); completed_edges |= EdgeFlagForSide(side); } if (needs_layer) - context.EndLayer(); + context_.EndLayer(); return completed_edges; } -void BoxBorderPainter::PaintSide(GraphicsContext& context, - const ComplexBorderInfo& border_info, +void BoxBorderPainter::PaintSide(const ComplexBorderInfo& border_info, BoxSide side, unsigned alpha, BorderEdgeFlags completed_edges) const { - const BorderEdge& edge = edges_[static_cast<unsigned>(side)]; + const BorderEdge& edge = Edge(side); DCHECK(edge.ShouldRender()); const Color color(edge.color.Red(), edge.color.Green(), edge.color.Blue(), alpha); @@ -843,7 +1070,7 @@ else side_rect.SetHeight(floorf(edge.Width())); - PaintOneBorderSide(context, side_rect, BoxSide::kTop, BoxSide::kLeft, + PaintOneBorderSide(side_rect, BoxSide::kTop, BoxSide::kLeft, BoxSide::kRight, path, border_info.anti_alias, color, completed_edges); break; @@ -858,7 +1085,7 @@ else side_rect.ShiftYEdgeTo(side_rect.MaxY() - floorf(edge.Width())); - PaintOneBorderSide(context, side_rect, BoxSide::kBottom, BoxSide::kLeft, + PaintOneBorderSide(side_rect, BoxSide::kBottom, BoxSide::kLeft, BoxSide::kRight, path, border_info.anti_alias, color, completed_edges); break; @@ -873,7 +1100,7 @@ else side_rect.SetWidth(floorf(edge.Width())); - PaintOneBorderSide(context, side_rect, BoxSide::kLeft, BoxSide::kTop, + PaintOneBorderSide(side_rect, BoxSide::kLeft, BoxSide::kTop, BoxSide::kBottom, path, border_info.anti_alias, color, completed_edges); break; @@ -888,7 +1115,7 @@ else side_rect.ShiftXEdgeTo(side_rect.MaxX() - floorf(edge.Width())); - PaintOneBorderSide(context, side_rect, BoxSide::kRight, BoxSide::kTop, + PaintOneBorderSide(side_rect, BoxSide::kRight, BoxSide::kTop, BoxSide::kBottom, path, border_info.anti_alias, color, completed_edges); break; @@ -903,8 +1130,7 @@ BoxSide adjacent_side, BorderEdgeFlags completed_edges, bool antialias) const { - const BorderEdge& adjacent_edge = - edges_[static_cast<unsigned>(adjacent_side)]; + const BorderEdge& adjacent_edge = Edge(adjacent_side); // No miters for missing edges. if (!adjacent_edge.is_present) @@ -916,15 +1142,13 @@ // Color transitions require miters. Use miters compatible with the AA drawing // mode to avoid introducing extra clips. - if (!ColorsMatchAtCorner(side, adjacent_side, edges_)) + if (!ColorsMatchAtCorner(side, adjacent_side)) return antialias ? kSoftMiter : kHardMiter; // Non-anti-aliased miters ensure correct same-color seaming when required by // style. - if (BorderStylesRequireMiter( - side, adjacent_side, - edges_[static_cast<unsigned>(side)].BorderStyle(), - adjacent_edge.BorderStyle())) + if (BorderStylesRequireMiter(side, adjacent_side, Edge(side).BorderStyle(), + adjacent_edge.BorderStyle())) return kHardMiter; // Overdraw the adjacent edge when the colors match and we have no style @@ -949,7 +1173,6 @@ } void BoxBorderPainter::PaintOneBorderSide( - GraphicsContext& graphics_context, const FloatRect& side_rect, BoxSide side, BoxSide adjacent_side1, @@ -958,33 +1181,27 @@ bool antialias, Color color, BorderEdgeFlags completed_edges) const { - const BorderEdge& edge_to_render = edges_[static_cast<unsigned>(side)]; + const BorderEdge& edge_to_render = Edge(side); DCHECK(edge_to_render.Width()); - const BorderEdge& adjacent_edge1 = - edges_[static_cast<unsigned>(adjacent_side1)]; - const BorderEdge& adjacent_edge2 = - edges_[static_cast<unsigned>(adjacent_side2)]; + const BorderEdge& adjacent_edge1 = Edge(adjacent_side1); + const BorderEdge& adjacent_edge2 = Edge(adjacent_side2); if (path) { - MiterType miter1 = ColorsMatchAtCorner(side, adjacent_side1, edges_) - ? kHardMiter - : kSoftMiter; - MiterType miter2 = ColorsMatchAtCorner(side, adjacent_side2, edges_) - ? kHardMiter - : kSoftMiter; + MiterType miter1 = + ColorsMatchAtCorner(side, adjacent_side1) ? kHardMiter : kSoftMiter; + MiterType miter2 = + ColorsMatchAtCorner(side, adjacent_side2) ? kHardMiter : kSoftMiter; - GraphicsContextStateSaver state_saver(graphics_context); + GraphicsContextStateSaver state_saver(context_); if (inner_.IsRenderable()) - ClipBorderSidePolygon(graphics_context, side, miter1, miter2); + ClipBorderSidePolygon(side, miter1, miter2); else - ClipBorderSideForComplexInnerPath(graphics_context, side); + ClipBorderSideForComplexInnerPath(side); float stroke_thickness = std::max(std::max(edge_to_render.Width(), adjacent_edge1.Width()), adjacent_edge2.Width()); - DrawBoxSideFromPath(graphics_context, - PhysicalRect::EnclosingRect(outer_.Rect()), *path, - edge_to_render.Width(), stroke_thickness, side, color, - edge_to_render.BorderStyle()); + DrawBoxSideFromPath(*path, edge_to_render.Width(), stroke_thickness, side, + color, edge_to_render.BorderStyle()); } else { MiterType miter1 = ComputeMiter(side, adjacent_side1, completed_edges, antialias); @@ -993,25 +1210,23 @@ bool should_clip = MitersRequireClipping( miter1, miter2, edge_to_render.BorderStyle(), antialias); - GraphicsContextStateSaver clip_state_saver(graphics_context, should_clip); + GraphicsContextStateSaver clip_state_saver(context_, should_clip); if (should_clip) { - ClipBorderSidePolygon(graphics_context, side, miter1, miter2); + ClipBorderSidePolygon(side, miter1, miter2); // Miters are applied via clipping, no need to draw them. miter1 = miter2 = kNoMiter; } - ObjectPainter::DrawLineForBoxSide( - graphics_context, side_rect.X(), side_rect.Y(), side_rect.MaxX(), + DrawLineForBoxSide( + context_, side_rect.X(), side_rect.Y(), side_rect.MaxX(), side_rect.MaxY(), side, color, edge_to_render.BorderStyle(), miter1 != kNoMiter ? floorf(adjacent_edge1.Width()) : 0, miter2 != kNoMiter ? floorf(adjacent_edge2.Width()) : 0, antialias); } } -void BoxBorderPainter::DrawBoxSideFromPath(GraphicsContext& graphics_context, - const PhysicalRect& border_rect, - const Path& border_path, +void BoxBorderPainter::DrawBoxSideFromPath(const Path& border_path, float border_thickness, float stroke_thickness, BoxSide side, @@ -1029,22 +1244,20 @@ return; case EBorderStyle::kDotted: case EBorderStyle::kDashed: { - DrawDashedDottedBoxSideFromPath(graphics_context, border_rect, - border_thickness, stroke_thickness, color, + DrawDashedDottedBoxSideFromPath(border_thickness, stroke_thickness, color, border_style); return; } case EBorderStyle::kDouble: { - DrawDoubleBoxSideFromPath(graphics_context, border_rect, border_path, - border_thickness, stroke_thickness, side, - color); + DrawDoubleBoxSideFromPath(border_path, border_thickness, stroke_thickness, + side, color); return; } case EBorderStyle::kRidge: case EBorderStyle::kGroove: { - DrawRidgeGrooveBoxSideFromPath(graphics_context, border_rect, border_path, - border_thickness, stroke_thickness, side, - color, border_style); + DrawRidgeGrooveBoxSideFromPath(border_path, border_thickness, + stroke_thickness, side, color, + border_style); return; } case EBorderStyle::kInset: @@ -1059,37 +1272,29 @@ break; } - graphics_context.SetStrokeStyle(kNoStroke); - graphics_context.SetFillColor(color); - graphics_context.DrawRect(PixelSnappedIntRect(border_rect)); + context_.SetStrokeStyle(kNoStroke); + context_.SetFillColor(color); + context_.DrawRect(PixelSnappedIntRect(border_rect_)); } void BoxBorderPainter::DrawDashedDottedBoxSideFromPath( - GraphicsContext& graphics_context, - const PhysicalRect& border_rect, float border_thickness, float stroke_thickness, Color color, EBorderStyle border_style) const { // Convert the path to be down the middle of the dots or dashes. - const LayoutRectOutsets center_offsets( - -edges_[static_cast<unsigned>(BoxSide::kTop)].UsedWidth() * 0.5, - -edges_[static_cast<unsigned>(BoxSide::kRight)].UsedWidth() * 0.5, - -edges_[static_cast<unsigned>(BoxSide::kBottom)].UsedWidth() * 0.5, - -edges_[static_cast<unsigned>(BoxSide::kLeft)].UsedWidth() * 0.5); Path centerline_path; centerline_path.AddRoundedRect( RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( - style_, border_rect, center_offsets, sides_to_include_)); + style_, border_rect_, CenterInsets(), sides_to_include_)); - graphics_context.SetStrokeColor(color); + context_.SetStrokeColor(color); if (!StrokeData::StrokeIsDashed(border_thickness, border_style == EBorderStyle::kDashed ? kDashedStroke : kDottedStroke)) { - DrawWideDottedBoxSideFromPath(graphics_context, centerline_path, - border_thickness); + DrawWideDottedBoxSideFromPath(centerline_path, border_thickness); return; } @@ -1098,33 +1303,29 @@ // the extra multiplier so that the clipping mask can antialias // the edges to prevent jaggies. const float thickness_multiplier = 2 * 1.1f; - graphics_context.SetStrokeThickness(stroke_thickness * thickness_multiplier); - graphics_context.SetStrokeStyle( + context_.SetStrokeThickness(stroke_thickness * thickness_multiplier); + context_.SetStrokeStyle( border_style == EBorderStyle::kDashed ? kDashedStroke : kDottedStroke); // TODO(schenney): stroking the border path causes issues with tight corners: // https://bugs.chromium.org/p/chromium/issues/detail?id=344234 - graphics_context.StrokePath(centerline_path, centerline_path.length(), - border_thickness); + context_.StrokePath(centerline_path, centerline_path.length(), + border_thickness); } void BoxBorderPainter::DrawWideDottedBoxSideFromPath( - GraphicsContext& graphics_context, const Path& border_path, float border_thickness) const { - graphics_context.SetStrokeThickness(border_thickness); - graphics_context.SetStrokeStyle(kDottedStroke); - graphics_context.SetLineCap(kRoundCap); + context_.SetStrokeThickness(border_thickness); + context_.SetStrokeStyle(kDottedStroke); + context_.SetLineCap(kRoundCap); // TODO(schenney): stroking the border path causes issues with tight corners: // https://bugs.webkit.org/show_bug.cgi?id=58711 - graphics_context.StrokePath(border_path, border_path.length(), - border_thickness); + context_.StrokePath(border_path, border_path.length(), border_thickness); } void BoxBorderPainter::DrawDoubleBoxSideFromPath( - GraphicsContext& graphics_context, - const PhysicalRect& border_rect, const Path& border_path, float border_thickness, float stroke_thickness, @@ -1132,25 +1333,24 @@ Color color) const { // Draw inner border line { - GraphicsContextStateSaver state_saver(graphics_context); + GraphicsContextStateSaver state_saver(context_); const LayoutRectOutsets inner_insets = - DoubleStripeInsets(edges_, BorderEdge::kDoubleBorderStripeInner); + DoubleStripeInsets(BorderEdge::kDoubleBorderStripeInner); FloatRoundedRect inner_clip = RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( - style_, border_rect, inner_insets, sides_to_include_); + style_, border_rect_, inner_insets, sides_to_include_); - graphics_context.ClipRoundedRect(inner_clip); - DrawBoxSideFromPath(graphics_context, border_rect, border_path, - border_thickness, stroke_thickness, side, color, - EBorderStyle::kSolid); + context_.ClipRoundedRect(inner_clip); + DrawBoxSideFromPath(border_path, border_thickness, stroke_thickness, side, + color, EBorderStyle::kSolid); } // Draw outer border line { - GraphicsContextStateSaver state_saver(graphics_context); - PhysicalRect outer_rect = border_rect; + GraphicsContextStateSaver state_saver(context_); + PhysicalRect outer_rect = border_rect_; LayoutRectOutsets outer_insets = - DoubleStripeInsets(edges_, BorderEdge::kDoubleBorderStripeOuter); + DoubleStripeInsets(BorderEdge::kDoubleBorderStripeOuter); if (BleedAvoidanceIsClipping(bleed_avoidance_)) { outer_rect.Inflate(LayoutUnit(1)); @@ -1163,16 +1363,13 @@ FloatRoundedRect outer_clip = RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( style_, outer_rect, outer_insets, sides_to_include_); - graphics_context.ClipOutRoundedRect(outer_clip); - DrawBoxSideFromPath(graphics_context, border_rect, border_path, - border_thickness, stroke_thickness, side, color, - EBorderStyle::kSolid); + context_.ClipOutRoundedRect(outer_clip); + DrawBoxSideFromPath(border_path, border_thickness, stroke_thickness, side, + color, EBorderStyle::kSolid); } } void BoxBorderPainter::DrawRidgeGrooveBoxSideFromPath( - GraphicsContext& graphics_context, - const PhysicalRect& border_rect, const Path& border_path, float border_thickness, float stroke_thickness, @@ -1190,43 +1387,56 @@ } // Paint full border - DrawBoxSideFromPath(graphics_context, border_rect, border_path, - border_thickness, stroke_thickness, side, color, s1); + DrawBoxSideFromPath(border_path, border_thickness, stroke_thickness, side, + color, s1); // Paint inner only - GraphicsContextStateSaver state_saver(graphics_context); - int top_width = edges_[static_cast<unsigned>(BoxSide::kTop)].UsedWidth() / 2; - int bottom_width = - edges_[static_cast<unsigned>(BoxSide::kBottom)].UsedWidth() / 2; - int left_width = - edges_[static_cast<unsigned>(BoxSide::kLeft)].UsedWidth() / 2; - int right_width = - edges_[static_cast<unsigned>(BoxSide::kRight)].UsedWidth() / 2; - + GraphicsContextStateSaver state_saver(context_); FloatRoundedRect clip_rect = RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( - style_, border_rect, - LayoutRectOutsets(-top_width, -right_width, -bottom_width, - -left_width), - sides_to_include_); + style_, border_rect_, CenterInsets(), sides_to_include_); - graphics_context.ClipRoundedRect(clip_rect); - DrawBoxSideFromPath(graphics_context, border_rect, border_path, - border_thickness, stroke_thickness, side, color, s2); + context_.ClipRoundedRect(clip_rect); + DrawBoxSideFromPath(border_path, border_thickness, stroke_thickness, side, + color, s2); } -void BoxBorderPainter::ClipBorderSideForComplexInnerPath( - GraphicsContext& graphics_context, +FloatRect BoxBorderPainter::CalculateSideRectIncludingInner( BoxSide side) const { - graphics_context.Clip(CalculateSideRectIncludingInner(outer_, edges_, side)); + FloatRect side_rect = outer_.Rect(); + float width; + + switch (side) { + case BoxSide::kTop: + width = side_rect.Height() - Edge(BoxSide::kBottom).Width(); + side_rect.SetHeight(width); + break; + case BoxSide::kBottom: + width = side_rect.Height() - Edge(BoxSide::kTop).Width(); + side_rect.ShiftYEdgeTo(side_rect.MaxY() - width); + break; + case BoxSide::kLeft: + width = side_rect.Width() - Edge(BoxSide::kRight).Width(); + side_rect.SetWidth(width); + break; + case BoxSide::kRight: + width = side_rect.Width() - Edge(BoxSide::kLeft).Width(); + side_rect.ShiftXEdgeTo(side_rect.MaxX() - width); + break; + } + + return side_rect; +} + +void BoxBorderPainter::ClipBorderSideForComplexInnerPath(BoxSide side) const { + context_.Clip(CalculateSideRectIncludingInner(side)); FloatRoundedRect adjusted_inner_rect = CalculateAdjustedInnerBorder(inner_, side); if (!adjusted_inner_rect.IsEmpty()) - graphics_context.ClipOutRoundedRect(adjusted_inner_rect); + context_.ClipOutRoundedRect(adjusted_inner_rect); } -void BoxBorderPainter::ClipBorderSidePolygon(GraphicsContext& graphics_context, - BoxSide side, +void BoxBorderPainter::ClipBorderSidePolygon(BoxSide side, MiterType first_miter, MiterType second_miter) const { DCHECK(first_miter != kNoMiter || second_miter != kNoMiter); @@ -1446,7 +1656,7 @@ } if (first_miter == second_miter) { - ClipQuad(graphics_context, edge_quad, first_miter == kSoftMiter); + ClipQuad(context_, edge_quad, first_miter == kSoftMiter); return; } @@ -1466,7 +1676,7 @@ clipping_quad[2] = bound_quad2; clipping_quad[3] = edge_quad[3]; - ClipQuad(graphics_context, clipping_quad, first_miter == kSoftMiter); + ClipQuad(context_, clipping_quad, first_miter == kSoftMiter); } if (second_miter != kNoMiter) { @@ -1479,7 +1689,101 @@ clipping_quad[2] -= extension_offset; clipping_quad[3] = edge_quad[3] - extension_offset; - ClipQuad(graphics_context, clipping_quad, second_miter == kSoftMiter); + ClipQuad(context_, clipping_quad, second_miter == kSoftMiter); + } +} + +LayoutRectOutsets BoxBorderPainter::DoubleStripeInsets( + BorderEdge::DoubleBorderStripe stripe) const { + return LayoutRectOutsets( + -Edge(BoxSide::kTop).GetDoubleBorderStripeWidth(stripe), + -Edge(BoxSide::kRight).GetDoubleBorderStripeWidth(stripe), + -Edge(BoxSide::kBottom).GetDoubleBorderStripeWidth(stripe), + -Edge(BoxSide::kLeft).GetDoubleBorderStripeWidth(stripe)); +} + +LayoutRectOutsets BoxBorderPainter::CenterInsets() const { + return LayoutRectOutsets(-Edge(BoxSide::kTop).UsedWidth() * 0.5, + -Edge(BoxSide::kRight).UsedWidth() * 0.5, + -Edge(BoxSide::kBottom).UsedWidth() * 0.5, + -Edge(BoxSide::kLeft).UsedWidth() * 0.5); +} + +bool BoxBorderPainter::ColorsMatchAtCorner(BoxSide side, + BoxSide adjacent_side) const { + if (!Edge(adjacent_side).ShouldRender()) + return false; + + if (!Edge(side).SharesColorWith(Edge(adjacent_side))) + return false; + + return !BorderStyleHasUnmatchedColorsAtCorner(Edge(side).BorderStyle(), side, + adjacent_side); +} + +void BoxBorderPainter::DrawLineForBoxSide(GraphicsContext& context, + float x1, + float y1, + float x2, + float y2, + BoxSide side, + Color color, + EBorderStyle style, + int adjacent_width1, + int adjacent_width2, + bool antialias) { + float thickness; + float length; + if (side == BoxSide::kTop || side == BoxSide::kBottom) { + thickness = y2 - y1; + length = x2 - x1; + } else { + thickness = x2 - x1; + length = y2 - y1; + } + + // We would like this check to be an ASSERT as we don't want to draw empty + // borders. However nothing guarantees that the following recursive calls to + // DrawLineForBoxSide() will have positive thickness and length. + if (length <= 0 || thickness <= 0) + return; + + if (style == EBorderStyle::kDouble && thickness < 3) + style = EBorderStyle::kSolid; + + switch (style) { + case EBorderStyle::kNone: + case EBorderStyle::kHidden: + return; + case EBorderStyle::kDotted: + case EBorderStyle::kDashed: + DrawDashedOrDottedBoxSide(context, x1, y1, x2, y2, side, color, thickness, + style, antialias); + break; + case EBorderStyle::kDouble: + DrawDoubleBoxSide(context, x1, y1, x2, y2, length, side, color, thickness, + adjacent_width1, adjacent_width2, antialias); + break; + case EBorderStyle::kRidge: + case EBorderStyle::kGroove: + DrawRidgeOrGrooveBoxSide(context, x1, y1, x2, y2, side, color, style, + adjacent_width1, adjacent_width2, antialias); + break; + case EBorderStyle::kInset: + // FIXME: Maybe we should lighten the colors on one side like Firefox. + // https://bugs.webkit.org/show_bug.cgi?id=58608 + if (side == BoxSide::kTop || side == BoxSide::kLeft) + color = color.Dark(); + FALLTHROUGH; + case EBorderStyle::kOutset: + if (style == EBorderStyle::kOutset && + (side == BoxSide::kBottom || side == BoxSide::kRight)) + color = color.Dark(); + FALLTHROUGH; + case EBorderStyle::kSolid: + DrawSolidBoxSide(context, x1, y1, x2, y2, side, color, adjacent_width1, + adjacent_width2, antialias); + break; } }
diff --git a/third_party/blink/renderer/core/paint/box_border_painter.h b/third_party/blink/renderer/core/paint/box_border_painter.h index 42c6059..e8bc08da 100644 --- a/third_party/blink/renderer/core/paint/box_border_painter.h +++ b/third_party/blink/renderer/core/paint/box_border_painter.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/layout/background_bleed_avoidance.h" #include "third_party/blink/renderer/core/layout/geometry/box_sides.h" +#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" #include "third_party/blink/renderer/core/style/border_edge.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" @@ -15,7 +16,6 @@ class ComputedStyle; class GraphicsContext; class Path; -struct PaintInfo; struct PhysicalRect; typedef unsigned BorderEdgeFlags; @@ -24,19 +24,66 @@ STACK_ALLOCATED(); public: - BoxBorderPainter(const PhysicalRect& border_rect, + static void PaintBorder(GraphicsContext& context, + const PhysicalRect& border_rect, + const ComputedStyle& style, + BackgroundBleedAvoidance bleed_avoidance, + PhysicalBoxSides sides_to_include) { + BoxBorderPainter(context, border_rect, style, bleed_avoidance, + sides_to_include) + .Paint(); + } + + static void PaintSingleRectOutline(GraphicsContext& context, + const ComputedStyle& style, + const PhysicalRect& outer, + const PhysicalRect& inner, + const BorderEdge& edge) { + BoxBorderPainter(context, style, outer, inner, edge).Paint(); + } + + static void DrawBoxSide(GraphicsContext& context, + const IntRect& snapped_edge_rect, + BoxSide side, + Color color, + EBorderStyle style) { + DrawLineForBoxSide(context, snapped_edge_rect.X(), snapped_edge_rect.Y(), + snapped_edge_rect.MaxX(), snapped_edge_rect.MaxY(), side, + color, style, 0, 0, true); + } + + // TODO(crbug.com/1201762): The float parameters are truncated to int in the + // function, which implicitly snaps to whole pixels perhaps unexpectedly. To + // avoid the problem, we should use the above function which requires the + // caller to snap to whole pixels explicitly. + static void DrawLineForBoxSide(GraphicsContext&, + float x1, + float y1, + float x2, + float y2, + BoxSide, + Color, + EBorderStyle, + int adjacent_edge_width1, + int adjacent_edge_width2, + bool antialias = false); + + private: + // For PaintBorder(). + BoxBorderPainter(GraphicsContext&, + const PhysicalRect& border_rect, const ComputedStyle&, BackgroundBleedAvoidance, PhysicalBoxSides sides_to_include); - - BoxBorderPainter(const ComputedStyle&, + // For PaintSingleRectOutline(). + BoxBorderPainter(GraphicsContext&, + const ComputedStyle&, const PhysicalRect& outer, const PhysicalRect& inner, - const BorderEdge& uniform_edge_info); + const BorderEdge&); - void PaintBorder(const PaintInfo&, const PhysicalRect& border_rect) const; + void Paint() const; - private: struct ComplexBorderInfo; enum MiterType { kNoMiter, @@ -46,17 +93,14 @@ void ComputeBorderProperties(); - BorderEdgeFlags PaintOpacityGroup(GraphicsContext&, - const ComplexBorderInfo&, + BorderEdgeFlags PaintOpacityGroup(const ComplexBorderInfo&, unsigned index, float accumulated_opacity) const; - void PaintSide(GraphicsContext&, - const ComplexBorderInfo&, + void PaintSide(const ComplexBorderInfo&, BoxSide, unsigned alpha, BorderEdgeFlags) const; - void PaintOneBorderSide(GraphicsContext&, - const FloatRect& side_rect, + void PaintOneBorderSide(const FloatRect& side_rect, BoxSide, BoxSide adjacent_side1, BoxSide adjacent_side2, @@ -64,48 +108,34 @@ bool antialias, Color, BorderEdgeFlags) const; - bool PaintBorderFastPath(GraphicsContext&, - const PhysicalRect& border_rect) const; - void DrawDoubleBorder(GraphicsContext&, - const PhysicalRect& border_rect) const; + bool PaintBorderFastPath() const; + void DrawDoubleBorder() const; - void DrawBoxSideFromPath(GraphicsContext&, - const PhysicalRect&, - const Path&, + void DrawBoxSideFromPath(const Path&, float thickness, float draw_thickness, BoxSide, Color, EBorderStyle) const; - void DrawDashedDottedBoxSideFromPath(GraphicsContext&, - const PhysicalRect&, - float thickness, + void DrawDashedDottedBoxSideFromPath(float thickness, float draw_thickness, Color, EBorderStyle) const; - void DrawWideDottedBoxSideFromPath(GraphicsContext&, - const Path&, - float thickness) const; - void DrawDoubleBoxSideFromPath(GraphicsContext&, - const PhysicalRect&, - const Path&, + void DrawWideDottedBoxSideFromPath(const Path&, float thickness) const; + void DrawDoubleBoxSideFromPath(const Path&, float thickness, float draw_thickness, BoxSide, Color) const; - void DrawRidgeGrooveBoxSideFromPath(GraphicsContext&, - const PhysicalRect&, - const Path&, + void DrawRidgeGrooveBoxSideFromPath(const Path&, float thickness, float draw_thickness, BoxSide, Color, EBorderStyle) const; - void ClipBorderSidePolygon(GraphicsContext&, - BoxSide, - MiterType miter1, - MiterType miter2) const; - void ClipBorderSideForComplexInnerPath(GraphicsContext&, BoxSide) const; + void ClipBorderSidePolygon(BoxSide, MiterType miter1, MiterType miter2) const; + FloatRect CalculateSideRectIncludingInner(BoxSide) const; + void ClipBorderSideForComplexInnerPath(BoxSide) const; MiterType ComputeMiter(BoxSide, BoxSide adjacent_side, @@ -116,12 +146,26 @@ EBorderStyle, bool antialias); + LayoutRectOutsets DoubleStripeInsets( + BorderEdge::DoubleBorderStripe stripe) const; + LayoutRectOutsets CenterInsets() const; + + bool ColorsMatchAtCorner(BoxSide side, BoxSide adjacent_side) const; + const BorderEdge& FirstEdge() const { DCHECK(visible_edge_set_); return edges_[first_visible_edge_]; } + BorderEdge& Edge(BoxSide side) { return edges_[static_cast<unsigned>(side)]; } + const BorderEdge& Edge(BoxSide side) const { + return edges_[static_cast<unsigned>(side)]; + } + + GraphicsContext& context_; + // const inputs + const PhysicalRect border_rect_; const ComputedStyle& style_; const BackgroundBleedAvoidance bleed_avoidance_; const PhysicalBoxSides sides_to_include_;
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index 8535a6e..535b786 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -1043,9 +1043,8 @@ return; } - const BoxBorderPainter border_painter(rect, style, bleed_avoidance, - sides_to_include); - border_painter.PaintBorder(info, rect); + BoxBorderPainter::PaintBorder(info.context, rect, style, bleed_avoidance, + sides_to_include); } void BoxPainterBase::PaintMaskImages(const PaintInfo& paint_info,
diff --git a/third_party/blink/renderer/core/paint/build.gni b/third_party/blink/renderer/core/paint/build.gni index d04dd51..7812d2a 100644 --- a/third_party/blink/renderer/core/paint/build.gni +++ b/third_party/blink/renderer/core/paint/build.gni
@@ -152,8 +152,8 @@ "object_paint_properties.h", "object_painter.cc", "object_painter.h", - "object_painter_base.cc", - "object_painter_base.h", + "outline_painter.cc", + "outline_painter.h", "paint_event.h", "paint_info.h", "paint_invalidator.cc",
diff --git a/third_party/blink/renderer/core/paint/collapsed_border_painter.cc b/third_party/blink/renderer/core/paint/collapsed_border_painter.cc index b7147fd..5d84c77 100644 --- a/third_party/blink/renderer/core/paint/collapsed_border_painter.cc +++ b/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/paint/collapsed_border_painter.h" #include "third_party/blink/renderer/core/paint/block_painter.h" -#include "third_party/blink/renderer/core/paint/object_painter.h" +#include "third_party/blink/renderer/core/paint/box_border_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/scoped_paint_state.h" #include "third_party/blink/renderer/core/paint/table_cell_painter.h" @@ -362,36 +362,36 @@ rect.Y() - before_.outer_width, rect.Width() + before_.begin_outset + before_.end_outset, before_.outer_width + before_.inner_width); - ObjectPainter::DrawBoxSide(context, edge_rect, BoxSide::kTop, - before_.value->GetColor(), - CollapsedBorderStyle(before_.value->Style())); + BoxBorderPainter::DrawBoxSide(context, edge_rect, BoxSide::kTop, + before_.value->GetColor(), + CollapsedBorderStyle(before_.value->Style())); } if (after_.value) { IntRect edge_rect(rect.X() - after_.begin_outset, rect.MaxY() - after_.inner_width, rect.Width() + after_.begin_outset + after_.end_outset, after_.inner_width + after_.outer_width); - ObjectPainter::DrawBoxSide(context, edge_rect, BoxSide::kBottom, - after_.value->GetColor(), - CollapsedBorderStyle(after_.value->Style())); + BoxBorderPainter::DrawBoxSide(context, edge_rect, BoxSide::kBottom, + after_.value->GetColor(), + CollapsedBorderStyle(after_.value->Style())); } if (start_.value) { IntRect edge_rect(rect.X() - start_.outer_width, rect.Y() - start_.begin_outset, start_.outer_width + start_.inner_width, rect.Height() + start_.begin_outset + start_.end_outset); - ObjectPainter::DrawBoxSide(context, edge_rect, BoxSide::kLeft, - start_.value->GetColor(), - CollapsedBorderStyle(start_.value->Style())); + BoxBorderPainter::DrawBoxSide(context, edge_rect, BoxSide::kLeft, + start_.value->GetColor(), + CollapsedBorderStyle(start_.value->Style())); } if (end_.value) { IntRect edge_rect(rect.MaxX() - end_.inner_width, rect.Y() - end_.begin_outset, end_.inner_width + end_.outer_width, rect.Height() + end_.begin_outset + end_.end_outset); - ObjectPainter::DrawBoxSide(context, edge_rect, BoxSide::kRight, - end_.value->GetColor(), - CollapsedBorderStyle(end_.value->Style())); + BoxBorderPainter::DrawBoxSide(context, edge_rect, BoxSide::kRight, + end_.value->GetColor(), + CollapsedBorderStyle(end_.value->Style())); } }
diff --git a/third_party/blink/renderer/core/paint/multi_column_set_painter.cc b/third_party/blink/renderer/core/paint/multi_column_set_painter.cc index cfc9b9d2..043e55ae 100644 --- a/third_party/blink/renderer/core/paint/multi_column_set_painter.cc +++ b/third_party/blink/renderer/core/paint/multi_column_set_painter.cc
@@ -6,7 +6,7 @@ #include "third_party/blink/renderer/core/layout/layout_multi_column_set.h" #include "third_party/blink/renderer/core/paint/block_painter.h" -#include "third_party/blink/renderer/core/paint/object_painter.h" +#include "third_party/blink/renderer/core/paint/box_border_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/platform/geometry/layout_point.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" @@ -64,8 +64,8 @@ for (auto& bound : column_rule_bounds) { IntRect pixel_snapped_rule_rect = PixelSnappedIntRect(bound); - ObjectPainter::DrawBoxSide(paint_info.context, pixel_snapped_rule_rect, - box_side, rule_color, rule_style); + BoxBorderPainter::DrawBoxSide(paint_info.context, pixel_snapped_rule_rect, + box_side, rule_color, rule_style); } }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index 2f1d6ba..b39306e 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/layout/pointer_events_hit_rules.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/background_image_geometry.h" +#include "third_party/blink/renderer/core/paint/box_border_painter.h" #include "third_party/blink/renderer/core/paint/box_decoration_data.h" #include "third_party/blink/renderer/core/paint/box_painter.h" #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" @@ -1285,8 +1286,8 @@ rule.Move(paint_offset); IntRect snapped_rule = PixelSnappedIntRect(rule); - ObjectPainter::DrawBoxSide(paint_info.context, snapped_rule, box_side, - rule_color, rule_style); + BoxBorderPainter::DrawBoxSide(paint_info.context, snapped_rule, box_side, + rule_color, rule_style); recorder.UniteVisualRect(snapped_rule); previous_column = current_column;
diff --git a/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc index dd8d402d..d8e25214 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h" #include "third_party/blink/renderer/core/layout/ng/ng_outline_utils.h" +#include "third_party/blink/renderer/core/paint/outline_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" @@ -35,7 +36,8 @@ visual_rect.Inflate(style_to_use.OutlineOutsetExtent()); DrawingRecorder recorder(paint_info.context, display_item_client, paint_info.phase, visual_rect); - PaintOutlineRects(paint_info, outline_rects, style_to_use); + OutlinePainter::PaintOutlineRects(paint_info.context, outline_rects, + style_to_use); } void NGFragmentPainter::AddURLRectIfNeeded(const PaintInfo& paint_info,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h index 679d9aad..b62e614 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h
@@ -6,7 +6,6 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_FRAGMENT_PAINTER_H_ #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" -#include "third_party/blink/renderer/core/paint/object_painter_base.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" namespace blink { @@ -15,8 +14,8 @@ struct PhysicalOffset; // Generic fragment painter for paint logic shared between all types of -// fragments. LayoutNG version of ObjectPainter, based on ObjectPainterBase. -class NGFragmentPainter : public ObjectPainterBase { +// fragments. LayoutNG version of ObjectPainter. +class NGFragmentPainter { STACK_ALLOCATED(); public:
diff --git a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc index e5bf0c8..53bca621 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
@@ -13,11 +13,11 @@ #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h" #include "third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h" #include "third_party/blink/renderer/core/paint/background_image_geometry.h" +#include "third_party/blink/renderer/core/paint/box_border_painter.h" #include "third_party/blink/renderer/core/paint/box_decoration_data.h" #include "third_party/blink/renderer/core/paint/box_model_object_painter.h" #include "third_party/blink/renderer/core/paint/box_painter.h" #include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h" -#include "third_party/blink/renderer/core/paint/object_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/scoped_paint_state.h" @@ -527,7 +527,7 @@ } else { box_side = edge.IsInlineAxis() ? BoxSide::kLeft : BoxSide::kTop; } - ObjectPainter::DrawBoxSide( + BoxBorderPainter::DrawBoxSide( paint_info.context, PixelSnappedIntRect(physical_border_rect), box_side, edge.BorderColor(), edge.BorderStyle()); }
diff --git a/third_party/blink/renderer/core/paint/object_painter.cc b/third_party/blink/renderer/core/paint/object_painter.cc index a59fa4d..51893f5 100644 --- a/third_party/blink/renderer/core/paint/object_painter.cc +++ b/third_party/blink/renderer/core/paint/object_painter.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" +#include "third_party/blink/renderer/core/paint/outline_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/style/border_edge.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -50,7 +51,8 @@ visual_rect.Inflate(style_to_use.OutlineOutsetExtent()); DrawingRecorder recorder(paint_info.context, layout_object_, paint_info.phase, visual_rect); - PaintOutlineRects(paint_info, outline_rects, style_to_use); + OutlinePainter::PaintOutlineRects(paint_info.context, outline_rects, + style_to_use); } void ObjectPainter::PaintInlineChildrenOutlines(const PaintInfo& paint_info) {
diff --git a/third_party/blink/renderer/core/paint/object_painter.h b/third_party/blink/renderer/core/paint/object_painter.h index 25a0c8b..5d001b5 100644 --- a/third_party/blink/renderer/core/paint/object_painter.h +++ b/third_party/blink/renderer/core/paint/object_painter.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OBJECT_PAINTER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OBJECT_PAINTER_H_ -#include "third_party/blink/renderer/core/paint/object_painter_base.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -15,7 +14,7 @@ struct PaintInfo; struct PhysicalOffset; -class ObjectPainter : public ObjectPainterBase { +class ObjectPainter { STACK_ALLOCATED(); public:
diff --git a/third_party/blink/renderer/core/paint/object_painter_base.cc b/third_party/blink/renderer/core/paint/object_painter_base.cc deleted file mode 100644 index be014b8d..0000000 --- a/third_party/blink/renderer/core/paint/object_painter_base.cc +++ /dev/null
@@ -1,664 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/paint/object_painter_base.h" - -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/renderer/core/paint/box_border_painter.h" -#include "third_party/blink/renderer/core/paint/paint_info.h" -#include "third_party/blink/renderer/core/style/border_edge.h" -#include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/platform/graphics/color.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" -#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" -#include "ui/base/ui_base_features.h" -#include "ui/native_theme/native_theme.h" - -namespace blink { - -namespace { - -struct OutlineEdgeInfo { - int x1; - int y1; - int x2; - int y2; - BoxSide side; -}; - -// Adjust length of edges if needed. Returns the width of the joint. -int AdjustJoint(int outline_width, - OutlineEdgeInfo& edge1, - OutlineEdgeInfo& edge2) { - // A clockwise joint: - // - needs no adjustment of edge length because our edges are along the - // clockwise outer edge of the outline; - // - needs a positive adjacent joint width (required by - // ObjectPainterBase::DrawLineForBoxSide). A counterclockwise joint: - needs - // to increase the edge length to include the joint; - needs a negative - // adjacent joint width (required by ObjectPainterBase::DrawLineForBoxSide). - switch (edge1.side) { - case BoxSide::kTop: - switch (edge2.side) { - case BoxSide::kRight: // Clockwise - return outline_width; - case BoxSide::kLeft: // Counterclockwise - edge1.x2 += outline_width; - edge2.y2 += outline_width; - return -outline_width; - default: // Same side or no joint. - return 0; - } - case BoxSide::kRight: - switch (edge2.side) { - case BoxSide::kBottom: // Clockwise - return outline_width; - case BoxSide::kTop: // Counterclockwise - edge1.y2 += outline_width; - edge2.x1 -= outline_width; - return -outline_width; - default: // Same side or no joint. - return 0; - } - case BoxSide::kBottom: - switch (edge2.side) { - case BoxSide::kLeft: // Clockwise - return outline_width; - case BoxSide::kRight: // Counterclockwise - edge1.x1 -= outline_width; - edge2.y1 -= outline_width; - return -outline_width; - default: // Same side or no joint. - return 0; - } - case BoxSide::kLeft: - switch (edge2.side) { - case BoxSide::kTop: // Clockwise - return outline_width; - case BoxSide::kBottom: // Counterclockwise - edge1.y1 -= outline_width; - edge2.x2 += outline_width; - return -outline_width; - default: // Same side or no joint. - return 0; - } - default: - NOTREACHED(); - return 0; - } -} - -void ApplyOutlineOffset(IntRect& rect, int offset) { - // A negative outline-offset should not cause the rendered outline shape to - // become smaller than twice the computed value of the outline-width, in each - // direction separately. See: https://drafts.csswg.org/css-ui/#outline-offset - rect.InflateX(std::max(offset, -rect.Width() / 2)); - rect.InflateY(std::max(offset, -rect.Height() / 2)); -} - -void PaintComplexOutline(GraphicsContext& graphics_context, - const Vector<IntRect> rects, - const ComputedStyle& style, - const Color& color) { - DCHECK(!style.OutlineStyleIsAuto()); - - // Construct a clockwise path along the outer edge of the outline. - SkRegion region; - uint16_t width = style.OutlineWidthInt(); - int offset = style.OutlineOffsetInt(); - for (auto& r : rects) { - IntRect rect = r; - ApplyOutlineOffset(rect, offset); - rect.Inflate(width); - region.op(rect, SkRegion::kUnion_Op); - } - SkPath path; - if (!region.getBoundaryPath(&path)) - return; - - Vector<OutlineEdgeInfo, 4> edges; - - SkPath::RawIter iter(path); - SkPoint points[4], first_point, last_point; - wtf_size_t count = 0; - for (SkPath::Verb verb = iter.next(points); verb != SkPath::kDone_Verb; - verb = iter.next(points)) { - // Keep track of the first and last point of each contour (started with - // kMove_Verb) so we can add the closing-line on kClose_Verb. - if (verb == SkPath::kMove_Verb) { - first_point = points[0]; - last_point = first_point; // this gets reset after each line, but we - // initialize it here - } else if (verb == SkPath::kClose_Verb) { - // create an artificial line to close the contour - verb = SkPath::kLine_Verb; - points[0] = last_point; - points[1] = first_point; - } - if (verb != SkPath::kLine_Verb) - continue; - last_point = points[1]; - - edges.Grow(++count); - OutlineEdgeInfo& edge = edges.back(); - edge.x1 = SkScalarTruncToInt(points[0].x()); - edge.y1 = SkScalarTruncToInt(points[0].y()); - edge.x2 = SkScalarTruncToInt(points[1].x()); - edge.y2 = SkScalarTruncToInt(points[1].y()); - if (edge.x1 == edge.x2) { - if (edge.y1 < edge.y2) { - edge.x1 -= width; - edge.side = BoxSide::kRight; - } else { - std::swap(edge.y1, edge.y2); - edge.x2 += width; - edge.side = BoxSide::kLeft; - } - } else { - DCHECK(edge.y1 == edge.y2); - if (edge.x1 < edge.x2) { - edge.y2 += width; - edge.side = BoxSide::kTop; - } else { - std::swap(edge.x1, edge.x2); - edge.y1 -= width; - edge.side = BoxSide::kBottom; - } - } - } - - if (!count) - return; - - Color outline_color = color; - bool use_transparency_layer = color.HasAlpha(); - if (use_transparency_layer) { - graphics_context.BeginLayer(static_cast<float>(color.Alpha()) / 255); - outline_color = - Color(outline_color.Red(), outline_color.Green(), outline_color.Blue()); - } - - DCHECK(count >= 4 && edges.size() == count); - int first_adjacent_width = AdjustJoint(width, edges.back(), edges.front()); - - // The width of the angled part of starting and ending joint of the current - // edge. - int adjacent_width_start = first_adjacent_width; - int adjacent_width_end; - for (wtf_size_t i = 0; i < count; ++i) { - OutlineEdgeInfo& edge = edges[i]; - adjacent_width_end = i == count - 1 - ? first_adjacent_width - : AdjustJoint(width, edge, edges[i + 1]); - int adjacent_width1 = adjacent_width_start; - int adjacent_width2 = adjacent_width_end; - if (edge.side == BoxSide::kLeft || edge.side == BoxSide::kBottom) - std::swap(adjacent_width1, adjacent_width2); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, edge.x1, edge.y1, edge.x2, edge.y2, edge.side, - outline_color, style.OutlineStyle(), adjacent_width1, adjacent_width2, - false); - adjacent_width_start = adjacent_width_end; - } - - if (use_transparency_layer) - graphics_context.EndLayer(); -} - -void PaintSingleRectangleOutline(const PaintInfo& paint_info, - const IntRect& rect, - const ComputedStyle& style, - const Color& color) { - DCHECK(!style.OutlineStyleIsAuto()); - - IntRect offset_rect = rect; - ApplyOutlineOffset(offset_rect, style.OutlineOffsetInt()); - - PhysicalRect inner(offset_rect); - PhysicalRect outer(inner); - outer.Inflate(LayoutUnit(style.OutlineWidthInt())); - const BorderEdge common_edge_info(style.OutlineWidthInt(), color, - style.OutlineStyle()); - BoxBorderPainter(style, outer, inner, common_edge_info) - .PaintBorder(paint_info, outer); -} - -void FillQuad(GraphicsContext& context, - const FloatPoint quad[], - const Color& color, - bool antialias) { - SkPathBuilder path; - path.moveTo(FloatPointToSkPoint(quad[0])); - path.lineTo(FloatPointToSkPoint(quad[1])); - path.lineTo(FloatPointToSkPoint(quad[2])); - path.lineTo(FloatPointToSkPoint(quad[3])); - PaintFlags flags(context.FillFlags()); - flags.setAntiAlias(antialias); - flags.setColor(color.Rgb()); - - context.DrawPath(path.detach(), flags); -} - -void DrawDashedOrDottedBoxSide(GraphicsContext& graphics_context, - int x1, - int y1, - int x2, - int y2, - BoxSide side, - Color color, - int thickness, - EBorderStyle style, - bool antialias) { - DCHECK_GT(thickness, 0); - - GraphicsContextStateSaver state_saver(graphics_context); - graphics_context.SetShouldAntialias(antialias); - graphics_context.SetStrokeColor(color); - graphics_context.SetStrokeThickness(thickness); - graphics_context.SetStrokeStyle( - style == EBorderStyle::kDashed ? kDashedStroke : kDottedStroke); - - switch (side) { - case BoxSide::kBottom: - case BoxSide::kTop: { - int mid_y = y1 + thickness / 2; - graphics_context.DrawLine(IntPoint(x1, mid_y), IntPoint(x2, mid_y)); - break; - } - case BoxSide::kRight: - case BoxSide::kLeft: { - int mid_x = x1 + thickness / 2; - graphics_context.DrawLine(IntPoint(mid_x, y1), IntPoint(mid_x, y2)); - break; - } - } -} - -void DrawDoubleBoxSide(GraphicsContext& graphics_context, - int x1, - int y1, - int x2, - int y2, - int length, - BoxSide side, - Color color, - float thickness, - int adjacent_width1, - int adjacent_width2, - bool antialias) { - int third_of_thickness = (thickness + 1) / 3; - DCHECK_GT(third_of_thickness, 0); - - if (!adjacent_width1 && !adjacent_width2) { - StrokeStyle old_stroke_style = graphics_context.GetStrokeStyle(); - graphics_context.SetStrokeStyle(kNoStroke); - graphics_context.SetFillColor(color); - - bool was_antialiased = graphics_context.ShouldAntialias(); - graphics_context.SetShouldAntialias(antialias); - - switch (side) { - case BoxSide::kTop: - case BoxSide::kBottom: - graphics_context.DrawRect(IntRect(x1, y1, length, third_of_thickness)); - graphics_context.DrawRect( - IntRect(x1, y2 - third_of_thickness, length, third_of_thickness)); - break; - case BoxSide::kLeft: - case BoxSide::kRight: - graphics_context.DrawRect(IntRect(x1, y1, third_of_thickness, length)); - graphics_context.DrawRect( - IntRect(x2 - third_of_thickness, y1, third_of_thickness, length)); - break; - } - - graphics_context.SetShouldAntialias(was_antialiased); - graphics_context.SetStrokeStyle(old_stroke_style); - return; - } - - int adjacent1_big_third = - ((adjacent_width1 > 0) ? adjacent_width1 + 1 : adjacent_width1 - 1) / 3; - int adjacent2_big_third = - ((adjacent_width2 > 0) ? adjacent_width2 + 1 : adjacent_width2 - 1) / 3; - - switch (side) { - case BoxSide::kTop: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), - y1, x2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), - y1 + third_of_thickness, side, color, EBorderStyle::kSolid, - adjacent1_big_third, adjacent2_big_third, antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), - y2 - third_of_thickness, - x2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), y2, side, color, - EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, - antialias); - break; - case BoxSide::kLeft: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1, - y1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), - x1 + third_of_thickness, - y2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), side, color, - EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, - antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x2 - third_of_thickness, - y1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), x2, - y2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), side, color, - EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, - antialias); - break; - case BoxSide::kBottom: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), y1, - x2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), - y1 + third_of_thickness, side, color, EBorderStyle::kSolid, - adjacent1_big_third, adjacent2_big_third, antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), - y2 - third_of_thickness, - x2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), y2, side, color, - EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, - antialias); - break; - case BoxSide::kRight: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1, y1 + std::max((adjacent_width1 * 2 + 1) / 3, 0), - x1 + third_of_thickness, - y2 - std::max((adjacent_width2 * 2 + 1) / 3, 0), side, color, - EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, - antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x2 - third_of_thickness, - y1 + std::max((-adjacent_width1 * 2 + 1) / 3, 0), x2, - y2 - std::max((-adjacent_width2 * 2 + 1) / 3, 0), side, color, - EBorderStyle::kSolid, adjacent1_big_third, adjacent2_big_third, - antialias); - break; - default: - break; - } -} - -void DrawRidgeOrGrooveBoxSide(GraphicsContext& graphics_context, - int x1, - int y1, - int x2, - int y2, - BoxSide side, - Color color, - EBorderStyle style, - int adjacent_width1, - int adjacent_width2, - bool antialias) { - EBorderStyle s1; - EBorderStyle s2; - if (style == EBorderStyle::kGroove) { - s1 = EBorderStyle::kInset; - s2 = EBorderStyle::kOutset; - } else { - s1 = EBorderStyle::kOutset; - s2 = EBorderStyle::kInset; - } - - int adjacent1_big_half = - ((adjacent_width1 > 0) ? adjacent_width1 + 1 : adjacent_width1 - 1) / 2; - int adjacent2_big_half = - ((adjacent_width2 > 0) ? adjacent_width2 + 1 : adjacent_width2 - 1) / 2; - - switch (side) { - case BoxSide::kTop: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max(-adjacent_width1, 0) / 2, y1, - x2 - std::max(-adjacent_width2, 0) / 2, (y1 + y2 + 1) / 2, side, - color, s1, adjacent1_big_half, adjacent2_big_half, antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max(adjacent_width1 + 1, 0) / 2, - (y1 + y2 + 1) / 2, x2 - std::max(adjacent_width2 + 1, 0) / 2, y2, - side, color, s2, adjacent_width1 / 2, adjacent_width2 / 2, antialias); - break; - case BoxSide::kLeft: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1, y1 + std::max(-adjacent_width1, 0) / 2, - (x1 + x2 + 1) / 2, y2 - std::max(-adjacent_width2, 0) / 2, side, - color, s1, adjacent1_big_half, adjacent2_big_half, antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, (x1 + x2 + 1) / 2, - y1 + std::max(adjacent_width1 + 1, 0) / 2, x2, - y2 - std::max(adjacent_width2 + 1, 0) / 2, side, color, s2, - adjacent_width1 / 2, adjacent_width2 / 2, antialias); - break; - case BoxSide::kBottom: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max(adjacent_width1, 0) / 2, y1, - x2 - std::max(adjacent_width2, 0) / 2, (y1 + y2 + 1) / 2, side, color, - s2, adjacent1_big_half, adjacent2_big_half, antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1 + std::max(-adjacent_width1 + 1, 0) / 2, - (y1 + y2 + 1) / 2, x2 - std::max(-adjacent_width2 + 1, 0) / 2, y2, - side, color, s1, adjacent_width1 / 2, adjacent_width2 / 2, antialias); - break; - case BoxSide::kRight: - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, x1, y1 + std::max(adjacent_width1, 0) / 2, - (x1 + x2 + 1) / 2, y2 - std::max(adjacent_width2, 0) / 2, side, color, - s2, adjacent1_big_half, adjacent2_big_half, antialias); - ObjectPainterBase::DrawLineForBoxSide( - graphics_context, (x1 + x2 + 1) / 2, - y1 + std::max(-adjacent_width1 + 1, 0) / 2, x2, - y2 - std::max(-adjacent_width2 + 1, 0) / 2, side, color, s1, - adjacent_width1 / 2, adjacent_width2 / 2, antialias); - break; - } -} - -void DrawSolidBoxSide(GraphicsContext& graphics_context, - int x1, - int y1, - int x2, - int y2, - BoxSide side, - Color color, - int adjacent_width1, - int adjacent_width2, - bool antialias) { - DCHECK_GE(x2, x1); - DCHECK_GE(y2, y1); - - if (!adjacent_width1 && !adjacent_width2) { - // Tweak antialiasing to match the behavior of fillQuad(); - // this matters for rects in transformed contexts. - bool was_antialiased = graphics_context.ShouldAntialias(); - if (antialias != was_antialiased) - graphics_context.SetShouldAntialias(antialias); - graphics_context.FillRect(IntRect(x1, y1, x2 - x1, y2 - y1), color); - if (antialias != was_antialiased) - graphics_context.SetShouldAntialias(was_antialiased); - return; - } - - FloatPoint quad[4]; - switch (side) { - case BoxSide::kTop: - quad[0] = FloatPoint(x1 + std::max(-adjacent_width1, 0), y1); - quad[1] = FloatPoint(x1 + std::max(adjacent_width1, 0), y2); - quad[2] = FloatPoint(x2 - std::max(adjacent_width2, 0), y2); - quad[3] = FloatPoint(x2 - std::max(-adjacent_width2, 0), y1); - break; - case BoxSide::kBottom: - quad[0] = FloatPoint(x1 + std::max(adjacent_width1, 0), y1); - quad[1] = FloatPoint(x1 + std::max(-adjacent_width1, 0), y2); - quad[2] = FloatPoint(x2 - std::max(-adjacent_width2, 0), y2); - quad[3] = FloatPoint(x2 - std::max(adjacent_width2, 0), y1); - break; - case BoxSide::kLeft: - quad[0] = FloatPoint(x1, y1 + std::max(-adjacent_width1, 0)); - quad[1] = FloatPoint(x1, y2 - std::max(-adjacent_width2, 0)); - quad[2] = FloatPoint(x2, y2 - std::max(adjacent_width2, 0)); - quad[3] = FloatPoint(x2, y1 + std::max(adjacent_width1, 0)); - break; - case BoxSide::kRight: - quad[0] = FloatPoint(x1, y1 + std::max(adjacent_width1, 0)); - quad[1] = FloatPoint(x1, y2 - std::max(adjacent_width2, 0)); - quad[2] = FloatPoint(x2, y2 - std::max(-adjacent_width2, 0)); - quad[3] = FloatPoint(x2, y1 + std::max(-adjacent_width1, 0)); - break; - } - - FillQuad(graphics_context, quad, color, antialias); -} - -float GetFocusRingBorderRadius(const ComputedStyle& style) { - // Default style is border-radius equal to outline width. - float border_radius = style.GetOutlineStrokeWidthForFocusRing(); - if (!style.HasAuthorBorder() && style.HasEffectiveAppearance()) { - // For the elements that have not been styled and that have an appearance, - // the focus ring should use the same border radius as the one used for - // drawing the element. - absl::optional<ui::NativeTheme::Part> part; - switch (style.EffectiveAppearance()) { - case kCheckboxPart: - part = ui::NativeTheme::kCheckbox; - break; - case kRadioPart: - part = ui::NativeTheme::kRadio; - break; - case kPushButtonPart: - case kSquareButtonPart: - case kButtonPart: - part = ui::NativeTheme::kPushButton; - break; - case kTextFieldPart: - case kTextAreaPart: - case kSearchFieldPart: - part = ui::NativeTheme::kTextField; - break; - default: - break; - } - if (part) { - border_radius = - ui::NativeTheme::GetInstanceForWeb()->GetBorderRadiusForPart( - part.value(), style.Width().GetFloatValue(), - style.Height().GetFloatValue()); - - // Form controls send to NativeTheme have zoom applied. But the focus ring - // outline does not. Apply zoom to checkbox focus ring. - return (style.EffectiveAppearance() == kCheckboxPart) - ? border_radius * style.EffectiveZoom() - : border_radius; - } - } - - return border_radius; -} - -} // anonymous namespace - -void ObjectPainterBase::PaintOutlineRects( - const PaintInfo& paint_info, - const Vector<PhysicalRect>& outline_rects, - const ComputedStyle& style) { - Vector<IntRect> pixel_snapped_outline_rects; - for (auto& r : outline_rects) - pixel_snapped_outline_rects.push_back(PixelSnappedIntRect(r)); - - Color color = style.VisitedDependentColor(GetCSSPropertyOutlineColor()); - if (style.OutlineStyleIsAuto()) { - // Logic in draw focus ring is dependent on whether the border is large - // enough to have an inset outline. Use the smallest border edge for that - // test. - float min_border_width = - std::min(std::min(style.BorderTopWidth(), style.BorderBottomWidth()), - std::min(style.BorderLeftWidth(), style.BorderRightWidth())); - float border_radius = GetFocusRingBorderRadius(style); - paint_info.context.DrawFocusRing( - pixel_snapped_outline_rects, style.GetOutlineStrokeWidthForFocusRing(), - style.OutlineOffsetInt(), border_radius, min_border_width, color, - style.UsedColorScheme()); - return; - } - - IntRect united_outline_rect = UnionRect(pixel_snapped_outline_rects); - if (united_outline_rect == pixel_snapped_outline_rects[0]) { - PaintSingleRectangleOutline(paint_info, united_outline_rect, style, color); - return; - } - PaintComplexOutline(paint_info.context, pixel_snapped_outline_rects, style, - color); -} - -void ObjectPainterBase::DrawLineForBoxSide(GraphicsContext& graphics_context, - float x1, - float y1, - float x2, - float y2, - BoxSide side, - Color color, - EBorderStyle style, - int adjacent_width1, - int adjacent_width2, - bool antialias) { - float thickness; - float length; - if (side == BoxSide::kTop || side == BoxSide::kBottom) { - thickness = y2 - y1; - length = x2 - x1; - } else { - thickness = x2 - x1; - length = y2 - y1; - } - - // We would like this check to be an ASSERT as we don't want to draw empty - // borders. However nothing guarantees that the following recursive calls to - // ObjectPainterBase::DrawLineForBoxSide will have positive thickness and - // length. - if (length <= 0 || thickness <= 0) - return; - - if (style == EBorderStyle::kDouble && thickness < 3) - style = EBorderStyle::kSolid; - - switch (style) { - case EBorderStyle::kNone: - case EBorderStyle::kHidden: - return; - case EBorderStyle::kDotted: - case EBorderStyle::kDashed: - DrawDashedOrDottedBoxSide(graphics_context, x1, y1, x2, y2, side, color, - thickness, style, antialias); - break; - case EBorderStyle::kDouble: - DrawDoubleBoxSide(graphics_context, x1, y1, x2, y2, length, side, color, - thickness, adjacent_width1, adjacent_width2, antialias); - break; - case EBorderStyle::kRidge: - case EBorderStyle::kGroove: - DrawRidgeOrGrooveBoxSide(graphics_context, x1, y1, x2, y2, side, color, - style, adjacent_width1, adjacent_width2, - antialias); - break; - case EBorderStyle::kInset: - // FIXME: Maybe we should lighten the colors on one side like Firefox. - // https://bugs.webkit.org/show_bug.cgi?id=58608 - if (side == BoxSide::kTop || side == BoxSide::kLeft) - color = color.Dark(); - FALLTHROUGH; - case EBorderStyle::kOutset: - if (style == EBorderStyle::kOutset && - (side == BoxSide::kBottom || side == BoxSide::kRight)) - color = color.Dark(); - FALLTHROUGH; - case EBorderStyle::kSolid: - DrawSolidBoxSide(graphics_context, x1, y1, x2, y2, side, color, - adjacent_width1, adjacent_width2, antialias); - break; - } -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/object_painter_base.h b/third_party/blink/renderer/core/paint/object_painter_base.h deleted file mode 100644 index 4f83f19..0000000 --- a/third_party/blink/renderer/core/paint/object_painter_base.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OBJECT_PAINTER_BASE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OBJECT_PAINTER_BASE_H_ - -#include "third_party/blink/renderer/core/style/computed_style_constants.h" -#include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/graphics/color.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class ComputedStyle; -class GraphicsContext; -struct PaintInfo; -struct PhysicalRect; - -// Base class for object painting. Has no dependencies on the layout tree and -// thus provides functionality and definitions that can be shared between both -// legacy layout and LayoutNG. -class ObjectPainterBase { - STACK_ALLOCATED(); - - public: - static void DrawBoxSide(GraphicsContext& context, - const IntRect& snapped_edge_rect, - BoxSide side, - Color color, - EBorderStyle style) { - DrawLineForBoxSide(context, snapped_edge_rect.X(), snapped_edge_rect.Y(), - snapped_edge_rect.MaxX(), snapped_edge_rect.MaxY(), side, - color, style, 0, 0, true); - } - - // TODO(wangxianzhu): The float parameters are truncated to int in the - // function, which implicitly snaps to whole pixels incorrectly. We should - // always use the above function. For now the only outside caller is - // BoxBorderPainter::PaintOneBorderSide(). - static void DrawLineForBoxSide(GraphicsContext&, - float x1, - float y1, - float x2, - float y2, - BoxSide, - Color, - EBorderStyle, - int adjacent_edge_width1, - int adjacent_edge_width2, - bool antialias = false); - - protected: - ObjectPainterBase() = default; - void PaintOutlineRects(const PaintInfo&, - const Vector<PhysicalRect>&, - const ComputedStyle&); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OBJECT_PAINTER_BASE_H_
diff --git a/third_party/blink/renderer/core/paint/outline_painter.cc b/third_party/blink/renderer/core/paint/outline_painter.cc new file mode 100644 index 0000000..6b1d3ea --- /dev/null +++ b/third_party/blink/renderer/core/paint/outline_painter.cc
@@ -0,0 +1,307 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/paint/outline_painter.h" + +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" +#include "third_party/blink/renderer/core/paint/box_border_painter.h" +#include "third_party/blink/renderer/core/style/border_edge.h" +#include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/platform/geometry/int_rect.h" +#include "third_party/blink/renderer/platform/graphics/color.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" +#include "ui/native_theme/native_theme.h" + +namespace blink { + +namespace { + +struct OutlineEdgeInfo { + int x1; + int y1; + int x2; + int y2; + BoxSide side; +}; + +// Adjust length of edges if needed. Returns the width of the joint. +int AdjustJoint(int outline_width, + OutlineEdgeInfo& edge1, + OutlineEdgeInfo& edge2) { + // A clockwise joint: + // - needs no adjustment of edge length because our edges are along the + // clockwise outer edge of the outline; + // - needs a positive adjacent joint width (required by + // BoxBorderPainter::DrawLineForBoxSide). + // A counterclockwise joint: + // - needs to increase the edge length to include the joint; + // - needs a negative adjacent joint width (required by + // BoxBorderPainter::DrawLineForBoxSide). + switch (edge1.side) { + case BoxSide::kTop: + switch (edge2.side) { + case BoxSide::kRight: // Clockwise + return outline_width; + case BoxSide::kLeft: // Counterclockwise + edge1.x2 += outline_width; + edge2.y2 += outline_width; + return -outline_width; + default: // Same side or no joint. + return 0; + } + case BoxSide::kRight: + switch (edge2.side) { + case BoxSide::kBottom: // Clockwise + return outline_width; + case BoxSide::kTop: // Counterclockwise + edge1.y2 += outline_width; + edge2.x1 -= outline_width; + return -outline_width; + default: // Same side or no joint. + return 0; + } + case BoxSide::kBottom: + switch (edge2.side) { + case BoxSide::kLeft: // Clockwise + return outline_width; + case BoxSide::kRight: // Counterclockwise + edge1.x1 -= outline_width; + edge2.y1 -= outline_width; + return -outline_width; + default: // Same side or no joint. + return 0; + } + case BoxSide::kLeft: + switch (edge2.side) { + case BoxSide::kTop: // Clockwise + return outline_width; + case BoxSide::kBottom: // Counterclockwise + edge1.y1 -= outline_width; + edge2.x2 += outline_width; + return -outline_width; + default: // Same side or no joint. + return 0; + } + default: + NOTREACHED(); + return 0; + } +} + +void ApplyOutlineOffset(IntRect& rect, int offset) { + // A negative outline-offset should not cause the rendered outline shape to + // become smaller than twice the computed value of the outline-width, in each + // direction separately. See: https://drafts.csswg.org/css-ui/#outline-offset + rect.InflateX(std::max(offset, -rect.Width() / 2)); + rect.InflateY(std::max(offset, -rect.Height() / 2)); +} + +void PaintComplexOutline(GraphicsContext& graphics_context, + const Vector<IntRect> rects, + const ComputedStyle& style, + const Color& color) { + DCHECK(!style.OutlineStyleIsAuto()); + + // Construct a clockwise path along the outer edge of the outline. + SkRegion region; + uint16_t width = style.OutlineWidthInt(); + int offset = style.OutlineOffsetInt(); + for (auto& r : rects) { + IntRect rect = r; + ApplyOutlineOffset(rect, offset); + rect.Inflate(width); + region.op(rect, SkRegion::kUnion_Op); + } + SkPath path; + if (!region.getBoundaryPath(&path)) + return; + + Vector<OutlineEdgeInfo, 4> edges; + + SkPath::RawIter iter(path); + SkPoint points[4], first_point, last_point; + wtf_size_t count = 0; + for (SkPath::Verb verb = iter.next(points); verb != SkPath::kDone_Verb; + verb = iter.next(points)) { + // Keep track of the first and last point of each contour (started with + // kMove_Verb) so we can add the closing-line on kClose_Verb. + if (verb == SkPath::kMove_Verb) { + first_point = points[0]; + last_point = first_point; // this gets reset after each line, but we + // initialize it here + } else if (verb == SkPath::kClose_Verb) { + // create an artificial line to close the contour + verb = SkPath::kLine_Verb; + points[0] = last_point; + points[1] = first_point; + } + if (verb != SkPath::kLine_Verb) + continue; + last_point = points[1]; + + edges.Grow(++count); + OutlineEdgeInfo& edge = edges.back(); + edge.x1 = SkScalarTruncToInt(points[0].x()); + edge.y1 = SkScalarTruncToInt(points[0].y()); + edge.x2 = SkScalarTruncToInt(points[1].x()); + edge.y2 = SkScalarTruncToInt(points[1].y()); + if (edge.x1 == edge.x2) { + if (edge.y1 < edge.y2) { + edge.x1 -= width; + edge.side = BoxSide::kRight; + } else { + std::swap(edge.y1, edge.y2); + edge.x2 += width; + edge.side = BoxSide::kLeft; + } + } else { + DCHECK(edge.y1 == edge.y2); + if (edge.x1 < edge.x2) { + edge.y2 += width; + edge.side = BoxSide::kTop; + } else { + std::swap(edge.x1, edge.x2); + edge.y1 -= width; + edge.side = BoxSide::kBottom; + } + } + } + + if (!count) + return; + + Color outline_color = color; + bool use_transparency_layer = color.HasAlpha(); + if (use_transparency_layer) { + graphics_context.BeginLayer(static_cast<float>(color.Alpha()) / 255); + outline_color = + Color(outline_color.Red(), outline_color.Green(), outline_color.Blue()); + } + + DCHECK(count >= 4 && edges.size() == count); + int first_adjacent_width = AdjustJoint(width, edges.back(), edges.front()); + + // The width of the angled part of starting and ending joint of the current + // edge. + int adjacent_width_start = first_adjacent_width; + int adjacent_width_end; + for (wtf_size_t i = 0; i < count; ++i) { + OutlineEdgeInfo& edge = edges[i]; + adjacent_width_end = i == count - 1 + ? first_adjacent_width + : AdjustJoint(width, edge, edges[i + 1]); + int adjacent_width1 = adjacent_width_start; + int adjacent_width2 = adjacent_width_end; + if (edge.side == BoxSide::kLeft || edge.side == BoxSide::kBottom) + std::swap(adjacent_width1, adjacent_width2); + BoxBorderPainter::DrawLineForBoxSide( + graphics_context, edge.x1, edge.y1, edge.x2, edge.y2, edge.side, + outline_color, style.OutlineStyle(), adjacent_width1, adjacent_width2, + false); + adjacent_width_start = adjacent_width_end; + } + + if (use_transparency_layer) + graphics_context.EndLayer(); +} + +void PaintSingleRectangleOutline(GraphicsContext& context, + const IntRect& rect, + const ComputedStyle& style, + const Color& color) { + DCHECK(!style.OutlineStyleIsAuto()); + + IntRect offset_rect = rect; + ApplyOutlineOffset(offset_rect, style.OutlineOffsetInt()); + + PhysicalRect inner(offset_rect); + PhysicalRect outer(inner); + outer.Inflate(LayoutUnit(style.OutlineWidthInt())); + const BorderEdge edge(style.OutlineWidthInt(), color, style.OutlineStyle()); + BoxBorderPainter::PaintSingleRectOutline(context, style, outer, inner, edge); +} + +float GetFocusRingBorderRadius(const ComputedStyle& style) { + // Default style is border-radius equal to outline width. + float border_radius = style.GetOutlineStrokeWidthForFocusRing(); + if (!style.HasAuthorBorder() && style.HasEffectiveAppearance()) { + // For the elements that have not been styled and that have an appearance, + // the focus ring should use the same border radius as the one used for + // drawing the element. + absl::optional<ui::NativeTheme::Part> part; + switch (style.EffectiveAppearance()) { + case kCheckboxPart: + part = ui::NativeTheme::kCheckbox; + break; + case kRadioPart: + part = ui::NativeTheme::kRadio; + break; + case kPushButtonPart: + case kSquareButtonPart: + case kButtonPart: + part = ui::NativeTheme::kPushButton; + break; + case kTextFieldPart: + case kTextAreaPart: + case kSearchFieldPart: + part = ui::NativeTheme::kTextField; + break; + default: + break; + } + if (part) { + border_radius = + ui::NativeTheme::GetInstanceForWeb()->GetBorderRadiusForPart( + part.value(), style.Width().GetFloatValue(), + style.Height().GetFloatValue()); + + // Form controls send to NativeTheme have zoom applied. But the focus ring + // outline does not. Apply zoom to checkbox focus ring. + return (style.EffectiveAppearance() == kCheckboxPart) + ? border_radius * style.EffectiveZoom() + : border_radius; + } + } + + return border_radius; +} + +} // anonymous namespace + +void OutlinePainter::PaintOutlineRects( + GraphicsContext& context, + const Vector<PhysicalRect>& outline_rects, + const ComputedStyle& style) { + Vector<IntRect> pixel_snapped_outline_rects; + for (auto& r : outline_rects) + pixel_snapped_outline_rects.push_back(PixelSnappedIntRect(r)); + + Color color = style.VisitedDependentColor(GetCSSPropertyOutlineColor()); + if (style.OutlineStyleIsAuto()) { + // Logic in draw focus ring is dependent on whether the border is large + // enough to have an inset outline. Use the smallest border edge for that + // test. + float min_border_width = + std::min(std::min(style.BorderTopWidth(), style.BorderBottomWidth()), + std::min(style.BorderLeftWidth(), style.BorderRightWidth())); + float border_radius = GetFocusRingBorderRadius(style); + context.DrawFocusRing(pixel_snapped_outline_rects, + style.GetOutlineStrokeWidthForFocusRing(), + style.OutlineOffsetInt(), border_radius, + min_border_width, color, style.UsedColorScheme()); + return; + } + + IntRect united_outline_rect = UnionRect(pixel_snapped_outline_rects); + if (united_outline_rect == pixel_snapped_outline_rects[0]) { + PaintSingleRectangleOutline(context, united_outline_rect, style, color); + return; + } + PaintComplexOutline(context, pixel_snapped_outline_rects, style, color); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/outline_painter.h b/third_party/blink/renderer/core/paint/outline_painter.h new file mode 100644 index 0000000..4b87cee --- /dev/null +++ b/third_party/blink/renderer/core/paint/outline_painter.h
@@ -0,0 +1,28 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OUTLINE_PAINTER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OUTLINE_PAINTER_H_ + +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +class ComputedStyle; +class GraphicsContext; +struct PhysicalRect; + +class OutlinePainter { + STATIC_ONLY(OutlinePainter); + + public: + static void PaintOutlineRects(GraphicsContext&, + const Vector<PhysicalRect>&, + const ComputedStyle&); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_OUTLINE_PAINTER_H_
diff --git a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc index 7168d98f..131320c22 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc
@@ -70,6 +70,7 @@ // 3. If reader.[[ownerReadableStream]].[[state]] is "readable", reject // reader.[[closedPromise]] with a TypeError exception. if (reader->owner_readable_stream_->state_ == ReadableStream::kReadable) { + reader->closed_promise_->MarkAsSilent(isolate); reader->closed_promise_->Reject( script_state, v8::Exception::TypeError(V8String( @@ -79,7 +80,7 @@ } else { // 4. Otherwise, set reader.[[closedPromise]] to a promise rejected with a // TypeError exception. - reader->closed_promise_ = StreamPromiseResolver::CreateRejected( + reader->closed_promise_ = StreamPromiseResolver::CreateRejectedAndSilent( script_state, v8::Exception::TypeError(V8String( isolate, "This readable stream reader has been released and " @@ -152,7 +153,7 @@ // b. Set reader.[[closedPromise]] to a promise rejected with stream. // [[storedError]]. - reader->closed_promise_ = StreamPromiseResolver::CreateRejected( + reader->closed_promise_ = StreamPromiseResolver::CreateRejectedAndSilent( script_state, stream->GetStoredError(isolate)); // c. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.cc b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc index a6784644..c7c2120 100644 --- a/third_party/blink/renderer/core/streams/stream_promise_resolver.cc +++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
@@ -32,6 +32,15 @@ return promise; } +StreamPromiseResolver* StreamPromiseResolver::CreateRejectedAndSilent( + ScriptState* script_state, + v8::Local<v8::Value> reason) { + auto* promise = MakeGarbageCollected<StreamPromiseResolver>(script_state); + promise->MarkAsSilent(script_state->GetIsolate()); + promise->Reject(script_state, reason); + return promise; +} + StreamPromiseResolver::StreamPromiseResolver(ScriptState* script_state) { v8::Local<v8::Promise::Resolver> resolver; if (v8::Promise::Resolver::New(script_state->GetContext()) @@ -103,6 +112,14 @@ promise->MarkAsHandled(); } +void StreamPromiseResolver::MarkAsSilent(v8::Isolate* isolate) { + v8::Local<v8::Promise> promise = V8Promise(isolate); + if (promise.IsEmpty()) { + return; + } + promise->MarkAsSilent(); +} + v8::Promise::PromiseState StreamPromiseResolver::State( v8::Isolate* isolate) const { v8::Local<v8::Promise> promise = V8Promise(isolate);
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.h b/third_party/blink/renderer/core/streams/stream_promise_resolver.h index 13723308..f6fb50a 100644 --- a/third_party/blink/renderer/core/streams/stream_promise_resolver.h +++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.h
@@ -46,6 +46,12 @@ static StreamPromiseResolver* CreateRejected(ScriptState*, v8::Local<v8::Value> reason); + // Similar to CreateRejected but marks the promise as silent before rejecting. + // https://crbug.com/1132506 + static StreamPromiseResolver* CreateRejectedAndSilent( + ScriptState*, + v8::Local<v8::Value> reason); + // Creates an initialised promise. explicit StreamPromiseResolver(ScriptState*); @@ -70,6 +76,10 @@ // an unhandled rejection. void MarkAsHandled(v8::Isolate*); + // Marks the promise as silent so that it doesn't pause the debugger when it + // rejects. + void MarkAsSilent(v8::Isolate*); + // Returns the state of the promise, one of pending, fulfilled or rejected. v8::Promise::PromiseState State(v8::Isolate*) const;
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc b/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc index 10bf54a..8888b903 100644 --- a/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc +++ b/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
@@ -92,7 +92,7 @@ case WritableStream::kErroring: { // a. Set this.[[readyPromise]] to a promise rejected with // stream.[[storedError]]. - ready_promise_ = StreamPromiseResolver::CreateRejected( + ready_promise_ = StreamPromiseResolver::CreateRejectedAndSilent( script_state, stream->GetStoredError(isolate)); // b. Set this.[[readyPromise]].[[PromiseIsHandled]] to true. @@ -127,16 +127,16 @@ // c. Set this.[[readyPromise]] to a promise rejected with // storedError. - ready_promise_ = - StreamPromiseResolver::CreateRejected(script_state, stored_error); + ready_promise_ = StreamPromiseResolver::CreateRejectedAndSilent( + script_state, stored_error); // d. Set this.[[readyPromise]].[[PromiseIsHandled]] to true. ready_promise_->MarkAsHandled(isolate); // e. Set this.[[closedPromise]] to a promise rejected with // storedError. - closed_promise_ = - StreamPromiseResolver::CreateRejected(script_state, stored_error); + closed_promise_ = StreamPromiseResolver::CreateRejectedAndSilent( + script_state, stored_error); // f. Set this.[[closedPromise]].[[PromiseIsHandled]] to true. closed_promise_->MarkAsHandled(isolate); @@ -284,12 +284,13 @@ // 1. If writer.[[readyPromise]].[[PromiseState]] is "pending", reject // writer.[[readyPromise]] with error. if (!writer->ready_promise_->IsSettled()) { + writer->ready_promise_->MarkAsSilent(isolate); writer->ready_promise_->Reject(script_state, error); } else { // 2. Otherwise, set writer.[[readyPromise]] to a promise rejected with // error. writer->ready_promise_ = - StreamPromiseResolver::CreateRejected(script_state, error); + StreamPromiseResolver::CreateRejectedAndSilent(script_state, error); } // 3. Set writer.[[readyPromise]].[[PromiseIsHandled]] to true. @@ -517,12 +518,13 @@ // 1. If writer.[[closedPromise]].[[PromiseState]] is "pending", reject // writer.[[closedPromise]] with error. if (!writer->closed_promise_->IsSettled()) { + writer->closed_promise_->MarkAsSilent(isolate); writer->closed_promise_->Reject(script_state, error); } else { // 2. Otherwise, set writer.[[closedPromise]] to a promise rejected with // error. writer->closed_promise_ = - StreamPromiseResolver::CreateRejected(script_state, error); + StreamPromiseResolver::CreateRejectedAndSilent(script_state, error); } // 3. Set writer.[[closedPromise]].[[PromiseIsHandled]] to true.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc b/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc index af587c98..a39e102 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
@@ -3,8 +3,10 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.h" + #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc index 261f03f..94b3564 100644 --- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc +++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
@@ -72,10 +72,11 @@ WorkletAnimationOptions options, scoped_refptr<SerializedScriptValue> serialized_state, const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings) { + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings) { DCHECK(!animators_.at(animation_id)); - Animator* animator = - CreateInstance(name, options, serialized_state, local_times, timings); + Animator* animator = CreateInstance(name, options, serialized_state, + local_times, timings, normalized_timings); if (!animator) return nullptr; animators_.Set(animation_id, animator); @@ -107,17 +108,20 @@ } // Down casting to blink type - Vector<Timing> timings = (static_cast<WorkletAnimationEffectTimings*>( - animation.effect_timings.get())) - ->GetTimings() - ->data; + WorkletAnimationEffectTimings* effect_timings = + (static_cast<WorkletAnimationEffectTimings*>( + animation.effect_timings.get())); + Vector<Timing> timings = effect_timings->GetTimings()->data; DCHECK_GE(timings.size(), 1u); + Vector<Timing::NormalizedTiming> normalized_timings = + effect_timings->GetNormalizedTimings()->data; + DCHECK_GE(normalized_timings.size(), 1u); Vector<absl::optional<base::TimeDelta>> local_times( static_cast<int>(timings.size()), absl::nullopt); CreateAnimatorFor(id, name, options, nullptr /* serialized_state */, - local_times, timings); + local_times, timings, normalized_timings); } } @@ -232,7 +236,8 @@ WorkletAnimationOptions options, scoped_refptr<SerializedScriptValue> serialized_state, const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings) { + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings) { DCHECK(IsContextThread()); AnimatorDefinition* definition = animator_definitions_.at(name); if (!definition) @@ -263,7 +268,7 @@ return MakeGarbageCollected<Animator>(isolate, definition, instance.V8Value(), name, std::move(options), local_times, - timings); + timings, normalized_timings); } bool AnimationWorkletGlobalScope::IsAnimatorStateful(int animation_id) { @@ -320,7 +325,8 @@ animator->GetLocalTimes(local_times); target_global_scope->CreateAnimatorFor( animation_id, animator->name(), animator->options(), serialized_state, - std::move(local_times), animator->GetTimings()); + std::move(local_times), animator->GetTimings(), + animator->GetNormalizedTimings()); } animators_.clear(); }
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h index 8465670..dfa168f 100644 --- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h +++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
@@ -78,14 +78,16 @@ WorkletAnimationOptions options, scoped_refptr<SerializedScriptValue> serialized_state, const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings); + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings); Animator* CreateAnimatorFor( int animation_id, const String& name, WorkletAnimationOptions options, scoped_refptr<SerializedScriptValue> serialized_state, const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings); + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings); typedef HeapHashMap<String, Member<AnimatorDefinition>> DefinitionMap; DefinitionMap animator_definitions_;
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc index 757a1c4..f9012b3 100644 --- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc +++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
@@ -62,7 +62,11 @@ std::unique_ptr<WorkletAnimationEffectTimings> CreateEffectTimings() { auto timings = base::MakeRefCounted<base::RefCountedData<Vector<Timing>>>(); timings->data.push_back(Timing()); - return std::make_unique<WorkletAnimationEffectTimings>(std::move(timings)); + auto normalized_timings = base::MakeRefCounted< + base::RefCountedData<Vector<Timing::NormalizedTiming>>>(); + normalized_timings->data.push_back(Timing::NormalizedTiming()); + return std::make_unique<WorkletAnimationEffectTimings>( + std::move(timings), std::move(normalized_timings)); } } // namespace
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc index 0aa9947c..ca81f237 100644 --- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc +++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc
@@ -148,7 +148,11 @@ std::unique_ptr<WorkletAnimationEffectTimings> CreateEffectTimings() { auto timings = base::MakeRefCounted<base::RefCountedData<Vector<Timing>>>(); timings->data.push_back(Timing()); - return std::make_unique<WorkletAnimationEffectTimings>(std::move(timings)); + auto normalized_timings = base::MakeRefCounted< + base::RefCountedData<Vector<Timing::NormalizedTiming>>>(); + normalized_timings->data.push_back(Timing::NormalizedTiming()); + return std::make_unique<WorkletAnimationEffectTimings>( + std::move(timings), std::move(normalized_timings)); } void RunMigrateAnimatorsBetweenGlobalScopesOnWorklet(
diff --git a/third_party/blink/renderer/modules/animationworklet/animator.cc b/third_party/blink/renderer/modules/animationworklet/animator.cc index e0a63ef..5da4168 100644 --- a/third_party/blink/renderer/modules/animationworklet/animator.cc +++ b/third_party/blink/renderer/modules/animationworklet/animator.cc
@@ -20,13 +20,16 @@ const String& name, WorkletAnimationOptions options, const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings) + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings) : definition_(definition), instance_(isolate, instance), name_(name), options_(options), group_effect_( - MakeGarbageCollected<WorkletGroupEffect>(local_times, timings)) { + MakeGarbageCollected<WorkletGroupEffect>(local_times, + timings, + normalized_timings)) { DCHECK_GE(local_times.size(), 1u); } @@ -80,6 +83,16 @@ return timings; } +Vector<Timing::NormalizedTiming> Animator::GetNormalizedTimings() const { + Vector<Timing::NormalizedTiming> normalized_timings; + normalized_timings.ReserveInitialCapacity( + group_effect_->getChildren().size()); + for (const auto& effect : group_effect_->getChildren()) { + normalized_timings.push_back(effect->NormalizedTiming()); + } + return normalized_timings; +} + bool Animator::IsStateful() const { return definition_->IsStateful(); }
diff --git a/third_party/blink/renderer/modules/animationworklet/animator.h b/third_party/blink/renderer/modules/animationworklet/animator.h index 672da5d..009a641 100644 --- a/third_party/blink/renderer/modules/animationworklet/animator.h +++ b/third_party/blink/renderer/modules/animationworklet/animator.h
@@ -31,7 +31,8 @@ const String& name, WorkletAnimationOptions options, const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings); + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings); ~Animator() final; void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "Animator"; } @@ -57,6 +58,7 @@ } Vector<Timing> GetTimings() const; + Vector<Timing::NormalizedTiming> GetNormalizedTimings() const; bool IsStateful() const; const String& name() const { return name_; }
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc index 5dee7c4c2..5ca1522 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -299,14 +299,20 @@ auto timings = base::MakeRefCounted<base::RefCountedData<Vector<Timing>>>(); timings->data.ReserveInitialCapacity(effects_.size()); + auto normalized_timings = base::MakeRefCounted< + base::RefCountedData<Vector<Timing::NormalizedTiming>>>(); + normalized_timings->data.ReserveInitialCapacity(effects_.size()); + DCHECK_GE(effects_.size(), 1u); for (auto& effect : effects_) { AnimationEffect* target_effect = effect; target_effect->Attach(this); local_times_.push_back(absl::nullopt); timings->data.push_back(target_effect->SpecifiedTiming()); + normalized_timings->data.push_back(target_effect->NormalizedTiming()); } - effect_timings_ = std::make_unique<WorkletAnimationEffectTimings>(timings); + effect_timings_ = std::make_unique<WorkletAnimationEffectTimings>( + timings, normalized_timings); if (timeline_->IsScrollTimeline()) To<ScrollTimeline>(*timeline_).WorkletAnimationAttached();
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc index 5f4275c..14c0a7cc 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc
@@ -10,9 +10,11 @@ WorkletAnimationEffect::WorkletAnimationEffect( absl::optional<base::TimeDelta> local_time, - const Timing& specified_timing) + const Timing& specified_timing, + const Timing::NormalizedTiming& normalized_timing) : local_time_(local_time), specified_timing_(specified_timing), + normalized_timing_(normalized_timing), calculated_() { specified_timing_.AssertValid(); } @@ -36,11 +38,11 @@ local_time = AnimationTimeDelta(local_time_.value()); } calculated_ = specified_timing_.CalculateTimings( - local_time, absl::nullopt, Timing::AnimationDirection::kForwards, false, - playback_rate); + local_time, absl::nullopt, normalized_timing_, + Timing::AnimationDirection::kForwards, false, playback_rate); } - return specified_timing_.getComputedTiming(calculated_, + return specified_timing_.getComputedTiming(calculated_, normalized_timing_, /*is_keyframe_effect*/ false); }
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h index 9a2cd7c..268d48fc 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h
@@ -20,15 +20,20 @@ public: WorkletAnimationEffect(absl::optional<base::TimeDelta> local_time, - const Timing& timing); + const Timing& timing, + const Timing::NormalizedTiming& normalized_timing); // Because getTiming needs to be used below, SpecifiedTiming will be used to // return the specified Timing object given at initialization const Timing& SpecifiedTiming() { return specified_timing_; } + const Timing::NormalizedTiming& NormalizedTiming() { + return normalized_timing_; + } // This function is named getTiming() as opposed to getEffectTiming() because // that is how it is defined in worklet_animation_effect.idl EffectTiming* getTiming() const; + ComputedEffectTiming* getComputedTiming() const; absl::optional<double> localTime() const; @@ -43,6 +48,7 @@ // above function call getTiming() which returns a pointer to an EffectTiming // object, as is defined in worklet_animation_effect.idl. const Timing specified_timing_; + const Timing::NormalizedTiming normalized_timing_; mutable Timing::CalculatedTiming calculated_; // last_update_time_ has type base::TimeDelta to match the type of local_time_ // since it is a cached value of local_time_
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.cc index 852ec23..72ef015 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.cc
@@ -7,12 +7,15 @@ namespace blink { WorkletAnimationEffectTimings::WorkletAnimationEffectTimings( - scoped_refptr<base::RefCountedData<Vector<Timing>>> timings) - : timings_(timings) {} + scoped_refptr<base::RefCountedData<Vector<Timing>>> timings, + scoped_refptr<base::RefCountedData<Vector<Timing::NormalizedTiming>>> + normalized_timings) + : timings_(timings), normalized_timings_(normalized_timings) {} std::unique_ptr<cc::AnimationEffectTimings> WorkletAnimationEffectTimings::Clone() const { - return std::make_unique<WorkletAnimationEffectTimings>(timings_); + return std::make_unique<WorkletAnimationEffectTimings>(timings_, + normalized_timings_); } WorkletAnimationEffectTimings::~WorkletAnimationEffectTimings() {}
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.h b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.h index c71c4d64..d253fda 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.h +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect_timings.h
@@ -15,7 +15,8 @@ : public cc::AnimationEffectTimings { public: explicit WorkletAnimationEffectTimings( - scoped_refptr<base::RefCountedData<Vector<Timing>>>); + scoped_refptr<base::RefCountedData<Vector<Timing>>>, + scoped_refptr<base::RefCountedData<Vector<Timing::NormalizedTiming>>>); std::unique_ptr<cc::AnimationEffectTimings> Clone() const override; @@ -24,9 +25,15 @@ const scoped_refptr<base::RefCountedData<Vector<Timing>>>& GetTimings() { return timings_; } + const scoped_refptr<base::RefCountedData<Vector<Timing::NormalizedTiming>>>& + GetNormalizedTimings() { + return normalized_timings_; + } private: scoped_refptr<base::RefCountedData<Vector<Timing>>> timings_; + scoped_refptr<base::RefCountedData<Vector<Timing::NormalizedTiming>>> + normalized_timings_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc index 968a35c..f7a8266 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc
@@ -8,14 +8,16 @@ WorkletGroupEffect::WorkletGroupEffect( const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings) { + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings) { DCHECK_GE(local_times.size(), 1u); DCHECK_EQ(local_times.size(), timings.size()); + DCHECK_EQ(local_times.size(), normalized_timings.size()); effects_.ReserveInitialCapacity(timings.size()); for (int i = 0; i < static_cast<int>(local_times.size()); i++) { effects_.push_back(MakeGarbageCollected<WorkletAnimationEffect>( - local_times[i], timings[i])); + local_times[i], timings[i], normalized_timings[i])); } }
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h index a0c8fa2e..8cf1289 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h +++ b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h
@@ -19,7 +19,8 @@ public: explicit WorkletGroupEffect( const Vector<absl::optional<base::TimeDelta>>& local_times, - const Vector<Timing>& timings); + const Vector<Timing>& timings, + const Vector<Timing::NormalizedTiming>& normalized_timings); const HeapVector<Member<WorkletAnimationEffect>>& getChildren() { return effects_; }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc index 91ed57e..92efd0f0 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
@@ -36,8 +36,7 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h" #include "base/numerics/safe_conversions.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_union_dompoint_unrestricteddouble.h" -#include "third_party/blink/renderer/core/geometry/dom_point.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" @@ -453,14 +452,13 @@ double double_y, double double_width, double double_height, - const HeapVector<Member<V8UnionDOMPointOrUnrestrictedDouble>>& radii, + const HeapVector<Member<V8UnionDOMPointInitOrUnrestrictedDouble>>& radii, ExceptionState& exception_state) { const int num_radii = radii.size(); if (num_radii < 1 || num_radii > 4) { - exception_state.ThrowDOMException( - DOMExceptionCode::kIndexSizeError, + exception_state.ThrowRangeError( String::Number(num_radii) + - " radii provided. Between one and four radii are necessary."); + " radii provided. Between one and four radii are necessary."); } float x = base::saturated_cast<float>(double_x); @@ -477,36 +475,34 @@ FloatSize r[num_radii]; for (int i = 0; i < num_radii; ++i) { switch (radii[i]->GetContentType()) { - case V8UnionDOMPointOrUnrestrictedDouble::ContentType::kDOMPoint: { - DOMPoint* p = radii[i]->GetAsDOMPoint(); + case V8UnionDOMPointInitOrUnrestrictedDouble::ContentType:: + kDOMPointInit: { + DOMPointInit* p = radii[i]->GetAsDOMPointInit(); float r_x = base::saturated_cast<float>(p->x()); float r_y = base::saturated_cast<float>(p->y()); if (UNLIKELY(!std::isfinite(r_x)) || UNLIKELY(!std::isfinite(r_y))) return; if (UNLIKELY(r_x < 0.0f)) { - exception_state.ThrowDOMException( - DOMExceptionCode::kIndexSizeError, + exception_state.ThrowRangeError( "X-radius value " + String::Number(r_x) + " is negative."); } if (UNLIKELY(r_y < 0.0f)) { - exception_state.ThrowDOMException( - DOMExceptionCode::kIndexSizeError, + exception_state.ThrowRangeError( "Y-radius value " + String::Number(r_y) + " is negative."); } r[i] = FloatSize(base::saturated_cast<float>(p->x()), base::saturated_cast<float>(p->y())); break; } - case V8UnionDOMPointOrUnrestrictedDouble::ContentType:: + case V8UnionDOMPointInitOrUnrestrictedDouble::ContentType:: kUnrestrictedDouble: { float a = base::saturated_cast<float>(radii[i]->GetAsUnrestrictedDouble()); if (UNLIKELY(!std::isfinite(a))) return; if (UNLIKELY(a < 0.0f)) { - exception_state.ThrowDOMException( - DOMExceptionCode::kIndexSizeError, - "Radius value " + String::Number(a) + " is negative."); + exception_state.ThrowRangeError("Radius value " + String::Number(a) + + " is negative."); } r[i] = FloatSize(a, a); break;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h index b7e217a2..0aa76c3 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h
@@ -30,6 +30,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_PATH_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_PATH_H_ +#include "third_party/blink/renderer/bindings/core/v8/v8_union_dompointinit_unrestricteddouble.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/no_alloc_direct_call_host.h" #include "third_party/blink/renderer/platform/graphics/path.h" @@ -40,7 +41,6 @@ namespace blink { class ExceptionState; -class V8UnionDOMPointOrUnrestrictedDouble; class MODULES_EXPORT CanvasPath : public NoAllocDirectCallHost { DISALLOW_NEW(); @@ -92,7 +92,7 @@ double double_y, double double_width, double double_height, - const HeapVector<Member<V8UnionDOMPointOrUnrestrictedDouble>>& radii, + const HeapVector<Member<V8UnionDOMPointInitOrUnrestrictedDouble>>& radii, ExceptionState& exception_state); virtual bool IsTransformInvertible() const { return true; }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl index 004eeb2..96d27a9c 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl
@@ -13,7 +13,7 @@ [NoAllocDirectCall] void bezierCurveTo(unrestricted double cp1x, unrestricted double cp1y, unrestricted double cp2x, unrestricted double cp2y, unrestricted double x, unrestricted double y); [NoAllocDirectCall, RaisesException] void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius); [NoAllocDirectCall] void rect(unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height); - [RuntimeEnabled=NewCanvas2DAPI, RaisesException] void roundRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, sequence<(unrestricted double or DOMPoint)> radii); + [RuntimeEnabled=NewCanvas2DAPI, RaisesException] void roundRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, sequence<(unrestricted double or DOMPointInit)> radii); [NoAllocDirectCall, RaisesException] void arc(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); [NoAllocDirectCall, RaisesException] void ellipse(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc index cc4c1e8e..a03cb81d 100644 --- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc +++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
@@ -20,17 +20,12 @@ namespace blink { -DelegatedInkTrailPresenter* DelegatedInkTrailPresenter::CreatePresenter( - Element* element, - LocalFrame* frame) { - DCHECK(!element || element->GetDocument() == frame->GetDocument()); - - return MakeGarbageCollected<DelegatedInkTrailPresenter>(element, frame); -} - DelegatedInkTrailPresenter::DelegatedInkTrailPresenter(Element* element, LocalFrame* frame) - : presentation_area_(element), local_frame_(frame) {} + : presentation_area_(element), local_frame_(frame) { + DCHECK(!presentation_area_ || + presentation_area_->GetDocument() == local_frame_->GetDocument()); +} void DelegatedInkTrailPresenter::updateInkTrailStartPoint( ScriptState* state,
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h index 1d7d05f..5e7fe2b 100644 --- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h +++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
@@ -29,9 +29,8 @@ DEFINE_WRAPPERTYPEINFO(); public: - static DelegatedInkTrailPresenter* CreatePresenter(Element* element, - LocalFrame* frame); DelegatedInkTrailPresenter(Element* element, LocalFrame* frame); + void updateInkTrailStartPoint(ScriptState* state, PointerEvent* evt, InkTrailStyle* style,
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc index 4570b77..7a065afb 100644 --- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc +++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc
@@ -63,7 +63,7 @@ DelegatedInkTrailPresenter* CreatePresenter(Element* element, LocalFrame* frame) { - return DelegatedInkTrailPresenter::CreatePresenter(element, frame); + return MakeGarbageCollected<DelegatedInkTrailPresenter>(element, frame); } } // namespace
diff --git a/third_party/blink/renderer/modules/delegated_ink/ink.cc b/third_party/blink/renderer/modules/delegated_ink/ink.cc index 53f7515..bca13e38 100644 --- a/third_party/blink/renderer/modules/delegated_ink/ink.cc +++ b/third_party/blink/renderer/modules/delegated_ink/ink.cc
@@ -5,8 +5,10 @@ #include "third_party/blink/renderer/modules/delegated_ink/ink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_presenter_type.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/navigator.h" +#include "third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -26,32 +28,23 @@ Ink::Ink(Navigator& navigator) : Supplement<Navigator>(navigator) {} ScriptPromise Ink::requestPresenter(ScriptState* state, - String type, - Element* presentationArea) { + const V8PresenterType& type, + Element* presentation_area, + ExceptionState& exception_state) { DCHECK(RuntimeEnabledFeatures::DelegatedInkTrailsEnabled()); - DCHECK_EQ(type, "delegated-ink-trail"); + DCHECK_EQ(type.AsEnum(), V8PresenterType::Enum::kDelegatedInkTrail); + + if (!state->ContextIsValid()) { + exception_state.ThrowException( + ToExceptionCode(ESErrorType::kError), + "The object is no longer associated with a window."); + return ScriptPromise(); + } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(state); ScriptPromise promise = resolver->Promise(); - - if (!state->ContextIsValid()) { - resolver->Reject(V8ThrowException::CreateError( - state->GetIsolate(), - "The object is no longer associated with a window.")); - return promise; - } - - if (type != "delegated-ink-trail") { - resolver->Reject(V8ThrowException::CreateTypeError( - state->GetIsolate(), "Unknown type requested.")); - return promise; - } - - DelegatedInkTrailPresenter* trail_presenter = - DelegatedInkTrailPresenter::CreatePresenter( - presentationArea, GetSupplementable()->DomWindow()->GetFrame()); - - resolver->Resolve(trail_presenter); + resolver->Resolve(MakeGarbageCollected<DelegatedInkTrailPresenter>( + presentation_area, GetSupplementable()->DomWindow()->GetFrame())); return promise; }
diff --git a/third_party/blink/renderer/modules/delegated_ink/ink.h b/third_party/blink/renderer/modules/delegated_ink/ink.h index 169cb34..7d6bf39 100644 --- a/third_party/blink/renderer/modules/delegated_ink/ink.h +++ b/third_party/blink/renderer/modules/delegated_ink/ink.h
@@ -5,17 +5,17 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_INK_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_INK_H_ -#include "third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/supplementable.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { class Element; +class ExceptionState; class Navigator; class ScriptPromise; class ScriptState; +class V8PresenterType; class Ink : public ScriptWrappable, public Supplement<Navigator> { DEFINE_WRAPPERTYPEINFO(); @@ -26,8 +26,9 @@ explicit Ink(Navigator&); ScriptPromise requestPresenter(ScriptState* state, - String type, - Element* presentationArea = nullptr); + const V8PresenterType& type, + Element* presentation_area, + ExceptionState& exception_state); void Trace(blink::Visitor*) const override; };
diff --git a/third_party/blink/renderer/modules/delegated_ink/ink.idl b/third_party/blink/renderer/modules/delegated_ink/ink.idl index 54fe51f..03ee065 100644 --- a/third_party/blink/renderer/modules/delegated_ink/ink.idl +++ b/third_party/blink/renderer/modules/delegated_ink/ink.idl
@@ -12,5 +12,5 @@ RuntimeEnabled=DelegatedInkTrails, Exposed=Window ] interface Ink { - [CallWith=ScriptState] Promise<DelegatedInkTrailPresenter> requestPresenter(PresenterType type, optional Element? presentationArea = null); -}; \ No newline at end of file + [CallWith=ScriptState, RaisesException] Promise<DelegatedInkTrailPresenter> requestPresenter(PresenterType type, optional Element? presentationArea = null); +};
diff --git a/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc b/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc index 3ab11622..1e7371a1 100644 --- a/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc +++ b/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc
@@ -12,7 +12,6 @@ #include "base/location.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" #include "base/synchronization/lock.h" #include "base/trace_event/trace_event.h" #include "media/audio/audio_device_description.h"
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc index 4db0c763..e0448ef 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -793,10 +793,10 @@ ExecutionContext::From(script_state)); } -String VideoFrame::format() const { +absl::optional<V8VideoPixelFormat> VideoFrame::format() const { auto local_frame = handle_->frame(); if (!local_frame || !IsSupportedPlanarFormat(*local_frame)) - return String(); + return absl::nullopt; switch (local_frame->format()) { case media::PIXEL_FORMAT_I420: @@ -819,7 +819,7 @@ return V8VideoPixelFormat(V8VideoPixelFormat::Enum::kBGRX); default: NOTREACHED(); - return String(); + return absl::nullopt; } }
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.h b/third_party/blink/renderer/modules/webcodecs/video_frame.h index 08567c5..e7d7f0a0 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_frame.h +++ b/third_party/blink/renderer/modules/webcodecs/video_frame.h
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_rect.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_video_pixel_format.h" #include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h" @@ -71,7 +72,7 @@ const VideoFrameBufferInit*, ExceptionState&); - String format() const; + absl::optional<V8VideoPixelFormat> format() const; // DEPRECATED. absl::optional<HeapVector<Member<Plane>>> planes(ExecutionContext*);
diff --git a/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h b/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h index 1cce2f53..1e3d46a 100644 --- a/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h +++ b/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h
@@ -31,6 +31,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_ANGLE_INSTANCED_ARRAYS_H_ #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h b/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h index 402b4e2..b488b94 100644 --- a/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h +++ b/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/gl_string_query.h b/third_party/blink/renderer/modules/webgl/gl_string_query.h index 70aa815..6cac386 100644 --- a/third_party/blink/renderer/modules/webgl/gl_string_query.h +++ b/third_party/blink/renderer/modules/webgl/gl_string_query.h
@@ -7,6 +7,7 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/khronos/GLES2/gl2ext.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h b/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h index 79778d7a..f77822c 100644 --- a/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h +++ b/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h
@@ -5,8 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_ -// #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h b/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h index f3f1e5f7..a3539bf 100644 --- a/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h +++ b/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h
@@ -27,6 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OES_VERTEX_ARRAY_OBJECT_H_ #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h index 8b17c544..196e8d5d 100644 --- a/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h +++ b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OVR_MULTIVIEW_2_H_ #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_context_group.h b/third_party/blink/renderer/modules/webgl/webgl_context_group.h index ca158b1..9e94ef3 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_context_group.h +++ b/third_party/blink/renderer/modules/webgl/webgl_context_group.h
@@ -27,11 +27,9 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_CONTEXT_GROUP_H_ #include "base/macros.h" -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/ref_counted.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h b/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h index f634a1d7..b7f8df6 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h +++ b/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h
@@ -26,8 +26,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_DRAW_BUFFERS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_DRAW_BUFFERS_H_ -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h b/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h index 047f1c4..dd8fb3a4 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h +++ b/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h
@@ -26,8 +26,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_DRAW_INSTANCED_BASE_VERTEX_BASE_INSTANCE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_DRAW_INSTANCED_BASE_VERTEX_BASE_INSTANCE_H_ -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_extension.h b/third_party/blink/renderer/modules/webgl/webgl_extension.h index b0f87453..2b2ff2c8 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_extension.h +++ b/third_party/blink/renderer/modules/webgl/webgl_extension.h
@@ -27,7 +27,6 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_EXTENSION_H_ #include "base/macros.h" -#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" #include "third_party/blink/renderer/modules/webgl/webgl_extension_name.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h"
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h b/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h index 2ab5670..1adf502 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h +++ b/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h
@@ -7,7 +7,6 @@ #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" #include "third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h index c7b7af03..c5d4f47 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h +++ b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h
@@ -7,6 +7,7 @@ #include "base/containers/span.h" #include "third_party/blink/renderer/modules/webgl/webgl_extension.h" +#include "third_party/khronos/GLES2/gl2.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_program.h b/third_party/blink/renderer/modules/webgl/webgl_program.h index e613737..784b77eb0 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_program.h +++ b/third_party/blink/renderer/modules/webgl/webgl_program.h
@@ -26,7 +26,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_PROGRAM_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_PROGRAM_H_ -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_shader.h" #include "third_party/blink/renderer/modules/webgl/webgl_shared_platform_3d_object.h"
diff --git a/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h b/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h index 12b2a49..af8814d 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h +++ b/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h
@@ -26,7 +26,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERBUFFER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERBUFFER_H_ -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_shared_platform_3d_object.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_shared_platform_3d_object.h b/third_party/blink/renderer/modules/webgl/webgl_shared_platform_3d_object.h index 5e7c896..40b2219 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_shared_platform_3d_object.h +++ b/third_party/blink/renderer/modules/webgl/webgl_shared_platform_3d_object.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_SHARED_PLATFORM_3D_OBJECT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_SHARED_PLATFORM_3D_OBJECT_H_ -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_shared_object.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h b/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h index 43c408c..a6b5697 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h +++ b/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_TRANSFORM_FEEDBACK_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_TRANSFORM_FEEDBACK_H_ -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/modules/webgl/webgl_context_object.h" #include "third_party/blink/renderer/modules/webgl/webgl_program.h"
diff --git a/third_party/blink/renderer/modules/webgl/webgl_video_texture.h b/third_party/blink/renderer/modules/webgl/webgl_video_texture.h index 536cc73..643ed0b 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_video_texture.h +++ b/third_party/blink/renderer/modules/webgl/webgl_video_texture.h
@@ -13,6 +13,8 @@ namespace blink { +class ExceptionState; +class ExecutionContext; class HTMLVideoElement; class VideoFrameMetadata; struct WebGLVideoFrameUploadMetadata;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc index 2b58767..e98d92a2 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" namespace blink { @@ -41,6 +42,7 @@ void GPUCanvasContext::Trace(Visitor* visitor) const { visitor->Trace(swapchain_); + visitor->Trace(configured_device_); CanvasRenderingContext::Trace(visitor); } @@ -66,6 +68,7 @@ swapchain_->Neuter(); swapchain_ = nullptr; } + configured_device_ = nullptr; stopped_ = true; } @@ -167,6 +170,8 @@ swapchain_->Neuter(); swapchain_ = nullptr; } + + configured_device_ = nullptr; } String GPUCanvasContext::getPreferredFormat(const GPUAdapter* adapter) { @@ -176,11 +181,16 @@ GPUTexture* GPUCanvasContext::getCurrentTexture( ExceptionState& exception_state) { - if (!swapchain_) { + if (!configured_device_) { exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, "context is not configured"); return nullptr; } + if (!swapchain_) { + configured_device_->InjectError(WGPUErrorType_Validation, + "context configuration is invalid."); + return GPUTexture::CreateError(configured_device_); + } return swapchain_->getCurrentTexture(); } @@ -228,6 +238,10 @@ swapchain_ = nullptr; } + // Store the configured device separately, even if the configuration fails, so + // that errors can be generated in the appropriate error scope. + configured_device_ = descriptor->device(); + WGPUTextureUsage usage = AsDawnEnum<WGPUTextureUsage>(descriptor->usage()); WGPUTextureFormat format = AsDawnEnum<WGPUTextureFormat>(descriptor->format()); @@ -235,13 +249,13 @@ case WGPUTextureFormat_BGRA8Unorm: break; case WGPUTextureFormat_RGBA16Float: - exception_state.ThrowDOMException( - DOMExceptionCode::kUnknownError, + configured_device_->InjectError( + WGPUErrorType_Validation, "rgba16float swap chain is not yet supported"); return; default: - exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, - "unsupported swap chain format"); + configured_device_->InjectError(WGPUErrorType_Validation, + "unsupported swap chain format"); return; } @@ -256,17 +270,23 @@ size = IntSize(dawn_extent.width, dawn_extent.height); if (dawn_extent.depthOrArrayLayers != 1) { - exception_state.ThrowDOMException( - DOMExceptionCode::kOperationError, + configured_device_->InjectError( + WGPUErrorType_Validation, "swap chain size must have depthOrArrayLayers set to 1"); return; } + if (size.IsEmpty()) { + configured_device_->InjectError( + WGPUErrorType_Validation, + "context width and height must be greater than 0"); + return; + } } else { size = CanvasSize(); } swapchain_ = MakeGarbageCollected<GPUSwapChain>( - this, descriptor->device(), usage, format, filter_quality_, size); + this, configured_device_, usage, format, filter_quality_, size); swapchain_->CcLayer()->SetContentsOpaque(!CreationAttributes().alpha); if (descriptor->hasLabel()) swapchain_->setLabel(descriptor->label());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h index 1c2952a..4241b459 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
@@ -96,6 +96,7 @@ SkFilterQuality filter_quality_ = kLow_SkFilterQuality; Member<GPUSwapChain> swapchain_; + Member<GPUDevice> configured_device_; bool stopped_ = false; };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc index 631ad62..202a15a 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
@@ -209,8 +209,7 @@ // gpu_swap_chain.idl GPUTexture* GPUSwapChain::getCurrentTexture() { if (!swap_buffers_) { - // TODO(cwallez@chromium.org) return an error texture. - return nullptr; + return GPUTexture::CreateError(device_); } // As we are getting a new texture, we need to tell the canvas context that
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc index b2faa8c..e94e305 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
@@ -100,6 +100,10 @@ } } +void popErrorDiscardCallback(WGPUErrorType, const char*, void*) { + // This callback is used to silently consume expected error messages +} + } // anonymous namespace // static @@ -123,6 +127,27 @@ } // static +GPUTexture* GPUTexture::CreateError(GPUDevice* device) { + DCHECK(device); + + // Force the creation of an invalid texture and consume the errors that it + // causes. It would be nice if Dawn provided a more direct way of creating + // an error texture to simplify this. + WGPUTextureDescriptor dawn_desc = {}; + device->GetProcs().devicePushErrorScope(device->GetHandle(), + WGPUErrorFilter_Validation); + GPUTexture* texture = MakeGarbageCollected<GPUTexture>( + device, + device->GetProcs().deviceCreateTexture(device->GetHandle(), &dawn_desc), + dawn_desc.dimension, dawn_desc.format, + static_cast<WGPUTextureUsage>(dawn_desc.usage)); + device->GetProcs().devicePopErrorScope(device->GetHandle(), + &popErrorDiscardCallback, nullptr); + + return texture; +} + +// static GPUTexture* GPUTexture::FromVideo(GPUDevice* device, HTMLVideoElement* video, WGPUTextureUsage usage,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture.h b/third_party/blink/renderer/modules/webgpu/gpu_texture.h index c02d7804..46499bbb 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture.h
@@ -26,6 +26,7 @@ static GPUTexture* Create(GPUDevice* device, const GPUTextureDescriptor* webgpu_desc, ExceptionState& exception_state); + static GPUTexture* CreateError(GPUDevice* device); static GPUTexture* FromVideo(GPUDevice* device, HTMLVideoElement* video, WGPUTextureUsage usage,
diff --git a/third_party/blink/renderer/modules/webshare/FILE_TYPES.md b/third_party/blink/renderer/modules/webshare/FILE_TYPES.md index 1fc4f89..563f57d 100644 --- a/third_party/blink/renderer/modules/webshare/FILE_TYPES.md +++ b/third_party/blink/renderer/modules/webshare/FILE_TYPES.md
@@ -5,6 +5,8 @@ - //components/browser_ui/webshare/android/java/src/org/chromium/components/browser_ui/webshare/ShareServiceImpl.java +# Application + "pdf" - application/pdf # Audio "flac" - audio/flac "m4a" - audio/x-m4a
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 52365cf..73d71b20 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -136,6 +136,10 @@ RuntimeEnabledFeatures::SetAccessibilityObjectModelEnabled(enable); } +void WebRuntimeFeatures::EnableAccessibilityPageZoom(bool enable) { + RuntimeEnabledFeatures::SetAccessibilityPageZoomEnabled(enable); +} + void WebRuntimeFeatures::EnableAccessibilityUseAXPositionForDocumentMarkers( bool enable) { RuntimeEnabledFeatures::
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index 5d847d91..444ad05 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -942,7 +942,8 @@ gl_->FramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1); } if (!ResizeFramebufferInternal(size)) { - DLOG(ERROR) << "Initialization failed to allocate backbuffer."; + DLOG(ERROR) << "Initialization failed to allocate backbuffer of size " + << size.Width() << " x " << size.Height() << "."; return false; }
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc index 6ac45cca..d69c077a 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -254,21 +254,13 @@ absl::optional<IntRect> expansion_bounds; bool expanded = false; if (last_scroll_translation_result == kExpandedForPartialScrollingContents) { - DCHECK(last_transform); DCHECK(last_transform->ScrollNode()); + expansion_bounds.emplace(IntPoint(), + last_transform->ScrollNode()->ContentsSize()); + // Map expansion_bounds into the same space as rect_. + GeometryMapper::SourceToDestinationRect( + *last_transform, destination.Transform(), *expansion_bounds); expanded = true; - // Expansion bounds checking is reliable only when there are no additional - // clips or non-translation transforms below the last scroll translation. - if (last_clip == &destination.Clip()) { - // Map expansion_bounds into the same space as rect_. - auto projection = GeometryMapper::SourceToDestinationProjection( - *last_transform, destination.Transform()); - if (projection.IsIdentityOr2DTranslation()) { - expansion_bounds.emplace(IntPoint(), - last_transform->ScrollNode()->ContentsSize()); - projection.MapRect(*expansion_bounds); - } - } } if (last_transform != &destination.Transform() && @@ -283,17 +275,19 @@ LocalPixelDistanceToExpand(root.Transform(), destination.Transform()); if (rect_.Width() < pixel_distance_to_expand) { rect_.InflateX(pixel_distance_to_expand); + if (expansion_bounds) + expansion_bounds->InflateX(pixel_distance_to_expand); expanded = true; } if (rect_.Height() < pixel_distance_to_expand) { rect_.InflateY(pixel_distance_to_expand); + if (expansion_bounds) + expansion_bounds->InflateY(pixel_distance_to_expand); expanded = true; } } - // TODO(wangxianzhu): For now disable ChangedEnough if the expansion_bounds - // in not set. Revisit this for carousel/marquee cases. - if (expanded && old_cull_rect && expansion_bounds && + if (expanded && old_cull_rect && !ChangedEnough(*old_cull_rect, expansion_bounds)) rect_ = old_cull_rect->Rect();
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc index 75b378f..2e13e75f 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
@@ -503,7 +503,7 @@ EXPECT_EQ(IntRect(0, 1010, 7060, 6990), cull_rect4.Rect()); } -TEST_F(CullRectTest, TranslationUnderScrollTranslation) { +TEST_F(CullRectTest, TransformUnderScrollTranslation) { ScopedCullRectUpdateForTest cull_rect_update(true); auto t1 = Create2DTranslation(t0(), 1, 2); @@ -541,44 +541,6 @@ EXPECT_EQ(IntRect(-2000, -1990, 7060, 6990), cull_rect4.Rect()); } -TEST_F(CullRectTest, ScaleUnderScrollTranslation) { - ScopedCullRectUpdateForTest cull_rect_update(true); - - auto t1 = Create2DTranslation(t0(), 1, 2); - PropertyTreeState state1(*t1, c0(), e0()); - auto scroll_translation_state = CreateCompositedScrollTranslationState( - state1, -3000, -5000, IntRect(20, 10, 40, 50), IntSize(8000, 8000)); - auto t2 = CreateTransform(scroll_translation_state.Transform(), - TransformationMatrix().Scale(2)); - PropertyTreeState state2 = - scroll_translation_state.GetPropertyTreeState().Unalias(); - state2.SetTransform(*t2); - - // Cases below are the same as those in SingleScrollPartialScrollingContents, - // except that the offset is adjusted with |t2|. - CullRect cull_rect1(IntRect(0, 0, 50, 100)); - cull_rect1.ApplyPaintProperties(state1, state1, state2, absl::nullopt); - EXPECT_EQ(IntRect(0, 505, 3525, 3495), cull_rect1.Rect()); - - CullRect old_cull_rect(IntRect(0, 500, 3525, 3495)); - CullRect cull_rect2(IntRect(0, 0, 50, 100)); - // ChangedEnough() doesn't apply because of the scale. - cull_rect2.ApplyPaintProperties(state1, state1, state2, old_cull_rect); - EXPECT_EQ(cull_rect1, cull_rect2); - - old_cull_rect.Move(IntSize(1000, 1000)); - CullRect cull_rect3(IntRect(0, 0, 50, 100)); - // Use the new cull rect if it changed enough. - cull_rect3.ApplyPaintProperties(state1, state1, state2, old_cull_rect); - EXPECT_EQ(cull_rect1, cull_rect3); - - CullRect cull_rect4 = CullRect::Infinite(); - cull_rect4.ApplyPaintProperties(state1, state1, state2, absl::nullopt); - // This result differs from the first result in height (3525 vs 3530) - // because it's not clipped by the infinite input cull rect. - EXPECT_EQ(IntRect(0, 505, 3530, 3495), cull_rect4.Rect()); -} - TEST_F(CullRectTest, TransformEscapingScroll) { ScopedCullRectUpdateForTest cull_rect_update(true); @@ -741,9 +703,9 @@ CullRect cull_rect2(IntRect(0, 0, 300, 500)); CullRect old_cull_rect = cull_rect1; old_cull_rect.Move(IntSize(200, 200)); - // TODO(wangxianzhu): For now ChangedEnough() doesn't apply. Revisit this. + // Use old_cull_rect if the new cull rect didn't change enough. cull_rect2.ApplyPaintProperties(root, root, state1, old_cull_rect); - EXPECT_EQ(cull_rect1, cull_rect2); + EXPECT_EQ(old_cull_rect, cull_rect2); CullRect cull_rect3(IntRect(0, 0, 300, 500)); old_cull_rect.Move(IntSize(1000, 1000)); @@ -768,7 +730,7 @@ auto t1 = Create2DTranslation(t0(), 0, 10000); auto scroll_clip = CreateClip(*c1, *t1, FloatRoundedRect(0, 0, 120, 120)); auto scroll_translation = CreateCompositedScrollTranslation( - *t1, 0, 0, IntRect(0, 0, 120, 120), IntSize(10000, 10000)); + *t1, 0, 0, IntRect(0, 0, 120, 120), IntSize(10000, 5000)); auto c2a = CreateClip(*scroll_clip, *scroll_translation, FloatRoundedRect(0, 300, 100, 100)); auto c2b = CreateClip(*scroll_clip, *scroll_translation, @@ -789,6 +751,20 @@ absl::nullopt); EXPECT_EQ(IntRect(-4000, -3700, 8100, 8100), cull_rect.Rect()); + // Using c2a with old cull rect. + cull_rect = CullRect::Infinite(); + cull_rect.ApplyPaintProperties( + root, root, PropertyTreeState(*scroll_translation, *c2a, e0()), + CullRect(IntRect(0, 310, 100, 100))); + EXPECT_EQ(IntRect(0, 310, 100, 100), cull_rect.Rect()); + // Composited case. The cull rect should be expanded. + cull_rect = CullRect::Infinite(); + cull_rect.ApplyPaintProperties(root, root, PropertyTreeState(*t2, *c2a, e0()), + CullRect(IntRect(-3900, -3700, 8100, 8100))); + // The new cull rect touches the left edge of the expanded scrolling contents + // bounds, so the old cull rect is not used. + EXPECT_EQ(IntRect(-4000, -3700, 8100, 8100), cull_rect.Rect()); + // c2b is out of the expansion area of the composited scroll. cull_rect = CullRect::Infinite(); cull_rect.ApplyPaintProperties(
diff --git a/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc b/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc index dd1edb8..e31f772 100644 --- a/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc +++ b/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
@@ -5,8 +5,13 @@ #include "third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h" #include <inttypes.h> +#include <ios> +#include <sstream> +#include <string> +#include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" +#include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/memory_dump_manager.h" #include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h" #include "v8/include/cppgc/heap-statistics.h" @@ -24,6 +29,27 @@ } } +void RecordType( + std::vector<cppgc::HeapStatistics::ObjectStatsEntry>& global_object_stats, + const cppgc::HeapStatistics::ObjectStatsEntry& local_object_stats, + size_t entry_index) { + global_object_stats[entry_index].allocated_bytes += + local_object_stats.allocated_bytes; + global_object_stats[entry_index].object_count += + local_object_stats.object_count; +} + +// Use the id to generate a unique name as different types may provide the same +// string as typename. This happens in component builds when cppgc creates +// different internal types for the same C++ class when it is instantiated from +// different libraries. +std::string GetUniqueName(std::string name, size_t id) { + std::stringstream stream; + // Convert the id to hex to avoid it reading like an object count. + stream << name << " (0x" << std::hex << id << ")"; + return stream.str(); +} + } // namespace BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider( @@ -33,7 +59,7 @@ : thread_state_(thread_state), heap_type_(heap_type), dump_base_name_( - "blink_gc/" + std::string(HeapTypeString(heap_type_)) + "/heap" + + "blink_gc/" + std::string(HeapTypeString(heap_type_)) + (heap_type_ == HeapType::kBlinkWorkerThread ? "/" + base::StringPrintf( "worker_0x%" PRIXPTR, @@ -60,10 +86,11 @@ ::cppgc::HeapStatistics stats = ThreadState::Current()->cpp_heap().CollectStatistics(detail_level); - auto* heap_dump = process_memory_dump->CreateAllocatorDump(dump_base_name_); + auto* heap_dump = + process_memory_dump->CreateAllocatorDump(dump_base_name_ + "/heap"); heap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, base::trace_event::MemoryAllocatorDump::kUnitsBytes, - stats.physical_size_bytes); + stats.resident_size_bytes); heap_dump->AddScalar("allocated_objects_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, stats.used_size_bytes); @@ -72,16 +99,19 @@ return true; } - // Detailed statistics. + // Aggregate global object stats from per page statistics. + std::vector<cppgc::HeapStatistics::ObjectStatsEntry> global_object_stats; + global_object_stats.resize(stats.type_names.size()); + + // Detailed statistics follow. for (const ::cppgc::HeapStatistics::SpaceStatistics& space_stats : stats.space_stats) { - std::string arena_dump_name = dump_base_name_ + "/" + space_stats.name; - auto* arena_dump = - process_memory_dump->CreateAllocatorDump(arena_dump_name); - arena_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + auto* space_dump = process_memory_dump->CreateAllocatorDump( + heap_dump->absolute_name() + "/" + space_stats.name); + space_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, base::trace_event::MemoryAllocatorDump::kUnitsBytes, - space_stats.physical_size_bytes); - arena_dump->AddScalar("allocated_objects_size", + space_stats.resident_size_bytes); + space_dump->AddScalar("allocated_objects_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, space_stats.used_size_bytes); @@ -89,19 +119,42 @@ for (const ::cppgc::HeapStatistics::PageStatistics& page_stats : space_stats.page_stats) { auto* page_dump = process_memory_dump->CreateAllocatorDump( - arena_dump_name + "/pages/page_" + + space_dump->absolute_name() + "/pages/page_" + base::NumberToString(page_count++)); + page_dump->AddScalar("committed_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + page_stats.committed_size_bytes); page_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, base::trace_event::MemoryAllocatorDump::kUnitsBytes, - page_stats.physical_size_bytes); + page_stats.resident_size_bytes); page_dump->AddScalar("allocated_objects_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, page_stats.used_size_bytes); + + const auto& object_stats = page_stats.object_statistics; + for (size_t i = 0; i < object_stats.size(); i++) { + if (!object_stats[i].object_count) + continue; + + auto* page_class_dump = process_memory_dump->CreateAllocatorDump( + page_dump->absolute_name() + "/types/" + + GetUniqueName(stats.type_names[i], i)); + page_class_dump->AddScalar( + base::trace_event::MemoryAllocatorDump::kNameObjectCount, + base::trace_event::MemoryAllocatorDump::kUnitsObjects, + object_stats[i].object_count); + page_class_dump->AddScalar( + "allocated_objects_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + object_stats[i].allocated_bytes); + + RecordType(global_object_stats, object_stats[i], i); + } } const ::cppgc::HeapStatistics::FreeListStatistics& free_list_stats = space_stats.free_list_stats; - for (wtf_size_t i = 0; i < free_list_stats.bucket_size.size(); ++i) { + for (size_t i = 0; i < free_list_stats.bucket_size.size(); ++i) { constexpr size_t kDigits = 8; std::string original_bucket_size = base::NumberToString(free_list_stats.bucket_size[i]); @@ -109,28 +162,40 @@ std::string(kDigits - original_bucket_size.length(), '0') + original_bucket_size; auto* free_list_bucket_dump = process_memory_dump->CreateAllocatorDump( - arena_dump_name + "/freelist/bucket_" + padded_bucket_size); + space_dump->absolute_name() + "/freelist/bucket_" + + padded_bucket_size); free_list_bucket_dump->AddScalar( - "free_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, + "free_slot_count", + base::trace_event::MemoryAllocatorDump::kUnitsObjects, + free_list_stats.free_count[i]); + free_list_bucket_dump->AddScalar( + "free_usable_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, free_list_stats.free_size[i]); } - - const ::cppgc::HeapStatistics::ObjectStatistics& object_stats = - space_stats.object_stats; - for (wtf_size_t i = 1; i < object_stats.num_types; i++) { - if (object_stats.type_name[i].empty()) - continue; - - auto* class_dump = process_memory_dump->CreateAllocatorDump( - arena_dump_name + "/classes/" + object_stats.type_name[i]); - class_dump->AddScalar( - "object_count", base::trace_event::MemoryAllocatorDump::kUnitsObjects, - object_stats.type_count[i]); - class_dump->AddScalar("object_size", - base::trace_event::MemoryAllocatorDump::kUnitsBytes, - object_stats.type_bytes[i]); - } } + + // Populate "allocated_objects" and "blink_objects/blink_gc" dumps. + const auto* allocated_objects_dump = process_memory_dump->CreateAllocatorDump( + dump_base_name_ + "/allocated_objects"); + for (size_t i = 0; i < global_object_stats.size(); i++) { + auto* details = process_memory_dump->CreateAllocatorDump( + "blink_objects/blink_gc/" + GetUniqueName(stats.type_names[i], i)); + details->AddScalar("allocated_objects_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + global_object_stats[i].allocated_bytes); + details->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount, + base::trace_event::MemoryAllocatorDump::kUnitsObjects, + global_object_stats[i].object_count); + details->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + global_object_stats[i].allocated_bytes); + process_memory_dump->AddSuballocation( + details->guid(), dump_base_name_ + "/allocated_objects"); + } + process_memory_dump->AddOwnershipEdge(allocated_objects_dump->guid(), + heap_dump->guid()); + return true; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc index 56845fc..1954e2c 100644 --- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -427,8 +427,14 @@ const int32_t context = static_cast<int32_t>(resource->GetResourceRequest().GetRequestContext()) + 0x800; + const int32_t mark1 = 0xcdcdcdcd; + char url[80] = {}; + const int32_t mark2 = 0xcdcdcdcd; base::debug::Alias(&destination); base::debug::Alias(&context); + base::debug::Alias(&mark1); + base::debug::Alias(url); + base::debug::Alias(&mark2); SECURITY_CHECK(state_ != kNotAddedAsClient); SECURITY_CHECK(state_ != kNotifyFinished); @@ -436,6 +442,10 @@ // TODO(https://crbug.com/1158346): Remove these CHECKs once the investigation // is done. if (!resource->ErrorOccurred()) { + std::string url_string = + resource->Url().UrlStrippedForUseAsReferrer().GetString().Utf8(); + strncpy(url, url_string.c_str(), sizeof(url) - 1); + SECURITY_CHECK(state_ != kStarted); SECURITY_CHECK(state_ != kRedirectBlocked); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index 35ac961..7db12dc 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -699,7 +699,7 @@ // This class is thread-bound. Do not copy/pass an instance across threads. // // Although request consists head and body, ResourceRequest is implemented by -// inheriting ResourceRequestHead due in order to make it possible to use +// inheriting ResourceRequestHead in order to make it possible to use // property accessors through both ResourceRequestHead and ResourceRequest while // avoiding duplicate accessor definitions. // For those who want to add a new property in request, please implement its
diff --git a/third_party/blink/renderer/platform/media/buffered_data_source_host_impl.cc b/third_party/blink/renderer/platform/media/buffered_data_source_host_impl.cc index 2cb4bdd..82ef8c2c 100644 --- a/third_party/blink/renderer/platform/media/buffered_data_source_host_impl.cc +++ b/third_party/blink/renderer/platform/media/buffered_data_source_host_impl.cc
@@ -100,10 +100,10 @@ } void BufferedDataSourceHostImpl::AddBufferedTimeRanges( - Ranges<base::TimeDelta>* buffered_time_ranges, + media::Ranges<base::TimeDelta>* buffered_time_ranges, base::TimeDelta media_duration) const { - DCHECK(media_duration != kNoTimestamp); - DCHECK(media_duration != kInfiniteDuration); + DCHECK(media_duration != media::kNoTimestamp); + DCHECK(media_duration != media::kInfiniteDuration); if (total_bytes_ && !buffered_byte_ranges_.empty()) { for (const auto i : buffered_byte_ranges_) { if (i.second) { @@ -155,7 +155,7 @@ double playback_rate) const { DCHECK_GE(playback_rate, 0); if (!total_bytes_ || media_duration <= base::TimeDelta() || - media_duration == kInfiniteDuration) { + media_duration == media::kInfiniteDuration) { return false; } if (current_position > media_duration)
diff --git a/third_party/blink/renderer/platform/media/buffered_data_source_host_impl_unittest.cc b/third_party/blink/renderer/platform/media/buffered_data_source_host_impl_unittest.cc index 61b426f..d5aea3b8 100644 --- a/third_party/blink/renderer/platform/media/buffered_data_source_host_impl_unittest.cc +++ b/third_party/blink/renderer/platform/media/buffered_data_source_host_impl_unittest.cc
@@ -31,7 +31,7 @@ protected: int progress_callback_calls_ = 0; BufferedDataSourceHostImpl host_; - Ranges<base::TimeDelta> ranges_; + media::Ranges<base::TimeDelta> ranges_; base::SimpleTestTickClock clock_; };
diff --git a/third_party/blink/renderer/platform/media/cdm_result_promise.h b/third_party/blink/renderer/platform/media/cdm_result_promise.h index 342ff11..c4a6bda 100644 --- a/third_party/blink/renderer/platform/media/cdm_result_promise.h +++ b/third_party/blink/renderer/platform/media/cdm_result_promise.h
@@ -26,7 +26,8 @@ // If constructed with a |uma_name|, CdmResultPromise will report the promise // result (success or rejection code) to UMA. template <typename... T> -class PLATFORM_EXPORT CdmResultPromise : public CdmPromiseTemplate<T...> { +class PLATFORM_EXPORT CdmResultPromise + : public media::CdmPromiseTemplate<T...> { public: CdmResultPromise(const blink::WebContentDecryptionModuleResult& result, const std::string& key_system_uma_prefix, @@ -35,16 +36,16 @@ CdmResultPromise& operator=(const CdmResultPromise&) = delete; ~CdmResultPromise() override; - // CdmPromiseTemplate<T> implementation. + // media::CdmPromiseTemplate<T> implementation. void resolve(const T&... result) override; - void reject(CdmPromise::Exception exception_code, + void reject(media::CdmPromise::Exception exception_code, uint32_t system_code, const std::string& error_message) override; private: - using CdmPromiseTemplate<T...>::IsPromiseSettled; - using CdmPromiseTemplate<T...>::MarkPromiseSettled; - using CdmPromiseTemplate<T...>::RejectPromiseOnDestruction; + using media::CdmPromiseTemplate<T...>::IsPromiseSettled; + using media::CdmPromiseTemplate<T...>::MarkPromiseSettled; + using media::CdmPromiseTemplate<T...>::RejectPromiseOnDestruction; blink::WebContentDecryptionModuleResult web_cdm_result_; @@ -90,8 +91,8 @@ } template <> -inline void CdmResultPromise<CdmKeyInformation::KeyStatus>::resolve( - const CdmKeyInformation::KeyStatus& key_status) { +inline void CdmResultPromise<media::CdmKeyInformation::KeyStatus>::resolve( + const media::CdmKeyInformation::KeyStatus& key_status) { MarkPromiseSettled(); ReportCdmResultUMA(key_system_uma_prefix_ + uma_name_, 0, SUCCESS); @@ -103,7 +104,7 @@ } template <typename... T> -void CdmResultPromise<T...>::reject(CdmPromise::Exception exception_code, +void CdmResultPromise<T...>::reject(media::CdmPromise::Exception exception_code, uint32_t system_code, const std::string& error_message) { MarkPromiseSettled();
diff --git a/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h b/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h index 1749d09..30f4893 100644 --- a/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h +++ b/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h
@@ -33,10 +33,10 @@ }; PLATFORM_EXPORT CdmResultForUMA -ConvertCdmExceptionToResultForUMA(CdmPromise::Exception exception_code); +ConvertCdmExceptionToResultForUMA(media::CdmPromise::Exception exception_code); PLATFORM_EXPORT blink::WebContentDecryptionModuleException ConvertCdmException( - CdmPromise::Exception exception_code); + media::CdmPromise::Exception exception_code); PLATFORM_EXPORT blink::WebEncryptedMediaKeyInformation::KeyStatus ConvertCdmKeyStatus(media::CdmKeyInformation::KeyStatus key_status);
diff --git a/third_party/blink/renderer/platform/media/cdm_session_adapter.cc b/third_party/blink/renderer/platform/media/cdm_session_adapter.cc index d5e94ee..14f2356 100644 --- a/third_party/blink/renderer/platform/media/cdm_session_adapter.cc +++ b/third_party/blink/renderer/platform/media/cdm_session_adapter.cc
@@ -34,9 +34,9 @@ CdmSessionAdapter::~CdmSessionAdapter() = default; -void CdmSessionAdapter::CreateCdm(CdmFactory* cdm_factory, +void CdmSessionAdapter::CreateCdm(media::CdmFactory* cdm_factory, const std::string& key_system, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, WebCdmCreatedCB web_cdm_created_cb) { TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "CdmSessionAdapter::CreateCdm", ++trace_id_); @@ -64,13 +64,13 @@ void CdmSessionAdapter::SetServerCertificate( const std::vector<uint8_t>& certificate, - std::unique_ptr<SimpleCdmPromise> promise) { + std::unique_ptr<media::SimpleCdmPromise> promise) { cdm_->SetServerCertificate(certificate, std::move(promise)); } void CdmSessionAdapter::GetStatusForPolicy( - HdcpVersion min_hdcp_version, - std::unique_ptr<KeyStatusCdmPromise> promise) { + media::HdcpVersion min_hdcp_version, + std::unique_ptr<media::KeyStatusCdmPromise> promise) { cdm_->GetStatusForPolicy(min_hdcp_version, std::move(promise)); } @@ -98,18 +98,18 @@ } void CdmSessionAdapter::InitializeNewSession( - EmeInitDataType init_data_type, + media::EmeInitDataType init_data_type, const std::vector<uint8_t>& init_data, - CdmSessionType session_type, - std::unique_ptr<NewSessionCdmPromise> promise) { + media::CdmSessionType session_type, + std::unique_ptr<media::NewSessionCdmPromise> promise) { cdm_->CreateSessionAndGenerateRequest(session_type, init_data_type, init_data, std::move(promise)); } void CdmSessionAdapter::LoadSession( - CdmSessionType session_type, + media::CdmSessionType session_type, const std::string& session_id, - std::unique_ptr<NewSessionCdmPromise> promise) { + std::unique_ptr<media::NewSessionCdmPromise> promise) { DVLOG(2) << __func__ << ": session_id = " << session_id; cdm_->LoadSession(session_type, session_id, std::move(promise)); } @@ -117,26 +117,26 @@ void CdmSessionAdapter::UpdateSession( const std::string& session_id, const std::vector<uint8_t>& response, - std::unique_ptr<SimpleCdmPromise> promise) { + std::unique_ptr<media::SimpleCdmPromise> promise) { DVLOG(3) << __func__ << ": session_id = " << session_id; cdm_->UpdateSession(session_id, response, std::move(promise)); } void CdmSessionAdapter::CloseSession( const std::string& session_id, - std::unique_ptr<SimpleCdmPromise> promise) { + std::unique_ptr<media::SimpleCdmPromise> promise) { DVLOG(2) << __func__ << ": session_id = " << session_id; cdm_->CloseSession(session_id, std::move(promise)); } void CdmSessionAdapter::RemoveSession( const std::string& session_id, - std::unique_ptr<SimpleCdmPromise> promise) { + std::unique_ptr<media::SimpleCdmPromise> promise) { DVLOG(2) << __func__ << ": session_id = " << session_id; cdm_->RemoveSession(session_id, std::move(promise)); } -std::unique_ptr<CdmContextRef> CdmSessionAdapter::GetCdmContextRef() { +std::unique_ptr<media::CdmContextRef> CdmSessionAdapter::GetCdmContextRef() { DVLOG(2) << __func__; if (!cdm_->GetCdmContext()) { @@ -144,7 +144,7 @@ return nullptr; } - return std::make_unique<CdmContextRefImpl>(cdm_); + return std::make_unique<media::CdmContextRefImpl>(cdm_); } const std::string& CdmSessionAdapter::GetKeySystem() const { @@ -156,16 +156,16 @@ return key_system_uma_prefix_; } -const CdmConfig& CdmSessionAdapter::GetCdmConfig() const { +const media::CdmConfig& CdmSessionAdapter::GetCdmConfig() const { DCHECK(cdm_); return cdm_config_; } void CdmSessionAdapter::OnCdmCreated( const std::string& key_system, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, base::TimeTicks start_time, - const scoped_refptr<ContentDecryptionModule>& cdm, + const scoped_refptr<media::ContentDecryptionModule>& cdm, const std::string& error_message) { DVLOG(1) << __func__ << ": " << (cdm ? "success" : "failure (" + error_message + ")"); @@ -176,7 +176,7 @@ (cdm ? "true" : "false"), "error_message", error_message); auto key_system_uma_prefix = - kMediaEME + GetKeySystemNameForUMA(key_system) + kDot; + kMediaEME + media::GetKeySystemNameForUMA(key_system) + kDot; base::UmaHistogramBoolean(key_system_uma_prefix + kCreateCdmUMAName, cdm ? true : false); @@ -201,7 +201,7 @@ } void CdmSessionAdapter::OnSessionMessage(const std::string& session_id, - CdmMessageType message_type, + media::CdmMessageType message_type, const std::vector<uint8_t>& message) { WebContentDecryptionModuleSessionImpl* session = GetSession(session_id); DLOG_IF(WARNING, !session) << __func__ << " for unknown session " @@ -214,7 +214,7 @@ void CdmSessionAdapter::OnSessionKeysChange(const std::string& session_id, bool has_additional_usable_key, - CdmKeysInfo keys_info) { + media::CdmKeysInfo keys_info) { WebContentDecryptionModuleSessionImpl* session = GetSession(session_id); DLOG_IF(WARNING, !session) << __func__ << " for unknown session " << session_id; @@ -246,7 +246,7 @@ } void CdmSessionAdapter::OnSessionClosed(const std::string& session_id, - CdmSessionClosedReason reason) { + media::CdmSessionClosedReason reason) { WebContentDecryptionModuleSessionImpl* session = GetSession(session_id); DLOG_IF(WARNING, !session) << __func__ << " for unknown session " << session_id;
diff --git a/third_party/blink/renderer/platform/media/cdm_session_adapter.h b/third_party/blink/renderer/platform/media/cdm_session_adapter.h index e0733da..166c553 100644 --- a/third_party/blink/renderer/platform/media/cdm_session_adapter.h +++ b/third_party/blink/renderer/platform/media/cdm_session_adapter.h
@@ -34,7 +34,7 @@ class WebContentDecryptionModuleSessionImpl; // Owns the CDM instance and makes calls from session objects to the CDM. -// Forwards the session ID-based callbacks of the ContentDecryptionModule +// Forwards the session ID-based callbacks of the media::ContentDecryptionModule // interface to the appropriate session object. Callers should hold references // to this class as long as they need the CDM instance. class PLATFORM_EXPORT CdmSessionAdapter @@ -46,20 +46,20 @@ // Creates the CDM for |key_system| using |cdm_factory| and returns the result // via |result|. - void CreateCdm(CdmFactory* cdm_factory, + void CreateCdm(media::CdmFactory* cdm_factory, const std::string& key_system, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, WebCdmCreatedCB web_cdm_created_cb); // Provides a server certificate to be used to encrypt messages to the // license server. void SetServerCertificate(const std::vector<uint8_t>& certificate, - std::unique_ptr<SimpleCdmPromise> promise); + std::unique_ptr<media::SimpleCdmPromise> promise); // Gets the key status for a hypothetical key with |min_hdcp_version| // requirement. - void GetStatusForPolicy(HdcpVersion min_hdcp_version, - std::unique_ptr<KeyStatusCdmPromise> promise); + void GetStatusForPolicy(media::HdcpVersion min_hdcp_version, + std::unique_ptr<media::KeyStatusCdmPromise> promise); // Creates a new session and adds it to the internal map. RemoveSession() // must be called when destroying it, if RegisterSession() was called. @@ -78,33 +78,34 @@ // Initializes a session with the |init_data_type|, |init_data| and // |session_type| provided. - void InitializeNewSession(EmeInitDataType init_data_type, - const std::vector<uint8_t>& init_data, - CdmSessionType session_type, - std::unique_ptr<NewSessionCdmPromise> promise); + void InitializeNewSession( + media::EmeInitDataType init_data_type, + const std::vector<uint8_t>& init_data, + media::CdmSessionType session_type, + std::unique_ptr<media::NewSessionCdmPromise> promise); // Loads the session specified by |session_id|. - void LoadSession(CdmSessionType session_type, + void LoadSession(media::CdmSessionType session_type, const std::string& session_id, - std::unique_ptr<NewSessionCdmPromise> promise); + std::unique_ptr<media::NewSessionCdmPromise> promise); // Updates the session specified by |session_id| with |response|. void UpdateSession(const std::string& session_id, const std::vector<uint8_t>& response, - std::unique_ptr<SimpleCdmPromise> promise); + std::unique_ptr<media::SimpleCdmPromise> promise); // Closes the session specified by |session_id|. void CloseSession(const std::string& session_id, - std::unique_ptr<SimpleCdmPromise> promise); + std::unique_ptr<media::SimpleCdmPromise> promise); // Removes stored session data associated with the session specified by // |session_id|. void RemoveSession(const std::string& session_id, - std::unique_ptr<SimpleCdmPromise> promise); + std::unique_ptr<media::SimpleCdmPromise> promise); // Returns a CdmContextRef which provides access to CdmContext and by holding // the CdmContextRef, makes sure the CdmContext is kept alive. - std::unique_ptr<CdmContextRef> GetCdmContextRef(); + std::unique_ptr<media::CdmContextRef> GetCdmContextRef(); // Returns the key system name. const std::string& GetKeySystem() const; @@ -113,7 +114,7 @@ const std::string& GetKeySystemUMAPrefix() const; // Returns the CdmConfig used in creation of CDM. - const CdmConfig& GetCdmConfig() const; + const media::CdmConfig& GetCdmConfig() const; private: friend class base::RefCounted<CdmSessionAdapter>; @@ -128,36 +129,36 @@ // Callback for CreateCdm(). void OnCdmCreated(const std::string& key_system, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, base::TimeTicks start_time, - const scoped_refptr<ContentDecryptionModule>& cdm, + const scoped_refptr<media::ContentDecryptionModule>& cdm, const std::string& error_message); // Callbacks for firing session events. void OnSessionMessage(const std::string& session_id, - CdmMessageType message_type, + media::CdmMessageType message_type, const std::vector<uint8_t>& message); void OnSessionKeysChange(const std::string& session_id, bool has_additional_usable_key, - CdmKeysInfo keys_info); + media::CdmKeysInfo keys_info); void OnSessionExpirationUpdate(const std::string& session_id, base::Time new_expiry_time); void OnSessionClosed(const std::string& session_id, - CdmSessionClosedReason reason); + media::CdmSessionClosedReason reason); // Helper function of the callbacks. WebContentDecryptionModuleSessionImpl* GetSession( const std::string& session_id); - scoped_refptr<ContentDecryptionModule> cdm_; + scoped_refptr<media::ContentDecryptionModule> cdm_; SessionMap sessions_; std::string key_system_; std::string key_system_uma_prefix_; - // CdmConfig used in creation of cdm_. - CdmConfig cdm_config_; + // media::CdmConfig used in creation of cdm_. + media::CdmConfig cdm_config_; // A unique ID to trace CdmSessionAdapter::CreateCdm() call and the matching // OnCdmCreated() call.
diff --git a/third_party/blink/renderer/platform/media/key_system_config_selector.cc b/third_party/blink/renderer/platform/media/key_system_config_selector.cc index 32cf756a..ca92f09d 100644 --- a/third_party/blink/renderer/platform/media/key_system_config_selector.cc +++ b/third_party/blink/renderer/platform/media/key_system_config_selector.cc
@@ -158,7 +158,7 @@ << ", use_aes_decryptor=" << use_aes_decryptor; std::vector<std::string> codec_vector; - SplitCodecs(codecs, &codec_vector); + media::SplitCodecs(codecs, &codec_vector); #if BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_HEVC) // EME HEVC is supported on under this build flag, but it is not supported for @@ -188,11 +188,12 @@ // AesDecryptor decrypts the stream in the demuxer before it reaches the // decoder so check whether the media format is supported when clear. - SupportsType support_result = + media::SupportsType support_result = use_aes_decryptor - ? IsSupportedMediaFormat(container_mime_type, codec_vector) - : IsSupportedEncryptedMediaFormat(container_mime_type, codec_vector); - return (support_result == IsSupported); + ? media::IsSupportedMediaFormat(container_mime_type, codec_vector) + : media::IsSupportedEncryptedMediaFormat(container_mime_type, + codec_vector); + return (support_result == media::IsSupported); } } // namespace @@ -362,8 +363,8 @@ }; KeySystemConfigSelector::KeySystemConfigSelector( - KeySystems* key_systems, - MediaPermission* media_permission, + media::KeySystems* key_systems, + media::MediaPermission* media_permission, std::unique_ptr<WebLocalFrameDelegate> web_frame_delegate) : key_systems_(key_systems), media_permission_(media_permission), @@ -413,7 +414,7 @@ // Before checking CDM support, split |codecs| into a vector of codecs. std::vector<std::string> codec_vector; - SplitCodecs(codecs, &codec_vector); + media::SplitCodecs(codecs, &codec_vector); // Check that |container_lower| and |codec_vector| are supported by the CDM. EmeConfigRule codecs_rule = key_systems_->GetContentTypeConfigRule( @@ -602,12 +603,12 @@ // run the following steps: if (!candidate.init_data_types.empty()) { // 3.1. Let supported types be an empty sequence of DOMStrings. - std::vector<EmeInitDataType> supported_types; + std::vector<media::EmeInitDataType> supported_types; // 3.2. For each value in candidate configuration's initDataTypes member: for (size_t i = 0; i < candidate.init_data_types.size(); i++) { // 3.2.1. Let initDataType be the value. - EmeInitDataType init_data_type = candidate.init_data_types[i]; + auto init_data_type = candidate.init_data_types[i]; // 3.2.2. If the implementation supports generating requests based on // initDataType, add initDataType to supported types. String @@ -1017,7 +1018,7 @@ // // Therefore, always support Clear Key key system and only check settings for // other key systems. - if (!is_encrypted_media_enabled && !IsClearKey(key_system_ascii)) { + if (!is_encrypted_media_enabled && !media::IsClearKey(key_system_ascii)) { std::move(cb).Run(Status::kUnsupportedKeySystem, nullptr, nullptr); return; } @@ -1051,7 +1052,7 @@ ConfigState config_state(request->was_permission_requested, request->is_permission_granted); blink::WebMediaKeySystemConfiguration accumulated_configuration; - CdmConfig cdm_config; + media::CdmConfig cdm_config; ConfigurationSupport support = GetSupportedConfiguration( request->key_system, request->candidate_configurations[i], &config_state, &accumulated_configuration); @@ -1066,7 +1067,7 @@ } DVLOG(3) << "Request permission."; media_permission_->RequestPermission( - MediaPermission::PROTECTED_MEDIA_IDENTIFIER, + media::MediaPermission::PROTECTED_MEDIA_IDENTIFIER, base::BindOnce(&KeySystemConfigSelector::OnPermissionResult, weak_factory_.GetWeakPtr(), std::move(request))); return;
diff --git a/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc b/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc index 146dbff7..faa68b90 100644 --- a/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc +++ b/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc
@@ -146,7 +146,7 @@ return false; std::vector<std::string> codec_vector; - SplitCodecs(codecs, &codec_vector); + media::SplitCodecs(codecs, &codec_vector); for (const std::string& codec : codec_vector) { DCHECK_NE(codec, kExtendedVideoCodecStripped) << "codecs passed into this function should not be stripped"; @@ -193,7 +193,7 @@ return config; } -class FakeKeySystems : public KeySystems { +class FakeKeySystems : public media::KeySystems { public: ~FakeKeySystems() override = default; @@ -353,7 +353,7 @@ int update_count = 0; }; -class FakeMediaPermission : public MediaPermission { +class FakeMediaPermission : public media::MediaPermission { public: // MediaPermission implementation. void HasPermission(Type type, @@ -462,7 +462,7 @@ void OnConfigSelected(KeySystemConfigSelector::Status status, WebMediaKeySystemConfiguration* config, - CdmConfig* cdm_config) { + media::CdmConfig* cdm_config) { if (status == KeySystemConfigSelector::Status::kSupported) { succeeded_count_++; config_ = *config; @@ -482,7 +482,7 @@ // Holds the selected configuration and CdmConfig. WebMediaKeySystemConfiguration config_; - CdmConfig cdm_config_; + media::CdmConfig cdm_config_; int succeeded_count_; int not_supported_count_;
diff --git a/third_party/blink/renderer/platform/media/multi_buffer.cc b/third_party/blink/renderer/platform/media/multi_buffer.cc index 48510a1..4ff9dd6 100644 --- a/third_party/blink/renderer/platform/media/multi_buffer.cc +++ b/third_party/blink/renderer/platform/media/multi_buffer.cc
@@ -397,7 +397,7 @@ break; } DCHECK_GE(pos, 0); - scoped_refptr<DataBuffer> data = provider->Read(); + scoped_refptr<media::DataBuffer> data = provider->Read(); data_[pos] = data; eof = data->end_of_stream(); if (!pinned_[pos]) @@ -478,7 +478,7 @@ void MultiBuffer::GetBlocksThreadsafe( const BlockId& from, const BlockId& to, - std::vector<scoped_refptr<DataBuffer>>* output) { + std::vector<scoped_refptr<media::DataBuffer>>* output) { base::AutoLock auto_lock(data_lock_); auto i = data_.find(from); BlockId j = from;
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc index d1977cfb..cd898d5 100644 --- a/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc +++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source.cc
@@ -69,7 +69,7 @@ ReadOperation(int64_t position, int size, uint8_t* data, - DataSource::ReadCB callback); + media::DataSource::ReadCB callback); ReadOperation(const ReadOperation&) = delete; ReadOperation& operator=(const ReadOperation&) = delete; ~ReadOperation(); @@ -86,13 +86,14 @@ const int64_t position_; const int size_; uint8_t* data_; - DataSource::ReadCB callback_; + media::DataSource::ReadCB callback_; }; -MultiBufferDataSource::ReadOperation::ReadOperation(int64_t position, - int size, - uint8_t* data, - DataSource::ReadCB callback) +MultiBufferDataSource::ReadOperation::ReadOperation( + int64_t position, + int size, + uint8_t* data, + media::DataSource::ReadCB callback) : position_(position), size_(size), data_(data), @@ -114,7 +115,7 @@ MultiBufferDataSource::MultiBufferDataSource( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, scoped_refptr<UrlData> url_data_arg, - MediaLog* media_log, + media::MediaLog* media_log, BufferedDataSourceHost* host, DownloadingCB downloading_cb) : total_bytes_(kPositionNotSpecified), @@ -392,7 +393,7 @@ void MultiBufferDataSource::Read(int64_t position, int size, uint8_t* data, - DataSource::ReadCB read_cb) { + media::DataSource::ReadCB read_cb) { DVLOG(1) << "Read: " << position << " offset, " << size << " bytes"; // Reading is not allowed until after initialization. DCHECK(!init_cb_); @@ -606,8 +607,8 @@ !AssumeFullyBuffered() && (total_bytes_ == kPositionNotSpecified || !url_data_->range_supported()); - media_log_->SetProperty<MediaLogProperty::kTotalBytes>(total_bytes_); - media_log_->SetProperty<MediaLogProperty::kIsStreaming>(streaming_); + media_log_->SetProperty<media::MediaLogProperty::kTotalBytes>(total_bytes_); + media_log_->SetProperty<media::MediaLogProperty::kIsStreaming>(streaming_); } else { SetReader(nullptr); } @@ -627,8 +628,9 @@ // Progress callback might be called after the start callback, // make sure that we update single_origin_ now. - media_log_->SetProperty<MediaLogProperty::kIsSingleOrigin>(single_origin_); - media_log_->SetProperty<MediaLogProperty::kIsRangeHeaderSupported>( + media_log_->SetProperty<media::MediaLogProperty::kIsSingleOrigin>( + single_origin_); + media_log_->SetProperty<media::MediaLogProperty::kIsRangeHeaderSupported>( url_data_->range_supported()); }
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc index cadea287..44c075b 100644 --- a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc +++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
@@ -229,7 +229,7 @@ private: // Whether the resource is downloading or deferred. bool downloading_; - NullMediaLog media_log_; + media::NullMediaLog media_log_; }; static const int64_t kFileSize = 5000000;
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_reader.cc b/third_party/blink/renderer/platform/media/multi_buffer_reader.cc index 642708749..448eaad 100644 --- a/third_party/blink/renderer/platform/media/multi_buffer_reader.cc +++ b/third_party/blink/renderer/platform/media/multi_buffer_reader.cc
@@ -87,7 +87,7 @@ int64_t MultiBufferReader::TryReadAt(int64_t pos, uint8_t* data, int64_t len) { DCHECK_GT(len, 0); - std::vector<scoped_refptr<DataBuffer>> buffers; + std::vector<scoped_refptr<media::DataBuffer>> buffers; multibuffer_->GetBlocksThreadsafe(block(pos), block_ceil(pos + len), &buffers); int64_t bytes_read = 0;
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_unittest.cc b/third_party/blink/renderer/platform/media/multi_buffer_unittest.cc index 26cd142..e3fa05d 100644 --- a/third_party/blink/renderer/platform/media/multi_buffer_unittest.cc +++ b/third_party/blink/renderer/platform/media/multi_buffer_unittest.cc
@@ -15,6 +15,7 @@ #include "base/callback_helpers.h" #include "base/containers/circular_deque.h" #include "base/logging.h" +#include "base/memory/scoped_refptr.h" #include "base/single_thread_task_runner.h" #include "base/test/simple_test_tick_clock.h" #include "media/base/fake_single_thread_task_runner.h" @@ -40,7 +41,7 @@ int max_blocks_after_defer, bool must_read_whole_file, MultiBuffer* multibuffer, - TestRandom* rnd) + media::TestRandom* rnd) : pos_(pos), blocks_until_deferred_(1 << 30), max_blocks_after_defer_(max_blocks_after_defer), @@ -70,9 +71,9 @@ bool Available() const override { return !fifo_.empty(); } int64_t AvailableBytes() const override { return 0; } - scoped_refptr<DataBuffer> Read() override { + scoped_refptr<media::DataBuffer> Read() override { DCHECK(Available()); - scoped_refptr<DataBuffer> ret = fifo_.front(); + scoped_refptr<media::DataBuffer> ret = fifo_.front(); fifo_.pop_front(); ++pos_; return ret; @@ -98,7 +99,7 @@ --blocks_until_deferred_; bool ret = true; - scoped_refptr<DataBuffer> block = new DataBuffer(kBlockSize); + auto block = base::MakeRefCounted<media::DataBuffer>(kBlockSize); size_t x = 0; size_t byte_pos = (fifo_.size() + pos_) * kBlockSize; for (x = 0; x < kBlockSize; x++, byte_pos++) { @@ -110,7 +111,7 @@ block->set_data_size(static_cast<int>(x)); fifo_.push_back(block); if (byte_pos == file_size_) { - fifo_.push_back(DataBuffer::CreateEOSBuffer()); + fifo_.push_back(media::DataBuffer::CreateEOSBuffer()); ret = false; } multibuffer_->OnDataProviderEvent(this); @@ -118,21 +119,21 @@ } private: - base::circular_deque<scoped_refptr<DataBuffer>> fifo_; + base::circular_deque<scoped_refptr<media::DataBuffer>> fifo_; MultiBufferBlockId pos_; int32_t blocks_until_deferred_; int32_t max_blocks_after_defer_; size_t file_size_; bool must_read_whole_file_; MultiBuffer* multibuffer_; - TestRandom* rnd_; + media::TestRandom* rnd_; }; class TestMultiBuffer : public MultiBuffer { public: explicit TestMultiBuffer(int32_t shift, const scoped_refptr<MultiBuffer::GlobalLRU>& lru, - TestRandom* rnd) + media::TestRandom* rnd) : MultiBuffer(shift, lru), range_supported_(false), create_ok_(true), @@ -219,14 +220,14 @@ int32_t max_blocks_after_defer_; bool must_read_whole_file_; int32_t writers_created_; - TestRandom* rnd_; + media::TestRandom* rnd_; }; class MultiBufferTest : public testing::Test { public: MultiBufferTest() : rnd_(42), - task_runner_(new FakeSingleThreadTaskRunner(&clock_)), + task_runner_(new media::FakeSingleThreadTaskRunner(&clock_)), lru_(new MultiBuffer::GlobalLRU(task_runner_)), multibuffer_(kBlockSizeShift, lru_, &rnd_) {} @@ -252,9 +253,9 @@ } protected: - TestRandom rnd_; + media::TestRandom rnd_; base::SimpleTestTickClock clock_; - scoped_refptr<FakeSingleThreadTaskRunner> task_runner_; + scoped_refptr<media::FakeSingleThreadTaskRunner> task_runner_; scoped_refptr<MultiBuffer::GlobalLRU> lru_; TestMultiBuffer multibuffer_; }; @@ -483,7 +484,7 @@ ReadHelper(size_t end, size_t max_read_size, MultiBuffer* multibuffer, - TestRandom* rnd, + media::TestRandom* rnd, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : pos_(0), end_(end), @@ -540,7 +541,7 @@ int64_t end_; int64_t max_read_size_; int64_t read_size_; - TestRandom* rnd_; + media::TestRandom* rnd_; MultiBufferReader reader_; };
diff --git a/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h b/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h index ce27d4e..f78f42d4 100644 --- a/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h +++ b/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h
@@ -43,7 +43,7 @@ // |new_session_created_cb| must be in |expected_statuses| for the promise to // be resolved. If it's not in the list, the promise will be rejected. class PLATFORM_EXPORT NewSessionCdmResultPromise - : public CdmPromiseTemplate<std::string> { + : public media::CdmPromiseTemplate<std::string> { public: NewSessionCdmResultPromise( const blink::WebContentDecryptionModuleResult& result, @@ -56,7 +56,7 @@ delete; ~NewSessionCdmResultPromise() override; - // CdmPromiseTemplate<T> implementation. + // media::CdmPromiseTemplate<T> implementation. void resolve(const std::string& session_id) override; void reject(CdmPromise::Exception exception_code, uint32_t system_code,
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc index 6f5c839..1b46574 100644 --- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc +++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
@@ -162,9 +162,9 @@ return bytes; } -scoped_refptr<DataBuffer> ResourceMultiBufferDataProvider::Read() { +scoped_refptr<media::DataBuffer> ResourceMultiBufferDataProvider::Read() { DCHECK(Available()); - scoped_refptr<DataBuffer> ret = fifo_.front(); + scoped_refptr<media::DataBuffer> ret = fifo_.front(); fifo_.pop_front(); ++pos_; return ret; @@ -380,7 +380,7 @@ } if (end_of_file) { - fifo_.push_back(DataBuffer::CreateEOSBuffer()); + fifo_.push_back(media::DataBuffer::CreateEOSBuffer()); url_data_->multibuffer()->OnDataProviderEvent(this); } } @@ -406,7 +406,7 @@ while (data_length) { if (fifo_.empty() || fifo_.back()->data_size() == block_size()) { - fifo_.push_back(new DataBuffer(block_size())); + fifo_.push_back(new media::DataBuffer(block_size())); fifo_.back()->set_data_size(0); } int last_block_size = fifo_.back()->data_size(); @@ -458,7 +458,7 @@ } url_data_->set_length(size); - fifo_.push_back(DataBuffer::CreateEOSBuffer()); + fifo_.push_back(media::DataBuffer::CreateEOSBuffer()); if (url_data_->url_index()) { url_data_->url_index()->TryInsert(url_data_); @@ -535,7 +535,7 @@ } void ResourceMultiBufferDataProvider::Terminate() { - fifo_.push_back(DataBuffer::CreateEOSBuffer()); + fifo_.push_back(media::DataBuffer::CreateEOSBuffer()); url_data_->multibuffer()->OnDataProviderEvent(this); }
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h index 13b52f8..0266865 100644 --- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h +++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h
@@ -52,7 +52,7 @@ MultiBufferBlockId Tell() const override; bool Available() const override; int64_t AvailableBytes() const override; - scoped_refptr<DataBuffer> Read() override; + scoped_refptr<media::DataBuffer> Read() override; void SetDeferred(bool defer) override; // blink::WebAssociatedURLLoaderClient implementation. @@ -103,7 +103,7 @@ UrlData* url_data_; // Temporary storage for incoming data. - std::list<scoped_refptr<DataBuffer>> fifo_; + std::list<scoped_refptr<media::DataBuffer>> fifo_; // How many retries have we done at the current position. int retries_;
diff --git a/third_party/blink/renderer/platform/media/text_track_impl.h b/third_party/blink/renderer/platform/media/text_track_impl.h index df4f3b5..5214cebb 100644 --- a/third_party/blink/renderer/platform/media/text_track_impl.h +++ b/third_party/blink/renderer/platform/media/text_track_impl.h
@@ -23,7 +23,7 @@ class WebInbandTextTrackImpl; -class PLATFORM_EXPORT TextTrackImpl : public TextTrack { +class PLATFORM_EXPORT TextTrackImpl : public media::TextTrack { public: // Constructor assumes ownership of the |text_track| object. TextTrackImpl(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
diff --git a/third_party/blink/renderer/platform/media/video_decode_stats_reporter.cc b/third_party/blink/renderer/platform/media/video_decode_stats_reporter.cc index ea87ccc..d0fa7a62 100644 --- a/third_party/blink/renderer/platform/media/video_decode_stats_reporter.cc +++ b/third_party/blink/renderer/platform/media/video_decode_stats_reporter.cc
@@ -15,12 +15,12 @@ namespace media { VideoDecodeStatsReporter::VideoDecodeStatsReporter( - mojo::PendingRemote<mojom::VideoDecodeStatsRecorder> recorder_remote, + mojo::PendingRemote<media::mojom::VideoDecodeStatsRecorder> recorder_remote, GetPipelineStatsCB get_pipeline_stats_cb, - VideoCodecProfile codec_profile, + media::VideoCodecProfile codec_profile, const gfx::Size& natural_size, std::string key_system, - absl::optional<CdmConfig> cdm_config, + absl::optional<media::CdmConfig> cdm_config, scoped_refptr<base::SingleThreadTaskRunner> task_runner, const base::TickClock* tick_clock) : kRecordingInterval( @@ -30,7 +30,7 @@ recorder_remote_(std::move(recorder_remote)), get_pipeline_stats_cb_(std::move(get_pipeline_stats_cb)), codec_profile_(codec_profile), - natural_size_(GetSizeBucket(natural_size)), + natural_size_(media::GetSizeBucket(natural_size)), key_system_(key_system), use_hw_secure_codecs_(cdm_config ? cdm_config->use_hw_secure_codecs : false), @@ -38,7 +38,7 @@ stats_cb_timer_(tick_clock_) { DCHECK(recorder_remote_.is_bound()); DCHECK(get_pipeline_stats_cb_); - DCHECK_NE(VIDEO_CODEC_PROFILE_UNKNOWN, codec_profile_); + DCHECK_NE(media::VIDEO_CODEC_PROFILE_UNKNOWN, codec_profile_); DCHECK(!cdm_config || !key_system_.empty()); recorder_remote_.set_disconnect_handler(base::BindOnce( @@ -98,7 +98,7 @@ if (num_stable_fps_samples_ >= kRequiredStableFpsSamples) { // Dropped frames are not reported during background rendering. Start a new // record to avoid reporting background stats. - PipelineStatistics stats = get_pipeline_stats_cb_.Run(); + media::PipelineStatistics stats = get_pipeline_stats_cb_.Run(); StartNewRecord(stats.video_frames_decoded, stats.video_frames_dropped, stats.video_frames_decoded_power_efficient); } @@ -110,8 +110,8 @@ bool VideoDecodeStatsReporter::MatchesBucketedNaturalSize( const gfx::Size& natural_size) const { // Stored natural size should always be bucketed. - DCHECK(natural_size_ == GetSizeBucket(natural_size_)); - return GetSizeBucket(natural_size) == natural_size_; + DCHECK(natural_size_ == media::GetSizeBucket(natural_size_)); + return media::GetSizeBucket(natural_size) == natural_size_; } void VideoDecodeStatsReporter::RunStatsTimerAtInterval( @@ -137,8 +137,8 @@ << " use_hw_secure_codecs:" << use_hw_secure_codecs_; // Size and frame rate should always be bucketed. - DCHECK(natural_size_ == GetSizeBucket(natural_size_)); - DCHECK_EQ(last_observed_fps_, GetFpsBucket(last_observed_fps_)); + DCHECK(natural_size_ == media::GetSizeBucket(natural_size_)); + DCHECK_EQ(last_observed_fps_, media::GetFpsBucket(last_observed_fps_)); // New records decoded and dropped counts should start at zero. // These should never move backward. @@ -152,7 +152,7 @@ frames_decoded_power_efficient_offset; bool use_hw_secure_codecs = use_hw_secure_codecs_; - mojom::PredictionFeaturesPtr features = mojom::PredictionFeatures::New( + auto features = media::mojom::PredictionFeatures::New( codec_profile_, natural_size_, last_observed_fps_, key_system_, use_hw_secure_codecs); @@ -184,7 +184,7 @@ } bool VideoDecodeStatsReporter::UpdateDecodeProgress( - const PipelineStatistics& stats) { + const media::PipelineStatistics& stats) { DCHECK_GE(stats.video_frames_decoded, last_frames_decoded_); DCHECK_GE(stats.video_frames_dropped, last_frames_dropped_); @@ -205,7 +205,7 @@ } bool VideoDecodeStatsReporter::UpdateFrameRateStability( - const PipelineStatistics& stats) { + const media::PipelineStatistics& stats) { // When (re)initializing, the pipeline may momentarily return an average frame // duration of zero. Ignore it and wait for a real frame rate. if (stats.video_frame_duration_average.is_zero()) @@ -213,7 +213,7 @@ // Bucket frame rate to simplify metrics aggregation. int frame_rate = - GetFpsBucket(1 / stats.video_frame_duration_average.InSecondsF()); + media::GetFpsBucket(1 / stats.video_frame_duration_average.InSecondsF()); if (frame_rate != last_observed_fps_) { DVLOG(2) << __func__ << " fps changed: " << last_observed_fps_ << " -> " @@ -285,7 +285,7 @@ void VideoDecodeStatsReporter::UpdateStats() { DCHECK(ShouldBeReporting()); - PipelineStatistics stats = get_pipeline_stats_cb_.Run(); + media::PipelineStatistics stats = get_pipeline_stats_cb_.Run(); DVLOG(2) << __func__ << " Raw stats -- dropped:" << stats.video_frames_dropped << "/" << stats.video_frames_decoded << " power efficient:" << stats.video_frames_decoded_power_efficient @@ -319,7 +319,7 @@ frames_decoded_power_efficient_offset_, frames_decoded); - mojom::PredictionTargetsPtr targets = mojom::PredictionTargets::New( + auto targets = media::mojom::PredictionTargets::New( frames_decoded, frames_dropped, frames_power_efficient); DVLOG(2) << __func__ << " Recording -- dropped:" << targets->frames_dropped
diff --git a/third_party/blink/renderer/platform/media/video_decode_stats_reporter.h b/third_party/blink/renderer/platform/media/video_decode_stats_reporter.h index 092054b..ac1e06b98 100644 --- a/third_party/blink/renderer/platform/media/video_decode_stats_reporter.h +++ b/third_party/blink/renderer/platform/media/video_decode_stats_reporter.h
@@ -32,15 +32,17 @@ // finalized at destruction and process tear-down. class PLATFORM_EXPORT VideoDecodeStatsReporter { public: - using GetPipelineStatsCB = base::RepeatingCallback<PipelineStatistics(void)>; + using GetPipelineStatsCB = + base::RepeatingCallback<media::PipelineStatistics(void)>; VideoDecodeStatsReporter( - mojo::PendingRemote<mojom::VideoDecodeStatsRecorder> recorder_remote, + mojo::PendingRemote<media::mojom::VideoDecodeStatsRecorder> + recorder_remote, GetPipelineStatsCB get_pipeline_stats_cb, - VideoCodecProfile codec_profile, + media::VideoCodecProfile codec_profile, const gfx::Size& natural_size, std::string key_system, - absl::optional<CdmConfig> cdm_config, + absl::optional<media::CdmConfig> cdm_config, scoped_refptr<base::SingleThreadTaskRunner> task_runner, const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance()); @@ -59,7 +61,7 @@ bool MatchesBucketedNaturalSize(const gfx::Size& natural_size) const; // NOTE: We do not listen for playback rate changes. These implicitly change - // the frame rate and surface via PipelineStatistics' + // the frame rate and surface via media::PipelineStatistics' // video_frame_duration_average. private: @@ -127,12 +129,12 @@ // decode/dropped frame counts. Will manage decoded/dropped frame state and // relax timer when no decode progress is made. Returns true iff decode is // progressing. - bool UpdateDecodeProgress(const PipelineStatistics& stats); + bool UpdateDecodeProgress(const media::PipelineStatistics& stats); // Called by UpdateStats() to do frame rate detection. Will manage frame rate // state, stats timer, and will start new capabilities records when frame rate // changes. Returns true iff frame rate is stable. - bool UpdateFrameRateStability(const PipelineStatistics& stats); + bool UpdateFrameRateStability(const media::PipelineStatistics& stats); // Returns true if the |stats_timer_cb_| should be running. Should be called // after any state change (e.g. |is_playing_|) as a check on whether to start @@ -150,13 +152,13 @@ // mojo::Remote for the recorder. The recorder runs in the browser process // and finalizes the record in the event of fast render process tear down. - mojo::Remote<mojom::VideoDecodeStatsRecorder> recorder_remote_; + mojo::Remote<media::mojom::VideoDecodeStatsRecorder> recorder_remote_; // Callback for retrieving playback statistics. GetPipelineStatsCB get_pipeline_stats_cb_; // Current video codec profile, used to index recorded stats. - const VideoCodecProfile codec_profile_; + const media::VideoCodecProfile codec_profile_; // Current video natural size, used to index recorded stats. These dimensions // will always be rounded to the nearest size bucket. If the original size is @@ -166,7 +168,7 @@ // The name of the current key system. Empty for unencrypted playback. const std::string key_system_; - // From CdmConfig in constructor. + // From media::CdmConfig in constructor. const bool use_hw_secure_codecs_; // Clock for |stats_cb_timer_| and getting current tick count (NowTicks()).
diff --git a/third_party/blink/renderer/platform/media/video_decode_stats_reporter_unittest.cc b/third_party/blink/renderer/platform/media/video_decode_stats_reporter_unittest.cc index 1ac0db5..a91f0e7 100644 --- a/third_party/blink/renderer/platform/media/video_decode_stats_reporter_unittest.cc +++ b/third_party/blink/renderer/platform/media/video_decode_stats_reporter_unittest.cc
@@ -33,34 +33,36 @@ namespace media { -const VideoCodecProfile kDefaultProfile = VP9PROFILE_PROFILE0; +const media::VideoCodecProfile kDefaultProfile = media::VP9PROFILE_PROFILE0; const int kDefaultHeight = 480; const int kDefaultWidth = 640; const char kDefaultKeySystem[] = "org.w3.clearkey"; const bool kDefaultUseHwSecureCodecs = true; -const CdmConfig kDefaultCdmConfig = {false, false, kDefaultUseHwSecureCodecs}; +const media::CdmConfig kDefaultCdmConfig = {false, false, + kDefaultUseHwSecureCodecs}; const double kDefaultFps = 30; const int kDecodeCountIncrement = 20; const int kDroppedCountIncrement = 1; const int kDecodePowerEfficientCountIncrement = 1; -VideoDecoderConfig MakeVideoConfig(VideoCodec codec, - VideoCodecProfile profile, - gfx::Size natural_size) { +media::VideoDecoderConfig MakeVideoConfig(media::VideoCodec codec, + media::VideoCodecProfile profile, + gfx::Size natural_size) { gfx::Size coded_size = natural_size; gfx::Rect visible_rect(coded_size.width(), coded_size.height()); - return VideoDecoderConfig( - codec, profile, VideoDecoderConfig::AlphaMode::kIsOpaque, - VideoColorSpace::JPEG(), kNoTransformation, coded_size, visible_rect, - natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); + return media::VideoDecoderConfig( + codec, profile, media::VideoDecoderConfig::AlphaMode::kIsOpaque, + media::VideoColorSpace::JPEG(), media::kNoTransformation, coded_size, + visible_rect, natural_size, media::EmptyExtraData(), + media::EncryptionScheme::kUnencrypted); } -PipelineStatistics MakeStats(int frames_decoded, - int frames_dropped, - int power_efficient_decoded_frames, - double fps) { +media::PipelineStatistics MakeStats(int frames_decoded, + int frames_dropped, + int power_efficient_decoded_frames, + double fps) { // Will initialize members with reasonable defaults. - PipelineStatistics stats; + media::PipelineStatistics stats; stats.video_frames_decoded = frames_decoded; stats.video_frames_dropped = frames_dropped; stats.video_frames_decoded_power_efficient = power_efficient_decoded_frames; @@ -69,26 +71,26 @@ } // Mock VideoDecodeStatsRecorder to verify reporter/recorder interactions. -class RecordInterceptor : public mojom::VideoDecodeStatsRecorder { +class RecordInterceptor : public media::mojom::VideoDecodeStatsRecorder { public: RecordInterceptor() = default; ~RecordInterceptor() override = default; // Until move-only types work. - void StartNewRecord(mojom::PredictionFeaturesPtr features) override { + void StartNewRecord(media::mojom::PredictionFeaturesPtr features) override { MockStartNewRecord(features->profile, features->video_size, features->frames_per_sec, features->key_system, features->use_hw_secure_codecs); } MOCK_METHOD5(MockStartNewRecord, - void(VideoCodecProfile profile, + void(media::VideoCodecProfile profile, const gfx::Size& natural_size, int frames_per_sec, std::string key_system, bool use_hw_secure_codecs)); - void UpdateRecord(mojom::PredictionTargetsPtr targets) override { + void UpdateRecord(media::mojom::PredictionTargetsPtr targets) override { MockUpdateRecord(targets->frames_decoded, targets->frames_dropped, targets->frames_power_efficient); } @@ -127,7 +129,7 @@ task_environment_.RunUntilIdle(); } - PipelineStatistics MakeAdvancingDecodeStats() { + media::PipelineStatistics MakeAdvancingDecodeStats() { pipeline_decoded_frames_ += kDecodeCountIncrement; pipeline_dropped_frames_ += kDroppedCountIncrement; pipeline_power_efficient_frames_ += kDecodePowerEfficientCountIncrement; @@ -137,7 +139,7 @@ // Peek at what MakeAdvancingDecodeStats() will return next without advancing // the tracked counts. - PipelineStatistics PeekNextDecodeStats() const { + media::PipelineStatistics PeekNextDecodeStats() const { return MakeStats( pipeline_decoded_frames_ + kDecodeCountIncrement, pipeline_dropped_frames_ + kDroppedCountIncrement, @@ -157,16 +159,16 @@ SLOW_STABILIZE_FPS, }; - // Return mojo::PendingRemote<mojom::VideoDecodeStatsRecorder> + // Return mojo::PendingRemote<media::mojom::VideoDecodeStatsRecorder> // after binding the RecordInterceptor to the receiver for a // VideoDecodeStatsRecorder. The interceptor serves as a mock recorder to // verify reporter/recorder interactions. - mojo::PendingRemote<mojom::VideoDecodeStatsRecorder> SetupRecordInterceptor( - RecordInterceptor** interceptor) { + mojo::PendingRemote<media::mojom::VideoDecodeStatsRecorder> + SetupRecordInterceptor(RecordInterceptor** interceptor) { // Capture a the interceptor pointer for verifying recorder calls. Lifetime // will be managed by the |recorder_remote|. *interceptor = new RecordInterceptor(); - mojo::PendingRemote<mojom::VideoDecodeStatsRecorder> recorder_remote; + mojo::PendingRemote<media::mojom::VideoDecodeStatsRecorder> recorder_remote; mojo::MakeSelfOwnedReceiver( base::WrapUnique(*interceptor), recorder_remote.InitWithNewPipeAndPassReceiver()); @@ -176,10 +178,10 @@ // Inject mock objects and create a new |reporter_| to test. void MakeReporter( - VideoCodecProfile profile = kDefaultProfile, + media::VideoCodecProfile profile = kDefaultProfile, const gfx::Size& natural_size = gfx::Size(kDefaultWidth, kDefaultHeight), const std::string key_system = kDefaultKeySystem, - const absl::optional<CdmConfig> cdm_config = kDefaultCdmConfig) { + const absl::optional<media::CdmConfig> cdm_config = kDefaultCdmConfig) { reporter_ = std::make_unique<VideoDecodeStatsReporter>( SetupRecordInterceptor(&interceptor_), base::BindRepeating(&VideoDecodeStatsReporterTest::GetPipelineStatsCB, @@ -211,7 +213,7 @@ // hidden state) // 3) No progress made yet toward stabilizing framerate. void StartPlayingAndStabilizeFramerate( - VideoCodecProfile expected_profile = kDefaultProfile, + media::VideoCodecProfile expected_profile = kDefaultProfile, gfx::Size expected_natural_size = gfx::Size(kDefaultWidth, kDefaultHeight), int expected_fps = kDefaultFps, @@ -248,7 +250,7 @@ // 2. Only call with GetPipelineStatsCB configured to return // progressing decode stats with a steady framerate. void StabilizeFramerateAndStartNewRecord( - VideoCodecProfile expected_profile, + media::VideoCodecProfile expected_profile, gfx::Size expected_natural_size, int expected_fps, std::string expected_key_system, @@ -256,18 +258,18 @@ FpsStabiliaztionSpeed fps_timer_speed = FAST_STABILIZE_FPS) { ASSERT_TRUE(ShouldBeReporting()); - base::TimeDelta last_frame_duration = kNoTimestamp; + base::TimeDelta last_frame_duration = media::kNoTimestamp; uint32_t last_decoded_frames = 0; while (CurrentStableFpsSamples() < kRequiredStableFpsSamples) { - PipelineStatistics next_stats = PeekNextDecodeStats(); + media::PipelineStatistics next_stats = PeekNextDecodeStats(); // Sanity check that the stats callback is progressing decode. DCHECK_GT(next_stats.video_frames_decoded, last_decoded_frames); last_decoded_frames = next_stats.video_frames_decoded; // Sanity check that the stats callback is providing steady fps. - if (last_frame_duration != kNoTimestamp) { + if (last_frame_duration != media::kNoTimestamp) { DCHECK_EQ(next_stats.video_frame_duration_average, last_frame_duration); } last_frame_duration = next_stats.video_frame_duration_average; @@ -318,7 +320,7 @@ // variable to workaround linker confusion with test macros. EXPECT_EQ(kRecordingInterval, CurrentStatsCbInterval()); - PipelineStatistics next_stats = PeekNextDecodeStats(); + media::PipelineStatistics next_stats = PeekNextDecodeStats(); // Decode stats must be advancing for record updates to be expected. Dropped // frames should at least not move backward. @@ -343,7 +345,7 @@ // Injected callback for fetching statistics. Each test will manage // expectations and return behavior. - MOCK_METHOD0(GetPipelineStatsCB, PipelineStatistics()); + MOCK_METHOD0(GetPipelineStatsCB, media::PipelineStatistics()); base::test::SingleThreadTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; @@ -777,7 +779,7 @@ FastForward(kRecordingInterval); // Verify new record uses bucketed framerate. - int bucketed_fps = GetFpsBucket(pipeline_framerate_); + int bucketed_fps = media::GetFpsBucket(pipeline_framerate_); EXPECT_NE(bucketed_fps, pipeline_framerate_); StabilizeFramerateAndStartNewRecord(kDefaultProfile, kDefaultSize_, bucketed_fps, kDefaultKeySystem, @@ -796,7 +798,7 @@ EXPECT_TRUE(reporter_->MatchesBucketedNaturalSize(kDefaultSize_)); // Note that our current size fits perfectly into known buckets... - EXPECT_EQ(GetSizeBucket(kDefaultSize_), kDefaultSize_); + EXPECT_EQ(media::GetSizeBucket(kDefaultSize_), kDefaultSize_); // A slightly smaller size should fall into the same size bucket as before. gfx::Size slightly_smaller_size(kDefaultWidth - 2, kDefaultHeight - 2); @@ -845,7 +847,8 @@ MakeReporter(kDefaultProfile, small_size); // Stabilize new framerate and verify record updates come with new offsets. - StartPlayingAndStabilizeFramerate(kDefaultProfile, GetSizeBucket(small_size)); + StartPlayingAndStabilizeFramerate(kDefaultProfile, + media::GetSizeBucket(small_size)); // Framerate is now stable! Recorded stats should be offset by the values // last provided to GetPipelineStatsCB. @@ -861,8 +864,8 @@ const gfx::Size kDefaultSize(kDefaultWidth, kDefaultHeight); const char kEmptyKeySystem[] = ""; const bool kNonDefaultHwSecureCodecs = !kDefaultUseHwSecureCodecs; - const CdmConfig kNonDefaultCdmConfig = {false, false, - kNonDefaultHwSecureCodecs}; + const media::CdmConfig kNonDefaultCdmConfig = {false, false, + kNonDefaultHwSecureCodecs}; const char kFooKeySystem[] = "fookeysytem"; // Make reporter with no EME properties.
diff --git a/third_party/blink/renderer/platform/media/video_frame_compositor.cc b/third_party/blink/renderer/platform/media/video_frame_compositor.cc index 455108c..dc92202 100644 --- a/third_party/blink/renderer/platform/media/video_frame_compositor.cc +++ b/third_party/blink/renderer/platform/media/video_frame_compositor.cc
@@ -84,10 +84,9 @@ client_->StopUsingProvider(); } -void VideoFrameCompositor::EnableSubmission( - const viz::SurfaceId& id, - VideoRotation rotation, - bool force_submit) { +void VideoFrameCompositor::EnableSubmission(const viz::SurfaceId& id, + media::VideoRotation rotation, + bool force_submit) { DCHECK(task_runner_->BelongsToCurrentThread()); // If we're switching to |submitter_| from some other client, then tell it. @@ -157,18 +156,19 @@ client_->StartRendering(); } -scoped_refptr<VideoFrame> VideoFrameCompositor::GetCurrentFrame() { +scoped_refptr<media::VideoFrame> VideoFrameCompositor::GetCurrentFrame() { DCHECK(task_runner_->BelongsToCurrentThread()); return current_frame_; } -scoped_refptr<VideoFrame> VideoFrameCompositor::GetCurrentFrameOnAnyThread() { +scoped_refptr<media::VideoFrame> +VideoFrameCompositor::GetCurrentFrameOnAnyThread() { base::AutoLock lock(current_frame_lock_); return current_frame_; } void VideoFrameCompositor::SetCurrentFrame_Locked( - scoped_refptr<VideoFrame> frame, + scoped_refptr<media::VideoFrame> frame, base::TimeTicks expected_display_time) { DCHECK(task_runner_->BelongsToCurrentThread()); TRACE_EVENT1("media", "VideoFrameCompositor::SetCurrentFrame", "frame", @@ -230,8 +230,9 @@ weak_ptr_factory_.GetWeakPtr(), false)); } -void VideoFrameCompositor::PaintSingleFrame(scoped_refptr<VideoFrame> frame, - bool repaint_duplicate_frame) { +void VideoFrameCompositor::PaintSingleFrame( + scoped_refptr<media::VideoFrame> frame, + bool repaint_duplicate_frame) { if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( FROM_HERE, base::BindOnce(&VideoFrameCompositor::PaintSingleFrame, @@ -317,7 +318,7 @@ auto frame_metadata = std::make_unique<blink::WebMediaPlayer::VideoFramePresentationMetadata>(); - scoped_refptr<VideoFrame> last_frame; + scoped_refptr<media::VideoFrame> last_frame; { // Manually acquire the lock instead of calling GetCurrentFrameOnAnyThread() // to also fetch the other frame dependent properties. @@ -347,9 +348,10 @@ return frame_metadata; } -bool VideoFrameCompositor::ProcessNewFrame(scoped_refptr<VideoFrame> frame, - base::TimeTicks presentation_time, - bool repaint_duplicate_frame) { +bool VideoFrameCompositor::ProcessNewFrame( + scoped_refptr<media::VideoFrame> frame, + base::TimeTicks presentation_time, + bool repaint_duplicate_frame) { DCHECK(task_runner_->BelongsToCurrentThread()); if (frame && GetCurrentFrame() && !repaint_duplicate_frame && @@ -380,7 +382,7 @@ return true; } -void VideoFrameCompositor::UpdateRotation(VideoRotation rotation) { +void VideoFrameCompositor::UpdateRotation(media::VideoRotation rotation) { DCHECK(task_runner_->BelongsToCurrentThread()); submitter_->SetRotation(rotation); }
diff --git a/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc b/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc index 15eb377..c8e300a2 100644 --- a/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc +++ b/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc
@@ -29,7 +29,7 @@ namespace media { -using RenderingMode = VideoRendererSink::RenderCallback::RenderingMode; +using RenderingMode = ::media::VideoRendererSink::RenderCallback::RenderingMode; class MockWebVideoFrameSubmitter : public blink::WebVideoFrameSubmitter { public: @@ -53,8 +53,9 @@ int did_receive_frame_count_ = 0; }; -class VideoFrameCompositorTest : public VideoRendererSink::RenderCallback, - public testing::Test { +class VideoFrameCompositorTest + : public media::VideoRendererSink::RenderCallback, + public testing::Test { public: VideoFrameCompositorTest() : client_(new StrictMock<MockWebVideoFrameSubmitter>()) {} @@ -84,14 +85,15 @@ compositor_->SetVideoFrameProviderClient(nullptr); } - scoped_refptr<VideoFrame> CreateOpaqueFrame() { + scoped_refptr<media::VideoFrame> CreateOpaqueFrame() { return CreateOpaqueFrame(8, 8); } - scoped_refptr<VideoFrame> CreateOpaqueFrame(int width, int height) { + scoped_refptr<media::VideoFrame> CreateOpaqueFrame(int width, int height) { gfx::Size size(width, height); - return VideoFrame::CreateFrame(PIXEL_FORMAT_I420, size, gfx::Rect(size), - size, base::TimeDelta()); + return media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_I420, size, + gfx::Rect(size), size, + base::TimeDelta()); } VideoFrameCompositor* compositor() { return compositor_.get(); } @@ -104,9 +106,9 @@ protected: // VideoRendererSink::RenderCallback implementation. MOCK_METHOD3(Render, - scoped_refptr<VideoFrame>(base::TimeTicks, - base::TimeTicks, - RenderingMode)); + scoped_refptr<media::VideoFrame>(base::TimeTicks, + base::TimeTicks, + RenderingMode)); MOCK_METHOD0(OnFrameDropped, void()); MOCK_METHOD0(OnNewFramePresented, void()); @@ -202,12 +204,13 @@ } TEST_F(VideoFrameCompositorTest, PaintSingleFrame) { - scoped_refptr<VideoFrame> expected = VideoFrame::CreateEOSFrame(); + scoped_refptr<media::VideoFrame> expected = + media::VideoFrame::CreateEOSFrame(); // Should notify compositor synchronously. EXPECT_EQ(0, submitter_->did_receive_frame_count()); compositor()->PaintSingleFrame(expected); - scoped_refptr<VideoFrame> actual = compositor()->GetCurrentFrame(); + scoped_refptr<media::VideoFrame> actual = compositor()->GetCurrentFrame(); EXPECT_EQ(expected, actual); EXPECT_EQ(1, submitter_->did_receive_frame_count()); } @@ -217,7 +220,7 @@ // and base::TimeTicks(). tick_clock_.Advance(base::TimeDelta::FromSeconds(1)); - scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame = CreateOpaqueFrame(); EXPECT_CALL(*this, Render(_, _, RenderingMode::kStartup)) .WillRepeatedly(Return(opaque_frame)); EXPECT_CALL(*this, OnNewFramePresented()); @@ -257,9 +260,12 @@ constexpr int kSize1 = 8; constexpr int kSize2 = 16; constexpr int kSize3 = 24; - scoped_refptr<VideoFrame> opaque_frame_1 = CreateOpaqueFrame(kSize1, kSize1); - scoped_refptr<VideoFrame> opaque_frame_2 = CreateOpaqueFrame(kSize2, kSize2); - scoped_refptr<VideoFrame> opaque_frame_3 = CreateOpaqueFrame(kSize3, kSize3); + scoped_refptr<media::VideoFrame> opaque_frame_1 = + CreateOpaqueFrame(kSize1, kSize1); + scoped_refptr<media::VideoFrame> opaque_frame_2 = + CreateOpaqueFrame(kSize2, kSize2); + scoped_refptr<media::VideoFrame> opaque_frame_3 = + CreateOpaqueFrame(kSize3, kSize3); EXPECT_CALL(*this, OnNewFramePresented()).Times(1); EXPECT_CALL(*submitter_, SetForceBeginFrames(_)).Times(AnyNumber()); @@ -290,7 +296,7 @@ } TEST_F(VideoFrameCompositorTest, VideoRendererSinkFrameDropped) { - scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame = CreateOpaqueFrame(); EXPECT_CALL(*this, Render(_, _, _)).WillRepeatedly(Return(opaque_frame)); StartVideoRendererSink(); @@ -324,7 +330,7 @@ } TEST_F(VideoFrameCompositorTest, StartFiresBackgroundRender) { - scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame = CreateOpaqueFrame(); EXPECT_CALL(*this, Render(_, _, RenderingMode::kStartup)) .WillRepeatedly(Return(opaque_frame)); StartVideoRendererSink(); @@ -332,7 +338,7 @@ } TEST_F(VideoFrameCompositorTest, BackgroundRenderTicks) { - scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame = CreateOpaqueFrame(); compositor_->set_background_rendering_for_testing(true); base::RunLoop run_loop; @@ -356,7 +362,7 @@ TEST_F(VideoFrameCompositorTest, UpdateCurrentFrameWorksWhenBackgroundRendered) { - scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame = CreateOpaqueFrame(); compositor_->set_background_rendering_for_testing(true); // Background render a frame that succeeds immediately. @@ -368,7 +374,7 @@ // UpdateCurrentFrame is expected to return true to account for the frame // rendered in the background. EXPECT_CALL(*this, Render(_, _, RenderingMode::kNormal)) - .WillOnce(Return(scoped_refptr<VideoFrame>(opaque_frame))); + .WillOnce(Return(scoped_refptr<media::VideoFrame>(opaque_frame))); EXPECT_TRUE( compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); RenderFrame(); @@ -376,7 +382,7 @@ // Second call to UpdateCurrentFrame will return false as no new frame has // been created since the last call. EXPECT_CALL(*this, Render(_, _, RenderingMode::kNormal)) - .WillOnce(Return(scoped_refptr<VideoFrame>(opaque_frame))); + .WillOnce(Return(scoped_refptr<media::VideoFrame>(opaque_frame))); EXPECT_FALSE( compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); @@ -384,8 +390,8 @@ } TEST_F(VideoFrameCompositorTest, UpdateCurrentFrameIfStale) { - scoped_refptr<VideoFrame> opaque_frame_1 = CreateOpaqueFrame(); - scoped_refptr<VideoFrame> opaque_frame_2 = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame_1 = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame_2 = CreateOpaqueFrame(); compositor_->set_background_rendering_for_testing(true); EXPECT_CALL(*submitter_, IsDrivingFrameUpdates) @@ -446,8 +452,8 @@ } TEST_F(VideoFrameCompositorTest, UpdateCurrentFrameIfStale_ClientBypass) { - scoped_refptr<VideoFrame> opaque_frame_1 = CreateOpaqueFrame(); - scoped_refptr<VideoFrame> opaque_frame_2 = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame_1 = CreateOpaqueFrame(); + scoped_refptr<media::VideoFrame> opaque_frame_2 = CreateOpaqueFrame(); compositor_->set_background_rendering_for_testing(true); EXPECT_CALL(*submitter_, IsDrivingFrameUpdates)
diff --git a/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc b/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc index e3f989a8..25f76e2 100644 --- a/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc +++ b/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc
@@ -99,7 +99,7 @@ class WatchTimeReporterTest : public testing::TestWithParam<WatchTimeReporterTestData> { public: - class WatchTimeInterceptor : public mojom::WatchTimeRecorder { + class WatchTimeInterceptor : public media::mojom::WatchTimeRecorder { public: WatchTimeInterceptor(WatchTimeReporterTest* parent) : parent_(parent) {} WatchTimeInterceptor(const WatchTimeInterceptor&) = delete; @@ -200,10 +200,12 @@ } } - void OnError(PipelineStatus status) override { parent_->OnError(status); } + void OnError(media::PipelineStatus status) override { + parent_->OnError(status); + } - void UpdateSecondaryProperties( - mojom::SecondaryPlaybackPropertiesPtr secondary_properties) override { + void UpdateSecondaryProperties(media::mojom::SecondaryPlaybackPropertiesPtr + secondary_properties) override { parent_->OnUpdateSecondaryProperties(std::move(secondary_properties)); } @@ -238,7 +240,7 @@ WatchTimeReporterTest* parent_; }; - class FakeMediaMetricsProvider : public mojom::MediaMetricsProvider { + class FakeMediaMetricsProvider : public media::mojom::MediaMetricsProvider { public: explicit FakeMediaMetricsProvider(WatchTimeReporterTest* parent) : parent_(parent) {} @@ -246,13 +248,14 @@ // mojom::WatchTimeRecorderProvider implementation: void AcquireWatchTimeRecorder( - mojom::PlaybackPropertiesPtr properties, - mojo::PendingReceiver<mojom::WatchTimeRecorder> receiver) override { + media::mojom::PlaybackPropertiesPtr properties, + mojo::PendingReceiver<media::mojom::WatchTimeRecorder> receiver) + override { mojo::MakeSelfOwnedReceiver( std::make_unique<WatchTimeInterceptor>(parent_), std::move(receiver)); } void AcquireVideoDecodeStatsRecorder( - mojo::PendingReceiver<mojom::VideoDecodeStatsRecorder> receiver) + mojo::PendingReceiver<media::mojom::VideoDecodeStatsRecorder> receiver) override { FAIL(); } @@ -261,27 +264,27 @@ mojo::PendingReceiver<media::learning::mojom::LearningTaskController> receiver) override {} void AcquirePlaybackEventsRecorder( - mojo::PendingReceiver<mojom::PlaybackEventsRecorder> receiver) + mojo::PendingReceiver<media::mojom::PlaybackEventsRecorder> receiver) override {} void Initialize(bool is_mse, - mojom::MediaURLScheme url_scheme, - mojom::MediaStreamType media_stream_type) override {} - void OnError(PipelineStatus status) override {} + media::mojom::MediaURLScheme url_scheme, + media::mojom::MediaStreamType media_stream_type) override {} + void OnError(media::PipelineStatus status) override {} void SetIsEME() override {} void SetTimeToMetadata(base::TimeDelta elapsed) override {} void SetTimeToFirstFrame(base::TimeDelta elapsed) override {} void SetTimeToPlayReady(base::TimeDelta elapsed) override {} void SetContainerName( - container_names::MediaContainerName container_name) override {} - void SetRendererType(RendererType renderer_type) override {} + media::container_names::MediaContainerName container_name) override {} + void SetRendererType(media::RendererType renderer_type) override {} void SetKeySystem(const std::string& key_system) override {} void SetIsHardwareSecure() override {} void SetHasPlayed() override {} void SetHaveEnough() override {} - void SetHasAudio(AudioCodec audio_codec) override {} - void SetHasVideo(VideoCodec video_codec) override {} - void SetVideoPipelineInfo(const VideoPipelineInfo& info) override {} - void SetAudioPipelineInfo(const AudioPipelineInfo& info) override {} + void SetHasAudio(media::AudioCodec audio_codec) override {} + void SetHasVideo(media::VideoCodec video_codec) override {} + void SetVideoPipelineInfo(const media::VideoPipelineInfo& info) override {} + void SetAudioPipelineInfo(const media::AudioPipelineInfo& info) override {} private: WatchTimeReporterTest* parent_; @@ -307,9 +310,9 @@ EXPECT_WATCH_TIME_FINALIZED(); wtr_ = std::make_unique<blink::WatchTimeReporter>( - mojom::PlaybackProperties::New(has_audio_, has_video_, false, false, - is_mse, is_encrypted, false, - mojom::MediaStreamType::kNone), + media::mojom::PlaybackProperties::New( + has_audio_, has_video_, false, false, is_mse, is_encrypted, false, + media::mojom::MediaStreamType::kNone), initial_video_size, base::BindRepeating(&WatchTimeReporterTest::GetCurrentMediaTime, base::Unretained(this)), @@ -322,7 +325,7 @@ // Most tests don't care about this. EXPECT_CALL(*this, GetPipelineStatistics()) - .WillRepeatedly(testing::Return(PipelineStatistics())); + .WillRepeatedly(testing::Return(media::PipelineStatistics())); EXPECT_CALL(*this, OnUpdateVideoDecodeStats(_, _)) .Times(testing::AnyNumber()); } @@ -616,7 +619,7 @@ } MOCK_METHOD0(GetCurrentMediaTime, base::TimeDelta()); - MOCK_METHOD0(GetPipelineStatistics, PipelineStatistics()); + MOCK_METHOD0(GetPipelineStatistics, media::PipelineStatistics()); MOCK_METHOD0(OnWatchTimeFinalized, void(void)); MOCK_METHOD0(OnPowerWatchTimeFinalized, void(void)); @@ -625,9 +628,9 @@ MOCK_METHOD2(OnWatchTimeUpdate, void(WatchTimeKey, base::TimeDelta)); MOCK_METHOD1(OnUnderflowUpdate, void(int)); MOCK_METHOD2(OnUnderflowDurationUpdate, void(int, base::TimeDelta)); - MOCK_METHOD1(OnError, void(PipelineStatus)); + MOCK_METHOD1(OnError, void(media::PipelineStatus)); MOCK_METHOD1(OnUpdateSecondaryProperties, - void(mojom::SecondaryPlaybackPropertiesPtr)); + void(media::mojom::SecondaryPlaybackPropertiesPtr)); MOCK_METHOD1(OnSetAutoplayInitiated, void(bool)); MOCK_METHOD1(OnDurationChanged, void(base::TimeDelta)); MOCK_METHOD2(OnUpdateVideoDecodeStats, void(uint32_t, uint32_t)); @@ -675,9 +678,9 @@ wtr_->OnPlaying(); EXPECT_TRUE(IsMonitoring()); - EXPECT_CALL(*this, OnError(PIPELINE_ERROR_DECODE)) + EXPECT_CALL(*this, OnError(media::PIPELINE_ERROR_DECODE)) .Times((has_audio_ && has_video_) ? 3 : 2); - wtr_->OnError(PIPELINE_ERROR_DECODE); + wtr_->OnError(media::PIPELINE_ERROR_DECODE); Initialize(true, true, gfx::Size()); wtr_->OnPlaying(); @@ -698,7 +701,7 @@ TEST_P(WatchTimeReporterTest, WatchTimeReporterInfiniteStartTime) { EXPECT_CALL(*this, GetCurrentMediaTime()) - .WillRepeatedly(testing::Return(kInfiniteDuration)); + .WillRepeatedly(testing::Return(media::kInfiniteDuration)); Initialize(false, false, kSizeJustRight); wtr_->OnPlaying(); EXPECT_FALSE(IsMonitoring()); @@ -713,12 +716,12 @@ .WillRepeatedly(testing::Return(kWatchTimeLate)); Initialize(true, true, kSizeJustRight); - PipelineStatistics stats; + media::PipelineStatistics stats; stats.video_frames_decoded = 10; stats.video_frames_dropped = 2; if (has_video_) { EXPECT_CALL(*this, GetPipelineStatistics()) - .WillOnce(testing::Return(PipelineStatistics())) + .WillOnce(testing::Return(media::PipelineStatistics())) .WillRepeatedly(testing::Return(stats)); EXPECT_CALL(*this, OnUpdateVideoDecodeStats(stats.video_frames_decoded, stats.video_frames_dropped)); @@ -763,11 +766,11 @@ .WillRepeatedly(testing::Return(kWatchTimeLate)); Initialize(true, true, kSizeJustRight); - PipelineStatistics initial_stats; + media::PipelineStatistics initial_stats; initial_stats.video_frames_decoded = 10; initial_stats.video_frames_dropped = 2; - PipelineStatistics stats; + media::PipelineStatistics stats; stats.video_frames_decoded = 17; stats.video_frames_dropped = 7; if (has_video_) { @@ -1093,15 +1096,20 @@ TEST_P(WatchTimeReporterTest, WatchTimeReporterSecondaryProperties) { Initialize(true, true, kSizeJustRight); - auto properties = mojom::SecondaryPlaybackProperties::New( - has_audio_ ? kCodecAAC : kUnknownAudioCodec, - has_video_ ? kCodecH264 : kUnknownVideoCodec, - has_audio_ ? AudioCodecProfile::kXHE_AAC : AudioCodecProfile::kUnknown, - has_video_ ? H264PROFILE_MAIN : VIDEO_CODEC_PROFILE_UNKNOWN, - has_audio_ ? AudioDecoderType::kMojo : AudioDecoderType::kUnknown, - has_video_ ? VideoDecoderType::kMojo : VideoDecoderType::kUnknown, - has_audio_ ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted, - has_video_ ? EncryptionScheme::kCbcs : EncryptionScheme::kUnencrypted, + auto properties = media::mojom::SecondaryPlaybackProperties::New( + has_audio_ ? media::kCodecAAC : media::kUnknownAudioCodec, + has_video_ ? media::kCodecH264 : media::kUnknownVideoCodec, + has_audio_ ? media::AudioCodecProfile::kXHE_AAC + : media::AudioCodecProfile::kUnknown, + has_video_ ? media::H264PROFILE_MAIN : media::VIDEO_CODEC_PROFILE_UNKNOWN, + has_audio_ ? media::AudioDecoderType::kMojo + : media::AudioDecoderType::kUnknown, + has_video_ ? media::VideoDecoderType::kMojo + : media::VideoDecoderType::kUnknown, + has_audio_ ? media::EncryptionScheme::kCenc + : media::EncryptionScheme::kUnencrypted, + has_video_ ? media::EncryptionScheme::kCbcs + : media::EncryptionScheme::kUnencrypted, has_video_ ? gfx::Size(800, 600) : gfx::Size()); // Get a pointer to our original properties since we're not allowed to use @@ -1133,11 +1141,14 @@ EXPECT_CALL(*this, OnUpdateSecondaryProperties(_)) .Times((has_audio_ && has_video_) ? 3 : 2); - wtr_->UpdateSecondaryProperties(mojom::SecondaryPlaybackProperties::New( - kUnknownAudioCodec, kUnknownVideoCodec, AudioCodecProfile::kUnknown, - VIDEO_CODEC_PROFILE_UNKNOWN, AudioDecoderType::kUnknown, - VideoDecoderType::kUnknown, EncryptionScheme::kUnencrypted, - EncryptionScheme::kUnencrypted, kSizeJustRight)); + wtr_->UpdateSecondaryProperties( + media::mojom::SecondaryPlaybackProperties::New( + media::kUnknownAudioCodec, media::kUnknownVideoCodec, + media::AudioCodecProfile::kUnknown, + media::VIDEO_CODEC_PROFILE_UNKNOWN, media::AudioDecoderType::kUnknown, + media::VideoDecoderType::kUnknown, + media::EncryptionScheme::kUnencrypted, + media::EncryptionScheme::kUnencrypted, kSizeJustRight)); EXPECT_TRUE(IsMonitoring()); EXPECT_WATCH_TIME_FINALIZED(); @@ -1156,11 +1167,14 @@ EXPECT_CALL(*this, OnUpdateSecondaryProperties(_)) .Times((has_audio_ && has_video_) ? 3 : 2); - wtr_->UpdateSecondaryProperties(mojom::SecondaryPlaybackProperties::New( - kUnknownAudioCodec, kUnknownVideoCodec, AudioCodecProfile::kUnknown, - VIDEO_CODEC_PROFILE_UNKNOWN, AudioDecoderType::kUnknown, - VideoDecoderType::kUnknown, EncryptionScheme::kUnencrypted, - EncryptionScheme::kUnencrypted, kSizeTooSmall)); + wtr_->UpdateSecondaryProperties( + media::mojom::SecondaryPlaybackProperties::New( + media::kUnknownAudioCodec, media::kUnknownVideoCodec, + media::AudioCodecProfile::kUnknown, + media::VIDEO_CODEC_PROFILE_UNKNOWN, media::AudioDecoderType::kUnknown, + media::VideoDecoderType::kUnknown, + media::EncryptionScheme::kUnencrypted, + media::EncryptionScheme::kUnencrypted, kSizeTooSmall)); EXPECT_WATCH_TIME_FINALIZED(); CycleReportingTimer(); @@ -1198,9 +1212,9 @@ // One call for the background, one for the foreground, and one for the muted // reporter if we have audio+video. - EXPECT_CALL(*this, OnError(PIPELINE_ERROR_DECODE)) + EXPECT_CALL(*this, OnError(media::PIPELINE_ERROR_DECODE)) .Times((has_audio_ && has_video_) ? 3 : 2); - wtr_->OnError(PIPELINE_ERROR_DECODE); + wtr_->OnError(media::PIPELINE_ERROR_DECODE); const base::TimeDelta kExpectedForegroundWatchTime = kWatchTimeEarly; EXPECT_WATCH_TIME(Ac, kExpectedForegroundWatchTime);
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc index 7a39ddde..2ee33474 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc
@@ -19,7 +19,7 @@ const base::WeakPtr<WebEncryptedMediaClientImpl>& client, const blink::WebString& key_system, const blink::WebSecurityOrigin& security_origin, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, std::unique_ptr<blink::WebContentDecryptionModuleResult> result) { // If |client| is gone (due to the frame getting destroyed), it is // impossible to create the CDM, so fail. @@ -45,7 +45,7 @@ const blink::WebString& key_system, const blink::WebSecurityOrigin& security_origin, const blink::WebMediaKeySystemConfiguration& configuration, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client) { return std::make_unique<WebContentDecryptionModuleAccessImpl>( key_system, security_origin, configuration, cdm_config, client); @@ -55,14 +55,13 @@ const blink::WebString& key_system, const blink::WebSecurityOrigin& security_origin, const blink::WebMediaKeySystemConfiguration& configuration, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client) : key_system_(key_system), security_origin_(security_origin), configuration_(configuration), cdm_config_(cdm_config), - client_(client) { -} + client_(client) {} WebContentDecryptionModuleAccessImpl::~WebContentDecryptionModuleAccessImpl() = default;
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h index b122d36..a771629a 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h
@@ -31,13 +31,13 @@ const blink::WebString& key_system, const blink::WebSecurityOrigin& security_origin, const blink::WebMediaKeySystemConfiguration& configuration, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client); WebContentDecryptionModuleAccessImpl( const blink::WebString& key_system, const blink::WebSecurityOrigin& security_origin, const blink::WebMediaKeySystemConfiguration& configuration, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client); WebContentDecryptionModuleAccessImpl( const WebContentDecryptionModuleAccessImpl&) = delete; @@ -57,7 +57,7 @@ const blink::WebString key_system_; const blink::WebSecurityOrigin security_origin_; const blink::WebMediaKeySystemConfiguration configuration_; - const CdmConfig cdm_config_; + const media::CdmConfig cdm_config_; // Keep a WeakPtr as client is owned by render_frame_impl. base::WeakPtr<WebEncryptedMediaClientImpl> client_;
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc index 9f80ad18b..c89814d 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc
@@ -73,7 +73,7 @@ media::CdmFactory* cdm_factory, const std::u16string& key_system, const blink::WebSecurityOrigin& security_origin, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, WebCdmCreatedCB web_cdm_created_cb) { DCHECK(!security_origin.IsNull()); DCHECK(!key_system.empty()); @@ -154,12 +154,12 @@ adapter_->GetStatusForPolicy( min_hdcp_version, - std::make_unique<CdmResultPromise<CdmKeyInformation::KeyStatus>>( + std::make_unique<CdmResultPromise<media::CdmKeyInformation::KeyStatus>>( result, adapter_->GetKeySystemUMAPrefix(), kGetStatusForPolicyUMAName)); } -std::unique_ptr<CdmContextRef> +std::unique_ptr<media::CdmContextRef> WebContentDecryptionModuleImpl::GetCdmContextRef() { return adapter_->GetCdmContextRef(); } @@ -168,7 +168,7 @@ return adapter_->GetKeySystem(); } -CdmConfig WebContentDecryptionModuleImpl::GetCdmConfig() const { +media::CdmConfig WebContentDecryptionModuleImpl::GetCdmConfig() const { return adapter_->GetCdmConfig(); }
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h index 0582d5ad..05979ca 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h
@@ -35,10 +35,10 @@ class PLATFORM_EXPORT WebContentDecryptionModuleImpl : public blink::WebContentDecryptionModule { public: - static void Create(CdmFactory* cdm_factory, + static void Create(media::CdmFactory* cdm_factory, const std::u16string& key_system, const blink::WebSecurityOrigin& security_origin, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, WebCdmCreatedCB web_cdm_created_cb); WebContentDecryptionModuleImpl(const WebContentDecryptionModuleImpl&) = @@ -58,11 +58,11 @@ const blink::WebString& min_hdcp_version_string, blink::WebContentDecryptionModuleResult result) override; - std::unique_ptr<CdmContextRef> GetCdmContextRef(); + std::unique_ptr<media::CdmContextRef> GetCdmContextRef(); std::string GetKeySystem() const; - CdmConfig GetCdmConfig() const; + media::CdmConfig GetCdmConfig() const; private: friend CdmSessionAdapter;
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc index fc742c9..5a5bf44 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc
@@ -64,7 +64,7 @@ std::vector<uint8_t>* sanitized_init_data, std::string* error_message) { DCHECK_GT(init_data_length, 0u); - if (init_data_length > limits::kMaxInitDataLength) { + if (init_data_length > media::limits::kMaxInitDataLength) { error_message->assign("Initialization data too long."); return false; } @@ -72,7 +72,7 @@ switch (init_data_type) { case EmeInitDataType::WEBM: // |init_data| for WebM is a single key. - if (init_data_length > limits::kMaxKeyIdLength) { + if (init_data_length > media::limits::kMaxKeyIdLength) { error_message->assign("Initialization data for WebM is too long."); return false; } @@ -81,7 +81,7 @@ case EmeInitDataType::CENC: sanitized_init_data->assign(init_data, init_data + init_data_length); - if (!ValidatePsshInput(*sanitized_init_data)) { + if (!media::ValidatePsshInput(*sanitized_init_data)) { error_message->assign("Initialization data for CENC is incorrect."); return false; } @@ -91,20 +91,20 @@ // Extract the keys and then rebuild the message. This ensures that any // extra data in the provided JSON is dropped. std::string init_data_string(init_data, init_data + init_data_length); - KeyIdList key_ids; - if (!ExtractKeyIdsFromKeyIdsInitData(init_data_string, &key_ids, - error_message)) + media::KeyIdList key_ids; + if (!media::ExtractKeyIdsFromKeyIdsInitData(init_data_string, &key_ids, + error_message)) return false; for (const auto& key_id : key_ids) { - if (key_id.size() < limits::kMinKeyIdLength || - key_id.size() > limits::kMaxKeyIdLength) { + if (key_id.size() < media::limits::kMinKeyIdLength || + key_id.size() > media::limits::kMaxKeyIdLength) { error_message->assign("Incorrect key size."); return false; } } - CreateKeyIdsInitData(key_ids, sanitized_init_data); + media::CreateKeyIdsInitData(key_ids, sanitized_init_data); return true; } @@ -126,7 +126,7 @@ return false; sanitized_session_id->assign(session_id.Ascii()); - if (sanitized_session_id->length() > limits::kMaxSessionIdLength) + if (sanitized_session_id->length() > media::limits::kMaxSessionIdLength) return false; // Check that |sanitized_session_id| only contains printable characters for @@ -151,13 +151,13 @@ // and/or generating a fully sanitized version. The user agent should check // that the length and values of fields are reasonable. Unknown fields should // be rejected or removed. - if (response_length > limits::kMaxSessionResponseLength) + if (response_length > media::limits::kMaxSessionResponseLength) return false; - if (IsClearKey(key_system) || IsExternalClearKey(key_system)) { + if (media::IsClearKey(key_system) || media::IsExternalClearKey(key_system)) { std::string key_string(response, response + response_length); - KeyIdAndKeyPairs keys; - CdmSessionType session_type = CdmSessionType::kTemporary; + media::KeyIdAndKeyPairs keys; + auto session_type = CdmSessionType::kTemporary; if (!ExtractKeysFromJWKSet(key_string, &keys, &session_type)) return false; @@ -166,8 +166,8 @@ return false; for (const auto& key_pair : keys) { - if (key_pair.first.size() < limits::kMinKeyIdLength || - key_pair.first.size() > limits::kMaxKeyIdLength) { + if (key_pair.first.size() < media::limits::kMinKeyIdLength || + key_pair.first.size() > media::limits::kMaxKeyIdLength) { return false; } } @@ -212,7 +212,7 @@ // session will be gone. if (!is_closed_ && !has_close_been_called_) { adapter_->CloseSession(session_id_, - std::make_unique<DoNothingCdmPromise<>>()); + std::make_unique<media::DoNothingCdmPromise<>>()); } } } @@ -295,12 +295,14 @@ // 10.9 Use the cdm to execute the following steps: adapter_->InitializeNewSession( eme_init_data_type, sanitized_init_data, session_type_, - std::unique_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise( - result, adapter_->GetKeySystemUMAPrefix(), kGenerateRequestUMAName, - base::BindOnce( - &WebContentDecryptionModuleSessionImpl::OnSessionInitialized, - weak_ptr_factory_.GetWeakPtr()), - {SessionInitStatus::NEW_SESSION}))); + std::unique_ptr<media::NewSessionCdmPromise>( + new NewSessionCdmResultPromise( + result, adapter_->GetKeySystemUMAPrefix(), + kGenerateRequestUMAName, + base::BindOnce( + &WebContentDecryptionModuleSessionImpl::OnSessionInitialized, + weak_ptr_factory_.GetWeakPtr()), + {SessionInitStatus::NEW_SESSION}))); } void WebContentDecryptionModuleSessionImpl::Load( @@ -328,13 +330,14 @@ adapter_->LoadSession( session_type_, sanitized_session_id, - std::unique_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise( - result, adapter_->GetKeySystemUMAPrefix(), kLoadSessionUMAName, - base::BindOnce( - &WebContentDecryptionModuleSessionImpl::OnSessionInitialized, - weak_ptr_factory_.GetWeakPtr()), - {SessionInitStatus::NEW_SESSION, - SessionInitStatus::SESSION_NOT_FOUND}))); + std::unique_ptr<media::NewSessionCdmPromise>( + new NewSessionCdmResultPromise( + result, adapter_->GetKeySystemUMAPrefix(), kLoadSessionUMAName, + base::BindOnce( + &WebContentDecryptionModuleSessionImpl::OnSessionInitialized, + weak_ptr_factory_.GetWeakPtr()), + {SessionInitStatus::NEW_SESSION, + SessionInitStatus::SESSION_NOT_FOUND}))); } void WebContentDecryptionModuleSessionImpl::Update( @@ -413,7 +416,7 @@ void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange( bool has_additional_usable_key, - CdmKeysInfo keys_info) { + media::CdmKeysInfo keys_info) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); blink::WebVector<blink::WebEncryptedMediaKeyInformation> keys( keys_info.size()); @@ -444,7 +447,7 @@ } void WebContentDecryptionModuleSessionImpl::OnSessionClosed( - CdmSessionClosedReason reason) { + media::CdmSessionClosedReason reason) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Only send one closed event to blink.
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h index 41546ee..4974aa9 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h
@@ -42,7 +42,7 @@ blink::WebString SessionId() const override; void InitializeNewSession( - EmeInitDataType init_data_type, + media::EmeInitDataType init_data_type, const unsigned char* initData, size_t initDataLength, blink::WebContentDecryptionModuleResult result) override; @@ -55,12 +55,12 @@ void Remove(blink::WebContentDecryptionModuleResult result) override; // Callbacks. - void OnSessionMessage(CdmMessageType message_type, + void OnSessionMessage(media::CdmMessageType message_type, const std::vector<uint8_t>& message); void OnSessionKeysChange(bool has_additional_usable_key, - CdmKeysInfo keys_info); + media::CdmKeysInfo keys_info); void OnSessionExpirationUpdate(base::Time new_expiry_time); - void OnSessionClosed(CdmSessionClosedReason reason); + void OnSessionClosed(media::CdmSessionClosedReason reason); private: // Called when a new session is created or loaded. |status| is set as @@ -72,7 +72,7 @@ // Keep track of the session type to be passed into InitializeNewSession() and // LoadSession(). - const CdmSessionType session_type_; + const media::CdmSessionType session_type_; // Non-owned pointer. Client* client_;
diff --git a/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc b/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc index f50258a9..50d48e7 100644 --- a/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc +++ b/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc
@@ -96,12 +96,12 @@ }; WebEncryptedMediaClientImpl::WebEncryptedMediaClientImpl( - CdmFactory* cdm_factory, - MediaPermission* media_permission, + media::CdmFactory* cdm_factory, + media::MediaPermission* media_permission, std::unique_ptr<KeySystemConfigSelector::WebLocalFrameDelegate> web_frame_delegate) : cdm_factory_(cdm_factory), - key_system_config_selector_(KeySystems::GetInstance(), + key_system_config_selector_(media::KeySystems::GetInstance(), media_permission, std::move(web_frame_delegate)) { DCHECK(cdm_factory_); @@ -122,7 +122,7 @@ void WebEncryptedMediaClientImpl::CreateCdm( const blink::WebString& key_system, const blink::WebSecurityOrigin& security_origin, - const CdmConfig& cdm_config, + const media::CdmConfig& cdm_config, std::unique_ptr<blink::WebContentDecryptionModuleResult> result) { WebContentDecryptionModuleImpl::Create( cdm_factory_, key_system.Utf16(), security_origin, cdm_config, @@ -134,7 +134,7 @@ blink::WebEncryptedMediaRequest request, KeySystemConfigSelector::Status status, blink::WebMediaKeySystemConfiguration* accumulated_configuration, - CdmConfig* cdm_config) { + media::CdmConfig* cdm_config) { // Update encrypted_media_supported_types_browsertest.cc if updating these // strings. // TODO(xhwang): Consider using different messages for kUnsupportedKeySystem @@ -180,7 +180,7 @@ key_system_ascii = key_system.Ascii(); // Return a per-frame singleton so that UMA reports will be once-per-frame. - std::string uma_name = GetKeySystemNameForUMA(key_system_ascii); + std::string uma_name = media::GetKeySystemNameForUMA(key_system_ascii); std::unique_ptr<Reporter>& reporter = reporters_[uma_name]; if (!reporter) reporter = std::make_unique<Reporter>(uma_name);
diff --git a/third_party/blink/renderer/platform/media/web_media_player_params.cc b/third_party/blink/renderer/platform/media/web_media_player_params.cc index 31e9fb8..84c75dd 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_params.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_params.cc
@@ -12,9 +12,10 @@ namespace media { WebMediaPlayerParams::WebMediaPlayerParams( - std::unique_ptr<MediaLog> media_log, + std::unique_ptr<media::MediaLog> media_log, const DeferLoadCB& defer_load_cb, - const scoped_refptr<SwitchableAudioRendererSink>& audio_renderer_sink, + const scoped_refptr<media::SwitchableAudioRendererSink>& + audio_renderer_sink, const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, const scoped_refptr<base::TaskRunner>& worker_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, @@ -22,18 +23,18 @@ video_frame_compositor_task_runner, const AdjustAllocatedMemoryCB& adjust_allocated_memory_cb, blink::WebContentDecryptionModule* initial_cdm, - RequestRoutingTokenCallback request_routing_token_cb, - base::WeakPtr<MediaObserver> media_observer, + media::RequestRoutingTokenCallback request_routing_token_cb, + base::WeakPtr<media::MediaObserver> media_observer, bool enable_instant_source_buffer_gc, bool embedded_media_experience_enabled, - mojo::PendingRemote<mojom::MediaMetricsProvider> metrics_provider, + mojo::PendingRemote<media::mojom::MediaMetricsProvider> metrics_provider, CreateSurfaceLayerBridgeCB create_bridge_callback, scoped_refptr<viz::RasterContextProvider> raster_context_provider, blink::WebMediaPlayer::SurfaceLayerMode use_surface_layer_for_video, bool is_background_suspend_enabled, bool is_background_video_playback_enabled, bool is_background_video_track_optimization_supported, - std::unique_ptr<Demuxer> demuxer_override, + std::unique_ptr<media::Demuxer> demuxer_override, std::unique_ptr<PowerStatusHelper> power_status_helper) : defer_load_cb_(defer_load_cb), audio_renderer_sink_(audio_renderer_sink), @@ -62,7 +63,7 @@ WebMediaPlayerParams::~WebMediaPlayerParams() = default; -std::unique_ptr<Demuxer> WebMediaPlayerParams::TakeDemuxerOverride() { +std::unique_ptr<media::Demuxer> WebMediaPlayerParams::TakeDemuxerOverride() { return std::move(demuxer_override_); }
diff --git a/third_party/blink/renderer/platform/media/web_media_source_impl.cc b/third_party/blink/renderer/platform/media/web_media_source_impl.cc index ab4fa0b..1cfc182 100644 --- a/third_party/blink/renderer/platform/media/web_media_source_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_source_impl.cc
@@ -17,16 +17,16 @@ namespace media { -#define STATIC_ASSERT_MATCHING_STATUS_ENUM(webkit_name, chromium_name) \ - static_assert(static_cast<int>(WebMediaSource::webkit_name) == \ - static_cast<int>(ChunkDemuxer::chromium_name), \ +#define STATIC_ASSERT_MATCHING_STATUS_ENUM(webkit_name, chromium_name) \ + static_assert(static_cast<int>(WebMediaSource::webkit_name) == \ + static_cast<int>(media::ChunkDemuxer::chromium_name), \ "mismatching status enum values: " #webkit_name) STATIC_ASSERT_MATCHING_STATUS_ENUM(kAddStatusOk, kOk); STATIC_ASSERT_MATCHING_STATUS_ENUM(kAddStatusNotSupported, kNotSupported); STATIC_ASSERT_MATCHING_STATUS_ENUM(kAddStatusReachedIdLimit, kReachedIdLimit); #undef STATIC_ASSERT_MATCHING_STATUS_ENUM -WebMediaSourceImpl::WebMediaSourceImpl(ChunkDemuxer* demuxer) +WebMediaSourceImpl::WebMediaSourceImpl(media::ChunkDemuxer* demuxer) : demuxer_(demuxer) { DCHECK(demuxer_); } @@ -49,7 +49,7 @@ } std::unique_ptr<blink::WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( - std::unique_ptr<AudioDecoderConfig> audio_config, + std::unique_ptr<media::AudioDecoderConfig> audio_config, WebMediaSource::AddStatus& out_status /* out */) { std::string id = base::GenerateGUID(); @@ -63,7 +63,7 @@ } std::unique_ptr<blink::WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( - std::unique_ptr<VideoDecoderConfig> video_config, + std::unique_ptr<media::VideoDecoderConfig> video_config, WebMediaSource::AddStatus& out_status /* out */) { std::string id = base::GenerateGUID(); @@ -87,16 +87,16 @@ void WebMediaSourceImpl::MarkEndOfStream( WebMediaSource::EndOfStreamStatus status) { - PipelineStatus pipeline_status = PIPELINE_OK; + media::PipelineStatus pipeline_status = media::PIPELINE_OK; switch (status) { case WebMediaSource::kEndOfStreamStatusNoError: break; case WebMediaSource::kEndOfStreamStatusNetworkError: - pipeline_status = CHUNK_DEMUXER_ERROR_EOS_STATUS_NETWORK_ERROR; + pipeline_status = media::CHUNK_DEMUXER_ERROR_EOS_STATUS_NETWORK_ERROR; break; case WebMediaSource::kEndOfStreamStatusDecodeError: - pipeline_status = CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR; + pipeline_status = media::CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR; break; }
diff --git a/third_party/blink/renderer/platform/media/web_media_source_impl.h b/third_party/blink/renderer/platform/media/web_media_source_impl.h index b53ccba..83b8851b 100644 --- a/third_party/blink/renderer/platform/media/web_media_source_impl.h +++ b/third_party/blink/renderer/platform/media/web_media_source_impl.h
@@ -17,7 +17,7 @@ class PLATFORM_EXPORT WebMediaSourceImpl : public blink::WebMediaSource { public: - WebMediaSourceImpl(ChunkDemuxer* demuxer); + WebMediaSourceImpl(media::ChunkDemuxer* demuxer); WebMediaSourceImpl(const WebMediaSourceImpl&) = delete; WebMediaSourceImpl& operator=(const WebMediaSourceImpl&) = delete; ~WebMediaSourceImpl() override; @@ -28,10 +28,10 @@ const blink::WebString& codecs, AddStatus& out_status /* out */) override; std::unique_ptr<blink::WebSourceBuffer> AddSourceBuffer( - std::unique_ptr<AudioDecoderConfig> audio_config, + std::unique_ptr<media::AudioDecoderConfig> audio_config, AddStatus& out_status /* out */) override; std::unique_ptr<blink::WebSourceBuffer> AddSourceBuffer( - std::unique_ptr<VideoDecoderConfig> video_config, + std::unique_ptr<media::VideoDecoderConfig> video_config, AddStatus& out_status /* out */) override; double Duration() override; void SetDuration(double duration) override; @@ -39,7 +39,7 @@ void UnmarkEndOfStream() override; private: - ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl. + media::ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl. }; } // namespace media
diff --git a/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc b/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc index 97546f4..71b35f7b 100644 --- a/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc +++ b/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc
@@ -23,9 +23,9 @@ namespace media { static blink::WebSourceBufferClient::ParseWarning ParseWarningToBlink( - const SourceBufferParseWarning warning) { + const media::SourceBufferParseWarning warning) { #define CHROMIUM_PARSE_WARNING_TO_BLINK_ENUM_CASE(name) \ - case SourceBufferParseWarning::name: \ + case media::SourceBufferParseWarning::name: \ return blink::WebSourceBufferClient::ParseWarning::name switch (warning) { @@ -48,7 +48,7 @@ DCHECK_NE(time, -std::numeric_limits<double>::infinity()); if (time == std::numeric_limits<double>::infinity()) - return kInfiniteDuration; + return media::kInfiniteDuration; constexpr double max_time_in_seconds = base::TimeDelta::FiniteMax().InSecondsF(); @@ -61,11 +61,11 @@ } WebSourceBufferImpl::WebSourceBufferImpl(const std::string& id, - ChunkDemuxer* demuxer) + media::ChunkDemuxer* demuxer) : id_(id), demuxer_(demuxer), client_(nullptr), - append_window_end_(kInfiniteDuration) { + append_window_end_(media::kInfiniteDuration) { DCHECK(demuxer_); demuxer_->SetTracksWatcher( id, base::BindRepeating(&WebSourceBufferImpl::InitSegmentReceived, @@ -105,7 +105,7 @@ } blink::WebTimeRanges WebSourceBufferImpl::Buffered() { - Ranges<base::TimeDelta> ranges = demuxer_->GetBufferedRanges(id_); + media::Ranges<base::TimeDelta> ranges = demuxer_->GetBufferedRanges(id_); blink::WebTimeRanges result(ranges.size()); for (size_t i = 0; i < ranges.size(); i++) { result[i].start = ranges.start(i).InSecondsF(); @@ -219,13 +219,14 @@ client_ = nullptr; } -blink::WebMediaPlayer::TrackType mediaTrackTypeToBlink(MediaTrack::Type type) { +blink::WebMediaPlayer::TrackType mediaTrackTypeToBlink( + media::MediaTrack::Type type) { switch (type) { - case MediaTrack::Audio: + case media::MediaTrack::Audio: return blink::WebMediaPlayer::kAudioTrack; - case MediaTrack::Text: + case media::MediaTrack::Text: return blink::WebMediaPlayer::kTextTrack; - case MediaTrack::Video: + case media::MediaTrack::Video: return blink::WebMediaPlayer::kVideoTrack; } NOTREACHED(); @@ -233,7 +234,7 @@ } void WebSourceBufferImpl::InitSegmentReceived( - std::unique_ptr<MediaTracks> tracks) { + std::unique_ptr<media::MediaTracks> tracks) { DCHECK(tracks.get()); DVLOG(1) << __func__ << " tracks=" << tracks->tracks().size(); @@ -254,7 +255,7 @@ } void WebSourceBufferImpl::NotifyParseWarning( - const SourceBufferParseWarning warning) { + const media::SourceBufferParseWarning warning) { client_->NotifyParseWarning(ParseWarningToBlink(warning)); }
diff --git a/third_party/blink/renderer/platform/media/web_source_buffer_impl.h b/third_party/blink/renderer/platform/media/web_source_buffer_impl.h index 402069fb..62c9191 100644 --- a/third_party/blink/renderer/platform/media/web_source_buffer_impl.h +++ b/third_party/blink/renderer/platform/media/web_source_buffer_impl.h
@@ -22,7 +22,7 @@ class PLATFORM_EXPORT WebSourceBufferImpl : public blink::WebSourceBuffer { public: - WebSourceBufferImpl(const std::string& id, ChunkDemuxer* demuxer); + WebSourceBufferImpl(const std::string& id, media::ChunkDemuxer* demuxer); WebSourceBufferImpl(const WebSourceBufferImpl&) = delete; WebSourceBufferImpl& operator=(const WebSourceBufferImpl&) = delete; ~WebSourceBufferImpl() override; @@ -55,13 +55,13 @@ private: // Demuxer callback handler to process an initialization segment received // during an append() call. - void InitSegmentReceived(std::unique_ptr<MediaTracks> tracks); + void InitSegmentReceived(std::unique_ptr<media::MediaTracks> tracks); // Demuxer callback handler to notify Blink of a non-fatal parse warning. - void NotifyParseWarning(const SourceBufferParseWarning warning); + void NotifyParseWarning(const media::SourceBufferParseWarning warning); std::string id_; - ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl. + media::ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl. blink::WebSourceBufferClient* client_;
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc index 453509e2..4c69a15f 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
@@ -11,7 +11,6 @@ #include "base/check_op.h" #include "base/containers/cxx20_erase.h" #include "base/single_thread_task_runner.h" -#include "base/stl_util.h" #include "base/time/time.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 3216ff05..e9e6fc75 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -139,8 +139,10 @@ status: "experimental", }, { + name: "AccessibilityPageZoom", + }, + { name: "AccessibilityUseAXPositionForDocumentMarkers", - status: "test", }, { name: "AddEventListenerAbortSignal", @@ -596,6 +598,12 @@ status: "experimental", }, { + // CSS animation/transition updates occur outside style recalc. + // + // https://crbug.com/1180159 + name: "CSSIsolatedAnimationUpdates", + }, + { name: "CSSLayoutAPI", status: "experimental", }, @@ -2523,7 +2531,7 @@ // exposes requisite information about displays connected to the device. { name: "WindowPlacement", - origin_trial_feature_name: "WindowPlacement", + origin_trial_feature_name: "WindowPlacementOT2", status: "experimental", }, {
diff --git a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc index cefbb77..bcefbdf 100644 --- a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc +++ b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -131,7 +131,6 @@ void DisableVirtualTimeForTesting() override {} bool VirtualTimeAllowedToAdvance() const override { return true; } void SetInitialVirtualTime(base::Time) override {} - void SetInitialVirtualTimeOffset(base::TimeDelta) override {} void SetVirtualTimePolicy(VirtualTimePolicy) override {} void GrantVirtualTimeBudget(base::TimeDelta, base::OnceClosure) override {} void SetMaxVirtualTimeTaskStarvationCount(int) override {}
diff --git a/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc b/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc index cdb59de..66ca4119 100644 --- a/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
@@ -100,7 +100,7 @@ if (long_idle_period_duration >= base::TimeDelta::FromMilliseconds(kMinimumIdlePeriodDurationMillis)) { *next_long_idle_period_delay_out = long_idle_period_duration; - if (!idle_queue_->HasTaskToRunImmediately()) + if (!idle_queue_->HasTaskToRunImmediatelyOrReadyDelayedTask()) return IdlePeriodState::kInLongIdlePeriodPaused; if (long_idle_period_duration == max_long_idle_period_duration) return IdlePeriodState::kInLongIdlePeriodWithMaxDeadline; @@ -248,7 +248,7 @@ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "UpdateLongIdlePeriodStateAfterIdleTask"); - if (!idle_queue_->HasTaskToRunImmediately()) { + if (!idle_queue_->HasTaskToRunImmediatelyOrReadyDelayedTask()) { // If there are no more idle tasks then pause long idle period ticks until a // new idle task is posted. state_.UpdateState(IdlePeriodState::kInLongIdlePeriodPaused,
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc index 60456fc..e5d1883 100644 --- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc +++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc
@@ -29,7 +29,7 @@ absl::optional<base::TimeTicks> NextTaskRunTime(LazyNow* lazy_now, TaskQueue* queue) { - if (queue->HasTaskToRunImmediately()) + if (queue->HasTaskToRunImmediatelyOrReadyDelayedTask()) return lazy_now->Now(); return queue->GetNextScheduledWakeUp(); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index 9f42ffa..2e42d1b 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -1441,7 +1441,8 @@ if (pair.first->GetPrioritisationType() == MainThreadTaskQueue::QueueTraits::PrioritisationType:: kCompositor && - pair.first->GetTaskQueue()->HasTaskToRunImmediately()) + pair.first->GetTaskQueue() + ->HasTaskToRunImmediatelyOrReadyDelayedTask()) return true; } return main_thread_only().blocking_input_expected_soon; @@ -1852,11 +1853,8 @@ if (main_thread_only().initial_virtual_time_ticks.is_null()) main_thread_only().initial_virtual_time_ticks = tick_clock()->NowTicks(); virtual_time_domain_ = std::make_unique<AutoAdvancingVirtualTimeDomain>( - main_thread_only().initial_virtual_time + - main_thread_only().initial_virtual_time_offset, - main_thread_only().initial_virtual_time_ticks + - main_thread_only().initial_virtual_time_offset, - &helper_, policy); + main_thread_only().initial_virtual_time, + main_thread_only().initial_virtual_time_ticks, &helper_, policy); RegisterTimeDomain(virtual_time_domain_.get()); DCHECK(!virtual_time_control_task_queue_); @@ -1982,11 +1980,6 @@ main_thread_only().initial_virtual_time = time; } -void MainThreadSchedulerImpl::SetInitialVirtualTimeOffset( - base::TimeDelta offset) { - main_thread_only().initial_virtual_time_offset = offset; -} - void MainThreadSchedulerImpl::ApplyVirtualTimePolicy() { switch (main_thread_only().virtual_time_policy) { case VirtualTimePolicy::kAdvance:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h index cd0acea3..1f2cd6d 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -314,7 +314,6 @@ bool VirtualTimeAllowedToAdvance() const; void SetVirtualTimePolicy(VirtualTimePolicy virtual_time_policy); void SetInitialVirtualTime(base::Time time); - void SetInitialVirtualTimeOffset(base::TimeDelta offset); void SetMaxVirtualTimeTaskStarvationCount(int max_task_starvation_count); base::TimeTicks IncrementVirtualTimePauseCount(); void DecrementVirtualTimePauseCount(); @@ -908,9 +907,6 @@ base::Time initial_virtual_time; base::TimeTicks initial_virtual_time_ticks; - // This is used for cross origin navigations to account for virtual time - // advancing in the previous renderer. - base::TimeDelta initial_virtual_time_offset; VirtualTimePolicy virtual_time_policy; // In VirtualTimePolicy::kDeterministicLoading virtual time is only allowed
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc index c4417cd6..4068d09 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -473,10 +473,6 @@ main_thread_scheduler_->SetInitialVirtualTime(time); } -void PageSchedulerImpl::SetInitialVirtualTimeOffset(base::TimeDelta offset) { - main_thread_scheduler_->SetInitialVirtualTimeOffset(offset); -} - bool PageSchedulerImpl::VirtualTimeAllowedToAdvance() const { return main_thread_scheduler_->VirtualTimeAllowedToAdvance(); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h index 50fe5f0..5d38ce41 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -88,7 +88,6 @@ bool VirtualTimeAllowedToAdvance() const override; void SetVirtualTimePolicy(VirtualTimePolicy) override; void SetInitialVirtualTime(base::Time time) override; - void SetInitialVirtualTimeOffset(base::TimeDelta offset) override; void GrantVirtualTimeBudget( base::TimeDelta budget, base::OnceClosure budget_exhausted_callback) override;
diff --git a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h index db5544f..00a40dd 100644 --- a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -117,10 +117,6 @@ // This is used to set initial Date.now() while in virtual time mode. virtual void SetInitialVirtualTime(base::Time time) = 0; - // This is used for cross origin navigations to account for virtual time - // advancing in the previous renderer. - virtual void SetInitialVirtualTimeOffset(base::TimeDelta offset) = 0; - // Sets the virtual time policy, which is applied imemdiatly to all child // FrameSchedulers. virtual void SetVirtualTimePolicy(VirtualTimePolicy) = 0;
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h index 55142ea..1a247732f 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
@@ -73,7 +73,6 @@ bool VirtualTimeAllowedToAdvance() const override { return false; } void SetVirtualTimePolicy(VirtualTimePolicy policy) override {} void SetInitialVirtualTime(base::Time time) override {} - void SetInitialVirtualTimeOffset(base::TimeDelta offset) override {} void GrantVirtualTimeBudget(base::TimeDelta budget, base::OnceClosure callback) override {} void SetMaxVirtualTimeTaskStarvationCount(int count) override {}
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn index 84b60b8..b5f24870 100644 --- a/third_party/blink/renderer/platform/wtf/BUILD.gn +++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -173,6 +173,7 @@ "text/text_stream.cc", "text/text_stream.h", "text/unicode.h", + "text/unicode_string.h", "text/utf8.cc", "text/utf8.h", "text/wtf_string.cc",
diff --git a/third_party/blink/renderer/platform/wtf/text/string_impl.cc b/third_party/blink/renderer/platform/wtf/text/string_impl.cc index e199f324..63e56ef7 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_impl.cc +++ b/third_party/blink/renderer/platform/wtf/text/string_impl.cc
@@ -41,6 +41,8 @@ #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" #include "third_party/blink/renderer/platform/wtf/text/string_to_number.h" +#include "third_party/blink/renderer/platform/wtf/text/unicode.h" +#include "third_party/blink/renderer/platform/wtf/text/unicode_string.h" using std::numeric_limits;
diff --git a/third_party/blink/renderer/platform/wtf/text/unicode.h b/third_party/blink/renderer/platform/wtf/text/unicode.h index a3574c89..40dbc65 100644 --- a/third_party/blink/renderer/platform/wtf/text/unicode.h +++ b/third_party/blink/renderer/platform/wtf/text/unicode.h
@@ -24,7 +24,6 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_UNICODE_H_ #include <unicode/uchar.h> -#include <unicode/ustring.h> // Define platform neutral 8 bit character type (L is for Latin-1). typedef unsigned char LChar; @@ -121,30 +120,6 @@ return u_foldCase(c, U_FOLD_CASE_DEFAULT); } -inline int FoldCase(UChar* result, - int result_length, - const UChar* src, - int src_length, - bool* error) { - UErrorCode status = U_ZERO_ERROR; - int real_length = u_strFoldCase(result, result_length, src, src_length, - U_FOLD_CASE_DEFAULT, &status); - *error = !U_SUCCESS(status); - return real_length; -} - -inline int ToLower(UChar* result, - int result_length, - const UChar* src, - int src_length, - bool* error) { - UErrorCode status = U_ZERO_ERROR; - int real_length = - u_strToLower(result, result_length, src, src_length, "", &status); - *error = !!U_FAILURE(status); - return real_length; -} - inline UChar32 ToLower(UChar32 c) { return u_tolower(c); } @@ -153,34 +128,14 @@ return u_toupper(c); } -inline int ToUpper(UChar* result, - int result_length, - const UChar* src, - int src_length, - bool* error) { - UErrorCode status = U_ZERO_ERROR; - int real_length = - u_strToUpper(result, result_length, src, src_length, "", &status); - *error = !!U_FAILURE(status); - return real_length; -} - inline UChar32 ToTitleCase(UChar32 c) { return u_totitle(c); } -inline bool IsArabicChar(UChar32 c) { - return ublock_getCode(c) == UBLOCK_ARABIC; -} - inline bool IsAlphanumeric(UChar32 c) { return !!u_isalnum(c); } -inline bool IsSeparatorSpace(UChar32 c) { - return u_charType(c) == U_SPACE_SEPARATOR; -} - inline bool IsPrintableChar(UChar32 c) { return !!u_isprint(c); } @@ -193,10 +148,6 @@ return u_getIntPropertyValue(c, UCHAR_LINE_BREAK) == U_LB_COMPLEX_CONTEXT; } -inline UChar32 MirroredChar(UChar32 c) { - return u_charMirror(c); -} - inline CharCategory Category(UChar32 c) { return static_cast<CharCategory>(U_GET_GC_MASK(c)); } @@ -213,19 +164,11 @@ return !!u_isupper(c); } -inline uint8_t CombiningClass(UChar32 c) { - return u_getCombiningClass(c); -} - inline CharDecompositionType DecompositionType(UChar32 c) { return static_cast<CharDecompositionType>( u_getIntPropertyValue(c, UCHAR_DECOMPOSITION_TYPE)); } -inline int Umemcasecmp(const UChar* a, const UChar* b, int len) { - return u_memcasecmp(a, b, len, U_FOLD_CASE_DEFAULT); -} - } // namespace unicode } // namespace WTF
diff --git a/third_party/blink/renderer/platform/wtf/text/unicode_string.h b/third_party/blink/renderer/platform/wtf/text/unicode_string.h new file mode 100644 index 0000000..9dd427b --- /dev/null +++ b/third_party/blink/renderer/platform/wtf/text/unicode_string.h
@@ -0,0 +1,51 @@ +/* + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_UNICODE_STRING_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_UNICODE_STRING_H_ + +#include <unicode/stringoptions.h> +#include <unicode/ustring.h> + +namespace WTF { +namespace unicode { + +inline int FoldCase(UChar* result, + int result_length, + const UChar* src, + int src_length, + bool* error) { + UErrorCode status = U_ZERO_ERROR; + int real_length = u_strFoldCase(result, result_length, src, src_length, + U_FOLD_CASE_DEFAULT, &status); + *error = !U_SUCCESS(status); + return real_length; +} + +inline int Umemcasecmp(const UChar* a, const UChar* b, int len) { + return u_memcasecmp(a, b, len, U_FOLD_CASE_DEFAULT); +} + +} // namespace unicode +} // namespace WTF + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_UNICODE_STRING_H_
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 4febcba..beb125f0 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -1305,7 +1305,7 @@ 'paths': [ 'third_party/blink/renderer/core/layout/layout_theme.cc', 'third_party/blink/renderer/core/layout/layout_theme_mac.mm', - 'third_party/blink/renderer/core/paint/object_painter_base.cc', + 'third_party/blink/renderer/core/paint/outline_painter.cc', 'third_party/blink/renderer/core/paint/theme_painter.cc', 'third_party/blink/renderer/core/paint/theme_painter_default.cc', ],
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py index b354311..487d9d3 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -27,11 +27,9 @@ from blinkpy.web_tests.port.android import ANDROID_DISABLED_TESTS MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS -MOCK_GEN = '/mock-checkout/out/Release/gen/' MANIFEST_INSTALL_CMD = [ 'python3', '/mock-checkout/third_party/wpt_tools/wpt/wpt', 'manifest', - '-v', '--no-download', '--tests-root', MOCK_WEB_TESTS + 'external/wpt', - '--path', MOCK_GEN + 'external/wpt/MANIFEST.json' + '-v', '--no-download', '--tests-root', MOCK_WEB_TESTS + 'external/wpt' ] @@ -528,12 +526,7 @@ host.filesystem.write_text_file( MOCK_WEB_TESTS + 'external/wpt/MANIFEST.json', '{}') importer._generate_manifest() - install_cmd = [ - 'python3', '/mock-checkout/third_party/wpt_tools/wpt/wpt', 'manifest', - '-v', '--no-download', '--tests-root', MOCK_WEB_TESTS + 'external/wpt', - '--path', MOCK_WEB_TESTS + 'external/wpt/MANIFEST.json' - ] - self.assertEqual(host.executive.calls, [MANIFEST_INSTALL_CMD, install_cmd]) + self.assertEqual(host.executive.calls, [MANIFEST_INSTALL_CMD] * 2) self.assertEqual(importer.chromium_git.added_paths, {MOCK_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME})
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py index 06d468b..b95556e 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
@@ -26,7 +26,6 @@ from blinkpy.web_tests.port.factory_mock import MockPortFactory MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS -MOCK_GEN = '/mock-checkout/out/Release/gen/' class WPTExpectationsUpdaterTest(LoggingTestCase): def mock_host(self): @@ -825,7 +824,7 @@ host.filesystem.maybe_make_directory( port.web_tests_dir(), 'wpt_internal') host.filesystem.copyfile( - host.filesystem.join(MOCK_GEN, + host.filesystem.join(port.web_tests_dir(), 'external', 'wpt', MANIFEST_NAME), host.filesystem.join(port.web_tests_dir(), 'wpt_internal', MANIFEST_NAME))
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py index c78f391..d45ced9e 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
@@ -102,10 +102,9 @@ @property def wpt_dir(self): - if 'external' in self.wpt_manifest_path: - return 'external/wpt' - else: - return 'wpt_internal' + return self.host.filesystem.dirname( + self.host.filesystem.relpath( + self.wpt_manifest_path, self.port.web_tests_dir())) def _items_for_file_path(self, path_in_wpt): """Finds manifest items for the given WPT path. @@ -286,21 +285,18 @@ return self.test_name_to_file.get(url) @staticmethod - def ensure_manifest(port, path=None, manifest_path=None): + def ensure_manifest(port, path=None): """Regenerates the WPT MANIFEST.json file. Args: port: A blinkpy.web_tests.port.Port object. path: The path to a WPT root (relative to web_tests, optional). - manifest_path: The path to the new manifest file """ fs = port.host.filesystem if path is None: path = fs.join('external', 'wpt') wpt_path = fs.join(port.web_tests_dir(), path) - if manifest_path is None: - manifest_path = fs.join(wpt_path, MANIFEST_NAME) - fs.maybe_make_directory(fs.dirname(manifest_path)) + manifest_path = fs.join(wpt_path, MANIFEST_NAME) # Unconditionally delete local MANIFEST.json to avoid regenerating the # manifest from scratch (when version is bumped) or invalid/out-of-date @@ -321,7 +317,7 @@ _log.error('Manifest base not found at "%s".', base_manifest_path) - WPTManifest.generate_manifest(port, wpt_path, manifest_path) + WPTManifest.generate_manifest(port, wpt_path) if fs.isfile(manifest_path): _log.debug('Manifest generation completed.') @@ -332,17 +328,14 @@ fs.write_text_file(manifest_path, '{}') @staticmethod - def generate_manifest(port, dest_path, manifest_path=None): + def generate_manifest(port, dest_path): """Generates MANIFEST.json on the specified directory.""" - if manifest_path is None: - fs = port.host.filesystem - manifest_path = fs.join(dest_path, MANIFEST_NAME) wpt_exec_path = PathFinder( port.host.filesystem).path_from_chromium_base( 'third_party', 'wpt_tools', 'wpt', 'wpt') cmd = [ port.python3_command(), wpt_exec_path, 'manifest', '-v', - '--no-download', '--tests-root', dest_path, '--path', manifest_path + '--no-download', '--tests-root', dest_path ] # ScriptError will be raised if the command fails.
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py index b653d29..7449816f 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
@@ -31,8 +31,6 @@ '--no-download', '--tests-root', WEB_TEST_DIR + '/external/wpt', - '--path', - WEB_TEST_DIR + '/external/wpt/MANIFEST.json' ]]) def test_ensure_manifest_updates_manifest_if_it_exists(self): @@ -57,8 +55,6 @@ '--no-download', '--tests-root', WEB_TEST_DIR + '/external/wpt', - '--path', - WEB_TEST_DIR + '/external/wpt/MANIFEST.json' ]]) def test_ensure_manifest_raises_exception(self): @@ -81,8 +77,6 @@ '--no-download', '--tests-root', WEB_TEST_DIR + '/wpt_internal', - '--path', - WEB_TEST_DIR + '/wpt_internal/MANIFEST.json', ]]) def test_does_not_throw_when_missing_some_test_types(self):
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 d0bd482..747edb7 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -1021,11 +1021,12 @@ assert path in self.WPT_DIRS # Convert '/' to the platform-specific separator. path = self._filesystem.normpath(path) - manifest_path = self._build_path('gen', path, MANIFEST_NAME) + manifest_path = self._filesystem.join(self.web_tests_dir(), path, + MANIFEST_NAME) if not self._filesystem.exists(manifest_path) or self.get_option( 'manifest_update', False): _log.debug('Generating MANIFEST.json for %s...', path) - WPTManifest.ensure_manifest(self, path, manifest_path) + WPTManifest.ensure_manifest(self, path) return WPTManifest(self.host, manifest_path) def is_wpt_crash_test(self, test_name):
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py index d5209f22..08a3012d 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py
@@ -779,7 +779,7 @@ port.set_option_default('manifest_update', False) filesystem = port.host.filesystem filesystem.write_text_file( - '/mock-checkout/out/Release/gen' + '/external/wpt/MANIFEST.json', '{}') + WEB_TEST_DIR + '/external/wpt/MANIFEST.json', '{}') filesystem.clear_written_files() port.wpt_manifest('external/wpt')
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/test.py b/third_party/blink/tools/blinkpy/web_tests/port/test.py index 23b7ef2..1b88176 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/test.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/test.py
@@ -530,7 +530,7 @@ port.set_option_default('manifest_update', False) filesystem = port.host.filesystem filesystem.write_text_file( - '/mock-checkout/out/Release/gen' + '/external/wpt/MANIFEST.json', + WEB_TEST_DIR + '/external/wpt/MANIFEST.json', json.dumps({ 'items': { 'testharness': { @@ -610,7 +610,7 @@ WEB_TEST_DIR + '/external/wpt/common/blank.html', 'foo') filesystem.write_text_file( - '/mock-checkout/out/Release/gen' + '/wpt_internal/MANIFEST.json', + WEB_TEST_DIR + '/wpt_internal/MANIFEST.json', json.dumps({ 'items': { 'testharness': {
diff --git a/third_party/blink/tools/gen_manifest.py b/third_party/blink/tools/gen_manifest.py deleted file mode 100755 index e96c0a5..0000000 --- a/third_party/blink/tools/gen_manifest.py +++ /dev/null
@@ -1,55 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2019 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import argparse -import errno -import os -import shutil -import subprocess -import sys - -SRC_DIR = os.path.abspath( - os.path.join(os.path.dirname(__file__), - os.pardir, os.pardir, os.pardir)) -WPT_EXEC_PATH = os.path.join(SRC_DIR, 'third_party', 'wpt_tools', 'wpt', 'wpt') -BASE_MANIFEST_PATH = os.path.join(SRC_DIR, 'third_party', 'blink', - 'web_tests', 'external', - 'WPT_BASE_MANIFEST_8.json') -MANIFEST_NAME = 'MANIFEST.json' - -def maybe_make_directory(path): - try: - os.makedirs(path) - except OSError as error: - if error.errno != errno.EEXIST: - raise - -def main() : - usage = "Generate manifest for web test..." - parser = argparse.ArgumentParser( - add_help=False, prog='gen_manifest.py', usage=usage) - parser.add_argument('--out', required=True, - help='Path of the output directory') - options = parser.parse_args() - if options.out.startswith('//'): - options.out = os.path.join(SRC_DIR, options.out[2:]) - - WPT_DIRS = ['wpt_internal', 'external/wpt'] - for path in WPT_DIRS: - print('Generating MANIFEST.json for %s...' % path) - wpt_path = os.path.join(SRC_DIR, 'third_party', - 'blink', 'web_tests', path) - manifest_path = os.path.join(options.out, path, MANIFEST_NAME) - if 'external' in path: - maybe_make_directory(os.path.dirname(manifest_path)) - shutil.copyfile(BASE_MANIFEST_PATH, manifest_path) - cmd = [ - sys.executable, WPT_EXEC_PATH, 'manifest', '-v', - '--no-download', '--tests-root', wpt_path, '--path', manifest_path - ] - subprocess.check_output(cmd) - -if __name__ == '__main__': - main()
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility index cb8f3d0..b9cd9d2 100644 --- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility +++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -12,7 +12,6 @@ crbug.com/1225860 virtual/layout_ng_block_frag/fast/multicol/dynamic/untransformed-becomes-transformed-has-abspos-crash.html [ CRASH ] # Slow -crbug.com/1212963 virtual/synchronous_html_parser/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html [ TIMEOUT ] crbug.com/1225893 crbug.com/1126305 virtual/prerender/wpt_internal/prerender/activation-start.html [ TIMEOUT ] crbug.com/1225893 crbug.com/1126305 virtual/prerender/wpt_internal/prerender/cross-origin-isolated.https.html [ TIMEOUT ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b1c658ba..cd2f8ff 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1218,47 +1218,37 @@ crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-006.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-009.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-002.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-003.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-004.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-005.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-006.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/mrow/legacy-mrow-like-elements-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/operators/embellished-operator-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/operators/embellished-operator-002.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/scripts/cramped-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/spaces/space-like-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/spaces/space-like-002.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/spaces/space-like-004.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/tables/table-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/tables/table-002.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/tables/table-axis-height.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/ignored-properties-001.html [ Failure Timeout ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-bold-fraktur.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-bold-italic.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-bold-sans-serif.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-bold-script.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-bold.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-case-sensitivity.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-double-struck.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-fraktur.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-initial.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-italic.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-looped.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-monospace.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-bold-italic.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-italic.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-sans-serif.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-script.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-stretched.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-tailed.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/width-height-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/html5-tree/href-click-1.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/html5-tree/href-click-2.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/html5-tree/href-click-3.html [ Failure ] + +# These tests fail because we don't support MathML ink metrics. +crbug.com/1125137 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-001.html [ Failure ] +crbug.com/1125137 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-002.html [ Failure ] +crbug.com/1125137 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-003.html [ Failure ] +crbug.com/1125137 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-004.html [ Failure ] +crbug.com/1125137 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-005.html [ Failure ] +crbug.com/1125137 external/wpt/mathml/presentation-markup/fractions/frac-parameters-gap-006.html [ Failure ] + +# These tests fail because we don't support embellished operators. +crbug.com/1124298 external/wpt/mathml/presentation-markup/operators/embellished-operator-001.html [ Failure ] +crbug.com/1124298 external/wpt/mathml/presentation-markup/operators/embellished-operator-002.html [ Failure ] +crbug.com/1124298 external/wpt/mathml/presentation-markup/spaces/space-like-001.html [ Failure ] +crbug.com/1124298 external/wpt/mathml/presentation-markup/spaces/space-like-002.html [ Failure ] +crbug.com/1124298 external/wpt/mathml/presentation-markup/spaces/space-like-004.html [ Failure ] + +# These tests fail because we don't support MathML tables. +crbug.com/1125111 external/wpt/mathml/presentation-markup/tables/table-001.html [ Failure ] +crbug.com/1125111 external/wpt/mathml/presentation-markup/tables/table-002.html [ Failure ] +crbug.com/1125111 external/wpt/mathml/presentation-markup/tables/table-axis-height.html [ Failure ] + +# These tests fail because some CSS properties affect MathML layout. +crbug.com/1227601 external/wpt/mathml/relations/css-styling/ignored-properties-001.html [ Failure Timeout ] +crbug.com/1227598 external/wpt/mathml/relations/css-styling/width-height-001.html [ Failure ] + +# This test has flaky timeout. +crbug.com/1093840 external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html [ Pass Timeout ] # These tests fail because we don't parse math display values according to the spec. crbug.com/1127222 external/wpt/css/css-display/display-math-on-pseudo-elements-001.html [ Failure ] @@ -1271,24 +1261,51 @@ # This test fails on macOS. crbug.com/6606 [ Mac ] external/wpt/mathml/relations/text-and-math/use-typo-metrics-1.html [ Failure ] -# Tentative tests for new CSS proposals -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-fraktur-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-stretched-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-looped-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-double-struck-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-initial-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-italic-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-italic-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-script-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-tailed-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-italic-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-sans-serif-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-monospace-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-fraktur-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-script-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-bold-italic-001.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-001.tentative.html [ Failure ] +# These tests fail because we don't support the MathML href attribute, which is +# not part of MathML Core Level 1. +crbug.com/6606 external/wpt/mathml/relations/html5-tree/href-click-1.html [ Failure ] +crbug.com/6606 external/wpt/mathml/relations/html5-tree/href-click-2.html [ Failure ] +crbug.com/6606 external/wpt/mathml/relations/html5-tree/href-click-3.html [ Failure ] + +# These tests fail because they require full support for new text-transform +# values and mathvariant attribute. Currently, we only support the new +# text-transform: auto, use the UA rule for the <mi> element and map +# mathvariant="normal" to "text-transform: none". +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-fraktur-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-italic-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-sans-serif-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-bold-script-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-double-struck-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-fraktur-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-initial-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-italic-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-looped-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-monospace-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-bold-italic-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-italic-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-script-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-stretched-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/css/css-text/text-transform/math/text-transform-math-tailed-001.tentative.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-bold-fraktur.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-bold-italic.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-bold-sans-serif.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-bold-script.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-bold.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-case-sensitivity.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-double-struck.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-fraktur.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-initial.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-italic.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-looped.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-monospace.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-bold-italic.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-italic.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-sans-serif.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-script.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-stretched.html [ Failure ] +crbug.com/1076420 external/wpt/mathml/relations/css-styling/mathvariant-tailed.html [ Failure ] # ====== Style team owned tests from here ====== @@ -1949,6 +1966,9 @@ crbug.com/479533 accessibility/show-context-menu-shadowdom.html [ Skip ] crbug.com/483653 accessibility/scroll-containers.html [ Skip ] +# Temporarily disabled until document marker serialization is enabled for AXInlineTextBox +crbug.com/1227485 accessibility/spelling-markers.html [ Failure ] + # Temporarily disabled after chromium change crbug.com/492511 [ Mac ] virtual/text-antialias/atsui-negative-spacing-features.html [ Failure ] crbug.com/492511 [ Mac ] virtual/text-antialias/international/arabic-justify.html [ Failure ] @@ -6316,7 +6336,6 @@ # Sheriff 2021-04-05 crbug.com/921151 http/tests/security/mixedContent/insecure-iframe-with-hsts.https.html [ Failure Pass ] -crbug.com/1093840 external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html [ Pass Timeout ] # Sheriff 2021-04-06 crbug.com/1032451 [ Linux ] virtual/threaded/animations/stability/animation-iteration-event-destroy-renderer.html [ Failure Pass Timeout ] @@ -6436,8 +6455,7 @@ # Sheriff 2021-05-03 crbug.com/1205133 [ Linux ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-color.html [ Pass Timeout ] crbug.com/1205133 [ Mac ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-color.html [ Pass Timeout ] -crbug.com/1205020 [ Win ] virtual/oopr-canvas2d/fast/canvas/canvas-blend-image.html [ Failure Pass ] -crbug.com/1205020 [ Linux ] virtual/oopr-canvas2d/fast/canvas/canvas-blend-image.html [ Failure Pass ] +crbug.com/1205020 virtual/oopr-canvas2d/fast/canvas/canvas-blend-image.html [ Failure Pass Timeout ] crbug.com/1205012 external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html [ Pass Timeout ] crbug.com/1197465 [ Linux ] virtual/scroll-unification/fast/events/mouse-cursor-no-mousemove.html [ Failure Pass ] crbug.com/1093041 fast/canvas/color-space/canvas-createImageBitmap-rec2020.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 80d5c22..b3199e2 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -727,6 +727,15 @@ "args": ["--enable-blink-features=CSSContainerQueries"] }, { + "prefix": "isolated-animation-updates", + "bases": ["external/wpt/css/css-animations", + "external/wpt/css/css-transitions", + "external/wpt/scroll-animations", + "external/wpt/web-animations", + "animations"], + "args": ["--enable-blink-features=CSSIsolatedAnimationUpdates"] + }, + { "prefix": "appcache-origin-trial", "bases": ["http/tests/appcache"], "args": ["--enable-features=AppCacheRequireOriginTrial",
diff --git a/third_party/blink/web_tests/WebGPUExpectations b/third_party/blink/web_tests/WebGPUExpectations index 26b2272..df6b695 100644 --- a/third_party/blink/web_tests/WebGPUExpectations +++ b/third_party/blink/web_tests/WebGPUExpectations
@@ -33,9 +33,12 @@ wpt_internal/webgpu/cts.html?q=webgpu:api,validation,buffer,destroy:error_buffer:* [ Failure ] wpt_internal/webgpu/cts.html?worker=1&q=webgpu:api,validation,buffer,destroy:* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:* [ Crash Failure ] -wpt_internal/webgpu/cts.html?q=webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,compressed,non_array:format="bc5-rg-snorm";* [ Crash ] -wpt_internal/webgpu/cts.html?q=webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:format="rg8unorm";* [ Crash ] +[ Win ] wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read";access="read";atomic=false;baseType="f32";* [ Timeout ] +[ Win ] wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=false;baseType="f32";* [ Timeout ] +[ Win ] wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="uniform";* [ Timeout ] + wpt_internal/webgpu/cts.html?q=webgpu:api,operation,rendering,blending:GPUBlendComponent:component="alpha";srcFactor="src-alpha-saturated";* [ Crash ] wpt_internal/webgpu/cts.html?q=webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToBuffer";format="rg8unorm";* [ Crash ] wpt_internal/webgpu/cts.html?q=webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToTexture";format="stencil8";* [ Crash ] @@ -50,8 +53,6 @@ crbug.com/1224802 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:web_platform,copyToTexture,canvas:copy_contents_from_2d_context_canvas:* [ Timeout Crash ] [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:web_platform,copyToTexture,canvas:copy_contents_from_gl_context_canvas:* [ Timeout Crash ] -wpt_internal/webgpu/cts.html?q=webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,compressed,array:* [ Failure ] -wpt_internal/webgpu/cts.html?q=webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,compressed,non_array:format="bc7-rgba-unorm";* [ Failure ] wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createTexture:sampleCount,various_sampleCount_with_all_formats:* [ Failure Crash ] crbug.com/dawn/759 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:api,operation,rendering,draw:vertex_attributes,basic:* [ Failure ] crbug.com/1203413 [ Mac ] wpt_internal/webgpu/cts.html?worker=1&q=webgpu:api,validation,buffer,mapping:* [ Crash ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/transform-marquee-resize-div-image-001.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/transform-marquee-resize-div-image-001.html new file mode 100644 index 0000000..8bdbb984 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/transform-marquee-resize-div-image-001.html
@@ -0,0 +1,8 @@ +<!DOCTYPE HTML> +<title>CSS Test (Transforms): Transform and marquee with resize, etc.</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/"> +<link rel="author" title="Google" href="http://www.google.com/"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1226919"> +<meta name="assert" content="This should not crash."> + +<body style="transform: scalex(0.9)"><marquee style="resize: both"><div><img src="../not-found.png">
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html new file mode 100644 index 0000000..1926bccf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.1.radius.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.1.radius.dompointinit</h1> +<p class="desc">Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-left corners.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-left corners."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(canvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(canvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(canvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(canvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// top-right corner +_assertPixel(canvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(canvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(canvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(canvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(canvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(canvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(canvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(canvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// bottom-left corner +_assertPixel(canvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(canvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(canvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(canvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html new file mode 100644 index 0000000..37eb89d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.2.radii.1.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.2.radii.1.dompointinit</h1> +<p class="desc">Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-right corners.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-right corners."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(canvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(canvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(canvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(canvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(canvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(canvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(canvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(canvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html new file mode 100644 index 0000000..7f67255 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.2.radii.2.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.2.radii.2.dompointinit</h1> +<p class="desc">Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right and bottom-left corners.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right and bottom-left corners."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(canvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(canvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(canvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(canvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-left corner +_assertPixel(canvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(canvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(canvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(canvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html new file mode 100644 index 0000000..11709a1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.3.radii.1.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.3.radii.1.dompointinit</h1> +<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(canvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(canvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(canvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(canvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html new file mode 100644 index 0000000..72e7533 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.3.radii.2.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.3.radii.2.dompointinit</h1> +<p class="desc">Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottom-left corners.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottom-left corners."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(canvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(canvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(canvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(canvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-left corner +_assertPixel(canvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(canvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(canvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(canvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html new file mode 100644 index 0000000..eec602e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.3.radii.3.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.3.radii.3.dompointinit</h1> +<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-right corner +_assertPixel(canvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(canvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(canvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(canvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html new file mode 100644 index 0000000..72b9ecc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.4.radii.1.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.4.radii.1.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(canvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(canvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(canvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(canvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html new file mode 100644 index 0000000..a58a846 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.4.radii.2.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.4.radii.2.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(canvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(canvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(canvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(canvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html new file mode 100644 index 0000000..f58de8e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.4.radii.3.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.4.radii.3.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-right corner +_assertPixel(canvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(canvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(canvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(canvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html new file mode 100644 index 0000000..5929112 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.4.radii.4.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.4.radii.4.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-left corner +_assertPixel(canvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(canvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(canvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(canvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html index 01ad92ea..37489d2 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html
@@ -19,9 +19,8 @@ var t = async_test("roundRect() with negative radius throws an exception"); _addTest(function(canvas, ctx) { -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 0, 0, [-1]); }); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 0, 0, [1, -1]); }); -t.done(); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])}); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])}); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html index b55d1ec..16a03c1f 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html
@@ -8,7 +8,7 @@ <body class="show_output"> <h1>2d.path.roundrect.radius.none</h1> -<p class="desc">Check that roundRect throws an IndexSizeError if radii is an empty array.</p> +<p class="desc">Check that roundRect throws an RangeError if radii is an empty array.</p> <p class="output">Actual output:</p> @@ -16,10 +16,10 @@ <ul id="d"></ul> <script> -var t = async_test("Check that roundRect throws an IndexSizeError if radii is an empty array."); +var t = async_test("Check that roundRect throws an RangeError if radii is an empty array."); _addTest(function(canvas, ctx) { -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 100, 50, []); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])}); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html index aaa7756..c6a960b0 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html
@@ -19,7 +19,7 @@ var t = async_test("Check that roundRect throws an IndeSizeError if radii has more than four items."); _addTest(function(canvas, ctx) { -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0]); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])}); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.html new file mode 100644 index 0000000..0bf3370 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.1.radius.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.1.radius.dompointinit</h1> +<p class="desc">Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-left corners.</p> + + +<script> +var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-left corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.worker.js new file mode 100644 index 0000000..ec0580b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.worker.js
@@ -0,0 +1,51 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.1.radius.dompointinit +// Description:Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-left corners. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-left corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html new file mode 100644 index 0000000..dbaac00 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.1.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.2.radii.1.dompointinit</h1> +<p class="desc">Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-right corners.</p> + + +<script> +var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-right corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.worker.js new file mode 100644 index 0000000..f9d11df --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.worker.js
@@ -0,0 +1,43 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.1.dompointinit +// Description:Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-right corners. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-right corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html new file mode 100644 index 0000000..eb782c13 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.2.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.2.radii.2.dompointinit</h1> +<p class="desc">Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners.</p> + + +<script> +var t = async_test("Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.worker.js new file mode 100644 index 0000000..5285968 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.worker.js
@@ -0,0 +1,43 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.2.dompointinit +// Description:Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html new file mode 100644 index 0000000..a419679 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.1.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.3.radii.1.dompointinit</h1> +<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p> + + +<script> +var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.worker.js new file mode 100644 index 0000000..8ef16a44 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.worker.js
@@ -0,0 +1,38 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.1.dompointinit +// Description:Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html new file mode 100644 index 0000000..07c4eec --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.2.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.3.radii.2.dompointinit</h1> +<p class="desc">Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners.</p> + + +<script> +var t = async_test("Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.worker.js new file mode 100644 index 0000000..557762505 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.worker.js
@@ -0,0 +1,43 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.2.dompointinit +// Description:Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html new file mode 100644 index 0000000..9e46776 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.3.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.3.radii.3.dompointinit</h1> +<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p> + + +<script> +var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.worker.js new file mode 100644 index 0000000..5bc8e6f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.worker.js
@@ -0,0 +1,38 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.3.dompointinit +// Description:Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html new file mode 100644 index 0000000..81900a2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.1.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.4.radii.1.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p> + + +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.worker.js new file mode 100644 index 0000000..dad5edf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.worker.js
@@ -0,0 +1,38 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.1.dompointinit +// Description:Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(offscreenCanvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html new file mode 100644 index 0000000..1386928 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.2.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.4.radii.2.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.</p> + + +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.worker.js new file mode 100644 index 0000000..d0dd9bab --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.worker.js
@@ -0,0 +1,38 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.2.dompointinit +// Description:Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-right corner +_assertPixel(offscreenCanvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html new file mode 100644 index 0000000..66e2b7e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.3.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.4.radii.3.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p> + + +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.worker.js new file mode 100644 index 0000000..5242cbb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.worker.js
@@ -0,0 +1,38 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.3.dompointinit +// Description:Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-right corner +_assertPixel(offscreenCanvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html new file mode 100644 index 0000000..2cd3930 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.4.dompointinit</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.path.roundrect.4.radii.4.dompointinit</h1> +<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.</p> + + +<script> +var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +t.done(); + +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.worker.js new file mode 100644 index 0000000..50cd0ed --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.worker.js
@@ -0,0 +1,38 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.4.dompointinit +// Description:Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// bottom-left corner +_assertPixel(offscreenCanvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(offscreenCanvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(offscreenCanvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(offscreenCanvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + +// other corners +_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255"); +_assertPixel(offscreenCanvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255"); +t.done(); + +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html index 4c97373..afedca2 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html
@@ -20,8 +20,8 @@ var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 0, 0, [-1]); }); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 0, 0, [1, -1]); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])}); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])}); t.done(); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js index b941725..9fc4e8f 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js
@@ -16,8 +16,8 @@ var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 0, 0, [-1]); }); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 0, 0, [1, -1]); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])}); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])}); t.done(); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html index 6defab2..85d9b80 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html
@@ -6,11 +6,11 @@ <script src="/html/canvas/resources/canvas-tests.js"></script> <h1>2d.path.roundrect.radius.none</h1> -<p class="desc">Check that roundRect throws an IndexSizeError if radii is an empty array.</p> +<p class="desc">Check that roundRect throws an RangeError if radii is an empty array.</p> <script> -var t = async_test("Check that roundRect throws an IndexSizeError if radii is an empty array."); +var t = async_test("Check that roundRect throws an RangeError if radii is an empty array."); var t_pass = t.done.bind(t); var t_fail = t.step_func(function(reason) { throw reason; @@ -20,7 +20,7 @@ var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 100, 50, []); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])}); t.done(); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js index 9acbf0d8..e1623b9 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js
@@ -1,12 +1,12 @@ // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. // OffscreenCanvas test in a worker:2d.path.roundrect.radius.none -// Description:Check that roundRect throws an IndexSizeError if radii is an empty array. +// Description:Check that roundRect throws an RangeError if radii is an empty array. // Note: importScripts("/resources/testharness.js"); importScripts("/html/canvas/resources/canvas-tests.js"); -var t = async_test("Check that roundRect throws an IndexSizeError if radii is an empty array."); +var t = async_test("Check that roundRect throws an RangeError if radii is an empty array."); var t_pass = t.done.bind(t); var t_fail = t.step_func(function(reason) { throw reason; @@ -16,7 +16,7 @@ var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 100, 50, []); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])}); t.done(); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html index fe75bc2..c615b0e8b 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html
@@ -20,7 +20,7 @@ var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0]); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])}); t.done(); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js index 294ae6b..2b35cb5 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js
@@ -16,7 +16,7 @@ var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); -assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0]); }); +assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])}); t.done(); });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml index 0e40e8b..5225600 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml +++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml
@@ -1820,6 +1820,26 @@ @assert pixel 98,48 == 0,255,0,255; @assert pixel 1,48 == 0,255,0,255; +- name: 2d.path.roundrect.4.radii.1.dompointinit + desc: Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // other corners + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + - name: 2d.path.roundrect.4.radii.2.double desc: Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner. code: | @@ -1853,6 +1873,26 @@ @assert pixel 98,48 == 0,255,0,255; @assert pixel 1,48 == 0,255,0,255; +- name: 2d.path.roundrect.4.radii.2.dompointinit + desc: Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + - name: 2d.path.roundrect.4.radii.3.double desc: Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner. code: | @@ -1886,6 +1926,26 @@ @assert pixel 98,1 == 0,255,0,255; @assert pixel 1,48 == 0,255,0,255; +- name: 2d.path.roundrect.4.radii.3.dompointinit + desc: Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + - name: 2d.path.roundrect.4.radii.4.double desc: Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner. code: | @@ -1919,6 +1979,26 @@ @assert pixel 98,1 == 0,255,0,255; @assert pixel 98,48 == 0,255,0,255; +- name: 2d.path.roundrect.4.radii.4.dompointinit + desc: Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + - name: 2d.path.roundrect.3.radii.1.double desc: Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner. code: | @@ -1952,6 +2032,26 @@ @assert pixel 98,48 == 0,255,0,255; @assert pixel 1,48 == 0,255,0,255; +- name: 2d.path.roundrect.3.radii.1.dompointinit + desc: Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // other corners + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + - name: 2d.path.roundrect.3.radii.2.double desc: Verify that when three radii are given to roundRect(), the second radius, specified as a double, applies to the top-right and bottom-left corners. code: | @@ -1990,6 +2090,31 @@ @assert pixel 1,1 == 0,255,0,255; @assert pixel 98,48 == 0,255,0,255; +- name: 2d.path.roundrect.3.radii.2.dompointinit + desc: Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottom-left corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + - name: 2d.path.roundrect.3.radii.3.double desc: Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner. code: | @@ -2023,6 +2148,26 @@ @assert pixel 98,1 == 0,255,0,255; @assert pixel 1,48 == 0,255,0,255; +- name: 2d.path.roundrect.3.radii.3.dompointinit + desc: Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + - name: 2d.path.roundrect.2.radii.1.double desc: Verify that when two radii are given to roundRect(), the first radius, specified as a double, applies to the top-left and bottom-right corners. code: | @@ -2061,6 +2206,31 @@ @assert pixel 98,1 == 0,255,0,255; @assert pixel 1,48 == 0,255,0,255; +- name: 2d.path.roundrect.2.radii.1.dompointinit + desc: Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-right corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // other corners + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + - name: 2d.path.roundrect.2.radii.2.double desc: Verify that when two radii are given to roundRect(), the second radius, specified as a double, applies to the top-right and bottom-left corners. code: | @@ -2099,6 +2269,31 @@ @assert pixel 1,1 == 0,255,0,255; @assert pixel 98,48 == 0,255,0,255; +- name: 2d.path.roundrect.2.radii.2.dompointinit + desc: Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right and bottom-left corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + - name: 2d.path.roundrect.1.radius.double desc: Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners. code: | @@ -2145,6 +2340,39 @@ @assert pixel 1,39 == 255,0,0,255; @assert pixel 1,28 == 0,255,0,255; +- name: 2d.path.roundrect.1.radius.dompointinit + desc: Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-left corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + - name: 2d.path.roundrect.radius.intersecting.1 desc: Check that roundRects with intersecting corner arcs are rendered correctly. code: | @@ -2182,21 +2410,20 @@ @assert pixel 98,48 == 255,0,0,255; - name: 2d.path.roundrect.radius.none - desc: Check that roundRect throws an IndexSizeError if radii is an empty array. + desc: Check that roundRect throws an RangeError if radii is an empty array. code: | - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 100, 50, []); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])}); - name: 2d.path.roundrect.radius.toomany desc: Check that roundRect throws an IndeSizeError if radii has more than four items. code: | - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0]); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])}); - name: 2d.path.roundrect.radius.negative desc: roundRect() with negative radius throws an exception code: | - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 0, 0, [-1]); - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 0, 0, [1, -1]); - t.done(); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])}); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])}); - name: 2d.path.ellipse.basics desc: Verify canvas throws error when drawing ellipse with negative radii.
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/path-objects.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/path-objects.yaml index c10b9d3..ea97135 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/path-objects.yaml +++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/path-objects.yaml
@@ -1799,6 +1799,27 @@ @assert pixel 1,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.4.radii.1.dompointinit + desc: Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // other corners + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.4.radii.2.double desc: Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner. code: | @@ -1834,6 +1855,27 @@ @assert pixel 1,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.4.radii.2.dompointinit + desc: Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.4.radii.3.double desc: Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner. code: | @@ -1869,6 +1911,27 @@ @assert pixel 1,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.4.radii.3.dompointinit + desc: Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.4.radii.4.double desc: Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner. code: | @@ -1904,6 +1967,27 @@ @assert pixel 98,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.4.radii.4.dompointinit + desc: Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.3.radii.1.double desc: Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner. code: | @@ -1939,6 +2023,27 @@ @assert pixel 1,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.3.radii.1.dompointinit + desc: Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // other corners + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.3.radii.2.double desc: Verify that when three radii are given to roundRect(), the second radius, specified as a double, applies to the top-right and bottom-left corners. code: | @@ -1979,6 +2084,32 @@ @assert pixel 98,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.3.radii.2.dompointinit + desc: Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.3.radii.3.double desc: Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner. code: | @@ -2014,6 +2145,27 @@ @assert pixel 1,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.3.radii.3.dompointinit + desc: Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.2.radii.1.double desc: Verify that when two radii are given to roundRect(), the first radius, specified as a double, applies to the top-left and bottom-right corners. code: | @@ -2054,6 +2206,32 @@ @assert pixel 1,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.2.radii.1.dompointinit + desc: Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-right corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // other corners + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.2.radii.2.double desc: Verify that when two radii are given to roundRect(), the second radius, specified as a double, applies to the top-right and bottom-left corners. code: | @@ -2094,6 +2272,32 @@ @assert pixel 98,48 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.2.radii.2.dompointinit + desc: Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottomInit-left corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + + // other corners + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.1.radius.double desc: Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners. code: | @@ -2142,6 +2346,40 @@ @assert pixel 1,28 == 0,255,0,255; t.done(); +- name: 2d.path.roundrect.1.radius.dompointinit + desc: Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottomInit-left corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + t.done(); + - name: 2d.path.roundrect.radius.intersecting.1 desc: Check that roundRects with intersecting corner arcs are rendered correctly. code: | @@ -2181,22 +2419,22 @@ t.done(); - name: 2d.path.roundrect.radius.none - desc: Check that roundRect throws an IndexSizeError if radii is an empty array. + desc: Check that roundRect throws an RangeError if radii is an empty array. code: | - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 100, 50, []); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])}); t.done(); - name: 2d.path.roundrect.radius.toomany desc: Check that roundRect throws an IndeSizeError if radii has more than four items. code: | - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0]); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])}); t.done(); - name: 2d.path.roundrect.radius.negative desc: roundRect() with negative radius throws an exception code: | - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 0, 0, [-1]); - @assert throws INDEX_SIZE_ERR ctx.roundRect(0, 0, 0, 0, [1, -1]); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])}); + assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])}); t.done(); - name: 2d.path.fill.overlap
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt index 92e3c597..f95a65c9 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt
@@ -7,7 +7,7 @@ "backgroundColor": "#FFFFFF" }, { - "name": "LayoutNGBlockFlow DIV id='test' class='composited box changed'", + "name": "LayoutNGBlockFlow DIV id='test' class='composited box'", "bounds": [202, 202], "contentsOpaqueForText": true, "transform": 2
diff --git a/third_party/blink/web_tests/http/tests/devtools/copy-network-request.js b/third_party/blink/web_tests/http/tests/devtools/copy-network-request.js index 361b8f5..dbba23f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/copy-network-request.js +++ b/third_party/blink/web_tests/http/tests/devtools/copy-network-request.js
@@ -11,7 +11,11 @@ var logView = UI.panels.network._networkLogView; function newRequest(isBlob, headers, data, opt_url, method = null) { - var request = new SDK.NetworkRequest(0, (isBlob === true ? 'blob:' : '') + (opt_url || 'http://example.org/path'), 0, 0, 0); + var request = SDK.NetworkRequest.create( + 0, + (isBlob === true ? 'blob:' : '') + + (opt_url || 'http://example.org/path'), + 0, 0, 0); request.requestMethod = method || (data ? 'POST' : 'GET'); var headerList = []; if (headers) {
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/json-preview.js b/third_party/blink/web_tests/http/tests/devtools/network/json-preview.js index 6bb884c..be2fef4f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/json-preview.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/json-preview.js
@@ -10,7 +10,7 @@ function createNetworkRequestWithJSONMIMEType(type) { TestRunner.addResult('Creating a NetworkRequest with type: ' + type); - var request = new SDK.NetworkRequest(0, 'http://localhost'); + var request = SDK.NetworkRequest.create(0, 'http://localhost'); request.mimeType = type; request._contentData = Promise.resolve({error: null, content: '{"number": 42}', encoded: false}); return request;
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js b/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js index b0441a9..ce4f4b7 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js
@@ -10,7 +10,7 @@ await TestRunner.showPanel('network'); function createNetworkRequest(mimeType, content, statusCode, resourceType) { - var request = new SDK.NetworkRequest(0, 'http://localhost'); + var request = SDK.NetworkRequest.create(0, 'http://localhost'); request._resourceType = resourceType; request.mimeType = mimeType; request._contentData = Promise.resolve({error: null, content: content, encoded: false});
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-close-request-view.js b/third_party/blink/web_tests/http/tests/devtools/network/network-close-request-view.js index 9429cfd..9b3eed7 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-close-request-view.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-close-request-view.js
@@ -9,7 +9,7 @@ var target = panel._networkLogView; var types = Common.resourceTypes; - var requestFoo = new SDK.NetworkRequest('', '', '', '', ''); + var requestFoo = SDK.NetworkRequest.create('', '', '', '', ''); requestFoo.setResourceType(types.XHR); requestFoo.setRequestIdForTest('foo'); TestRunner.addResult('Showing request foo'); @@ -22,4 +22,4 @@ TestRunner.addResult('Network Item View: ' + (panel._networkItemView && panel._networkItemView.isShowing())); TestRunner.completeTest(); -})(); \ No newline at end of file +})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-cookies-pane.js b/third_party/blink/web_tests/http/tests/devtools/network/network-cookies-pane.js index 094f037..e11c983 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-cookies-pane.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-cookies-pane.js
@@ -12,7 +12,7 @@ var target = panel._networkLogView; var types = Common.resourceTypes; - var requestFoo = new SDK.NetworkRequest('', '', '', '', ''); + var requestFoo = SDK.NetworkRequest.create('', '', '', '', ''); requestFoo.setResourceType(types.XHR); requestFoo.setRequestIdForTest('foo'); requestFoo.setRequestHeaders([{name: 'Cookie', value: 'mycookie=myvalue;myother=myvalue2'}]);
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-filter-http-requests.js b/third_party/blink/web_tests/http/tests/devtools/network/network-filter-http-requests.js index b45cda7..f3ce541 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-filter-http-requests.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-filter-http-requests.js
@@ -8,7 +8,7 @@ await TestRunner.showPanel('network'); function checkURL(url) { - var request = new SDK.NetworkRequest(url, url, '', '', ''); + var request = SDK.NetworkRequest.create(url, url, '', '', ''); var result = Network.NetworkLogView.HTTPRequestsFilter(request); TestRunner.addResult((result ? '' : 'Non-') + 'HTTP request URL: ' + url); }
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-filter-updated-requests.js b/third_party/blink/web_tests/http/tests/devtools/network/network-filter-updated-requests.js index 71c431b..d49abe39 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-filter-updated-requests.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-filter-updated-requests.js
@@ -14,12 +14,12 @@ target._resourceCategoryFilterUI._toggleTypeFilter(categoryName, false); TestRunner.addResult('Clicked \'' + categoryName + '\' button.'); - var requestFoo = new SDK.NetworkRequest('', '', '', '', ''); + var requestFoo = SDK.NetworkRequest.create('', '', '', '', ''); requestFoo.setResourceType(types.Script); requestFoo.setRequestIdForTest('foo'); TestRunner.networkManager._dispatcher._startNetworkRequest(requestFoo); - var requestBar = new SDK.NetworkRequest('', '', '', '', ''); + var requestBar = SDK.NetworkRequest.create('', '', '', '', ''); requestBar.setResourceType(types.Script); requestBar.setRequestIdForTest('bar'); TestRunner.networkManager._dispatcher._startNetworkRequest(requestBar);
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-request-parse-query-params.js b/third_party/blink/web_tests/http/tests/devtools/network/network-request-parse-query-params.js index f13c85e..9884c00 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-request-parse-query-params.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-request-parse-query-params.js
@@ -9,7 +9,7 @@ function checkQuery(query) { var url = 'http://webkit.org?' + query; - var request = new SDK.NetworkRequest(url, url, '', '', ''); + var request = SDK.NetworkRequest.create(url, url, '', '', ''); TestRunner.addResult('Query: ' + request.queryString()); var params = request.queryParameters; TestRunner.addResult('Parameters: ');
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-request-query-string.js b/third_party/blink/web_tests/http/tests/devtools/network/network-request-query-string.js index a37d4ca..db35fd1af 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-request-query-string.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-request-query-string.js
@@ -8,7 +8,7 @@ await TestRunner.showPanel('network'); function checkURL(url) { - var request = new SDK.NetworkRequest(url, url, '', '', ''); + var request = SDK.NetworkRequest.create(url, url, '', '', ''); TestRunner.addResult('URL: ' + url); TestRunner.addResult('Query: ' + request.queryString()); TestRunner.addResult('');
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-serviceworker-timing-view.js b/third_party/blink/web_tests/http/tests/devtools/network/network-serviceworker-timing-view.js index 29fd7eb..835bdbf4 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-serviceworker-timing-view.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-serviceworker-timing-view.js
@@ -56,8 +56,9 @@ url: 'http://example.com/inspector-test.js', lineNumber: 117 }; - var testRequest = new SDK.NetworkRequest( - 'testRequest', 'http://example.com/inspector-test.js', 'http://example.com/fake-document-url', 1, 1, fakeInitiator); + var testRequest = SDK.NetworkRequest.create( + 'testRequest', 'http://example.com/inspector-test.js', + 'http://example.com/fake-document-url', 1, 1, fakeInitiator); setRequestValues(testRequest); const calculator = UI.panels.network._calculator;
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-update-calculator-for-all-requests.js b/third_party/blink/web_tests/http/tests/devtools/network/network-update-calculator-for-all-requests.js index 8ab1a99f..e5b686f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-update-calculator-for-all-requests.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-update-calculator-for-all-requests.js
@@ -13,7 +13,7 @@ target._reset(); function appendRequest(id, type, startTime, endTime) { - var request = new SDK.NetworkRequest('', '', '', '', ''); + var request = SDK.NetworkRequest.create('', '', '', '', ''); request.setResourceType(type); request.setRequestIdForTest(id); request.setIssueTime(startTime);
diff --git a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js index 0e7ade5..3826fea 100644 --- a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js +++ b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js
@@ -56,8 +56,9 @@ url: 'http://example.com/inspector-test.js', lineNumber: 117 }; - var testRequest = new SDK.NetworkRequest( - 'testRequest', 'http://example.com/inspector-test.js', 'http://example.com/fake-document-url', 1, 1, fakeInitiator); + var testRequest = SDK.NetworkRequest.create( + 'testRequest', 'http://example.com/inspector-test.js', + 'http://example.com/fake-document-url', 1, 1, fakeInitiator); setRequestValues(testRequest); var headersText = testRequest.requestHeadersText(); var requestResults = {
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/blank-origins-not-shown.js b/third_party/blink/web_tests/http/tests/devtools/security/blank-origins-not-shown.js index 9d0c9d0..e947f00a 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/blank-origins-not-shown.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/blank-origins-not-shown.js
@@ -7,10 +7,11 @@ await TestRunner.loadTestModule('security_test_runner'); await TestRunner.showPanel('security'); - var request1 = new SDK.NetworkRequest(0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null); + var request1 = SDK.NetworkRequest.create( + 0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null); SecurityTestRunner.dispatchRequestFinished(request1); - var request2 = new SDK.NetworkRequest( + var request2 = SDK.NetworkRequest.create( 0, 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAYAAABmBXS+AAAAPElEQVR42mNgQAMZGRn/GfABkIIdO3b8x6kQpgAEsCpEVgADKAqxKcBQCCLwARRFIBodYygiyiSCighhAO4e2jskhrm3AAAAAElFTkSuQmCC', 'https://foo.test', 0, 0, null);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/blocked-mixed-content.js b/third_party/blink/web_tests/http/tests/devtools/security/blocked-mixed-content.js index fbb5946..a34b9fd 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/blocked-mixed-content.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/blocked-mixed-content.js
@@ -14,7 +14,8 @@ Protocol.Security.SecurityState.Neutral, /* certificateSecurityState= */ null, /* safetyTipInfo= */ null, /* securityStateIssueIds= */ ['scheme-is-not-cryptographic'])); - var request = new SDK.NetworkRequest(0, 'http://foo.test', 'https://foo.test', 0, 0, null); + var request = SDK.NetworkRequest.create( + 0, 'http://foo.test', 'https://foo.test', 0, 0, null); request.setBlockedReason(Protocol.Network.BlockedReason.MixedContent); request.mixedContentType = 'blockable'; SecurityTestRunner.dispatchRequestFinished(request);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/failed-request.js b/third_party/blink/web_tests/http/tests/devtools/security/failed-request.js index 59045ff2..bb02d7d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/failed-request.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/failed-request.js
@@ -8,12 +8,14 @@ await TestRunner.loadTestModule('security_test_runner'); await TestRunner.showPanel('security'); - var request1 = new SDK.NetworkRequest(0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null); + var request1 = SDK.NetworkRequest.create( + 0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null); request1.setSecurityState(Protocol.Security.SecurityState.Secure); SecurityTestRunner.dispatchRequestFinished(request1); - var request2 = - new SDK.NetworkRequest(0, 'https://does-not-resolve.test', 'https://does-not-resolve.test', 0, 0, null); + var request2 = SDK.NetworkRequest.create( + 0, 'https://does-not-resolve.test', 'https://does-not-resolve.test', 0, 0, + null); // Leave the security state unknown. SecurityTestRunner.dispatchRequestFinished(request2);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar.js b/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar.js index 068c63f..88a91252 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/interstitial-sidebar.js
@@ -8,11 +8,13 @@ await TestRunner.loadTestModule('security_test_runner'); await TestRunner.showPanel('security'); - var request1 = new SDK.NetworkRequest(0, 'https://foo.test/', 'https://foo.test', 0, 0, null); + var request1 = SDK.NetworkRequest.create( + 0, 'https://foo.test/', 'https://foo.test', 0, 0, null); request1.setSecurityState(Protocol.Security.SecurityState.Secure); SecurityTestRunner.dispatchRequestFinished(request1); - var request2 = new SDK.NetworkRequest(0, 'https://bar.test/foo.jpg', 'https://bar.test', 0, 0, null); + var request2 = SDK.NetworkRequest.create( + 0, 'https://bar.test/foo.jpg', 'https://bar.test', 0, 0, null); request2.setSecurityState(Protocol.Security.SecurityState.Secure); SecurityTestRunner.dispatchRequestFinished(request2); @@ -23,7 +25,8 @@ TestRunner.mainTarget.model(SDK.ResourceTreeModel) .dispatchEventToListeners(SDK.ResourceTreeModel.Events.InterstitialShown); // Simulate a request finishing after the interstitial is shown, to make sure that doesn't show up in the sidebar. - var request3 = new SDK.NetworkRequest(0, 'https://bar.test/foo.jpg', 'https://bar.test', 0, 0, null); + var request3 = SDK.NetworkRequest.create( + 0, 'https://bar.test/foo.jpg', 'https://bar.test', 0, 0, null); request3.setSecurityState(Protocol.Security.SecurityState.Unknown); SecurityTestRunner.dispatchRequestFinished(request3); TestRunner.addResult('After interstitial is shown:');
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/main-origin-assigned-despite-request-missing.js b/third_party/blink/web_tests/http/tests/devtools/security/main-origin-assigned-despite-request-missing.js index ee219d74..b15ede2 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/main-origin-assigned-despite-request-missing.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/main-origin-assigned-despite-request-missing.js
@@ -26,13 +26,16 @@ TestRunner.addResult('Detected main origin: ' + detectedMainOrigin); // Send subdownload resource requests to other origins. - const request1 = new SDK.NetworkRequest(0, 'https://foo.test/favicon.ico', page_url, 0, 0, null); + const request1 = SDK.NetworkRequest.create( + 0, 'https://foo.test/favicon.ico', page_url, 0, 0, null); SecurityTestRunner.dispatchRequestFinished(request1); - const request2 = new SDK.NetworkRequest(0, 'https://bar.test/bar.css', page_url, 0, 0, null); + const request2 = SDK.NetworkRequest.create( + 0, 'https://bar.test/bar.css', page_url, 0, 0, null); SecurityTestRunner.dispatchRequestFinished(request2); // Send one request to the Same Origin as the original page to ensure it appears in the group. - const request3 = new SDK.NetworkRequest(0, detectedMainOrigin + '/favicon.ico', page_url, 0, 0, null); + const request3 = SDK.NetworkRequest.create( + 0, detectedMainOrigin + '/favicon.ico', page_url, 0, 0, null); SecurityTestRunner.dispatchRequestFinished(request3); SecurityTestRunner.dumpSecurityPanelSidebarOrigins(); TestRunner.completeTest();
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-active-and-passive-reload.js b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-active-and-passive-reload.js index 43b39ca0..dfa663b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-active-and-passive-reload.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-active-and-passive-reload.js
@@ -32,11 +32,13 @@ Security.SecurityModel.Events.VisibleSecurityStateChanged, pageVisibleSecurityState); - var passive = new SDK.NetworkRequest(0, 'http://foo.test', 'https://foo.test', 0, 0, null); + var passive = SDK.NetworkRequest.create( + 0, 'http://foo.test', 'https://foo.test', 0, 0, null); passive.mixedContentType = 'optionally-blockable'; SecurityTestRunner.dispatchRequestFinished(passive); - var active = new SDK.NetworkRequest(0, 'http://foo.test', 'https://foo.test', 0, 0, null); + var active = SDK.NetworkRequest.create( + 0, 'http://foo.test', 'https://foo.test', 0, 0, null); active.mixedContentType = 'blockable'; SecurityTestRunner.dispatchRequestFinished(active);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-reload.js b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-reload.js index 8f0e4c1..1ecb6022 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-reload.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-reload.js
@@ -32,7 +32,8 @@ Security.SecurityModel.Events.VisibleSecurityStateChanged, pageVisibleSecurityState); - var request = new SDK.NetworkRequest(0, 'http://foo.test', 'https://foo.test', 0, 0, null); + var request = SDK.NetworkRequest.create( + 0, 'http://foo.test', 'https://foo.test', 0, 0, null); request.mixedContentType = 'optionally-blockable'; SecurityTestRunner.dispatchRequestFinished(request);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar.js b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar.js index 1c8a744..6b8d4eb2 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/mixed-content-sidebar.js
@@ -16,11 +16,13 @@ Security.SecurityModel.Events.VisibleSecurityStateChanged, pageVisibleSecurityState); - var passive = new SDK.NetworkRequest(0, 'http://foo.test', 'https://foo.test', 0, 0, null); + var passive = SDK.NetworkRequest.create( + 0, 'http://foo.test', 'https://foo.test', 0, 0, null); passive.mixedContentType = 'optionally-blockable'; SecurityTestRunner.dispatchRequestFinished(passive); - var active = new SDK.NetworkRequest(0, 'http://bar.test', 'https://bar.test', 0, 0, null); + var active = SDK.NetworkRequest.create( + 0, 'http://bar.test', 'https://bar.test', 0, 0, null); active.mixedContentType = 'blockable'; SecurityTestRunner.dispatchRequestFinished(active);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-ct-compliance.js b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-ct-compliance.js index e11f8633..2e64c6d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-ct-compliance.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-ct-compliance.js
@@ -8,7 +8,8 @@ await TestRunner.loadTestModule('security_test_runner'); await TestRunner.showPanel('security'); - var request1 = new SDK.NetworkRequest(0, 'https://foo.test/', 'https://foo.test', 0, 0, null); + var request1 = SDK.NetworkRequest.create( + 0, 'https://foo.test/', 'https://foo.test', 0, 0, null); request1.setSecurityState(Protocol.Security.SecurityState.Secure); let securityDetails = {}; securityDetails.protocol = 'TLS 1.2';
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-noncryptographic-secure-origin.js b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-noncryptographic-secure-origin.js index b4da6278..93821226 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-noncryptographic-secure-origin.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-noncryptographic-secure-origin.js
@@ -8,7 +8,8 @@ await TestRunner.loadTestModule('security_test_runner'); await TestRunner.showPanel('security'); - var request1 = new SDK.NetworkRequest(0, 'chrome-test://test', 'chrome-test://test', 0, 0, null); + var request1 = SDK.NetworkRequest.create( + 0, 'chrome-test://test', 'chrome-test://test', 0, 0, null); request1.setSecurityState(Protocol.Security.SecurityState.Secure); SecurityTestRunner.dispatchRequestFinished(request1);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial.js b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial.js index 9707db8..6bb63ea 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/origin-view-then-interstitial.js
@@ -8,7 +8,8 @@ await TestRunner.loadTestModule('security_test_runner'); await TestRunner.showPanel('security'); - var request1 = new SDK.NetworkRequest(0, 'http://foo.test/', 'http://foo.test', 0, 0, null); + var request1 = SDK.NetworkRequest.create( + 0, 'http://foo.test/', 'http://foo.test', 0, 0, null); request1.setSecurityState(Protocol.Security.SecurityState.Insecure); SecurityTestRunner.dispatchRequestFinished(request1);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/security-blocked-mixed-content.js b/third_party/blink/web_tests/http/tests/devtools/security/security-blocked-mixed-content.js index a3d9e7b8..6ab072c2 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/security-blocked-mixed-content.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/security-blocked-mixed-content.js
@@ -14,7 +14,8 @@ Protocol.Security.SecurityState.Secure, /* certificateSecurityState= */ null, /* safetyTipInfo */ null, /* securityStateIssueIds= */ ['scheme-is-not-cryptographic'])); - var request = new SDK.NetworkRequest(0, 'http://foo.test', 'https://foo.test', 0, 0, null); + var request = SDK.NetworkRequest.create( + 0, 'http://foo.test', 'https://foo.test', 0, 0, null); request.setBlockedReason(Protocol.Network.BlockedReason.MixedContent); request.mixedContentType = 'blockable'; SecurityTestRunner.dispatchRequestFinished(request);
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/security-details-updated-with-security-state.js b/third_party/blink/web_tests/http/tests/devtools/security/security-details-updated-with-security-state.js index 026aa28f..2b79051 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/security-details-updated-with-security-state.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/security-details-updated-with-security-state.js
@@ -8,17 +8,20 @@ await TestRunner.showPanel('security'); // Add a request without security details. - const request1 = new SDK.NetworkRequest(0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null); + const request1 = SDK.NetworkRequest.create( + 0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null); request1.setSecurityState(Protocol.Security.SecurityState.Unknown); SecurityTestRunner.dispatchRequestFinished(request1); // Add an unrelated request. - const request2 = new SDK.NetworkRequest(0, 'https://bar.test/bar.jpg', 'https://bar.test', 0, 0, null); + const request2 = SDK.NetworkRequest.create( + 0, 'https://bar.test/bar.jpg', 'https://bar.test', 0, 0, null); request2.setSecurityState(Protocol.Security.SecurityState.Unknown); SecurityTestRunner.dispatchRequestFinished(request2); // Add a request to the first origin, this time including security details. - const request3 = new SDK.NetworkRequest(0, 'https://foo.test/foo2.jpg', 'https://foo.test', 0, 0, null); + const request3 = SDK.NetworkRequest.create( + 0, 'https://foo.test/foo2.jpg', 'https://foo.test', 0, 0, null); request3.setSecurityState(Protocol.Security.SecurityState.Secure); let securityDetails = {}; securityDetails.protocol = 'TLS 1.2';
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/security-explanation-ordering.js b/third_party/blink/web_tests/http/tests/devtools/security/security-explanation-ordering.js index fcc9d8f..cd613aaa 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/security-explanation-ordering.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/security-explanation-ordering.js
@@ -38,7 +38,8 @@ Security.SecurityModel.Events.VisibleSecurityStateChanged, pageVisibleSecurityState); - var request = new SDK.NetworkRequest(0, 'http://foo.test', 'https://foo.test', 0, 0, null); + var request = SDK.NetworkRequest.create( + 0, 'http://foo.test', 'https://foo.test', 0, 0, null); SecurityTestRunner.dispatchRequestFinished(request); var explanations =
diff --git a/third_party/blink/web_tests/http/tests/devtools/security/security-unknown-resource.js b/third_party/blink/web_tests/http/tests/devtools/security/security-unknown-resource.js index a574d68..0cf51dad 100644 --- a/third_party/blink/web_tests/http/tests/devtools/security/security-unknown-resource.js +++ b/third_party/blink/web_tests/http/tests/devtools/security/security-unknown-resource.js
@@ -8,7 +8,8 @@ await TestRunner.loadTestModule('security_test_runner'); await TestRunner.showPanel('security'); - var request = new SDK.NetworkRequest(0, 'http://unknown', 'https://foo.test', 0, 0, null); + var request = SDK.NetworkRequest.create( + 0, 'http://unknown', 'https://foo.test', 0, 0, null); SecurityTestRunner.dispatchRequestFinished(request); SecurityTestRunner.dumpSecurityPanelSidebarOrigins();
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/window-placement-origin-trial-interfaces.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/window-placement-origin-trial-interfaces.html index 2ee53dd6..915383b7 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/window-placement-origin-trial-interfaces.html +++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/window-placement-origin-trial-interfaces.html
@@ -1,9 +1,9 @@ <!DOCTYPE html> <meta charset="utf-8"> <!-- Generate token with the command: -generate_token.py http://127.0.0.1:8000 WindowPlacement --expire-timestamp=2000000000 --version 3 +generate_token.py http://127.0.0.1:8000 WindowPlacementOT2 --expire-timestamp=2000000000 --version 3 --> -<meta http-equiv="origin-trial" content="A48lmPPh6S3kN4VWiZ7ePykrQfuJ/LoBkShMtn08/du8HZR25PgQ9JJ1Ofv9szEfoV/H1JaqRd8O/4mnY8fu7QAAAABXeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2luZG93UGxhY2VtZW50IiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9" /> +<meta http-equiv="origin-trial" content="A2olqhso0OsTDx8t8ph298kXO0YKw7i06MsaVzw736c/wRA+nYG9eWETvsnNJxVa/P+R60Nxh3f5vCx1prSJnwQAAABaeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2luZG93UGxhY2VtZW50T1QyIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9" /> <title>Window Placement API - interfaces exposed by origin trial</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/virtual/isolated-animation-updates/README.md b/third_party/blink/web_tests/virtual/isolated-animation-updates/README.md new file mode 100644 index 0000000..05f2ecea --- /dev/null +++ b/third_party/blink/web_tests/virtual/isolated-animation-updates/README.md
@@ -0,0 +1 @@ +Virtual test suite for isolated animation updates, which is part of the container queries project (runtime flag: CSSIsolatedAnimationUpdates).
diff --git a/third_party/blink/web_tests/virtual/isolated-animation-updates/animations/add-keyframes-recalc-expected.txt b/third_party/blink/web_tests/virtual/isolated-animation-updates/animations/add-keyframes-recalc-expected.txt new file mode 100644 index 0000000..d53f0d7 --- /dev/null +++ b/third_party/blink/web_tests/virtual/isolated-animation-updates/animations/add-keyframes-recalc-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS Check that window.internals is defined +PASS Check that adding @keyframes does not cause a style recalc of the anim element when no animations are running. +PASS Check initial color of #anim. +FAIL Check that adding @keyframes after keyframe resolution failed, recalculates whole document assert_equals: Full document recalc. expected 11 but got 12 +PASS Check that @keyframes rule applies. +FAIL Check that adding @keyframes causes a style recalc of the #anim element when an animation is running. assert_equals: Recalc of style, script, and #anim. expected 3 but got 4 +PASS Check that the new @keyframes rule for 'later' applies. +PASS Check that adding unused @keyframes causes a style recalc of the #anim element when an animation is running. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/css/css-animations/CSSAnimation-compositeOrder.tentative-expected.txt b/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/css/css-animations/CSSAnimation-compositeOrder.tentative-expected.txt new file mode 100644 index 0000000..197eaf83 --- /dev/null +++ b/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/css/css-animations/CSSAnimation-compositeOrder.tentative-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Animations are composited by their order in the animation-name property. +PASS Web-animation replaces CSS animation +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/css/css-transitions/properties-value-inherit-001-expected.txt b/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/css/css-transitions/properties-value-inherit-001-expected.txt new file mode 100644 index 0000000..354f3ec --- /dev/null +++ b/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/css/css-transitions/properties-value-inherit-001-expected.txt
@@ -0,0 +1,564 @@ +This is a testharness.js-based test. +Found 560 tests; 548 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS background-color color(rgba) / values +PASS background-color color(rgba) / events +PASS background-position length(pt) / values +FAIL background-position length(pt) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position length(pc) / values +FAIL background-position length(pc) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position length(px) / values +FAIL background-position length(px) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position length(em) / values +FAIL background-position length(em) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position length(ex) / values +FAIL background-position length(ex) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position length(mm) / values +FAIL background-position length(mm) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position length(cm) / values +FAIL background-position length(cm) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position length(in) / values +FAIL background-position length(in) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS background-position percentage(%) / values +FAIL background-position percentage(%) / events assert_equals: Expected TransitionEnd events triggered on .container expected "background-position:2s" but got "background-position-x:2s" +PASS border-top-width length(pt) / values +PASS border-top-width length(pt) / events +PASS border-top-width length(pc) / values +PASS border-top-width length(pc) / events +PASS border-top-width length(px) / values +PASS border-top-width length(px) / events +PASS border-top-width length(em) / values +PASS border-top-width length(em) / events +PASS border-top-width length(ex) / values +PASS border-top-width length(ex) / events +PASS border-top-width length(mm) / values +PASS border-top-width length(mm) / events +PASS border-top-width length(cm) / values +PASS border-top-width length(cm) / events +PASS border-top-width length(in) / values +PASS border-top-width length(in) / events +PASS border-right-width length(pt) / values +PASS border-right-width length(pt) / events +PASS border-right-width length(pc) / values +PASS border-right-width length(pc) / events +PASS border-right-width length(px) / values +PASS border-right-width length(px) / events +PASS border-right-width length(em) / values +PASS border-right-width length(em) / events +PASS border-right-width length(ex) / values +PASS border-right-width length(ex) / events +PASS border-right-width length(mm) / values +PASS border-right-width length(mm) / events +PASS border-right-width length(cm) / values +PASS border-right-width length(cm) / events +PASS border-right-width length(in) / values +PASS border-right-width length(in) / events +PASS border-bottom-width length(pt) / values +PASS border-bottom-width length(pt) / events +PASS border-bottom-width length(pc) / values +PASS border-bottom-width length(pc) / events +PASS border-bottom-width length(px) / values +PASS border-bottom-width length(px) / events +PASS border-bottom-width length(em) / values +PASS border-bottom-width length(em) / events +PASS border-bottom-width length(ex) / values +PASS border-bottom-width length(ex) / events +PASS border-bottom-width length(mm) / values +PASS border-bottom-width length(mm) / events +PASS border-bottom-width length(cm) / values +PASS border-bottom-width length(cm) / events +PASS border-bottom-width length(in) / values +PASS border-bottom-width length(in) / events +PASS border-left-width length(pt) / values +PASS border-left-width length(pt) / events +PASS border-left-width length(pc) / values +PASS border-left-width length(pc) / events +PASS border-left-width length(px) / values +PASS border-left-width length(px) / events +PASS border-left-width length(em) / values +PASS border-left-width length(em) / events +PASS border-left-width length(ex) / values +PASS border-left-width length(ex) / events +PASS border-left-width length(mm) / values +PASS border-left-width length(mm) / events +PASS border-left-width length(cm) / values +PASS border-left-width length(cm) / events +PASS border-left-width length(in) / values +PASS border-left-width length(in) / events +PASS border-top-color color(rgba) / values +PASS border-top-color color(rgba) / events +PASS border-right-color color(rgba) / values +PASS border-right-color color(rgba) / events +PASS border-bottom-color color(rgba) / values +PASS border-bottom-color color(rgba) / events +PASS border-left-color color(rgba) / values +PASS border-left-color color(rgba) / events +PASS padding-bottom length(pt) / values +PASS padding-bottom length(pt) / events +PASS padding-bottom length(pc) / values +PASS padding-bottom length(pc) / events +PASS padding-bottom length(px) / values +PASS padding-bottom length(px) / events +PASS padding-bottom length(em) / values +PASS padding-bottom length(em) / events +PASS padding-bottom length(ex) / values +PASS padding-bottom length(ex) / events +PASS padding-bottom length(mm) / values +PASS padding-bottom length(mm) / events +PASS padding-bottom length(cm) / values +PASS padding-bottom length(cm) / events +PASS padding-bottom length(in) / values +PASS padding-bottom length(in) / events +PASS padding-left length(pt) / values +PASS padding-left length(pt) / events +PASS padding-left length(pc) / values +PASS padding-left length(pc) / events +PASS padding-left length(px) / values +PASS padding-left length(px) / events +PASS padding-left length(em) / values +PASS padding-left length(em) / events +PASS padding-left length(ex) / values +PASS padding-left length(ex) / events +PASS padding-left length(mm) / values +PASS padding-left length(mm) / events +PASS padding-left length(cm) / values +PASS padding-left length(cm) / events +PASS padding-left length(in) / values +PASS padding-left length(in) / events +PASS padding-right length(pt) / values +PASS padding-right length(pt) / events +PASS padding-right length(pc) / values +PASS padding-right length(pc) / events +PASS padding-right length(px) / values +PASS padding-right length(px) / events +PASS padding-right length(em) / values +PASS padding-right length(em) / events +PASS padding-right length(ex) / values +PASS padding-right length(ex) / events +PASS padding-right length(mm) / values +PASS padding-right length(mm) / events +PASS padding-right length(cm) / values +PASS padding-right length(cm) / events +PASS padding-right length(in) / values +PASS padding-right length(in) / events +PASS padding-top length(pt) / values +PASS padding-top length(pt) / events +PASS padding-top length(pc) / values +PASS padding-top length(pc) / events +PASS padding-top length(px) / values +PASS padding-top length(px) / events +PASS padding-top length(em) / values +PASS padding-top length(em) / events +PASS padding-top length(ex) / values +PASS padding-top length(ex) / events +PASS padding-top length(mm) / values +PASS padding-top length(mm) / events +PASS padding-top length(cm) / values +PASS padding-top length(cm) / events +PASS padding-top length(in) / values +PASS padding-top length(in) / events +PASS margin-bottom length(pt) / values +PASS margin-bottom length(pt) / events +PASS margin-bottom length(pc) / values +PASS margin-bottom length(pc) / events +PASS margin-bottom length(px) / values +PASS margin-bottom length(px) / events +PASS margin-bottom length(em) / values +PASS margin-bottom length(em) / events +PASS margin-bottom length(ex) / values +PASS margin-bottom length(ex) / events +PASS margin-bottom length(mm) / values +PASS margin-bottom length(mm) / events +PASS margin-bottom length(cm) / values +PASS margin-bottom length(cm) / events +PASS margin-bottom length(in) / values +PASS margin-bottom length(in) / events +PASS margin-left length(pt) / values +PASS margin-left length(pt) / events +PASS margin-left length(pc) / values +PASS margin-left length(pc) / events +PASS margin-left length(px) / values +PASS margin-left length(px) / events +PASS margin-left length(em) / values +PASS margin-left length(em) / events +PASS margin-left length(ex) / values +PASS margin-left length(ex) / events +PASS margin-left length(mm) / values +PASS margin-left length(mm) / events +PASS margin-left length(cm) / values +PASS margin-left length(cm) / events +PASS margin-left length(in) / values +PASS margin-left length(in) / events +PASS margin-right length(pt) / values +PASS margin-right length(pt) / events +PASS margin-right length(pc) / values +PASS margin-right length(pc) / events +PASS margin-right length(px) / values +PASS margin-right length(px) / events +PASS margin-right length(em) / values +PASS margin-right length(em) / events +PASS margin-right length(ex) / values +PASS margin-right length(ex) / events +PASS margin-right length(mm) / values +PASS margin-right length(mm) / events +PASS margin-right length(cm) / values +PASS margin-right length(cm) / events +PASS margin-right length(in) / values +PASS margin-right length(in) / events +PASS margin-top length(pt) / values +PASS margin-top length(pt) / events +PASS margin-top length(pc) / values +PASS margin-top length(pc) / events +PASS margin-top length(px) / values +PASS margin-top length(px) / events +PASS margin-top length(em) / values +PASS margin-top length(em) / events +PASS margin-top length(ex) / values +PASS margin-top length(ex) / events +PASS margin-top length(mm) / values +PASS margin-top length(mm) / events +PASS margin-top length(cm) / values +PASS margin-top length(cm) / events +PASS margin-top length(in) / values +PASS margin-top length(in) / events +PASS height length(pt) / values +PASS height length(pt) / events +PASS height length(pc) / values +PASS height length(pc) / events +PASS height length(px) / values +PASS height length(px) / events +PASS height length(em) / values +PASS height length(em) / events +PASS height length(ex) / values +PASS height length(ex) / events +PASS height length(mm) / values +PASS height length(mm) / events +PASS height length(cm) / values +PASS height length(cm) / events +PASS height length(in) / values +PASS height length(in) / events +PASS height percentage(%) / values +PASS height percentage(%) / events +PASS width length(pt) / values +PASS width length(pt) / events +PASS width length(pc) / values +PASS width length(pc) / events +PASS width length(px) / values +PASS width length(px) / events +PASS width length(em) / values +PASS width length(em) / events +PASS width length(ex) / values +PASS width length(ex) / events +PASS width length(mm) / values +PASS width length(mm) / events +PASS width length(cm) / values +PASS width length(cm) / events +PASS width length(in) / values +PASS width length(in) / events +PASS width percentage(%) / values +PASS width percentage(%) / events +PASS min-height length(pt) / values +PASS min-height length(pt) / events +PASS min-height length(pc) / values +PASS min-height length(pc) / events +PASS min-height length(px) / values +PASS min-height length(px) / events +PASS min-height length(em) / values +PASS min-height length(em) / events +PASS min-height length(ex) / values +PASS min-height length(ex) / events +PASS min-height length(mm) / values +PASS min-height length(mm) / events +PASS min-height length(cm) / values +PASS min-height length(cm) / events +PASS min-height length(in) / values +PASS min-height length(in) / events +PASS min-height percentage(%) / values +PASS min-height percentage(%) / events +PASS min-width length(pt) / values +PASS min-width length(pt) / events +PASS min-width length(pc) / values +PASS min-width length(pc) / events +PASS min-width length(px) / values +PASS min-width length(px) / events +PASS min-width length(em) / values +PASS min-width length(em) / events +PASS min-width length(ex) / values +PASS min-width length(ex) / events +PASS min-width length(mm) / values +PASS min-width length(mm) / events +PASS min-width length(cm) / values +PASS min-width length(cm) / events +PASS min-width length(in) / values +PASS min-width length(in) / events +PASS min-width percentage(%) / values +PASS min-width percentage(%) / events +PASS max-height length(pt) / values +PASS max-height length(pt) / events +PASS max-height length(pc) / values +PASS max-height length(pc) / events +PASS max-height length(px) / values +PASS max-height length(px) / events +PASS max-height length(em) / values +PASS max-height length(em) / events +PASS max-height length(ex) / values +PASS max-height length(ex) / events +PASS max-height length(mm) / values +PASS max-height length(mm) / events +PASS max-height length(cm) / values +PASS max-height length(cm) / events +PASS max-height length(in) / values +PASS max-height length(in) / events +PASS max-height percentage(%) / values +PASS max-height percentage(%) / events +PASS max-width length(pt) / values +PASS max-width length(pt) / events +PASS max-width length(pc) / values +PASS max-width length(pc) / events +PASS max-width length(px) / values +PASS max-width length(px) / events +PASS max-width length(em) / values +PASS max-width length(em) / events +PASS max-width length(ex) / values +PASS max-width length(ex) / events +PASS max-width length(mm) / values +PASS max-width length(mm) / events +PASS max-width length(cm) / values +PASS max-width length(cm) / events +PASS max-width length(in) / values +PASS max-width length(in) / events +PASS max-width percentage(%) / values +PASS max-width percentage(%) / events +PASS top length(pt) / values +PASS top length(pt) / events +PASS top length(pc) / values +PASS top length(pc) / events +PASS top length(px) / values +PASS top length(px) / events +PASS top length(em) / values +PASS top length(em) / events +PASS top length(ex) / values +PASS top length(ex) / events +PASS top length(mm) / values +PASS top length(mm) / events +PASS top length(cm) / values +PASS top length(cm) / events +PASS top length(in) / values +PASS top length(in) / events +PASS top percentage(%) / values +PASS top percentage(%) / events +PASS right length(pt) / values +PASS right length(pt) / events +PASS right length(pc) / values +PASS right length(pc) / events +PASS right length(px) / values +PASS right length(px) / events +PASS right length(em) / values +PASS right length(em) / events +PASS right length(ex) / values +PASS right length(ex) / events +PASS right length(mm) / values +PASS right length(mm) / events +PASS right length(cm) / values +PASS right length(cm) / events +PASS right length(in) / values +PASS right length(in) / events +PASS right percentage(%) / values +PASS right percentage(%) / events +PASS bottom length(pt) / values +PASS bottom length(pt) / events +PASS bottom length(pc) / values +PASS bottom length(pc) / events +PASS bottom length(px) / values +PASS bottom length(px) / events +PASS bottom length(em) / values +PASS bottom length(em) / events +PASS bottom length(ex) / values +PASS bottom length(ex) / events +PASS bottom length(mm) / values +PASS bottom length(mm) / events +PASS bottom length(cm) / values +PASS bottom length(cm) / events +PASS bottom length(in) / values +PASS bottom length(in) / events +PASS bottom percentage(%) / values +PASS bottom percentage(%) / events +PASS left length(pt) / values +PASS left length(pt) / events +PASS left length(pc) / values +PASS left length(pc) / events +PASS left length(px) / values +PASS left length(px) / events +PASS left length(em) / values +PASS left length(em) / events +PASS left length(ex) / values +PASS left length(ex) / events +PASS left length(mm) / values +PASS left length(mm) / events +PASS left length(cm) / values +PASS left length(cm) / events +PASS left length(in) / values +PASS left length(in) / events +PASS left percentage(%) / values +PASS left percentage(%) / events +PASS color color(rgba) / values +PASS color color(rgba) / events +PASS font-size length(pt) / values +PASS font-size length(pt) / events +PASS font-size length(pc) / values +PASS font-size length(pc) / events +PASS font-size length(px) / values +PASS font-size length(px) / events +PASS font-size length(em) / values +PASS font-size length(em) / events +PASS font-size length(ex) / values +PASS font-size length(ex) / events +PASS font-size length(mm) / values +PASS font-size length(mm) / events +PASS font-size length(cm) / values +PASS font-size length(cm) / events +PASS font-size length(in) / values +PASS font-size length(in) / events +PASS font-size percentage(%) / values +PASS font-size percentage(%) / events +PASS font-weight font-weight(keyword) / values +PASS font-weight font-weight(keyword) / events +PASS font-weight font-weight(numeric) / values +PASS font-weight font-weight(numeric) / events +PASS line-height number(integer) / values +PASS line-height number(integer) / events +PASS line-height number(decimal) / values +PASS line-height number(decimal) / events +PASS line-height length(pt) / values +PASS line-height length(pt) / events +PASS line-height length(pc) / values +PASS line-height length(pc) / events +PASS line-height length(px) / values +PASS line-height length(px) / events +PASS line-height length(em) / values +PASS line-height length(em) / events +PASS line-height length(ex) / values +PASS line-height length(ex) / events +PASS line-height length(mm) / values +PASS line-height length(mm) / events +PASS line-height length(cm) / values +PASS line-height length(cm) / events +PASS line-height length(in) / values +PASS line-height length(in) / events +PASS line-height percentage(%) / values +PASS line-height percentage(%) / events +PASS letter-spacing length(pt) / values +PASS letter-spacing length(pt) / events +PASS letter-spacing length(pc) / values +PASS letter-spacing length(pc) / events +PASS letter-spacing length(px) / values +PASS letter-spacing length(px) / events +PASS letter-spacing length(em) / values +PASS letter-spacing length(em) / events +PASS letter-spacing length(ex) / values +PASS letter-spacing length(ex) / events +PASS letter-spacing length(mm) / values +PASS letter-spacing length(mm) / events +PASS letter-spacing length(cm) / values +PASS letter-spacing length(cm) / events +PASS letter-spacing length(in) / values +PASS letter-spacing length(in) / events +PASS word-spacing length(pt) / values +PASS word-spacing length(pt) / events +PASS word-spacing length(pc) / values +PASS word-spacing length(pc) / events +PASS word-spacing length(px) / values +PASS word-spacing length(px) / events +PASS word-spacing length(em) / values +PASS word-spacing length(em) / events +PASS word-spacing length(ex) / values +PASS word-spacing length(ex) / events +PASS word-spacing length(mm) / values +PASS word-spacing length(mm) / events +PASS word-spacing length(cm) / values +PASS word-spacing length(cm) / events +PASS word-spacing length(in) / values +PASS word-spacing length(in) / events +FAIL word-spacing percentage(%) / values assert_not_equals: initial and target values may not match got disallowed value "0px" +FAIL word-spacing percentage(%) / events assert_equals: Expected TransitionEnd events triggered on .container expected "word-spacing:2s" but got "" +PASS text-indent length(pt) / values +PASS text-indent length(pt) / events +PASS text-indent length(pc) / values +PASS text-indent length(pc) / events +PASS text-indent length(px) / values +PASS text-indent length(px) / events +PASS text-indent length(em) / values +PASS text-indent length(em) / events +PASS text-indent length(ex) / values +PASS text-indent length(ex) / events +PASS text-indent length(mm) / values +PASS text-indent length(mm) / events +PASS text-indent length(cm) / values +PASS text-indent length(cm) / events +PASS text-indent length(in) / values +PASS text-indent length(in) / events +PASS text-indent percentage(%) / values +PASS text-indent percentage(%) / events +PASS text-shadow shadow(shadow) / values +PASS text-shadow shadow(shadow) / events +PASS outline-color color(rgba) / values +PASS outline-color color(rgba) / events +PASS outline-offset length(pt) / values +PASS outline-offset length(pt) / events +PASS outline-offset length(pc) / values +PASS outline-offset length(pc) / events +PASS outline-offset length(px) / values +PASS outline-offset length(px) / events +PASS outline-offset length(em) / values +PASS outline-offset length(em) / events +PASS outline-offset length(ex) / values +PASS outline-offset length(ex) / events +PASS outline-offset length(mm) / values +PASS outline-offset length(mm) / events +PASS outline-offset length(cm) / values +PASS outline-offset length(cm) / events +PASS outline-offset length(in) / values +PASS outline-offset length(in) / events +PASS outline-width length(pt) / values +PASS outline-width length(pt) / events +PASS outline-width length(pc) / values +PASS outline-width length(pc) / events +PASS outline-width length(px) / values +PASS outline-width length(px) / events +PASS outline-width length(em) / values +PASS outline-width length(em) / events +PASS outline-width length(ex) / values +PASS outline-width length(ex) / events +PASS outline-width length(mm) / values +PASS outline-width length(mm) / events +PASS outline-width length(cm) / values +PASS outline-width length(cm) / events +PASS outline-width length(in) / values +PASS outline-width length(in) / events +PASS clip rectangle(rectangle) / values +PASS clip rectangle(rectangle) / events +PASS vertical-align length(pt) / values +PASS vertical-align length(pt) / events +PASS vertical-align length(pc) / values +PASS vertical-align length(pc) / events +PASS vertical-align length(px) / values +PASS vertical-align length(px) / events +PASS vertical-align length(em) / values +PASS vertical-align length(em) / events +PASS vertical-align length(ex) / values +PASS vertical-align length(ex) / events +PASS vertical-align length(mm) / values +PASS vertical-align length(mm) / events +PASS vertical-align length(cm) / values +PASS vertical-align length(cm) / events +PASS vertical-align length(in) / values +PASS vertical-align length(in) / events +PASS vertical-align percentage(%) / values +PASS vertical-align percentage(%) / events +PASS opacity number[0,1](zero-to-one) / values +PASS opacity number[0,1](zero-to-one) / events +PASS visibility visibility(keyword) / values +FAIL visibility visibility(keyword) / events assert_equals: Expected TransitionEnd events triggered on .transition expected "" but got "visibility:2s" +PASS z-index integer(integer) / values +PASS z-index integer(integer) / events +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/scroll-animations/css/at-scroll-timeline-dynamic.tentative-expected.txt b/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/scroll-animations/css/at-scroll-timeline-dynamic.tentative-expected.txt new file mode 100644 index 0000000..8dc99835 --- /dev/null +++ b/third_party/blink/web_tests/virtual/isolated-animation-updates/external/wpt/scroll-animations/css/at-scroll-timeline-dynamic.tentative-expected.txt
@@ -0,0 +1,23 @@ +This is a testharness.js-based test. +PASS Switching between document and scroll timelines [immediate] +PASS Switching between document and scroll timelines [scroll] +PASS Changing computed value of animation-timeline changes effective timeline [immediate] +PASS Changing computed value of animation-timeline changes effective timeline [scroll] +FAIL Changing to/from animation-timeline:none [immediate] assert_equals: expected "0px" but got "100px" +PASS Changing to/from animation-timeline:none [scroll] +PASS Changing the source descriptor switches effective timeline [immediate] +PASS Changing the source descriptor switches effective timeline [scroll] +PASS Changing the time-range descriptor switches effective timeline [immediate] +PASS Changing the time-range descriptor switches effective timeline [scroll] +PASS Changing the start descriptor switches effective timeline [immediate] +PASS Changing the start descriptor switches effective timeline [scroll] +PASS Changing the end descriptor switches effective timeline [immediate] +PASS Changing the end descriptor switches effective timeline [scroll] +PASS Reverse animation direction [immediate] +PASS Reverse animation direction [scroll] +PASS Switching timelines while paused [immediate] +PASS Switching timelines while paused [scroll] +PASS Switching timelines and pausing at the same time [immediate] +PASS Switching timelines and pausing at the same time [scroll] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl b/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl index 94743c6b..0ca52542 100644 --- a/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl +++ b/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl
@@ -55,4 +55,12 @@ 'wpt_internal/webgpu/cts.html?q=webgpu:api,operation,vertex_state,correctness:setVertexBufferOffset_and_attributeOffset:format="uint8x2";*', 'wpt_internal/webgpu/cts.html?q=webgpu:api,operation,vertex_state,correctness:nonZeroArrayStride_and_attributeOffset:format="uint8x2";*', + + 'wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read";access="read";atomic=false;baseType="i32";*', + 'wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read";access="read";atomic=false;baseType="u32";*', + 'wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read";access="read";atomic=false;baseType="f32";*', + 'wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=false;baseType="i32";*', + 'wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=false;baseType="u32";*', + 'wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=false;baseType="f32";*', + 'wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=true;*', ]
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html index 6f57cb0..225e5adc 100644 --- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html +++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html
@@ -46,6 +46,7 @@ <meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:request_default_after_error:*'> <meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,write:*'> +<meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,write,unchanged_ranges_preserved:*'> <meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,read:*'> <meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,read,typedArrayAccess:*'> <meta name=variant content='?q=webgpu:api,operation,buffers,map:mappedAtCreation:*'> @@ -722,6 +723,20 @@ <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,dynamic_state:setScissorRect,xy_rect_contained_in_attachment:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,dynamic_state:setBlendConstant:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,dynamic_state:setStencilReference:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,indirect_draw:indirect_buffer:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,indirect_draw:indirect_buffer_usage:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,indirect_draw:indirect_offset_alignment:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,indirect_draw:indirect_offset_oob:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setIndexBuffer:index_buffer:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setIndexBuffer:index_buffer_usage:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setIndexBuffer:offset_alignment:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setIndexBuffer:offset_and_size_oob:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setPipeline:invalid_pipeline:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setVertexBuffer:slot:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setVertexBuffer:vertex_buffer:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setVertexBuffer:vertex_buffer_usage:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setVertexBuffer:offset_alignment:*'> +<meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,setVertexBuffer:offset_and_size_oob:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,state_tracking:vertex_buffers_inherit_from_previous_pipeline:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,render,state_tracking:vertex_buffers_do_not_inherit_between_render_passes:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,setBindGroup:state_and_binding_index:*'> @@ -855,6 +870,19 @@ <meta name=variant content='?q=webgpu:idl,constants,flags:ColorWrite,values:*'> <meta name=variant content='?q=webgpu:idl,constants,flags:ShaderStage,count:*'> <meta name=variant content='?q=webgpu:idl,constants,flags:ShaderStage,values:*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read";access="read";atomic=false;baseType="i32";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read";access="read";atomic=false;baseType="u32";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read";access="read";atomic=false;baseType="f32";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="write";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=false;baseType="i32";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=false;baseType="u32";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=false;baseType="f32";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="read";atomic=true;*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="storage";storageMode="read_write";access="write";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="uniform";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="private";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="function";*'> +<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:storageClass="workgroup";*'> <meta name=variant content='?q=webgpu:shader,execution,robust_access_vertex:vertexAccess:indexed=false;indirect=false;*'> <meta name=variant content='?q=webgpu:shader,execution,robust_access_vertex:vertexAccess:indexed=false;indirect=true;*'> <meta name=variant content='?q=webgpu:shader,execution,robust_access_vertex:vertexAccess:indexed=true;indirect=false;*'>
diff --git a/third_party/r8/3pp/3pp.pb b/third_party/r8/3pp/3pp.pb index 54909960..ef9c4ba 100644 --- a/third_party/r8/3pp/3pp.pb +++ b/third_party/r8/3pp/3pp.pb
@@ -5,7 +5,6 @@ tag_pattern: "%s-dev" } patch_dir: "patches" - patch_version: "alpha" } build {
diff --git a/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch b/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch index 0b9e8792..32ed2a600 100644 --- a/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch +++ b/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch
@@ -1,7 +1,7 @@ -From 35ed636e46ee1be966b5e4ac3557403d4f8b3fae Mon Sep 17 00:00:00 2001 +From 60780034d9ef3d627b16725c197403a5fe1b6a27 Mon Sep 17 00:00:00 2001 From: Andrew Grieve <agrieve@chromium.org> Date: Mon, 1 Feb 2021 15:09:52 -0500 -Subject: [PATCH 1/5] Statefull lambdas regress dex size. +Subject: [PATCH 1/4] Statefull lambdas regress dex size. Bug: b/129997269 --- @@ -23,5 +23,5 @@ // Synthesize virtual methods. -- -2.32.0.93.g670b81a890-goog +2.32.0.288.g62a8d224e6-goog
diff --git a/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch b/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch index 0d3af40..0dd13d5 100644 --- a/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch +++ b/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch
@@ -1,7 +1,7 @@ -From ad3675346cba5227c6f4b4d334340601cfe42853 Mon Sep 17 00:00:00 2001 +From 4ab201427d83f47fda9dba7b6ef79b9cef6d7c2c Mon Sep 17 00:00:00 2001 From: Andrew Grieve <agrieve@chromium.org> Date: Wed, 21 Oct 2020 10:59:42 -0400 -Subject: [PATCH 2/5] Allow access modification everywhere +Subject: [PATCH 2/4] Allow access modification everywhere Chrome does not need need -keep to maintain original visibility. Loosening this constraint allows for better optimization, and is easier @@ -11,7 +11,7 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java -index 68b7e13b1..886f630a1 100644 +index 2ff90085c..0e0acd581 100644 --- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java +++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java @@ -953,7 +953,7 @@ public class AppInfoWithLiveness extends AppInfoWithClassHierarchy @@ -24,5 +24,5 @@ public boolean isRepackagingAllowed(DexProgramClass clazz) { -- -2.32.0.93.g670b81a890-goog +2.32.0.288.g62a8d224e6-goog
diff --git a/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch b/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch index 14ec68f..aec0a9e0 100644 --- a/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch +++ b/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch
@@ -1,7 +1,7 @@ -From 78629559e44a09acd689452cad3634a70933301e Mon Sep 17 00:00:00 2001 +From bc79e6d9c90e8586d841ddf9cdfaaf591c33996d Mon Sep 17 00:00:00 2001 From: Mohamed Heikal <mheikal@google.com> Date: Wed, 26 May 2021 19:03:39 -0400 -Subject: [PATCH 3/5] Add disassemble command to keeps +Subject: [PATCH 3/4] Add disassemble command to keeps --- src/main/keep.txt | 1 + @@ -20,5 +20,5 @@ -keep public class com.android.tools.r8.dexsplitter.DexSplitter { public static void main(java.lang.String[]); } -- -2.32.0.93.g670b81a890-goog +2.32.0.288.g62a8d224e6-goog
diff --git a/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch b/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch index 28649aa..0781a3e 100644 --- a/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch +++ b/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch
@@ -1,7 +1,7 @@ -From 1a7ca4f116f86104a772705433a12f91a7d6a08f Mon Sep 17 00:00:00 2001 +From ca66a211ce82c330257d9ca94dcca4c644cb4674 Mon Sep 17 00:00:00 2001 From: Andrew Grieve <agrieve@chromium.org> Date: Wed, 23 Jun 2021 21:53:35 -0400 -Subject: [PATCH 4/5] Disable useDexPcAsDebugInformation +Subject: [PATCH 4/4] Disable useDexPcAsDebugInformation useDexPcAsDebugInformation breaks deobfuscation, but would be great to turn on. @@ -11,10 +11,10 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java -index c17a6ac6e..f20be9f49 100644 +index e82e04d90..03bab9255 100644 --- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java +++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java -@@ -1718,7 +1718,7 @@ public class InternalOptions implements GlobalKeepInfoConfiguration { +@@ -1704,7 +1704,7 @@ public class InternalOptions implements GlobalKeepInfoConfiguration { } public boolean canUseDexPcAsDebugInformation() { @@ -24,5 +24,5 @@ public boolean isInterfaceMethodDesugaringEnabled() { -- -2.32.0.93.g670b81a890-goog +2.32.0.288.g62a8d224e6-goog
diff --git a/third_party/r8/3pp/patches/0005-Change-PushableEnqueuerWorkList-backing-to-Concurren.patch b/third_party/r8/3pp/patches/0005-Change-PushableEnqueuerWorkList-backing-to-Concurren.patch deleted file mode 100644 index 17c0928e..0000000 --- a/third_party/r8/3pp/patches/0005-Change-PushableEnqueuerWorkList-backing-to-Concurren.patch +++ /dev/null
@@ -1,38 +0,0 @@ -From ffba24c4288a3f7c8ee1d2d43c92c82c29e077fb Mon Sep 17 00:00:00 2001 -From: Morten Krogh-Jespersen <mkroghj@google.com> -Date: Wed, 7 Jul 2021 16:37:56 +0200 -Subject: [PATCH 5/5] Change PushableEnqueuerWorkList backing to - ConcurrentLinkedQueue - -Bug: 193003098 -Change-Id: If667bb01502dad0efec7a16aea1b1aa93bfbaffb ---- - .../java/com/android/tools/r8/shaking/EnqueuerWorklist.java | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java -index 47684370e..2fcac5531 100644 ---- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java -+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java -@@ -18,8 +18,8 @@ import com.android.tools.r8.shaking.GraphReporter.KeepReasonWitness; - import com.android.tools.r8.utils.Action; - import com.android.tools.r8.utils.InternalOptions; - import com.android.tools.r8.utils.collections.ProgramMethodSet; --import java.util.ArrayDeque; - import java.util.Queue; -+import java.util.concurrent.ConcurrentLinkedQueue; - - public abstract class EnqueuerWorklist { - -@@ -369,7 +369,7 @@ public abstract class EnqueuerWorklist { - static class PushableEnqueuerWorkList extends EnqueuerWorklist { - - PushableEnqueuerWorkList(Enqueuer enqueuer) { -- super(enqueuer, new ArrayDeque<>()); -+ super(enqueuer, new ConcurrentLinkedQueue<>()); - } - - @Override --- -2.32.0.93.g670b81a890-goog -
diff --git a/third_party/r8/README.chromium b/third_party/r8/README.chromium index b2cbac0e..dc99df65 100644 --- a/third_party/r8/README.chromium +++ b/third_party/r8/README.chromium
@@ -1,6 +1,6 @@ Name: R8 URL: https://r8.googlesource.com/r8 -Version: 3.1.2-dev +Version: 3.1.13.alpha License: BSD 3-Clause License File: NOT_SHIPPED Security Critical: no
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt index a042808..590e6e8 100644 --- a/third_party/webgpu-cts/ts_sources.txt +++ b/third_party/webgpu-cts/ts_sources.txt
@@ -37,6 +37,7 @@ src/common/tools/gen_wpt_cts_html.ts src/common/tools/version.ts src/common/util/collect_garbage.ts +src/common/util/data_tables.ts src/common/util/preprocessor.ts src/unittests/unit_test.ts src/demo/a.spec.ts @@ -163,7 +164,11 @@ src/webgpu/api/validation/encoding/cmds/render_pass.spec.ts src/webgpu/api/validation/encoding/cmds/setBindGroup.spec.ts src/webgpu/api/validation/encoding/cmds/render/dynamic_state.spec.ts -src/webgpu/api/validation/encoding/cmds/render/other.spec.ts +src/webgpu/api/validation/encoding/cmds/render/render.ts +src/webgpu/api/validation/encoding/cmds/render/indirect_draw.spec.ts +src/webgpu/api/validation/encoding/cmds/render/setIndexBuffer.spec.ts +src/webgpu/api/validation/encoding/cmds/render/setPipeline.spec.ts +src/webgpu/api/validation/encoding/cmds/render/setVertexBuffer.spec.ts src/webgpu/api/validation/encoding/cmds/render/state_tracking.spec.ts src/webgpu/api/validation/encoding/programmable/pipeline_bind_group_compat.spec.ts src/webgpu/api/validation/encoding/queries/common.ts @@ -191,6 +196,8 @@ src/webgpu/api/validation/texture/destroy.spec.ts src/webgpu/idl/idl_test.ts src/webgpu/idl/constants/flags.spec.ts +src/webgpu/shader/types.ts +src/webgpu/shader/execution/robust_access.spec.ts src/webgpu/shader/execution/robust_access_vertex.spec.ts src/webgpu/shader/validation/shader_validation_test.ts src/webgpu/shader/validation/variable_and_const.spec.ts
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index a17d7775..fc83122 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -1130,7 +1130,10 @@ # because the asan install changes library RPATHs which CMake only # supports on ELF platforms and MacOS uses Mach-O instead of ELF. if sys.platform != 'darwin': - fuchsia_args.append('-DCOMPILER_RT_BUILD_SANITIZERS=ON') + fuchsia_args.extend([ + '-DCOMPILER_RT_BUILD_SANITIZERS=ON', + '-DSANITIZER_NO_UNDEFINED_SYMBOLS=OFF', + ]) build_phase2_dir = os.path.join(LLVM_BUILD_DIR, 'fuchsia-phase2-' + target_arch) if not os.path.exists(build_phase2_dir): @@ -1140,16 +1143,16 @@ fuchsia_args + [COMPILER_RT_DIR]) profile_a = 'libclang_rt.profile.a' - asan_a = 'libclang_rt.asan.a' + asan_so = 'libclang_rt.asan.so' ninja_command = ['ninja', profile_a] if sys.platform != 'darwin': - ninja_command.append(asan_a) + ninja_command.append(asan_so) RunCommand(ninja_command) CopyFile(os.path.join(build_phase2_dir, 'lib', target_spec, profile_a), fuchsia_lib_dst_dir) if sys.platform != 'darwin': - CopyFile(os.path.join(build_phase2_dir, 'lib', target_spec, asan_a), - fuchsia_lib_dst_dir) + CopyFile(os.path.join(build_phase2_dir, 'lib', target_spec, asan_so), + fuchsia_lib_dst_dir) # Run tests. if (not args.build_mac_arm and
diff --git a/tools/clang/scripts/goma_link.py b/tools/clang/scripts/goma_link.py index 9beecb3..a101dc9 100755 --- a/tools/clang/scripts/goma_link.py +++ b/tools/clang/scripts/goma_link.py
@@ -229,10 +229,11 @@ FUNCTION_SECTIONS_RE = re.compile('-f(no-)?function-sections|[-/]Gy(-)?', re.IGNORECASE) LIB_RE = re.compile('.*\\.(?:a|lib)', re.IGNORECASE) + # LTO_RE matches flags we want to pass in the thin link step but not in the + # native link step. + # Continue to pass -flto and -fsanitize flags in the native link even though + # they're not normally necessary because clang needs them to build with CFI. LTO_RE = re.compile('|'.join(( - '-fsanitize=cfi.*', - '-flto.*', - '-fthin.*', '-Wl,-plugin-opt=.*', '-Wl,--lto.*', '-Wl,--thin.*',
diff --git a/tools/clang/scripts/goma_link_unit_tests.py b/tools/clang/scripts/goma_link_unit_tests.py index d792b59f..711f37b 100755 --- a/tools/clang/scripts/goma_link_unit_tests.py +++ b/tools/clang/scripts/goma_link_unit_tests.py
@@ -123,7 +123,7 @@ self.assertNotIn('-fwhole-program-vtables', result.codegen_params) self.assertNotIn('-fsanitize=cfi', result.codegen_params) - self.assertNotIn('-flto=thin', result.final_params) + self.assertIn('-flto=thin', result.final_params) def test_codegen_params_default(self): with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']):
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py index e02dd5ce..7234723 100755 --- a/tools/clang/scripts/package.py +++ b/tools/clang/scripts/package.py
@@ -255,7 +255,7 @@ want.append('lib/clang/$V/lib/x86_64-unknown-fuchsia/libclang_rt.profile.a') if sys.platform != 'darwin': # The Fuchsia asan runtime is only built on non-Mac platforms. - want.append('lib/clang/$V/lib/x86_64-unknown-fuchsia/libclang_rt.asan.a') + want.append('lib/clang/$V/lib/x86_64-unknown-fuchsia/libclang_rt.asan.so') if sys.platform == 'darwin': want.extend([ # AddressSanitizer runtime.
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index a2cf0fe0..0fc9f042 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -40,7 +40,7 @@ # Reverting problematic clang rolls is safe, though. # This is the output of `git describe` and is usable as a commit-ish. CLANG_REVISION = 'llvmorg-13-init-14732-g8a7b5ebf' -CLANG_SUB_REVISION = 1 +CLANG_SUB_REVISION = 2 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION) RELEASE_VERSION = '13.0.0'
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 75ab0faf..f12bc77b 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -111,6 +111,7 @@ 'Android arm64 Builder (dbg) (reclient)': 'android_webview_google_debug_static_bot_arm64_reclient', 'Android WebView P FYI (rel)': 'android_release_bot_minimal_symbols_arm64_webview_google', 'android-11-x86-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_google', + 'android-12-x64-fyi-rel': 'android_release_bot_minimal_symbols_x64_fastbuild_webview_google', 'android-pie-arm64-wpt-rel-non-cq': 'android_release_bot_minimal_symbols_arm64_webview_google', 'android-web-platform-pie-x86-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_google', 'android-weblayer-pie-x86-wpt-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_google', @@ -735,7 +736,7 @@ 'chromeos-betty-pi-arc-chrome-dchecks': 'chromeos_betty-pi-arc_dchecks', 'chromeos-eve-arc-r-chrome': 'chromeos_eve-arc-r_include_unwind_tables_official', 'lacros-amd64-generic-chrome-fyi': 'chromeos_amd64-generic_lacros_official_skylab', - 'lacros-arm-generic-chrome-fyi': 'chromeos_arm-generic_lacros_official', + 'lacros-arm-generic-chrome-fyi': 'chromeos_arm-generic_lacros_official_skylab', }, # Manually triggered internal builders running on LUCI. @@ -816,6 +817,7 @@ 'android-webview-pie-arm64-fyi-rel': 'android_release_trybot_arm64_webview_google', 'android-10-arm64-rel': 'android_release_trybot_arm64_fastbuild_webview_google', 'android-11-x86-fyi-rel': 'android_release_trybot_x86_fastbuild_webview_google', + 'android-12-x64-fyi-rel': 'android_release_trybot_x64_fastbuild_webview_google', 'android-webview-marshmallow-arm64-dbg': 'android_release_trybot_arm64_webview_google', 'android-webview-nougat-arm64-dbg': 'android_release_trybot_arm64_webview_google', 'android-webview-oreo-arm64-dbg': 'android_release_trybot_arm64_webview_google', @@ -1439,6 +1441,11 @@ 'webview_google', ], + 'android_release_bot_minimal_symbols_x64_fastbuild_webview_google': [ + 'android', 'release_bot', 'minimal_symbols', 'x64', + 'strip_debug_info', 'android_fastbuild', 'webview_google', + ], + 'android_release_bot_minimal_symbols_x86_fastbuild_resource_allowlisting_disable_proguard_chrome_google': [ 'android', 'release_bot', 'minimal_symbols', 'android_fastbuild', 'x86', 'resource_allowlisting', 'disable_proguard', @@ -1521,6 +1528,11 @@ 'chrome_google' ], + 'android_release_trybot_x64_fastbuild_webview_google': [ + 'android', 'release_trybot', 'strip_debug_info', 'x64', + 'android_fastbuild', 'webview_google', + ], + 'android_release_trybot_x86_fastbuild_resource_allowlisting_webview_google': [ 'android', 'release_trybot', 'x86', 'android_fastbuild', 'resource_allowlisting', 'webview_google', @@ -1781,6 +1793,10 @@ 'chromeos_arm-generic', 'arm-lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto', ], + 'chromeos_arm-generic_lacros_official_skylab': [ + 'chromeos_arm-generic', 'arm-lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto', 'is_skylab', + ], + 'chromeos_arm-generic_lacros_rel': [ 'chromeos_arm-generic', 'arm-lacros', ], @@ -2446,7 +2462,7 @@ ], 'official_goma_android_arm32_pgo': [ - 'official', 'goma', 'android_official', 'arm', 'pgo_phase_1', + 'official', 'goma', 'android', 'arm', 'minimal_symbols', 'no_default_afdo', 'pgo_phase_1', ], 'official_goma_mac': [ @@ -2857,15 +2873,6 @@ 'gn_args': 'is_java_debug=true', }, - 'android_official': { - 'mixins': ['android', 'android_official_webview_target', 'android_without_codecs', 'clank_custom_args', 'enable_remoting', 'enable_webview_bundles', 'ffmpeg_branding_chrome', 'official'], - 'gn_args': 'use_signing_keys=true' - }, - - 'android_official_webview_target': { - 'gn_args': 'system_webview_apk_target="//clank/android_webview:system_webview_google_apk"', - }, - 'android_without_codecs': { 'gn_args': 'target_os="android"', }, @@ -3016,10 +3023,6 @@ 'gn_args': 'is_clang=true', }, - 'clank_custom_args': { - 'args_file': '//clank/build/custom_args.gn', - }, - # Settings used by the codesearch builders to generate cross-references. 'codesearch': { 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', @@ -3140,10 +3143,6 @@ 'gn_args': 'skip_archive_compression=false', }, - 'enable_remoting': { - 'gn_args': 'enable_remoting=true', - }, - 'enable_v8_oilpan': { 'gn_args': 'enable_blink_heap_use_v8_oilpan=true', }, @@ -3160,10 +3159,6 @@ 'gn_args': 'enable_vulkan=true', }, - 'enable_webview_bundles': { - 'gn_args': 'enable_webview_bundles = true' - }, - 'eve': { 'args_file': '//build/args/chromeos/eve.gni', },
diff --git a/tools/mb/mb_config_expectations/chrome.pgo.json b/tools/mb/mb_config_expectations/chrome.pgo.json index 6cb7c02..7e56154 100644 --- a/tools/mb/mb_config_expectations/chrome.pgo.json +++ b/tools/mb/mb_config_expectations/chrome.pgo.json
@@ -1,20 +1,17 @@ { "android-arm32-pgo": { - "args_file": "//clank/build/custom_args.gn", "gn_args": { "chrome_pgo_phase": 1, - "enable_remoting": true, - "enable_webview_bundles": true, + "clang_use_default_sample_profile": false, "ffmpeg_branding": "Chrome", "is_chrome_branded": true, "is_official_build": true, "proprietary_codecs": true, "strip_absolute_paths_from_debug_symbols": true, - "system_webview_apk_target": "//clank/android_webview:system_webview_google_apk", + "symbol_level": 1, "target_cpu": "arm", "target_os": "android", - "use_goma": true, - "use_signing_keys": true + "use_goma": true } }, "linux-pgo": {
diff --git a/tools/mb/mb_config_expectations/chromium.android.fyi.json b/tools/mb/mb_config_expectations/chromium.android.fyi.json index 59f3be5..bd6c97a1 100644 --- a/tools/mb/mb_config_expectations/chromium.android.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.android.fyi.json
@@ -56,6 +56,22 @@ "use_goma": true } }, + "android-12-x64-fyi-rel": { + "gn_args": { + "disable_android_lint": true, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "strip_debug_info": true, + "symbol_level": 1, + "system_webview_package_name": "com.google.android.webview", + "target_cpu": "x64", + "target_os": "android", + "use_errorprone_java_compiler": false, + "use_goma": true + } + }, "android-pie-arm64-wpt-rel-non-cq": { "gn_args": { "ffmpeg_branding": "Chrome",
diff --git a/tools/mb/mb_config_expectations/internal.chromeos.fyi.json b/tools/mb/mb_config_expectations/internal.chromeos.fyi.json index 1cf24e3..a3522f2 100644 --- a/tools/mb/mb_config_expectations/internal.chromeos.fyi.json +++ b/tools/mb/mb_config_expectations/internal.chromeos.fyi.json
@@ -82,6 +82,7 @@ "is_chrome_branded": true, "is_chromeos_device": true, "is_official_build": true, + "is_skylab": true, "ozone_platform": "wayland", "ozone_platform_drm": false, "ozone_platform_gbm": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json index 6cb7c02..7e56154 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json
@@ -1,20 +1,17 @@ { "android-arm32-pgo": { - "args_file": "//clank/build/custom_args.gn", "gn_args": { "chrome_pgo_phase": 1, - "enable_remoting": true, - "enable_webview_bundles": true, + "clang_use_default_sample_profile": false, "ffmpeg_branding": "Chrome", "is_chrome_branded": true, "is_official_build": true, "proprietary_codecs": true, "strip_absolute_paths_from_debug_symbols": true, - "system_webview_apk_target": "//clank/android_webview:system_webview_google_apk", + "symbol_level": 1, "target_cpu": "arm", "target_os": "android", - "use_goma": true, - "use_signing_keys": true + "use_goma": true } }, "linux-pgo": {
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json index 4826831..864b47ab 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -35,6 +35,24 @@ "use_goma": true } }, + "android-12-x64-fyi-rel": { + "gn_args": { + "blink_enable_generated_code_formatting": false, + "dcheck_always_on": true, + "disable_android_lint": true, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "strip_debug_info": true, + "symbol_level": 1, + "system_webview_package_name": "com.google.android.webview", + "target_cpu": "x64", + "target_os": "android", + "use_errorprone_java_compiler": false, + "use_goma": true + } + }, "android-asan": { "gn_args": { "blink_enable_generated_code_formatting": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 03c305c..341d992 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -6802,7 +6802,7 @@ <int value="3" label="Has related active contents"/> <int value="4" label="Does not have a site"/> <int value="5" label="Source URL scheme is not HTTP(S)"/> - <int value="6" label="Destination URL scheme is not HTTP(S)"/> + <int value="6" label="Destination URL scheme is not HTTP(S) (removed)"/> <int value="7" label="Same site navigation, same-site proactive swap disabled"/> <int value="8" label="Error page"/> @@ -46049,6 +46049,7 @@ <int value="-2132161378" label="SendTabToSelfHistory:disabled"/> <int value="-2131746498" label="AutofillUseImprovedLabelDisambiguation:enabled"/> + <int value="-2130982324" label="DesktopPWAsWebBundles:disabled"/> <int value="-2129940395" label="WebAssemblySimd:disabled"/> <int value="-2129013032" label="DocumentTransition:enabled"/> <int value="-2128705444" label="AssistantAppSupport:enabled"/> @@ -46989,6 +46990,7 @@ <int value="-1390005994" label="AppCache:disabled"/> <int value="-1388817073" label="OmniboxReverseAnswers:disabled"/> <int value="-1388044691" label="ContentLanguagesInLanguagePicker:enabled"/> + <int value="-1387339670" label="AssistMultiWordExpanded:disabled"/> <int value="-1386966873" label="disable-mac-views-native-app-windows"/> <int value="-1386790338" label="ImeMozcProto:disabled"/> <int value="-1386776772" label="FilesZipPack:disabled"/> @@ -47731,6 +47733,8 @@ <int value="-792079435" label="EnableAppsGridGapFeature:disabled"/> <int value="-791778534" label="LauncherQueryHighlighting:enabled"/> <int value="-790900615" label="NtpShoppingTasksModule:disabled"/> + <int value="-790544721" + label="OverrideUnsupportedPageLanguageForHrefTranslate:disabled"/> <int value="-790036192" label="overscroll-start-threshold"/> <int value="-787969387" label="HTTPSServerPreviewsUsingURLLoader:enabled"/> <int value="-787876637" label="HomeLauncherGestures:enabled"/> @@ -48536,6 +48540,8 @@ <int value="-85706353" label="VirtualDesksGestures:enabled"/> <int value="-82530769" label="WebXRPlaneDetection:enabled"/> <int value="-82266557" label="SafeBrowsingSecuritySectionUIAndroid:disabled"/> + <int value="-81940476" + label="OverrideSimilarLanguagesForHrefTranslate:disabled"/> <int value="-80501013" label="AutofillOffNoServerData:enabled"/> <int value="-80353187" label="disable-display-color-calibration"/> <int value="-79327236" label="ModeSpecificPowerButton:enabled"/> @@ -49299,6 +49305,7 @@ <int value="550378029" label="reset-app-list-install-state"/> <int value="550387510" label="NTPAssetDownloadSuggestions:disabled"/> <int value="552317551" label="MediaAppHandlesPdf:disabled"/> + <int value="552421509" label="AssistMultiWordExpanded:enabled"/> <int value="555959995" label="ChromeSharingHub:enabled"/> <int value="556555487" label="AutofillDoNotUploadSaveUnsupportedCards:disabled"/> @@ -50106,6 +50113,8 @@ <int value="1226624874" label="Mus:disabled"/> <int value="1226676061" label="PageInfoV2Desktop:enabled"/> <int value="1227633129" label="NtpChromeCartModule:disabled"/> + <int value="1228054141" + label="OverrideUnsupportedPageLanguageForHrefTranslate:enabled"/> <int value="1228115769" label="SiteCharacteristicsDatabase:disabled"/> <int value="1229299518" label="SingleTabMode:disabled"/> <int value="1229388323" label="AutofillEnableGoogleIssuedCard:disabled"/> @@ -50369,6 +50378,7 @@ <int value="1435251818" label="AutofillNoLocalSaveOnUploadSuccess:enabled"/> <int value="1436454450" label="InterestFeedV2:disabled"/> <int value="1437413720" label="CooperativeScheduling:disabled"/> + <int value="1438417722" label="MessagesForAndroidReaderMode:enabled"/> <int value="1440618113" label="EnableNetworkingInDiagnosticsApp:disabled"/> <int value="1440881073" label="DesktopPWAsAppIconShortcutsMenuUI:enabled"/> <int value="1441897340" label="AndroidSpellCheckerNonLowEnd:enabled"/> @@ -50740,6 +50750,8 @@ <int value="1758262950" label="OmniboxUIExperimentVerticalMarginLimitToNonTouchOnly:disabled"/> <int value="1760946944" label="MacViewsAutofillPopup:disabled"/> + <int value="1761920078" + label="OverrideSimilarLanguagesForHrefTranslate:enabled"/> <int value="1762320532" label="AutofillKeyboardAccessory:enabled"/> <int value="1764618580" label="MojoLinuxChannelSharedMem:disabled"/> <int value="1766676896" label="affiliation-based-matching:disabled"/> @@ -50751,6 +50763,7 @@ <int value="1775475563" label="malware-interstitial-v3"/> <int value="1775652804" label="OmniboxBookmarkPaths:disabled"/> <int value="1775730290" label="OmniboxKeywordSearchButton:enabled"/> + <int value="1776163541" label="DesktopPWAsWebBundles:enabled"/> <int value="1776475705" label="show-composited-layer-borders"/> <int value="1777059507" label="trust-autofill-server-name-types"/> <int value="1777241671" label="EnableAriaElementReflection:disabled"/> @@ -51183,6 +51196,7 @@ <int value="2114894984" label="DelayCompetingLowPriorityRequests:enabled"/> <int value="2115848376" label="LacrosSupport:disabled"/> <int value="2118287149" label="HelpAppSearchServiceIntegration:enabled"/> + <int value="2118374092" label="MessagesForAndroidReaderMode:disabled"/> <int value="2119964154" label="enable-download-resumption"/> <int value="2120659210" label="BackForwardCache:enabled"/> <int value="2121056855" label="IncreaseInputAudioBufferSize:disabled"/> @@ -54222,6 +54236,7 @@ <int value="7" label="MerchantTrust"/> <int value="8" label="AddToHomescreenIPH"/> <int value="9" label="SendTabToSelf"/> + <int value="10" label="ReaderMode"/> </enum> <enum name="MessageLoopProblems"> @@ -56564,6 +56579,9 @@ </enum> <enum name="NetReportingReportOutcome"> + <obsolete> + Removed from code, July 2021. + </obsolete> <int value="0" label="Unknown"/> <int value="1" label="Discarded: no URLRequestContext"/> <int value="2" label="Discarded: no ReportingService"/>
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml index 0efb4da..a637074 100644 --- a/tools/metrics/histograms/histograms_xml/android/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -66,6 +66,7 @@ <variant name=".GeneratedPasswordSaved"/> <variant name=".MerchantTrust"/> <variant name=".PopupBlocked"/> + <variant name=".ReaderMode"/> <variant name=".SafetyTip"/> <variant name=".SaveAddressProfile"/> <variant name=".SavePassword"/>
diff --git a/tools/metrics/histograms/histograms_xml/ash/histograms.xml b/tools/metrics/histograms/histograms_xml/ash/histograms.xml index ff001f94..9b87ad7 100644 --- a/tools/metrics/histograms/histograms_xml/ash/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/ash/histograms.xml
@@ -1566,11 +1566,47 @@ </summary> </histogram> +<histogram name="Ash.Notification.ClearAllStacked.AnimationSmoothness" + units="%" expires_after="2022-07-02"> + <owner>newcomer@chromium.org</owner> + <owner>cros-status-area-eng@google.com</owner> + <summary> + Animation smoothness of the "clear all" animation in the CrOS + message center. This occurs when the clear all button is pressed with + notifications that are not visible on screen. Measured via a throughtput + tracker. + </summary> +</histogram> + +<histogram name="Ash.Notification.ClearAllVisible.AnimationSmoothness" + units="%" expires_after="2022-07-02"> + <owner>newcomer@chromium.org</owner> + <owner>cros-status-area-eng@google.com</owner> + <summary> + Animation smoothness of the "clear all" animation in the CrOS + message center. This occurs when the clear all button is pressed and all + notifications are visible. Measured via a throughtput tracker. + </summary> +</histogram> + +<histogram name="Ash.Notification.MoveDown.AnimationSmoothness" units="%" + expires_after="2022-07-02"> + <owner>newcomer@chromium.org</owner> + <owner>cros-status-area-eng@google.com</owner> + <summary> + Animation smoothness of the "move down" animation in the CrOS + message center. This occurs when a notification is removed and notifications + above the deleted one animate downwards to fill in the space. Measured via a + throughtput tracker. + </summary> +</histogram> + <histogram name="Ash.NotificationPopup.AnimationSmoothness" units="%" expires_after="2022-06-25"> <owner>leandre@chromium.org</owner> <owner>amehfooz@chromium.org</owner> <owner>tbarzic@chromium.org</owner> + <owner>cros-status-area-eng@google.com</owner> <summary> Relative smoothness of animations of notification pop-up. 100% represents ideally smooth 60 frames per second. Emitted when pop-up animations are
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index 7c827021..cf4dc62d 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -12594,6 +12594,7 @@ <histogram_suffixes name="OptimizationGuide_OptimizationTargets" separator="."> <suffix name="LanguageDetection" label="Language detection"/> + <suffix name="ModelValidation" label="Model validation triggered via CLI"/> <suffix name="PageTopics" label="Page topics"/> <suffix name="PainfulPageLoad" label="Painful page load"/> <suffix name="SegmentationNewTab" label="Segmentation: New tab page user"/>
diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml index 7497edd..7645975 100644 --- a/tools/metrics/histograms/histograms_xml/net/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml
@@ -4814,6 +4814,9 @@ <histogram name="Net.Reporting.ReportOutcome" enum="NetReportingReportOutcome" expires_after="2021-06-25"> + <obsolete> + Removed July 2021 + </obsolete> <owner>chlily@chromium.org</owner> <owner>juliatuttle@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index ae37844..4abe846 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -10631,6 +10631,15 @@ <summary>Records whether the created note was shared or not.</summary> </histogram> +<histogram name="NoteCreation.NumberOfTemplateChanges" + units="Number of changes" expires_after="2021-12-01"> + <owner>sebsg@chromium.org</owner> + <owner>chrome-creation@google.com</owner> + <summary> + Records the number of times the user changed templates when creating a note. + </summary> +</histogram> + <histogram name="NQE.CachedNetworkQualityAvailable" enum="BooleanAvailable" expires_after="2021-10-10"> <owner>tbansal@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/scheduler/histograms.xml b/tools/metrics/histograms/histograms_xml/scheduler/histograms.xml index 8a2d9f42..fee3fea 100644 --- a/tools/metrics/histograms/histograms_xml/scheduler/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/scheduler/histograms.xml
@@ -47,7 +47,7 @@ <histogram base="true" name="Scheduler.DOMScheduler.QueueingDurationPerPriority" units="ms" - expires_after="2020-12-01"> + expires_after="2022-12-01"> <!-- Name completed by histogram_suffixes name="Scheduler.DOMScheduler.Priority" --> <owner>kdillon@chromium.org</owner> @@ -60,7 +60,7 @@ </histogram> <histogram name="Scheduler.DOMScheduler.TaskSignalPriorityWasChanged" - enum="PriorityChangeStatus" expires_after="2020-12-01"> + enum="PriorityChangeStatus" expires_after="2022-12-01"> <owner>kdillon@chromium.org</owner> <owner>shaseley@chromium.org</owner> <summary>
diff --git a/tools/perf/core/minidump_unittest.py b/tools/perf/core/minidump_unittest.py index b31ea67..42f5fad 100644 --- a/tools/perf/core/minidump_unittest.py +++ b/tools/perf/core/minidump_unittest.py
@@ -48,6 +48,7 @@ # Minidump symbolization doesn't work in ChromeOS local mode if the rootfs is # still read-only, so skip the test in that case. @decorators.Disabled( + 'android', # https://crbug.com/1218560 'chromeos-local', 'win7' # https://crbug.com/1084931 ) @@ -93,6 +94,7 @@ # Minidump symbolization doesn't work in ChromeOS local mode if the rootfs is # still read-only, so skip the test in that case. @decorators.Disabled( + 'android', # https://crbug.com/1218560 'chromeos-local', 'win7' # https://crbug.com/1084931 )
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index b35d2a2..4678e0f 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,8 +1,8 @@ { "trace_processor_shell": { "win": { - "hash": "82e3f4365393d31a587d58b9ae66e9f81461e960", - "remote_path": "perfetto_binaries/trace_processor_shell/win/ca06eb435506f54cf6a7c013a6c545726532f2b3/trace_processor_shell.exe" + "hash": "a517575f7a3131da2838899a7f9d72b01be7341a", + "remote_path": "perfetto_binaries/trace_processor_shell/win/cc178a3f172732fa9b107cda5281c98c1ac9fead/trace_processor_shell.exe" }, "mac": { "hash": "e9c26d8ab8a0a60c936bfbd07de9074b2470b392", @@ -10,7 +10,7 @@ }, "linux": { "hash": "81aad5d60c5ed2f7b1a7ff926de7e6a06fe1d097", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/80c6050169a35f725abc5390a7ef1bc36298462f/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/cc178a3f172732fa9b107cda5281c98c1ac9fead/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/tracing/PRESUBMIT.py b/tools/tracing/PRESUBMIT.py new file mode 100644 index 0000000..07e0b58 --- /dev/null +++ b/tools/tracing/PRESUBMIT.py
@@ -0,0 +1,26 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Tracing unittests presubmit script. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for +details on the presubmit API built into gcl. +""" + +PRESUBMIT_VERSION = '2.0.0' +USE_PYTHON3 = True + + +def RunUnittests(input_api, output_api): + presubmit_path = input_api.PresubmitLocalPath() + return input_api.canned_checks.RunUnitTests(input_api, output_api, [ + input_api.os_path.join(presubmit_path, 'metadata_extractor_unittests.py'), + ]) + + +def CheckChangeOnUpload(input_api, output_api): + return RunUnittests(input_api, output_api) + + +def CheckChangeOnCommit(input_api, output_api): + return RunUnittests(input_api, output_api)
diff --git a/tools/tracing/adb_profile_chrome_startup.py b/tools/tracing/adb_profile_chrome_startup.py index 6eac6af..658aa3b 100644 --- a/tools/tracing/adb_profile_chrome_startup.py +++ b/tools/tracing/adb_profile_chrome_startup.py
@@ -35,6 +35,9 @@ Args: options: Command line flags with their specified values as returned by optparse. + + Returns: + Path to Android profetto trace file """ if not options.device_serial_number: # Find the serial number of the connected device. @@ -79,6 +82,8 @@ if options.view: _DisplayInBrowser(options, trace_file) + return trace_file + def _DisplayInBrowser(options, trace_file): """Displays trace in browser.
diff --git a/tools/tracing/metadata_extractor.py b/tools/tracing/metadata_extractor.py new file mode 100644 index 0000000..f4b3f2f3d --- /dev/null +++ b/tools/tracing/metadata_extractor.py
@@ -0,0 +1,139 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +""" +Extracts metadata information from proto traces. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, 'perf')) + +from core.tbmv3 import trace_processor + +VERSION_NUM_QUERY = ( + 'select str_value from metadata where name="cr-product-version"') +OS_NAME_QUERY = 'select str_value from metadata where name="cr-os-name"' +ARCH_QUERY = 'select str_value from metadata where name="cr-os-arch"' +BITNESS_QUERY = ( + 'select int_value from metadata where name="cr-chrome-bitness"') +VERSION_CODE_QUERY = ( + 'select int_value from metadata where name="cr-playstore_version_code"') +MODULES_QUERY = 'select name, build_id from stack_profile_mapping' + + +class MetadataExtractor: + """Extracts and stores metadata from a perfetto trace. + + Attributes: + _initialized: boolean of whether the class has been + initialized or not by calling the Initialize function. + _trace_processor_path: path to the trace_processor executable. + _trace_file: path to a perfetto system trace file. + version_number: chrome version number (eg: 93.0.4537.0). + os_name: platform of the trace writer (eg. Android). + architecture: OS arch of the trace writer, as returned by + base::SysInfo::OperatingSystemArchitecture() (eg: 'x86_64). + bitness: integer of architecture bitness (eg. 32, 64). + version_code: version code of chrome used by Android play store. + modules: map from module name to module debug ID, for all + modules that need symbolization. + """ + + def __init__(self, trace_processor_path, trace_file): + self._initialized = False + self._trace_processor_path = trace_processor_path + self._trace_file = trace_file + self.version_number = None + self.os_name = None + self.architecture = None + self.bitness = None + self.version_code = None + self.modules = None + + def __str__(self): + return ('Initialized: {initialized}\n' + 'Trace Processor Path: {trace_processor_path}\n' + 'Trace File: {trace_file}\n' + 'Version Number: {version_number}\n' + 'OS Name: {os_name}\n' + 'Architecture: {architecture}\n' + 'Bitness: {bitness}\n' + 'Version Code: {version_code}\n' + 'Modules: {modules}\n'.format( + initialized=self._initialized, + trace_processor_path=self._trace_processor_path, + trace_file=self._trace_file, + version_number=self.version_number, + os_name=self.os_name, + architecture=self.architecture, + bitness=self.bitness, + version_code=self.version_code, + modules=self.modules)) + + def Initialize(self): + """Extracts metadata from perfetto system trace. + """ + if self._initialized: + return + self._initialized = True + + # Version Number query returns the name and number (Chrome/93.0.4537.0). + # Parse the result to only get the version number. + version_number = self._GetStringValueFromQuery(VERSION_NUM_QUERY) + if version_number is None: + self.version_number = None + elif version_number.count('/') == 1: + self.version_number = version_number.split('/')[1] + else: + self.version_number = version_number + + self.os_name = self._GetStringValueFromQuery(OS_NAME_QUERY) + self.architecture = self._GetStringValueFromQuery(ARCH_QUERY) + self.bitness = self._GetIntValueFromQuery(BITNESS_QUERY) + self.version_code = self._GetIntValueFromQuery(VERSION_CODE_QUERY) + + # Parse module to be a mapping between module name and debug id + self.modules = self._ExtractValidModuleMap() + + def _GetStringValueFromQuery(self, sql): + """Runs SQL query on trace processor and returns 'str_value' result. + """ + try: + return trace_processor.RunQuery(self._trace_processor_path, + self._trace_file, sql)[0]['str_value'] + except: + return None + + def _GetIntValueFromQuery(self, sql): + """Runs SQL query on trace processor and returns 'int_value' result. + """ + try: + return trace_processor.RunQuery(self._trace_processor_path, + self._trace_file, sql)[0]['int_value'] + except: + return None + + def _ExtractValidModuleMap(self): + """Extracts valid module name to module debug ID map/dict from trace. + """ + try: + query_result = trace_processor.RunQuery(self._trace_processor_path, + self._trace_file, MODULES_QUERY) + module_map = {} + for row in query_result: + row_name = row['name'] + row_debug_id = row['build_id'] + # Discard invalid key, value pairs + if ((row_name is None or row_name == '/missing') + or (row_debug_id is None or row_debug_id == '/missing')): + continue + module_map[row_name] = row_debug_id + + if not module_map: + return None + return module_map + + except: + return None
diff --git a/tools/tracing/metadata_extractor_unittests.py b/tools/tracing/metadata_extractor_unittests.py new file mode 100644 index 0000000..d25c4cd --- /dev/null +++ b/tools/tracing/metadata_extractor_unittests.py
@@ -0,0 +1,195 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import sys +import unittest + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, 'perf')) + +from core import path_util +path_util.AddPyUtilsToPath() +path_util.AddTracingToPath() + +import metadata_extractor +from core.tbmv3 import trace_processor + +import mock + + +class ExtractMetadataTestCase(unittest.TestCase): + def setUp(self): + self.trace_processor_path = 'trace_processor_shell' + self.trace_file = 'trace_file.proto' + + def _RunQueryParams(self, query): + """Returns tuple of RunQuery function parameters. + + Args: + query: sql query to extract metadata from proto trace. + """ + return (self.trace_processor_path, self.trace_file, query) + + def _CreateRunQueryResults(self, + version_number_results=[], + os_name_results=[], + architecture_results=[], + bitness_results=[], + version_code_results=[], + modules_results=[]): + """Mock return of RunQuery calls. + + See trace_processor.RunQuery for the format of the query results. + Each parameter is a result dictionary for corresponding SQL query + defined in metadata_extractor.py. For example, valid value for + os_name_results = [{'str_value' : 'pineapple'}] + + Returns: + A dictionary mapping of RunQuery parameters to their mocked + RunQuery function return values. + """ + return { + self._RunQueryParams(metadata_extractor.VERSION_NUM_QUERY): + version_number_results, + self._RunQueryParams(metadata_extractor.OS_NAME_QUERY): os_name_results, + self._RunQueryParams(metadata_extractor.ARCH_QUERY): + architecture_results, + self._RunQueryParams(metadata_extractor.BITNESS_QUERY): bitness_results, + self._RunQueryParams(metadata_extractor.VERSION_CODE_QUERY): + version_code_results, + self._RunQueryParams(metadata_extractor.MODULES_QUERY): modules_results + } + + def _CreateRunQueryResultsFromValues(self, + version_number=None, + os_name=None, + architecture=None, + bitness=None, + version_code=None, + modules=None): + """Mock return of RunQuery calls by values, except for modules. + + Args: + version_number: string containing chrome version number + (eg: 'Chrome/93.0.4537.0'). + os_name: string of platform of the trace writer (eg. 'Android'). + architecture: string of OS arch of the trace writer, as returned by + base::SysInfo::OperatingSystemArchitecture() (eg: 'x86_64). + bitness: string of architecture bitness (eg. '32', '64'). + version_code: string of version code of chrome used by Android + play store. + modules: list of dictionaries mock return value of RunQuery + when its called with sql query metadata_extractor.MODULES_QUERY + See _CreateRunQueryResults function for more information. + (eg: [{'name': '/libmonochrome.so, 'build_id': '3284389AB83CD'}]). + + Returns: + A dictionary mapping of RunQuery parameters to their mocked + RunQuery function return values. + """ + return self._CreateRunQueryResults(version_number_results=[{ + 'str_value': + version_number + }], + os_name_results=[{ + 'str_value': os_name + }], + architecture_results=[{ + 'str_value': + architecture + }], + bitness_results=[{ + 'int_value': bitness + }], + version_code_results=[{ + 'int_value': + version_code + }], + modules_results=modules) + + def testExtractMetadata(self): + def side_effect(*args): + params = self._CreateRunQueryResultsFromValues( + version_number='Chrome/36.9.7934.4', + os_name='Android', + architecture='x86_64', + bitness='64', + version_code='857854', + modules=[{ + 'name': '/libmonochrome.so', + 'build_id': '3284389AB83CD' + }, { + 'name': '/missing', + 'build_id': 'AB3288CDE3283' + }]) + return params[args] + + extractor = metadata_extractor.MetadataExtractor(self.trace_processor_path, + self.trace_file) + trace_processor.RunQuery = mock.MagicMock(side_effect=side_effect) + extractor.Initialize() + + self.assertEqual(extractor.version_number, '36.9.7934.4') + self.assertEqual(extractor.os_name, 'Android') + self.assertEqual(extractor.architecture, 'x86_64') + self.assertEqual(extractor.bitness, '64') + self.assertEqual(extractor.version_code, '857854') + self.assertEqual(extractor.modules, {'/libmonochrome.so': '3284389AB83CD'}) + + def testExtractMetadataEmptyList(self): + def side_effect(*args): + params = self._CreateRunQueryResults() + return params[args] + + extractor = metadata_extractor.MetadataExtractor(self.trace_processor_path, + self.trace_file) + trace_processor.RunQuery = mock.MagicMock(side_effect=side_effect) + extractor.Initialize() + + self.assertEqual(extractor.version_number, None) + self.assertEqual(extractor.os_name, None) + self.assertEqual(extractor.architecture, None) + self.assertEqual(extractor.bitness, None) + self.assertEqual(extractor.version_code, None) + self.assertEqual(extractor.modules, None) + + def testExtractMetadataValuesNull(self): + def side_effect(*args): + params = self._CreateRunQueryResultsFromValues(modules=[{ + 'name': None, + 'build_id': None + }, { + 'name': None, + 'build_id': None + }]) + return params[args] + + extractor = metadata_extractor.MetadataExtractor(self.trace_processor_path, + self.trace_file) + trace_processor.RunQuery = mock.MagicMock(side_effect=side_effect) + extractor.Initialize() + + self.assertEqual(extractor.version_number, None) + self.assertEqual(extractor.os_name, None) + self.assertEqual(extractor.architecture, None) + self.assertEqual(extractor.bitness, None) + self.assertEqual(extractor.version_code, None) + self.assertEqual(extractor.modules, None) + + def testExtractMetadataVersionNumberParsed(self): + def side_effect(*args): + params = self._CreateRunQueryResultsFromValues( + version_number='36.9.7934.4') + return params[args] + + extractor = metadata_extractor.MetadataExtractor(self.trace_processor_path, + self.trace_file) + trace_processor.RunQuery = mock.MagicMock(side_effect=side_effect) + extractor.Initialize() + + self.assertEqual(extractor.version_number, '36.9.7934.4') + + +if __name__ == '__main__': + unittest.main()
diff --git a/tools/tracing/profile_chrome_startup b/tools/tracing/profile_chrome_startup index 92a61e89..c258bb3 100755 --- a/tools/tracing/profile_chrome_startup +++ b/tools/tracing/profile_chrome_startup
@@ -22,6 +22,7 @@ from profile_chrome import flags from systrace import util + _DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES' @@ -63,13 +64,13 @@ parser = _CreateOptionParser() options, _ = parser.parse_args() - if options.platform == 'android': - adb_profile_chrome_startup.ProfileChrome(options) + # Run Tracing + trace_file = None + if options.platform.lower() == 'android': + trace_file = adb_profile_chrome_startup.ProfileChrome(options) else: - raise ValueError('Platform %s is not supported. ' + - 'Specify platform with the --platform flag.' - .format(options.platform)) - + raise ValueError('Platform "%s" is not supported. ' + 'Specify platform with the --platform flag.' % (options.platform)) if __name__ == '__main__': sys.exit(main())
diff --git a/tools/traffic_annotation/scripts/auditor/auditor.py b/tools/traffic_annotation/scripts/auditor/auditor.py index 3fafd901..a46eb77 100755 --- a/tools/traffic_annotation/scripts/auditor/auditor.py +++ b/tools/traffic_annotation/scripts/auditor/auditor.py
@@ -1953,9 +1953,9 @@ errors.extend(self.auditor.parse_extractor_output(all_annotations)) - # Perform checks on successfully extracted annotations, otherwise skip to - # reporting errors. - if self.auditor.extracted_annotations: + # If we already have errors from parsing annotations, report them. Otherwise + # check the extracted annotations and their consistency with previous state. + if not errors: errors.extend( self.auditor.run_all_checks(self.path_filters, self.test_only))
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn index f9549e9..25380598 100644 --- a/ui/file_manager/BUILD.gn +++ b/ui/file_manager/BUILD.gn
@@ -195,7 +195,6 @@ "file_manager/foreground/js/drive_dialog_controller.js", "file_manager/foreground/js/drop_effect_and_label.js", "file_manager/foreground/js/elements_importer.js", - "file_manager/foreground/js/empty_folder_controller.js", "file_manager/foreground/js/fake_android_app_list_model.js", "file_manager/foreground/js/fake_file_selection_handler.js", "file_manager/foreground/js/file_list_model.js", @@ -279,7 +278,6 @@ "file_manager/foreground/js/ui/dialog_footer.js", "file_manager/foreground/js/ui/directory_tree.js", "file_manager/foreground/js/ui/drag_selector.js", - "file_manager/foreground/js/ui/empty_folder.js", "file_manager/foreground/js/ui/file_grid.js", "file_manager/foreground/js/ui/file_list_selection_model.js", "file_manager/foreground/js/ui/file_manager_dialog_base.js",
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 1fa401b..4026f9c 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -2527,10 +2527,6 @@ position: relative; } -body.files-ng #empty-folder { - display: none; -} - #volume-space-info-contents { align-items: center; display: flex;
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/empty_folder.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/empty_folder.png deleted file mode 100644 index 6aef93a..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/empty_folder.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/empty_folder.png b/ui/file_manager/file_manager/foreground/images/files/ui/empty_folder.png deleted file mode 100644 index f53d186f..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/empty_folder.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn index 99f05fc..d9c0a22b 100644 --- a/ui/file_manager/file_manager/foreground/js/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -41,7 +41,6 @@ ":drive_dialog_controller", ":drop_effect_and_label", ":elements_importer", - ":empty_folder_controller", ":fake_android_app_list_model", ":fake_file_selection_handler", ":file_list_model", @@ -117,7 +116,6 @@ ":drive_dialog_controller", ":drop_effect_and_label", ":elements_importer", - ":empty_folder_controller", ":fake_android_app_list_model", ":fake_file_selection_handler", ":file_list_model", @@ -447,18 +445,6 @@ ] } -js_library("empty_folder_controller") { - deps = [ - ":constants", - ":directory_model", - ":file_list_model", - "ui:empty_folder", - "ui:files_alert_dialog", - "//ui/file_manager/file_manager/common/js:util", - "//ui/webui/resources/js:assert.m", - ] -} - js_library("file_list_model") { deps = [ "metadata:metadata_model", @@ -492,7 +478,6 @@ ":directory_model", ":directory_tree_naming_controller", ":drive_dialog_controller", - ":empty_folder_controller", ":file_manager_commands", ":file_selection", ":file_tasks",
diff --git a/ui/file_manager/file_manager/foreground/js/empty_folder_controller.js b/ui/file_manager/file_manager/foreground/js/empty_folder_controller.js deleted file mode 100644 index efe6a9c4..0000000 --- a/ui/file_manager/file_manager/foreground/js/empty_folder_controller.js +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright 2015 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 {assert} from 'chrome://resources/js/assert.m.js'; - -import {str, strf, util} from '../../common/js/util.js'; - -import {constants} from './constants.js'; -import {DirectoryModel} from './directory_model.js'; -import {FileListModel} from './file_list_model.js'; -import {EmptyFolder} from './ui/empty_folder.js'; -import {FilesAlertDialog} from './ui/files_alert_dialog.js'; - -/** - * Empty folder controller. - */ -export class EmptyFolderController { - /** - * @param {!EmptyFolder} emptyFolder Empty folder ui. - * @param {!DirectoryModel} directoryModel Directory model. - * @param {!FilesAlertDialog} alertDialog Alert dialog. - */ - constructor(emptyFolder, directoryModel, alertDialog) { - /** - * @private {!EmptyFolder} - */ - this.emptyFolder_ = emptyFolder; - - /** - * @private {!DirectoryModel} - */ - this.directoryModel_ = directoryModel; - - /** - * @private {!FilesAlertDialog} - */ - this.alertDialog_ = alertDialog; - - /** - * @private {!FileListModel} - */ - this.dataModel_ = assert(this.directoryModel_.getFileList()); - - /** - * @private {boolean} - */ - this.isScanning_ = false; - - this.directoryModel_.addEventListener( - 'scan-started', this.onScanStarted_.bind(this)); - this.directoryModel_.addEventListener( - 'scan-failed', this.onScanFailed_.bind(this)); - this.directoryModel_.addEventListener( - 'scan-cancelled', this.onScanFinished_.bind(this)); - this.directoryModel_.addEventListener( - 'scan-completed', this.onScanFinished_.bind(this)); - this.directoryModel_.addEventListener( - 'rescan-completed', this.onScanFinished_.bind(this)); - - this.dataModel_.addEventListener('splice', this.onSplice_.bind(this)); - } - - /** - * Handles splice event. - * @private - */ - onSplice_() { - this.update_(); - } - - /** - * Handles scan start. - * @private - */ - onScanStarted_() { - this.isScanning_ = true; - this.update_(); - } - - /** - * Handles scan fail. - * @param {Event} event Event may contain error field containing DOMError for - * alert. - * @private - */ - onScanFailed_(event) { - this.isScanning_ = false; - // Show alert for crostini connection error. - if (event.error.name == constants.CROSTINI_CONNECT_ERR) { - this.alertDialog_.showWithTitle( - str('ERROR_LINUX_FILES_CONNECTION'), event.error.message); - } - this.update_(); - } - - /** - * Handles scan finish. - * @private - */ - onScanFinished_() { - this.isScanning_ = false; - this.update_(); - } - - /** - * Updates visibility of empty folder UI. - * @private - */ - update_() { - if (!this.isScanning_ && this.dataModel_.length === 0) { - const query = this.directoryModel_.getLastSearchQuery(); - let html = ''; - if (query) { - html = strf('SEARCH_NO_MATCHING_FILES_HTML', util.htmlEscape(query)); - } else { - html = str('EMPTY_FOLDER'); - } - - this.emptyFolder_.setMessage(html); - this.emptyFolder_.show(); - } else { - this.emptyFolder_.hide(); - } - } -}
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index ecdb708..8a7095f9 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -43,7 +43,6 @@ import {DirectoryTreeNamingController} from './directory_tree_naming_controller.js'; import {DriveDialogController} from './drive_dialog_controller.js'; import {importElements} from './elements_importer.js'; -import {EmptyFolderController} from './empty_folder_controller.js'; import {CommandHandler, CommandUtil} from './file_manager_commands.js'; import {FileSelection, FileSelectionHandler} from './file_selection.js'; import {FileTasks} from './file_tasks.js'; @@ -303,12 +302,6 @@ this.toolbarController_ = null; /** - * Empty folder controller. - * @private {EmptyFolderController} - */ - this.emptyFolderController_ = null; - - /** * App state controller. * @private {?AppStateController} */ @@ -688,8 +681,6 @@ assert(this.ui_.locationLine), this.selectionHandler_, this.directoryModel_, this.volumeManager_, this.fileOperationManager_, /** @type {!A11yAnnounce} */ (this.ui_)); - this.emptyFolderController_ = new EmptyFolderController( - this.ui_.emptyFolder, this.directoryModel_, this.ui_.alertDialog); this.actionsController_ = new ActionsController( this.volumeManager_, assert(this.metadataModel_), this.directoryModel_, assert(this.folderShortcutsModel_),
diff --git a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn index eb56c402..05078c5a 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
@@ -32,7 +32,6 @@ ":dialog_footer", ":directory_tree", ":drag_selector", - ":empty_folder", ":file_grid", ":file_list_selection_model", ":file_manager_dialog_base", @@ -84,7 +83,6 @@ ":dialog_footer", ":directory_tree", ":drag_selector", - ":empty_folder", ":file_grid", ":file_list_selection_model", ":file_manager_dialog_base", @@ -271,10 +269,6 @@ externs_list = [ "//ui/file_manager/file_manager/externs/drag_target.js" ] } -js_library("empty_folder") { - deps = [ "//ui/webui/resources/js:util.m" ] -} - js_library("file_grid") { deps = [ ":a11y_announce", @@ -340,7 +334,6 @@ ":default_task_dialog", ":dialog_footer", ":directory_tree", - ":empty_folder", ":file_grid", ":file_table", ":files_alert_dialog",
diff --git a/ui/file_manager/file_manager/foreground/js/ui/empty_folder.js b/ui/file_manager/file_manager/foreground/js/ui/empty_folder.js deleted file mode 100644 index 1d4f4f800..0000000 --- a/ui/file_manager/file_manager/foreground/js/ui/empty_folder.js +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2015 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 {queryRequiredElement} from 'chrome://resources/js/util.m.js'; - -export class EmptyFolder { - /** - * Empty folder UI. - * @param {!HTMLElement} emptyFolder DOM element of empty folder. - */ - constructor(emptyFolder) { - /** - * @private {!HTMLElement} - */ - this.emptyFolder_ = emptyFolder; - - /** - * @private {!HTMLElement} - */ - this.label_ = queryRequiredElement('#empty-folder-label', emptyFolder); - } - - /** - * Shows empty folder UI. - */ - show() { - this.emptyFolder_.hidden = false; - } - - /** - * Hides empty folder UI. - */ - hide() { - this.emptyFolder_.hidden = true; - } - - /** - * Set message to empty folder UI. - * @param {string} html HTML string set to the label. - */ - setMessage(html) { - this.label_.innerHTML = html; - } -}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js index 62728ad..abeff93a4 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -29,7 +29,6 @@ import {DefaultTaskDialog} from './default_task_dialog.js'; import {DialogFooter} from './dialog_footer.js'; import {DirectoryTree} from './directory_tree.js'; -import {EmptyFolder} from './empty_folder.js'; import {FileGrid} from './file_grid.js'; import {FileTable} from './file_table.js'; import {FilesAlertDialog} from './files_alert_dialog.js'; @@ -219,14 +218,6 @@ queryRequiredElement('#search-button', this.element)); /** - * Empty folder UI. - * @type {!EmptyFolder} - * @const - */ - this.emptyFolder = - new EmptyFolder(queryRequiredElement('#empty-folder', this.element)); - - /** * Toggle-view button. * @type {!Element} * @const
diff --git a/ui/file_manager/integration_tests/file_manager/file_display.js b/ui/file_manager/integration_tests/file_manager/file_display.js index a2e19c6..9ff1514 100644 --- a/ui/file_manager/integration_tests/file_manager/file_display.js +++ b/ui/file_manager/integration_tests/file_manager/file_display.js
@@ -446,9 +446,8 @@ // Notify the element of the input. await remoteCall.callRemoteTestUtil( 'fakeEvent', appId, ['#search-box cr-input', 'input']); - const element = - await remoteCall.waitForElement(appId, ['#empty-folder-label b']); - chrome.test.assertEq(element.text, '\"' + searchTerm + '\"'); + + await remoteCall.waitForFiles(appId, []); }; /**
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc index de0bd0d..21f7e7b 100644 --- a/ui/platform_window/x11/x11_window.cc +++ b/ui/platform_window/x11/x11_window.cc
@@ -1565,8 +1565,6 @@ display->GetDisplayMatching(target_window_bounds); auto display_window_current = display->GetDisplayMatching(current_window_bounds); - DCHECK_EQ(display_window_target.device_scale_factor(), - display_window_current.device_scale_factor()); ConvertEventLocationToTargetWindowLocation(target_window_bounds.origin(), current_window_bounds.origin(),
diff --git a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm index f7e99f4..03b291e 100644 --- a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm +++ b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
@@ -49,43 +49,19 @@ return std::vector<T>(data, data + N); } -// Helper struct to hold arguments for the call to -// SelectFileDialogImpl::SelectFileImpl. -struct FileDialogArguments { - ui::SelectFileDialog::Type type; - std::u16string title; - base::FilePath default_path; - ui::SelectFileDialog::FileTypeInfo* file_types; - int file_type_index; - base::FilePath::StringType default_extension; - gfx::NativeWindow owning_window; - void* params; -}; - -// Helper method to return a FileDialogArguments struct initialized with -// appropriate default values. -FileDialogArguments GetDefaultArguments() { - return {ui::SelectFileDialog::SELECT_SAVEAS_FILE, - u"", - base::FilePath(), - nullptr, - 0, - "", - nullptr, - nullptr}; -} - } // namespace namespace ui { namespace test { // Helper test base to initialize SelectFileDialogImpl. -class SelectFileDialogMacTest : public testing::Test, +class SelectFileDialogMacTest : public ::testing::Test, public SelectFileDialog::Listener { public: SelectFileDialogMacTest() : dialog_(new SelectFileDialogImpl(this, nullptr)) {} + SelectFileDialogMacTest(const SelectFileDialogMacTest&) = delete; + SelectFileDialogMacTest& operator=(const SelectFileDialogMacTest&) = delete; // Overridden from SelectFileDialog::Listener. void FileSelected(const base::FilePath& path, @@ -95,6 +71,17 @@ protected: base::test::TaskEnvironment task_environment_; + struct FileDialogArguments { + SelectFileDialog::Type type = SelectFileDialog::SELECT_SAVEAS_FILE; + std::u16string title; + base::FilePath default_path; + SelectFileDialog::FileTypeInfo* file_types = nullptr; + int file_type_index = 0; + base::FilePath::StringType default_extension; + gfx::NativeWindow owning_window = nullptr; + void* params = nullptr; + }; + // Helper method to launch a dialog with the given |args|. void SelectFileWithParams(FileDialogArguments args) { dialog_->SelectFile(args.type, args.title, args.default_path, @@ -123,10 +110,17 @@ private: scoped_refptr<SelectFileDialogImpl> dialog_; - - DISALLOW_COPY_AND_ASSIGN(SelectFileDialogMacTest); }; +class SelectFileDialogMacOpenAndSaveTest + : public SelectFileDialogMacTest, + public ::testing::WithParamInterface<SelectFileDialog::Type> {}; + +INSTANTIATE_TEST_SUITE_P(All, + SelectFileDialogMacOpenAndSaveTest, + ::testing::Values(SelectFileDialog::SELECT_SAVEAS_FILE, + SelectFileDialog::SELECT_OPEN_FILE)); + // Verify that the extension popup has the correct description and changing the // popup item changes the allowed file types. TEST_F(SelectFileDialogMacTest, ExtensionPopup) { @@ -142,7 +136,7 @@ GetVectorFromArray<std::u16string>(extension_descriptions_arr); file_type_info.include_all_files = false; - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; args.file_types = &file_type_info; SelectFileWithParams(args); @@ -182,7 +176,7 @@ } // Verify file_type_info.include_all_files argument is respected. -TEST_F(SelectFileDialogMacTest, IncludeAllFiles) { +TEST_P(SelectFileDialogMacOpenAndSaveTest, IncludeAllFiles) { const std::string extensions_arr[][2] = {{"html", "htm"}, {"jpeg", "jpg"}}; const std::u16string extension_descriptions_arr[] = {u"Webpage", u"Image"}; @@ -195,7 +189,8 @@ GetVectorFromArray<std::u16string>(extension_descriptions_arr); file_type_info.include_all_files = true; - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; + args.type = GetParam(); args.file_types = &file_type_info; SelectFileWithParams(args); @@ -204,24 +199,28 @@ NSPopUpButton* popup = GetPopup(panel); EXPECT_TRUE(popup); - // Check that the dropdown list created has the correct description. - const std::vector<std::u16string> extension_descriptions = - GetExtensionDescriptionList(popup); - EXPECT_EQ(3lu, extension_descriptions.size()); - EXPECT_EQ(u"Webpage", extension_descriptions[0]); - EXPECT_EQ(u"Image", extension_descriptions[1]); - EXPECT_EQ(u"All Files", extension_descriptions[2]); - // Ensure other file types are allowed. EXPECT_TRUE([panel allowsOtherFileTypes]); - // Select the last item i.e. All Files. - SelectItemAtIndex(popup, 2); + // Check that the dropdown list created has the correct description. + const std::vector<std::u16string> extension_descriptions = + GetExtensionDescriptionList(popup); - // Ensure allowedFileTypes is set to nil, which means any file type can be - // used. - EXPECT_EQ(2, [popup indexOfSelectedItem]); - EXPECT_EQ(nil, [panel allowedFileTypes]); + // Save dialogs don't have "all files". + if (args.type == SelectFileDialog::SELECT_SAVEAS_FILE) { + ASSERT_EQ(2lu, extension_descriptions.size()); + EXPECT_EQ(u"Webpage", extension_descriptions[0]); + EXPECT_EQ(u"Image", extension_descriptions[1]); + } else { + ASSERT_EQ(3lu, extension_descriptions.size()); + EXPECT_EQ(u"Webpage", extension_descriptions[0]); + EXPECT_EQ(u"Image", extension_descriptions[1]); + EXPECT_EQ(u"All Files", extension_descriptions[2]); + + // Note that no further testing on the popup can be done. Open dialogs are + // out-of-process starting in macOS 10.15, so once it's been run and closed, + // the accessory view controls no longer work. + } } // Verify that file_type_index and default_extension arguments cause the @@ -238,7 +237,7 @@ file_type_info.extension_description_overrides = GetVectorFromArray<std::u16string>(extension_descriptions_arr); - FileDialogArguments args = GetDefaultArguments(); + FileDialogArguments args; args.file_types = &file_type_info; args.file_type_index = 2; @@ -302,7 +301,7 @@ file_type_info.extension_description_overrides = GetVectorFromArray<std::u16string>(extension_descriptions_arr); - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; args.file_types = &file_type_info; SelectFileWithParams(args); @@ -326,23 +325,18 @@ EXPECT_EQ(u"QQQ File (.qqq)", extension_descriptions[2]); } -// Verify that passing an empty extension list in file_type_info causes the All -// Files Option to display in the extension dropdown. -TEST_F(SelectFileDialogMacTest, EmptyExtension) { +// Verify that passing an empty extension list in file_type_info causes no +// extension dropdown to display. +TEST_P(SelectFileDialogMacOpenAndSaveTest, EmptyExtension) { SelectFileDialog::FileTypeInfo file_type_info; - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; + args.type = GetParam(); args.file_types = &file_type_info; SelectFileWithParams(args); NSSavePanel* panel = GetPanel(); - NSPopUpButton* popup = GetPopup(panel); - EXPECT_TRUE(popup); - - const std::vector<std::u16string> extension_descriptions = - GetExtensionDescriptionList(popup); - EXPECT_EQ(1lu, extension_descriptions.size()); - EXPECT_EQ(u"All Files", extension_descriptions[0]); + EXPECT_FALSE([panel accessoryView]); // Ensure other file types are allowed. EXPECT_TRUE([panel allowsOtherFileTypes]); @@ -351,17 +345,20 @@ // Verify that passing a null file_types value causes no extension dropdown to // display. TEST_F(SelectFileDialogMacTest, FileTypesNull) { - SelectFileWithParams(GetDefaultArguments()); + SelectFileWithParams({}); NSSavePanel* panel = GetPanel(); EXPECT_TRUE([panel allowsOtherFileTypes]); EXPECT_FALSE([panel accessoryView]); + + // Ensure other file types are allowed. + EXPECT_TRUE([panel allowsOtherFileTypes]); } // Verify that appropriate properties are set on the NSSavePanel for different // dialog types. TEST_F(SelectFileDialogMacTest, SelectionType) { SelectFileDialog::FileTypeInfo file_type_info; - FileDialogArguments args = GetDefaultArguments(); + FileDialogArguments args; args.file_types = &file_type_info; enum { @@ -380,12 +377,10 @@ {SelectFileDialog::SELECT_FOLDER, PICK_DIRS | CREATE_DIRS, "Select"}, {SelectFileDialog::SELECT_UPLOAD_FOLDER, PICK_DIRS, "Upload"}, {SelectFileDialog::SELECT_EXISTING_FOLDER, PICK_DIRS, "Select"}, - {SelectFileDialog::SELECT_SAVEAS_FILE, HAS_ACCESSORY_VIEW | CREATE_DIRS, - "Save"}, - {SelectFileDialog::SELECT_OPEN_FILE, HAS_ACCESSORY_VIEW | PICK_FILES, - "Open"}, + {SelectFileDialog::SELECT_SAVEAS_FILE, CREATE_DIRS, "Save"}, + {SelectFileDialog::SELECT_OPEN_FILE, PICK_FILES, "Open"}, {SelectFileDialog::SELECT_OPEN_MULTI_FILE, - HAS_ACCESSORY_VIEW | PICK_FILES | MULTIPLE_SELECTION, "Open"}, + PICK_FILES | MULTIPLE_SELECTION, "Open"}, }; for (size_t i = 0; i < base::size(test_cases); i++) { @@ -420,15 +415,15 @@ // Verify that the correct message is set on the NSSavePanel. TEST_F(SelectFileDialogMacTest, DialogMessage) { const std::string test_title = "test title"; - FileDialogArguments args = GetDefaultArguments(); + FileDialogArguments args; args.title = base::ASCIIToUTF16(test_title); SelectFileWithParams(args); EXPECT_EQ(test_title, base::SysNSStringToUTF8([GetPanel() message])); } -// Verify that multiple file dialogs are corrected handled. +// Verify that multiple file dialogs are correctly handled. TEST_F(SelectFileDialogMacTest, MultipleDialogs) { - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; SelectFileWithParams(args); NSSavePanel* panel1 = GetPanel(); SelectFileWithParams(args); @@ -454,7 +449,7 @@ // Verify that the default_path argument is respected. TEST_F(SelectFileDialogMacTest, DefaultPath) { - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; args.default_path = base::GetHomeDir().AppendASCII("test.txt"); SelectFileWithParams(args); @@ -474,7 +469,7 @@ const std::string fake_path_normal = "/fake_directory/filename.tar"; const std::string fake_path_multiple = "/fake_directory/filename.tar.gz"; const std::string fake_path_long = "/fake_directory/example.com-123.json"; - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; args.default_path = base::FilePath(FILE_PATH_LITERAL(fake_path_normal)); SelectFileWithParams(args); @@ -509,7 +504,7 @@ GetVectorFromArray<std::string>(extensions_arr[1])); file_type_info.keep_extension_visible = true; - FileDialogArguments args(GetDefaultArguments()); + FileDialogArguments args; args.file_types = &file_type_info; SelectFileWithParams(args); @@ -523,7 +518,7 @@ TEST_F(SelectFileDialogMacTest, Lifetime) { base::scoped_nsobject<NSSavePanel> panel; @autoreleasepool { - auto args = GetDefaultArguments(); + FileDialogArguments args; // Set a type (Save dialogs do not have a delegate). args.type = SelectFileDialog::SELECT_OPEN_MULTI_FILE; SelectFileWithParams(args);
diff --git a/ui/views/controls/color_tracking_icon_view.cc b/ui/views/controls/color_tracking_icon_view.cc index f1fadd8..1d08463 100644 --- a/ui/views/controls/color_tracking_icon_view.cc +++ b/ui/views/controls/color_tracking_icon_view.cc
@@ -11,7 +11,11 @@ ColorTrackingIconView::ColorTrackingIconView(const gfx::VectorIcon& icon, int icon_size) - : icon_(icon), icon_size_(icon_size) {} + : icon_(icon), icon_size_(icon_size) { + // Set the image using a placeholder color. This will allow the ImageView to + // report its preferred size before OnThemeChanged for layout purposes. + SetImage(gfx::CreateVectorIcon(icon_, icon_size_, gfx::kPlaceholderColor)); +} void ColorTrackingIconView::OnThemeChanged() { ImageView::OnThemeChanged();
diff --git a/ui/webui/resources/mojo/BUILD.gn b/ui/webui/resources/mojo/BUILD.gn new file mode 100644 index 0000000..6da3352 --- /dev/null +++ b/ui/webui/resources/mojo/BUILD.gn
@@ -0,0 +1,26 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//tools/typescript/ts_library.gni") + +preprocessed_folder = "$root_gen_dir/ui/webui/resources/preprocessed/mojo" + +ts_library("library") { + root_dir = "$root_gen_dir/mojom-webui" + out_dir = preprocessed_folder + tsconfig_base = "tsconfig_base.json" + composite = true + + in_files = [ + "mojo/public/mojom/base/big_buffer.mojom-webui.js", + "mojo/public/mojom/base/string16.mojom-webui.js", + "mojo/public/mojom/base/time.mojom-webui.js", + "url/mojom/url.mojom-webui.js", + ] + + extra_deps = [ + "//mojo/public/mojom/base:base_js__generator", + "//url/mojom:url_mojom_gurl_js__generator", + ] +}
diff --git a/ui/webui/resources/mojo/tsconfig_base.json b/ui/webui/resources/mojo/tsconfig_base.json new file mode 100644 index 0000000..99a81eca --- /dev/null +++ b/ui/webui/resources/mojo/tsconfig_base.json
@@ -0,0 +1,6 @@ +{ + "extends": "../../../../tools/typescript/tsconfig_base.json", + "compilerOptions": { + "allowJs": true + } +}
diff --git a/url/ipc/url_param_traits_unittest.cc b/url/ipc/url_param_traits_unittest.cc index a49203d..79b5b43 100644 --- a/url/ipc/url_param_traits_unittest.cc +++ b/url/ipc/url_param_traits_unittest.cc
@@ -4,7 +4,6 @@ #include <string> -#include "base/stl_util.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_utils.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/url/mojom/url_gurl_mojom_traits_unittest.cc b/url/mojom/url_gurl_mojom_traits_unittest.cc index 5be941c..357a701 100644 --- a/url/mojom/url_gurl_mojom_traits_unittest.cc +++ b/url/mojom/url_gurl_mojom_traits_unittest.cc
@@ -4,7 +4,6 @@ #include <utility> -#include "base/stl_util.h" #include "base/test/task_environment.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h"