diff --git a/DEPS b/DEPS index c2a9faf..f10b7b44 100644 --- a/DEPS +++ b/DEPS
@@ -138,11 +138,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': 'b97824d4d1d1b1ae3ab87ec5c122f6da855923ca', + 'skia_revision': 'f91aeb259e095bf8c942063f7f2525fef2d5020c', # 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': 'e1d02819408cc1a1606b91429482c6b697245cba', + 'v8_revision': '17007c11a74c87be69bf173e4db15d50bcaf1593', # 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. @@ -150,15 +150,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': '08b5629336d0a8a8a97d0482b8df153cbd7a2110', + 'angle_revision': '2d223552e3fe454420a8fcd936390104009e0ba5', # 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': 'ea38f958d07254e3cda97a7347058da130973746', + 'swiftshader_revision': '9283b2559c0580dbb8fb6effffd11dc3f28b5f42', # 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': '7e5908802f90d171145b4531d11814332dd3ce75', + 'pdfium_revision': 'f0f9a8f1fd94d812afbe9df814657340d43fda79', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -173,7 +173,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling googletest # and whatever else without interference from each other. - 'googletest_revision': '076b7f7788833ca31206bc30e5a2cfbdb9628f29', + 'googletest_revision': 'd7003576dd133856432e2e07340f45926242cc3a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling lighttpd # and whatever else without interference from each other. @@ -201,7 +201,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': '9e5dbd8b462b23d989f6ce32ae72fd2a8cb09ee3', + 'catapult_revision': 'baea8814b88ef71a1f1866c5efa19f6f8a7e5b1c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -269,11 +269,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'shaderc_revision': '8b2600f715e5f4996718a47925389a0af268c79f', + 'shaderc_revision': '2a888de1db058adc9093118a7d9d28d4db1d1480', # 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': '8f4046b0b66765d2cb00c9a477e757c4e3e99fe9', + 'dawn_revision': '872c1d7fe98a41359364e96609231f9700160d7a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -477,7 +477,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'df4ef89b8001252758209b93f2c830779002cfc1', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '0f1656a03a06f4c00561bf0664833125bdf4c08e', 'condition': 'checkout_ios', }, @@ -709,7 +709,7 @@ Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'), 'src/third_party/dav1d/libdav1d': - Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + 'fc3777b44c0449180073665eb78070d388b11738', + Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + 'a1e3f35842de92b526422af05360c84cf233f07f', 'src/third_party/dawn': Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'), @@ -832,7 +832,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'bc23ca13f1b3b684d9c2a127f33b618a71644829', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2313020206fce572179a52ac2cce0d342491e1ab', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -901,7 +901,7 @@ }, 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '9db72785beb33a89729d801249b23fdda79ae91d', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'f9d08a25fbe17e0677a89d398f4d7f232339c3f9', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1081,7 +1081,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '28cc5f3646bac9d01e583621f611303f738424f0', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'bb9511684f70a735b3b909712666021e178c93e7', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + '51ca718c3adf0ddedacd7df25fe45f67dc5a9ce1', @@ -1187,7 +1187,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'ba0eb777bf5a0b54add3bf54e49cd134130489f3', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c0d17117afe95d13bb1920fff2aa67022959a356', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1355,7 +1355,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '1dee91aec9a626e92f549643832e30ff19810600', + Var('webrtc_git') + '/src.git' + '@' + '61d8ee10b61171cd4b90ed36c178f223f99256cf', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1396,7 +1396,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d00e241a16e018aa78317db88f2a236d66bf3653', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a8103e5d2c6452965b6cf83373336a275827a1fe', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 3ccbe478..171164f 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -716,15 +716,93 @@ (), ), ( + r'/\bstd::stoi\b', + ( + 'std::stoi uses exceptions to communicate results. ', + 'Use base::StringToInt() instead.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( + r'/\bstd::stol\b', + ( + 'std::stol uses exceptions to communicate results. ', + 'Use base::StringToInt() instead.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( + r'/\bstd::stoul\b', + ( + 'std::stoul uses exceptions to communicate results. ', + 'Use base::StringToUint() instead.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( + r'/\bstd::stoll\b', + ( + 'std::stoll uses exceptions to communicate results. ', + 'Use base::StringToInt64() instead.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( + r'/\bstd::stoull\b', + ( + 'std::stoull uses exceptions to communicate results. ', + 'Use base::StringToUint64() instead.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( + r'/\bstd::stof\b', + ( + 'std::stof uses exceptions to communicate results. ', + 'For locale-independent values, e.g. reading numbers from disk', + 'profiles, use base::StringToDouble().', + 'For user-visible values, parse using ICU.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( + r'/\bstd::stod\b', + ( + 'std::stod uses exceptions to communicate results. ', + 'For locale-independent values, e.g. reading numbers from disk', + 'profiles, use base::StringToDouble().', + 'For user-visible values, parse using ICU.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( + r'/\bstd::stold\b', + ( + 'std::stold uses exceptions to communicate results. ', + 'For locale-independent values, e.g. reading numbers from disk', + 'profiles, use base::StringToDouble().', + 'For user-visible values, parse using ICU.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. + ), + ( r'/\bstd::to_string\b', ( 'std::to_string is locale dependent and slower than alternatives.', - 'For locale-independent strings, e.g. writing numbers to and from', - 'disk profiles, use base::NumberToString().', + 'For locale-independent strings, e.g. writing numbers to disk', + 'profiles, use base::NumberToString().', 'For user-visible strings, use base::FormatNumber() and', 'the related functions in base/i18n/number_formatting.h.', ), - False, # Only a warning for now since it is already used, + False, # Only a warning since it is already used. [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), ( @@ -736,6 +814,14 @@ [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), ( + r'/\bstd::weak_ptr\b', + ( + 'std::weak_ptr should not be used. Use base::WeakPtr instead.', + ), + True, + [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. + ), + ( r'/\blong long\b', ( 'long long is banned. Use stdint.h if you need a 64 bit number.', @@ -775,7 +861,7 @@ 'std::function is banned. Instead use base::Callback which directly', 'supports Chromium\'s weak pointers, ref counting and more.', ), - False, # Only a warning since there are dozens of uses already. + False, # Only a warning since it is already used. [_THIRD_PARTY_EXCEPT_BLINK], # Do not warn in third_party folders. ), (
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc index 455db38..3fd79eb 100644 --- a/android_webview/browser/aw_permission_manager.cc +++ b/android_webview/browser/aw_permission_manager.cc
@@ -336,6 +336,7 @@ break; case PermissionType::MIDI: case PermissionType::SENSORS: + case PermissionType::WAKE_LOCK_SCREEN: // PermissionType::SENSORS requests are always granted so that access // to device motion and device orientation data (and underlying // sensors) works in the WebView. SensorProviderImpl::GetSensor() @@ -343,6 +344,10 @@ pending_request_raw->SetPermissionStatus(permissions[i], PermissionStatus::GRANTED); break; + case PermissionType::WAKE_LOCK_SYSTEM: + pending_request_raw->SetPermissionStatus(permissions[i], + PermissionStatus::DENIED); + break; case PermissionType::NUM: NOTREACHED() << "PermissionType::NUM was not expected here."; pending_request_raw->SetPermissionStatus(permissions[i], @@ -530,6 +535,8 @@ break; case PermissionType::MIDI: case PermissionType::SENSORS: + case PermissionType::WAKE_LOCK_SCREEN: + case PermissionType::WAKE_LOCK_SYSTEM: // There is nothing to cancel so this is simply ignored. break; case PermissionType::NUM:
diff --git a/android_webview/browser/net/aw_network_change_notifier_factory.cc b/android_webview/browser/net/aw_network_change_notifier_factory.cc index f05627f9..9821511 100644 --- a/android_webview/browser/net/aw_network_change_notifier_factory.cc +++ b/android_webview/browser/net/aw_network_change_notifier_factory.cc
@@ -5,6 +5,7 @@ #include "android_webview/browser/net/aw_network_change_notifier_factory.h" #include "android_webview/browser/net/aw_network_change_notifier.h" +#include "base/memory/ptr_util.h" namespace android_webview { @@ -12,8 +13,9 @@ AwNetworkChangeNotifierFactory::~AwNetworkChangeNotifierFactory() {} -net::NetworkChangeNotifier* AwNetworkChangeNotifierFactory::CreateInstance() { - return new AwNetworkChangeNotifier(&delegate_); +std::unique_ptr<net::NetworkChangeNotifier> +AwNetworkChangeNotifierFactory::CreateInstance() { + return base::WrapUnique(new AwNetworkChangeNotifier(&delegate_)); } } // namespace android_webview
diff --git a/android_webview/browser/net/aw_network_change_notifier_factory.h b/android_webview/browser/net/aw_network_change_notifier_factory.h index 747cadb..a6b02cf4 100644 --- a/android_webview/browser/net/aw_network_change_notifier_factory.h +++ b/android_webview/browser/net/aw_network_change_notifier_factory.h
@@ -5,6 +5,8 @@ #ifndef ANDROID_WEBVIEW_BROWSER_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_ #define ANDROID_WEBVIEW_BROWSER_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_ +#include <memory> + #include "net/android/network_change_notifier_delegate_android.h" #include "net/base/network_change_notifier_factory.h" @@ -27,7 +29,7 @@ ~AwNetworkChangeNotifierFactory() override; // NetworkChangeNotifierFactory: - net::NetworkChangeNotifier* CreateInstance() override; + std::unique_ptr<net::NetworkChangeNotifier> CreateInstance() override; private: // Delegate passed to the instances created by this class.
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index faf0ea4..9ddd46c 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -2106,6 +2106,8 @@ "shell/toplevel_window.cc", "shell/toplevel_window.h", "shell_test_api.cc", + "system/message_center/test_notifier_settings_controller.cc", + "system/message_center/test_notifier_settings_controller.h", "system/palette/palette_tray_test_api.cc", "system/palette/palette_tray_test_api.h", "system/power/power_button_controller_test_api.cc",
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc index 029a1fe..c6c21b1 100644 --- a/ash/accelerators/accelerator_controller_impl.cc +++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -744,6 +744,9 @@ l10n_util::GetStringUTF16( IDS_ASH_VOICE_INTERACTION_DISABLED_BY_ACCOUNT_MESSAGE)); return; + case mojom::AssistantAllowedState::DISALLOWED_BY_KIOSK_MODE: + // No need to show toast in KIOSK mode. + return; case mojom::AssistantAllowedState::ALLOWED: // Nothing need to do if allowed. break;
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 881847d..69d9867 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -1105,56 +1105,62 @@ TEST_F(AcceleratorControllerTest, TabletModeVolumeAdjustHistogram) { Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); base::HistogramTester histogram_tester; - EXPECT_TRUE( - histogram_tester.GetAllSamples(kTabletCountOfVolumeAdjustType).empty()); const ui::Accelerator kVolumeDown(ui::VKEY_VOLUME_DOWN, ui::EF_NONE); const ui::Accelerator kVolumeUp(ui::VKEY_VOLUME_UP, ui::EF_NONE); - ASSERT_FALSE(features::IsSwapSideVolumeButtonsForOrientationEnabled()); - // Starts with volume down but ends with an overall-increased volume when - // features::kSwapSideVolumeButtonsForOrientation is disabled. - ProcessInController(kVolumeDown); - ProcessInController(kVolumeUp); - ProcessInController(kVolumeUp); - EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); - EXPECT_FALSE( - histogram_tester.GetAllSamples(kTabletCountOfVolumeAdjustType).empty()); - histogram_tester.ExpectBucketCount( - kTabletCountOfVolumeAdjustType, - TabletModeVolumeAdjustType::kAccidentalAdjustWithSwapDisabled, 1); - // Starts with volume up and ends with an overall-increased volume when - // features::kSwapSideVolumeButtonsForOrientation is disabled. - ProcessInController(kVolumeUp); - ProcessInController(kVolumeUp); - ProcessInController(kVolumeUp); - EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); - histogram_tester.ExpectBucketCount( - kTabletCountOfVolumeAdjustType, - TabletModeVolumeAdjustType::kNormalAdjustWithSwapDisabled, 1); + // Disable features::kSwapSideVolumeButtonsForOrientation. + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + features::kSwapSideVolumeButtonsForOrientation); + EXPECT_FALSE(features::IsSwapSideVolumeButtonsForOrientationEnabled()); + EXPECT_TRUE( + histogram_tester.GetAllSamples(kTabletCountOfVolumeAdjustType).empty()); + // Starts with volume down but ends with an overall-increased volume. + ProcessInController(kVolumeDown); + ProcessInController(kVolumeUp); + ProcessInController(kVolumeUp); + EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); + EXPECT_FALSE( + histogram_tester.GetAllSamples(kTabletCountOfVolumeAdjustType).empty()); + histogram_tester.ExpectBucketCount( + kTabletCountOfVolumeAdjustType, + TabletModeVolumeAdjustType::kAccidentalAdjustWithSwapDisabled, 1); - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kSwapSideVolumeButtonsForOrientation); - EXPECT_TRUE(features::IsSwapSideVolumeButtonsForOrientationEnabled()); - // Starts with volume up but ends with an overall-decreased volume when - // features::kSwapSideVolumeButtonsForOrientation is enabled. - ProcessInController(kVolumeUp); - ProcessInController(kVolumeDown); - ProcessInController(kVolumeDown); - EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); - histogram_tester.ExpectBucketCount( - kTabletCountOfVolumeAdjustType, - TabletModeVolumeAdjustType::kAccidentalAdjustWithSwapEnabled, 1); + // Starts with volume up and ends with an overall-increased volume. + ProcessInController(kVolumeUp); + ProcessInController(kVolumeUp); + ProcessInController(kVolumeUp); + EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); + histogram_tester.ExpectBucketCount( + kTabletCountOfVolumeAdjustType, + TabletModeVolumeAdjustType::kNormalAdjustWithSwapDisabled, 1); + } - // Starts with volume up and ends with an overall-increased volume when - // features::kSwapSideVolumeButtonsForOrientation is enabled. - ProcessInController(kVolumeUp); - ProcessInController(kVolumeUp); - ProcessInController(kVolumeUp); - EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); - histogram_tester.ExpectBucketCount( - kTabletCountOfVolumeAdjustType, - TabletModeVolumeAdjustType::kNormalAdjustWithSwapEnabled, 1); + // Enable features::kSwapSideVolumeButtonsForOrientation. + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kSwapSideVolumeButtonsForOrientation); + EXPECT_TRUE(features::IsSwapSideVolumeButtonsForOrientationEnabled()); + // Starts with volume up but ends with an overall-decreased volume. + ProcessInController(kVolumeUp); + ProcessInController(kVolumeDown); + ProcessInController(kVolumeDown); + EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); + histogram_tester.ExpectBucketCount( + kTabletCountOfVolumeAdjustType, + TabletModeVolumeAdjustType::kAccidentalAdjustWithSwapEnabled, 1); + + // Starts with volume up and ends with an overall-increased volume. + ProcessInController(kVolumeUp); + ProcessInController(kVolumeUp); + ProcessInController(kVolumeUp); + EXPECT_TRUE(test_api_->TriggerTabletModeVolumeAdjustTimer()); + histogram_tester.ExpectBucketCount( + kTabletCountOfVolumeAdjustType, + TabletModeVolumeAdjustType::kNormalAdjustWithSwapEnabled, 1); + } } class SideVolumeButtonAcceleratorTest
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 341c92a1..712b973 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -189,17 +189,27 @@ // "zoom out" case when releasing an item being dragged. class ItemMoveAnimationDelegate : public gfx::AnimationDelegate { public: - explicit ItemMoveAnimationDelegate(views::View* view) : view_(view) {} + explicit ItemMoveAnimationDelegate(AppListItemView* view, + bool is_released_drag_view) + : view_(view), is_released_drag_view_(is_released_drag_view) { + if (is_released_drag_view_) + view_->title()->SetVisible(false); + } void AnimationEnded(const gfx::Animation* animation) override { + if (is_released_drag_view_) + view_->title()->SetVisible(true); view_->SchedulePaint(); } void AnimationCanceled(const gfx::Animation* animation) override { + if (is_released_drag_view_) + view_->title()->SetVisible(true); view_->SchedulePaint(); } private: - views::View* view_; + AppListItemView* view_; + bool is_released_drag_view_; DISALLOW_COPY_AND_ASSIGN(ItemMoveAnimationDelegate); }; @@ -724,6 +734,11 @@ } SetAsFolderDroppingTarget(drop_target_, false); + + // Keep track of the |drag_view| after it is released to ensure that it does + // not have a visible title until its animation to ideal bounds is complete. + AppListItemView* released_drag_view = drag_view_; + ClearDragState(); UpdatePaging(); if (GetWidget()) { @@ -735,7 +750,7 @@ base::AutoReset<bool> auto_reset(&ignore_layout_, true); GetWidget()->LayoutRootViewIfNecessary(); } - AnimateToIdealBounds(); + AnimateToIdealBounds(released_drag_view); if (!cancel && !folder_delegate_) view_structure_.SaveToMetadata(); @@ -1375,7 +1390,7 @@ } } -void AppsGridView::AnimateToIdealBounds() { +void AppsGridView::AnimateToIdealBounds(AppListItemView* released_drag_view) { const gfx::Rect visible_bounds(GetVisibleBounds()); CalculateIdealBoundsForFolder(); @@ -1400,8 +1415,9 @@ } else if (visible || bounds_animator_.IsAnimating(view)) { bounds_animator_.AnimateViewTo(view, target); bounds_animator_.SetAnimationDelegate( - view, std::unique_ptr<gfx::AnimationDelegate>( - new ItemMoveAnimationDelegate(view))); + view, + std::make_unique<ItemMoveAnimationDelegate>( + view, view == released_drag_view /* is_released_drag_view */)); } else { view->SetBoundsRect(target); } @@ -1620,7 +1636,7 @@ void AppsGridView::OnReorderTimer() { reorder_placeholder_ = drop_target_; MaybeCreateDragReorderAccessibilityEvent(); - AnimateToIdealBounds(); + AnimateToIdealBounds(nullptr /* released_drag_view */); CreateGhostImageView(); } @@ -1894,7 +1910,7 @@ drag_view_ = nullptr; } ClearDragState(); - AnimateToIdealBounds(); + AnimateToIdealBounds(nullptr /* released_drag_view */); if (!folder_delegate_) view_structure_.SaveToMetadata(); @@ -2592,7 +2608,7 @@ view_structure_.LoadFromMetadata(); UpdateColsAndRowsForFolder(); UpdatePaging(); - AnimateToIdealBounds(); + AnimateToIdealBounds(nullptr /* released_drag_view */); } void AppsGridView::OnAppListItemHighlight(size_t index, bool highlight) {
diff --git a/ash/app_list/views/apps_grid_view.h b/ash/app_list/views/apps_grid_view.h index 48879a6..aa54bd0f 100644 --- a/ash/app_list/views/apps_grid_view.h +++ b/ash/app_list/views/apps_grid_view.h
@@ -350,7 +350,7 @@ // Calculates the item views' bounds for folder. void CalculateIdealBoundsForFolder(); - void AnimateToIdealBounds(); + void AnimateToIdealBounds(AppListItemView* released_drag_view); // Invoked when the given |view|'s current bounds and target bounds are on // different rows. To avoid moving diagonally, |view| would be put into a
diff --git a/ash/autoclick/autoclick_scroll_position_handler.cc b/ash/autoclick/autoclick_scroll_position_handler.cc index f396c72..02fa897 100644 --- a/ash/autoclick/autoclick_scroll_position_handler.cc +++ b/ash/autoclick/autoclick_scroll_position_handler.cc
@@ -10,6 +10,7 @@ #include "third_party/skia/include/core/SkRect.h" #include "ui/aura/window.h" #include "ui/compositor/layer.h" +#include "ui/gfx/animation/linear_animation.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/paint_vector_icon.h" @@ -19,9 +20,12 @@ namespace ash { namespace { -int kScrollBackgroundSizeInDips = 32; -int kScrollIconSizeInDips = 24; -SkColor kIconBackgroundColor = SkColorSetARGB(255, 128, 134, 139); +constexpr int kScrollBackgroundSizeInDips = 32; +constexpr int kScrollIconSizeInDips = 24; +constexpr SkColor kIconBackgroundColor = SkColorSetARGB(255, 128, 134, 139); +constexpr base::TimeDelta kAnimationTime = + base::TimeDelta::FromMilliseconds(500); +constexpr float kFadedOpacity = 0.5; } // namespace // View of the AutoclickScrollPositionHandler. Draws the actual contents and @@ -52,9 +56,14 @@ kScrollBackgroundSizeInDips, kScrollBackgroundSizeInDips)); widget_->Show(); + widget_->SetOpacity(1.0); SchedulePaint(); } + void UpdateForAnimationStep(gfx::Animation* animation) { + widget_->SetOpacity(animation->CurrentValueBetween(1.0, kFadedOpacity)); + } + private: void OnPaint(gfx::Canvas* canvas) override { gfx::Point center(kScrollBackgroundSizeInDips / 2, @@ -84,9 +93,13 @@ AutoclickScrollPositionHandler::AutoclickScrollPositionHandler( const gfx::Point& center_point_in_screen, - views::Widget* widget) { + views::Widget* widget) + : gfx::LinearAnimation(nullptr) { view_ = std::make_unique<AutoclickScrollPositionView>(center_point_in_screen, widget); + SetDuration(kAnimationTime); + animation_state_ = AnimationState::kWait; + Start(); } AutoclickScrollPositionHandler::~AutoclickScrollPositionHandler() { @@ -97,6 +110,22 @@ const gfx::Point& center_point_in_screen, views::Widget* widget) { view_->SetLocation(center_point_in_screen); + animation_state_ = AnimationState::kWait; + Start(); +} + +void AutoclickScrollPositionHandler::AnimateToState(double state) { + if (animation_state_ == AnimationState::kFade) + view_->UpdateForAnimationStep(this); +} + +void AutoclickScrollPositionHandler::AnimationStopped() { + if (animation_state_ == AnimationState::kWait) { + animation_state_ = AnimationState::kFade; + Start(); + } else if (animation_state_ == AnimationState::kFade) { + animation_state_ = AnimationState::kDone; + } } } // namespace ash
diff --git a/ash/autoclick/autoclick_scroll_position_handler.h b/ash/autoclick/autoclick_scroll_position_handler.h index 848f4d07..442b2b4 100644 --- a/ash/autoclick/autoclick_scroll_position_handler.h +++ b/ash/autoclick/autoclick_scroll_position_handler.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/macros.h" +#include "ui/gfx/animation/linear_animation.h" #include "ui/gfx/geometry/point.h" #include "ui/views/widget/widget.h" @@ -17,18 +18,30 @@ // AutoclickScrollPositionHandler displays the position at which the next scroll // event will occur, giving users a sense of which part of the screen will -// receive scroll events. -class AutoclickScrollPositionHandler { +// receive scroll events. It will display at full opacity for a short time, then +// partially fade out to keep from blocking content. +class AutoclickScrollPositionHandler : public gfx::LinearAnimation { public: AutoclickScrollPositionHandler(const gfx::Point& center_point_in_screen, views::Widget* widget); - ~AutoclickScrollPositionHandler(); + ~AutoclickScrollPositionHandler() override; void SetCenter(const gfx::Point& center_point_in_screen, views::Widget* widget); private: + enum AnimationState { + kWait, + kFade, + kDone, + }; + + // Overridden from gfx::LinearAnimation. + void AnimateToState(double state) override; + void AnimationStopped() override; + std::unique_ptr<AutoclickScrollPositionView> view_; + AnimationState animation_state_ = kDone; DISALLOW_COPY_AND_ASSIGN(AutoclickScrollPositionHandler); };
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index 8dddeeb..510c218 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -123,6 +123,11 @@ "note_taking_client.h", "notification_utils.cc", "notification_utils.h", + "notifier_metadata.cc", + "notifier_metadata.h", + "notifier_settings_controller.cc", + "notifier_settings_controller.h", + "notifier_settings_observer.h", "pagination/pagination_controller.cc", "pagination/pagination_controller.h", "pagination/pagination_model.cc",
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index f80aad7..a424777e 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -79,7 +79,7 @@ "SystemTrayFeaturePodsPagination", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kSwapSideVolumeButtonsForOrientation{ - "SwapSideVolumeButtonsForOrientation", base::FEATURE_DISABLED_BY_DEFAULT}; + "SwapSideVolumeButtonsForOrientation", base::FEATURE_ENABLED_BY_DEFAULT}; bool IsHideArcMediaNotificationsEnabled() { return base::FeatureList::IsEnabled(kMediaSessionNotification) &&
diff --git a/ash/public/cpp/notifier_metadata.cc b/ash/public/cpp/notifier_metadata.cc new file mode 100644 index 0000000..4290293 --- /dev/null +++ b/ash/public/cpp/notifier_metadata.cc
@@ -0,0 +1,32 @@ +// 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. + +#include "ash/public/cpp/notifier_metadata.h" + +namespace ash { + +NotifierMetadata::NotifierMetadata() = default; +NotifierMetadata::NotifierMetadata(const NotifierMetadata& other) = default; +NotifierMetadata::NotifierMetadata(NotifierMetadata&& other) = default; + +NotifierMetadata::NotifierMetadata( + const message_center::NotifierId& notifier_id, + const base::string16& name, + bool enabled, + bool enforced, + const gfx::ImageSkia& icon) + : notifier_id(notifier_id), + name(name), + enabled(enabled), + enforced(enforced), + icon(icon) {} + +NotifierMetadata::~NotifierMetadata() = default; + +NotifierMetadata& NotifierMetadata::operator=(const NotifierMetadata& other) = + default; +NotifierMetadata& NotifierMetadata::operator=(NotifierMetadata&& other) = + default; + +} // namespace ash
diff --git a/ash/public/cpp/notifier_metadata.h b/ash/public/cpp/notifier_metadata.h new file mode 100644 index 0000000..c29b9da3 --- /dev/null +++ b/ash/public/cpp/notifier_metadata.h
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_PUBLIC_CPP_NOTIFIER_METADATA_H_ +#define ASH_PUBLIC_CPP_NOTIFIER_METADATA_H_ + +#include "ash/public/cpp/ash_public_export.h" +#include "base/strings/string16.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/message_center/public/cpp/notifier_id.h" + +namespace ash { + +// Ash-specific information about a Message Center notifier. +struct ASH_PUBLIC_EXPORT NotifierMetadata { + NotifierMetadata(); + NotifierMetadata(const NotifierMetadata& other); + NotifierMetadata(NotifierMetadata&& other); + NotifierMetadata(const message_center::NotifierId& notifier_id, + const base::string16& name, + bool enabled, + bool enforced, + const gfx::ImageSkia& icon); + + ~NotifierMetadata(); + + NotifierMetadata& operator=(const NotifierMetadata& other); + NotifierMetadata& operator=(NotifierMetadata&& other); + + // The notifier (e.g. an extension). + message_center::NotifierId notifier_id; + + // The user-visible name of the notifier (e.g. an extension's name). + base::string16 name; + + // True if notifications from the notifier are presently enabled. + bool enabled = false; + + // True if the setting is enforced by administrator and the user can't change. + bool enforced = false; + + // An icon displayed next to the name. + gfx::ImageSkia icon; +}; + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_NOTIFIER_METADATA_H_
diff --git a/ash/public/cpp/notifier_settings_controller.cc b/ash/public/cpp/notifier_settings_controller.cc new file mode 100644 index 0000000..3fdeb7b5 --- /dev/null +++ b/ash/public/cpp/notifier_settings_controller.cc
@@ -0,0 +1,32 @@ +// 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. + +#include "ash/public/cpp/notifier_settings_controller.h" + +#include "base/logging.h" + +namespace ash { + +namespace { + +NotifierSettingsController* g_instance = nullptr; + +} // namespace + +// static +NotifierSettingsController* NotifierSettingsController::Get() { + return g_instance; +} + +NotifierSettingsController::NotifierSettingsController() { + DCHECK_EQ(nullptr, g_instance); + g_instance = this; +} + +NotifierSettingsController::~NotifierSettingsController() { + DCHECK_EQ(this, g_instance); + g_instance = nullptr; +} + +} // namespace ash
diff --git a/ash/public/cpp/notifier_settings_controller.h b/ash/public/cpp/notifier_settings_controller.h new file mode 100644 index 0000000..541929c --- /dev/null +++ b/ash/public/cpp/notifier_settings_controller.h
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_PUBLIC_CPP_NOTIFIER_SETTINGS_CONTROLLER_H_ +#define ASH_PUBLIC_CPP_NOTIFIER_SETTINGS_CONTROLLER_H_ + +#include "ash/public/cpp/ash_public_export.h" +#include "base/macros.h" + +namespace message_center { +struct NotifierId; +} + +namespace ash { + +class NotifierSettingsObserver; + +// An interface, implemented by Chrome, which allows Ash to read and write +// settings and UI data regarding message center notification sources. +class ASH_PUBLIC_EXPORT NotifierSettingsController { + public: + // Returns the singleton instance. + static NotifierSettingsController* Get(); + + // Assembles the list of active notifiers and updates all + // NotifierSettingsObservers via OnNotifiersUpdated. + virtual void GetNotifiers() = 0; + + // Called to toggle the |enabled| state of a specific notifier (in response to + // a user selecting or de-selecting that notifier). + virtual void SetNotifierEnabled(const message_center::NotifierId& notifier_id, + bool enabled) = 0; + + virtual void AddNotifierSettingsObserver( + NotifierSettingsObserver* listener) = 0; + virtual void RemoveNotifierSettingsObserver( + NotifierSettingsObserver* listener) = 0; + + protected: + NotifierSettingsController(); + virtual ~NotifierSettingsController(); + + DISALLOW_COPY_AND_ASSIGN(NotifierSettingsController); +}; + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_NOTIFIER_SETTINGS_CONTROLLER_H_
diff --git a/ash/public/cpp/notifier_settings_observer.h b/ash/public/cpp/notifier_settings_observer.h new file mode 100644 index 0000000..104d9873 --- /dev/null +++ b/ash/public/cpp/notifier_settings_observer.h
@@ -0,0 +1,42 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_PUBLIC_CPP_NOTIFIER_SETTINGS_OBSERVER_H_ +#define ASH_PUBLIC_CPP_NOTIFIER_SETTINGS_OBSERVER_H_ + +#include <vector> + +#include "ash/public/cpp/ash_public_export.h" +#include "base/observer_list_types.h" + +namespace message_center { +struct NotifierId; +} + +namespace gfx { +class ImageSkia; +} + +namespace ash { + +struct NotifierMetadata; + +// An interface used to listen for changes to notifier settings information, +// implemented by any view that displays info about notifiers. +class ASH_PUBLIC_EXPORT NotifierSettingsObserver + : public base::CheckedObserver { + public: + // Sets the user-visible and toggle-able list of notifiers. + virtual void OnNotifiersUpdated( + const std::vector<NotifierMetadata>& notifiers) {} + + // Updates an icon for a notifier previously sent via OnNotifierListUpdated. + virtual void OnNotifierIconUpdated( + const message_center::NotifierId& notifier_id, + const gfx::ImageSkia& icon) {} +}; + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_NOTIFIER_SETTINGS_OBSERVER_H_
diff --git a/ash/public/interfaces/ash_message_center_controller.mojom b/ash/public/interfaces/ash_message_center_controller.mojom index 0b6e2e4..cd74659 100644 --- a/ash/public/interfaces/ash_message_center_controller.mojom +++ b/ash/public/interfaces/ash_message_center_controller.mojom
@@ -5,30 +5,6 @@ module ash.mojom; import "components/arc/common/notifications.mojom"; -import "ui/gfx/image/mojo/image.mojom"; -import "ui/message_center/public/mojo/notification.mojom"; -import "ui/message_center/public/mojo/notifier_id.mojom"; -import "mojo/public/mojom/base/string16.mojom"; -import "mojo/public/mojom/base/unguessable_token.mojom"; - -// A struct that contains information for presenting a notifier in a settings -// panel. -struct NotifierUiData { - // The notifier (e.g. an extension). - message_center.mojom.NotifierId notifier_id; - - // The user-visible name of the notifier (e.g. an extension's name). - mojo_base.mojom.String16 name; - - // True if notifications from the notifier are presently enabled. - bool enabled; - - // True if the setting is enforced by administrator and the user can't change. - bool enforced; - - // An icon displayed next to the name. - gfx.mojom.ImageSkia? icon; -}; // The message center controller funnels notification requests from the client // to the MessageCenter. @@ -38,12 +14,6 @@ // Sets the ARC notification instance. SetArcNotificationsInstance(arc.mojom.NotificationsInstance instance); - UpdateNotifierIcon(message_center.mojom.NotifierId notifier_id, - gfx.mojom.ImageSkia icon); - - NotifierEnabledChanged(message_center.mojom.NotifierId notifier_id, - bool enabled); - // Changes the quiet mode state in the message center. SetQuietMode(bool enabled); }; @@ -53,14 +23,6 @@ // |notification| in ShowClientNotification and the format of the ID is up to // the client. interface AshMessageCenterClient { - // Called when a user enables or disables notifications from the given - // notifier. - SetNotifierEnabled(message_center.mojom.NotifierId notifier_id, bool enabled); - - // Asks the client for a list of notifiers and associated UI information to be - // displayed in a settings panel. - GetNotifierList() => (array<NotifierUiData> notifiers); - // Gets ARC app id from a given package name. GetArcAppIdByPackageName(string package_name) => (string app_id); };
diff --git a/ash/public/interfaces/voice_interaction_controller.mojom b/ash/public/interfaces/voice_interaction_controller.mojom index 5c09282..21b618f 100644 --- a/ash/public/interfaces/voice_interaction_controller.mojom +++ b/ash/public/interfaces/voice_interaction_controller.mojom
@@ -42,7 +42,9 @@ // Disallowed because the device is in public session. DISALLOWED_BY_PUBLIC_SESSION, // Disallowed because the user's account type is currently not supported. - DISALLOWED_BY_ACCOUNT_TYPE + DISALLOWED_BY_ACCOUNT_TYPE, + // Disallowed because the device is in Kiosk mode. + DISALLOWED_BY_KIOSK_MODE }; // Allows observing changes to voice interaction status and settings.
diff --git a/ash/system/message_center/message_center_controller.cc b/ash/system/message_center/message_center_controller.cc index b83611c..4204911 100644 --- a/ash/system/message_center/message_center_controller.cc +++ b/ash/system/message_center/message_center_controller.cc
@@ -128,11 +128,6 @@ binding_set_.AddBinding(this, std::move(request)); } -void MessageCenterController::SetNotifierEnabled(const NotifierId& notifier_id, - bool enabled) { - client_->SetNotifierEnabled(notifier_id, enabled); -} - void MessageCenterController::SetClient( mojom::AshMessageCenterClientAssociatedPtrInfo client) { DCHECK(!client_.is_bound()); @@ -153,19 +148,6 @@ arc_notification_manager_->SetInstance(std::move(arc_notification_instance)); } -void MessageCenterController::UpdateNotifierIcon(const NotifierId& notifier_id, - const gfx::ImageSkia& icon) { - for (auto& listener : notifier_settings_listeners_) - listener.UpdateNotifierIcon(notifier_id, icon); -} - -void MessageCenterController::NotifierEnabledChanged( - const NotifierId& notifier_id, - bool enabled) { - if (!enabled) - MessageCenter::Get()->RemoveNotificationsForNotifierId(notifier_id); -} - void MessageCenterController::SetQuietMode(bool enabled) { MessageCenter::Get()->SetQuietMode(enabled); } @@ -177,37 +159,4 @@ client_->GetArcAppIdByPackageName(package_name, std::move(callback)); } -void MessageCenterController::AddNotifierSettingsListener( - NotifierSettingsListener* listener) { - DCHECK(listener); - notifier_settings_listeners_.AddObserver(listener); -} - -void MessageCenterController::RemoveNotifierSettingsListener( - NotifierSettingsListener* listener) { - DCHECK(listener); - notifier_settings_listeners_.RemoveObserver(listener); -} - -void MessageCenterController::RequestNotifierSettingsUpdate() { - // |client_| may not be bound in unit tests. - if (!client_.is_bound()) - return; - - client_->GetNotifierList(base::BindOnce( - &MessageCenterController::OnGotNotifierList, base::Unretained(this))); -} - -void MessageCenterController::OnGotNotifierList( - std::vector<mojom::NotifierUiDataPtr> ui_data) { - disabled_notifier_count_ = 0; - for (const auto& notifier : ui_data) { - if (!notifier->enabled) - ++disabled_notifier_count_; - } - - for (auto& listener : notifier_settings_listeners_) - listener.OnNotifierListUpdated(ui_data); -} - } // namespace ash
diff --git a/ash/system/message_center/message_center_controller.h b/ash/system/message_center/message_center_controller.h index 1024e42..209df05 100644 --- a/ash/system/message_center/message_center_controller.h +++ b/ash/system/message_center/message_center_controller.h
@@ -22,10 +22,6 @@ class PrefRegistrySimple; -namespace message_center { -struct NotifierId; -} - namespace ash { // This class manages the ash message center and allows clients (like Chrome) to @@ -40,19 +36,11 @@ void BindRequest(mojom::AshMessageCenterControllerRequest request); - // Called when the user has toggled a notifier in the inline settings UI. - void SetNotifierEnabled(const message_center::NotifierId& notifier_id, - bool enabled); - // mojom::AshMessageCenterController: void SetClient( mojom::AshMessageCenterClientAssociatedPtrInfo client) override; void SetArcNotificationsInstance( arc::mojom::NotificationsInstancePtr arc_notification_instance) override; - void UpdateNotifierIcon(const message_center::NotifierId& notifier_id, - const gfx::ImageSkia& icon) override; - void NotifierEnabledChanged(const message_center::NotifierId& notifier_id, - bool enabled) override; void SetQuietMode(bool enabled) override; // Handles get app id calls from ArcNotificationManager. @@ -66,35 +54,7 @@ return inactive_user_notification_blocker_.get(); } - // An interface used to listen for changes to notifier settings information, - // implemented by the view that displays notifier settings. - class NotifierSettingsListener { - public: - // Sets the user-visible and toggle-able list of notifiers. - virtual void OnNotifierListUpdated( - const std::vector<mojom::NotifierUiDataPtr>& ui_data) = 0; - - // Updates an icon for a notifier previously sent via OnNotifierListUpdated. - virtual void UpdateNotifierIcon( - const message_center::NotifierId& notifier_id, - const gfx::ImageSkia& icon) = 0; - }; - - void AddNotifierSettingsListener(NotifierSettingsListener* listener); - void RemoveNotifierSettingsListener(NotifierSettingsListener* listener); - - // Asks the client for the list of notifiers to display. - void RequestNotifierSettingsUpdate(); - - int disabled_notifier_count() const { return disabled_notifier_count_; } - private: - // Number of disabled notifier sources. Updated in OnGotNotifierList. - int disabled_notifier_count_ = 0; - - // Callback for GetNotifierList. - void OnGotNotifierList(std::vector<mojom::NotifierUiDataPtr> ui_data); - std::unique_ptr<FullscreenNotificationBlocker> fullscreen_notification_blocker_; std::unique_ptr<InactiveUserNotificationBlocker> @@ -103,9 +63,6 @@ session_state_notification_blocker_; std::unique_ptr<message_center::NotificationBlocker> all_popup_blocker_; - base::ObserverList<NotifierSettingsListener>::Unchecked - notifier_settings_listeners_; - mojo::BindingSet<mojom::AshMessageCenterController> binding_set_; mojom::AshMessageCenterClientAssociatedPtr client_;
diff --git a/ash/system/message_center/notifier_settings_view.cc b/ash/system/message_center/notifier_settings_view.cc index 7093aae5..f777393 100644 --- a/ash/system/message_center/notifier_settings_view.cc +++ b/ash/system/message_center/notifier_settings_view.cc
@@ -10,6 +10,8 @@ #include <string> #include <utility> +#include "ash/public/cpp/notifier_metadata.h" +#include "ash/public/cpp/notifier_settings_controller.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -55,7 +57,6 @@ namespace ash { using message_center::MessageCenter; -using mojom::NotifierUiData; using message_center::NotifierId; namespace { @@ -101,7 +102,7 @@ // |kNotifierButtonWrapperHeight|. The button is placed in the middle of // the wrapper view by giving padding to the top and the bottom. // The view is focusable and provides focus painter. When the button is disabled -// (NotifierUiData.enforced), it also applies filter to make the color of the +// (NotifierMetadata.enforced), it also applies filter to make the color of the // button dim. class NotifierButtonWrapperView : public views::View { public: @@ -299,11 +300,11 @@ // We do not use views::Checkbox class directly because it doesn't support // showing 'icon'. NotifierSettingsView::NotifierButton::NotifierButton( - const mojom::NotifierUiData& notifier_ui_data, + const NotifierMetadata& notifier, views::ButtonListener* listener) - : views::Button(listener), notifier_id_(notifier_ui_data.notifier_id) { + : views::Button(listener), notifier_id_(notifier.notifier_id) { auto icon_view = std::make_unique<views::ImageView>(); - auto name_view = std::make_unique<views::Label>(notifier_ui_data.name); + auto name_view = std::make_unique<views::Label>(notifier.name); auto checkbox = std::make_unique<views::Checkbox>(base::string16(), this /* listener */); name_view->SetAutoColorReadabilityEnabled(false); @@ -313,11 +314,11 @@ name_view->SetFontList( gfx::FontList().DeriveWithSizeDelta(kLabelFontSizeDelta)); - checkbox->SetChecked(notifier_ui_data.enabled); + checkbox->SetChecked(notifier.enabled); checkbox->SetFocusBehavior(FocusBehavior::NEVER); - checkbox->SetAccessibleName(notifier_ui_data.name); + checkbox->SetAccessibleName(notifier.name); - if (notifier_ui_data.enforced) { + if (notifier.enforced) { Button::SetEnabled(false); checkbox->SetEnabled(false); } @@ -328,7 +329,7 @@ icon_view_ = AddChildView(std::move(icon_view)); name_view_ = AddChildView(std::move(name_view)); - UpdateIconImage(notifier_ui_data.icon); + UpdateIconImage(notifier.icon); } NotifierSettingsView::NotifierButton::~NotifierButton() = default; @@ -494,14 +495,13 @@ no_notifiers_view_ = AddChildView(std::make_unique<EmptyNotifierView>()); - OnNotifierListUpdated({}); - Shell::Get()->message_center_controller()->AddNotifierSettingsListener(this); - Shell::Get()->message_center_controller()->RequestNotifierSettingsUpdate(); + OnNotifiersUpdated({}); + NotifierSettingsController::Get()->AddNotifierSettingsObserver(this); + NotifierSettingsController::Get()->GetNotifiers(); } NotifierSettingsView::~NotifierSettingsView() { - Shell::Get()->message_center_controller()->RemoveNotifierSettingsListener( - this); + NotifierSettingsController::Get()->RemoveNotifierSettingsObserver(this); } bool NotifierSettingsView::IsScrollable() { @@ -531,8 +531,8 @@ return "NotifierSettingsView"; } -void NotifierSettingsView::OnNotifierListUpdated( - const std::vector<mojom::NotifierUiDataPtr>& ui_data) { +void NotifierSettingsView::OnNotifiersUpdated( + const std::vector<NotifierMetadata>& notifiers) { // TODO(tetsui): currently notifier settings list doesn't update after once // it's loaded, in order to retain scroll position. if (scroller_->contents() && buttons_.size() > 0) @@ -544,9 +544,8 @@ contents_view->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kVertical, gfx::Insets(0, kHorizontalMargin))); - size_t notifier_count = ui_data.size(); - for (size_t i = 0; i < notifier_count; ++i) { - NotifierButton* button = new NotifierButton(*ui_data[i], this); + for (const auto& notifier : notifiers) { + NotifierButton* button = new NotifierButton(notifier, this); NotifierButtonWrapperView* wrapper = new NotifierButtonWrapperView(button); wrapper->SetFocusBehavior(FocusBehavior::ALWAYS); @@ -554,8 +553,8 @@ buttons_.insert(button); } - top_label_->SetVisible(notifier_count > 0); - no_notifiers_view_->SetVisible(notifier_count == 0); + top_label_->SetVisible(!buttons_.empty()); + no_notifiers_view_->SetVisible(buttons_.empty()); top_label_->InvalidateLayout(); auto* contents_view_ptr = scroller_->SetContents(std::move(contents_view)); @@ -565,8 +564,8 @@ Layout(); } -void NotifierSettingsView::UpdateNotifierIcon(const NotifierId& notifier_id, - const gfx::ImageSkia& icon) { +void NotifierSettingsView::OnNotifierIconUpdated(const NotifierId& notifier_id, + const gfx::ImageSkia& icon) { for (auto* button : buttons_) { if (button->notifier_id() == notifier_id) { button->UpdateIconImage(icon); @@ -639,9 +638,9 @@ NotifierButton* button = *iter; button->SetChecked(!button->GetChecked()); - Shell::Get()->message_center_controller()->SetNotifierEnabled( - button->notifier_id(), button->GetChecked()); - Shell::Get()->message_center_controller()->RequestNotifierSettingsUpdate(); + NotifierSettingsController::Get()->SetNotifierEnabled(button->notifier_id(), + button->GetChecked()); + NotifierSettingsController::Get()->GetNotifiers(); } } // namespace ash
diff --git a/ash/system/message_center/notifier_settings_view.h b/ash/system/message_center/notifier_settings_view.h index 169bf23e..531b0ff0 100644 --- a/ash/system/message_center/notifier_settings_view.h +++ b/ash/system/message_center/notifier_settings_view.h
@@ -9,7 +9,7 @@ #include <set> #include "ash/ash_export.h" -#include "ash/system/message_center/message_center_controller.h" +#include "ash/public/cpp/notifier_settings_observer.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "ui/message_center/public/cpp/notifier_id.h" @@ -27,10 +27,9 @@ // A class to show the list of notifier extensions / URL patterns and allow // users to customize the settings. -class ASH_EXPORT NotifierSettingsView - : public views::View, - public views::ButtonListener, - public MessageCenterController::NotifierSettingsListener { +class ASH_EXPORT NotifierSettingsView : public views::View, + public views::ButtonListener, + public NotifierSettingsObserver { public: explicit NotifierSettingsView(); ~NotifierSettingsView() override; @@ -39,11 +38,11 @@ void SetQuietModeState(bool is_quiet_mode); - // NotifierSettingsListener: - void OnNotifierListUpdated( - const std::vector<mojom::NotifierUiDataPtr>& ui_data) override; - void UpdateNotifierIcon(const message_center::NotifierId& notifier_id, - const gfx::ImageSkia& icon) override; + // NotifierSettingsObserver: + void OnNotifiersUpdated( + const std::vector<NotifierMetadata>& notifiers) override; + void OnNotifierIconUpdated(const message_center::NotifierId& notifier_id, + const gfx::ImageSkia& icon) override; // views::View: void GetAccessibleNodeData(ui::AXNodeData* node_data) override; @@ -56,7 +55,7 @@ class ASH_EXPORT NotifierButton : public views::Button, public views::ButtonListener { public: - NotifierButton(const mojom::NotifierUiData& notifier_ui_data, + NotifierButton(const NotifierMetadata& notifier, views::ButtonListener* listener); ~NotifierButton() override;
diff --git a/ash/system/message_center/notifier_settings_view_unittest.cc b/ash/system/message_center/notifier_settings_view_unittest.cc index 7169b64..6e9fe3c 100644 --- a/ash/system/message_center/notifier_settings_view_unittest.cc +++ b/ash/system/message_center/notifier_settings_view_unittest.cc
@@ -2,14 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/system/message_center/notifier_settings_view.h" + #include <stddef.h> + #include <memory> +#include "ash/public/cpp/notifier_metadata.h" +#include "ash/public/cpp/notifier_settings_controller.h" #include "ash/public/interfaces/ash_message_center_controller.mojom.h" #include "ash/shell.h" #include "ash/system/message_center/message_center_controller.h" -#include "ash/system/message_center/notifier_settings_view.h" +#include "ash/system/message_center/test_notifier_settings_controller.h" #include "ash/test/ash_test_base.h" +#include "ash/test/ash_test_helper.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" @@ -19,78 +25,19 @@ namespace ash { -using mojom::NotifierUiData; using message_center::NotifierId; -namespace { - -class TestAshMessageCenterClient : public mojom::AshMessageCenterClient { - public: - TestAshMessageCenterClient() : binding_(this) {} - ~TestAshMessageCenterClient() override = default; - - void set_no_notifiers(bool no_notifiers) { no_notifiers_ = no_notifiers; } - - mojom::AshMessageCenterClientAssociatedPtrInfo CreateInterfacePtr() { - mojom::AshMessageCenterClientAssociatedPtr ptr; - binding_.Bind(mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr)); - return ptr.PassInterface(); - } - - // mojom::AshMessageCenterClient: - void SetNotifierEnabled(const NotifierId& notifier_id, - bool enabled) override {} - - void GetNotifierList(GetNotifierListCallback callback) override { - std::vector<mojom::NotifierUiDataPtr> ui_data; - if (!no_notifiers_) { - ui_data.push_back(mojom::NotifierUiData::New( - NotifierId(message_center::NotifierType::APPLICATION, "id"), - base::ASCIIToUTF16("title"), true /* enabled */, false /* enforced */, - gfx::ImageSkia())); - ui_data.push_back(mojom::NotifierUiData::New( - NotifierId(message_center::NotifierType::APPLICATION, "id2"), - base::ASCIIToUTF16("other title"), false /* enabled */, - false /* enforced */, gfx::ImageSkia())); - } - - std::move(callback).Run(std::move(ui_data)); - } - void GetArcAppIdByPackageName( - const std::string& package_name, - GetArcAppIdByPackageNameCallback callback) override { - std::move(callback).Run(std::string()); - } - - private: - bool no_notifiers_ = false; - - mojo::AssociatedBinding<mojom::AshMessageCenterClient> binding_; - - DISALLOW_COPY_AND_ASSIGN(TestAshMessageCenterClient); -}; - -} // namespace - class NotifierSettingsViewTest : public AshTestBase { public: NotifierSettingsViewTest(); ~NotifierSettingsViewTest() override; - void SetUp() override; - void TearDown() override; - - void InitView(); - NotifierSettingsView* GetView() const; - TestAshMessageCenterClient* client() { return &client_; } void SetNoNotifiers(bool no_notifiers) { - client_.set_no_notifiers(no_notifiers); + ash_test_helper()->notifier_settings_controller()->set_no_notifiers( + no_notifiers); } private: - TestAshMessageCenterClient client_; - std::unique_ptr<NotifierSettingsView> notifier_settings_view_; - DISALLOW_COPY_AND_ASSIGN(NotifierSettingsViewTest); }; @@ -98,41 +45,20 @@ NotifierSettingsViewTest::~NotifierSettingsViewTest() = default; -void NotifierSettingsViewTest::SetUp() { - AshTestBase::SetUp(); - SetNoNotifiers(false); - - Shell::Get()->message_center_controller()->SetClient( - client_.CreateInterfacePtr()); -} - -void NotifierSettingsViewTest::TearDown() { - notifier_settings_view_.reset(); - AshTestBase::TearDown(); -} - -void NotifierSettingsViewTest::InitView() { - notifier_settings_view_.reset(); - notifier_settings_view_ = std::make_unique<NotifierSettingsView>(); -} - -NotifierSettingsView* NotifierSettingsViewTest::GetView() const { - return notifier_settings_view_.get(); -} - TEST_F(NotifierSettingsViewTest, TestEmptyNotifierView) { - InitView(); + SetNoNotifiers(false); + auto notifier_settings_view = std::make_unique<NotifierSettingsView>(); // Wait for mojo. base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(GetView()->no_notifiers_view_->GetVisible()); - EXPECT_TRUE(GetView()->top_label_->GetVisible()); + EXPECT_FALSE(notifier_settings_view->no_notifiers_view_->GetVisible()); + EXPECT_TRUE(notifier_settings_view->top_label_->GetVisible()); SetNoNotifiers(true); - InitView(); + notifier_settings_view = std::make_unique<NotifierSettingsView>(); // Wait for mojo. base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(GetView()->no_notifiers_view_->GetVisible()); - EXPECT_FALSE(GetView()->top_label_->GetVisible()); + EXPECT_TRUE(notifier_settings_view->no_notifiers_view_->GetVisible()); + EXPECT_FALSE(notifier_settings_view->top_label_->GetVisible()); } } // namespace ash
diff --git a/ash/system/message_center/test_notifier_settings_controller.cc b/ash/system/message_center/test_notifier_settings_controller.cc new file mode 100644 index 0000000..a5bdef6 --- /dev/null +++ b/ash/system/message_center/test_notifier_settings_controller.cc
@@ -0,0 +1,51 @@ +// 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. + +#include "ash/system/message_center/test_notifier_settings_controller.h" + +#include <vector> + +#include "ash/public/cpp/notifier_metadata.h" +#include "ash/public/cpp/notifier_settings_observer.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/message_center/public/cpp/notifier_id.h" + +namespace ash { + +TestNotifierSettingsController::TestNotifierSettingsController() = default; +TestNotifierSettingsController::~TestNotifierSettingsController() = default; + +void TestNotifierSettingsController::GetNotifiers() { + std::vector<NotifierMetadata> notifiers; + if (!no_notifiers_) { + notifiers.emplace_back(message_center::NotifierId( + message_center::NotifierType::APPLICATION, "id"), + base::ASCIIToUTF16("title"), true /* enabled */, + false /* enforced */, gfx::ImageSkia()); + notifiers.emplace_back( + message_center::NotifierId(message_center::NotifierType::APPLICATION, + "id2"), + base::ASCIIToUTF16("other title"), false /* enabled */, + false /* enforced */, gfx::ImageSkia()); + } + + for (auto& observer : observers_) + observer.OnNotifiersUpdated(notifiers); +} + +void TestNotifierSettingsController::SetNotifierEnabled( + const message_center::NotifierId& notifier_id, + bool enabled) {} + +void TestNotifierSettingsController::AddNotifierSettingsObserver( + NotifierSettingsObserver* observer) { + observers_.AddObserver(observer); +} + +void TestNotifierSettingsController::RemoveNotifierSettingsObserver( + NotifierSettingsObserver* observer) { + observers_.RemoveObserver(observer); +} + +} // namespace ash
diff --git a/ash/system/message_center/test_notifier_settings_controller.h b/ash/system/message_center/test_notifier_settings_controller.h new file mode 100644 index 0000000..42c69df --- /dev/null +++ b/ash/system/message_center/test_notifier_settings_controller.h
@@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_MESSAGE_CENTER_TEST_NOTIFIER_SETTINGS_CONTROLLER_H_ +#define ASH_SYSTEM_MESSAGE_CENTER_TEST_NOTIFIER_SETTINGS_CONTROLLER_H_ + +#include "ash/public/cpp/notifier_settings_controller.h" +#include "base/macros.h" +#include "base/observer_list.h" + +namespace ash { + +class TestNotifierSettingsController : public NotifierSettingsController { + public: + TestNotifierSettingsController(); + ~TestNotifierSettingsController() override; + + void set_no_notifiers(bool no_notifiers) { no_notifiers_ = no_notifiers; } + + // NotifierSettingsController: + void GetNotifiers() override; + void SetNotifierEnabled(const message_center::NotifierId& notifier_id, + bool enabled) override; + void AddNotifierSettingsObserver(NotifierSettingsObserver* observer) override; + void RemoveNotifierSettingsObserver( + NotifierSettingsObserver* observer) override; + + private: + bool no_notifiers_ = false; + + base::ObserverList<NotifierSettingsObserver> observers_; + + DISALLOW_COPY_AND_ASSIGN(TestNotifierSettingsController); +}; + +} // namespace ash + +#endif // ASH_SYSTEM_MESSAGE_CENTER_TEST_NOTIFIER_SETTINGS_CONTROLLER_H_
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h index 1ba571fa..b271463 100644 --- a/ash/system/tray/tray_constants.h +++ b/ash/system/tray/tray_constants.h
@@ -241,6 +241,11 @@ constexpr int kUnifiedFeaturePodsPageSpacing = 48; constexpr int kUnifiedNotificationSeparatorThickness = 1; +// Constants used in system tray page transition animations (ms). +constexpr int kUnifiedSystemTrayPageTransitionDurationMs = 250; +constexpr int kUnifiedSystemTrayOverScrollPageTransitionDurationMs = 50; +constexpr double kCollapseThreshold = 0.3; + // Constants used in PageIndicatorView of UnifiedSystemTray. constexpr int kUnifiedPageIndicatorButtonRadius = 3; constexpr SkColor kUnifiedPageIndicatorButtonColor =
diff --git a/ash/system/unified/feature_pod_button.cc b/ash/system/unified/feature_pod_button.cc index 6a3904f..6a9090d0 100644 --- a/ash/system/unified/feature_pod_button.cc +++ b/ash/system/unified/feature_pod_button.cc
@@ -262,6 +262,11 @@ FeaturePodButton::~FeaturePodButton() = default; +double FeaturePodButton::GetOpacityForExpandedAmount(double expanded_amount) { + // TODO(amehfooz): Confirm the animation curve with UX. + return std::max(0., 5. * expanded_amount - 4.); +} + void FeaturePodButton::SetVectorIcon(const gfx::VectorIcon& icon) { icon_button_->SetImage(views::Button::STATE_NORMAL, gfx::CreateVectorIcon(icon, kUnifiedMenuIconColor)); @@ -309,10 +314,16 @@ icon_button_->SetToggled(toggled); } -void FeaturePodButton::SetExpandedAmount(double expanded_amount) { - // TODO(tetsui): Confirm the animation curve with UX. - label_button_->layer()->SetOpacity(std::max(0., 5. * expanded_amount - 4.)); +void FeaturePodButton::SetExpandedAmount(double expanded_amount, + bool fade_icon_button) { label_button_->SetVisible(expanded_amount > 0.0); + label_button_->layer()->SetOpacity( + GetOpacityForExpandedAmount(expanded_amount)); + + if (fade_icon_button) + layer()->SetOpacity(GetOpacityForExpandedAmount(expanded_amount)); + else + layer()->SetOpacity(1.0); } void FeaturePodButton::SetVisibleByContainer(bool visible) {
diff --git a/ash/system/unified/feature_pod_button.h b/ash/system/unified/feature_pod_button.h index ae7dae38..92da75a 100644 --- a/ash/system/unified/feature_pod_button.h +++ b/ash/system/unified/feature_pod_button.h
@@ -136,8 +136,16 @@ // Change the expanded state. 0.0 if collapsed, and 1.0 if expanded. // Otherwise, it shows intermediate state. In the collapsed state, the labels - // are not shown. - void SetExpandedAmount(double expanded_amount); + // are not shown, so the label buttons always fade out as expanded_amount + // decreases. We also need to fade out the icon button when it's not part of + // the buttons visible in the collapsed state. fade_icon_button will be passed + // as true for these cases. + void SetExpandedAmount(double expanded_amount, bool fade_icon_button); + + // Get opacity for a given expanded_amount value. Used to fade out + // all label buttons and icon buttons that are hidden in collapsed state + // while collapsing. + double GetOpacityForExpandedAmount(double expanded_amount); // Only called by the container. Same as SetVisible but doesn't change // |visible_preferred_| flag.
diff --git a/ash/system/unified/feature_pods_container_view.cc b/ash/system/unified/feature_pods_container_view.cc index 889561f..6f62cb8ec 100644 --- a/ash/system/unified/feature_pods_container_view.cc +++ b/ash/system/unified/feature_pods_container_view.cc
@@ -33,8 +33,35 @@ return; expanded_amount_ = expanded_amount; - for (auto* view : children()) - static_cast<FeaturePodButton*>(view)->SetExpandedAmount(expanded_amount_); + int visible_index = 0; + for (auto* view : children()) { + FeaturePodButton* button = static_cast<FeaturePodButton*>(view); + // When collapsing from page 1, buttons below the second row fade out + // while the rest move up into a single row for the collapsed state. + // When collapsing from page > 1, each row of buttons fades out one by one + // and once expanded_amount is less than kCollapseThreshold we begin to + // fade in the single row of buttons for the collapsed state. + if (expanded_amount_ < kCollapseThreshold && + pagination_model_->selected_page() > 0) { + button->SetExpandedAmount(1.0 - expanded_amount, + true /* fade_icon_button */); + } else if (visible_index > kUnifiedFeaturePodMaxItemsInCollapsed) { + int row = (visible_index / kUnifiedFeaturePodItemsInRow) % + kUnifiedFeaturePodItemsRows; + double button_expanded_amount = + expanded_amount + ? std::min(1.0, + expanded_amount + + (0.25 * (kUnifiedFeaturePodItemsRows - row - 1))) + : expanded_amount; + button->SetExpandedAmount(button_expanded_amount, + true /* fade_icon_button */); + } else { + button->SetExpandedAmount(expanded_amount, false /* fade_icon_button */); + } + if (view->GetVisible()) + visible_index++; + } UpdateChildVisibility(); // We have to call Layout() explicitly here. Layout(); @@ -159,10 +186,15 @@ kUnifiedFeaturePodVerticalPadding) * row; - // When fully expanded, or below the second row, always return the same - // position. - if (expanded_amount_ == 1.0 || row > 2) + // Only feature pods visible in the collapsed state (i.e. the first 5 pods) + // move during expansion/collapse. Otherwise, the button position will always + // be constant. + if (expanded_amount_ == 1.0 || + visible_index > kUnifiedFeaturePodMaxItemsInCollapsed || + (pagination_model_->selected_page() > 0 && + expanded_amount_ >= kCollapseThreshold)) { return gfx::Point(x, y); + } int collapsed_x = collapsed_side_padding_ + (kUnifiedFeaturePodCollapsedSize.width() + @@ -170,8 +202,10 @@ visible_index; int collapsed_y = kUnifiedFeaturePodCollapsedVerticalPadding; - // When fully collapsed, just return the collapsed position. - if (expanded_amount_ == 0.0) + // When fully collapsed or collapsing from a different page to the first + // page, just return the collapsed position. + if (expanded_amount_ == 0.0 || (expanded_amount_ < kCollapseThreshold && + pagination_model_->selected_page() > 0)) return gfx::Point(collapsed_x, collapsed_y); // Button width is different between expanded and collapsed states. @@ -246,7 +280,13 @@ for (int i = 0; i < visible_buttons_.view_size(); ++i) { gfx::Rect tile_bounds; gfx::Size child_size; - if (expanded_amount_ > 0.0) { + // When we are on the first page we calculate bounds for an expanded tray + // when expanded_amount is greater than zero. However, when not on the first + // page, we only calculate bounds for an expanded tray until expanded_amount + // is above kCollapseThreshold. Below kCollapseThreshold we return collapsed + // bounds. + if ((expanded_amount_ > 0.0 && pagination_model_->selected_page() == 0) || + expanded_amount_ >= kCollapseThreshold) { child_size = kUnifiedFeaturePodSize; // Flexibly give more height if the child view doesn't fit into the
diff --git a/ash/system/unified/feature_pods_container_view.h b/ash/system/unified/feature_pods_container_view.h index fd43f1f..2e65e344 100644 --- a/ash/system/unified/feature_pods_container_view.h +++ b/ash/system/unified/feature_pods_container_view.h
@@ -90,7 +90,7 @@ // PaginationModelObserver: void TransitionChanged() override; - UnifiedSystemTrayController* controller_; + UnifiedSystemTrayController* const controller_; // Owned by UnifiedSystemTrayModel. PaginationModel* pagination_model_;
diff --git a/ash/system/unified/page_indicator_view.cc b/ash/system/unified/page_indicator_view.cc index 787312e..a89f821 100644 --- a/ash/system/unified/page_indicator_view.cc +++ b/ash/system/unified/page_indicator_view.cc
@@ -189,7 +189,8 @@ SetVisible(expanded_amount > 0.0); expanded_amount_ = expanded_amount; InvalidateLayout(); - layer()->SetOpacity(expanded_amount_); + // TODO(amehfooz): Confirm animation curve with UX. + layer()->SetOpacity(std::max(0., 6 * expanded_amount_ - 5.)); } void PageIndicatorView::TotalPagesChanged() {
diff --git a/ash/system/unified/quiet_mode_feature_pod_controller.cc b/ash/system/unified/quiet_mode_feature_pod_controller.cc index 4a90db6..2047e60 100644 --- a/ash/system/unified/quiet_mode_feature_pod_controller.cc +++ b/ash/system/unified/quiet_mode_feature_pod_controller.cc
@@ -4,6 +4,8 @@ #include "ash/system/unified/quiet_mode_feature_pod_controller.h" +#include "ash/public/cpp/notifier_metadata.h" +#include "ash/public/cpp/notifier_settings_controller.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" @@ -26,8 +28,7 @@ } QuietModeFeaturePodController::~QuietModeFeaturePodController() { - Shell::Get()->message_center_controller()->RemoveNotifierSettingsListener( - this); + NotifierSettingsController::Get()->RemoveNotifierSettingsObserver(this); MessageCenter::Get()->RemoveObserver(this); } @@ -43,13 +44,8 @@ button_->SetIconTooltip(l10n_util::GetStringUTF16( IDS_ASH_STATUS_TRAY_NOTIFICATIONS_TOGGLE_TOOLTIP)); button_->ShowDetailedViewArrow(); + NotifierSettingsController::Get()->AddNotifierSettingsObserver(this); OnQuietModeChanged(MessageCenter::Get()->IsQuietMode()); - - if (button_->GetVisible()) { - Shell::Get()->message_center_controller()->AddNotifierSettingsListener( - this); - Shell::Get()->message_center_controller()->RequestNotifierSettingsUpdate(); - } return button_; } @@ -75,20 +71,6 @@ } void QuietModeFeaturePodController::OnQuietModeChanged(bool in_quiet_mode) { - Update(); -} - -void QuietModeFeaturePodController::OnNotifierListUpdated( - const std::vector<mojom::NotifierUiDataPtr>& ui_data) { - Update(); -} - -void QuietModeFeaturePodController::UpdateNotifierIcon( - const message_center::NotifierId& notifier_id, - const gfx::ImageSkia& icon) {} - -void QuietModeFeaturePodController::Update() { - bool in_quiet_mode = MessageCenter::Get()->IsQuietMode(); button_->SetToggled(in_quiet_mode); if (in_quiet_mode) { @@ -96,11 +78,22 @@ IDS_ASH_STATUS_TRAY_NOTIFICATIONS_DO_NOT_DISTURB_SUBLABEL)); button_->SetLabelTooltip(l10n_util::GetStringUTF16( IDS_ASH_STATUS_TRAY_NOTIFICATIONS_SETTINGS_DO_NOT_DISTURB_TOOLTIP)); + } else if (button_->GetVisible()) { + NotifierSettingsController::Get()->GetNotifiers(); + } +} + +void QuietModeFeaturePodController::OnNotifiersUpdated( + const std::vector<NotifierMetadata>& notifiers) { + if (MessageCenter::Get()->IsQuietMode()) return; + + int disabled_count = 0; + for (const NotifierMetadata& notifier : notifiers) { + if (!notifier.enabled) + ++disabled_count; } - int disabled_count = - Shell::Get()->message_center_controller()->disabled_notifier_count(); if (disabled_count > 0) { button_->SetSubLabel(l10n_util::GetPluralStringFUTF16( IDS_ASH_STATUS_TRAY_NOTIFICATIONS_OFF_FOR_APPS_SUBLABEL,
diff --git a/ash/system/unified/quiet_mode_feature_pod_controller.h b/ash/system/unified/quiet_mode_feature_pod_controller.h index 9cd6e7a9..a8efa88 100644 --- a/ash/system/unified/quiet_mode_feature_pod_controller.h +++ b/ash/system/unified/quiet_mode_feature_pod_controller.h
@@ -6,7 +6,7 @@ #define ASH_SYSTEM_UNIFIED_QUIET_MODE_FEATURE_POD_CONTROLLER_H_ #include "ash/ash_export.h" -#include "ash/system/message_center/message_center_controller.h" +#include "ash/public/cpp/notifier_settings_observer.h" #include "ash/system/unified/feature_pod_controller_base.h" #include "base/macros.h" #include "base/strings/string16.h" @@ -22,7 +22,7 @@ class ASH_EXPORT QuietModeFeaturePodController : public FeaturePodControllerBase, public message_center::MessageCenterObserver, - public MessageCenterController::NotifierSettingsListener { + public NotifierSettingsObserver { public: explicit QuietModeFeaturePodController( UnifiedSystemTrayController* tray_controller); @@ -37,15 +37,11 @@ // message_center::MessageCenterObserver: void OnQuietModeChanged(bool in_quiet_mode) override; - // MessageCenterController::NotifierSettingsListener: - void OnNotifierListUpdated( - const std::vector<mojom::NotifierUiDataPtr>& ui_data) override; - void UpdateNotifierIcon(const message_center::NotifierId& notifier_id, - const gfx::ImageSkia& icon) override; + // NotifierSettingsObserver: + void OnNotifiersUpdated( + const std::vector<NotifierMetadata>& notifiers) override; private: - void Update(); - UnifiedSystemTrayController* const tray_controller_; FeaturePodButton* button_ = nullptr;
diff --git a/ash/system/unified/unified_notifier_settings_controller.cc b/ash/system/unified/unified_notifier_settings_controller.cc index 4669c70..6e8a6ac 100644 --- a/ash/system/unified/unified_notifier_settings_controller.cc +++ b/ash/system/unified/unified_notifier_settings_controller.cc
@@ -8,6 +8,7 @@ #include "ash/system/message_center/notifier_settings_view.h" #include "ash/system/tray/detailed_view_delegate.h" #include "ash/system/tray/tray_detailed_view.h" +#include "ui/message_center/message_center.h" #include "ui/message_center/message_center_observer.h" #include "ui/views/layout/box_layout.h"
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index 34f757c..8605222d 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -32,6 +32,7 @@ #include "ash/system/night_light/night_light_feature_pod_controller.h" #include "ash/system/rotation/rotation_lock_feature_pod_controller.h" #include "ash/system/tray/system_tray_item_uma_type.h" +#include "ash/system/tray/tray_constants.h" #include "ash/system/unified/detailed_view_controller.h" #include "ash/system/unified/feature_pod_button.h" #include "ash/system/unified/feature_pod_controller_base.h" @@ -71,6 +72,10 @@ animation_->SetSlideDuration(kExpandAnimationDurationMs); animation_->SetTweenType(gfx::Tween::EASE_IN_OUT); + model_->pagination_model()->SetTransitionDurations( + kUnifiedSystemTrayPageTransitionDurationMs, + kUnifiedSystemTrayOverScrollPageTransitionDurationMs); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_STATUS_AREA_MENU_OPENED); UMA_HISTOGRAM_BOOLEAN("ChromeOS.SystemTray.IsExpandedOnOpen", model_->IsExpandedOnOpen()); @@ -347,7 +352,8 @@ std::unique_ptr<FeaturePodControllerBase> controller) { DCHECK(unified_view_); FeaturePodButton* button = controller->CreateButton(); - button->SetExpandedAmount(IsExpanded() ? 1.0 : 0.0); + button->SetExpandedAmount(IsExpanded() ? 1.0 : 0.0, + false /* fade_icon_button */); // Record DefaultView.VisibleRows UMA. SystemTrayItemUmaType uma_type = controller->GetUmaType();
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index 7562712..c56a525 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc
@@ -26,6 +26,7 @@ #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" #include "ash/shell_init_params.h" +#include "ash/system/message_center/test_notifier_settings_controller.h" #include "ash/system/model/system_tray_model.h" #include "ash/system/screen_layout_observer.h" #include "ash/test/ash_test_views_delegate.h" @@ -156,6 +157,9 @@ shell->session_controller(), prefs_provider_.get())); session_controller_client_->InitializeAndSetClient(); + notifier_settings_controller_ = + std::make_unique<TestNotifierSettingsController>(); + assistant_service_ = std::make_unique<TestAssistantService>(); shell->assistant_controller()->SetAssistant( assistant_service_->CreateInterfacePtrAndBind());
diff --git a/ash/test/ash_test_helper.h b/ash/test/ash_test_helper.h index bdda0c0..57745c7 100644 --- a/ash/test/ash_test_helper.h +++ b/ash/test/ash_test_helper.h
@@ -46,6 +46,7 @@ class AshTestViewsDelegate; class TestKeyboardControllerObserver; class TestNewWindowDelegate; +class TestNotifierSettingsController; class TestPrefServiceProvider; class TestShellDelegate; class TestSystemTrayClient; @@ -90,6 +91,9 @@ std::unique_ptr<TestSessionControllerClient> session_controller_client) { session_controller_client_ = std::move(session_controller_client); } + TestNotifierSettingsController* notifier_settings_controller() { + return notifier_settings_controller_.get(); + } TestSystemTrayClient* system_tray_client() { return system_tray_client_.get(); } @@ -123,6 +127,7 @@ bool power_policy_controller_initialized_ = false; std::unique_ptr<TestSessionControllerClient> session_controller_client_; + std::unique_ptr<TestNotifierSettingsController> notifier_settings_controller_; std::unique_ptr<TestSystemTrayClient> system_tray_client_; std::unique_ptr<TestPrefServiceProvider> prefs_provider_; std::unique_ptr<TestAssistantService> assistant_service_;
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index e8826daf..807b141a 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -514,6 +514,10 @@ SelectedWindow()->set_selected(false); } + // TODO(dantonvu|sammiequon): Refactor this so OverviewSession controls and + // owns |selection_widget_|. Also rename selection related names to + // highlighted as selection can also mean something else in overview. + // [up] key is equivalent to [left] key and [down] key is equivalent to // [right] key. if (!selection_widget_) { @@ -529,19 +533,30 @@ } changed_selection_index = true; } + + // Checks number of windows present during a session. If there's only one + // window being used across all displays, allow the user to highlight the + // window but unable to move it. + // TODO(sammiequon): Investigate if we can remove this call. + if (overview_session()->NumWindowsTotal() == 1u) { + MoveSelectionWidget(direction, recreate_selection_widget, out_of_bounds, + animate); + return true; + } + while (!changed_selection_index) { switch (direction) { case OverviewSession::UP: case OverviewSession::LEFT: if (selected_index_ == 0) out_of_bounds = true; - selected_index_--; + --selected_index_; break; case OverviewSession::DOWN: case OverviewSession::RIGHT: if (selected_index_ >= window_list_.size() - 1) out_of_bounds = true; - selected_index_++; + ++selected_index_; break; } if (!out_of_bounds && SelectedWindow()) {
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index f024543..e0b7368 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -753,6 +753,13 @@ return true; } +size_t OverviewSession::NumWindowsTotal() const { + size_t sum = 0; + for (const std::unique_ptr<OverviewGrid>& overview_grid : grid_list_) + sum += overview_grid->size(); + return sum; +} + void OverviewSession::OnDisplayRemoved(const display::Display& display) { // TODO(flackr): Keep window selection active on remaining displays. EndOverview();
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h index fd82f611..10a01b3 100644 --- a/ash/wm/overview/overview_session.h +++ b/ash/wm/overview/overview_session.h
@@ -230,6 +230,9 @@ // Returns true if all its window grids don't have any window item. bool IsEmpty() const; + // Returns the sum of the number of windows in all window grids. + size_t NumWindowsTotal() const; + // display::DisplayObserver: void OnDisplayRemoved(const display::Display& display) override; void OnDisplayMetricsChanged(const display::Display& display,
diff --git a/base/task/task_traits.h b/base/task/task_traits.h index 046caa4..e7d45cb 100644 --- a/base/task/task_traits.h +++ b/base/task/task_traits.h
@@ -45,11 +45,13 @@ // the priority when that user interactions happens). BEST_EFFORT = LOWEST, - // This task affects UI but it is not an immediate response to a user + // The result of this task is visible to the user (in the UI or as a + // side-effect on the system) but it is not an immediate response to a user // interaction. // // Examples: // - Updating the UI to reflect progress on a long task. + // - Downloading a file requested by the user. // - Loading an image that is displayed in the UI but is non-critical. USER_VISIBLE,
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 25fe7873..058e03f 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8910405371392102240 \ No newline at end of file +8910378163651872592 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 71ba207..da02f04a 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8910404852664286432 \ No newline at end of file +8910380642259799440 \ No newline at end of file
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc index 6f0dec36..36c9f7a 100644 --- a/build/sanitizers/tsan_suppressions.cc +++ b/build/sanitizers/tsan_suppressions.cc
@@ -52,9 +52,6 @@ // http://crbug.com/239359 "race:media::TestInputCallback::OnData\n" - // http://crbug.com/244385 - "race:unixTempFileDir\n" - // http://crbug.com/244755 "race:v8::internal::Zone::NewExpand\n"
diff --git a/build_overrides/angle.gni b/build_overrides/angle.gni index 56b6c8e..fcd31af 100644 --- a/build_overrides/angle.gni +++ b/build_overrides/angle.gni
@@ -2,6 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# Override for angle_root +angle_root = "//third_party/angle" + # Overrides for ANGLE's dependencies angle_glslang_dir = "//third_party/glslang/src" angle_googletest_dir = "//third_party/googletest/src"
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc index 37f63d5..9a66fe86 100644 --- a/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -198,11 +198,8 @@ } TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOutsets) { - if (renderer_type() == RENDERER_SKIA_GL -#if defined(ENABLE_CC_VULKAN_TESTS) - || renderer_type() == RENDERER_SKIA_VK -#endif - ) { + if (renderer_type() == RENDERER_SKIA_GL || + renderer_type() == RENDERER_SKIA_VK) { // TODO(973696): Implement bounds clipping in skia_renderer. return; }
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc index 20299713..7cd0802 100644 --- a/cc/trees/proxy_main.cc +++ b/cc/trees/proxy_main.cc
@@ -202,11 +202,22 @@ current_pipeline_stage_ = ANIMATE_PIPELINE_STAGE; - // Synchronizes scroll offsets and page scale deltas (for pinch zoom) from the - // compositor thread thread to the main thread for both cc and and its - // client (e.g. Blink). - layer_tree_host_->ApplyScrollAndScale( - begin_main_frame_state->scroll_info.get()); + // Check now if we should stop deferring commits due to a timeout. We + // may also stop deferring in BeginMainFrame, but maintain the status + // from this point to keep scroll in sync. + if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) { + StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout); + } + skip_commit |= defer_commits_; + + if (!skip_commit) { + // Synchronizes scroll offsets and page scale deltas (for pinch zoom) from + // the compositor thread to the main thread for both cc and and its client + // (e.g. Blink). Do not do this if we explicitly plan to not commit the + // layer tree, to prevent scroll offsets getting out of sync. + layer_tree_host_->ApplyScrollAndScale( + begin_main_frame_state->scroll_info.get()); + } layer_tree_host_->WillBeginMainFrame(); layer_tree_host_->RecordStartOfFrameMetrics(); @@ -230,14 +241,10 @@ // what this does. layer_tree_host_->RequestMainFrameUpdate(); - // Check now if we should stop deferring commits - if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) { - StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout); - } - - // At this point the main frame may have deferred commits to avoid committing - // right now, or we may be deferring commits but not deferring main - // frame updates. + // At this point the main frame may have deferred main frame updates to + // avoid committing right now, or we may be deferring commits but not + // deferring main frame updates. Either may have changed the status + // of the defer... flags, so re-evaluate skip_commit. skip_commit |= defer_main_frame_update_ || defer_commits_; if (skip_commit) {
diff --git a/chrome/VERSION b/chrome/VERSION index b892a52..1e19a1b 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=77 MINOR=0 -BUILD=3829 +BUILD=3830 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 77adc407..a21ca76 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2007,7 +2007,11 @@ "//chrome/android/webapk/shell_apk:shell_apk_javatests", "//chrome/browser/profiling_host:profiling_host_javatests", ] - + if (enable_chrome_android_internal) { + data_deps = [ + "//clank/build/bot/filters:chrome_public_test_apk_filters", + ] + } additional_apks = [ "//chrome/android/webapk/libs/runtime_library/javatests/apk_with_webapk_service:apk_with_webapk_service", "//chrome/android/webapk/shell_apk:javatests_webapk",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index b674b3f..8e39e99 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -155,9 +155,11 @@ java_files = [ "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantActionsCarouselUiTest.java", + "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestTestHelper.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestUiTest.java", + "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/EditDistanceTest.java", ]
diff --git a/chrome/android/features/autofill_assistant/java/DEPS b/chrome/android/features/autofill_assistant/java/DEPS index cc628521..c3de06b 100644 --- a/chrome/android/features/autofill_assistant/java/DEPS +++ b/chrome/android/features/autofill_assistant/java/DEPS
@@ -1,3 +1,4 @@ include_rules = [ + "+chrome/lib/image_fetcher", "+content/public/android/java/src/org/chromium/content_public/browser", ]
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml index bd5062b..950007c 100644 --- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml +++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml
@@ -5,8 +5,6 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/autofill_assistant_shadow_bg"
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsCoordinator.java index 198bd91..c6d6d3f 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsCoordinator.java
@@ -5,13 +5,20 @@ package org.chromium.chrome.browser.autofill_assistant.details; import android.content.Context; +import android.os.Build; import android.view.LayoutInflater; import android.view.View; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsViewBinder.ViewHolder; +import org.chromium.chrome.browser.image_fetcher.ImageFetcher; +import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig; +import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; +import java.util.Locale; + /** * Coordinator responsible for showing details. */ @@ -20,11 +27,22 @@ private final AssistantDetailsModel mModel; public AssistantDetailsCoordinator(Context context, AssistantDetailsModel model) { + this(context, + Build.VERSION.SDK_INT >= Build.VERSION_CODES.N + ? context.getResources().getConfiguration().getLocales().get(0) + : context.getResources().getConfiguration().locale, + model, ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY)); + } + + @VisibleForTesting + public AssistantDetailsCoordinator(Context context, Locale locale, AssistantDetailsModel model, + ImageFetcher imageFetcher) { mView = LayoutInflater.from(context).inflate( R.layout.autofill_assistant_details, /* root= */ null); mModel = model; ViewHolder viewHolder = new ViewHolder(context, mView); - AssistantDetailsViewBinder viewBinder = new AssistantDetailsViewBinder(context); + AssistantDetailsViewBinder viewBinder = + new AssistantDetailsViewBinder(context, locale, imageFetcher); PropertyModelChangeProcessor.create(model, viewHolder, viewBinder); // Details view is initially hidden.
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java index 67358c1..8cb3af023 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java
@@ -16,7 +16,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.media.ThumbnailUtils; -import android.os.Build; import android.support.annotation.StyleRes; import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; @@ -31,8 +30,6 @@ import org.chromium.chrome.browser.compositor.animation.CompositorAnimator; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.image_fetcher.ImageFetcher; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory; import org.chromium.chrome.browser.modaldialog.AppModalPresenter; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -77,7 +74,7 @@ final TextView mTotalPriceLabelView; final TextView mTotalPriceView; - public ViewHolder(Context context, View detailsView) { + ViewHolder(Context context, View detailsView) { mDefaultImage = (GradientDrawable) context.getResources().getDrawable( R.drawable.autofill_assistant_default_details); mImageView = detailsView.findViewById(R.id.details_image); @@ -93,6 +90,7 @@ } private final Context mContext; + private final Locale mLocale; private final int mImageWidth; private final int mImageHeight; @@ -102,15 +100,16 @@ private ValueAnimator mPulseAnimation; private ImageFetcher mImageFetcher; - AssistantDetailsViewBinder(Context context) { + AssistantDetailsViewBinder(Context context, Locale locale, ImageFetcher imageFetcher) { mContext = context; + mLocale = locale; mImageWidth = context.getResources().getDimensionPixelSize( R.dimen.autofill_assistant_details_image_size); mImageHeight = context.getResources().getDimensionPixelSize( R.dimen.autofill_assistant_details_image_size); mPulseAnimationStartColor = context.getResources().getColor(R.color.modern_grey_300); mPulseAnimationEndColor = context.getResources().getColor(R.color.modern_grey_200); - mImageFetcher = ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY); + mImageFetcher = imageFetcher; } /** @@ -224,22 +223,16 @@ return TextUtils.join(" • ", parts); } - private Locale getLocale() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - ? mContext.getResources().getConfiguration().getLocales().get(0) - : mContext.getResources().getConfiguration().locale; - } - private String formatDetailsTime(Date date) { - DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()); + DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT, mLocale); String timeFormatPattern = (df instanceof SimpleDateFormat) ? ((SimpleDateFormat) df).toPattern() : DETAILS_TIME_FORMAT; - return new SimpleDateFormat(timeFormatPattern, getLocale()).format(date); + return new SimpleDateFormat(timeFormatPattern, mLocale).format(date); } private String formatDetailsDate(Date date) { - return new SimpleDateFormat(DETAILS_DATE_FORMAT, getLocale()).format(date); + return new SimpleDateFormat(DETAILS_DATE_FORMAT, mLocale).format(date); } private void hideIfEmpty(TextView view) {
diff --git a/chrome/android/features/autofill_assistant/javatests/DEPS b/chrome/android/features/autofill_assistant/javatests/DEPS new file mode 100644 index 0000000..4455294 --- /dev/null +++ b/chrome/android/features/autofill_assistant/javatests/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+chrome/lib/image_fetcher", +]
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java new file mode 100644 index 0000000..57021e1 --- /dev/null +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java
@@ -0,0 +1,341 @@ +// 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. + +package org.chromium.chrome.browser.autofill_assistant; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.assertThat; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withText; + +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.isTextMaxLines; +import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.support.design.widget.CoordinatorLayout; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.LocaleUtils; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.autofill_assistant.R; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetails; +import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsCoordinator; +import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsModel; +import org.chromium.chrome.browser.customtabs.CustomTabActivity; +import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; +import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; + +import java.util.Calendar; +import java.util.Locale; + +/** Tests for the Autofill Assistant details. */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +public class AutofillAssistantDetailsUiTest { + private static class ViewHolder { + final ImageView mImageView; + final TextView mTitleView; + final TextView mDescriptionLine1View; + final TextView mDescriptionLine2View; + final TextView mDescriptionLine3View; + final TextView mPriceAttributionView; + final View mPriceView; + final TextView mTotalPriceLabelView; + final TextView mTotalPriceView; + + ViewHolder(View detailsView) { + mImageView = detailsView.findViewById(R.id.details_image); + mTitleView = detailsView.findViewById(R.id.details_title); + mDescriptionLine1View = detailsView.findViewById(R.id.details_line1); + mDescriptionLine2View = detailsView.findViewById(R.id.details_line2); + mDescriptionLine3View = detailsView.findViewById(R.id.details_line3); + mPriceAttributionView = detailsView.findViewById(R.id.details_price_attribution); + mPriceView = detailsView.findViewById(R.id.details_price); + mTotalPriceView = detailsView.findViewById(R.id.details_total_price); + mTotalPriceLabelView = detailsView.findViewById(R.id.details_total_price_label); + } + } + + @Rule + public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); + + @Before + public void setUp() throws Exception { + mCustomTabActivityTestRule.startCustomTabActivityWithIntent( + CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), "about:blank")); + } + + private CustomTabActivity getActivity() { + return mCustomTabActivityTestRule.getActivity(); + } + + private AssistantDetailsCoordinator createCoordinator(AssistantDetailsModel model) + throws Exception { + return createCoordinator(model, Locale.getDefault()); + } + + /** Creates a coordinator for use in UI tests, and adds it to the global view hierarchy. */ + private AssistantDetailsCoordinator createCoordinator( + AssistantDetailsModel model, Locale locale) throws Exception { + AssistantDetailsCoordinator coordinator = runOnUiThreadBlocking(() -> { + Bitmap testImage = BitmapFactory.decodeResource( + getActivity().getResources(), R.drawable.btn_close); + + return new AssistantDetailsCoordinator(InstrumentationRegistry.getTargetContext(), + locale, model, + new AutofillAssistantUiTestUtil.MockImageFetcher(testImage, null)); + }); + + runOnUiThreadBlocking(() -> { + CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.BOTTOM; + + ViewGroup chromeCoordinatorView = getActivity().findViewById(R.id.coordinator); + chromeCoordinatorView.addView(coordinator.getView(), lp); + }); + + return coordinator; + } + + /** Tests assumptions about the initial state of the details. */ + @Test + @SmallTest + public void testInitialState() throws Exception { + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model); + + assertThat(model.get(AssistantDetailsModel.DETAILS), nullValue()); + onView(is(coordinator.getView())).check(matches(not(isDisplayed()))); + } + + /** Tests visibility of views. */ + @Test + @SmallTest + public void testVisibility() throws Exception { + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model); + ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); + + runOnUiThreadBlocking(() -> { + model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + java.util.Calendar.getInstance().getTime(), "line 1", "line 2", + "line 3", false, false, false, false, false, false)); + }); + + onView(is(viewHolder.mImageView)).check(matches(isDisplayed())); + onView(is(viewHolder.mTitleView)).check(matches(isDisplayed())); + onView(is(viewHolder.mDescriptionLine1View)).check(matches(isDisplayed())); + onView(is(viewHolder.mDescriptionLine2View)).check(matches(isDisplayed())); + onView(is(viewHolder.mPriceView)).check(matches(isDisplayed())); + onView(is(viewHolder.mTotalPriceLabelView)).check(matches(isDisplayed())); + onView(is(viewHolder.mTotalPriceView)).check(matches(isDisplayed())); + // When total price is set, descriptionLine3 is shown in mPriceAttributionView instead. + onView(is(viewHolder.mPriceAttributionView)).check(matches(isDisplayed())); + onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed()))); + } + + @Test + @SmallTest + public void testTitle() throws Exception { + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model); + ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); + + /* All description lines are set, title must be in single line. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + null, "line 1", "line 2", "line 3", false, false, false, + false, false, false))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(1))); + + /* Description line 2 not set, title may wrap once. */ + runOnUiThreadBlocking(() + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, + "Total", "$12", null, "line 1", "", "line 3", + false, false, false, false, false, false))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(2))); + + /* Description line 1 not set, title may wrap once.*/ + runOnUiThreadBlocking(() + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, + "Total", "$12", null, "", "line 2", "line 3", + false, false, false, false, false, false))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(2))); + + /* Description lines 1 and 2 not set, title may wrap twice.*/ + runOnUiThreadBlocking(() + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, + "Total", "$12", null, "", "", "line 3", false, + false, false, false, false, false))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(3))); + + /* Check title text and visibility. */ + onView(is(viewHolder.mTitleView)).check(matches(allOf(withText("title"), isDisplayed()))); + } + + @Test + @SmallTest + public void testDescriptionLine1() throws Exception { + Locale locale = LocaleUtils.forLanguageTag("en-US"); + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model, locale); + ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); + + /* Both line 1 and date are set: description line 1 should show line 1. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + java.util.Calendar.getInstance().getTime(), "line 1", + "line 2", "line 3", false, false, false, false, false, + false))); + onView(is(viewHolder.mDescriptionLine1View)) + .check(matches(allOf(withText("line 1"), isDisplayed()))); + + /* + * Line 1 is empty, but date is set: description line 1 should show the date & time. + * Note: locale was set to en-US, so we know the output format for date and time. + */ + Calendar calendar = java.util.Calendar.getInstance(locale); + calendar.set(2050, 6, 25, 10, 05, 00); + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + calendar.getTime(), "", "line 2", "line 3", false, false, + false, false, false, false))); + onView(is(viewHolder.mDescriptionLine1View)) + .check(matches(withText(containsString("Mon, Jul 25")))); + onView(is(viewHolder.mDescriptionLine1View)) + .check(matches(withText(containsString("10:05 AM")))); + + /* Line 1 is empty, date is not set: description line 1 should be invisible. */ + runOnUiThreadBlocking(() + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, + "Total", "$12", null, "", "line 2", "line 3", + false, false, false, false, false, false))); + onView(is(viewHolder.mDescriptionLine1View)).check(matches(not(isDisplayed()))); + } + + @Test + @SmallTest + public void testDescriptionLine1NonUSLocale() throws Exception { + Locale locale = LocaleUtils.forLanguageTag("de-DE"); + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model, locale); + ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); + + Calendar calendar = java.util.Calendar.getInstance(locale); + calendar.set(2050, 6, 25, 10, 05, 00); + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + calendar.getTime(), "", "line 2", "line 3", false, false, + false, false, false, false))); + onView(is(viewHolder.mDescriptionLine1View)) + .check(matches(withText(containsString("Mo., Juli 25")))); + onView(is(viewHolder.mDescriptionLine1View)) + .check(matches(withText(containsString("10:05")))); + } + + @Test + @SmallTest + public void testDescriptionLine2() throws Exception { + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model); + ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); + + /* Description line 2 is set and should be visible. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + java.util.Calendar.getInstance().getTime(), "line 1", + "line 2", "line 3", false, false, false, false, false, + false))); + onView(is(viewHolder.mDescriptionLine2View)) + .check(matches(allOf(withText("line 2"), isDisplayed()))); + + /* Description line 2 is not set and should be invisible. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + java.util.Calendar.getInstance().getTime(), "line 1", "", + "line 3", false, false, false, false, false, false))); + onView(is(viewHolder.mDescriptionLine2View)).check(matches(not(isDisplayed()))); + } + + @Test + @SmallTest + public void testDescriptionLine3() throws Exception { + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model); + ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); + + /* No total price set, line 3 should be displayed in the normal spot. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "", "", + java.util.Calendar.getInstance().getTime(), "line 1", + "line 2", "line 3", false, false, false, false, false, + false))); + onView(is(viewHolder.mDescriptionLine3View)) + .check(matches(allOf(withText("line 3"), isDisplayed()))); + onView(is(viewHolder.mPriceAttributionView)).check(matches(not(isDisplayed()))); + + /* Total price and line 3 set, line 3 should be displayed in a different view. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + java.util.Calendar.getInstance().getTime(), "line 1", "", + "line 3", false, false, false, false, false, false))); + onView(is(viewHolder.mPriceAttributionView)) + .check(matches(allOf(withText("line 3"), isDisplayed()))); + onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed()))); + + /* Line 3 not set, both views should be invisible. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", null, false, "Total", "$12", + java.util.Calendar.getInstance().getTime(), "line 1", "", + "", false, false, false, false, false, false))); + onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed()))); + onView(is(viewHolder.mPriceAttributionView)).check(matches(not(isDisplayed()))); + } +}
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java index 7d7a161b..c887523 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java
@@ -4,6 +4,12 @@ package org.chromium.chrome.browser.autofill_assistant; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.design.widget.CoordinatorLayout; @@ -13,13 +19,11 @@ import android.view.ViewGroup; import android.widget.TextView; -import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.autofill_assistant.R; @@ -30,42 +34,15 @@ import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; -import org.chromium.chrome.browser.image_fetcher.ImageFetcher; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import jp.tomorrowkey.android.gifplayer.BaseGifImage; - /** * Tests for the Autofill Assistant infobox. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class AutofillAssistantInfoBoxUiTest { - private class MockImageFetcher extends ImageFetcher { - @Override - public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) {} - - @Override - public void fetchImage( - String url, String clientName, int width, int height, Callback<Bitmap> callback) { - callback.onResult(BitmapFactory.decodeResource( - getActivity().getResources(), R.drawable.btn_close)); - } - - @Override - public void clear() {} - - @Override - public @ImageFetcherConfig int getConfig() { - return ImageFetcherConfig.IN_MEMORY_ONLY; - } - - @Override - public void destroy() {} - } - @Rule public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); @@ -87,8 +64,13 @@ /** Creates a coordinator for use in UI tests, and adds it to the global view hierarchy. */ private AssistantInfoBoxCoordinator createCoordinator(AssistantInfoBoxModel model) { ThreadUtils.assertOnUiThread(); - AssistantInfoBoxCoordinator coordinator = new AssistantInfoBoxCoordinator( - InstrumentationRegistry.getTargetContext(), model, new MockImageFetcher()); + + Bitmap testImage = + BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.btn_close); + + AssistantInfoBoxCoordinator coordinator = + new AssistantInfoBoxCoordinator(InstrumentationRegistry.getTargetContext(), model, + new AutofillAssistantUiTestUtil.MockImageFetcher(testImage, null)); CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); @@ -108,8 +90,8 @@ AssistantInfoBoxModel model = new AssistantInfoBoxModel(); AssistantInfoBoxCoordinator coordinator = createCoordinator(model); - Assert.assertNull(model.get(AssistantInfoBoxModel.INFO_BOX)); - Assert.assertFalse(coordinator.getView().isShown()); + assertNull(model.get(AssistantInfoBoxModel.INFO_BOX)); + assertFalse(coordinator.getView().isShown()); }); } @@ -124,11 +106,10 @@ AssistantInfoBox infoBox = new AssistantInfoBox("", "Message"); model.set(AssistantInfoBoxModel.INFO_BOX, infoBox); - Assert.assertTrue(getExplanationView(coordinator).isShown()); - Assert.assertNull("Image should not be set", + assertTrue(getExplanationView(coordinator).isShown()); + assertNull("Image should not be set", getExplanationView(coordinator).getCompoundDrawables()[1]); - Assert.assertEquals( - infoBox.getExplanation(), getExplanationView(coordinator).getText()); + assertEquals(infoBox.getExplanation(), getExplanationView(coordinator).getText()); }); } @@ -143,11 +124,10 @@ AssistantInfoBox infoBox = new AssistantInfoBox("x", "Message"); model.set(AssistantInfoBoxModel.INFO_BOX, infoBox); - Assert.assertTrue(getExplanationView(coordinator).isShown()); - Assert.assertNotNull("Image should be set", + assertTrue(getExplanationView(coordinator).isShown()); + assertNotNull("Image should be set", getExplanationView(coordinator).getCompoundDrawables()[1]); - Assert.assertEquals( - infoBox.getExplanation(), getExplanationView(coordinator).getText()); + assertEquals(infoBox.getExplanation(), getExplanationView(coordinator).getText()); }); } @@ -160,10 +140,10 @@ AssistantInfoBox infoBox = new AssistantInfoBox("", ""); model.set(AssistantInfoBoxModel.INFO_BOX, infoBox); - Assert.assertTrue(coordinator.getView().isShown()); + assertTrue(coordinator.getView().isShown()); model.set(AssistantInfoBoxModel.INFO_BOX, null); - Assert.assertFalse(coordinator.getView().isShown()); + assertFalse(coordinator.getView().isShown()); }); } }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java new file mode 100644 index 0000000..be701fdb --- /dev/null +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -0,0 +1,72 @@ +// 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. + +package org.chromium.chrome.browser.autofill_assistant; + +import android.graphics.Bitmap; +import android.support.annotation.Nullable; +import android.view.View; +import android.widget.TextView; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +import org.chromium.base.Callback; +import org.chromium.chrome.browser.image_fetcher.ImageFetcher; +import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig; + +import jp.tomorrowkey.android.gifplayer.BaseGifImage; + +/** + * Contains utilities for testing Autofill Assistant. + */ +class AutofillAssistantUiTestUtil { + /** Image fetcher which synchronously returns a preset image. */ + static class MockImageFetcher extends ImageFetcher { + private final Bitmap mBitmapToFetch; + private final BaseGifImage mGifToFetch; + + MockImageFetcher(@Nullable Bitmap bitmapToFetch, @Nullable BaseGifImage gifToFetch) { + mBitmapToFetch = bitmapToFetch; + mGifToFetch = gifToFetch; + } + + @Override + public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) { + callback.onResult(mGifToFetch); + } + + @Override + public void fetchImage( + String url, String clientName, int width, int height, Callback<Bitmap> callback) { + callback.onResult(mBitmapToFetch); + } + + @Override + public void clear() {} + + @Override + public @ImageFetcherConfig int getConfig() { + return ImageFetcherConfig.IN_MEMORY_ONLY; + } + + @Override + public void destroy() {} + } + + /** Checks that a text view has a specific maximum number of lines to display. */ + public static TypeSafeMatcher<View> isTextMaxLines(int maxLines) { + return new TypeSafeMatcher<View>() { + @Override + protected boolean matchesSafely(View item) { + return ((TextView) item).getMaxLines() == maxLines; + } + + @Override + public void describeTo(Description description) { + description.appendText("isTextMaxLines"); + } + }; + } +}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java index 7af8790..f52d328 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java
@@ -9,6 +9,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.INITIAL_SCROLL_INDEX; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.IS_INCOGNITO; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.IS_VISIBLE; +import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.SHADOW_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.TOP_CONTROLS_HEIGHT; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.TOP_PADDING; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.VISIBILITY_LISTENER; @@ -188,11 +189,18 @@ mContainerViewModel.set(TOP_CONTROLS_HEIGHT, fullscreenManager.getTopControlsHeight()); mContainerViewModel.set( BOTTOM_CONTROLS_HEIGHT, fullscreenManager.getBottomControlsHeight()); + + int toolbarHeight = + ContextUtils.getApplicationContext().getResources().getDimensionPixelSize( + R.dimen.toolbar_height_no_shadow); int topPadding = ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() - ? ContextUtils.getApplicationContext().getResources().getDimensionPixelSize( - R.dimen.toolbar_height_no_shadow) + ? toolbarHeight : DEFAULT_TOP_PADDING; mContainerViewModel.set(TOP_PADDING, topPadding); + int shadowTopMargin = ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() + ? toolbarHeight * 2 + : toolbarHeight; + mContainerViewModel.set(SHADOW_TOP_MARGIN, shadowTopMargin); mCompositorViewHolder = compositorViewHolder; mTabGridDialogResetHandler = tabGridDialogResetHandler;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinder.java index 106fa77..627e617 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinder.java
@@ -9,6 +9,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.INITIAL_SCROLL_INDEX; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.IS_INCOGNITO; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.IS_VISIBLE; +import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.SHADOW_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.TOP_CONTROLS_HEIGHT; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.TOP_PADDING; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.VISIBILITY_LISTENER; @@ -58,6 +59,8 @@ } else if (TOP_PADDING == propertyKey) { view.setPadding(view.getPaddingLeft(), model.get(TOP_PADDING), view.getPaddingRight(), view.getPaddingBottom()); + } else if (SHADOW_TOP_MARGIN == propertyKey) { + view.setShadowTopMargin(model.get(SHADOW_TOP_MARGIN)); } } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerProperties.java index e77ef67..da4617e8 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerProperties.java
@@ -37,7 +37,10 @@ public static final PropertyModel.WritableIntPropertyKey TOP_PADDING = new PropertyModel.WritableIntPropertyKey(); + public static final PropertyModel.WritableIntPropertyKey SHADOW_TOP_MARGIN = + new PropertyModel.WritableIntPropertyKey(); + public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {IS_VISIBLE, IS_INCOGNITO, VISIBILITY_LISTENER, INITIAL_SCROLL_INDEX, ANIMATE_VISIBILITY_CHANGES, - TOP_CONTROLS_HEIGHT, BOTTOM_CONTROLS_HEIGHT, TOP_PADDING}; + TOP_CONTROLS_HEIGHT, BOTTOM_CONTROLS_HEIGHT, TOP_PADDING, SHADOW_TOP_MARGIN}; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java index ec73af0..58de2d9 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java
@@ -11,14 +11,20 @@ import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.Context; +import android.content.res.Resources; import android.graphics.Rect; import android.os.SystemClock; import android.support.annotation.Nullable; +import android.support.v7.content.res.AppCompatResources; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; +import android.view.Gravity; import android.view.View; import android.view.ViewParent; +import android.widget.FrameLayout; +import android.widget.ImageView; +import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.ui.interpolators.BakedBezierInterpolator; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; @@ -69,12 +75,25 @@ void finishedHiding(); } + private class TabListOnScrollListener extends RecyclerView.OnScrollListener { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + final int yOffset = recyclerView.computeVerticalScrollOffset(); + setShadowVisibility(yOffset > 0); + } + } + private ValueAnimator mFadeInAnimator; private ValueAnimator mFadeOutAnimator; private VisibilityListener mListener; + private DynamicResourceLoader mLoader; private ViewResourceAdapter mDynamicView; + private boolean mIsDynamicViewRegistered; private long mLastDirtyTime; private RecyclerView.ItemAnimator mOriginalAnimator; + private ImageView mShadowImageView; + private int mShadowTopMargin; + private TabListOnScrollListener mScrollListener; /** * Basic constructor to use during inflation from xml. @@ -94,6 +113,8 @@ void prepareOverview() { endAllAnimations(); + registerDynamicView(); + // Stop all the animations to make all the items show up and scroll to position immediately. mOriginalAnimator = getItemAnimator(); setItemAnimator(null); @@ -124,14 +145,46 @@ mListener.finishedShowing(); // Restore the original value. setItemAnimator(mOriginalAnimator); - - if (mDynamicView != null) + setShadowVisibility(computeVerticalScrollOffset() > 0); + if (mDynamicView != null) { mDynamicView.dropCachedBitmap(); + unregisterDynamicView(); + } } }); if (!animate) mFadeInAnimator.end(); } + void setShadowVisibility(boolean shouldShowShadow) { + if (!(getParent() instanceof FrameLayout)) return; + + if (mShadowImageView == null) { + Context context = getContext(); + mShadowImageView = new ImageView(context); + mShadowImageView.setImageDrawable( + AppCompatResources.getDrawable(context, R.drawable.modern_toolbar_shadow)); + Resources res = context.getResources(); + FrameLayout.LayoutParams params = + new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + res.getDimensionPixelSize(R.dimen.toolbar_shadow_height), Gravity.TOP); + params.topMargin = mShadowTopMargin; + mShadowImageView.setScaleType(ImageView.ScaleType.FIT_XY); + mShadowImageView.setLayoutParams(params); + FrameLayout parent = (FrameLayout) getParent(); + parent.addView(mShadowImageView); + } + + if (shouldShowShadow && mShadowImageView.getVisibility() != VISIBLE) { + mShadowImageView.setVisibility(VISIBLE); + } else if (!shouldShowShadow && mShadowImageView.getVisibility() != GONE) { + mShadowImageView.setVisibility(GONE); + } + } + + void setShadowTopMargin(int shadowTopMargin) { + mShadowTopMargin = shadowTopMargin; + } + /** * @return The ID for registering and using the dynamic resource in compositor. */ @@ -167,7 +220,24 @@ } }; mDynamicView.setDownsamplingScale(getDownsamplingScale()); - loader.registerResource(getResourceId(), mDynamicView); + assert mLoader == null : "createDynamicView should only be called once"; + mLoader = loader; + } + + private void registerDynamicView() { + if (mIsDynamicViewRegistered) return; + if (mLoader == null) return; + + mLoader.registerResource(getResourceId(), mDynamicView); + mIsDynamicViewRegistered = true; + } + + private void unregisterDynamicView() { + if (!mIsDynamicViewRegistered) return; + if (mLoader == null) return; + + mLoader.unregisterResource(getResourceId()); + mIsDynamicViewRegistered = false; } @SuppressLint("NewApi") // Used on O+, invalidateChildInParent used for previous versions. @@ -188,12 +258,38 @@ return retVal; } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + mScrollListener = new TabListOnScrollListener(); + addOnScrollListener(mScrollListener); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + if (mShadowImageView != null) { + removeViewInLayout(mShadowImageView); + mShadowImageView = null; + } + + if (mScrollListener != null) { + removeOnScrollListener(mScrollListener); + mScrollListener = null; + } + } + /** * Start hiding the tab list. * @param animate Whether the visibility change should be animated. */ void startHiding(boolean animate) { endAllAnimations(); + + registerDynamicView(); + mListener.startedHiding(animate); mFadeOutAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 0); mFadeOutAnimator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE); @@ -206,6 +302,7 @@ mListener.finishedHiding(); } }); + setShadowVisibility(false); mFadeOutAnimator.start(); if (!animate) mFadeOutAnimator.end(); } @@ -213,6 +310,7 @@ void postHiding() { if (mDynamicView != null) { mDynamicView.dropCachedBitmap(); + unregisterDynamicView(); } }
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index ea718076..28717c0 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -603,8 +603,8 @@ <!-- History Navigation UI Item --> <dimen name="navigation_bubble_border_width">1dp</dimen> - <dimen name="navigation_bubble_default_height">48dp</dimen> - <dimen name="navigation_bubble_bg_vertical_inset">8dp</dimen> + <dimen name="navigation_bubble_default_height">32dp</dimen> + <dimen name="navigation_bubble_bg_vertical_inset">0dp</dimen> <dimen name="navigation_bubble_vertical_padding">4dp</dimen> <dimen name="navigation_bubble_horizontal_padding">8dp</dimen> <dimen name="navigation_bubble_icon_size">20dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 9909971aa..0d3f770 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -295,7 +295,6 @@ "PredictivePrefetchingAllowedOnAllConnectionTypes"; public static final String PRIORITIZE_BOOTSTRAP_TASKS = "PrioritizeBootstrapTasks"; public static final String PROGRESS_BAR_THROTTLE = "ProgressBarThrottle"; - public static final String PWA_PERSISTENT_NOTIFICATION = "PwaPersistentNotification"; public static final String QUERY_IN_OMNIBOX = "QueryInOmnibox"; public static final String REACHED_CODE_PROFILER = "ReachedCodeProfiler"; public static final String READER_MODE_IN_CCT = "ReaderModeInCCT";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java index 122a120..b833abe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
@@ -77,8 +77,6 @@ public static final String EXTRA_THEME_COLOR = "org.chromium.chrome.browser.theme_color"; public static final String EXTRA_BACKGROUND_COLOR = "org.chromium.chrome.browser.background_color"; - public static final String EXTRA_SPLASH_SCREEN_URL = - "org.chromium.chrome.browser.webapp_splash_screen_url"; public static final String EXTRA_IS_ICON_GENERATED = "org.chromium.chrome.browser.is_icon_generated"; public static final String EXTRA_IS_ICON_ADAPTIVE = @@ -191,7 +189,7 @@ final String userTitle, final String name, final String shortName, final String iconUrl, final Bitmap icon, boolean isIconAdaptive, @WebDisplayMode final int displayMode, final int orientation, final int source, final long themeColor, - final long backgroundColor, final String splashScreenUrl, final long callbackPointer) { + final long backgroundColor, final long callbackPointer) { new AsyncTask<Intent>() { @Override protected Intent doInBackground() { @@ -203,7 +201,7 @@ Intent shortcutIntent = createWebappShortcutIntent(id, sDelegate.getFullscreenAction(), url, scopeUrl, name, shortName, encodedIcon, WEBAPP_SHORTCUT_VERSION, displayMode, orientation, themeColor, - backgroundColor, splashScreenUrl, iconUrl.isEmpty(), isIconAdaptive); + backgroundColor, iconUrl.isEmpty(), isIconAdaptive); shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(url)); shortcutIntent.putExtra(EXTRA_SOURCE, source); return shortcutIntent; @@ -358,7 +356,6 @@ * @param orientation Orientation of the web app. * @param themeColor Theme color of the web app. * @param backgroundColor Background color of the web app. - * @param splashScreenUrl Url of the HTML splash screen. * @param isIconGenerated True if the icon is generated by Chromium. * @param isIconAdaptive Whether the shortcut icon is Adaptive. * @return Intent for onclick action of the shortcut. @@ -367,7 +364,7 @@ public static Intent createWebappShortcutIntent(String id, String action, String url, String scope, String name, String shortName, String encodedIcon, int version, @WebDisplayMode int displayMode, int orientation, long themeColor, long backgroundColor, - String splashScreenUrl, boolean isIconGenerated, boolean isIconAdaptive) { + boolean isIconGenerated, boolean isIconAdaptive) { // Create an intent as a launcher icon for a full-screen Activity. Intent shortcutIntent = new Intent(); shortcutIntent.setPackage(ContextUtils.getApplicationContext().getPackageName()) @@ -383,7 +380,6 @@ .putExtra(EXTRA_ORIENTATION, orientation) .putExtra(EXTRA_THEME_COLOR, themeColor) .putExtra(EXTRA_BACKGROUND_COLOR, backgroundColor) - .putExtra(EXTRA_SPLASH_SCREEN_URL, splashScreenUrl) .putExtra(EXTRA_IS_ICON_GENERATED, isIconGenerated) .putExtra(EXTRA_IS_ICON_ADAPTIVE, isIconAdaptive); return shortcutIntent; @@ -398,7 +394,7 @@ */ public static Intent createWebappShortcutIntentForTesting(String id, String url) { return createWebappShortcutIntent(id, null, url, getScopeFromUrl(url), null, null, null, - WEBAPP_SHORTCUT_VERSION, WebDisplayMode.STANDALONE, 0, 0, 0, null, false, false); + WEBAPP_SHORTCUT_VERSION, WebDisplayMode.STANDALONE, 0, 0, 0, false, false); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java index 78cfac6..da5a8ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java
@@ -100,7 +100,7 @@ // Only cache the visuals if the update we are about to push is interesting and we think we // will need them in the future. if (shouldCacheVisuals(item)) mVisualsCache.put(id, visuals); - pushItemToUi(item, null, visuals); + pushItemToUi(item, visuals); } // DownloadServiceDelegate implementation. @@ -123,6 +123,7 @@ public void destroyServiceDelegate() {} private void getVisualsAndUpdateItem(OfflineItem item, UpdateDelta updateDelta) { + if (shouldIgnoreUpdate(item, updateDelta)) return; if (updateDelta != null && updateDelta.visualsChanged) mVisualsCache.remove(item.id); if (needsVisualsForUi(item)) { if (!mVisualsCache.containsKey(item.id)) { @@ -141,13 +142,12 @@ mVisualsCache.remove(item.id); } - pushItemToUi(item, updateDelta, mVisualsCache.get(item.id)); + pushItemToUi(item, mVisualsCache.get(item.id)); // We will no longer be needing the visuals for this item after this notification. if (!shouldCacheVisuals(item)) mVisualsCache.remove(item.id); } - private void pushItemToUi( - OfflineItem item, UpdateDelta updateDelta, OfflineItemVisuals visuals) { + private void pushItemToUi(OfflineItem item, OfflineItemVisuals visuals) { // TODO(http://crbug.com/855141): Find a cleaner way to hide unimportant UI updates. // If it's a suggested page, do not add it to the notification UI. if (LegacyHelpers.isLegacyOfflinePage(item.id) && item.isSuggested) return; @@ -158,9 +158,7 @@ mUi.notifyDownloadProgress(info, item.creationTimeMs, item.allowMetered); break; case OfflineItemState.COMPLETE: - if (updateDelta == null || updateDelta.stateChanged) { - mUi.notifyDownloadSuccessful(info, -1L, false, item.isOpenable); - } + mUi.notifyDownloadSuccessful(info, -1L, false, item.isOpenable); break; case OfflineItemState.CANCELLED: mUi.notifyDownloadCanceled(item.id); @@ -212,4 +210,13 @@ return false; } } + + private boolean shouldIgnoreUpdate(OfflineItem item, UpdateDelta updateDelta) { + // We only ignore updates for completed items, if there is no significant state change + // update. + if (item.state != OfflineItemState.COMPLETE) return false; + if (updateDelta == null) return false; + if (updateDelta.stateChanged || updateDelta.visualsChanged) return false; + return true; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/ntp/OWNERS index f4818dc..a564d5f4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/OWNERS
@@ -1,5 +1,3 @@ -mvanouwerkerk@chromium.org -peconn@chromium.org tedchoc@chromium.org twellington@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index 6439753..ebd441ab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -392,7 +392,7 @@ }); } } else { - recordSuggestionsShown(); + if (mNativeInitialized) recordSuggestionsShown(); mSuggestionVisibilityState = SuggestionVisibilityState.DISALLOWED; mHasStartedNewOmniboxEditSession = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ChromeSigninManagerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ChromeSigninManagerDelegate.java index 660a2f8..133700ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ChromeSigninManagerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ChromeSigninManagerDelegate.java
@@ -8,6 +8,7 @@ import android.app.Activity; import android.content.Context; +import org.chromium.base.Callback; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.JCaller; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; @@ -32,6 +33,12 @@ } @Override + public String getManagementDomain( + @JCaller SigninManager self, long nativeSigninManagerAndroid) { + return SigninManagerJni.get().getManagementDomain(self, nativeSigninManagerAndroid); + } + + @Override public void handleGooglePlayServicesUnavailability(Activity activity, boolean cancelable) { UserRecoverableErrorHandler errorHandler = activity != null ? new UserRecoverableErrorHandler.ModalDialog(activity, cancelable) @@ -45,6 +52,13 @@ } @Override + public void isAccountManaged(@JCaller SigninManager signinManager, + long nativeSigninManagerAndroid, String email, final Callback<Boolean> callback) { + SigninManagerJni.get().isAccountManaged( + signinManager, nativeSigninManagerAndroid, email, callback); + } + + @Override public void fetchAndApplyCloudPolicy(@JCaller SigninManager signinManager, long nativeSigninManagerAndroid, String username) { SigninManagerJni.get().fetchAndApplyCloudPolicy(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java index ee6b395..05a85735 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
@@ -192,7 +192,7 @@ } private void requestNewAccountManagementStatus() { - SigninManager.get().isUserManaged(mNewAccountName, this::setIsNewAccountManaged); + SigninManager.get().isAccountManaged(mNewAccountName, this::setIsNewAccountManaged); } private void setIsNewAccountManaged(Boolean isManaged) { @@ -279,4 +279,3 @@ cancel(false); } } -
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index b52cf4b0..c02df423 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -584,7 +584,7 @@ * Returns the management domain if the signed in account is managed, otherwise returns null. */ public String getManagementDomain() { - return SigninManagerJni.get().getManagementDomain(this, mNativeSigninManagerAndroid); + return mDelegate.getManagementDomain(this, mNativeSigninManagerAndroid); } @VisibleForTesting @@ -678,12 +678,15 @@ } /** - * Performs an asynchronous check to see if the user is a managed user. - * @param callback A callback to be called with true if the user is a managed user and false - * otherwise. May be called synchronously from this function. + * Verifies if the account is managed. Callback may be called either + * synchronously or asynchronously depending on the availability of the + * result. + * @param email An email of the account. + * @param callback The callback that will receive true if the account is managed, false + * otherwise. */ - public void isUserManaged(String email, final Callback<Boolean> callback) { - SigninManagerJni.get().isUserManaged(this, mNativeSigninManagerAndroid, email, callback); + public void isAccountManaged(String email, final Callback<Boolean> callback) { + mDelegate.isAccountManaged(this, mNativeSigninManagerAndroid, email, callback); } public static String extractDomainName(String email) { @@ -730,7 +733,7 @@ boolean isSignedInOnNative(@JCaller SigninManager self, long nativeSigninManagerAndroid); - void isUserManaged(@JCaller SigninManager self, long nativeSigninManagerAndroid, + void isAccountManaged(@JCaller SigninManager self, long nativeSigninManagerAndroid, String username, Callback<Boolean> callback); String extractDomainName(String email);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerDelegate.java index eb32668..e2bd40c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerDelegate.java
@@ -8,6 +8,7 @@ import android.app.Activity; import android.content.Context; +import org.chromium.base.Callback; import org.chromium.base.annotations.JCaller; /** @@ -25,11 +26,29 @@ public void handleGooglePlayServicesUnavailability(Activity activity, boolean cancelable); /** + * @return the management domain if the signed in account is managed, otherwise null. + */ + public String getManagementDomain(@JCaller SigninManager self, long nativeSigninManagerAndroid); + + /** * @return Whether the device has Google Play Services. */ public boolean isGooglePlayServicesPresent(Context context); /** + * Verifies if the account is managed. Callback may be called either synchronously or + * asynchronously depending on the availability of the result. + * @param signinManager a reference on SigninManager used for the native calls + * @param nativeSigninManagerAndroid a reference on the native SigninManager used for native + * calls + * @param email An email of the account. + * @param callback The callback that will receive true if the account is managed, false + * otherwise. + */ + public void isAccountManaged(@JCaller SigninManager signinManager, + long nativeSigninManagerAndroid, String email, final Callback<Boolean> callback); + + /** * Interact with the UserPolicySigninService to retrieve the user policy. * @param signinManager a reference on SigninManager used for the native calls * @param nativeSigninManagerAndroid a reference on the native SigninManager used for native
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java index 5106b603..93b7d64 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java
@@ -19,10 +19,10 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.ProfileDataCache; import org.chromium.chrome.browser.signin.SigninManager; +import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; import org.chromium.components.signin.ChromeSigninController; -import org.chromium.components.sync.AndroidSyncSettings; import java.util.Collections; @@ -32,16 +32,16 @@ */ class IdentityDiscController implements NativeInitObserver, ProfileDataCache.Observer, SigninManager.SignInStateObserver, - AndroidSyncSettings.AndroidSyncSettingsObserver { + ProfileSyncService.SyncStateChangedListener { // Context is used for fetching resources and launching preferences page. private final Context mContext; // Toolbar manager exposes APIs for manipulating experimental button. private final ToolbarManager mToolbarManager; private ActivityLifecycleDispatcher mActivityLifecycleDispatcher; - // SigninManager and AndroidSyncSettings allow observing sign-in and sync state. + // SigninManager and ProfileSyncService allow observing sign-in and sync state. private SigninManager mSigninManager; - private AndroidSyncSettings mAndroidSyncSettings; + private ProfileSyncService mProfileSyncService; // ProfileDataCache facilitates retrieving profile picture. private ProfileDataCache mProfileDataCache; @@ -70,8 +70,8 @@ mSigninManager = SigninManager.get(); mSigninManager.addSignInStateObserver(this); - mAndroidSyncSettings = AndroidSyncSettings.get(); - mAndroidSyncSettings.registerObserver(this); + mProfileSyncService = ProfileSyncService.get(); + mProfileSyncService.addSyncStateChangedListener(this); mActivityLifecycleDispatcher.unregister(this); mActivityLifecycleDispatcher = null; @@ -85,8 +85,8 @@ mIsNTPVisible = isNTPVisible; String accountName = ChromeSigninController.get().getSignedInAccountName(); - boolean shouldShowIdentityDisc = - isNTPVisible && accountName != null && AndroidSyncSettings.get().isSyncEnabled(); + boolean shouldShowIdentityDisc = isNTPVisible && accountName != null + && ProfileSyncService.get().canSyncFeatureStart(); if (shouldShowIdentityDisc == mIsIdentityDiscVisible) return; @@ -159,9 +159,9 @@ updateButtonState(mIsNTPVisible); } - // AndroidSyncSettings.AndroidSyncSettingsObserver implementation. + // ProfileSyncService.SyncStateChangedListener implementation. @Override - public void androidSyncSettingsChanged() { + public void syncStateChanged() { updateButtonState(mIsNTPVisible); } @@ -177,9 +177,9 @@ mSigninManager.removeSignInStateObserver(this); mSigninManager = null; } - if (mAndroidSyncSettings != null) { - mAndroidSyncSettings.unregisterObserver(this); - mAndroidSyncSettings = null; + if (mProfileSyncService != null) { + mProfileSyncService.removeSyncStateChangedListener(this); + mProfileSyncService = null; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java index 0865c87..dd26d4a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java
@@ -21,7 +21,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabSelectionType; -import org.chromium.content_public.browser.NavigationHandle; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -58,7 +57,7 @@ @Override public void onShown(Tab tab, @TabSelectionType int type) { if (!tab.isLoading() && !tab.isBeingRestored()) { - updateUsingCanonicalUrl(tab); + updateUrl(tab.getUrl()); } } @@ -82,25 +81,13 @@ public void didFirstVisuallyNonEmptyPaint(Tab tab) { assert tab == mCurrentTab; - updateUsingCanonicalUrl(tab); + updateUrl(tab.getUrl()); } @Override public void onCrash(Tab tab) { updateUrl(null); } - - @Override - public void onDidFinishNavigation(Tab tab, NavigationHandle navigation) { - // We only check isLikelySubframeAmpNavigation here because this is the only - // observer method that fires for subframe navigations. The reason we have the - // isLikelySubframeAmpNavigation at all is that onDidFinishNavigation triggers very - // often, and we only want to bother getting the canonical URL if we think there's a - // good chance that it will actually be present. - if (isLikelySubframeAmpNavigation(navigation)) { - updateUsingCanonicalUrl(tab); - } - } }; mTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) { @@ -146,22 +133,6 @@ } } - private void updateUsingCanonicalUrl(Tab tab) { - if (tab.getWebContents() == null || tab.getWebContents().getMainFrame() == null) { - updateUrl(tab.getUrl()); - return; - } - - tab.getWebContents().getMainFrame().getCanonicalUrlForSharing((canonicalUrl) -> { - if (tab != mCurrentTab) return; - String urlToUse = tab.getUrl(); - if (canonicalUrl != null && canonicalUrl.length() > 0) { - urlToUse = canonicalUrl; - } - updateUrl(urlToUse); - }); - } - /** * Updates our state from the previous url to {@code newUrl}. This can result in any/all of the * following: @@ -232,7 +203,7 @@ // If the newly active tab is hidden, we don't want to check its URL yet; we'll wait until // the onShown event fires. if (mCurrentTab != null && !tab.isHidden()) { - updateUsingCanonicalUrl(tab); + updateUrl(tab.getUrl()); } } @@ -274,18 +245,4 @@ String host = Uri.parse(url).getHost(); return host == null ? "" : host; } - - private boolean isLikelySubframeAmpNavigation(NavigationHandle navigation) { - if (navigation.isInMainFrame()) return false; - String subframeUrl = navigation.getUrl(); - if (subframeUrl == null || subframeUrl.length() == 0) return false; - - // Our heuristic for AMP pages, based on AMPPageLoadMetricsObserver, is to look for a - // subframe navigation that contains "amp_js_v" in the query. This might produce a false - // positive, but we're OK with that; we'll just call updateUrl an extra time. This is a - // no-op if the URL hasn't actually changed. - String query = Uri.parse(subframeUrl).getQuery(); - if (query == null) return false; - return query.contains(AMP_QUERY_PARAM); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java index 7ab5512..a250b9d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java
@@ -412,8 +412,8 @@ String shareTargetActivityName, boolean forceNavigation, boolean isSplashProvidedByWebApk, ShareData shareData) { super(id, url, scope, primaryIcon, name, shortName, displayMode, orientation, source, - themeColor, backgroundColor, null /* splash_screen_url */, - false /* isIconGenerated */, false /* isIconAdaptive */, forceNavigation); + themeColor, backgroundColor, false /* isIconGenerated */, + false /* isIconAdaptive */, forceNavigation); mBadgeIcon = badgeIcon; mSplashIcon = splashIcon; mApkPackageName = webApkPackageName;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java index 1824c0e..cde09fe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
@@ -14,7 +14,6 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.blink_public.platform.WebDisplayMode; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.notifications.ChromeNotification; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; @@ -49,10 +48,7 @@ static boolean isEnabled() { // This UI doesn't work with no-touch. - if (FeatureUtilities.isNoTouchModeEnabled()) { - return false; - } - return ChromeFeatureList.isEnabled(ChromeFeatureList.PWA_PERSISTENT_NOTIFICATION); + return !FeatureUtilities.isNoTouchModeEnabled(); } public static void maybeShowNotification(Tab tab, WebappInfo webappInfo) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java index d2c64086..b95b84c6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java
@@ -40,7 +40,6 @@ static final String KEY_LAST_USED = "last_used"; static final String KEY_HAS_BEEN_LAUNCHED = "has_been_launched"; static final String KEY_URL = "url"; - static final String KEY_SPLASH_SCREEN_URL = "splash_screen_url"; static final String KEY_SCOPE = "scope"; static final String KEY_ICON = "icon"; static final String KEY_NAME = "name"; @@ -217,7 +216,6 @@ KEY_THEME_COLOR, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING), mPreferences.getLong( KEY_BACKGROUND_COLOR, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING), - mPreferences.getString(KEY_SPLASH_SCREEN_URL, ""), mPreferences.getBoolean(KEY_IS_ICON_GENERATED, false), mPreferences.getBoolean(KEY_IS_ICON_ADAPTIVE, false)); } @@ -257,9 +255,6 @@ // cleared together. if (mPreferences.getInt(KEY_VERSION, VERSION_INVALID) != ShortcutHelper.WEBAPP_SHORTCUT_VERSION) { - editor.putString(KEY_SPLASH_SCREEN_URL, - IntentUtils.safeGetStringExtra( - shortcutIntent, ShortcutHelper.EXTRA_SPLASH_SCREEN_URL)); editor.putString(KEY_NAME, IntentUtils.safeGetStringExtra( shortcutIntent, ShortcutHelper.EXTRA_NAME)); editor.putString(KEY_SHORT_NAME, IntentUtils.safeGetStringExtra(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java index 9f829f9..224c559 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java
@@ -71,7 +71,6 @@ private int mSource; private long mThemeColor; private long mBackgroundColor; - private Uri mSplashScreenUri; private boolean mIsIconGenerated; private boolean mIsIconAdaptive; private boolean mForceNavigation; @@ -160,8 +159,6 @@ long backgroundColor = IntentUtils.safeGetLongExtra(intent, ShortcutHelper.EXTRA_BACKGROUND_COLOR, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING); - String splashScreenUrl = - IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_SPLASH_SCREEN_URL); boolean isIconGenerated = IntentUtils.safeGetBooleanExtra(intent, ShortcutHelper.EXTRA_IS_ICON_GENERATED, false); boolean isIconAdaptive = IntentUtils.safeGetBooleanExtra(intent, @@ -173,8 +170,8 @@ String shortName = shortNameFromIntent(intent); return create(id, url, scope, new Icon(icon), name, shortName, displayMode, orientation, - source, themeColor, backgroundColor, splashScreenUrl, isIconGenerated, - isIconAdaptive, forceNavigation); + source, themeColor, backgroundColor, isIconGenerated, isIconAdaptive, + forceNavigation); } /** @@ -190,7 +187,6 @@ * @param source Source where the webapp was added from. * @param themeColor The theme color of the webapp. * @param backgroundColor The background color of the webapp. - * @param splashScreenUrl URL of the HTML splash screen. * @param isIconGenerated Whether the |icon| was generated by Chromium. * @param isIconAdaptive Whether the Icon is an Android Adaptive Icon. * @param forceNavigation Whether the webapp should navigate to {@link url} if the @@ -198,22 +194,22 @@ */ public static WebappInfo create(String id, String url, String scope, Icon icon, String name, String shortName, @WebDisplayMode int displayMode, int orientation, int source, - long themeColor, long backgroundColor, String splashScreenUrl, boolean isIconGenerated, - boolean isIconAdaptive, boolean forceNavigation) { + long themeColor, long backgroundColor, boolean isIconGenerated, boolean isIconAdaptive, + boolean forceNavigation) { if (id == null || url == null) { Log.e(TAG, "Incomplete data provided: " + id + ", " + url); return null; } return new WebappInfo(id, url, scope, icon, name, shortName, displayMode, orientation, - source, themeColor, backgroundColor, splashScreenUrl, isIconGenerated, - isIconAdaptive, forceNavigation); + source, themeColor, backgroundColor, isIconGenerated, isIconAdaptive, + forceNavigation); } protected WebappInfo(String id, String url, String scope, Icon icon, String name, String shortName, @WebDisplayMode int displayMode, int orientation, int source, - long themeColor, long backgroundColor, String splashScreenUrl, boolean isIconGenerated, - boolean isIconAdaptive, boolean forceNavigation) { + long themeColor, long backgroundColor, boolean isIconGenerated, boolean isIconAdaptive, + boolean forceNavigation) { Uri uri = Uri.parse(url); if (TextUtils.isEmpty(scope)) { scope = ShortcutHelper.getScopeFromUrl(url); @@ -231,7 +227,6 @@ mSource = source; mThemeColor = themeColor; mBackgroundColor = backgroundColor; - mSplashScreenUri = Uri.parse(splashScreenUrl != null ? splashScreenUrl : ""); mIsIconGenerated = isIconGenerated; mIsIconAdaptive = isIconAdaptive; mForceNavigation = forceNavigation; @@ -338,20 +333,6 @@ return hasValidBackgroundColor() ? (int) mBackgroundColor : fallback; } - /** - * Returns the Splash Screen URL, or empty if not specified. - */ - public Uri splashScreenUri() { - return mSplashScreenUri; - } - - /** - * Returns whether a non-empty Splash Screen URL has been specified. - */ - public boolean hasSplashScreenUri() { - return !mSplashScreenUri.equals(Uri.EMPTY); - } - // This is needed for clients that want to send the icon through an intent. public String encodedIcon() { return (mIcon == null) ? null : mIcon.encoded(); @@ -405,7 +386,6 @@ intent.putExtra(ShortcutHelper.EXTRA_SOURCE, source()); intent.putExtra(ShortcutHelper.EXTRA_THEME_COLOR, themeColor()); intent.putExtra(ShortcutHelper.EXTRA_BACKGROUND_COLOR, backgroundColor()); - intent.putExtra(ShortcutHelper.EXTRA_SPLASH_SCREEN_URL, splashScreenUri().toString()); intent.putExtra(ShortcutHelper.EXTRA_IS_ICON_GENERATED, isIconGenerated()); intent.putExtra(ShortcutHelper.EXTRA_IS_ICON_ADAPTIVE, isIconAdaptive()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java index cf7c8f6..ab7b3b01 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
@@ -1566,7 +1566,7 @@ private static WebappInfo newWebappInfoFromScope(String scope) { return WebappInfo.create("", "", scope, null, null, null, WebDisplayMode.STANDALONE, 0, 0, - 0, 0, null, false, false, false); + 0, 0, false, false, false); } private static class IntentActivity {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java index eebdaa9..d56d4af 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java
@@ -292,7 +292,7 @@ // If the CONTENT_SETTINGS_NUM_TYPES value changes *and* a new value has been exposed on // Android, then please update this code block to include a test for your new type. // Otherwise, just update count in the assert. - Assert.assertEquals(49, ContentSettingsType.CONTENT_SETTINGS_NUM_TYPES); + Assert.assertEquals(51, ContentSettingsType.CONTENT_SETTINGS_NUM_TYPES); websitePreferenceBridge.addContentSettingException( new ContentSettingException(ContentSettingsType.CONTENT_SETTINGS_TYPE_COOKIES, googleOrigin, ContentSettingValues.DEFAULT, preferenceSource));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java index a5a77c8..75229240 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java
@@ -42,15 +42,12 @@ import org.chromium.components.safe_browsing.SafeBrowsingApiBridge; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.test.util.CriteriaHelper; -import org.chromium.content_public.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.common.ContentSwitches; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.ui.base.PageTransition; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; /** * Integration tests for {@link PageViewObserver} and {@link SuspendedTab} @@ -63,9 +60,6 @@ public class TabSuspensionTest { private static final String STARTING_FQDN = "example.com"; private static final String DIFFERENT_FQDN = "www.google.com"; - private static final String MAINFRAME_TEST_PAGE = - "/chrome/test/data/android/usage_stats/amp_root.html"; - private static final String SUBFRAME_TEST_PAGE = "/chrome/test/data/android/test.html"; @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -75,13 +69,12 @@ @Mock private UsageStatsBridge mUsageStatsBridge; @Mock - private EventTracker mEventTracker; - @Mock private SuspensionTracker mSuspensionTracker; private ChromeTabbedActivity mActivity; private PageViewObserver mPageViewObserver; private TokenTracker mTokenTracker; + private EventTracker mEventTracker; private Tab mTab; private EmbeddedTestServer mTestServer; private String mStartingUrl; @@ -90,10 +83,12 @@ @Before public void setUp() throws InterruptedException { MockitoAnnotations.initMocks(this); - // TokenTracker holds a promise, and Promises can only be used on a single thread, so we - // have to initialize it on the thread where it will be used. - TestThreadUtils.runOnUiThreadBlocking( - () -> { mTokenTracker = new TokenTracker(mUsageStatsBridge); }); + // TokenTracker and EventTracker hold a promise, and Promises can only be used on a single + // thread, so we have to initialize them on the thread where they will be used. + TestThreadUtils.runOnUiThreadBlocking(() -> { + mTokenTracker = new TokenTracker(mUsageStatsBridge); + mEventTracker = new EventTracker(mUsageStatsBridge); + }); mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); mStartingUrl = mTestServer.getURLWithHostName(STARTING_FQDN, "/defaultresponse"); mDifferentUrl = mTestServer.getURLWithHostName(DIFFERENT_FQDN, "/defaultresponse"); @@ -286,38 +281,6 @@ }); } - @Test - @MediumTest - public void testAmpPage() throws InterruptedException, TimeoutException { - String mainframeUrl = mTestServer.getURLWithHostName(DIFFERENT_FQDN, MAINFRAME_TEST_PAGE); - mActivityTestRule.loadUrl(mainframeUrl); - doReturn(true).when(mSuspensionTracker).isWebsiteSuspended(STARTING_FQDN); - - String iframeSrc = - mTestServer.getURLWithHostName(STARTING_FQDN, SUBFRAME_TEST_PAGE + "?amp_js_v=0"); - String code = "document.getElementById('iframe_test_id').src='" + iframeSrc + "';"; - JavaScriptUtils.executeJavaScriptAndWaitForResult( - mTab.getWebContents(), code, 3, TimeUnit.SECONDS); - waitForSuspendedTabToShow(mTab, STARTING_FQDN); - - doReturn(false).when(mSuspensionTracker).isWebsiteSuspended(STARTING_FQDN); - unsuspendDomain(STARTING_FQDN); - assertSuspendedTabHidden(mTab); - - // Un-suspension reloads the page, so we need to wait for it to load and re-navigate the - // iframe back to the suspended domain. - ChromeTabUtils.waitForTabPageLoaded(mTab, mainframeUrl); - JavaScriptUtils.executeJavaScriptAndWaitForResult( - mTab.getWebContents(), code, 3, TimeUnit.SECONDS); - - doReturn(true).when(mSuspensionTracker).isWebsiteSuspended(STARTING_FQDN); - suspendDomain(STARTING_FQDN); - waitForSuspendedTabToShow(mTab, STARTING_FQDN); - - mActivityTestRule.loadUrl(mDifferentUrl); - assertSuspendedTabHidden(mTab); - } - private void startLoadingUrl(Tab tab, String url) { TestThreadUtils.runOnUiThreadBlocking( () -> { tab.loadUrl(new LoadUrlParams(url, PageTransition.TYPED)); });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java index be5bfcd..fa99e35 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java
@@ -27,7 +27,6 @@ import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ShortcutHelper; @@ -61,7 +60,6 @@ @Feature({"Webapps"}) @RetryOnFailure @MinAndroidSdkLevel(Build.VERSION_CODES.M) // NotificationManager.getActiveNotifications - @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.PWA_PERSISTENT_NOTIFICATION}) public void testNotification_openInChrome() throws Exception { Notification notification = getWebappNotification(); @@ -92,7 +90,6 @@ @Feature({"Webapps"}) @RetryOnFailure @MinAndroidSdkLevel(Build.VERSION_CODES.M) // NotificationManager.getActiveNotifications - @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.PWA_PERSISTENT_NOTIFICATION}) */ @DisabledTest(message = "crbug.com/774491") public void testNotification_copyUrl() throws Exception { @@ -110,19 +107,6 @@ }); } - @Test - /* - @SmallTest - @Feature({"Webapps"}) - @MinAndroidSdkLevel(Build.VERSION_CODES.M) // NotificationManager.getActiveNotifications - @CommandLineFlags.Add({"disable-features=" + ChromeFeatureList.PWA_PERSISTENT_NOTIFICATION}) - */ - @DisabledTest(message = "crbug.com/768557") - public void testNotificationNotEnabled() throws Exception { - // Note ChromeFeatureList.PWA_PERSISTENT_NOTIFICATION is not enabled. - Assert.assertNull(getWebappNotification()); - } - @Nullable private Notification getWebappNotification() { NotificationManager nm =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java index cfe3d0c..130bbfbc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
@@ -90,7 +90,7 @@ WebappInfo webappInfo = WebappInfo.create(id, url, null, new WebappInfo.Icon(icon), title, null, WebDisplayMode.STANDALONE, ScreenOrientationValues.PORTRAIT, ShortcutSource.UNKNOWN, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, - ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, null, false /* isIconGenerated */, + ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, false /* isIconGenerated */, false /* isIconAdaptive */, false /* forceNavigation */); webappInfo.setWebappIntentExtras(intent);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappVisibilityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappVisibilityTest.java index 0979c1a8..18991d5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappVisibilityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappVisibilityTest.java
@@ -130,7 +130,7 @@ @WebappScopePolicy.Type int scopePolicy, @WebDisplayMode int displayMode) { return scopePolicy == WebappScopePolicy.Type.LEGACY ? WebappInfo.create("", webappStartUrlOrScopeUrl, null, null, null, null, - displayMode, 0, 0, 0, 0, null, false /* isIconGenerated */, + displayMode, 0, 0, 0, 0, false /* isIconGenerated */, false /* isIconAdaptive */, false /* forceNavigation */) : WebApkInfo.create( "", "", webappStartUrlOrScopeUrl, null, null, null, null, null, displayMode,
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java index de73d32..17d82b9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
@@ -75,7 +75,7 @@ doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt()); doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(true), any()); // See verification of nativeWipeProfileData below. - doReturn("TestDomain").when(mNativeMock).getManagementDomain(any(), anyLong()); + doReturn("TestDomain").when(mDelegateMock).getManagementDomain(any(), anyLong()); // Trigger the sign out flow! mSigninManager.signOut(SignoutReason.SIGNOUT_TEST); @@ -98,7 +98,7 @@ doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt()); doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(false), any()); // See verification of nativeWipeGoogleServiceWorkerCaches below. - doReturn(null).when(mNativeMock).getManagementDomain(any(), anyLong()); + doReturn(null).when(mDelegateMock).getManagementDomain(any(), anyLong()); // Trigger the sign out flow! mSigninManager.signOut(SignoutReason.SIGNOUT_TEST); @@ -121,7 +121,7 @@ doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt()); doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(true), any()); // See verification of nativeWipeProfileData below. - doReturn("TestDomain").when(mNativeMock).getManagementDomain(any(), anyLong()); + doReturn("TestDomain").when(mDelegateMock).getManagementDomain(any(), anyLong()); // Trigger the sign out flow! mSigninManager.onNativeSignOut(); @@ -141,7 +141,7 @@ doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt()); doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(false), any()); // See verification of nativeWipeGoogleServiceWorkerCaches below. - doReturn(null).when(mNativeMock).getManagementDomain(any(), anyLong()); + doReturn(null).when(mDelegateMock).getManagementDomain(any(), anyLong()); // Trigger the sign out flow! mSigninManager.onNativeSignOut();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java index 47370876..d2185c80 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java
@@ -87,7 +87,6 @@ assertEquals("orientation", WebappDataStorage.KEY_ORIENTATION); assertEquals("theme_color", WebappDataStorage.KEY_THEME_COLOR); assertEquals("background_color", WebappDataStorage.KEY_BACKGROUND_COLOR); - assertEquals("splash_screen_url", WebappDataStorage.KEY_SPLASH_SCREEN_URL); assertEquals("source", WebappDataStorage.KEY_SOURCE); assertEquals("action", WebappDataStorage.KEY_ACTION); assertEquals("is_icon_generated", WebappDataStorage.KEY_IS_ICON_GENERATED); @@ -216,13 +215,11 @@ final int orientation = 1; final long themeColor = 2; final long backgroundColor = 3; - final String splashScreenUrl = "splashy"; final boolean isIconGenerated = false; final boolean isIconAdaptive = false; Intent shortcutIntent = ShortcutHelper.createWebappShortcutIntent(id, action, url, scope, name, shortName, encodedIcon, ShortcutHelper.WEBAPP_SHORTCUT_VERSION, displayMode, - orientation, themeColor, backgroundColor, splashScreenUrl, isIconGenerated, - isIconAdaptive); + orientation, themeColor, backgroundColor, isIconGenerated, isIconAdaptive); WebappDataStorage storage = WebappDataStorage.open("test"); storage.updateFromShortcutIntent(shortcutIntent); @@ -240,8 +237,6 @@ assertEquals(themeColor, mSharedPreferences.getLong(WebappDataStorage.KEY_THEME_COLOR, 0)); assertEquals(backgroundColor, mSharedPreferences.getLong(WebappDataStorage.KEY_BACKGROUND_COLOR, 0)); - assertEquals(splashScreenUrl, - mSharedPreferences.getString(WebappDataStorage.KEY_SPLASH_SCREEN_URL, null)); assertEquals(isIconGenerated, mSharedPreferences.getBoolean(WebappDataStorage.KEY_IS_ICON_GENERATED, true)); assertEquals(isIconAdaptive, @@ -259,7 +254,6 @@ .remove(WebappDataStorage.KEY_ORIENTATION) .remove(WebappDataStorage.KEY_THEME_COLOR) .remove(WebappDataStorage.KEY_BACKGROUND_COLOR) - .remove(WebappDataStorage.KEY_SPLASH_SCREEN_URL) .remove(WebappDataStorage.KEY_IS_ICON_GENERATED) .remove(WebappDataStorage.KEY_IS_ICON_ADAPTIVE) .apply(); @@ -274,8 +268,6 @@ assertEquals(0, mSharedPreferences.getInt(WebappDataStorage.KEY_ORIENTATION, 0)); assertEquals(0, mSharedPreferences.getLong(WebappDataStorage.KEY_THEME_COLOR, 0)); assertEquals(0, mSharedPreferences.getLong(WebappDataStorage.KEY_BACKGROUND_COLOR, 0)); - assertEquals( - null, mSharedPreferences.getString(WebappDataStorage.KEY_SPLASH_SCREEN_URL, null)); assertEquals(true, mSharedPreferences.getBoolean(WebappDataStorage.KEY_IS_ICON_GENERATED, true)); assertEquals(true, @@ -297,8 +289,6 @@ assertEquals(themeColor, mSharedPreferences.getLong(WebappDataStorage.KEY_THEME_COLOR, 0)); assertEquals(backgroundColor, mSharedPreferences.getLong(WebappDataStorage.KEY_BACKGROUND_COLOR, 0)); - assertEquals(splashScreenUrl, - mSharedPreferences.getString(WebappDataStorage.KEY_SPLASH_SCREEN_URL, null)); assertEquals(isIconGenerated, mSharedPreferences.getBoolean(WebappDataStorage.KEY_IS_ICON_GENERATED, true)); assertEquals(isIconAdaptive,
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappInfoTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappInfoTest.java index b79553ea..4ad96e620 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappInfoTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappInfoTest.java
@@ -23,8 +23,6 @@ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) public class WebappInfoTest { - private static final String SPLASH_SCREEN_URL = "https://foo.com/splash.html"; - @Test public void testAbout() { String id = "webapp id"; @@ -35,9 +33,8 @@ WebappInfo info = WebappInfo.create(id, url, null, null, name, shortName, WebDisplayMode.STANDALONE, ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, - ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, SPLASH_SCREEN_URL, - false /* isIconGenerated */, false /* isIconAdaptive */, - false /* forceNavigation */); + ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, false /* isIconGenerated */, + false /* isIconAdaptive */, false /* forceNavigation */); Assert.assertNotNull(info); } @@ -51,9 +48,8 @@ WebappInfo info = WebappInfo.create(id, url, null, null, name, shortName, WebDisplayMode.STANDALONE, ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, - ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, SPLASH_SCREEN_URL, - false /* isIconGenerated */, false /* isIconAdaptive */, - false /* forceNavigation */); + ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, false /* isIconGenerated */, + false /* isIconAdaptive */, false /* forceNavigation */); Assert.assertNotNull(info); } @@ -136,9 +132,8 @@ WebappInfo info = WebappInfo.create(id, url, null, null, name, shortName, WebDisplayMode.FULLSCREEN, ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, - ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, SPLASH_SCREEN_URL, - false /* isIconGenerated */, false /* isIconAdaptive */, - false /* forceNavigation */); + ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, false /* isIconGenerated */, + false /* isIconAdaptive */, false /* forceNavigation */); Assert.assertEquals(WebDisplayMode.FULLSCREEN, info.displayMode()); Assert.assertEquals(ScreenOrientationValues.DEFAULT, info.orientation()); Assert.assertEquals(ShortcutSource.UNKNOWN, info.source()); @@ -155,7 +150,7 @@ WebappInfo info = WebappInfo.create(id, url, null, null, name, shortName, WebDisplayMode.STANDALONE, ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, - themeColor, backgroundColor, SPLASH_SCREEN_URL, false /* isIconGenerated */, + themeColor, backgroundColor, false /* isIconGenerated */, false /* isIconAdaptive */, false /* forceNavigation */); Assert.assertEquals(themeColor, info.themeColor()); Assert.assertEquals(backgroundColor, info.backgroundColor()); @@ -171,9 +166,8 @@ WebappInfo info = WebappInfo.create(id, url, null, null, name, shortName, WebDisplayMode.STANDALONE, ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, - ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, SPLASH_SCREEN_URL, - false /* isIconGenerated */, false /* isIconAdaptive */, - false /* forceNavigation */); + ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, false /* isIconGenerated */, + false /* isIconAdaptive */, false /* forceNavigation */); Assert.assertEquals(ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, info.themeColor()); Assert.assertEquals( ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, info.backgroundColor()); @@ -228,22 +222,6 @@ } @Test - public void testSplashScreenUrl() { - Intent intent = createIntentWithUrlAndId(); - { - WebappInfo info = WebappInfo.create(intent); - Assert.assertFalse(info.hasSplashScreenUri()); - } - - intent.putExtra(ShortcutHelper.EXTRA_SPLASH_SCREEN_URL, SPLASH_SCREEN_URL); - { - WebappInfo info = WebappInfo.create(intent); - Assert.assertTrue(info.hasSplashScreenUri()); - Assert.assertEquals(SPLASH_SCREEN_URL, info.splashScreenUri().toString()); - } - } - - @Test public void testIntentGeneratedIcon() { String id = "webapp id"; String name = "longName";
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java index e641924..4c015361 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java
@@ -198,6 +198,8 @@ listener.setIsMultiClickable(model.get(DialogListItemProperties.MULTI_CLICKABLE)); model.set(DialogListItemProperties.CLICK_LISTENER, listener); view.setOnClickListener(listener); + } else { + view.setOnClickListener(model.get(DialogListItemProperties.CLICK_LISTENER)); } } else if (DialogListItemProperties.MULTI_CLICKABLE == propertyKey) { View.OnClickListener listener = model.get(DialogListItemProperties.CLICK_LISTENER);
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 83ceb0a2..e09d899 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -619,7 +619,6 @@ if (is_chromeos) { deps += [ "//ash/public/cpp:manifest", - "//chrome/services/ble_scan_parser/public/cpp:manifest", "//chrome/services/cups_ipp_parser/public/cpp:manifest", "//chrome/services/cups_proxy/public/cpp:manifest", "//chromeos/services/cellular_setup/public/cpp:manifest",
diff --git a/chrome/app/DEPS b/chrome/app/DEPS index 291ba12..cd61910 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS
@@ -83,7 +83,6 @@ "+third_party/blink/public/mojom", ], "builtin_service_manifests\.cc": [ - "+chrome/services/ble_scan_parser/public", "+chrome/services/cups_ipp_parser/public", "+chrome/services/cups_proxy/public", "+chrome/services/file_util/public",
diff --git a/chrome/app/builtin_service_manifests.cc b/chrome/app/builtin_service_manifests.cc index 9a8a88d..fc1cd13b 100644 --- a/chrome/app/builtin_service_manifests.cc +++ b/chrome/app/builtin_service_manifests.cc
@@ -8,7 +8,6 @@ #include "build/build_config.h" #include "chrome/common/buildflags.h" #include "chrome/common/constants.mojom.h" -#include "chrome/services/ble_scan_parser/public/cpp/manifest.h" #include "chrome/services/file_util/public/cpp/manifest.h" #include "components/services/patch/public/cpp/manifest.h" #include "components/services/quarantine/public/cpp/manifest.h" @@ -143,7 +142,6 @@ #endif #if defined(OS_CHROMEOS) ash::GetManifest(), - ble_scan_parser::GetManifest(), chromeos::cellular_setup::GetManifest(), chromeos::ime::GetManifest(), chromeos::network_config::GetManifest(),
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index d888fdc..d10ecaa 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -3360,11 +3360,6 @@ <message name="IDS_UTILITY_PROCESS_NOOP_SERVICE_NAME" desc="The name of the utility process which does nothing, used for experimentation."> No-op Service </message> - <if expr="chromeos"> - <message name="IDS_UTILITY_PROCESS_BLE_SCAN_PARSER_NAME" desc="The name of the utility process used for parsing BLE scans."> - BLE Scan Parser Service - </message> - </if> <!-- Theme preview infobar --> <message name="IDS_THEME_INSTALL_INFOBAR_LABEL" desc="Text displayed on an infobar when a theme has been installed."> Installed theme "<ph name="THEME_NAME">$1<ex>Snowflake Theme</ex></ph>"
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 000d10a5..9d1b2531 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -919,8 +919,6 @@ "page_load_metrics/observers/ad_metrics/frame_data.h", "page_load_metrics/observers/amp_page_load_metrics_observer.cc", "page_load_metrics/observers/amp_page_load_metrics_observer.h", - "page_load_metrics/observers/amp_ukm_observer.cc", - "page_load_metrics/observers/amp_ukm_observer.h", "page_load_metrics/observers/core_page_load_metrics_observer.cc", "page_load_metrics/observers/core_page_load_metrics_observer.h", "page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc", @@ -1076,9 +1074,10 @@ "performance_manager/persistence/site_data/noop_site_data_writer.cc", "performance_manager/persistence/site_data/noop_site_data_writer.h", "performance_manager/persistence/site_data/site_data_cache.h", + "performance_manager/persistence/site_data/site_data_cache_factory.cc", + "performance_manager/persistence/site_data/site_data_cache_factory.h", "performance_manager/persistence/site_data/site_data_cache_impl.cc", "performance_manager/persistence/site_data/site_data_cache_impl.h", - "performance_manager/persistence/site_data/site_data_cache_inspector.cc", "performance_manager/persistence/site_data/site_data_cache_inspector.h", "performance_manager/persistence/site_data/site_data_impl.cc", "performance_manager/persistence/site_data/site_data_impl.h", @@ -1491,10 +1490,16 @@ "sessions/session_tab_helper.h", "sessions/tab_restore_service_factory.cc", "sessions/tab_restore_service_factory.h", + "sharing/ack_message_handler.cc", + "sharing/ack_message_handler.h", "sharing/features.cc", "sharing/features.h", "sharing/sharing_device_info.cc", "sharing/sharing_device_info.h", + "sharing/sharing_fcm_handler.cc", + "sharing/sharing_fcm_handler.h", + "sharing/sharing_fcm_sender.cc", + "sharing/sharing_fcm_sender.h", "sharing/sharing_message_handler.h", "sharing/sharing_service.cc", "sharing/sharing_service.h", @@ -1739,6 +1744,8 @@ "vr/ui_suppressed_element.h", "vr/vr_tab_helper.cc", "vr/vr_tab_helper.h", + "wake_lock/wake_lock_permission_context.cc", + "wake_lock/wake_lock_permission_context.h", "web_data_service_factory.cc", "web_data_service_factory.h", "webauthn/authenticator_list_observer.h",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 48cd7fc..beb0b7d 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -183,8 +183,6 @@ "+third_party/blink/public/platform/web_speech_synthesis_constants.h", "+third_party/blink/public/platform/web_sudden_termination_disabler_type.h", "+third_party/blink/public/platform/modules/notifications/web_notification_constants.h", - "+third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_availability.h", - "+third_party/blink/public/platform/modules/screen_orientation/web_screen_orientation_lock_type.h", "+third_party/blink/public/public_buildflags.h", "+third_party/blink/public/web/web_context_menu_data.h", "+third_party/blink/public/web/web_fullscreen_options.h", @@ -193,11 +191,6 @@ "+third_party/blink/public/web/web_presentation_receiver_flags.h", "+third_party/blink/public/web/web_text_direction.h", "+third_party/blink/public/web/web_triggering_event_info.h", - - # Allow mojo generated files in WebKit. These files use STL types and - # don't use WTF types. - "+third_party/blink/public/platform/modules/budget_service/budget_service.mojom.h", - "+third_party/blink/public/platform/modules/presentation/presentation.mojom.h", ] specific_include_rules = {
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 47730bf..7c07f583 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2680,13 +2680,6 @@ FEATURE_VALUE_TYPE(chrome::android::kReaderModeInCCT)}, #endif // !defined(OS_ANDROID) -#if defined(OS_ANDROID) - {"pwa-persistent-notification", - flag_descriptions::kPwaPersistentNotificationName, - flag_descriptions::kPwaPersistentNotificationDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kPwaPersistentNotification)}, -#endif // OS_ANDROID - {"click-to-open-pdf", flag_descriptions::kClickToOpenPDFName, flag_descriptions::kClickToOpenPDFDescription, kOsAll, FEATURE_VALUE_TYPE(features::kClickToOpenPDFPlaceholder)}, @@ -3175,12 +3168,6 @@ #endif // OS_CHROMEOS #if defined(OS_CHROMEOS) - {"enable-drive-fs", flag_descriptions::kEnableDriveFsName, - flag_descriptions::kEnableDriveFsDescription, kOsCrOS, - FEATURE_VALUE_TYPE(chromeos::features::kDriveFs)}, -#endif // OS_CHROMEOS - -#if defined(OS_CHROMEOS) {"enable-myfiles-volume", flag_descriptions::kEnableMyFilesVolumeName, flag_descriptions::kEnableMyFilesVolumeDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kMyFilesVolume)},
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index f0bddb79..14a752de 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -153,7 +153,6 @@ &kPayWithGoogleV1, &kPhotoPickerVideoSupport, &kProgressBarThrottleFeature, - &kPwaPersistentNotification, &kReachedCodeProfiler, &kReaderModeInCCT, &kRevampedContextMenu, @@ -483,9 +482,6 @@ const base::Feature kProgressBarThrottleFeature{ "ProgressBarThrottle", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kPwaPersistentNotification{ - "PwaPersistentNotification", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kReachedCodeProfiler{"ReachedCodeProfiler", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 4711027..8393201 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -92,7 +92,6 @@ extern const base::Feature kPayWithGoogleV1; extern const base::Feature kPhotoPickerVideoSupport; extern const base::Feature kProgressBarThrottleFeature; -extern const base::Feature kPwaPersistentNotification; extern const base::Feature kReachedCodeProfiler; extern const base::Feature kReaderModeInCCT; extern const base::Feature kRevampedContextMenu;
diff --git a/chrome/browser/android/preferences/prefs.h b/chrome/browser/android/preferences/prefs.h index a71d5f3..4ac67b7 100644 --- a/chrome/browser/android/preferences/prefs.h +++ b/chrome/browser/android/preferences/prefs.h
@@ -18,6 +18,7 @@ #include "components/ntp_snippets/pref_names.h" #include "components/offline_pages/core/prefetch/prefetch_prefs.h" #include "components/payments/core/payment_prefs.h" +#include "components/safe_browsing/common/safe_browsing_prefs.h" // A preference exposed to Java. // A Java counterpart will be generated for this enum. @@ -36,6 +37,7 @@ AUTOFILL_CREDIT_CARD_ENABLED, USAGE_STATS_ENABLED, OFFLINE_PREFETCH_USER_SETTING_ENABLED, + SAFE_BROWSING_EXTENDED_REPORTING_OPT_IN_ALLOWED, // PREF_NUM_PREFS must be the last entry. PREF_NUM_PREFS }; @@ -63,6 +65,7 @@ autofill::prefs::kAutofillCreditCardEnabled, prefs::kUsageStatsEnabled, offline_pages::prefetch_prefs::kUserSettingEnabled, + prefs::kSafeBrowsingExtendedReportingOptInAllowed, }; #endif // CHROME_BROWSER_ANDROID_PREFERENCES_PREFS_H_
diff --git a/chrome/browser/android/preferences/prefs_unittest.cc b/chrome/browser/android/preferences/prefs_unittest.cc index ab2e406..46ee66e 100644 --- a/chrome/browser/android/preferences/prefs_unittest.cc +++ b/chrome/browser/android/preferences/prefs_unittest.cc
@@ -62,6 +62,8 @@ EXPECT_EQ(prefs::kUsageStatsEnabled, GetPrefName(USAGE_STATS_ENABLED)); EXPECT_EQ(offline_pages::prefetch_prefs::kUserSettingEnabled, GetPrefName(OFFLINE_PREFETCH_USER_SETTING_ENABLED)); + EXPECT_EQ(prefs::kSafeBrowsingExtendedReportingOptInAllowed, + GetPrefName(SAFE_BROWSING_EXTENDED_REPORTING_OPT_IN_ALLOWED)); // If this check fails, a pref is missing a test case above. EXPECT_EQ(Pref::PREF_NUM_PREFS, pref_count_);
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc index 270093b..ec24eeb 100644 --- a/chrome/browser/android/shortcut_helper.cc +++ b/chrome/browser/android/shortcut_helper.cc
@@ -98,9 +98,6 @@ ScopedJavaLocalRef<jstring> java_best_primary_icon_url = base::android::ConvertUTF8ToJavaString(env, info.best_primary_icon_url.spec()); - ScopedJavaLocalRef<jstring> java_splash_screen_url = - base::android::ConvertUTF8ToJavaString(env, - info.splash_screen_url.spec()); ScopedJavaLocalRef<jobject> java_bitmap; if (!icon_bitmap.drawsNothing()) java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap); @@ -117,8 +114,7 @@ java_short_name, java_best_primary_icon_url, java_bitmap, is_icon_maskable, info.display, info.orientation, info.source, OptionalSkColorToJavaColor(info.theme_color), - OptionalSkColorToJavaColor(info.background_color), java_splash_screen_url, - callback_pointer); + OptionalSkColorToJavaColor(info.background_color), callback_pointer); } // Adds a shortcut which opens in a browser tab to the launcher.
diff --git a/chrome/browser/android/shortcut_info.cc b/chrome/browser/android/shortcut_info.cc index 6282507..45ed410 100644 --- a/chrome/browser/android/shortcut_info.cc +++ b/chrome/browser/android/shortcut_info.cc
@@ -80,10 +80,6 @@ if (manifest.background_color) background_color = manifest.background_color; - // Sets the URL of the HTML splash screen, if any. - if (manifest.splash_screen_url.is_valid()) - splash_screen_url = manifest.splash_screen_url; - // Set the icon urls based on the icons in the manifest, if any. icon_urls.clear(); for (const auto& icon : manifest.icons)
diff --git a/chrome/browser/android/shortcut_info.h b/chrome/browser/android/shortcut_info.h index 1a05dd5..b830a5d 100644 --- a/chrome/browser/android/shortcut_info.h +++ b/chrome/browser/android/shortcut_info.h
@@ -119,7 +119,6 @@ Source source; base::Optional<SkColor> theme_color; base::Optional<SkColor> background_color; - GURL splash_screen_url; int ideal_splash_image_size_in_px; int minimum_splash_image_size_in_px; GURL splash_image_url;
diff --git a/chrome/browser/android/shortcut_info_unittest.cc b/chrome/browser/android/shortcut_info_unittest.cc index 6ee8d7c..581a365 100644 --- a/chrome/browser/android/shortcut_info_unittest.cc +++ b/chrome/browser/android/shortcut_info_unittest.cc
@@ -46,9 +46,6 @@ info_.background_color = 0xffaa0000; manifest_.background_color = 0xffbb0000; - info_.splash_screen_url = GURL("https://old.com/splash.html"); - manifest_.splash_screen_url = GURL("https://new.com/splash.html"); - info_.icon_urls.push_back("https://old.com/icon.png"); blink::Manifest::ImageResource icon; icon.src = GURL("https://new.com/icon.png"); @@ -63,7 +60,6 @@ ASSERT_EQ(manifest_.display, info_.display); ASSERT_EQ(manifest_.theme_color, info_.theme_color); ASSERT_EQ(manifest_.background_color, info_.background_color); - ASSERT_EQ(manifest_.splash_screen_url, info_.splash_screen_url); ASSERT_EQ(1u, info_.icon_urls.size()); ASSERT_EQ(manifest_.icons[0].src, GURL(info_.icon_urls[0])); }
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc index f3527ebd..f599078 100644 --- a/chrome/browser/android/signin/signin_manager_android.cc +++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -357,7 +357,7 @@ return reinterpret_cast<intptr_t>(signin_manager_android); } -void SigninManagerAndroid::IsUserManaged( +void SigninManagerAndroid::IsAccountManaged( JNIEnv* env, const JavaParamRef<jobject>& obj, const JavaParamRef<jstring>& j_username,
diff --git a/chrome/browser/android/signin/signin_manager_android.h b/chrome/browser/android/signin/signin_manager_android.h index 55d90fd2..bb16d31 100644 --- a/chrome/browser/android/signin/signin_manager_android.h +++ b/chrome/browser/android/signin/signin_manager_android.h
@@ -81,10 +81,10 @@ jboolean IsSignedInOnNative(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - void IsUserManaged(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_username, - const base::android::JavaParamRef<jobject>& j_callback); + void IsAccountManaged(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& j_username, + const base::android::JavaParamRef<jobject>& j_callback); // identity::IdentityManager::Observer implementation. void OnPrimaryAccountCleared(
diff --git a/chrome/browser/android/webapps/add_to_homescreen_manager.cc b/chrome/browser/android/webapps/add_to_homescreen_manager.cc index afdc489..c064cd66 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_manager.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
@@ -86,8 +86,7 @@ // Fire the appinstalled event and do install time logging. banners::AppBannerManagerAndroid* app_banner_manager = banners::AppBannerManagerAndroid::FromWebContents(web_contents); - app_banner_manager->OnInstall(false /* is_native */, - data_fetcher_->shortcut_info().display); + app_banner_manager->OnInstall(data_fetcher_->shortcut_info().display); } void AddToHomescreenManager::Start(content::WebContents* web_contents) {
diff --git a/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm b/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm index 1b8d8a3..9f73165 100644 --- a/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm +++ b/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm
@@ -301,7 +301,9 @@ namespace apps { -// Shims require static libraries http://crbug.com/386024. +// Shims require static libraries unless running from their original build +// location. +// https://crbug.com/386024, https://crrev.com/619648 #if defined(COMPONENT_BUILD) #define MAYBE_Launch DISABLED_Launch #define MAYBE_HostedAppLaunch DISABLED_HostedAppLaunch
diff --git a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc index ccf9324..56f5522 100644 --- a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc +++ b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc
@@ -227,6 +227,10 @@ DISALLOW_COPY_AND_ASSIGN(EnableViaPrompt); }; +bool UsesRemoteViews(const extensions::Extension* extension) { + return extension->is_hosted_app() && extension->from_bookmark(); +} + } // namespace namespace apps { @@ -299,7 +303,7 @@ Profile* profile, const extensions::Extension* extension) { return new AppShimHost(extension->id(), profile->GetPath(), - extension->is_hosted_app()); + UsesRemoteViews(extension)); } void ExtensionAppShimHandler::Delegate::EnableExtension( @@ -338,7 +342,10 @@ bool recreate_shims, apps::ShimLaunchedCallback launched_callback, apps::ShimTerminatedCallback terminated_callback) { - if (recreate_shims) { + // Only force recreation of shims when RemoteViews is in use (that is, for + // PWAs). Otherwise, shims may be created unexpectedly. + // https://crbug.com/941160 + if (recreate_shims && UsesRemoteViews(extension)) { // Load the resources needed to build the app shim (icons, etc), and then // recreate the shim and launch it. web_app::GetShortcutInfoForApp(
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc index e73e4ea..5fb3f623 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -268,6 +268,11 @@ #endif // !defined(OS_ANDROID) } +component_updater::ComponentUpdateService* +ChromeAutocompleteProviderClient::GetComponentUpdateService() { + return g_browser_process->component_updater(); +} + bool ChromeAutocompleteProviderClient::IsOffTheRecord() const { return profile_->IsOffTheRecord(); }
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h index 2aee567..bb354c8f5 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h
@@ -52,6 +52,9 @@ // GetCurrentVisitTimestamp is only implemented for desktop users. For mobile // users, the function returns base::Time(). base::Time GetCurrentVisitTimestamp() const override; + component_updater::ComponentUpdateService* GetComponentUpdateService() + override; + bool IsOffTheRecord() const override; bool SearchSuggestEnabled() const override; bool IsPersonalizedUrlDataCollectionActive() const override;
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc index 9fa0c4b..7053c9f 100644 --- a/chrome/browser/banners/app_banner_manager.cc +++ b/chrome/browser/banners/app_banner_manager.cc
@@ -175,24 +175,24 @@ base::BindOnce(&AppBannerManager::OnDidGetManifest, GetWeakPtr())); } -void AppBannerManager::OnInstall(bool is_native, - blink::WebDisplayMode display) { - if (!is_native) - TrackInstallDisplayMode(display); +void AppBannerManager::OnInstall(blink::WebDisplayMode display) { + TrackInstallDisplayMode(display); blink::mojom::InstallationServicePtr installation_service; web_contents()->GetMainFrame()->GetRemoteInterfaces()->GetInterface( mojo::MakeRequest(&installation_service)); DCHECK(installation_service); installation_service->OnInstall(); - // We've triggered an installation, so reset bindings to ensure that any - // existing beforeinstallprompt events cannot trigger add to home screen. - ResetBindings(); + // App has been installed (possibly by the user), page may no longer request + // install prompt. + binding_.Close(); } void AppBannerManager::SendBannerAccepted() { - if (event_.is_bound()) + if (event_.is_bound()) { event_->BannerAccepted(GetBannerType()); + event_.reset(); + } } void AppBannerManager::SendBannerDismissed() { @@ -777,6 +777,9 @@ } void AppBannerManager::DisplayAppBanner() { + // Prevent this from being called multiple times on the same connection. + binding_.Close(); + if (state_ == State::PENDING_PROMPT) { ShowBanner(); } else if (state_ == State::SENDING_EVENT) {
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h index 67a9638..c806b10 100644 --- a/chrome/browser/banners/app_banner_manager.h +++ b/chrome/browser/banners/app_banner_manager.h
@@ -153,7 +153,7 @@ // redundant for the beforeinstallprompt event's promise being resolved, but // is required by the install event spec. // This is virtual for testing. - virtual void OnInstall(bool is_native, blink::WebDisplayMode display); + virtual void OnInstall(blink::WebDisplayMode display); // Sends a message to the renderer that the user accepted the banner. void SendBannerAccepted();
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc index 4a935b0..494bbcc 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.cc +++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -54,9 +54,15 @@ AppBannerManagerDesktop::AppBannerManagerDesktop( content::WebContents* web_contents) - : AppBannerManager(web_contents), - extension_registry_(extensions::ExtensionRegistry::Get( - web_contents->GetBrowserContext())) {} + : AppBannerManager(web_contents), registrar_observer_(this) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + extension_registry_ = extensions::ExtensionRegistry::Get(profile); + auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile); + // May be null in unit tests e.g. TabDesktopMediaListTest.*. + if (provider) + registrar_observer_.Add(&provider->registrar()); +} AppBannerManagerDesktop::~AppBannerManagerDesktop() { } @@ -147,6 +153,21 @@ AppBannerManager::OnEngagementEvent(web_contents, url, score, type); } +void AppBannerManagerDesktop::OnWebAppInstalled( + const web_app::AppId& installed_app_id) { + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile); + DCHECK(provider); + web_app::AppId app_id = provider->registrar().FindAppIdForUrl(validated_url_); + if (!app_id.empty() && app_id == installed_app_id) + OnInstall(blink::kWebDisplayModeStandalone); +} + +void AppBannerManagerDesktop::OnAppRegistrarDestroyed() { + registrar_observer_.RemoveAll(); +} + void AppBannerManagerDesktop::CreateWebApp(WebappInstallSource install_source) { content::WebContents* contents = web_contents(); DCHECK(contents); @@ -184,9 +205,6 @@ SendBannerAccepted(); AppBannerSettingsHelper::RecordBannerInstallEvent( contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB); - - // OnInstall must be called last since it resets Mojo bindings. - OnInstall(false /* is_native app */, blink::kWebDisplayModeStandalone); } WEB_CONTENTS_USER_DATA_KEY_IMPL(AppBannerManagerDesktop)
diff --git a/chrome/browser/banners/app_banner_manager_desktop.h b/chrome/browser/banners/app_banner_manager_desktop.h index 5fa0ded..1c3663b 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.h +++ b/chrome/browser/banners/app_banner_manager_desktop.h
@@ -10,6 +10,8 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/banners/app_banner_manager.h" +#include "chrome/browser/web_applications/components/app_registrar.h" +#include "chrome/browser/web_applications/components/app_registrar_observer.h" #include "content/public/browser/web_contents_user_data.h" namespace extensions { @@ -25,7 +27,8 @@ // Manages web app banners for desktop platforms. class AppBannerManagerDesktop : public AppBannerManager, - public content::WebContentsUserData<AppBannerManagerDesktop> { + public content::WebContentsUserData<AppBannerManagerDesktop>, + public web_app::AppRegistrarObserver { public: ~AppBannerManagerDesktop() override; @@ -70,9 +73,17 @@ double score, SiteEngagementService::EngagementType type) override; + // web_app::AppRegistrarObserver: + void OnWebAppInstalled(const web_app::AppId& app_id) override; + void OnAppRegistrarDestroyed() override; + void CreateWebApp(WebappInstallSource install_source); extensions::ExtensionRegistry* extension_registry_; + + ScopedObserver<web_app::AppRegistrar, web_app::AppRegistrarObserver> + registrar_observer_; + base::WeakPtrFactory<AppBannerManagerDesktop> weak_factory_{this}; WEB_CONTENTS_USER_DATA_KEY_DECL();
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc index 9c4f757c..a1188e0 100644 --- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -64,8 +64,8 @@ } protected: - void OnInstall(bool is_native, blink::WebDisplayMode display) override { - AppBannerManager::OnInstall(is_native, display); + void OnInstall(blink::WebDisplayMode display) override { + AppBannerManager::OnInstall(display); if (on_install_) std::move(on_install_).Run(); } @@ -248,15 +248,6 @@ IN_PROC_BROWSER_TEST_F(AppBannerManagerDesktopBrowserTest, InstallPromptAfterUserMenuInstall) { - // TODO(https://crbug.com/915043): Fix this test for the unified install - // codepath. This fails under unified install because the menu install path - // relies on extensions::TabHelper to call AppBannerManager::OnInstall which - // is no longer the case under unified install. This will be fixed in a follow - // up patch when AppBannerManager calls OnInstall by itself via - // AppRegistrarObserver::OnWebAppInstalled(). - if (base::FeatureList::IsEnabled(features::kDesktopPWAsUnifiedInstall)) - return; - FakeAppBannerManagerDesktop* manager = FakeAppBannerManagerDesktop::CreateForWebContents( browser()->tab_strip_model()->GetActiveWebContents());
diff --git a/chrome/browser/banners/app_banner_ui_delegate_android.cc b/chrome/browser/banners/app_banner_ui_delegate_android.cc index 9682c8d..ed66bb29 100644 --- a/chrome/browser/banners/app_banner_ui_delegate_android.cc +++ b/chrome/browser/banners/app_banner_ui_delegate_android.cc
@@ -337,7 +337,7 @@ // WebAPKs). // TODO(mgiuca): Fire the event *after* the installation is completed. if (!IsForNativeApp()) - weak_manager_->OnInstall(/*is_native=*/false, shortcut_info_->display); + weak_manager_->OnInstall(shortcut_info_->display); } } // namespace banners
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc index ddc24f29..c6e2ebf 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
@@ -4,13 +4,19 @@ #include "chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h" +#include <inttypes.h> + #include <algorithm> +#include <set> #include "base/bind.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" +#include "base/memory/ptr_util.h" #include "base/no_destructor.h" +#include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/time/time.h" #include "base/trace_event/common/trace_event_common.h" #include "chrome/browser/chromeos/arc/tracing/arc_graphics_jank_detector.h" @@ -18,6 +24,7 @@ #include "chrome/browser/chromeos/arc/tracing/arc_tracing_event_matcher.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_model.h" #include "components/arc/arc_util.h" +#include "ui/events/event_constants.h" namespace arc { @@ -28,12 +35,16 @@ using BufferEventType = ArcTracingGraphicsModel::BufferEventType; constexpr char kCustomTracePrefix[] = "customTrace"; +constexpr char kInputEventPrefix[] = "InputEvent: "; +constexpr char kDeliverInputEvent[] = "deliverInputEvent"; constexpr char kUnknownActivity[] = "unknown"; constexpr char kArgumentAppId[] = "app_id"; constexpr char kArgumentBufferId[] = "buffer_id"; constexpr char kArgumentPutOffset[] = "put_offset"; +constexpr char kArgumentTimestamp[] = "timestamp"; +constexpr char kArgumentType[] = "type"; constexpr char kKeyActivity[] = "activity"; constexpr char kKeyAndroid[] = "android"; @@ -41,6 +52,7 @@ constexpr char kKeyChrome[] = "chrome"; constexpr char kKeyDuration[] = "duration"; constexpr char kKeyGlobalEvents[] = "global_events"; +constexpr char kKeyInput[] = "input"; constexpr char kKeyViews[] = "views"; constexpr char kKeySystem[] = "system"; constexpr char kKeyTaskId[] = "task_id"; @@ -59,6 +71,9 @@ constexpr char kDequeueBufferQuery[] = "android:dequeueBuffer"; constexpr char kQueueBufferQuery[] = "android:queueBuffer"; +constexpr char kInputQuery[] = + "android:Choreographer#doFrame/android:input/android:"; + constexpr char kBarrierOrderingSubQuery[] = "gpu:CommandBufferProxyImpl::OrderingBarrier"; constexpr char kBufferInUseQuery[] = "exo:BufferInUse"; @@ -78,6 +93,7 @@ "exo:Buffer::ProduceTransferableResource"; constexpr char kExoBufferReleaseContentsMatcher[] = "exo:Buffer::ReleaseContents"; +constexpr char kExoInputEventMatcher[] = "exo:Input::OnInputEvent"; constexpr ssize_t kInvalidBufferIndex = -1; @@ -238,13 +254,41 @@ bool SortByTimestampPred(const ArcTracingGraphicsModel::BufferEvent& a, const ArcTracingGraphicsModel::BufferEvent& b) { - return a.timestamp < b.timestamp; + if (a.timestamp != b.timestamp) + return a.timestamp < b.timestamp; + return static_cast<int>(a.type) < static_cast<int>(b.type); } void SortBufferEventsByTimestamp(BufferEvents* events) { std::sort(events->begin(), events->end(), SortByTimestampPred); } +std::string RouteToSelector(const std::vector<const ArcTracingEvent*>& route) { + std::string result; + for (const ArcTracingEvent* segment : route) + result = result + "/" + segment->GetCategory() + ":" + segment->GetName(); + return result; +} + +void DetermineHierarchy(std::vector<const ArcTracingEvent*>* route, + const ArcTracingEvent* event, + const ArcTracingEventMatcher& matcher, + std::string* out_query) { + if (!out_query->empty()) + return; + + route->emplace_back(event); + + if (matcher.Match(*event)) { + *out_query = RouteToSelector(*route); + } else { + for (const auto& child : event->children()) + DetermineHierarchy(route, child.get(), matcher, out_query); + } + + route->pop_back(); +} + // Extracts buffer id from the surface flinger event. For example: // android|releaseBuffer // android|com.android.vending/com.android.vending.AssetBrowserActivity#0: 2 @@ -386,6 +430,484 @@ return true; } +// Represents input event in Wayland. It contains input timestamp that shows the +// time of event creation, event timestamp in this case shows the time when this +// event was dispatched using Wayland interface. Type defines the input type. +class ExoInputEvent { + public: + ExoInputEvent(const ArcTracingEvent* event, + uint64_t input_timestamp, + ui::EventType type) + : event_(event), input_timestamp_(input_timestamp), type_(type) {} + ~ExoInputEvent() = default; + + // Parses |event| and extracts information for Wayland input event. Returns + // nullptr in case |event| could not be parsed. + static std::unique_ptr<ExoInputEvent> Create(const ArcTracingEvent* event) { + const uint64_t timestamp = + event->GetArgAsDouble(kArgumentTimestamp, 0 /* default_value */); + const int type = + event->GetArgAsInteger(kArgumentType, 0 /* default_value */); + + if (!timestamp || !type) { + LOG(ERROR) << "Could not parse timestamp or type of event: " + << event->ToString(); + return nullptr; + } + + return std::make_unique<ExoInputEvent>(event, timestamp, + static_cast<ui::EventType>(type)); + } + + const ArcTracingEvent* event() const { return event_; } + uint64_t input_timestamp() const { return input_timestamp_; } + ui::EventType type() const { return type_; } + + private: + const ArcTracingEvent* event_; + // Time of the creation of the event. Normally, it is before the event + // timestamp that indicates when event was seen in Wayland. + const uint64_t input_timestamp_; + // Type of the event; + const ui::EventType type_; + + DISALLOW_COPY_AND_ASSIGN(ExoInputEvent); +}; + +bool SortExoByInputTimestampPred(const std::unique_ptr<ExoInputEvent>& a, + const uint64_t input_timestamp) { + return a->input_timestamp() < input_timestamp; +} + +// Represents input event in Android. It contains input timestamp that shows the +// time of the creation event in Chrome. Source defines the origin of the input +// event, mouse, keyboard, touch and so on. Sequence id is the unique +// identifier of the input event in context of one application. +class AndroidInputEvent { + public: + enum Source { + Keyboard = 0x101, + Touch = 0x1002, + Mouse = 0x2002, + }; + + AndroidInputEvent(const ArcTracingEvent* event, + std::vector<uint64_t> input_timestamps, + Source source, + int sequence_id) + : event_(event), + input_timestamps_(std::move(input_timestamps)), + source_(source), + sequence_id_(sequence_id) {} + + ~AndroidInputEvent() = default; + + // Parses |event| and extracts information for Android input event. Returns + // nullptr in case |event| could not be parsed. + static std::unique_ptr<AndroidInputEvent> Create( + const ArcTracingEvent* event) { + if (!base::StartsWith(event->GetName(), kInputEventPrefix, + base::CompareCase::SENSITIVE)) { + return nullptr; + } + + // Has following structure + // InputEvent: source timestamps sequence_id|0| + const std::string body = + event->GetName().substr(base::size(kInputEventPrefix) - 1); + base::StringTokenizer tokenizer(body, " "); + std::vector<std::string> tokens; + while (tokenizer.GetNext()) + tokens.emplace_back(tokenizer.token()); + if (tokens.size() != 3) { + LOG(ERROR) << "Failed to parse input event: " << event->ToString(); + return nullptr; + } + + uint32_t source = -1; + sscanf(tokens[0].c_str(), "%" PRId32, &source); + switch (static_cast<Source>(source)) { + case Source::Keyboard: + case Source::Mouse: + case Source::Touch: + break; + default: + LOG(ERROR) << "Unrecognized source: " << event->ToString(); + return nullptr; + } + + std::vector<uint64_t> input_timestamps; + // Timestamps are separated by comma. It is used in case event is synthetic + // and is composed from one more physical events. + base::StringTokenizer tokenizer_timestamps(tokens[1], ","); + while (tokenizer_timestamps.GetNext()) { + uint64_t timestamp; + if (sscanf(tokenizer_timestamps.token().c_str(), "%" PRId64, + ×tamp) != 1) { + LOG(ERROR) << "Failed to parse timestamp: " << event->ToString(); + return nullptr; + } + // Convert nanosecond to microseconds, as it is use in tracing. + input_timestamps.emplace_back(timestamp / 1000L); + } + + if (input_timestamps.empty()) { + LOG(ERROR) << "Timestamp is not found: " << event->ToString(); + return nullptr; + } + + int sequence_id; + if (sscanf(tokens[2].c_str(), "%" PRId32 "|0|", &sequence_id) != 1) { + LOG(ERROR) << "Sequence id is not found: " << event->ToString(); + return nullptr; + } + + return std::make_unique<AndroidInputEvent>( + event, std::move(input_timestamps), static_cast<Source>(source), + sequence_id); + } + + const ArcTracingEvent* event() const { return event_; } + std::vector<uint64_t> input_timestamps() const { return input_timestamps_; } + Source source() const { return source_; } + int sequence_id() const { return sequence_id_; } + + private: + const ArcTracingEvent* event_; + // Time of the creation of the event. Note that Wayland passes only + // milliseconds. So for events coming from Chrome, it is expected 0 for + // microsecond and nanosecond fraction. There is special case for motion + // events, when Android motion event is composed from the set of actual + // events with prediction of trajectory. In last case |input_timestamps_| + // contains all events, used for calculation of synthetic move event. + const std::vector<uint64_t> input_timestamps_; + + const Source source_; + const int sequence_id_; + + DISALLOW_COPY_AND_ASSIGN(AndroidInputEvent); +}; + +// Maps Android sources to possible input types from Chrome. +struct InputEventMapper { + InputEventMapper() { + source_to_type[AndroidInputEvent::Source::Keyboard] = { + ui::EventType::ET_KEY_PRESSED, ui::EventType::ET_KEY_RELEASED}; + source_to_type[AndroidInputEvent::Source::Touch] = { + ui::EventType::ET_TOUCH_RELEASED, ui::EventType::ET_TOUCH_PRESSED, + ui::EventType::ET_TOUCH_MOVED, ui::EventType::ET_TOUCH_CANCELLED}; + source_to_type[AndroidInputEvent::Source::Mouse] = { + ui::EventType::ET_MOUSE_PRESSED, + ui::EventType::ET_MOUSE_RELEASED, + ui::EventType::ET_MOUSE_MOVED, + }; + } + + std::map<int, std::set<ui::EventType>> source_to_type; +}; + +const InputEventMapper& GetInputEventMapper() { + static base::NoDestructor<InputEventMapper> instance; + return *instance; +} + +// Finds the corresponded Wayland input event among |exo_input_events| for the +// given |android_input_timestamp| and |source|. Return nullptr in case event +// could not be found or more than one event matches the +// |android_input_timestamp| and |source|. |exo_input_events| is sorted by input +// timestamp. +const ExoInputEvent* FindExoInputEventForAndroidEvent( + const std::vector<std::unique_ptr<ExoInputEvent>>& exo_input_events, + uint64_t android_input_timestamp, + int source) { + const InputEventMapper& mapper = GetInputEventMapper(); + const auto& allowed_set = mapper.source_to_type.find(source); + if (allowed_set == mapper.source_to_type.end()) { + LOG(ERROR) << "Input source is not recognized " << source; + return nullptr; + } + + // Wayland does not pass microsecond and nanosecond fraction. If it set, that + // means we deal with synthetic Android input event and does not have match in + // Wayland. + if (android_input_timestamp % 1000L) + return nullptr; + + const ExoInputEvent* exo_input_event = nullptr; + // Seek in the range of 1 millisecond once |android_input_timestamp| has + // millisecond resolution. + const uint64_t max_input_timestamp = android_input_timestamp + 1000L; + auto it = + std::lower_bound(exo_input_events.begin(), exo_input_events.end(), + android_input_timestamp, SortExoByInputTimestampPred); + while (it != exo_input_events.end() && + it->get()->input_timestamp() < max_input_timestamp) { + if (allowed_set->second.count(it->get()->type())) { + // Check if detected more than one exo input event. + if (exo_input_event) { + LOG(WARNING) << "More than one exo input event found for timestamp " + << android_input_timestamp; + return nullptr; + } + exo_input_event = it->get(); + } + ++it; + } + + return exo_input_event; +} + +// Finds the timestamps when input event was delivered to the target app. This +// finds the pair of asynchronous events deliverInputEvent that has the same +// sequence id and belongs to the same process as |input_event|. Returns true +// in case |out_start_delivery_timestamp| and |out_end_delivery_timestamp| are +// set. +bool GetDeliverInputEventTimestamp(const ArcTracingModel& common_model, + const AndroidInputEvent* input_event, + uint64_t* out_start_delivery_timestamp, + uint64_t* out_end_delivery_timestamp) { + const ArcTracingModel::TracingEventPtrs group_events = + common_model.GetGroupEvents( + base::StringPrintf("%d", input_event->sequence_id())); + + const ArcTracingEvent* start_event = nullptr; + const ArcTracingEvent* end_event = nullptr; + for (const ArcTracingEvent* event : group_events) { + if (event->GetName() != kDeliverInputEvent) + continue; + // Potentially events from different tasks/processes may overlap. + if (event->GetPid() != input_event->event()->GetPid()) + continue; + + switch (event->GetPhase()) { + case TRACE_EVENT_PHASE_ASYNC_BEGIN: + if (start_event) { + LOG(ERROR) << "Double start event found " << start_event->ToString(); + return false; + } + start_event = event; + break; + case TRACE_EVENT_PHASE_ASYNC_END: + if (end_event) { + LOG(ERROR) << "Double end event found " << end_event->ToString(); + return false; + } + end_event = event; + break; + } + } + + if (!start_event || !end_event) + return false; + + *out_start_delivery_timestamp = start_event->GetTimestamp(); + *out_end_delivery_timestamp = end_event->GetTimestamp(); + + if (*out_start_delivery_timestamp > *out_end_delivery_timestamp) { + LOG(ERROR) << "Start event is after end event " << start_event->ToString(); + return false; + } + + if (*out_start_delivery_timestamp > input_event->event()->GetTimestamp() || + *out_end_delivery_timestamp < input_event->event()->GetTimestamp()) { + LOG(ERROR) << "Wrong start/end timestamps for " + << input_event->event()->ToString(); + return false; + } + + return true; +} + +std::string InputTypeToString(ui::EventType type) { + switch (type) { + case ui::EventType::ET_MOUSE_PRESSED: + return "mouse pressed"; + case ui::EventType::ET_MOUSE_RELEASED: + return "mouse released"; + case ui::EventType::ET_MOUSE_MOVED: + return "mouse moved"; + case ui::EventType::ET_KEY_PRESSED: + return "key pressed"; + case ui::EventType::ET_KEY_RELEASED: + return "key released"; + case ui::EventType::ET_TOUCH_RELEASED: + return "touch released"; + case ui::EventType::ET_TOUCH_PRESSED: + return "touch pressed"; + case ui::EventType::ET_TOUCH_MOVED: + return "touch moved"; + default: + return base::StringPrintf("type: %d", type); + } +} + +std::string SourceToString(AndroidInputEvent::Source source) { + switch (source) { + case AndroidInputEvent::Source::Keyboard: + return "keyboard"; + case AndroidInputEvent::Source::Mouse: + return "mouse"; + case AndroidInputEvent::Source::Touch: + return "touch"; + default: + return base::StringPrintf("source: %d", static_cast<int>(source)); + } +} + +// Analyzes |common_model| and reconstructs input events activity. +void GetInputEvents( + const ArcTracingModel& common_model, + ArcTracingGraphicsModel::EventsContainer* out_events_container) { + // Determine route to Wayland input events. + const ArcTracingModel::TracingEventPtrs top_level_events = + common_model.Select("toplevel:"); + std::vector<const ArcTracingEvent*> route; + std::string exo_input_event_query; + for (const ArcTracingEvent* top_level_event : top_level_events) { + DetermineHierarchy(&route, top_level_event, + ArcTracingEventMatcher(kExoInputEventMatcher), + &exo_input_event_query); + } + + // Collect list of input events, seen in Wayaland and sort them based on input + // event creation time. + std::vector<std::unique_ptr<ExoInputEvent>> exo_input_events; + if (!exo_input_event_query.empty()) { + const ArcTracingModel::TracingEventPtrs input_events = + common_model.Select(exo_input_event_query); + for (const ArcTracingEvent* input_event : input_events) { + std::unique_ptr<ExoInputEvent> exo_input_event = + ExoInputEvent::Create(input_event); + if (exo_input_event) + exo_input_events.emplace_back(std::move(exo_input_event)); + } + } + + std::sort(exo_input_events.begin(), exo_input_events.end(), + [](const auto& lhs, const auto& rhs) { + if (lhs->input_timestamp() != rhs->input_timestamp()) + return lhs->input_timestamp() < rhs->input_timestamp(); + return lhs->event()->GetTimestamp() < + rhs->event()->GetTimestamp(); + }); + + // Extracts Android input events that can appear as root events or under the + // |kInputQuery| hierarchy. + std::vector<std::unique_ptr<AndroidInputEvent>> android_input_events; + ArcTracingModel::TracingEventPtrs android_input_event_candidates = + common_model.GetRoots(); + const ArcTracingModel::TracingEventPtrs inputs = + common_model.Select(kInputQuery); + android_input_event_candidates.insert(android_input_event_candidates.end(), + inputs.begin(), inputs.end()); + for (const ArcTracingEvent* root : android_input_event_candidates) { + // It is logged as counter. + if (root->GetPhase() != TRACE_EVENT_PHASE_COUNTER) + continue; + + std::unique_ptr<AndroidInputEvent> android_input_event = + AndroidInputEvent::Create(root); + if (android_input_event) + android_input_events.emplace_back(std::move(android_input_event)); + } + + std::sort(android_input_events.begin(), android_input_events.end(), + [](const auto& lhs, const auto& rhs) { + if (lhs->input_timestamps()[0] != rhs->input_timestamps()[0]) + return lhs->input_timestamps()[0] < rhs->input_timestamps()[0]; + return lhs->event()->GetTimestamp() < + rhs->event()->GetTimestamp(); + }); + + // Group of events per each input. + std::vector<BufferEvents> events_group; + for (const auto& android_input_event : android_input_events) { + uint64_t start_delivery_timestamp; + uint64_t end_delivery_timestamp; + if (!GetDeliverInputEventTimestamp(common_model, android_input_event.get(), + &start_delivery_timestamp, + &end_delivery_timestamp)) { + LOG(ERROR) << "Deliver input event is not found for " + << android_input_event->event()->ToString(); + continue; + } + + BufferEvents input_events; + input_events.emplace_back(BufferEventType::kInputEventDeliverStart, + start_delivery_timestamp); + input_events.emplace_back(BufferEventType::kInputEventDeliverEnd, + end_delivery_timestamp); + // In case of synthetic move event, last timestamp is generated timestamp, + // discard it. + constexpr size_t one = 1; + const size_t timestamp_count = + std::max(one, android_input_event->input_timestamps().size() - 1); + for (size_t i = 0; i < timestamp_count; ++i) { + const uint64_t input_timestamp = + android_input_event->input_timestamps()[i]; + const ExoInputEvent* exo_input_event = FindExoInputEventForAndroidEvent( + exo_input_events, input_timestamp, android_input_event->source()); + if (exo_input_event) { + const uint64_t dispatch_timestamp = + exo_input_event->event()->GetTimestamp(); + // crbug.com/968324, input timestamp might be set in the future, in this + // case use dispatch_timestamp as creation timestamp. + const uint64_t creation_timestamp = exo_input_event->input_timestamp(); + if (creation_timestamp <= dispatch_timestamp) { + input_events.emplace_back(BufferEventType::kInputEventCreated, + creation_timestamp, + InputTypeToString(exo_input_event->type())); + } else { + // Sort by type. + input_events.emplace_back( + BufferEventType::kInputEventCreated, dispatch_timestamp, + InputTypeToString(exo_input_event->type()) + " - estimated"); + } + + input_events.emplace_back(BufferEventType::kInputEventWaylandDispatched, + dispatch_timestamp); + } else { + // Could not map Wayland event. Let use best we can, which precision + // rounded down to millisecond. + // crbug.com/968324, input timestamp might be set in the future, in this + // case, clamp to |start_delivery_timestamp|. + if (input_timestamp <= start_delivery_timestamp) { + input_events.emplace_back( + BufferEventType::kInputEventCreated, input_timestamp, + SourceToString(android_input_event->source())); + } else { + input_events.emplace_back( + BufferEventType::kInputEventCreated, start_delivery_timestamp, + SourceToString(android_input_event->source()) + " - estimated"); + } + } + } + SortBufferEventsByTimestamp(&input_events); + DCHECK_EQ(BufferEventType::kInputEventCreated, input_events.begin()->type); + DCHECK_EQ(BufferEventType::kInputEventDeliverEnd, + input_events.rbegin()->type); + + // Try to put series of events to the default first bar. However, in case + // series of events overlap, use another bar to keep them separated. + size_t target_buffer = 0; + for (target_buffer = 0; + target_buffer < out_events_container->buffer_events().size(); + ++target_buffer) { + if (out_events_container->buffer_events()[target_buffer] + .rbegin() + ->timestamp < input_events.begin()->timestamp) { + break; + } + } + if (target_buffer == out_events_container->buffer_events().size()) + out_events_container->buffer_events().emplace_back(BufferEvents()); + + out_events_container->buffer_events()[target_buffer].insert( + out_events_container->buffer_events()[target_buffer].end(), + input_events.begin(), input_events.end()); + } +} + // Processes exo events Surface::Attach and Buffer::ReleaseContents. Each event // has argument buffer_id that identifies graphics buffer on Chrome side. // buffer_id is just row pointer to internal class. If |buffer_id_to_task_id| is @@ -424,32 +946,6 @@ } } -std::string RouteToSelector(const std::vector<const ArcTracingEvent*>& route) { - std::string result; - for (const ArcTracingEvent* segment : route) - result = result + "/" + segment->GetCategory() + ":" + segment->GetName(); - return result; -} - -void DetermineHierarchy(std::vector<const ArcTracingEvent*>* route, - const ArcTracingEvent* event, - const ArcTracingEventMatcher& matcher, - std::string* out_query) { - if (!out_query->empty()) - return; - - route->emplace_back(event); - - if (matcher.Match(*event)) { - *out_query = RouteToSelector(*route); - } else { - for (const auto& child : event->children()) - DetermineHierarchy(route, child.get(), matcher, out_query); - } - - route->pop_back(); -} - BufferToEvents GetChromeEvents( const ArcTracingModel& common_model, std::map<std::string, int>* buffer_id_to_task_id) { @@ -846,12 +1342,8 @@ event_value.GetList().push_back(base::Value(static_cast<int>(event.type))); event_value.GetList().push_back( base::Value(static_cast<double>(event.timestamp))); - if (event.type == BufferEventType::kCustomEvent) { - DCHECK(!event.content.empty()); + if (!event.content.empty()) event_value.GetList().push_back(base::Value(event.content)); - } else { - DCHECK(event.content.empty()); - } list.GetList().emplace_back(std::move(event_value)); } return list; @@ -907,7 +1399,9 @@ !IsInRange(type, BufferEventType::kChromeOSDraw, BufferEventType::kChromeOSJank) && !IsInRange(type, BufferEventType::kCustomEvent, - BufferEventType::kCustomEvent)) { + BufferEventType::kCustomEvent) && + !IsInRange(type, BufferEventType::kInputEventCreated, + BufferEventType::kInputEventDeliverEnd)) { return false; } @@ -916,13 +1410,11 @@ const int64_t timestamp = entry.GetList()[1].GetDouble(); if (timestamp < previous_timestamp) return false; - if (type == BufferEventType::kCustomEvent) { - if (entry.GetList().size() != 3 || !entry.GetList()[2].is_string()) + if (entry.GetList().size() == 3) { + if (!entry.GetList()[2].is_string()) return false; out_events->emplace_back(type, timestamp, entry.GetList()[2].GetString()); } else { - if (entry.GetList().size() != 2) - return false; out_events->emplace_back(type, timestamp); } previous_timestamp = timestamp; @@ -1002,8 +1494,10 @@ ArcTracingGraphicsModel::EventsContainer* container, int64_t trim_timestamp, const std::set<ArcTracingGraphicsModel::BufferEventType>& start_types) { + // For trim point use |ArcTracingGraphicsModel::BufferEventType::kNone| that + // is less than any other event type. const ArcTracingGraphicsModel::BufferEvent trim_point( - ArcTracingGraphicsModel::BufferEventType::kCustomEvent, trim_timestamp); + ArcTracingGraphicsModel::BufferEventType::kNone, trim_timestamp); // Global events are trimmed by timestamp only. auto global_cut_pos = std::lower_bound(container->global_events().begin(), @@ -1031,7 +1525,8 @@ BufferToEvents per_buffer_surface_flinger_events; if (!GetSurfaceFlingerEvents(common_model, &per_buffer_surface_flinger_events)) { - return false; + if (!skip_structure_validation_for_testing_) + return false; } BufferToEvents per_buffer_chrome_events = GetChromeEvents(common_model, &chrome_buffer_id_to_task_id_); @@ -1091,7 +1586,8 @@ if (view_buffers_.empty()) { LOG(ERROR) << "No buffer events"; - return false; + if (!skip_structure_validation_for_testing_) + return false; } // TODO(khmel): Add more information to resolve owner of custom events. At @@ -1112,15 +1608,19 @@ GetChromeTopLevelEvents(common_model, &chrome_top_level_); if (chrome_top_level_.buffer_events().empty()) { LOG(ERROR) << "No Chrome top events"; - return false; + if (!skip_structure_validation_for_testing_) + return false; } GetAndroidTopEvents(common_model, &android_top_level_); if (android_top_level_.buffer_events().empty()) { LOG(ERROR) << "No Android events"; - return false; + if (!skip_structure_validation_for_testing_) + return false; } + GetInputEvents(common_model, &input_); + system_model_.CopyFrom(common_model.system_model()); VsyncTrim(); @@ -1138,13 +1638,13 @@ all_buffers.emplace_back(&view.second.global_events()); } - for (auto& buffer : android_top_level_.buffer_events()) - all_buffers.emplace_back(&buffer); - all_buffers.emplace_back(&android_top_level_.global_events()); - - for (auto& buffer : chrome_top_level_.buffer_events()) - all_buffers.emplace_back(&buffer); - all_buffers.emplace_back(&chrome_top_level_.global_events()); + std::vector<EventsContainer*> containers{&android_top_level_, + &chrome_top_level_, &input_}; + for (EventsContainer* container : containers) { + for (auto& buffer : container->buffer_events()) + all_buffers.emplace_back(&buffer); + all_buffers.emplace_back(&container->global_events()); + } uint64_t min = std::numeric_limits<uint64_t>::max(); uint64_t max = std::numeric_limits<uint64_t>::min(); @@ -1186,6 +1686,7 @@ void ArcTracingGraphicsModel::Reset() { chrome_top_level_.Reset(); android_top_level_.Reset(); + input_.Reset(); view_buffers_.clear(); chrome_buffer_id_to_task_id_.clear(); system_model_.Reset(); @@ -1212,6 +1713,8 @@ TrimEventsContainer(&android_top_level_, trim_timestamp, {BufferEventType::kSurfaceFlingerInvalidationStart, BufferEventType::kSurfaceFlingerCompositionStart}); + TrimEventsContainer(&input_, trim_timestamp, + {BufferEventType::kInputEventCreated}); for (auto& view_buffer : view_buffers_) { TrimEventsContainer(&view_buffer.second, trim_timestamp, {BufferEventType::kBufferQueueDequeueStart, @@ -1250,6 +1753,9 @@ // Chrome top events root->SetKey(kKeyChrome, SerializeEventsContainer(chrome_top_level_)); + // Input events + root->SetKey(kKeyInput, SerializeEventsContainer(input_)); + // System. root->SetKey(kKeySystem, system_model_.Serialize()); @@ -1310,6 +1816,10 @@ if (!LoadEventsContainer(root.FindKey(kKeyChrome), &chrome_top_level_)) return false; + const base::Value* input_value = root.FindKey(kKeyInput); + if (input_value && !LoadEventsContainer(input_value, &input_)) + return false; + if (!system_model_.Load(root.FindKey(kKeySystem))) return false;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h index 4b166e1..0f9432b 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
@@ -81,6 +81,12 @@ // Custom event. kCustomEvent = 600, + + // Input events + kInputEventCreated = 700, // 700 + kInputEventWaylandDispatched, // 701 + kInputEventDeliverStart, // 702 + kInputEventDeliverEnd, // 703 }; struct BufferEvent { @@ -170,9 +176,15 @@ const EventsContainer& chrome_top_level() const { return chrome_top_level_; } + const EventsContainer& input() const { return input_; } + ArcSystemModel& system_model() { return system_model_; } const ArcSystemModel& system_model() const { return system_model_; } + void set_skip_structure_validation_for_testing() { + skip_structure_validation_for_testing_ = true; + } + private: // Normalizes timestamp for all events by subtracting the timestamp of the // earliest event. @@ -194,12 +206,15 @@ // To avoid overlapping events are stored interlaced. EventsContainer chrome_top_level_; EventsContainer android_top_level_; + EventsContainer input_; // Total duration of this model. uint32_t duration_ = 0; // Map Chrome buffer id to task id. std::map<std::string, int> chrome_buffer_id_to_task_id_; // CPU event model. ArcSystemModel system_model_; + // Allows to have model incomplete for testing. + bool skip_structure_validation_for_testing_ = false; DISALLOW_COPY_AND_ASSIGN(ArcTracingGraphicsModel); };
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc index 4b6d57c7..f60b731 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
@@ -602,4 +602,63 @@ EXPECT_EQ(1400000UL, group2[1]->GetTimestamp()); } +TEST_F(ArcTracingModelTest, InputEvents) { + base::FilePath base_path; + base::PathService::Get(chrome::DIR_TEST_DATA, &base_path); + const base::FilePath tracing_path = + base_path.Append("arc_graphics_tracing").Append("trace_input.dat.gz"); + + std::string tracing_data_compressed; + ASSERT_TRUE(base::ReadFileToString(tracing_path, &tracing_data_compressed)); + + std::string tracing_data; + ASSERT_TRUE( + compression::GzipUncompress(tracing_data_compressed, &tracing_data)); + + ArcTracingModel model; + ASSERT_TRUE(model.Build(tracing_data)); + + ArcTracingGraphicsModel graphics_model; + graphics_model.set_skip_structure_validation_for_testing(); + ASSERT_TRUE(graphics_model.Build(model)); + + const std::vector<GraphicsEvents>& buffers = + graphics_model.input().buffer_events(); + ASSERT_TRUE(buffers.size()); + + for (const GraphicsEvents& buffer : buffers) { + ASSERT_FALSE(buffer.empty()); + + uint64_t last_timestamp = buffer[0].timestamp; + GraphicsEventType last_type = buffer[0].type; + EXPECT_EQ(GraphicsEventType::kInputEventCreated, last_type); + for (size_t i = 1; i < buffer.size(); ++i) { + const uint64_t timestamp = buffer[i].timestamp; + const GraphicsEventType type = buffer[i].type; + EXPECT_GE(timestamp, last_timestamp); + // One input sequence may contain multiple input events. + switch (last_type) { + case GraphicsEventType::kInputEventCreated: + case GraphicsEventType::kInputEventWaylandDispatched: + EXPECT_TRUE(type == GraphicsEventType::kInputEventCreated || + type == GraphicsEventType::kInputEventWaylandDispatched || + type == GraphicsEventType::kInputEventDeliverStart); + break; + case GraphicsEventType::kInputEventDeliverStart: + EXPECT_EQ(GraphicsEventType::kInputEventDeliverEnd, type); + break; + case GraphicsEventType::kInputEventDeliverEnd: + EXPECT_EQ(GraphicsEventType::kInputEventCreated, type); + break; + default: + NOTREACHED(); + } + + last_timestamp = timestamp; + last_type = type; + } + EXPECT_EQ(GraphicsEventType::kInputEventDeliverEnd, last_type); + } +} + } // namespace arc
diff --git a/chrome/browser/chromeos/assistant/assistant_util.cc b/chrome/browser/chromeos/assistant/assistant_util.cc index a2b14e1..6a5e9ee7 100644 --- a/chrome/browser/chromeos/assistant/assistant_util.cc +++ b/chrome/browser/chromeos/assistant/assistant_util.cc
@@ -42,10 +42,9 @@ if (user_manager::UserManager::Get()->IsLoggedInAsPublicAccount()) return ash::mojom::AssistantAllowedState::DISALLOWED_BY_PUBLIC_SESSION; - // TODO(wutao): Add a new type DISALLOWED_BY_KIOSK_MODE. if (user_manager::UserManager::Get()->IsLoggedInAsKioskApp() || user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp()) { - return ash::mojom::AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE; + return ash::mojom::AssistantAllowedState::DISALLOWED_BY_KIOSK_MODE; } // String literals used in some cases in the array because their
diff --git a/chrome/browser/chromeos/assistant/assistant_util_unittest.cc b/chrome/browser/chromeos/assistant/assistant_util_unittest.cc index 6e04e99..89f9a2e 100644 --- a/chrome/browser/chromeos/assistant/assistant_util_unittest.cc +++ b/chrome/browser/chromeos/assistant/assistant_util_unittest.cc
@@ -259,7 +259,7 @@ AccountId::FromUserEmail(profile()->GetProfileUserName()), user_manager::USER_TYPE_KIOSK_APP); - EXPECT_EQ(ash::mojom::AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE, + EXPECT_EQ(ash::mojom::AssistantAllowedState::DISALLOWED_BY_KIOSK_MODE, IsAssistantAllowedForProfile(profile())); } @@ -268,7 +268,7 @@ AccountId::FromUserEmail(profile()->GetProfileUserName()), user_manager::USER_TYPE_ARC_KIOSK_APP); - EXPECT_EQ(ash::mojom::AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE, + EXPECT_EQ(ash::mojom::AssistantAllowedState::DISALLOWED_BY_KIOSK_MODE, IsAssistantAllowedForProfile(profile())); }
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.cc b/chrome/browser/chromeos/drive/drive_integration_service.cc index 12f0676f..76d81c8 100644 --- a/chrome/browser/chromeos/drive/drive_integration_service.cc +++ b/chrome/browser/chromeos/drive/drive_integration_service.cc
@@ -659,6 +659,7 @@ std::move(test_drivefs_mojo_listener_factory)) : nullptr), preference_watcher_(preference_watcher), + power_manager_observer_(this), weak_ptr_factory_(this) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(profile && !profile->IsOffTheRecord()); @@ -684,6 +685,10 @@ if (migrated_to_drivefs) { state_ = INITIALIZED; } + // PowerManagerClient is unset in unit tests. + if (chromeos::PowerManagerClient::Get()) { + power_manager_observer_.Add(chromeos::PowerManagerClient::Get()); + } SetEnabled(drive::util::IsDriveEnabledForProfile(profile)); return; } @@ -1269,6 +1274,21 @@ profile_->GetPrefs()->SetBoolean(prefs::kDriveFsPinnedMigrated, true); } +void DriveIntegrationService::SuspendImminent( + power_manager::SuspendImminent::Reason reason) { + // This may a bit racy since it doesn't prevent suspend until the unmount is + // completed, instead relying on something else to defer suspending long + // enough. + RemoveDriveMountPoint(); +} + +void DriveIntegrationService::SuspendDone( + const base::TimeDelta& sleep_duration) { + if (is_enabled()) { + AddDriveMountPoint(); + } +} + //===================== DriveIntegrationServiceFactory ======================= DriveIntegrationServiceFactory::FactoryCallback*
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.h b/chrome/browser/chromeos/drive/drive_integration_service.h index f27540af..54d1971 100644 --- a/chrome/browser/chromeos/drive/drive_integration_service.h +++ b/chrome/browser/chromeos/drive/drive_integration_service.h
@@ -15,7 +15,9 @@ #include "base/memory/singleton.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/scoped_observer.h" #include "chromeos/components/drivefs/drivefs_host.h" +#include "chromeos/dbus/power/power_manager_client.h" #include "components/drive/drive_notification_observer.h" #include "components/drive/file_errors.h" #include "components/drive/file_system_core_util.h" @@ -98,7 +100,8 @@ class DriveIntegrationService : public KeyedService, public DriveNotificationObserver, public content::NotificationObserver, - public drivefs::DriveFsHost::MountObserver { + public drivefs::DriveFsHost::MountObserver, + public chromeos::PowerManagerClient::Observer { public: class PreferenceWatcher; using DriveFsMojoListenerFactory = base::RepeatingCallback< @@ -247,6 +250,10 @@ // Pin all the files in |files_to_pin| with DriveFS. void PinFiles(const std::vector<base::FilePath>& files_to_pin); + // chromeos::PowerManagerClient::Observer overrides: + void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; + void SuspendDone(const base::TimeDelta& sleep_duration) override; + friend class DriveIntegrationServiceFactory; Profile* profile_; @@ -283,6 +290,9 @@ base::TimeTicks mount_start_; + ScopedObserver<chromeos::PowerManagerClient, DriveIntegrationService> + power_manager_observer_; + // 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<DriveIntegrationService> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/login/oobe_browsertest.cc b/chrome/browser/chromeos/login/oobe_browsertest.cc index c0947e8..7452adda 100644 --- a/chrome/browser/chromeos/login/oobe_browsertest.cc +++ b/chrome/browser/chromeos/login/oobe_browsertest.cc
@@ -20,6 +20,10 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/constants/chromeos_switches.h" +#include "components/account_id/account_id.h" +#include "components/user_manager/known_user.h" +#include "components/user_manager/user.h" +#include "content/public/browser/notification_details.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" #include "google_apis/gaia/gaia_switches.h" @@ -85,6 +89,12 @@ FakeGaiaMixin::kEmptyUserServices); session_start_waiter.Wait(); + + const AccountId account_id = + content::Details<const user_manager::User>(session_start_waiter.details()) + ->GetAccountId(); + EXPECT_FALSE( + user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(account_id)); } IN_PROC_BROWSER_TEST_F(OobeTest, Accelerator) {
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc index 307187b..810b400 100644 --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -85,6 +85,7 @@ #include "components/policy/policy_constants.h" #include "components/policy/proto/chrome_device_policy.pb.h" #include "components/policy/proto/device_management_backend.pb.h" +#include "components/user_manager/known_user.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_task_traits.h" @@ -536,6 +537,10 @@ SystemSaltGetter::ConvertRawSaltToHexString( FakeCryptohomeClient::GetStubSystemSalt())); EXPECT_EQ(key.GetSecret(), cryptohome_client_->salted_hashed_secret()); + + EXPECT_TRUE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( + AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail, + kFirstSAMLUserGaiaId))); } // Tests the single password scraped flow. @@ -568,6 +573,10 @@ } while (message != "\"fake_password\""); session_start_waiter.Wait(); + + EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( + AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail, + kFirstSAMLUserGaiaId))); } // Tests password scraping from a dynamically created password field. @@ -594,6 +603,10 @@ content::NotificationService::AllSources()); SigninFrameJS().TapOn("Submit"); session_start_waiter.Wait(); + + EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( + AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail, + kFirstSAMLUserGaiaId))); } // Tests the multiple password scraped flow. @@ -619,6 +632,10 @@ content::NotificationService::AllSources()); SendConfirmPassword("password1"); session_start_waiter.Wait(); + + EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( + AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail, + kFirstSAMLUserGaiaId))); } // Tests the no password scraped flow. @@ -645,6 +662,10 @@ content::NotificationService::AllSources()); SetManualPasswords("Test1", "Test1"); session_start_waiter.Wait(); + + EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( + AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail, + kFirstSAMLUserGaiaId))); } // Types |bob@corp.example.com| into the GAIA login form but then authenticates
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc index d818255..f65dce5 100644 --- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc +++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -55,6 +55,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/service_manager_connection.h" #include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/primary_account_mutator.h" #include "services/service_manager/public/cpp/connector.h" namespace chromeos { @@ -254,10 +255,10 @@ // In these contexts, emulate as if sync has been initialized. VLOG(1) << "Starting Chrome with stub login."; - // TODO(https://crbug.com/814787): Determine the right long-term flow here. std::string login_user_id = login_account_id.GetUserEmail(); - IdentityManagerFactory::GetForProfile(profile)->LegacySetPrimaryAccount( - login_user_id, login_user_id); + IdentityManagerFactory::GetForProfile(profile) + ->GetPrimaryAccountMutator() + ->SetPrimaryAccountAndUpdateAccountInfo(login_user_id, login_user_id); StartUserSession(profile, login_user_id); return; }
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 54e5e1d..53115ff7 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -157,6 +157,7 @@ #include "rlz/buildflags/buildflags.h" #include "services/identity/public/cpp/accounts_mutator.h" #include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/primary_account_mutator.h" #include "third_party/cros_system_api/switches/chrome_switches.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/chromeos/input_method_manager.h" @@ -1309,9 +1310,9 @@ // Make sure that the google service username is properly set (we do this // on every sign in, not just the first login, to deal with existing // profiles that might not have it set yet). - // TODO(https://crbug.com/814787): Determine the right long-term flow here. - identity_manager->LegacySetPrimaryAccount( - gaia_id, user_context.GetAccountId().GetUserEmail()); + identity_manager->GetPrimaryAccountMutator() + ->SetPrimaryAccountAndUpdateAccountInfo( + gaia_id, user_context.GetAccountId().GetUserEmail()); std::string account_id = identity_manager->GetPrimaryAccountId(); VLOG(1) << "Seed IdentityManager with the authenticated account info, " << "success=" << !account_id.empty(); @@ -1515,9 +1516,13 @@ user_manager::UserManager* user_manager = user_manager::UserManager::Get(); if (user_manager->IsLoggedInAsUserWithGaiaAccount()) { - if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML) + if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML) { user_manager::known_user::UpdateUsingSAML(user_context_.GetAccountId(), true); + user_manager::known_user::UpdateIsUsingSAMLPrincipalsAPI( + user_context_.GetAccountId(), + user_context_.IsUsingSamlPrincipalsApi()); + } SAMLOfflineSigninLimiter* saml_offline_signin_limiter = SAMLOfflineSigninLimiterFactory::GetForProfile(profile); if (saml_offline_signin_limiter)
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc index 472444e5..16fd46b 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
@@ -186,9 +186,9 @@ DCHECK(identity_manager->HasPrimaryAccount()); // On ChromeOS, the primary account is set via - // IdentityManager::LegacySetPrimaryAccount(), which seeds the account - // info with AccountTrackerService. Hence, the primary account info will be - // available at this point. + // PrimaryAccountMutator::SetPrimaryAccountAndUpdateAccountInfo(), which + // seeds the account info with AccountTrackerService. Hence, the primary + // account info will be available at this point. const CoreAccountInfo primary_account_info = identity_manager->GetPrimaryAccountInfo();
diff --git a/chrome/browser/chromeos/network_change_manager_client_unittest.cc b/chrome/browser/chromeos/network_change_manager_client_unittest.cc index a2576eb6..680768a 100644 --- a/chrome/browser/chromeos/network_change_manager_client_unittest.cc +++ b/chrome/browser/chromeos/network_change_manager_client_unittest.cc
@@ -113,7 +113,7 @@ content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<net::NetworkChangeNotifierPosix> network_change_notifier( static_cast<net::NetworkChangeNotifierPosix*>( - net::NetworkChangeNotifier::Create())); + net::NetworkChangeNotifier::Create().release())); network_change_notifier->OnConnectionChanged( net::NetworkChangeNotifier::CONNECTION_UNKNOWN); EXPECT_EQ(net::NetworkChangeNotifier::CONNECTION_UNKNOWN, @@ -150,7 +150,7 @@ ~NetworkChangeManagerClientUpdateTest() override = default; void SetUp() override { - network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); + network_change_notifier_ = net::NetworkChangeNotifier::Create(); DBusThreadManager::Initialize(); PowerManagerClient::InitializeFake(); NetworkHandler::Initialize();
diff --git a/chrome/browser/chromeos/ui/request_pin_view.cc b/chrome/browser/chromeos/ui/request_pin_view.cc index 2a8d5b4..88feacc 100644 --- a/chrome/browser/chromeos/ui/request_pin_view.cc +++ b/chrome/browser/chromeos/ui/request_pin_view.cc
@@ -197,9 +197,9 @@ // Infomation label. int label_text_id = IDS_REQUEST_PIN_DIALOG_HEADER; base::string16 label_text = l10n_util::GetStringUTF16(label_text_id); - header_label_ = new views::Label(label_text); - header_label_->SetEnabled(true); - layout->AddView(header_label_); + auto header_label = std::make_unique<views::Label>(label_text); + header_label->SetEnabled(true); + header_label_ = layout->AddView(std::move(header_label)); const int related_vertical_spacing = provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL); @@ -212,12 +212,13 @@ // Textfield to enter the PIN/PUK. layout->StartRow(0, column_view_set_id); - textfield_ = new PassphraseTextfield(); - textfield_->set_controller(this); - textfield_->SetEnabled(true); - textfield_->SetAssociatedLabel(header_label_); - layout->AddView(textfield_, 1, 1, views::GridLayout::LEADING, - views::GridLayout::FILL, kDefaultTextWidth, 0); + auto textfield = std::make_unique<PassphraseTextfield>(); + textfield->set_controller(this); + textfield->SetEnabled(true); + textfield->SetAssociatedLabel(header_label_); + textfield_ = + layout->AddView(std::move(textfield), 1, 1, views::GridLayout::LEADING, + views::GridLayout::FILL, kDefaultTextWidth, 0); layout->AddPaddingRow(0, related_vertical_spacing); @@ -228,10 +229,10 @@ // Error label. layout->StartRow(0, column_view_set_id); - error_label_ = new views::Label(); - error_label_->SetVisible(false); - error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); - layout->AddView(error_label_); + auto error_label = std::make_unique<views::Label>(); + error_label->SetVisible(false); + error_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + error_label_ = layout->AddView(std::move(error_label)); } void RequestPinView::SetAcceptInput(bool accept_input) {
diff --git a/chrome/browser/devtools/protocol/browser_handler.cc b/chrome/browser/devtools/protocol/browser_handler.cc index 6e81fd4..75068d39 100644 --- a/chrome/browser/devtools/protocol/browser_handler.cc +++ b/chrome/browser/devtools/protocol/browser_handler.cc
@@ -100,6 +100,10 @@ *out_type = content::PermissionType::PAYMENT_HANDLER; } else if (type == protocol::Browser::PermissionTypeEnum::BackgroundFetch) { *out_type = content::PermissionType::BACKGROUND_FETCH; + } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockScreen) { + *out_type = content::PermissionType::WAKE_LOCK_SCREEN; + } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockSystem) { + *out_type = content::PermissionType::WAKE_LOCK_SYSTEM; } else { return Response::InvalidParams("Unknown permission type: " + type); }
diff --git a/chrome/browser/download/download_offline_content_provider.cc b/chrome/browser/download/download_offline_content_provider.cc index f56a6b4..2b97166 100644 --- a/chrome/browser/download/download_offline_content_provider.cc +++ b/chrome/browser/download/download_offline_content_provider.cc
@@ -81,6 +81,7 @@ void DownloadOfflineContentProvider::SetSimpleDownloadManagerCoordinator( SimpleDownloadManagerCoordinator* manager) { DCHECK(manager); + DCHECK(!manager_); manager_ = manager; manager_->AddObserver(this); } @@ -206,13 +207,8 @@ } download::DownloadItem::RenameDownloadCallback download_callback = base::BindOnce( - [](RenameCallback callback, - download::DownloadItem::DownloadRenameResult result) { - std::move(callback).Run( - OfflineItemUtils::ConvertDownloadRenameResultToRenameResult( - result)); - }, - std::move(callback)); + &DownloadOfflineContentProvider::OnRenameDownloadCallbackDone, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), item); base::FilePath::StringType filename; #if defined(OS_WIN) filename = base::UTF8ToWide(name); @@ -222,6 +218,22 @@ item->Rename(base::FilePath(filename), std::move(download_callback)); } +void DownloadOfflineContentProvider::OnRenameDownloadCallbackDone( + RenameCallback callback, + DownloadItem* item, + DownloadItem::DownloadRenameResult result) { + if (result == DownloadItem::DownloadRenameResult::SUCCESS) { + auto offline_item = OfflineItemUtils::CreateOfflineItem(name_space_, item); + UpdateDelta update_delta; + update_delta.state_changed = false; + update_delta.visuals_changed = false; + UpdateObservers(offline_item, update_delta); + } + + std::move(callback).Run( + OfflineItemUtils::ConvertDownloadRenameResultToRenameResult(result)); +} + void DownloadOfflineContentProvider::AddObserver( OfflineContentProvider::Observer* observer) { if (observers_.HasObserver(observer)) @@ -273,6 +285,7 @@ completed_downloads_.end(); // TODO(crbug.com/938152): May be move this to DownloadItem. + // Never call this for completed downloads from history. if (completed_downloads_.find(item->GetGuid()) != completed_downloads_.end()) { return; @@ -283,10 +296,8 @@ AddCompletedDownload(item); } - for (auto& observer : observers_) { - observer.OnItemUpdated( - OfflineItemUtils::CreateOfflineItem(name_space_, item), update_delta); - } + auto offline_item = OfflineItemUtils::CreateOfflineItem(name_space_, item); + UpdateObservers(offline_item, update_delta); } void DownloadOfflineContentProvider::OnDownloadRemoved(DownloadItem* item) { @@ -334,3 +345,9 @@ manager_->GetAllDownloads(all_items); } +void DownloadOfflineContentProvider::UpdateObservers( + const OfflineItem& item, + const base::Optional<UpdateDelta>& update_delta) { + for (auto& observer : observers_) + observer.OnItemUpdated(item, update_delta); +}
diff --git a/chrome/browser/download/download_offline_content_provider.h b/chrome/browser/download/download_offline_content_provider.h index 07099849..cc8af56 100644 --- a/chrome/browser/download/download_offline_content_provider.h +++ b/chrome/browser/download/download_offline_content_provider.h
@@ -23,6 +23,7 @@ using OfflineContentProvider = offline_items_collection::OfflineContentProvider; using OfflineContentAggregator = offline_items_collection::OfflineContentAggregator; +using UpdateDelta = offline_items_collection::UpdateDelta; using LaunchLocation = offline_items_collection::LaunchLocation; class SkBitmap; @@ -89,11 +90,18 @@ void AddCompletedDownloadDone(DownloadItem* item, int64_t system_download_id, bool can_resolve); + void OnRenameDownloadCallbackDone(RenameCallback callback, + DownloadItem* item, + DownloadItem::DownloadRenameResult result); + void UpdateObservers(const OfflineItem& item, + const base::Optional<UpdateDelta>& update_delta); base::ObserverList<OfflineContentProvider::Observer>::Unchecked observers_; OfflineContentAggregator* aggregator_; std::string name_space_; SimpleDownloadManagerCoordinator* manager_; + + // Tracks the completed downloads in the current session. std::set<std::string> completed_downloads_; base::WeakPtrFactory<DownloadOfflineContentProvider> weak_ptr_factory_;
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 3e251325..017ef4d 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc
@@ -9,7 +9,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "chrome/browser/banners/app_banner_manager_desktop.h" #include "chrome/browser/extensions/activity_log/activity_log.h" #include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h" #include "chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.h" @@ -61,7 +60,6 @@ #include "extensions/common/manifest_handlers/icons_handler.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" -#include "third_party/blink/public/common/manifest/web_display_mode.h" #include "url/url_constants.h" using content::NavigationController; @@ -192,18 +190,10 @@ void TabHelper::FinishCreateBookmarkApp( const Extension* extension, const WebApplicationInfo& web_app_info) { - const bool success = (extension != nullptr); - - if (success && web_app_info.open_as_window) { - // Send the 'appinstalled' event and ensure any beforeinstallpromptevent - // cannot trigger installation again. - banners::AppBannerManagerDesktop::FromWebContents(web_contents()) - ->OnInstall(false /* is_native app */, - blink::kWebDisplayModeStandalone); - } pending_web_app_action_ = NONE; const ExtensionId app_id = extension ? extension->id() : ExtensionId(); + const bool success = (extension != nullptr); std::move(install_callback_).Run(app_id, success); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index d41e853..226ebfa 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1033,11 +1033,6 @@ "expiry_milestone": 80 }, { - "name": "enable-drive-fs", - "owners": [ "sammc", "dats" ], - "expiry_milestone": 76 - }, - { "name": "enable-encryption-migration", "owners": [ "fukino" ], "expiry_milestone": 76 @@ -2640,11 +2635,6 @@ "expiry_milestone": 83 }, { - "name": "pwa-persistent-notification", - "owners": [ "desktop-pwas-team@google.com" ], - "expiry_milestone": 76 - }, - { "name": "reader-mode-heuristics", "owners": [ "mdjones" ], "expiry_milestone": 78
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 4e07df4..34decc3 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2413,11 +2413,6 @@ const char kProgressBarThrottleDescription[] = "Limit the maximum progress update to make progress appear smoother."; -const char kPwaPersistentNotificationName[] = - "Persistent notification in standalone PWA"; -const char kPwaPersistentNotificationDescription[] = - "Enables a persistent Android notification for standalone PWAs"; - const char kReaderModeHeuristicsName[] = "Reader Mode triggering"; const char kReaderModeHeuristicsDescription[] = "Determines what pages the Reader Mode infobar is shown on."; @@ -3031,10 +3026,6 @@ const char kEnableDiscoverAppDescription[] = "Enable Discover App icon in launcher."; -const char kEnableDriveFsName[] = "Enable DriveFS"; -const char kEnableDriveFsDescription[] = - "Enables use of the new DriveFS-based Drive sync client."; - const char kEnableEncryptionMigrationName[] = "Enable encryption migration of user data"; const char kEnableEncryptionMigrationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index f28e225..69ef78d 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1427,9 +1427,6 @@ extern const char kProgressBarThrottleName[]; extern const char kProgressBarThrottleDescription[]; -extern const char kPwaPersistentNotificationName[]; -extern const char kPwaPersistentNotificationDescription[]; - extern const char kReaderModeHeuristicsName[]; extern const char kReaderModeHeuristicsDescription[]; extern const char kReaderModeHeuristicsMarkup[]; @@ -1812,9 +1809,6 @@ extern const char kEnableDiscoverAppName[]; extern const char kEnableDiscoverAppDescription[]; -extern const char kEnableDriveFsName[]; -extern const char kEnableDriveFsDescription[]; - extern const char kEnableEncryptionMigrationName[]; extern const char kEnableEncryptionMigrationDescription[];
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc index 9b577b5..90565a7 100644 --- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc +++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
@@ -22,6 +22,7 @@ #include "components/guest_view/browser/guest_view_manager.h" #include "components/guest_view/browser/guest_view_manager_delegate.h" #include "components/guest_view/browser/test_guest_view_manager.h" +#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -31,6 +32,7 @@ #include "content/public/test/browser_test_utils.h" #include "content/public/test/find_test_utils.h" #include "content/public/test/hit_test_region_observer.h" +#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_renderer_host.h" #include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_stream_manager.h" @@ -642,6 +644,49 @@ "PDF.LoadStatus", PDFLoadStatus::kLoadedEmbeddedPdfWithPdfium, 1); } +namespace { + +// A DevToolsAgentHostClient implementation doing nothing. +class StubDevToolsAgentHostClient : public content::DevToolsAgentHostClient { + public: + StubDevToolsAgentHostClient() {} + ~StubDevToolsAgentHostClient() override {} + void AgentHostClosed(content::DevToolsAgentHost* agent_host) override {} + void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, + const std::string& message) override {} +}; + +} // namespace + +IN_PROC_BROWSER_TEST_P(ChromeMimeHandlerViewCrossProcessTest, + GuestDevToolsReloadsEmbedder) { + GURL data_url("data:application/pdf,foo"); + ui_test_utils::NavigateToURL(browser(), data_url); + auto* embedder_web_contents = + browser()->tab_strip_model()->GetWebContentsAt(0); + auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated(); + EXPECT_NE(embedder_web_contents, guest_web_contents); + while (guest_web_contents->IsLoading()) { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); + run_loop.Run(); + } + + // Load DevTools. + scoped_refptr<content::DevToolsAgentHost> devtools_agent_host = + content::DevToolsAgentHost::GetOrCreateFor(guest_web_contents); + StubDevToolsAgentHostClient devtools_agent_host_client; + devtools_agent_host->AttachClient(&devtools_agent_host_client); + + // Reload via guest's DevTools, embedder should reload. + content::TestNavigationObserver reload_observer(embedder_web_contents); + devtools_agent_host->DispatchProtocolMessage( + &devtools_agent_host_client, R"({"id":1,"method": "Page.reload"})"); + reload_observer.Wait(); + devtools_agent_host->DetachClient(&devtools_agent_host_client); +} + INSTANTIATE_TEST_SUITE_P(, ChromeMimeHandlerViewCrossProcessTest, testing::Bool());
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc b/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc index e04a943..0de4fe5f 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc
@@ -12,7 +12,9 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" +#include "net/base/features.h" #include "net/cert/trial_comparison_cert_verifier.h" +#include "net/net_buildflags.h" #include "net/test/embedded_test_server/embedded_test_server.h" class TrialComparisonCertVerifierTest : public InProcessBrowserTest { @@ -81,8 +83,65 @@ https_test_server_.GetURL("/title1.html")); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1); +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) + if (base::FeatureList::IsEnabled( + net::features::kCertVerifierBuiltinFeature)) { + // If both the dual cert verifier trial feature and the builtin verifier + // feature are enabled, the dual cert verifier trial should not be used. + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 0); + histograms.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0); + return; + } +#endif histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1); histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", 1); histograms.ExpectUniqueSample("Net.CertVerifier_TrialComparisonResult", net::TrialComparisonCertVerifier::kEqual, 1); } + +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) +class TrialComparisonCertVerifierFeatureOverridenByBuiltinVerifierTest + : public TrialComparisonCertVerifierTest { + public: + TrialComparisonCertVerifierFeatureOverridenByBuiltinVerifierTest() { + TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(true); + scoped_feature_ = std::make_unique<base::test::ScopedFeatureList>(); + scoped_feature_->InitWithFeaturesAndParameters( + // None of these tests should generate a report, but set the trial to + // uma_only mode anyway just to be safe. + {{features::kCertDualVerificationTrialFeature, {{"uma_only", "true"}}}, + // Enable the builtin verifier. + {net::features::kCertVerifierBuiltinFeature, {}}}, + {}); + } + + ~TrialComparisonCertVerifierFeatureOverridenByBuiltinVerifierTest() override { + TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting( + false); + } + + protected: + std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_; +}; + +IN_PROC_BROWSER_TEST_F( + TrialComparisonCertVerifierFeatureOverridenByBuiltinVerifierTest, + TrialEnabledPrefEnabledBuiltVerifierEnabled) { + safe_browsing::SetExtendedReportingPref(browser()->profile()->GetPrefs(), + true); + + ASSERT_TRUE(https_test_server_.Start()); + base::HistogramTester histograms; + ui_test_utils::NavigateToURL(browser(), + https_test_server_.GetURL("/title1.html")); + SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1); + // If both the dual cert verifier trial feature and the builtin verifier + // feature are enabled, the dual cert verifier trial should not be used. + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", 0); + histograms.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0); +} +#endif
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_controller.cc b/chrome/browser/net/trial_comparison_cert_verifier_controller.cc index a203a05..e01a2bf 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_controller.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_controller.cc
@@ -23,6 +23,8 @@ #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "net/base/features.h" +#include "net/net_buildflags.h" namespace { @@ -58,6 +60,14 @@ #if defined(OFFICIAL_BUILD) && defined(GOOGLE_CHROME_BUILD) is_official_build = true; #endif + +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) + // If the builtin verifier is enabled as the default verifier, the trial does + // not make sense. + if (base::FeatureList::IsEnabled(net::features::kCertVerifierBuiltinFeature)) + return false; +#endif + return is_official_build && base::FeatureList::IsEnabled( features::kCertDualVerificationTrialFeature) &&
diff --git a/chrome/browser/no_best_effort_tasks_browsertest.cc b/chrome/browser/no_best_effort_tasks_browsertest.cc index 27936974..a500d2b 100644 --- a/chrome/browser/no_best_effort_tasks_browsertest.cc +++ b/chrome/browser/no_best_effort_tasks_browsertest.cc
@@ -24,6 +24,7 @@ #include "content/public/test/test_utils.h" #include "net/dns/mock_host_resolver.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/url_constants.h" #if BUILDFLAG(ENABLE_EXTENSIONS) #include "chrome/browser/extensions/unpacked_installer.h" @@ -132,6 +133,25 @@ run_until_loaded_and_painted.Run(); } +// Verify that it is possible to load and paint a file:// URL without running +// BEST_EFFORT tasks. Regression test for https://crbug.com/973244. +IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTest, LoadAndPaintFileScheme) { + constexpr base::FilePath::CharType kFile[] = FILE_PATH_LITERAL("links.html"); + GURL file_url(ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kFile))); + ASSERT_TRUE(file_url.SchemeIs(url::kFileScheme)); + + content::OpenURLParams open(file_url, content::Referrer(), + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_TYPED, false); + content::WebContents* const web_contents = browser()->OpenURL(open); + EXPECT_TRUE(web_contents->IsLoading()); + + RunLoopUntilLoadedAndPainted run_until_loaded_and_painted(web_contents); + run_until_loaded_and_painted.Run(); +} + // Verify that an extension can be loaded and perform basic messaging without // running BEST_EFFORT tasks. Regression test for http://crbug.com/177163#c112. //
diff --git a/chrome/browser/notifications/arc_application_notifier_controller.cc b/chrome/browser/notifications/arc_application_notifier_controller.cc index dbedc12..e483c3a 100644 --- a/chrome/browser/notifications/arc_application_notifier_controller.cc +++ b/chrome/browser/notifications/arc_application_notifier_controller.cc
@@ -6,6 +6,7 @@ #include <set> +#include "ash/public/cpp/notifier_metadata.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" @@ -52,21 +53,21 @@ StopObserving(); } -std::vector<ash::mojom::NotifierUiDataPtr> +std::vector<ash::NotifierMetadata> ArcApplicationNotifierController::GetNotifierList(Profile* profile) { // In Guest mode, it can be called but there's no ARC apps to return. if (profile->IsOffTheRecord()) - return std::vector<ash::mojom::NotifierUiDataPtr>(); + return std::vector<ash::NotifierMetadata>(); package_to_app_ids_.clear(); icons_.clear(); StopObserving(); ArcAppListPrefs* const app_list = ArcAppListPrefs::Get(profile); - std::vector<ash::mojom::NotifierUiDataPtr> results; + std::vector<ash::NotifierMetadata> notifiers; // The app list can be null in unit tests. if (!app_list) - return results; + return notifiers; const std::vector<std::string>& app_ids = app_list->GetAppIds(); last_profile_ = profile; @@ -96,14 +97,13 @@ package_to_app_ids_.insert(std::make_pair(app->package_name, app_id)); message_center::NotifierId notifier_id( message_center::NotifierType::ARC_APPLICATION, app_id); - auto ui_data = ash::mojom::NotifierUiData::New( - notifier_id, base::UTF8ToUTF16(app->name), app->notifications_enabled, - false /* enforced */, icon->image_skia()); + notifiers.emplace_back(notifier_id, base::UTF8ToUTF16(app->name), + app->notifications_enabled, false /* enforced */, + icon->image_skia()); icons_.push_back(std::move(icon)); - results.push_back(std::move(ui_data)); } - return results; + return notifiers; } void ArcApplicationNotifierController::SetNotifierEnabled(
diff --git a/chrome/browser/notifications/arc_application_notifier_controller.h b/chrome/browser/notifications/arc_application_notifier_controller.h index 59d8b19..e9569b5 100644 --- a/chrome/browser/notifications/arc_application_notifier_controller.h +++ b/chrome/browser/notifications/arc_application_notifier_controller.h
@@ -31,8 +31,7 @@ ~ArcApplicationNotifierController() override; // TODO(hirono): Rewrite the function with new API to fetch package list. - std::vector<ash::mojom::NotifierUiDataPtr> GetNotifierList( - Profile* profile) override; + std::vector<ash::NotifierMetadata> GetNotifierList(Profile* profile) override; void SetNotifierEnabled(Profile* profile, const message_center::NotifierId& notifier_id, bool enabled) override;
diff --git a/chrome/browser/notifications/chrome_ash_message_center_client.cc b/chrome/browser/notifications/chrome_ash_message_center_client.cc index f2c8e3a..93e7231a 100644 --- a/chrome/browser/notifications/chrome_ash_message_center_client.cc +++ b/chrome/browser/notifications/chrome_ash_message_center_client.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/notifications/chrome_ash_message_center_client.h" +#include "ash/public/cpp/notifier_metadata.h" +#include "ash/public/cpp/notifier_settings_observer.h" #include "ash/public/interfaces/constants.mojom.h" #include "base/i18n/string_compare.h" #include "base/stl_util.h" @@ -24,7 +26,6 @@ #include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/notifier_id.h" -using ash::mojom::NotifierUiDataPtr; using message_center::MessageCenter; using message_center::NotifierId; @@ -44,15 +45,16 @@ public: explicit NotifierComparator(icu::Collator* collator) : collator_(collator) {} - bool operator()(const NotifierUiDataPtr& n1, const NotifierUiDataPtr& n2) { - if (n1->notifier_id.type != n2->notifier_id.type) - return n1->notifier_id.type < n2->notifier_id.type; + bool operator()(const ash::NotifierMetadata& n1, + const ash::NotifierMetadata& n2) { + if (n1.notifier_id.type != n2.notifier_id.type) + return n1.notifier_id.type < n2.notifier_id.type; if (collator_) { - return base::i18n::CompareString16WithCollator(*collator_, n1->name, - n2->name) == UCOL_LESS; + return base::i18n::CompareString16WithCollator(*collator_, n1.name, + n2.name) == UCOL_LESS; } - return n1->name < n2->name; + return n1.name < n2.name; } private: @@ -138,10 +140,6 @@ ChromeAshMessageCenterClient::~ChromeAshMessageCenterClient() { DCHECK_EQ(this, g_chrome_ash_message_center_client); g_chrome_ash_message_center_client = nullptr; - if (deferred_notifier_list_callback_) { - std::move(deferred_notifier_list_callback_) - .Run(std::vector<ash::mojom::NotifierUiDataPtr>()); - } } void ChromeAshMessageCenterClient::Display( @@ -163,6 +161,30 @@ } } +void ChromeAshMessageCenterClient::GetNotifiers() { + Profile* profile = GetProfileForNotifiers(); + if (!profile) { + LOG(ERROR) << "GetNotifiers called before profile fully loaded, see " + "https://crbug.com/968825"; + return; + } + + std::vector<ash::NotifierMetadata> notifiers; + for (auto& source : sources_) { + auto source_notifiers = source.second->GetNotifierList(profile); + for (auto& notifier : source_notifiers) + notifiers.push_back(std::move(notifier)); + } + + UErrorCode error = U_ZERO_ERROR; + std::unique_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); + NotifierComparator comparator(U_SUCCESS(error) ? collator.get() : nullptr); + std::sort(notifiers.begin(), notifiers.end(), comparator); + + for (auto& observer : notifier_observers_) + observer.OnNotifiersUpdated(notifiers); +} + void ChromeAshMessageCenterClient::SetNotifierEnabled( const NotifierId& notifier_id, bool enabled) { @@ -171,63 +193,14 @@ sources_[notifier_id.type]->SetNotifierEnabled(profile, notifier_id, enabled); } -void ChromeAshMessageCenterClient::GetNotifierList( - GetNotifierListCallback callback) { - if (deferred_notifier_list_callback_) { - std::move(deferred_notifier_list_callback_) - .Run(std::vector<ash::mojom::NotifierUiDataPtr>()); - registrar_.RemoveAll(); - } - Profile* profile = GetProfileForNotifiers(); - if (profile) { - RespondWithNotifierList(profile, std::move(callback)); - } else { - LOG(ERROR) << "GetNotifierList called before profile fully loaded, see " - "https://crbug.com/968825"; - deferred_notifier_list_callback_ = std::move(callback); - registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, - content::NotificationService::AllSources()); - } +void ChromeAshMessageCenterClient::AddNotifierSettingsObserver( + ash::NotifierSettingsObserver* observer) { + notifier_observers_.AddObserver(observer); } -void ChromeAshMessageCenterClient::RespondWithNotifierList( - Profile* profile, - GetNotifierListCallback callback) const { - CHECK(profile); - std::vector<ash::mojom::NotifierUiDataPtr> notifiers; - for (auto& source : sources_) { - auto source_notifiers = source.second->GetNotifierList(profile); - for (auto& notifier : source_notifiers) { - notifiers.push_back(std::move(notifier)); - } - } - - UErrorCode error = U_ZERO_ERROR; - std::unique_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); - NotifierComparator comparator(U_SUCCESS(error) ? collator.get() : nullptr); - std::sort(notifiers.begin(), notifiers.end(), comparator); - - std::move(callback).Run(std::move(notifiers)); -} - -void ChromeAshMessageCenterClient::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_PROFILE_ADDED: { - Profile* profile = GetProfileForNotifiers(); - if (profile) { - CHECK(deferred_notifier_list_callback_); - RespondWithNotifierList(profile, - std::move(deferred_notifier_list_callback_)); - registrar_.RemoveAll(); - } - break; - } - default: - NOTREACHED(); - } +void ChromeAshMessageCenterClient::RemoveNotifierSettingsObserver( + ash::NotifierSettingsObserver* observer) { + notifier_observers_.RemoveObserver(observer); } void ChromeAshMessageCenterClient::GetArcAppIdByPackageName( @@ -241,20 +214,36 @@ void ChromeAshMessageCenterClient::OnIconImageUpdated( const NotifierId& notifier_id, const gfx::ImageSkia& image) { - // |controller_| may be null in unit tests. - if (!image.isNull() && controller_) - controller_->UpdateNotifierIcon(notifier_id, image); + for (auto& observer : notifier_observers_) + observer.OnNotifierIconUpdated(notifier_id, image); } void ChromeAshMessageCenterClient::OnNotifierEnabledChanged( const NotifierId& notifier_id, bool enabled) { - // May be null in unit tests. - if (controller_) - controller_->NotifierEnabledChanged(notifier_id, enabled); + if (!enabled) + MessageCenter::Get()->RemoveNotificationsForNotifierId(notifier_id); } // static void ChromeAshMessageCenterClient::FlushForTesting() { g_chrome_ash_message_center_client->binding_.FlushForTesting(); } + +void ChromeAshMessageCenterClient::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + switch (type) { + case chrome::NOTIFICATION_PROFILE_ADDED: { + Profile* profile = GetProfileForNotifiers(); + if (profile) { + GetNotifiers(); + registrar_.RemoveAll(); + } + break; + } + default: + NOTREACHED(); + } +}
diff --git a/chrome/browser/notifications/chrome_ash_message_center_client.h b/chrome/browser/notifications/chrome_ash_message_center_client.h index 90f118e..afdb52f 100644 --- a/chrome/browser/notifications/chrome_ash_message_center_client.h +++ b/chrome/browser/notifications/chrome_ash_message_center_client.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_NOTIFICATIONS_CHROME_ASH_MESSAGE_CENTER_CLIENT_H_ #define CHROME_BROWSER_NOTIFICATIONS_CHROME_ASH_MESSAGE_CENTER_CLIENT_H_ +#include "ash/public/cpp/notifier_settings_controller.h" #include "ash/public/interfaces/ash_message_center_controller.mojom.h" #include "chrome/browser/notifications/notification_platform_bridge.h" #include "chrome/browser/notifications/notification_platform_bridge_chromeos.h" @@ -19,7 +20,8 @@ // and handles interactions with those notifications, plus it keeps track of // NotifierControllers to provide notifier settings information to Ash (visible // in NotifierSettingsView). -class ChromeAshMessageCenterClient : public ash::mojom::AshMessageCenterClient, +class ChromeAshMessageCenterClient : public ash::NotifierSettingsController, + public ash::mojom::AshMessageCenterClient, public NotifierController::Observer, public content::NotificationObserver { public: @@ -31,10 +33,16 @@ void Display(const message_center::Notification& notification); void Close(const std::string& notification_id); - // ash::mojom::AshMessageCenterClient: + // ash::NotifierSettingsController: + void GetNotifiers() override; void SetNotifierEnabled(const message_center::NotifierId& notifier_id, bool enabled) override; - void GetNotifierList(GetNotifierListCallback callback) override; + void AddNotifierSettingsObserver( + ash::NotifierSettingsObserver* observer) override; + void RemoveNotifierSettingsObserver( + ash::NotifierSettingsObserver* observer) override; + + // ash::mojom::AshMessageCenterClient: void GetArcAppIdByPackageName( const std::string& package_name, GetArcAppIdByPackageNameCallback callback) override; @@ -49,9 +57,6 @@ static void FlushForTesting(); private: - void RespondWithNotifierList(Profile* profile, - GetNotifierListCallback callback) const; - // content::NotificationObserver override. void Observe(int type, const content::NotificationSource& source, @@ -63,10 +68,11 @@ std::map<message_center::NotifierType, std::unique_ptr<NotifierController>> sources_; + base::ObserverList<ash::NotifierSettingsObserver> notifier_observers_; + ash::mojom::AshMessageCenterControllerPtr controller_; mojo::AssociatedBinding<ash::mojom::AshMessageCenterClient> binding_; content::NotificationRegistrar registrar_; - GetNotifierListCallback deferred_notifier_list_callback_; DISALLOW_COPY_AND_ASSIGN(ChromeAshMessageCenterClient); };
diff --git a/chrome/browser/notifications/chrome_ash_message_center_client_unittest.cc b/chrome/browser/notifications/chrome_ash_message_center_client_unittest.cc index 1391939..d083784 100644 --- a/chrome/browser/notifications/chrome_ash_message_center_client_unittest.cc +++ b/chrome/browser/notifications/chrome_ash_message_center_client_unittest.cc
@@ -7,6 +7,8 @@ #include <string> #include <utility> +#include "ash/public/cpp/notifier_metadata.h" +#include "ash/public/cpp/notifier_settings_observer.h" #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" @@ -28,25 +30,39 @@ #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/notifier_id.h" namespace { -class ChromeAshMessageCenterClientTest : public testing::Test { +class ChromeAshMessageCenterClientTest : public testing::Test, + public ash::NotifierSettingsObserver { protected: ChromeAshMessageCenterClientTest() : testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {} ~ChromeAshMessageCenterClientTest() override {} + // testing::Test: void SetUp() override { ASSERT_TRUE(testing_profile_manager_.SetUp()); // Initialize the UserManager singleton to a fresh FakeUserManager instance. user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( std::make_unique<chromeos::FakeChromeUserManager>()); + + message_center::MessageCenter::Initialize(); } - void TearDown() override { client_.reset(); } + void TearDown() override { + client_.reset(); + message_center::MessageCenter::Shutdown(); + } + + // ash::NotifierSettingsObserver: + void OnNotifiersUpdated( + const std::vector<ash::NotifierMetadata>& notifiers) override { + notifiers_ = notifiers; + } TestingProfile* CreateProfile(const std::string& name) { TestingProfile* profile = @@ -69,6 +85,7 @@ void CreateClient() { client_.reset(new ChromeAshMessageCenterClient(nullptr)); + client_->AddNotifierSettingsObserver(this); } ChromeAshMessageCenterClient* message_center_client() { @@ -76,13 +93,9 @@ } protected: - void RefreshNotifierList() { - message_center_client()->GetNotifierList( - base::BindOnce(&ChromeAshMessageCenterClientTest::SetNotifierUiData, - base::Unretained(this))); - } + void RefreshNotifierList() { message_center_client()->GetNotifiers(); } - std::vector<ash::mojom::NotifierUiDataPtr> notifiers_; + std::vector<ash::NotifierMetadata> notifiers_; private: chromeos::FakeChromeUserManager* GetFakeUserManager() { @@ -90,10 +103,6 @@ user_manager::UserManager::Get()); } - void SetNotifierUiData(std::vector<ash::mojom::NotifierUiDataPtr> notifiers) { - notifiers_ = std::move(notifiers); - } - content::TestBrowserThreadBundle thread_bundle_; TestingProfileManager testing_profile_manager_; std::unique_ptr<ChromeAshMessageCenterClient> client_; @@ -215,8 +224,8 @@ RefreshNotifierList(); ASSERT_EQ(2u, notifiers_.size()); - EXPECT_EQ(kBarId, notifiers_[0]->notifier_id.id); - EXPECT_EQ(kFooId, notifiers_[1]->notifier_id.id); + EXPECT_EQ(kBarId, notifiers_[0].notifier_id.id); + EXPECT_EQ(kFooId, notifiers_[1].notifier_id.id); } TEST_F(ChromeAshMessageCenterClientTest, SetWebPageNotifierEnabled) {
diff --git a/chrome/browser/notifications/extension_notifier_controller.cc b/chrome/browser/notifications/extension_notifier_controller.cc index 9c0e575..6b1b9a748 100644 --- a/chrome/browser/notifications/extension_notifier_controller.cc +++ b/chrome/browser/notifications/extension_notifier_controller.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/notifications/extension_notifier_controller.h" +#include "ash/public/cpp/notifier_metadata.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/chrome_app_icon_loader.h" #include "chrome/browser/notifications/notifier_state_tracker.h" @@ -22,9 +23,9 @@ ExtensionNotifierController::~ExtensionNotifierController() {} -std::vector<ash::mojom::NotifierUiDataPtr> -ExtensionNotifierController::GetNotifierList(Profile* profile) { - std::vector<ash::mojom::NotifierUiDataPtr> ui_data; +std::vector<ash::NotifierMetadata> ExtensionNotifierController::GetNotifierList( + Profile* profile) { + std::vector<ash::NotifierMetadata> notifiers; const extensions::ExtensionSet& extension_set = extensions::ExtensionRegistry::Get(profile)->enabled_extensions(); // The extension icon size has to be 32x32 at least to load bigger icons if @@ -53,14 +54,14 @@ message_center::NotifierType::APPLICATION, extension->id()); NotifierStateTracker* const notifier_state_tracker = NotifierStateTrackerFactory::GetForProfile(profile); - ui_data.push_back(ash::mojom::NotifierUiData::New( + notifiers.emplace_back( notifier_id, base::UTF8ToUTF16(extension->name()), notifier_state_tracker->IsNotifierEnabled(notifier_id), - false /* enforced */, gfx::ImageSkia())); + false /* enforced */, gfx::ImageSkia()); app_icon_loader_->FetchImage(extension->id()); } - return ui_data; + return notifiers; } void ExtensionNotifierController::SetNotifierEnabled(
diff --git a/chrome/browser/notifications/extension_notifier_controller.h b/chrome/browser/notifications/extension_notifier_controller.h index 179cc8d..e7f7b20 100644 --- a/chrome/browser/notifications/extension_notifier_controller.h +++ b/chrome/browser/notifications/extension_notifier_controller.h
@@ -19,8 +19,7 @@ ~ExtensionNotifierController() override; // NotifierController: - std::vector<ash::mojom::NotifierUiDataPtr> GetNotifierList( - Profile* profile) override; + std::vector<ash::NotifierMetadata> GetNotifierList(Profile* profile) override; void SetNotifierEnabled(Profile* profile, const message_center::NotifierId& notifier_id, bool enabled) override;
diff --git a/chrome/browser/notifications/notifier_controller.h b/chrome/browser/notifications/notifier_controller.h index fce6a31a..b23375a6 100644 --- a/chrome/browser/notifications/notifier_controller.h +++ b/chrome/browser/notifications/notifier_controller.h
@@ -8,12 +8,15 @@ #include <memory> #include <vector> -#include "ash/public/interfaces/ash_message_center_controller.mojom.h" +#include "ash/public/cpp/notifier_metadata.h" #include "base/macros.h" -#include "ui/message_center/public/cpp/notifier_id.h" class Profile; +namespace message_center { +struct NotifierId; +} + // An interface to control Notifiers, grouped by NotifierType. Controllers are // responsible for both collating display data and toggling settings in response // to user inputs. @@ -33,7 +36,7 @@ // Returns notifiers to display in the settings UI. Not all notifiers appear // in settings. If the source starts loading for icon images, it needs to call // Observer::OnIconImageUpdated after the icon is loaded. - virtual std::vector<ash::mojom::NotifierUiDataPtr> GetNotifierList( + virtual std::vector<ash::NotifierMetadata> GetNotifierList( Profile* profile) = 0; // Set notifier enabled. |notifier_id| must have notifier type that can be
diff --git a/chrome/browser/notifications/web_page_notifier_controller.cc b/chrome/browser/notifications/web_page_notifier_controller.cc index 4eeb877..1c07723e 100644 --- a/chrome/browser/notifications/web_page_notifier_controller.cc +++ b/chrome/browser/notifications/web_page_notifier_controller.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/notifications/web_page_notifier_controller.h" +#include "ash/public/cpp/notifier_metadata.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" #include "base/task/cancelable_task_tracker.h" @@ -21,9 +22,9 @@ WebPageNotifierController::~WebPageNotifierController() {} -std::vector<ash::mojom::NotifierUiDataPtr> -WebPageNotifierController::GetNotifierList(Profile* profile) { - std::vector<ash::mojom::NotifierUiDataPtr> notifiers; +std::vector<ash::NotifierMetadata> WebPageNotifierController::GetNotifierList( + Profile* profile) { + std::vector<ash::NotifierMetadata> notifiers; ContentSettingsForOneType settings; HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType( @@ -52,11 +53,11 @@ content_settings::SettingInfo info; HostContentSettingsMapFactory::GetForProfile(profile)->GetWebsiteSetting( url, GURL(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string(), &info); - notifiers.push_back(ash::mojom::NotifierUiData::New( + notifiers.emplace_back( notifier_id, name, notifier_state_tracker->IsNotifierEnabled(notifier_id), info.source == content_settings::SETTING_SOURCE_POLICY, - gfx::ImageSkia())); + gfx::ImageSkia()); patterns_[url_pattern] = iter->primary_pattern; // Note that favicon service obtains the favicon from history. This means // that it will fail to obtain the image if there are no history data for
diff --git a/chrome/browser/notifications/web_page_notifier_controller.h b/chrome/browser/notifications/web_page_notifier_controller.h index 239a71f..69d378c 100644 --- a/chrome/browser/notifications/web_page_notifier_controller.h +++ b/chrome/browser/notifications/web_page_notifier_controller.h
@@ -21,8 +21,7 @@ explicit WebPageNotifierController(Observer* observer); ~WebPageNotifierController() override; - std::vector<ash::mojom::NotifierUiDataPtr> GetNotifierList( - Profile* profile) override; + std::vector<ash::NotifierMetadata> GetNotifierList(Profile* profile) override; void SetNotifierEnabled(Profile* profile, const message_center::NotifierId& notifier_id,
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc index ca3e7d84..aa3f58ab 100644 --- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc
@@ -227,6 +227,8 @@ content::RenderFrameHost* subframe_rfh, int behavior_flags, const page_load_metrics::PageLoadExtraInfo& info) { + RecordLoadingBehaviorObserved(info); + if (subframe_rfh == nullptr) return; @@ -255,6 +257,31 @@ } } +void AMPPageLoadMetricsObserver::RecordLoadingBehaviorObserved( + const page_load_metrics::PageLoadExtraInfo& info) { + ukm::builders::AmpPageLoad builder(info.source_id); + bool should_record = false; + if (!observed_amp_main_frame_ && + (info.main_frame_metadata.behavior_flags & + blink::WebLoadingBehaviorFlag::kWebLoadingBehaviorAmpDocumentLoaded) != + 0) { + builder.SetMainFrameAmpPageLoad(true); + observed_amp_main_frame_ = true; + should_record = true; + } + + if (!observed_amp_sub_frame_ && + (info.subframe_metadata.behavior_flags & + blink::WebLoadingBehaviorFlag::kWebLoadingBehaviorAmpDocumentLoaded) != + 0) { + builder.SetSubFrameAmpPageLoad(true); + observed_amp_sub_frame_ = true; + should_record = true; + } + if (should_record) + builder.Record(ukm::UkmRecorder::Get()); +} + void AMPPageLoadMetricsObserver::MaybeRecordAmpDocumentMetrics() { if (current_main_frame_nav_info_ == nullptr || current_main_frame_nav_info_->subframe_rfh == nullptr)
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h index 57eef59..9acd51b 100644 --- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h
@@ -113,6 +113,9 @@ bool amp_document_loaded = false; }; + void RecordLoadingBehaviorObserved( + const page_load_metrics::PageLoadExtraInfo& info); + void ProcessMainFrameNavigation(content::NavigationHandle* navigation_handle); void MaybeRecordAmpDocumentMetrics(); @@ -126,6 +129,9 @@ GURL current_url_; + bool observed_amp_main_frame_ = false; + bool observed_amp_sub_frame_ = false; + DISALLOW_COPY_AND_ASSIGN(AMPPageLoadMetricsObserver); };
diff --git a/chrome/browser/page_load_metrics/observers/amp_ukm_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_browsertest.cc similarity index 92% rename from chrome/browser/page_load_metrics/observers/amp_ukm_observer_browsertest.cc rename to chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_browsertest.cc index fe9440bc..7314c260 100644 --- a/chrome/browser/page_load_metrics/observers/amp_ukm_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_browsertest.cc
@@ -23,10 +23,10 @@ using UkmEntry = ukm::builders::AmpPageLoad; -class AmpUkmObserverBrowserTest : public InProcessBrowserTest { +class AmpPageLoadMetricsBrowserTest : public InProcessBrowserTest { public: - AmpUkmObserverBrowserTest() {} - ~AmpUkmObserverBrowserTest() override {} + AmpPageLoadMetricsBrowserTest() {} + ~AmpPageLoadMetricsBrowserTest() override {} void PreRunTestOnMainThread() override { InProcessBrowserTest::PreRunTestOnMainThread(); @@ -85,10 +85,10 @@ std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_; std::unique_ptr<net::EmbeddedTestServer> https_test_server_; - DISALLOW_COPY_AND_ASSIGN(AmpUkmObserverBrowserTest); + DISALLOW_COPY_AND_ASSIGN(AmpPageLoadMetricsBrowserTest); }; -IN_PROC_BROWSER_TEST_F(AmpUkmObserverBrowserTest, NoAmp) { +IN_PROC_BROWSER_TEST_F(AmpPageLoadMetricsBrowserTest, NoAmp) { page_load_metrics::PageLoadMetricsTestWaiter waiter( browser()->tab_strip_model()->GetActiveWebContents()); waiter.AddPageExpectation( @@ -102,7 +102,7 @@ ExpectMetricCountForUrl(url, "SubFrameAmpPageLoad", 0); } -IN_PROC_BROWSER_TEST_F(AmpUkmObserverBrowserTest, AmpMainFrame) { +IN_PROC_BROWSER_TEST_F(AmpPageLoadMetricsBrowserTest, AmpMainFrame) { page_load_metrics::PageLoadMetricsTestWaiter waiter( browser()->tab_strip_model()->GetActiveWebContents()); waiter.AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter:: @@ -116,7 +116,7 @@ ExpectMetricCountForUrl(url, "SubFrameAmpPageLoad", 0); } -IN_PROC_BROWSER_TEST_F(AmpUkmObserverBrowserTest, AmpSubframe) { +IN_PROC_BROWSER_TEST_F(AmpPageLoadMetricsBrowserTest, AmpSubframe) { page_load_metrics::PageLoadMetricsTestWaiter waiter( browser()->tab_strip_model()->GetActiveWebContents()); waiter.AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc index dc55520..2826809 100644 --- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc
@@ -80,14 +80,17 @@ 1); } - ukm::mojom::UkmEntryPtr GetAmpPageLoadUkmEntry() { - std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> entries = - test_ukm_recorder().GetMergedEntriesByName( - ukm::builders::AmpPageLoad::kEntryName); - if (entries.size() != 1ul) { - return nullptr; + ukm::mojom::UkmEntryPtr GetAmpPageLoadUkmEntry(const GURL& url) { + ukm::mojom::UkmEntryPtr entry; + for (auto& it : test_ukm_recorder().GetMergedEntriesByName( + ukm::builders::AmpPageLoad::kEntryName)) { + const ukm::UkmSource* source = + test_ukm_recorder().GetSourceForSourceId(it.first); + if (source->url() == url) { + entry = std::move(it.second); + } } - return std::move(entries.begin()->second); + return entry; } protected: @@ -170,13 +173,13 @@ } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameInputBeforeNavigation) { + GURL main_frame_url("https://ampviewer.com/"); GURL amp_url("https://ampviewer.com/page"); // This emulates the AMP subframe non-prerender flow: first we perform a // same-document navigation in the main frame to the AMP viewer URL, then we // create and navigate the subframe to an AMP cache URL. - NavigationSimulator::CreateRendererInitiated(GURL("https://ampviewer.com/"), - main_rfh()) + NavigationSimulator::CreateRendererInitiated(main_frame_url, main_rfh()) ->Commit(); NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh()) @@ -210,14 +213,25 @@ "MainFrameToSubFrameNavigationDelta.Subframe", 0); + ukm::mojom::UkmEntryPtr main_frame_entry = + GetAmpPageLoadUkmEntry(main_frame_url); + ukm::mojom::UkmEntryPtr sub_frame_entry = GetAmpPageLoadUkmEntry(amp_url); + ASSERT_NE(nullptr, main_frame_entry.get()); + ASSERT_NE(nullptr, sub_frame_entry.get()); + // We expect a source with a negative NavigationDelta metric, since the main // frame navigation occurred before the AMP subframe navigation. - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); - test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( - entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); + sub_frame_entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); EXPECT_NE(nullptr, nav_delta_metric); EXPECT_GE(*nav_delta_metric, 0ll); + + const int64_t* amp_subframe_metric = test_ukm_recorder().GetEntryMetric( + main_frame_entry.get(), "SubFrameAmpPageLoad"); + EXPECT_NE(nullptr, amp_subframe_metric); + EXPECT_GE(*amp_subframe_metric, 1ll); + EXPECT_EQ(nullptr, test_ukm_recorder().GetEntryMetric( + main_frame_entry.get(), "MainFrameAmpPageLoad")); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameNavigationBeforeInput) { @@ -261,9 +275,11 @@ "MainFrameToSubFrameNavigationDelta.Subframe", 0); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(amp_url); + ASSERT_NE(nullptr, entry.get()); + // We expect a source with a positive NavigationDelta metric, since the main // frame navigation occurred after the AMP subframe navigation. - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); @@ -323,7 +339,8 @@ histogram_tester().ExpectTotalCount( "PageLoad.Clients.AMP.InteractiveTiming.FirstInputDelay3.Subframe", 1); - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(amp_url); + ASSERT_NE(nullptr, entry.get()); test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); test_ukm_recorder().ExpectEntryMetric( entry.get(), "SubFrame.InteractiveTiming.FirstInputDelay3", 3); @@ -367,7 +384,8 @@ "PageLoad.Clients.AMP.Experimental.LayoutStability.JankScore.Subframe", 10, 1); - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(amp_url); + ASSERT_NE(nullptr, entry.get()); test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); test_ukm_recorder().ExpectEntryMetric( entry.get(), "SubFrame.LayoutStability.JankScore", 100); @@ -424,7 +442,7 @@ "FullNavigation", 1); - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(amp_url); test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); test_ukm_recorder().ExpectEntryMetric( entry.get(), "SubFrame.InteractiveTiming.FirstInputDelay3", 3); @@ -467,7 +485,7 @@ // We expect a source with a negative NavigationDelta metric, since the main // frame navigation occurred before the AMP subframe navigation. - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(amp_url); test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); @@ -510,7 +528,7 @@ // We expect a source with a negative NavigationDelta metric, since the main // frame navigation occurred before the AMP subframe navigation. - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(amp_url); test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); @@ -519,11 +537,11 @@ } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameMultipleFrames) { + GURL main_frame_url("https://ampviewer.com/"); GURL amp_url1("https://ampviewer.com/page"); GURL amp_url2("https://ampviewer.com/page2"); - NavigationSimulator::CreateRendererInitiated(GURL("https://ampviewer.com/"), - main_rfh()) + NavigationSimulator::CreateRendererInitiated(main_frame_url, main_rfh()) ->Commit(); // Simulate a prerender. @@ -596,7 +614,7 @@ std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> entries = test_ukm_recorder().GetMergedEntriesByName( ukm::builders::AmpPageLoad::kEntryName); - EXPECT_EQ(2ull, entries.size()); + EXPECT_EQ(3ull, entries.size()); const ukm::UkmSource* source1 = nullptr; const ukm::UkmSource* source2 = nullptr; @@ -608,6 +626,8 @@ source1 = candidate; } else if (candidate->url() == amp_url2) { source2 = candidate; + } else if (candidate->url() == main_frame_url) { + // Ignore. } else { FAIL() << "Encountered unexpected source for: " << candidate->url(); } @@ -671,7 +691,7 @@ // We expect a source with a negative NavigationDelta metric, since the main // frame navigation occurred before the AMP subframe navigation. - ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(amp_url); test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); @@ -717,17 +737,17 @@ TEST_F(AMPPageLoadMetricsObserverTest, NoSubFrameMetricsForSubFrameWithoutViewerUrl) { + GURL subframe_url("https://ampviewer.com/page"); NavigationSimulator::CreateRendererInitiated(GURL("https://ampviewer.com/"), main_rfh()) ->Commit(); - NavigationSimulator::CreateRendererInitiated( - GURL("https://ampviewer.com/page"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(GURL(subframe_url), main_rfh()) ->CommitSameDocument(); content::RenderFrameHost* subframe = NavigationSimulator::NavigateAndCommitFromDocument( - GURL("https://ampsubframe.com/page"), + GURL(subframe_url), content::RenderFrameHostTester::For(web_contents()->GetMainFrame()) ->AppendChild("subframe")); @@ -752,7 +772,6 @@ "MainFrameToSubFrameNavigationDelta.Subframe", 0); - EXPECT_TRUE(test_ukm_recorder() - .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) - .empty()); + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(subframe_url); + EXPECT_EQ(nullptr, entry.get()); }
diff --git a/chrome/browser/page_load_metrics/observers/amp_ukm_observer.cc b/chrome/browser/page_load_metrics/observers/amp_ukm_observer.cc deleted file mode 100644 index 39870e7..0000000 --- a/chrome/browser/page_load_metrics/observers/amp_ukm_observer.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// 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. - -#include "chrome/browser/page_load_metrics/observers/amp_ukm_observer.h" - -#include "chrome/browser/page_load_metrics/page_load_metrics_util.h" -#include "services/metrics/public/cpp/metrics_utils.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "services/metrics/public/cpp/ukm_recorder.h" -#include "third_party/blink/public/common/features.h" - -AmpUkmObserver::AmpUkmObserver() {} - -AmpUkmObserver::~AmpUkmObserver() {} - -void AmpUkmObserver::OnLoadingBehaviorObserved( - content::RenderFrameHost* rfh, - int behavior_flags, - const page_load_metrics::PageLoadExtraInfo& info) { - ukm::builders::AmpPageLoad builder(info.source_id); - bool should_record = false; - if (!logged_main_frame_ && - (info.main_frame_metadata.behavior_flags & - blink::WebLoadingBehaviorFlag::kWebLoadingBehaviorAmpDocumentLoaded) != - 0) { - builder.SetMainFrameAmpPageLoad(true); - logged_main_frame_ = true; - should_record = true; - } - - if (!logged_subframe_ && - (info.subframe_metadata.behavior_flags & - blink::WebLoadingBehaviorFlag::kWebLoadingBehaviorAmpDocumentLoaded) != - 0) { - builder.SetSubFrameAmpPageLoad(true); - logged_subframe_ = true; - should_record = true; - } - if (should_record) - builder.Record(ukm::UkmRecorder::Get()); -}
diff --git a/chrome/browser/page_load_metrics/observers/amp_ukm_observer.h b/chrome/browser/page_load_metrics/observers/amp_ukm_observer.h deleted file mode 100644 index a2249754..0000000 --- a/chrome/browser/page_load_metrics/observers/amp_ukm_observer.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AMP_UKM_OBSERVER_H_ -#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AMP_UKM_OBSERVER_H_ - -#include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" -#include "services/metrics/public/cpp/ukm_source.h" - -// If URL-Keyed-Metrics (UKM) is enabled in the system, this is used to -// populate it with AMP-related page-load metrics. -class AmpUkmObserver : public page_load_metrics::PageLoadMetricsObserver { - public: - AmpUkmObserver(); - ~AmpUkmObserver() override; - - void OnLoadingBehaviorObserved( - content::RenderFrameHost* rfh, - int behavior_flags, - const page_load_metrics::PageLoadExtraInfo& extra_info) override; - - private: - // Track what we've already logged. - bool logged_main_frame_ = false; - bool logged_subframe_ = false; - - DISALLOW_COPY_AND_ASSIGN(AmpUkmObserver); -}; - -#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AMP_UKM_OBSERVER_H_
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc index cef3475..7374014 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h" -#include "chrome/browser/page_load_metrics/observers/amp_ukm_observer.h" #include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h" @@ -92,7 +91,6 @@ if (!IsPrerendering()) { tracker->AddObserver(std::make_unique<AbortsPageLoadMetricsObserver>()); tracker->AddObserver(std::make_unique<AMPPageLoadMetricsObserver>()); - tracker->AddObserver(std::make_unique<AmpUkmObserver>()); tracker->AddObserver(std::make_unique<CorePageLoadMetricsObserver>()); tracker->AddObserver( std::make_unique<
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache.h index 1c158d6..1776e711 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache.h +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache.h
@@ -19,7 +19,7 @@ class SiteDataCache { public: SiteDataCache() = default; - ~SiteDataCache() = default; + virtual ~SiteDataCache() = default; // Returns a SiteDataReader for the given origin. virtual std::unique_ptr<SiteDataReader> GetReaderForOrigin(
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.cc new file mode 100644 index 0000000..d50957d --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.cc
@@ -0,0 +1,157 @@ +// 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. + +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h" + +#include <utility> + +#include "base/sequenced_task_runner.h" +#include "base/stl_util.h" +#include "base/task_runner_util.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "chrome/browser/performance_manager/performance_manager.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" + +namespace performance_manager { + +namespace { +SiteDataCacheFactory* g_instance = nullptr; +} // namespace + +SiteDataCacheFactory* SiteDataCacheFactory::GetInstance() { + return g_instance; +} + +SiteDataCacheFactory::SiteDataCacheFactory( + const scoped_refptr<base::SequencedTaskRunner> task_runner) + : task_runner_(task_runner) { + DETACH_FROM_SEQUENCE(sequence_checker_); + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); +} + +SiteDataCacheFactory::~SiteDataCacheFactory() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_EQ(this, g_instance); + g_instance = nullptr; +} + +// static +std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> +SiteDataCacheFactory::Create() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK_EQ(nullptr, g_instance); + auto task_runner = PerformanceManager::GetInstance()->task_runner(); + std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> instance( + new SiteDataCacheFactory(task_runner), + base::OnTaskRunnerDeleter(task_runner)); + + g_instance = instance.get(); + return instance; +} + +// static +std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> +SiteDataCacheFactory::CreateForTesting( + const scoped_refptr<base::SequencedTaskRunner> task_runner) { + DCHECK_EQ(nullptr, g_instance); + std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> instance( + new SiteDataCacheFactory(task_runner), + base::OnTaskRunnerDeleter(task_runner)); + g_instance = instance.get(); + return instance; +} + +// static +void SiteDataCacheFactory::OnBrowserContextCreatedOnUIThread( + SiteDataCacheFactory* factory, + const content::BrowserContext* browser_context) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(factory); + + // As |factory| will be deleted on its task runner it's safe to pass the raw + // pointer to BindOnce, it's guaranteed that this task will run before the + // factory. + factory->task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&SiteDataCacheFactory::OnBrowserContextCreated, + base::Unretained(factory), browser_context->UniqueId(), + browser_context->GetPath(), + browser_context->IsOffTheRecord())); +} + +// static +void SiteDataCacheFactory::OnBrowserContextDestroyedOnUIThread( + SiteDataCacheFactory* factory, + const content::BrowserContext* browser_context) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(factory); + // See OnBrowserContextCreatedOnUIThread for why it's safe to use a raw + // pointer in BindOnce. + factory->task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&SiteDataCacheFactory::OnBrowserContextDestroyed, + base::Unretained(factory), browser_context->UniqueId())); +} + +// static +SiteDataCache* SiteDataCacheFactory::GetDataCacheForBrowserContext( + const std::string& browser_context_id) const { + auto it = data_cache_map_.find(browser_context_id); + if (it != data_cache_map_.end()) + return it->second.get(); + return nullptr; +} + +// static +SiteDataCacheInspector* SiteDataCacheFactory::GetInspectorForBrowserContext( + const std::string& browser_context_id) const { + auto it = data_cache_inspector_map_.find(browser_context_id); + if (it != data_cache_inspector_map_.end()) + return it->second; + return nullptr; +} + +// static +void SiteDataCacheFactory::SetDataCacheInspectorForBrowserContext( + SiteDataCacheInspector* inspector, + const std::string& browser_context_id) { + if (inspector) { + DCHECK_EQ(nullptr, GetInspectorForBrowserContext(browser_context_id)); + data_cache_inspector_map_.emplace( + std::make_pair(browser_context_id, inspector)); + } else { + DCHECK_NE(nullptr, GetInspectorForBrowserContext(browser_context_id)); + data_cache_inspector_map_.erase(browser_context_id); + } +} + +void SiteDataCacheFactory::OnBrowserContextCreated( + const std::string& browser_context_id, + const base::FilePath& context_path, + bool context_is_off_the_record) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + DCHECK(!base::Contains(data_cache_map_, browser_context_id)); + + if (context_is_off_the_record) { + // TODO(sebmarchand): Add support for off-the-record contexts. + NOTREACHED(); + } else { + data_cache_map_.emplace(std::make_pair( + std::move(browser_context_id), + std::make_unique<SiteDataCacheImpl>(browser_context_id, context_path))); + } +} + +void SiteDataCacheFactory::OnBrowserContextDestroyed( + const std::string& browser_context_id) { + DCHECK(base::Contains(data_cache_map_, browser_context_id)); + data_cache_map_.erase(browser_context_id); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h new file mode 100644 index 0000000..145c610c --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h
@@ -0,0 +1,123 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_FACTORY_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_FACTORY_H_ + +#include <memory> +#include <string> + +#include "base/containers/flat_map.h" +#include "base/files/file_path.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/sequence_checker.h" +#include "base/sequenced_task_runner.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache.h" +#include "content/public/browser/browser_context.h" + +namespace content { +class BrowserContext; +} + +namespace performance_manager { + +class SiteDataCacheInspector; + +// This class is responsible for tracking the SiteDataCache instances associated +// with each browser context. It is meant to be used as a bridge between the +// browser contexts living on the UI thread and the PerformanceManager sequence. +class SiteDataCacheFactory { + public: + ~SiteDataCacheFactory(); + + // Retrieves the currently registered instance. + // The caller needs to ensure that the lifetime of the registered instance + // exceeds the use of this function and the retrieved pointer. + // This function can be called from any sequence with those caveats. + static SiteDataCacheFactory* GetInstance(); + + // Creates, initializes and registers an instance. The created instance will + // use the task runner from PerformanceManager for all its operations and thus + // should be created after the PerformanceManager global instance. + // The instance will be deleted on the instance's task runner. + // + // This function should only be called from the UI thread. + static std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> + Create(); + + // Create an instance that will live and be destroyed on |task_runner|. + // + // This function should only be called from the UI thread. + static std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> + CreateForTesting(const scoped_refptr<base::SequencedTaskRunner> task_runner); + + // Functions that should be called when a new browser context is created or + // destroyed. They should be called from the UI thread, a task will then be + // posted to the task_runner owned by |factory| to create the data store + // associated with this browser context. + static void OnBrowserContextCreatedOnUIThread( + SiteDataCacheFactory* factory, + const content::BrowserContext* browser_context); + static void OnBrowserContextDestroyedOnUIThread( + SiteDataCacheFactory* factory, + const content::BrowserContext* browser_context); + + // Returns a pointer to the data cache associated with |browser_context_id|, + // or null if there's no cache for this context yet. + // + // Should only be called from the Performance Manager sequence. + SiteDataCache* GetDataCacheForBrowserContext( + const std::string& browser_context_id) const; + + // Returns the data cache inspector associated with |browser_context_id|, or + // null if there's no data cache inspector for this context yet. + // + // Should only be called from the Performance Manager sequence. + SiteDataCacheInspector* GetInspectorForBrowserContext( + const std::string& browser_context_id) const; + + // Sets the inspector instance associated with a given browser context. + // If |inspector| is nullptr the association is cleared. + // The caller must ensure that |inspector|'s registration is cleared before + // |inspector| or |browser_context| are deleted. + // The intent is for this to be called from the SiteDataCache implementation + // class' constructors and destructors. + // + // Should only be called from the Performance Manager sequence. + void SetDataCacheInspectorForBrowserContext( + SiteDataCacheInspector* inspector, + const std::string& browser_context_id); + + private: + explicit SiteDataCacheFactory( + const scoped_refptr<base::SequencedTaskRunner> task_runner); + + // Implementation of the corresponding *OnUIThread public static functions + // that runs on this object's task runner. + void OnBrowserContextCreated(const std::string& browser_context_id, + const base::FilePath& context_path, + bool context_is_off_the_record); + void OnBrowserContextDestroyed(const std::string& browser_context_id); + + // The task runner on which this object lives, this is expected to be the + // performance task runner in practice. + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + + // A map that associates a BrowserContext's ID with a SiteDataCache. This + // object owns the caches. + base::flat_map<std::string, std::unique_ptr<SiteDataCache>> data_cache_map_; + + // A map that associates a BrowserContext's ID with a SiteDataCacheInspector. + base::flat_map<std::string, SiteDataCacheInspector*> + data_cache_inspector_map_; + + SEQUENCE_CHECKER(sequence_checker_); + + DISALLOW_COPY_AND_ASSIGN(SiteDataCacheFactory); +}; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_FACTORY_H_
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc new file mode 100644 index 0000000..3a4c6a22 --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc
@@ -0,0 +1,82 @@ +// 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. + +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h" + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/sequenced_task_runner.h" +#include "base/task/post_task.h" +#include "base/test/bind_test_util.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager { + +class SiteDataCacheFactoryTest : public ::testing::Test { + protected: + SiteDataCacheFactoryTest() + : task_runner_(base::CreateSequencedTaskRunner({})), + factory_(SiteDataCacheFactory::CreateForTesting(task_runner_)) {} + + ~SiteDataCacheFactoryTest() override { + factory_.reset(); + test_browser_thread_bundle_.RunUntilIdle(); + } + + void SetUp() override { + EXPECT_EQ(SiteDataCacheFactory::GetInstance(), factory_.get()); + } + + content::TestBrowserThreadBundle test_browser_thread_bundle_; + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> factory_; + TestingProfile profile_; + + DISALLOW_COPY_AND_ASSIGN(SiteDataCacheFactoryTest); +}; + +TEST_F(SiteDataCacheFactoryTest, EndToEnd) { + SiteDataCacheFactory::OnBrowserContextCreatedOnUIThread(factory_.get(), + &profile_); + + base::RunLoop run_loop; + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](SiteDataCacheFactory* factory, + const std::string& browser_context_id, + base::OnceClosure quit_closure) { + DCHECK_NE(nullptr, factory->GetDataCacheForBrowserContext( + browser_context_id)); + DCHECK_NE(nullptr, factory->GetInspectorForBrowserContext( + browser_context_id)); + std::move(quit_closure).Run(); + }, + factory_.get(), profile_.UniqueId(), run_loop.QuitClosure())); + run_loop.Run(); + + SiteDataCacheFactory::OnBrowserContextDestroyedOnUIThread(factory_.get(), + &profile_); + + base::RunLoop run_loop2; + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](SiteDataCacheFactory* factory, + const std::string& browser_context_id, + base::OnceClosure quit_closure) { + DCHECK_EQ(nullptr, factory->GetDataCacheForBrowserContext( + browser_context_id)); + DCHECK_EQ(nullptr, factory->GetInspectorForBrowserContext( + browser_context_id)); + std::move(quit_closure).Run(); + }, + factory_.get(), profile_.UniqueId(), run_loop.QuitClosure())); + test_browser_thread_bundle_.RunUntilIdle(); +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.cc index 95c9c184..06bb6895 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.cc +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.cc
@@ -10,9 +10,9 @@ #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "chrome/browser/performance_manager/persistence/site_data/leveldb_site_data_store.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_reader.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_writer.h" -#include "content/public/browser/browser_context.h" namespace performance_manager { @@ -22,21 +22,27 @@ } // namespace -SiteDataCacheImpl::SiteDataCacheImpl(content::BrowserContext* browser_context) - : browser_context_(browser_context) { +SiteDataCacheImpl::SiteDataCacheImpl(const std::string& browser_context_id, + const base::FilePath& browser_context_path) + : browser_context_id_(browser_context_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); data_store_ = std::make_unique<LevelDBSiteDataStore>( - browser_context->GetPath().AppendASCII(kDataStoreDBName)); + browser_context_path.AppendASCII(kDataStoreDBName)); // Register the debug interface against the browser context. - SiteDataCacheInspector::SetForBrowserContext(this, browser_context); + SiteDataCacheFactory::GetInstance()->SetDataCacheInspectorForBrowserContext( + this, browser_context_id_); } SiteDataCacheImpl::~SiteDataCacheImpl() { - SiteDataCacheInspector::SetForBrowserContext(nullptr, browser_context_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + SiteDataCacheFactory::GetInstance()->SetDataCacheInspectorForBrowserContext( + nullptr, browser_context_id_); } std::unique_ptr<SiteDataReader> SiteDataCacheImpl::GetReaderForOrigin( const url::Origin& origin) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); internal::SiteDataImpl* impl = GetOrCreateFeatureImpl(origin); DCHECK(impl); SiteDataReader* data_reader = new SiteDataReader(impl); @@ -46,6 +52,7 @@ std::unique_ptr<SiteDataWriter> SiteDataCacheImpl::GetWriterForOrigin( const url::Origin& origin, performance_manager::TabVisibility tab_visibility) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); internal::SiteDataImpl* impl = GetOrCreateFeatureImpl(origin); DCHECK(impl); SiteDataWriter* data_writer = new SiteDataWriter(impl, tab_visibility); @@ -53,6 +60,7 @@ } bool SiteDataCacheImpl::IsRecordingForTesting() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return true; } @@ -61,6 +69,7 @@ } std::vector<url::Origin> SiteDataCacheImpl::GetAllInMemoryOrigins() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); std::vector<url::Origin> ret; ret.reserve(origin_data_map_.size()); @@ -71,12 +80,14 @@ } void SiteDataCacheImpl::GetDataStoreSize(DataStoreSizeCallback on_have_data) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); data_store_->GetStoreSize(std::move(on_have_data)); } bool SiteDataCacheImpl::GetDataForOrigin(const url::Origin& origin, bool* is_dirty, std::unique_ptr<SiteDataProto>* data) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_NE(nullptr, data); const auto it = origin_data_map_.find(origin); if (it == origin_data_map_.end()) @@ -90,11 +101,13 @@ } SiteDataCacheImpl* SiteDataCacheImpl::GetDataCache() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return this; } internal::SiteDataImpl* SiteDataCacheImpl::GetOrCreateFeatureImpl( const url::Origin& origin) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Start by checking if there's already an entry for this origin. auto iter = origin_data_map_.find(origin); if (iter != origin_data_map_.end()) @@ -112,6 +125,7 @@ } void SiteDataCacheImpl::OnSiteDataImplDestroyed(internal::SiteDataImpl* impl) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(impl); DCHECK(base::Contains(origin_data_map_, impl->origin())); // Remove the entry for this origin as this is about to get destroyed. @@ -121,6 +135,7 @@ void SiteDataCacheImpl::ClearSiteDataForOrigins( const std::vector<url::Origin>& origins_to_remove) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // It's not necessary to invalidate the pending DB write operations as they // run on a sequenced task and so it's guaranteed that the remove operations // posted here will run after any other pending operation. @@ -134,6 +149,7 @@ } void SiteDataCacheImpl::ClearAllSiteData() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // It's not necessary to invalidate the pending DB write operations as they // run on a sequenced task and so it's guaranteed that the remove operations // posted here will run after any other pending operation.
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h index cd361010..1469bf5 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h
@@ -6,10 +6,12 @@ #define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_IMPL_H_ #include <memory> +#include <string> #include <utility> #include <vector> #include "base/containers/flat_map.h" +#include "base/files/file_path.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/scoped_observer.h" @@ -18,10 +20,6 @@ #include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_impl.h" -namespace content { -class BrowserContext; -} - namespace performance_manager { // Implementation of a SiteDataCache that serves normal reader and writers. @@ -34,8 +32,9 @@ public: using SiteDataMap = base::flat_map<url::Origin, internal::SiteDataImpl*>; - explicit SiteDataCacheImpl(content::BrowserContext* browser_context); - virtual ~SiteDataCacheImpl(); + SiteDataCacheImpl(const std::string& browser_context_id, + const base::FilePath& browser_context_path); + ~SiteDataCacheImpl() override; // SiteCharacteristicDataCache: std::unique_ptr<SiteDataReader> GetReaderForOrigin( @@ -84,8 +83,10 @@ std::unique_ptr<SiteDataStore> data_store_; - // The browser context this data store is associated with. - content::BrowserContext* browser_context_; + // The ID of the browser context this data store is associated with. + const std::string browser_context_id_; + + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(SiteDataCacheImpl); };
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc index abba180..c8536adc 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" #include "chrome/browser/performance_manager/performance_manager_clock.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_impl.h" #include "chrome/browser/performance_manager/persistence/site_data/unittest_utils.h" @@ -45,9 +46,12 @@ class SiteDataCacheImplTest : public ::testing::Test { protected: - SiteDataCacheImplTest() { + SiteDataCacheImplTest() + : data_cache_factory_(SiteDataCacheFactory::CreateForTesting( + test_browser_thread_bundle_.GetMainThreadTaskRunner())) { PerformanceManagerClock::SetClockForTesting(&test_clock_); - data_cache_ = std::make_unique<SiteDataCacheImpl>(&profile_); + data_cache_ = std::make_unique<SiteDataCacheImpl>(profile_.UniqueId(), + profile_.GetPath()); mock_db_ = new ::testing::StrictMock<MockSiteCache>(); data_cache_->SetDataStoreForTesting(base::WrapUnique(mock_db_)); test_clock_.SetNowTicks(base::TimeTicks::UnixEpoch()); @@ -124,6 +128,8 @@ // Owned by |data_cache_|. ::testing::StrictMock<MockSiteCache>* mock_db_ = nullptr; + std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> + data_cache_factory_; std::unique_ptr<SiteDataCacheImpl> data_cache_; std::unique_ptr<SiteDataReader> reader_; @@ -231,7 +237,8 @@ TEST_F(SiteDataCacheImplTest, InspectorWorks) { // Make sure the inspector interface was registered at construction. SiteDataCacheInspector* inspector = - SiteDataCacheInspector::GetForBrowserContext(&profile_); + SiteDataCacheFactory::GetInstance()->GetInspectorForBrowserContext( + profile_.UniqueId()); EXPECT_NE(nullptr, inspector); EXPECT_EQ(data_cache_.get(), inspector); @@ -263,7 +270,9 @@ // Make sure the interface is unregistered from the profile on destruction. data_cache_.reset(); - EXPECT_EQ(nullptr, SiteDataCacheInspector::GetForBrowserContext(&profile_)); + EXPECT_EQ(nullptr, + SiteDataCacheFactory::GetInstance()->GetInspectorForBrowserContext( + profile_.UniqueId())); } } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.cc deleted file mode 100644 index 763c6eab..0000000 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// 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. - -#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h" - -#include "base/macros.h" -#include "content/public/browser/browser_context.h" - -namespace performance_manager { - -namespace { - -const void* const kSiteDataCacheInspectorUserKey = - &kSiteDataCacheInspectorUserKey; - -class SiteDataUserData : public base::SupportsUserData::Data { - public: - explicit SiteDataUserData(SiteDataCacheInspector* inspector) - : inspector_(inspector) {} - - SiteDataCacheInspector* inspector() const { return inspector_; } - - private: - SiteDataCacheInspector* inspector_; -}; - -} // namespace - -// static -SiteDataCacheInspector* SiteDataCacheInspector::GetForBrowserContext( - content::BrowserContext* browser_context) { - SiteDataUserData* data = static_cast<SiteDataUserData*>( - browser_context->GetUserData(kSiteDataCacheInspectorUserKey)); - - if (!data) - return nullptr; - - return data->inspector(); -} - -// static -void SiteDataCacheInspector::SetForBrowserContext( - SiteDataCacheInspector* inspector, - content::BrowserContext* browser_context) { - if (inspector) { - DCHECK_EQ(nullptr, GetForBrowserContext(browser_context)); - - browser_context->SetUserData(kSiteDataCacheInspectorUserKey, - std::make_unique<SiteDataUserData>(inspector)); - } else { - DCHECK_NE(nullptr, GetForBrowserContext(browser_context)); - browser_context->RemoveUserData(kSiteDataCacheInspectorUserKey); - } -} - -} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h index f1fb469b..7bfc106 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h
@@ -16,10 +16,6 @@ #include "chrome/browser/performance_manager/persistence/site_data/site_data.pb.h" #include "url/origin.h" -namespace content { -class BrowserContext; -} - namespace performance_manager { class SiteDataCache; @@ -28,11 +24,6 @@ // information for the associated web UI. class SiteDataCacheInspector { public: - // Retrieves the instance associated with a given browser context, or nullptr - // if none is associated with that browser context. - static SiteDataCacheInspector* GetForBrowserContext( - content::BrowserContext* browser_context); - // Returns the name of the data cache, which should uniquely identify the kind // of storage it implements. virtual const char* GetDataCacheName() = 0; @@ -62,16 +53,6 @@ // Retrieves the data cache this inspector is associated with. virtual SiteDataCache* GetDataCache() = 0; - - protected: - // Sets the inspector instance associated with a given browser context. - // If |inspector| is nullptr the association is cleared. - // The caller must ensure that |inspector|'s registration is cleared before - // |inspector| or |browser_context| are deleted. - // The intent is for this to be called from implementation class' constructors - // and destructors. - static void SetForBrowserContext(SiteDataCacheInspector* inspector, - content::BrowserContext* browser_context); }; } // namespace performance_manager
diff --git a/chrome/browser/permissions/PERMISSIONS_OWNERS b/chrome/browser/permissions/PERMISSIONS_OWNERS index 3cf4dd0f8..695d59f 100644 --- a/chrome/browser/permissions/PERMISSIONS_OWNERS +++ b/chrome/browser/permissions/PERMISSIONS_OWNERS
@@ -1,4 +1,5 @@ benwells@chromium.org dominickn@chromium.org +engedy@chromium.org raymes@chromium.org timloh@chromium.org
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc index 3f612a3c..9f53533 100644 --- a/chrome/browser/permissions/permission_manager.cc +++ b/chrome/browser/permissions/permission_manager.cc
@@ -34,6 +34,7 @@ #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "chrome/browser/storage/durable_storage_permission_context.h" #include "chrome/browser/tab_contents/tab_util.h" +#include "chrome/browser/wake_lock/wake_lock_permission_context.h" #include "chrome/common/buildflags.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" @@ -131,6 +132,10 @@ return CONTENT_SETTINGS_TYPE_IDLE_DETECTION; case PermissionType::PERIODIC_BACKGROUND_SYNC: return CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC; + case PermissionType::WAKE_LOCK_SCREEN: + return CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN; + case PermissionType::WAKE_LOCK_SYSTEM: + return CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM; case PermissionType::NUM: // This will hit the NOTREACHED below. break; @@ -320,6 +325,12 @@ std::make_unique<IdleDetectionPermissionContext>(profile); permission_contexts_[CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC] = std::make_unique<PeriodicBackgroundSyncPermissionContext>(profile); + permission_contexts_[CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN] = + std::make_unique<WakeLockPermissionContext>( + profile, CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN); + permission_contexts_[CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM] = + std::make_unique<WakeLockPermissionContext>( + profile, CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM); } PermissionManager::~PermissionManager() {
diff --git a/chrome/browser/permissions/permission_util.cc b/chrome/browser/permissions/permission_util.cc index b0d2cd1..334766ac 100644 --- a/chrome/browser/permissions/permission_util.cc +++ b/chrome/browser/permissions/permission_util.cc
@@ -56,6 +56,10 @@ return "IdleDetection"; case CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC: return "PeriodicBackgroundSync"; + case CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN: + return "WakeLockScreen"; + case CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM: + return "WakeLockSystem"; default: break; } @@ -132,6 +136,10 @@ *out = PermissionType::BACKGROUND_FETCH; } else if (type == CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC) { *out = PermissionType::PERIODIC_BACKGROUND_SYNC; + } else if (type == CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN) { + *out = PermissionType::WAKE_LOCK_SCREEN; + } else if (type == CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM) { + *out = PermissionType::WAKE_LOCK_SYSTEM; } else { return false; } @@ -157,6 +165,8 @@ case CONTENT_SETTINGS_TYPE_PAYMENT_HANDLER: case CONTENT_SETTINGS_TYPE_BACKGROUND_FETCH: case CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC: + case CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN: + case CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM: return true; default: return false;
diff --git a/chrome/browser/previews/previews_offline_helper.cc b/chrome/browser/previews/previews_offline_helper.cc index 833f3ac..45e47ff 100644 --- a/chrome/browser/previews/previews_offline_helper.cc +++ b/chrome/browser/previews/previews_offline_helper.cc
@@ -27,6 +27,7 @@ #include "components/previews/core/previews_experiments.h" #include "components/previews/core/previews_features.h" #include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_task_traits.h" namespace { // Pref key for the available hashed pages kept in class. @@ -160,7 +161,10 @@ // expensive DB query doesn't occur during startup or during other user // visible actions. base::PostDelayedTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::LOWEST}, + FROM_HERE, + {base::MayBlock(), content::BrowserThread::UI, + base::TaskPriority::LOWEST, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce(&PreviewsOfflineHelper::RequestDBUpdate, weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(30));
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc index 0a5b0c4..7df04e4 100644 --- a/chrome/browser/printing/print_preview_message_handler.cc +++ b/chrome/browser/printing/print_preview_message_handler.cc
@@ -315,7 +315,7 @@ mojom::PdfCompositor::Status status, base::ReadOnlySharedMemoryRegion region) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (status != mojom::PdfCompositor::Status::SUCCESS) { + if (status != mojom::PdfCompositor::Status::kSuccess) { DLOG(ERROR) << "Compositing pdf failed with error " << status; return; } @@ -386,7 +386,7 @@ mojom::PdfCompositor::Status status, base::ReadOnlySharedMemoryRegion region) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (status != mojom::PdfCompositor::Status::SUCCESS) { + if (status != mojom::PdfCompositor::Status::kSuccess) { DLOG(ERROR) << "Compositing pdf failed with error " << status; return; }
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index 0c779b5..9cffbb0f 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -285,7 +285,7 @@ mojom::PdfCompositor::Status status, base::ReadOnlySharedMemoryRegion region) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (status != mojom::PdfCompositor::Status::SUCCESS) { + if (status != mojom::PdfCompositor::Status::kSuccess) { DLOG(ERROR) << "Compositing pdf failed with error " << status; return; }
diff --git a/chrome/browser/resources/bookmarks/bookmarks.html b/chrome/browser/resources/bookmarks/bookmarks.html index b91e6202..077405e 100644 --- a/chrome/browser/resources/bookmarks/bookmarks.html +++ b/chrome/browser/resources/bookmarks/bookmarks.html
@@ -1,6 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading" - $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading"> <head> <meta charset="utf8"> <title>$i18n{title}</title> @@ -34,6 +33,5 @@ <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="app.html"> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/browser_switch/browser_switch.html b/chrome/browser/resources/browser_switch/browser_switch.html index 9b61a63d..968ae80f 100644 --- a/chrome/browser/resources/browser_switch/browser_switch.html +++ b/chrome/browser/resources/browser_switch/browser_switch.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>$i18n{title}</title>
diff --git a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js index ec1a3d8a..c1778b0 100644 --- a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js +++ b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
@@ -107,6 +107,15 @@ // kCustomEvent 600: {color: '#7cb342', name: 'Custom event', width: 1.0, radius: 4.0}, + // kInputEventCreated + 700: {color: '#ff6f00', name: 'create'}, + // kInputEventWaylandDispatched + 701: {color: '#f4ff81', name: 'dispatch'}, + // kInputEventDeliverStart + 702: {color: '#388e3c', name: 'deliver start'}, + // kInputEventDeliverEnd + 703: {color: unusedColor, name: 'deliver end'}, + // Service events. // kTimeMark 10000: {color: '#888', name: 'Time mark', width: 0.75}, @@ -146,6 +155,8 @@ 503: [500 /* kChromeOSDraw */], // kChromeOSSwapDone 504: [500 /* kChromeOSDraw */], + // kInputEventDeliverEnd + 703: [], }; /** @@ -653,10 +664,10 @@ eventIndices.push(eventIndex); minValue = Math.min(minValue, source.events[eventIndex][2]); maxValue = Math.max(maxValue, source.events[eventIndex][2]); - eventIndex = source.getNextEvent(eventIndex, 1 /* direction */); if (!attributes) { attributes = valueAttributes[source.events[eventIndex][0]]; } + eventIndex = source.getNextEvent(eventIndex, 1 /* direction */); } eventIndicesForAll.push(eventIndices); } @@ -1042,7 +1053,11 @@ var eventTimestamp = eventBand.events[index][1]; var entryToShow = {}; entryToShow.color = attributes.color; - entryToShow.text = attributes.name; + if (eventBand.events[index].length > 2) { + entryToShow.text = attributes.name + ' ' + eventBand.events[index][2]; + } else { + entryToShow.text = attributes.name; + } if (entriesToShow.length > 0) { entriesToShow[entriesToShow.length - 1].text += ' [' + timestampToMsText(eventTimestamp - lastTimestamp) + ' ms]'; @@ -1754,6 +1769,21 @@ allActivityCustomEvents.push(activityCustomEvents); } + // Input section if exists. + if (model.input && model.input.buffers.length > 0) { + var inputTitle = + new EventBandTitle(parent, 'Input', 'arc-events-band-title'); + var inputBands = new EventBands( + inputTitle, 'arc-events-band', resolution, 0, model.duration); + inputBands.setWidth(inputBands.timestampToOffset(model.duration)); + for (var i = 0; i < model.input.buffers.length; i++) { + inputBands.addBand( + new Events(model.input.buffers[i], 700, 799), topBandHeight, + topBandPadding); + } + inputBands.setVSync(vsyncEvents); + } + // Create time ruler. var timeRulerEventHeight = 16; var timeRulerLabelHeight = 92;
diff --git a/chrome/browser/resources/chromeos/drive_internals.html b/chrome/browser/resources/chromeos/drive_internals.html index 92ced649..884bfe7 100644 --- a/chrome/browser/resources/chromeos/drive_internals.html +++ b/chrome/browser/resources/chromeos/drive_internals.html
@@ -115,6 +115,7 @@ <section id="service-log-section" hidden> <h2>Service Log</h2> + <button id="button-export-logs">Export logs</button> <ul> <li><a id="other-logs">Other Logs</a> </ul>
diff --git a/chrome/browser/resources/chromeos/drive_internals.js b/chrome/browser/resources/chromeos/drive_internals.js index 6d6dc26..926ed729 100644 --- a/chrome/browser/resources/chromeos/drive_internals.js +++ b/chrome/browser/resources/chromeos/drive_internals.js
@@ -293,6 +293,10 @@ } } +function onZipDone(success) { + $('button-export-logs').removeAttribute('disabled'); +} + document.addEventListener('DOMContentLoaded', function() { chrome.send('pageLoaded'); @@ -317,6 +321,11 @@ chrome.send('listFileEntries'); }); + $('button-export-logs').addEventListener('click', function() { + $('button-export-logs').setAttribute('disabled', 'true'); + chrome.send('zipLogs'); + }); + window.setInterval(function() { chrome.send('periodicUpdate'); }, 1000);
diff --git a/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js b/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js index a02df75..3dfc945 100644 --- a/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js +++ b/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js
@@ -78,6 +78,28 @@ return dateToHtmlValues(maxDate).date; } +/** + * Gets the current time in a different timezone. + * @param {!string} timezoneId The timezone to be used to convert the time. + * @return {Date} The converted time. + */ +function getDateInTimezone(timezoneId) { + return new Date(new Date().toLocaleString('en-US', {timeZone: timezoneId})); +} + +/** + * Gives the time difference between two timezones. + * @param {!string} firstTimezoneId The timezone on the left-hand size of the + * subtraction. + * @param {!string} secondsTimezoneId The timezone on the right-hand side of the + * subtraction. + * @return {number} Delta in milliseconds between the two timezones. + */ +function getTimezoneDelta(firstTimezoneId, secondsTimezoneId) { + return getDateInTimezone(firstTimezoneId) - + getDateInTimezone(secondsTimezoneId); +} + Polymer({ is: 'set-time-dialog', @@ -124,6 +146,16 @@ readonly: true, value: getMaxDate, }, + + /** + * The last timezone selected. + * @private + */ + selectedTimezone_: { + type: String, + value: () => + /** @type {string} */ (loadTimeData.getValue('currentTimezoneId')), + }, }, /** @@ -149,13 +181,14 @@ /** @override */ ready: function() { - this.updateTime_(); + this.updateTime_(new Date()); }, /** @override */ attached: function() { // Register listeners for updates from C++ code. - this.addWebUIListener('system-clock-updated', this.updateTime_.bind(this)); + this.addWebUIListener( + 'system-clock-updated', this.updateTime_.bind(this, new Date())); this.addWebUIListener( 'system-timezone-changed', this.setTimezone_.bind(this)); this.addWebUIListener('validation-complete', this.saveAndClose_.bind(this)); @@ -166,6 +199,23 @@ }, /** + * @return {!Date} The date that is currently displayed on the dialog. + * @private + */ + getInputTime_: function() { + // Midnight of the current day in GMT. + const date = this.$.dateInput.valueAsDate; + // Add hours and minutes as set on the time input field. + date.setMilliseconds(this.$.timeInput.valueAsNumber); + // Add seconds from the system time, since the input fields only allow + // setting hour and minute. + date.setSeconds(date.getSeconds() + new Date().getSeconds()); + // Add timezone offset to get real time. + date.setMinutes(date.getMinutes() + date.getTimezoneOffset()); + return date; + }, + + /** * Sets the current timezone. * @param {string} timezoneId The timezone ID to select. * @private @@ -174,21 +224,26 @@ const timezoneSelect = this.$$('#timezoneSelect'); assert(timezoneSelect.childElementCount > 0); timezoneSelect.value = timezoneId; - this.updateTime_(); + + const now = this.getInputTime_(); + const timezoneDelta = getTimezoneDelta(timezoneId, this.selectedTimezone_); + now.setMilliseconds(now.getMilliseconds() + timezoneDelta); + + this.selectedTimezone_ = timezoneId; + this.updateTime_(now); }, /** - * Updates the date/time controls to the current local time. + * Updates the date/time controls time. * Called initially, then called again once a minute. + * @param {!Date} newTime Time used to update the date/time controls. * @private */ - updateTime_: function() { - const now = new Date(); - + updateTime_: function(newTime) { // Only update time controls if neither is focused. if (document.activeElement.id != 'dateInput' && document.activeElement.id != 'timeInput') { - const htmlValues = dateToHtmlValues(now); + const htmlValues = dateToHtmlValues(newTime); this.prevValues_.date = this.$.dateInput.value = htmlValues.date; this.prevValues_.time = this.$.timeInput.value = htmlValues.time; } @@ -198,9 +253,11 @@ } // Start timer to update these inputs every minute. - const secondsRemaining = 60 - now.getSeconds(); - this.timeTimeoutId_ = - window.setTimeout(this.updateTime_.bind(this), secondsRemaining * 1000); + const secondsRemaining = 60 - newTime.getSeconds(); + const nextTime = + new Date(newTime.setSeconds(newTime.getSeconds() + secondsRemaining)); + this.timeTimeoutId_ = window.setTimeout( + this.updateTime_.bind(this, nextTime), secondsRemaining * 1000); }, /** @@ -208,14 +265,15 @@ * @private */ applyTime_: function() { - const date = this.$.dateInput.valueAsDate; - date.setMilliseconds( - date.getMilliseconds() + this.$.timeInput.valueAsNumber); + const now = this.getInputTime_(); // Add timezone offset to get real time. - date.setMinutes(date.getMinutes() + date.getTimezoneOffset()); + const timezoneDelta = getTimezoneDelta( + /** @type {string} */ (loadTimeData.getValue('currentTimezoneId')), + this.selectedTimezone_); + now.setMilliseconds(now.getMilliseconds() + timezoneDelta); - const seconds = Math.floor(date / 1000); + const seconds = Math.floor(now / 1000); this.browserProxy_.setTimeInSeconds(seconds); }, @@ -232,6 +290,9 @@ // Restore previous value. e.target.value = this.prevValues_[e.target.id]; } + + // Schedule periodic updates with the new time. + this.updateTime_(this.getInputTime_()); }, /** @@ -239,7 +300,7 @@ * @private */ onTimezoneChange_: function(e) { - this.browserProxy_.setTimezone(e.currentTarget.value); + this.setTimezone_(e.currentTarget.value); }, /** @@ -258,6 +319,7 @@ /** @private */ saveAndClose_: function() { this.applyTime_(); + this.browserProxy_.setTimezone(this.selectedTimezone_); this.browserProxy_.dialogClose(); }, });
diff --git a/chrome/browser/resources/downloads/downloads.html b/chrome/browser/resources/downloads/downloads.html index 05a625d..ad88272 100644 --- a/chrome/browser/resources/downloads/downloads.html +++ b/chrome/browser/resources/downloads/downloads.html
@@ -1,6 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading" - $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading"> <head> <meta charset="utf-8"> <if expr="not optimize_webui"> @@ -53,6 +52,5 @@ <link rel="import" href="i18n_setup.html"> <link rel="import" href="manager.html"> <script src="downloads.js"></script> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/extensions/extensions.html b/chrome/browser/resources/extensions/extensions.html index ed51757..83ea4fe72 100644 --- a/chrome/browser/resources/extensions/extensions.html +++ b/chrome/browser/resources/extensions/extensions.html
@@ -1,6 +1,6 @@ <!doctype html> <html dir="$i18n{textdirection}" lang="$i18n{language}" - class="loading $i18n{loadTimeClasses}" $i18n{dark}> + class="loading $i18n{loadTimeClasses}"> <head> <meta charset="utf8"> <title>$i18n{title}</title> @@ -62,6 +62,5 @@ <extensions-manager></extensions-manager> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="chrome://extensions/manager.html"> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/history/history.html b/chrome/browser/resources/history/history.html index c87ee2b..af0c23e 100644 --- a/chrome/browser/resources/history/history.html +++ b/chrome/browser/resources/history/history.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf8"> <title>$i18n{title}</title> @@ -99,7 +99,6 @@ <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="constants.html"> <script src="history.js"></script> - <link rel="import" href="chrome://resources/html/dark_mode.html"> <link rel="import" href="app.html" async id="bundle"> </body>
diff --git a/chrome/browser/resources/management/management.html b/chrome/browser/resources/management/management.html index 62a62bf..8b4f155 100644 --- a/chrome/browser/resources/management/management.html +++ b/chrome/browser/resources/management/management.html
@@ -1,6 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading" - $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=yes">
diff --git a/chrome/browser/resources/ntp4/guest_tab.html b/chrome/browser/resources/ntp4/guest_tab.html index 1807bfc1..a89226c 100644 --- a/chrome/browser/resources/ntp4/guest_tab.html +++ b/chrome/browser/resources/ntp4/guest_tab.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>$i18n{title}</title>
diff --git a/chrome/browser/resources/page_not_available_for_guest/app.html b/chrome/browser/resources/page_not_available_for_guest/app.html index 9e8736a..9d08222e 100644 --- a/chrome/browser/resources/page_not_available_for_guest/app.html +++ b/chrome/browser/resources/page_not_available_for_guest/app.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>$i18n{pageTitle}</title> @@ -20,6 +20,5 @@ </head> <body> <h1>$i18n{pageHeading}</h1> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js index ffe73802..b068b14 100644 --- a/chrome/browser/resources/pdf/pdf_viewer.js +++ b/chrome/browser/resources/pdf/pdf_viewer.js
@@ -746,7 +746,7 @@ sendBackgroundColorForPrintPreview_: function() { this.pluginController_.postMessage({ type: 'backgroundColorChanged', - backgroundColor: document.documentElement.hasAttribute('dark') ? + backgroundColor: this.dark_ ? PDFViewer.PRINT_PREVIEW_DARK_BACKGROUND_COLOR : PDFViewer.PRINT_PREVIEW_BACKGROUND_COLOR, }); @@ -1014,7 +1014,7 @@ this.toolbarManager_.resetKeyboardNavigationAndHideToolbars(); return true; case 'darkModeChanged': - document.documentElement.toggleAttribute('dark', message.data.darkMode); + this.dark_ = message.data.darkMode; if (this.isPrintPreview_) { this.sendBackgroundColorForPrintPreview_(); }
diff --git a/chrome/browser/resources/print_preview/print_preview.html b/chrome/browser/resources/print_preview/print_preview.html index a24e2f9..d0e4cf1 100644 --- a/chrome/browser/resources/print_preview/print_preview.html +++ b/chrome/browser/resources/print_preview/print_preview.html
@@ -1,6 +1,6 @@ <!doctype html> <html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading" - $i18n{dark} $i18n{newprintpreviewlayout}> + $i18n{newprintpreviewlayout}> <head> <meta charset="utf-8"> <if expr="not optimize_webui"> @@ -79,6 +79,5 @@ <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="import" href="ui/app.html"> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/print_preview/ui/advanced_settings_dialog.js b/chrome/browser/resources/print_preview/ui/advanced_settings_dialog.js index 4fadd89..00abe9b1 100644 --- a/chrome/browser/resources/print_preview/ui/advanced_settings_dialog.js +++ b/chrome/browser/resources/print_preview/ui/advanced_settings_dialog.js
@@ -52,10 +52,21 @@ onKeydown_: function(e) { e.stopPropagation(); const searchInput = this.$.searchBox.getSearchInput(); - if (e.key == 'Escape' && - (e.composedPath()[0] !== searchInput || !searchInput.value.trim())) { + const eventInSearchBox = e.composedPath().includes(searchInput); + if (e.key == 'Escape' && (!eventInSearchBox || !searchInput.value.trim())) { this.$.dialog.cancel(); e.preventDefault(); + return; + } + + if (e.key == 'Enter' && !eventInSearchBox) { + const activeElementTag = e.composedPath()[0].tagName; + if (['CR-BUTTON', 'SELECT'].includes(activeElementTag)) { + return; + } + this.onApplyButtonClick_(); + e.preventDefault(); + return; } },
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html index 3929df2..81f28b12 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
@@ -17,32 +17,38 @@ <dom-module id="settings-bluetooth-page"> <template> <style include="settings-shared"> + .link-wrapper { + align-items: center; + display: flex; + flex-grow: 1; + } </style> <settings-animated-pages id="pages" section="bluetooth" focus-config="[[focusConfig_]]"> <div route-path="default"> <template is="dom-if" if="[[!isSecondaryUser_]]"> - <div id="bluetoothDevices" - class="settings-box two-line" actionable on-click="onTap_"> - <iron-icon icon="[[getIcon_(bluetoothToggleState_)]]"></iron-icon> - <div class="middle settings-box-text"> - $i18n{bluetoothPageTitle} - <div class="secondary" id="bluetoothSecondary"> - [[getOnOffString_(bluetoothToggleState_, - '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]] + <div id="bluetoothDevices" class="settings-box two-line"> + <div class="link-wrapper" actionable on-click="onTap_"> + <iron-icon icon="[[getIcon_(bluetoothToggleState_)]]"></iron-icon> + <div class="middle settings-box-text"> + $i18n{bluetoothPageTitle} + <div class="secondary" id="bluetoothSecondary"> + [[getOnOffString_(bluetoothToggleState_, + '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]] + </div> </div> + <cr-policy-pref-indicator + icon-aria-label="$i18n{bluetoothPageTitle}" + pref="[[prefs.cros.device.allow_bluetooth]]" + hidden="[[prefs.cros.device.allow_bluetooth.value]]"> + </cr-policy-pref-indicator> + <template is="dom-if" if="[[bluetoothToggleState_]]"> + <cr-icon-button class="subpage-arrow" + on-click="onSubpageArrowTap_" + aria-label="$i18n{bluetoothPageTitle}" + aria-describedby="bluetoothSecondary"></cr-icon-button> + </template> </div> - <cr-policy-pref-indicator - icon-aria-label="$i18n{bluetoothPageTitle}" - pref="[[prefs.cros.device.allow_bluetooth]]" - hidden="[[prefs.cros.device.allow_bluetooth.value]]"> - </cr-policy-pref-indicator> - <template is="dom-if" if="[[bluetoothToggleState_]]"> - <cr-icon-button class="subpage-arrow" - on-click="onSubpageArrowTap_" - aria-label="$i18n{bluetoothPageTitle}" - aria-describedby="bluetoothSecondary"></cr-icon-button> - </template> <div class="separator"></div> <cr-toggle id="enableBluetooth" checked="{{bluetoothToggleState_}}"
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.html b/chrome/browser/resources/settings/chromeos/os_settings.html index 95cf9194..462d617 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.html +++ b/chrome/browser/resources/settings/chromeos/os_settings.html
@@ -1,6 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading" - $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading"> <head> <meta charset="utf-8"> <title>$i18n{settings}</title> @@ -31,7 +30,6 @@ <os-settings-ui></os-settings-ui> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="chrome://resources/html/polymer.html"> - <link rel="import" href="chrome://resources/html/dark_mode.html"> <if expr="not optimize_webui"> <link rel="import" href="chromeos/os_settings_ui/os_settings_ui.html"> </if>
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index abf4d55..d7522a5 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -1534,6 +1534,11 @@ return false; } + // Cellular IP addresses are shown under the network details section. + if (this.isCellular_(networkProperties)) { + return false; + } + return !!ipAddress && this.isConnectedState_(networkProperties); },
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.html b/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.html index a31ccce..b4d6903 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.html +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.html
@@ -27,30 +27,43 @@ cr-policy-indicator { padding: 0 var(--cr-controlled-by-spacing); } + + .link-wrapper { + align-items: center; + display: flex; + flex-grow: 1; + } </style> - <div id="card" - class="settings-box two-line" - on-click="handleItemClick_" - actionable$="[[hasSubpageClickHandler_( - feature, pageContentData, subpageRoute)]]"> - <slot name="icon"> - <iron-icon icon="[[getIconName(feature)]]"></iron-icon> - </slot> - <div id="item-text-container" class="middle"> - <div id="featureName">[[getFeatureName(feature)]]</div> - <div class="secondary" - id="featureSecondary" - inner-h-t-m-l="[[getFeatureSummaryHtml(feature)]]"> + <div id="card" class="settings-box two-line"> + <div class="link-wrapper" actionable + actionable$="[[hasSubpageClickHandler_( + feature, pageContentData, subpageRoute)]]" + on-click="handleItemClick_"> + <slot name="icon"> + <iron-icon icon="[[getIconName(feature)]]"></iron-icon> + </slot> + <div id="item-text-container" class="middle"> + <div id="featureName">[[getFeatureName(feature)]]</div> + <div class="secondary" + id="featureSecondary" + inner-h-t-m-l="[[getFeatureSummaryHtml(feature)]]"> + </div> </div> + <template is="dom-if" + if="[[hasSubpageClickHandler_( + feature, pageContentData, subpageRoute)]]" + restamp> + <cr-icon-button class="subpage-arrow" aria-labelledby="featureName" + aria-describedby="featureSecondary"></cr-icon-button> + </template> </div> <template is="dom-if" - if="[[hasSubpageClickHandler_( + if="[[hasSubpageClickHandler_( feature, pageContentData, subpageRoute)]]" - restamp> - <cr-icon-button class="subpage-arrow" aria-labelledby="featureName" - aria-describedby="featureSecondary"></cr-icon-button> + restamp> <div class="separator"></div> </template> + <template is="dom-if" if="[[!isFeatureAllowedByPolicy(feature, pageContentData)]]" restamp>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html index b7891ce..f318ff4 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html
@@ -27,30 +27,46 @@ cr-policy-indicator { padding: 0 var(--cr-controlled-by-spacing); } + + .link-wrapper { + align-items: center; + display: flex; + flex-grow: 1; + } </style> <settings-animated-pages id="pages" section="multidevice" focus-config="[[focusConfig_]]"> <div route-path="default"> - <div id="multidevice-item" - class="settings-box two-line" - on-click="handleItemClick_" - actionable$="[[doesClickOpenSubpage_(pageContentData)]]"> - <template is="dom-if" if="[[isHostSet(pageContentData)]]" restamp> - <iron-icon icon= - "[[getIconName(MultiDeviceFeature.BETTER_TOGETHER_SUITE)]]"> - </iron-icon> - </template> - <div class$= - "[[getMultiDeviceItemLabelBlockCssClass_(pageContentData)]] - settings-box-text"> - <div id="multidevice-label">[[getLabelText_(pageContentData)]]</div> - <div id="multideviceSubLabel" class="secondary" - inner-h-t-m-l="[[getSubLabelInnerHtml_(pageContentData)]]"> + <div id="multidevice-item" class="settings-box two-line"> + <div class="link-wrapper" actionable + actionable$="[[doesClickOpenSubpage_(pageContentData)]]" + on-click="handleItemClick_"> + <template is="dom-if" if="[[isHostSet(pageContentData)]]" restamp> + <iron-icon icon= + "[[getIconName(MultiDeviceFeature.BETTER_TOGETHER_SUITE)]]"> + </iron-icon> + </template> + <div class$= + "[[getMultiDeviceItemLabelBlockCssClass_(pageContentData)]] + settings-box-text"> + <div id="multidevice-label"> + [[getLabelText_(pageContentData)]] + </div> + <div id="multideviceSubLabel" class="secondary" + inner-h-t-m-l="[[getSubLabelInnerHtml_(pageContentData)]]"> + </div> </div> + <template is="dom-if" + if="[[doesClickOpenSubpage_(pageContentData)]]" + restamp> + <cr-icon-button class="subpage-arrow" + aria-labelledby="multidevice-label" + aria-describedby="multideviceSubLabel"></cr-icon-button> + </template> </div> <template is="dom-if" - if="[[!isSuiteAllowedByPolicy(pageContentData)]]" - restamp> + if="[[!isSuiteAllowedByPolicy(pageContentData)]]" + restamp> <cr-policy-indicator indicator-type="userPolicy"> </cr-policy-indicator> <settings-multidevice-feature-toggle @@ -61,13 +77,6 @@ <template is="dom-if" if="[[shouldShowSeparatorAndSubpageArrow_(pageContentData)]]" restamp> - <template is="dom-if" - if="[[doesClickOpenSubpage_(pageContentData)]]" - restamp> - <cr-icon-button class="subpage-arrow" - aria-labelledby="multidevice-label" - aria-describedby="multideviceSubLabel"></cr-icon-button> - </template> <div class="separator"></div> </template> <template is="dom-if"
diff --git a/chrome/browser/resources/settings/settings.html b/chrome/browser/resources/settings/settings.html index c99aed2..7842e79 100644 --- a/chrome/browser/resources/settings/settings.html +++ b/chrome/browser/resources/settings/settings.html
@@ -1,6 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading" - $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading"> <head> <meta charset="utf-8"> <title>$i18n{settings}</title> @@ -31,6 +30,5 @@ <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="settings_ui/settings_ui.html"> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html index 6b02251..52d93830 100644 --- a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html +++ b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> @@ -24,5 +24,4 @@ <link rel="import" href="chrome://resources/html/cr.html"></script> <link rel="import" href="chrome://resources/html/util.html"></script> <script src="sync_confirmation.js"></script> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </html>
diff --git a/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html b/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html index 0ed1aa72..e920129 100644 --- a/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html +++ b/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> @@ -71,5 +71,4 @@ <link rel="import" href="chrome://resources/html/util.html"> <script src="sync_disabled_confirmation.js"></script> <script src="chrome://sync-confirmation/strings.js"></script> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </html>
diff --git a/chrome/browser/resources/user_manager/user_manager.html b/chrome/browser/resources/user_manager/user_manager.html index 9c6f9db..3166b31b 100644 --- a/chrome/browser/resources/user_manager/user_manager.html +++ b/chrome/browser/resources/user_manager/user_manager.html
@@ -2,8 +2,7 @@ <html build="$i18n{buildType}" dir="$i18n{textdirection}" lang="$i18n{language}" - screen="$i18n{screenType}" - $i18n{dark}> + screen="$i18n{screenType}"> <head> <meta charset="utf-8"> <meta name="google" value="notranslate"> @@ -422,6 +421,5 @@ <include src="../../../../ui/login/account_picker/user_pod_template.html"> </user-manager-pages> <script src="user_manager.js"></script> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/welcome/dice_welcome/welcome.html b/chrome/browser/resources/welcome/dice_welcome/welcome.html index f9fc786..6ca16ab1 100644 --- a/chrome/browser/resources/welcome/dice_welcome/welcome.html +++ b/chrome/browser/resources/welcome/dice_welcome/welcome.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>$i18n{headerText}</title> @@ -17,6 +17,5 @@ <body> <welcome-app></welcome-app> <div class="watermark"></div> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/welcome.html b/chrome/browser/resources/welcome/onboarding_welcome/welcome.html index f6ceb5c..e2a37c5 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/welcome.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/welcome.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>$i18n{headerText}</title> @@ -17,7 +17,6 @@ </style> <welcome-app></welcome-app> <script src="/welcome.js"></script> - <link rel="import" href="chrome://resources/html/dark_mode.html"> <link rel="stylesheet" href="chrome://welcome/welcome.css"> </body> </html>
diff --git a/chrome/browser/resources/welcome/welcome.html b/chrome/browser/resources/welcome/welcome.html index 41b76d6..8f0474a 100644 --- a/chrome/browser/resources/welcome/welcome.html +++ b/chrome/browser/resources/welcome/welcome.html
@@ -1,5 +1,5 @@ <!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>$i18n{headerText}</title> @@ -240,6 +240,5 @@ <body> <welcome-app></welcome-app> <div class="watermark"></div> - <link rel="import" href="chrome://resources/html/dark_mode.html"> </body> </html>
diff --git a/chrome/browser/sessions/session_restore_stats_collector.cc b/chrome/browser/sessions/session_restore_stats_collector.cc index 7172f26..7ea3a86 100644 --- a/chrome/browser/sessions/session_restore_stats_collector.cc +++ b/chrome/browser/sessions/session_restore_stats_collector.cc
@@ -125,7 +125,8 @@ loading_tab_count_(0u), deferred_tab_count_(0u), tick_clock_(new base::DefaultTickClock()), - reporting_delegate_(std::move(reporting_delegate)) { + reporting_delegate_(std::move(reporting_delegate)), + observer_(this) { this_retainer_ = this; } @@ -351,8 +352,10 @@ void SessionRestoreStatsCollector::RenderWidgetHostDestroyed( content::RenderWidgetHost* widget_host) { auto* tab_state = GetTabState(widget_host); - if (tab_state) + if (tab_state) { + observer_.Remove(tab_state->observed_host); tab_state->observed_host = nullptr; + } } void SessionRestoreStatsCollector::RemoveTab(NavigationController* tab) { @@ -367,7 +370,7 @@ DCHECK(tab_it != tabs_tracked_.end()); TabState& tab_state = tab_it->second; if (tab_state.observed_host) - tab_state.observed_host->RemoveObserver(this); + observer_.Remove(tab_state.observed_host); // If this tab was waiting for a NOTIFICATION_LOAD_STOP event then update // the loading counts. @@ -419,7 +422,7 @@ // Register for RenderWidgetHostVisibilityChanged notifications for this tab. tab_state->observed_host = GetRenderWidgetHost(tab); if (tab_state->observed_host) - tab_state->observed_host->AddObserver(this); + observer_.Add(tab_state->observed_host); return tab_state; }
diff --git a/chrome/browser/sessions/session_restore_stats_collector.h b/chrome/browser/sessions/session_restore_stats_collector.h index 40c5e01..d75d443 100644 --- a/chrome/browser/sessions/session_restore_stats_collector.h +++ b/chrome/browser/sessions/session_restore_stats_collector.h
@@ -11,6 +11,7 @@ #include <utility> #include <vector> +#include "base//scoped_observer.h" #include "base/callback_list.h" #include "base/macros.h" #include "base/time/tick_clock.h" @@ -209,7 +210,7 @@ void RemoveTab(content::NavigationController* tab); // Registers for relevant notifications for a tab and inserts the tab into - // to tabs_tracked_ map. Return a pointer to the newly created TabState. + // to |tabs_tracked_| map. Return a pointer to the newly created TabState. TabState* RegisterForNotifications(content::NavigationController* tab); // Returns the tab state, nullptr if not found. @@ -281,6 +282,9 @@ // has deferred tabs remaining from an interrupted session restore. scoped_refptr<SessionRestoreStatsCollector> this_retainer_; + ScopedObserver<content::RenderWidgetHost, SessionRestoreStatsCollector> + observer_; + DISALLOW_COPY_AND_ASSIGN(SessionRestoreStatsCollector); };
diff --git a/chrome/browser/sharing/ack_message_handler.cc b/chrome/browser/sharing/ack_message_handler.cc new file mode 100644 index 0000000..2827123 --- /dev/null +++ b/chrome/browser/sharing/ack_message_handler.cc
@@ -0,0 +1,10 @@ +// 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. + +#include "chrome/browser/sharing/ack_message_handler.h" + +void AckMessageHandler::OnMessage( + const chrome_browser_sharing::SharingMessage& message) { + // TODO +}
diff --git a/chrome/browser/sharing/ack_message_handler.h b/chrome/browser/sharing/ack_message_handler.h new file mode 100644 index 0000000..6a4221f --- /dev/null +++ b/chrome/browser/sharing/ack_message_handler.h
@@ -0,0 +1,20 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHARING_ACK_MESSAGE_HANDLER_H_ +#define CHROME_BROWSER_SHARING_ACK_MESSAGE_HANDLER_H_ + +#include "base/macros.h" +#include "chrome/browser/sharing/sharing_message_handler.h" + +class AckMessageHandler : public SharingMessageHandler { + public: + void OnMessage( + const chrome_browser_sharing::SharingMessage& message) override; + + private: + DISALLOW_COPY_AND_ASSIGN(AckMessageHandler); +}; + +#endif // CHROME_BROWSER_SHARING_ACK_MESSAGE_HANDLER_H_
diff --git a/chrome/browser/sharing/proto/BUILD.gn b/chrome/browser/sharing/proto/BUILD.gn index 5971cdb..832182ad 100644 --- a/chrome/browser/sharing/proto/BUILD.gn +++ b/chrome/browser/sharing/proto/BUILD.gn
@@ -13,6 +13,7 @@ proto_library("proto") { sources = [ + "click_to_call_message.proto", "sharing_message.proto", ] }
diff --git a/chrome/browser/sharing/proto/click_to_call_message.proto b/chrome/browser/sharing/proto/click_to_call_message.proto new file mode 100644 index 0000000..3258af9a --- /dev/null +++ b/chrome/browser/sharing/proto/click_to_call_message.proto
@@ -0,0 +1,16 @@ +// 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. + +syntax = "proto3"; + +package chrome_browser_sharing; + +// Required in Chrome. +option optimize_for = LITE_RUNTIME; + +// Message to pass phone number in click to call feature. +message ClickToCallMessage { + // required + string phone_number = 1; +}
diff --git a/chrome/browser/sharing/proto/sharing_message.proto b/chrome/browser/sharing/proto/sharing_message.proto index 1fd254f..85437501 100644 --- a/chrome/browser/sharing/proto/sharing_message.proto +++ b/chrome/browser/sharing/proto/sharing_message.proto
@@ -4,6 +4,8 @@ syntax = "proto3"; +import "click_to_call_message.proto"; + package chrome_browser_sharing; // Required in Chrome. @@ -18,6 +20,7 @@ oneof payload { PingMessage ping_message = 2; AckMessage ack_message = 3; + ClickToCallMessage click_to_call_message = 4; } }
diff --git a/chrome/browser/sharing/sharing_fcm_handler.cc b/chrome/browser/sharing/sharing_fcm_handler.cc new file mode 100644 index 0000000..65f9b2f4 --- /dev/null +++ b/chrome/browser/sharing/sharing_fcm_handler.cc
@@ -0,0 +1,105 @@ +// 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. + +#include "chrome/browser/sharing/sharing_fcm_handler.h" + +#include "chrome/browser/sharing/sharing_fcm_sender.h" +#include "chrome/browser/sharing/sharing_message_handler.h" +#include "chrome/browser/sharing/sharing_service_factory.h" +#include "components/gcm_driver/gcm_driver.h" + +namespace { +const char kSharingFCMAppID[] = "com.google.chrome.sharing.fcm"; +} // namespace + +SharingFCMHandler::SharingFCMHandler(gcm::GCMDriver* gcm_driver, + SharingFCMSender* sharing_fcm_sender) + : gcm_driver_(gcm_driver), + sharing_fcm_sender_(sharing_fcm_sender), + weak_ptr_factory_(this) { + StartListening(); +} + +SharingFCMHandler::~SharingFCMHandler() { + StopListening(); +} + +void SharingFCMHandler::StartListening() { + gcm_driver_->AddAppHandler(kSharingFCMAppID, this); +} + +void SharingFCMHandler::StopListening() { + gcm_driver_->RemoveAppHandler(kSharingFCMAppID); +} + +void SharingFCMHandler::AddSharingHandler( + const SharingMessage::PayloadCase& payload_case, + SharingMessageHandler* handler) { + DCHECK(handler) << "Received request to add null handler"; + DCHECK(payload_case != SharingMessage::PAYLOAD_NOT_SET) + << "Incorrect payload type specified for handler"; + DCHECK(!sharing_handlers_.count(payload_case)) << "Handler already exists"; + + sharing_handlers_[payload_case] = handler; +} + +void SharingFCMHandler::RemoveSharingHandler( + const SharingMessage::PayloadCase& payload_case) { + sharing_handlers_.erase(payload_case); +} + +void SharingFCMHandler::OnMessagesDeleted(const std::string& app_id) { + NOTIMPLEMENTED(); +} + +void SharingFCMHandler::ShutdownHandler() { + NOTIMPLEMENTED(); +} + +void SharingFCMHandler::OnMessage(const std::string& app_id, + const gcm::IncomingMessage& message) { + SharingMessage sharing_message; + if (!sharing_message.ParseFromString(message.raw_data)) { + LOG(ERROR) << "Failed to parse incoming message with id : " + << message.message_id; + return; + } + DCHECK(sharing_message.payload_case() != SharingMessage::PAYLOAD_NOT_SET) + << "No payload set in SharingMessage received"; + + auto it = sharing_handlers_.find(sharing_message.payload_case()); + if (it == sharing_handlers_.end()) { + LOG(ERROR) << "No handler found for payload : " + << sharing_message.payload_case(); + } else { + it->second->OnMessage(sharing_message); + + if (sharing_message.payload_case() != SharingMessage::kAckMessage) + SendAckMessage(sharing_message.sender_guid(), message.message_id); + } +} + +void SharingFCMHandler::OnSendAcknowledged(const std::string& app_id, + const std::string& message_id) { + NOTIMPLEMENTED(); +} + +void SharingFCMHandler::OnSendError( + const std::string& app_id, + const gcm::GCMClient::SendErrorDetails& details) { + NOTIMPLEMENTED(); +} + +void SharingFCMHandler::OnStoreReset() { + NOTIMPLEMENTED(); +} + +bool SharingFCMHandler::SendAckMessage( + const std::string& original_sender_guid, + const std::string& original_message_id) const { + SharingMessage ack_message; + ack_message.mutable_ack_message()->set_original_message_id( + original_message_id); + return sharing_fcm_sender_->SendMessage(original_sender_guid, ack_message); +}
diff --git a/chrome/browser/sharing/sharing_fcm_handler.h b/chrome/browser/sharing/sharing_fcm_handler.h new file mode 100644 index 0000000..a234805 --- /dev/null +++ b/chrome/browser/sharing/sharing_fcm_handler.h
@@ -0,0 +1,83 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHARING_SHARING_FCM_HANDLER_H_ +#define CHROME_BROWSER_SHARING_SHARING_FCM_HANDLER_H_ + +#include <map> +#include <string> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/sharing/proto/sharing_message.pb.h" +#include "components/gcm_driver/gcm_app_handler.h" + +namespace gcm { +class GCMDriver; +} + +class SharingMessageHandler; + +class SharingFCMSender; + +// SharingFCMHandler is responsible for receiving SharingMessage from GCMDriver +// and delegate it to the payload specific handler. +class SharingFCMHandler : public gcm::GCMAppHandler { + using SharingMessage = chrome_browser_sharing::SharingMessage; + + public: + SharingFCMHandler(gcm::GCMDriver* gcm_driver, + SharingFCMSender* sharing_fcm_sender); + ~SharingFCMHandler() override; + + // Registers itself as app handler for sharing messages. + void StartListening(); + + // Unregisters itself as app handler for sharing messages. + void StopListening(); + + // Registers |handler| for handling |payload_case| SharingMessage. + void AddSharingHandler(const SharingMessage::PayloadCase& payload_case, + SharingMessageHandler* handler); + + // Removes SharingMessageHandler registered for |payload_case|. + void RemoveSharingHandler(const SharingMessage::PayloadCase& payload_case); + + // GCMAppHandler overrides. + void ShutdownHandler() override; + + void OnStoreReset() override; + + // Responsible for delegating the message to the registered + // SharingMessageHandler. Also sends back an ack to original sender after + // delegating the message. + void OnMessage(const std::string& app_id, + const gcm::IncomingMessage& message) override; + + void OnSendError(const std::string& app_id, + const gcm::GCMClient::SendErrorDetails& details) override; + + void OnSendAcknowledged(const std::string& app_id, + const std::string& message_id) override; + + void OnMessagesDeleted(const std::string& app_id) override; + + private: + // Ack message sent back to the original sender of message. + bool SendAckMessage(const std::string& original_sender_guid, + const std::string& original_message_id) const; + + gcm::GCMDriver* const gcm_driver_; + + SharingFCMSender* sharing_fcm_sender_; + + std::map<SharingMessage::PayloadCase, SharingMessageHandler*> + sharing_handlers_; + + base::WeakPtrFactory<SharingFCMHandler> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SharingFCMHandler); +}; + +#endif // CHROME_BROWSER_SHARING_SHARING_FCM_HANDLER_H_
diff --git a/chrome/browser/sharing/sharing_fcm_handler_unittest.cc b/chrome/browser/sharing/sharing_fcm_handler_unittest.cc new file mode 100644 index 0000000..cc232b2 --- /dev/null +++ b/chrome/browser/sharing/sharing_fcm_handler_unittest.cc
@@ -0,0 +1,131 @@ +// 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. + +#include "chrome/browser/sharing/sharing_fcm_handler.h" + +#include <memory> + +#include "chrome/browser/sharing/sharing_fcm_sender.h" +#include "chrome/browser/sharing/sharing_message_handler.h" +#include "components/gcm_driver/fake_gcm_driver.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using SharingMessage = chrome_browser_sharing::SharingMessage; +using namespace testing; + +namespace { + +const char kTestAppId[] = "test_app_id"; +const char kTestMessageId[] = "test_message_id"; +const char kOriginalMessageId[] = "test_original_message_id"; +const char kSenderGuid[] = "test_sender_guid"; + +class MockSharingMessageHandler : public SharingMessageHandler { + public: + MockSharingMessageHandler() {} + ~MockSharingMessageHandler() override {} + + MOCK_METHOD1(OnMessage, void(const SharingMessage& message)); +}; + +class MockSharingFCMSender : public SharingFCMSender { + public: + MockSharingFCMSender() {} + ~MockSharingFCMSender() override {} + + MOCK_METHOD2(SendMessage, + bool(const std::string& device_guid, + const SharingMessage& message)); +}; + +class SharingFCMHandlerTest : public Test { + protected: + SharingFCMHandlerTest() { + sharing_fcm_handler_.reset( + new SharingFCMHandler(&fake_gcm_driver_, &mock_sharing_fcm_sender_)); + } + + // Creates a gcm::IncomingMessage with SharingMessage and defaults. + gcm::IncomingMessage CreateGCMIncomingMessage( + const SharingMessage& sharing_message) { + gcm::IncomingMessage incoming_message; + incoming_message.raw_data = sharing_message.SerializeAsString(); + incoming_message.message_id = kTestMessageId; + return incoming_message; + } + + // Creates a SharingMessage with defaults. + SharingMessage CreateSharingMessage() { + SharingMessage sharing_message; + sharing_message.set_sender_guid(kSenderGuid); + return sharing_message; + } + + NiceMock<MockSharingMessageHandler> mock_sharing_message_handler_; + NiceMock<MockSharingFCMSender> mock_sharing_fcm_sender_; + + gcm::FakeGCMDriver fake_gcm_driver_; + std::unique_ptr<SharingFCMHandler> sharing_fcm_handler_; +}; + +} // namespace + +MATCHER_P(ProtoEquals, message, "") { + std::string expected_serialized, actual_serialized; + message.SerializeToString(&expected_serialized); + arg.SerializeToString(&actual_serialized); + return expected_serialized == actual_serialized; +} + +// Tests handling of SharingMessage with AckMessage payload. This is different +// from other payloads since we need to ensure AckMessage is not sent for +// SharingMessage with AckMessage payload. +TEST_F(SharingFCMHandlerTest, AckMessageHandler) { + SharingMessage sharing_message = CreateSharingMessage(); + sharing_message.mutable_ack_message()->set_original_message_id( + kOriginalMessageId); + gcm::IncomingMessage incoming_message = + CreateGCMIncomingMessage(sharing_message); + + EXPECT_CALL(mock_sharing_message_handler_, + OnMessage(ProtoEquals(sharing_message))); + EXPECT_CALL(mock_sharing_fcm_sender_, SendMessage(_, _)).Times(0); + sharing_fcm_handler_->AddSharingHandler(SharingMessage::kAckMessage, + &mock_sharing_message_handler_); + sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message); +} + +// Generic test for handling of SharingMessage payload other than AckMessage. +TEST_F(SharingFCMHandlerTest, PingMessageHandler) { + SharingMessage sharing_message = CreateSharingMessage(); + sharing_message.mutable_ping_message(); + gcm::IncomingMessage incoming_message = + CreateGCMIncomingMessage(sharing_message); + + SharingMessage sharing_ack_message; + sharing_ack_message.mutable_ack_message()->set_original_message_id( + incoming_message.message_id); + + // Tests OnMessage flow in SharingFCMHandler when no handler is registered. + EXPECT_CALL(mock_sharing_message_handler_, OnMessage(_)).Times(0); + EXPECT_CALL(mock_sharing_fcm_sender_, SendMessage(_, _)).Times(0); + sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message); + + // Tests OnMessage flow in SharingFCMHandler after handler is added. + EXPECT_CALL(mock_sharing_message_handler_, + OnMessage(ProtoEquals(sharing_message))); + EXPECT_CALL(mock_sharing_fcm_sender_, + SendMessage(Eq(kSenderGuid), ProtoEquals(sharing_ack_message))); + sharing_fcm_handler_->AddSharingHandler(SharingMessage::kPingMessage, + &mock_sharing_message_handler_); + sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message); + + // Tests OnMessage flow in SharingFCMHandler after registered handler is + // removed. + EXPECT_CALL(mock_sharing_message_handler_, OnMessage(_)).Times(0); + EXPECT_CALL(mock_sharing_fcm_sender_, SendMessage(_, _)).Times(0); + sharing_fcm_handler_->RemoveSharingHandler(SharingMessage::kPingMessage); + sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message); +}
diff --git a/chrome/browser/sharing/sharing_fcm_sender.cc b/chrome/browser/sharing/sharing_fcm_sender.cc new file mode 100644 index 0000000..e6f7b76 --- /dev/null +++ b/chrome/browser/sharing/sharing_fcm_sender.cc
@@ -0,0 +1,16 @@ +// 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. + +#include "chrome/browser/sharing/sharing_fcm_sender.h" + +SharingFCMSender::SharingFCMSender() = default; + +SharingFCMSender::~SharingFCMSender() = default; + +bool SharingFCMSender::SendMessage( + const std::string& device_guid, + const chrome_browser_sharing::SharingMessage& message) { + // TODO + return true; +}
diff --git a/chrome/browser/sharing/sharing_fcm_sender.h b/chrome/browser/sharing/sharing_fcm_sender.h new file mode 100644 index 0000000..e0a4e9a2 --- /dev/null +++ b/chrome/browser/sharing/sharing_fcm_sender.h
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHARING_SHARING_FCM_SENDER_H_ +#define CHROME_BROWSER_SHARING_SHARING_FCM_SENDER_H_ + +#include <string> + +#include "base/macros.h" +#include "chrome/browser/sharing/proto/sharing_message.pb.h" + +// Responsible for sending FCM messages within Sharing infrastructure. +class SharingFCMSender { + public: + SharingFCMSender(); + virtual ~SharingFCMSender(); + + // Sends a |message| to device identified by |device_guid|. + virtual bool SendMessage( + const std::string& device_guid, + const chrome_browser_sharing::SharingMessage& message); + + private: + DISALLOW_COPY_AND_ASSIGN(SharingFCMSender); +}; + +#endif // CHROME_BROWSER_SHARING_SHARING_FCM_SENDER_H_
diff --git a/chrome/browser/sharing/sharing_message_handler.h b/chrome/browser/sharing/sharing_message_handler.h index c089f5f..5617032 100644 --- a/chrome/browser/sharing/sharing_message_handler.h +++ b/chrome/browser/sharing/sharing_message_handler.h
@@ -7,17 +7,21 @@ #include <string> +#include "base/macros.h" #include "chrome/browser/sharing/proto/sharing_message.pb.h" // Interface for handling incoming SharingMessage. class SharingMessageHandler { public: - SharingMessageHandler(); - virtual ~SharingMessageHandler(); + SharingMessageHandler() = default; + virtual ~SharingMessageHandler() = default; // Called when a SharingMessage has been received. virtual void OnMessage( const chrome_browser_sharing::SharingMessage& message) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SharingMessageHandler); }; #endif // CHROME_BROWSER_SHARING_SHARING_MESSAGE_HANDLER_H_
diff --git a/chrome/browser/signin/identity_manager_factory.cc b/chrome/browser/signin/identity_manager_factory.cc index 7281e00..c74c68e 100644 --- a/chrome/browser/signin/identity_manager_factory.cc +++ b/chrome/browser/signin/identity_manager_factory.cc
@@ -22,6 +22,7 @@ #include "components/signin/core/browser/identity_manager_wrapper.h" #include "components/signin/core/browser/primary_account_manager.h" #include "components/signin/core/browser/primary_account_policy_manager_impl.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_client.h" #include "services/identity/public/cpp/accounts_cookie_mutator.h" #include "services/identity/public/cpp/accounts_cookie_mutator_impl.h" @@ -29,10 +30,7 @@ #include "services/identity/public/cpp/diagnostics_provider_impl.h" #include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/primary_account_mutator.h" - -#if !defined(OS_CHROMEOS) #include "services/identity/public/cpp/primary_account_mutator_impl.h" -#endif #if !defined(OS_ANDROID) #include "chrome/browser/web_data_service_factory.h" @@ -42,21 +40,6 @@ namespace { -// Helper function returning a newly constructed PrimaryAccountMutator for -// |profile|. May return null if mutation of the signed-in state is not -// supported on the current platform. -std::unique_ptr<identity::PrimaryAccountMutator> BuildPrimaryAccountMutator( - Profile* profile, - AccountTrackerService* account_tracker_service, - PrimaryAccountManager* primary_account_manager) { -#if !defined(OS_CHROMEOS) - return std::make_unique<identity::PrimaryAccountMutatorImpl>( - account_tracker_service, primary_account_manager, profile->GetPrefs()); -#else - return nullptr; -#endif -} - // Helper function returning a newly constructed AccountsMutator for // |profile|. May return null if mutation of accounts is not supported on the // current platform. @@ -187,8 +170,9 @@ token_service.get()); std::unique_ptr<identity::PrimaryAccountMutator> primary_account_mutator = - BuildPrimaryAccountMutator(profile, account_tracker_service.get(), - primary_account_manager.get()); + std::make_unique<identity::PrimaryAccountMutatorImpl>( + account_tracker_service.get(), primary_account_manager.get(), + profile->GetPrefs()); std::unique_ptr<identity::AccountsMutator> accounts_mutator = BuildAccountsMutator(profile, account_tracker_service.get(),
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index ed529c07a..ece6553 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -896,6 +896,10 @@ "global_error/global_error_service.h", "global_error/global_error_service_factory.cc", "global_error/global_error_service_factory.h", + "global_media_controls/media_toolbar_button_controller.cc", + "global_media_controls/media_toolbar_button_controller.h", + "global_media_controls/media_toolbar_button_controller_delegate.cc", + "global_media_controls/media_toolbar_button_controller_delegate.h", "hats/hats_helper.cc", "hats/hats_helper.h", "hats/hats_service.cc", @@ -1158,8 +1162,6 @@ "webui/chrome_web_contents_handler.h", "webui/constrained_web_dialog_delegate_base.cc", "webui/constrained_web_dialog_delegate_base.h", - "webui/dark_mode_handler.cc", - "webui/dark_mode_handler.h", "webui/devtools_ui.cc", "webui/devtools_ui.h", "webui/downloads/downloads_dom_handler.cc", @@ -1847,6 +1849,7 @@ "//chrome/browser/chromeos/supervision/mojom", "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings", "//chrome/browser/ui/webui/chromeos/machine_learning:mojo_bindings", + "//chrome/services/file_util/public/cpp", "//chromeos", "//chromeos/assistant:buildflags", "//chromeos/audio", @@ -2713,6 +2716,8 @@ "views/fullscreen_control/fullscreen_control_view.h", "views/global_error_bubble_view.cc", "views/global_error_bubble_view.h", + "views/global_media_controls/media_toolbar_button_view.cc", + "views/global_media_controls/media_toolbar_button_view.h", "views/hover_button.cc", "views/hover_button.h", "views/hung_renderer_view.cc", @@ -3083,6 +3088,7 @@ "//components/payments/core", "//components/ui_devtools/views", "//device/vr/buildflags:buildflags", + "//services/media_session/public/mojom", "//ui/views:buildflags", ]
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc index 0dd2b41..3a3175d 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/files/scoped_temp_dir.h" #include "base/strings/string_number_conversions.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" @@ -16,6 +17,7 @@ #include "chrome/browser/ui/app_list/chrome_app_list_item.h" #include "chrome/browser/ui/app_list/page_break_constants.h" #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" +#include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "components/crx_file/id_util.h" @@ -426,7 +428,20 @@ EXPECT_FALSE(GetSyncItem(app_list::kDefaultPageBreak1)); } -TEST_F(AppListSyncableServiceTest, ExistingDefaultPageBreak) { +class AppListInternalAppSyncableServiceTest + : public AppListSyncableServiceTest { + public: + AppListInternalAppSyncableServiceTest() { + // Disable System Web Apps so the Settings Internal App is still installed. + scoped_feature_list_.InitAndDisableFeature(features::kSystemWebApps); + } + ~AppListInternalAppSyncableServiceTest() override = default; + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(AppListInternalAppSyncableServiceTest, ExistingDefaultPageBreak) { // Non-first time users have items in their remote sync data. syncer::SyncDataList sync_list; sync_list.push_back(CreateAppRemoteData( @@ -452,7 +467,7 @@ page_break_sync_item->item_pin_ordinal.ToDebugString()); } -TEST_F(AppListSyncableServiceTest, DefaultPageBreakFirstTimeUser) { +TEST_F(AppListInternalAppSyncableServiceTest, DefaultPageBreakFirstTimeUser) { // Empty sync list simulates a first time user. syncer::SyncDataList sync_list;
diff --git a/chrome/browser/ui/app_list/extension_app_utils.cc b/chrome/browser/ui/app_list/extension_app_utils.cc index 002ddce..9affea2 100644 --- a/chrome/browser/ui/app_list/extension_app_utils.cc +++ b/chrome/browser/ui/app_list/extension_app_utils.cc
@@ -16,11 +16,6 @@ #include "ui/views/controls/menu/menu_config.h" #include "ui/views/vector_icons.h" -#if defined(OS_CHROMEOS) -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/web_applications/system_web_app_ui_utils_chromeos.h" -#endif - namespace app_list { namespace { @@ -32,26 +27,6 @@ bool ShouldShowInLauncher(const extensions::Extension* extension, content::BrowserContext* context) { - // TODO(crbug.com/971029): Make this a per System Web App property that is - // accessible by querying the SystemWebAppManager. -#if defined(OS_CHROMEOS) - Profile* profile = Profile::FromBrowserContext(context); - // These System Web Apps should not show in the launcher as they are added - // as internal apps. - web_app::SystemAppType hidden_system_web_apps[] = { - // TODO(crbug.com/836128): Remove this once OS Settings is launched, and - // permanently migrate OS Settings from an internal app to a full System - // Web App. - web_app::SystemAppType::SETTINGS, - }; - for (auto app_type : hidden_system_web_apps) { - if (extension->id() == - web_app::GetAppIdForSystemWebApp(profile, app_type)) { - return false; - } - } -#endif - return !HideInLauncherById(extension->id()) && chromeos::DemoSession::ShouldDisplayInAppLauncher(extension->id()) && extensions::ui_util::ShouldDisplayInAppLauncher(extension, context);
diff --git a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc index fd29643..b712f71 100644 --- a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc +++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/webui/chromeos/login/discover/discover_window_manager.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/generated_resources.h" #include "chromeos/constants/chromeos_features.h" @@ -66,13 +67,6 @@ InternalAppName::kKeyboardShortcutViewer, IDS_LAUNCHER_SEARCHABLE_KEYBOARD_SHORTCUT_VIEWER}, - {kInternalAppIdSettings, IDS_INTERNAL_APP_SETTINGS, - IDR_SETTINGS_LOGO_192, - /*recommendable=*/true, - /*searchable=*/true, - /*show_in_launcher=*/true, InternalAppName::kSettings, - /*searchable_string_resource_id=*/0}, - {kInternalAppIdContinueReading, IDS_INTERNAL_APP_CONTINUOUS_READING, IDR_PRODUCT_LOGO_256, /*recommendable=*/true, @@ -109,6 +103,16 @@ /*searchable_string_resource_id=*/IDS_INTERNAL_APP_DISCOVER}); } + if (!web_app::SystemWebAppManager::IsEnabled()) { + internal_app_list->push_back( + {kInternalAppIdSettings, IDS_INTERNAL_APP_SETTINGS, + IDR_SETTINGS_LOGO_192, + /*recommendable=*/true, + /*searchable=*/true, + /*show_in_launcher=*/true, InternalAppName::kSettings, + /*searchable_string_resource_id=*/0}); + } + if (get_all || plugin_vm::IsPluginVmAllowedForProfile(profile)) { internal_app_list->push_back( {plugin_vm::kPluginVmAppId, IDS_PLUGIN_VM_APP_NAME,
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc index baaa88f..901ac576 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc
@@ -36,7 +36,7 @@ constexpr char kLogFileOpenType[] = "RecurrenceRanker.LogFileOpenType"; // Represents each model used within the SearchResultRanker. -enum class Model { NONE, RESULTS_LIST_GROUP_RANKER }; +enum class Model { NONE, MIXED_TYPES }; // Returns the model relevant for predicting launches for results with the given // |type|. @@ -48,7 +48,7 @@ case RankingItemType::kOmniboxDocument: case RankingItemType::kOmniboxHistory: case RankingItemType::kOmniboxSearch: - return Model::RESULTS_LIST_GROUP_RANKER; + return Model::MIXED_TYPES; default: return Model::NONE; } @@ -87,35 +87,45 @@ : enable_zero_state_mixed_types_( app_list_features::IsZeroStateMixedTypesRankerEnabled()) { if (app_list_features::IsQueryBasedMixedTypesRankerEnabled()) { + results_list_boost_coefficient_ = base::GetFieldTrialParamByFeatureAsDouble( + app_list_features::kEnableQueryBasedMixedTypesRanker, + "boost_coefficient", 0.1); + RecurrenceRankerConfigProto config; + config.set_min_seconds_between_saves(240u); config.set_condition_limit(0u); config.set_condition_decay(0.5f); - config.set_target_limit(base::GetFieldTrialParamByFeatureAsInt( app_list_features::kEnableQueryBasedMixedTypesRanker, "target_limit", 200)); config.set_target_decay(base::GetFieldTrialParamByFeatureAsDouble( app_list_features::kEnableQueryBasedMixedTypesRanker, "target_decay", 0.8f)); - + // TODO(931149): Replace this with a more sophisticated model if the + // query-based mixed type model is being used. config.mutable_default_predictor(); - results_list_group_ranker_ = std::make_unique<RecurrenceRanker>( - profile->GetPath().AppendASCII("adaptive_result_ranker.proto"), config, - chromeos::ProfileHelper::IsEphemeralUserProfile(profile)); - - results_list_boost_coefficient_ = base::GetFieldTrialParamByFeatureAsDouble( - app_list_features::kEnableQueryBasedMixedTypesRanker, - "boost_coefficient", 0.1); + if (GetFieldTrialParamByFeatureAsBool( + app_list_features::kEnableQueryBasedMixedTypesRanker, + "use_category_model", false)) { + results_list_group_ranker_ = std::make_unique<RecurrenceRanker>( + profile->GetPath().AppendASCII("results_list_group_ranker.pb"), + config, chromeos::ProfileHelper::IsEphemeralUserProfile(profile)); + } else { + query_based_mixed_types_ranker_ = std::make_unique<RecurrenceRanker>( + profile->GetPath().AppendASCII("query_based_mixed_types_ranker.pb"), + config, chromeos::ProfileHelper::IsEphemeralUserProfile(profile)); + } } - profile_ = profile; + profile_ = profile; if (auto* notifier = file_manager::file_tasks::FileTasksNotifier::GetForProfile( profile_)) { notifier->AddObserver(this); } + if (enable_zero_state_mixed_types_) { RecurrenceRankerConfigProto config; config.set_min_seconds_between_saves(240u); @@ -162,6 +172,9 @@ if (results_list_group_ranker_) { group_ranks_.clear(); group_ranks_ = results_list_group_ranker_->Rank(); + } else if (query_based_mixed_types_ranker_) { + query_mixed_ranks_.clear(); + query_mixed_ranks_ = query_based_mixed_types_ranker_->Rank(); } } @@ -170,35 +183,46 @@ return; for (auto& result : *results) { - const RankingItemType& type = - RankingItemTypeFromSearchResult(*result.result); - const Model& model = ModelForType(type); + const auto& type = RankingItemTypeFromSearchResult(*result.result); + const auto& model = ModelForType(type); - if (model == Model::RESULTS_LIST_GROUP_RANKER && - results_list_group_ranker_) { - const auto& rank_it = - group_ranks_.find(base::NumberToString(static_cast<int>(type))); - // The ranker only contains entries trained with types relating to files - // or the omnibox. This means scores for apps, app shortcuts, and answer - // cards will be unchanged. - if (rank_it != group_ranks_.end()) { - // Ranker scores are guaranteed to be in [0,1]. But, enforce that the - // result of tweaking does not put the score above 3.0, as that may - // interfere with apps or answer cards. - result.score = std::min( - result.score + rank_it->second * results_list_boost_coefficient_, - 3.0); + if (model == Model::MIXED_TYPES) { + if (results_list_group_ranker_) { + const auto& rank_it = + group_ranks_.find(base::NumberToString(static_cast<int>(type))); + // The ranker only contains entries trained with types relating to files + // or the omnibox. This means scores for apps, app shortcuts, and answer + // cards will be unchanged. + if (rank_it != group_ranks_.end()) { + // Ranker scores are guaranteed to be in [0,1]. But, enforce that the + // result of tweaking does not put the score above 3.0, as that may + // interfere with apps or answer cards. + result.score = std::min( + result.score + rank_it->second * results_list_boost_coefficient_, + 3.0); + } + } else if (query_based_mixed_types_ranker_) { + // TODO(931149): Add some normalization for URLs. + const auto& rank_it = query_mixed_ranks_.find(result.result->id()); + if (rank_it != query_mixed_ranks_.end()) { + result.score = std::min( + result.score + rank_it->second * results_list_boost_coefficient_, + 3.0); + } } } } } void SearchResultRanker::Train(const std::string& id, RankingItemType type) { - const Model& model = ModelForType(type); - - if (model == Model::RESULTS_LIST_GROUP_RANKER && results_list_group_ranker_) { - results_list_group_ranker_->Record( - base::NumberToString(static_cast<int>(type))); + if (ModelForType(type) == Model::MIXED_TYPES) { + // TODO(931149): Add some normalization for URLs. + if (results_list_group_ranker_) { + results_list_group_ranker_->Record( + base::NumberToString(static_cast<int>(type))); + } else if (query_based_mixed_types_ranker_) { + query_based_mixed_types_ranker_->Record(id); + } } }
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h index 17d8ea42..95f109d 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h
@@ -69,11 +69,21 @@ // Stores the scores produced by |results_list_group_ranker_|. base::flat_map<std::string, float> group_ranks_; + // Stores the scores produced by |query_based_mixed_types_ranker|. + base::flat_map<std::string, float> query_mixed_ranks_; + + // The |results_list_group_ranker_| and |query_based_mixed_types_ranker_| are + // models for two different experiments. Only one will be constructed. + // A model that ranks groups (eg. 'file' and 'omnibox'), which is used to // tweak the results shown in the search results list only. This does not // affect apps. std::unique_ptr<RecurrenceRanker> results_list_group_ranker_; + // Ranks items shown in the results list after a search query. Currently + // these are local files and omnibox results. + std::unique_ptr<RecurrenceRanker> query_based_mixed_types_ranker_; + // Ranks files and previous queries for launcher zero-state. std::unique_ptr<RecurrenceRanker> zero_state_mixed_types_ranker_;
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc index a724605..41578438 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc
@@ -89,14 +89,14 @@ } std::unique_ptr<SearchResultRanker> MakeRanker( - bool use_group_ranker, + bool query_based_mixed_types_enabled, const std::map<std::string, std::string>& params = {}) { - if (use_group_ranker) { + if (query_based_mixed_types_enabled) { scoped_feature_list_.InitAndEnableFeatureWithParameters( app_list_features::kEnableQueryBasedMixedTypesRanker, params); } else { - scoped_feature_list_.InitWithFeatures( - {}, {app_list_features::kEnableQueryBasedMixedTypesRanker}); + scoped_feature_list_.InitAndDisableFeature( + app_list_features::kEnableQueryBasedMixedTypesRanker); } auto ranker = std::make_unique<SearchResultRanker>(profile_.get()); @@ -132,7 +132,7 @@ DISALLOW_COPY_AND_ASSIGN(SearchResultRankerTest); }; -TEST_F(SearchResultRankerTest, GroupRankerIsDisabledWithFlag) { +TEST_F(SearchResultRankerTest, MixedTypesRankersAreDisabledWithFlag) { auto ranker = MakeRanker(false); for (int i = 0; i < 20; ++i) ranker->Train("unused", RankingItemType::kFile); @@ -150,8 +150,9 @@ HasId("C"), HasId("D")))); } -TEST_F(SearchResultRankerTest, GroupRankerImprovesScores) { - auto ranker = MakeRanker(true, {{"boost_coefficient", "1.0"}}); +TEST_F(SearchResultRankerTest, CategoryModelImprovesScores) { + auto ranker = MakeRanker( + true, {{"use_category_model", "true"}, {"boost_coefficient", "1.0"}}); for (int i = 0; i < 20; ++i) ranker->Train("unused", RankingItemType::kFile); ranker->FetchRankings(base::string16()); @@ -167,5 +168,28 @@ HasId("B"), HasId("A")))); } +TEST_F(SearchResultRankerTest, ItemModelImprovesScores) { + // Without the |use_category_model| parameter, the ranker defaults to the item + // model. + auto ranker = MakeRanker(true, {{"boost_coefficient", "1.0"}}); + + for (int i = 0; i < 10; ++i) { + ranker->Train("C", RankingItemType::kFile); + ranker->Train("D", RankingItemType::kFile); + } + ranker->FetchRankings(base::string16()); + + // The types associated with these results don't match what was trained on, + // to check that the type is irrelevant to the item model. + auto results = MakeSearchResults({"A", "B", "C", "D"}, + {ResultType::kOmnibox, ResultType::kOmnibox, + ResultType::kOmnibox, ResultType::kOmnibox}, + {0.3f, 0.2f, 0.1f, 0.1f}); + + ranker->Rank(&results); + EXPECT_THAT(results, WhenSorted(ElementsAre(HasId("D"), HasId("C"), + HasId("A"), HasId("B")))); +} + } // namespace test } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc index 88b74dc..99254c5 100644 --- a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
@@ -105,7 +105,10 @@ class AppSearchProviderTest : public AppListTestBase { public: - AppSearchProviderTest() {} + AppSearchProviderTest() { + // Disable System Web Apps so the Settings Internal App is still installed. + scoped_feature_list_.InitAndDisableFeature(features::kSystemWebApps); + } ~AppSearchProviderTest() override {} // AppListTestBase overrides: @@ -227,6 +230,7 @@ private: base::SimpleTestClock clock_; base::ScopedTempDir temp_dir_; + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<FakeAppListModelUpdater> model_updater_; std::unique_ptr<AppSearchProvider> app_search_; std::unique_ptr<::test::TestAppListControllerDelegate> controller_;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index 87a16ab..b72c3f5f 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -4276,7 +4276,7 @@ InitLauncherController(); // Only test the first internal app. The others should be the same. - const auto& internal_app = app_list::GetInternalAppList(profile()).front(); + const auto internal_app = app_list::GetInternalAppList(profile()).front(); std::string app_id; ash::ShelfID shelf_id; EXPECT_FALSE(launcher_controller_->GetItem(shelf_id));
diff --git a/chrome/browser/ui/ash/network/enrollment_dialog_view.cc b/chrome/browser/ui/ash/network/enrollment_dialog_view.cc index 0f723cb..4e54afb 100644 --- a/chrome/browser/ui/ash/network/enrollment_dialog_view.cc +++ b/chrome/browser/ui/ash/network/enrollment_dialog_view.cc
@@ -155,7 +155,7 @@ void EnrollmentDialogView::InitDialog() { added_cert_ = false; // Create the views and layout manager and set them up. - views::Label* label = new views::Label( + auto label = std::make_unique<views::Label>( l10n_util::GetStringFUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_INSTRUCTIONS, base::UTF8ToUTF16(network_name_))); label->SetHorizontalAlignment(gfx::ALIGN_LEFT); @@ -187,7 +187,7 @@ 0); // Minimum size. grid_layout->StartRow(views::GridLayout::kFixedSize, 0); - grid_layout->AddView(label); + grid_layout->AddView(std::move(label)); grid_layout->AddPaddingRow( views::GridLayout::kFixedSize, provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index eb01cab..50b2b45e 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1096,7 +1096,7 @@ bool Browser::CanOverscrollContent() const { #if defined(USE_AURA) - return !is_app() && is_type_tabbed() && + return !is_devtools() && base::FeatureList::IsEnabled(features::kOverscrollHistoryNavigation); #else return false;
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 349ebf0..29916d8 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -1225,6 +1225,25 @@ EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count()); } +IN_PROC_BROWSER_TEST_F(BrowserTest, OverscrollEnabledInRegularWindows) { + ASSERT_TRUE(browser()->is_type_tabbed()); + EXPECT_TRUE(browser()->CanOverscrollContent()); +} + +IN_PROC_BROWSER_TEST_F(BrowserTest, OverscrollEnabledInPopups) { + Browser* popup_browser = new Browser( + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); + ASSERT_TRUE(popup_browser->is_type_popup()); + EXPECT_TRUE(popup_browser->CanOverscrollContent()); +} + +IN_PROC_BROWSER_TEST_F(BrowserTest, OverscrollDisabledInDevToolsWindows) { + DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), false); + Browser* dev_tools_browser = chrome::FindLastActive(); + ASSERT_EQ(dev_tools_browser->app_name(), DevToolsWindow::kDevToolsApp); + EXPECT_FALSE(dev_tools_browser->CanOverscrollContent()); +} + // Open an app window and the dev tools window and ensure that the location // bar settings are correct. IN_PROC_BROWSER_TEST_F(BrowserTest, ShouldShowLocationBar) {
diff --git a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm index c386235..8d976fc 100644 --- a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm +++ b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm
@@ -64,16 +64,12 @@ // TODO(erikchen): Detect symbolic hot keys, and force control to be passed // back to AppKit so that it can handle it correctly. // https://crbug.com/846893. - auto* bridge = - remote_cocoa::NativeWidgetNSWindowBridge::GetFromNativeWindow(window); NSResponder* responder = [window firstResponder]; if ([responder conformsToProtocol:@protocol(CommandDispatcherTarget)]) { NSObject<CommandDispatcherTarget>* target = static_cast<NSObject<CommandDispatcherTarget>*>(responder); if ([target isKeyLocked:event]) { - if (bridge) - bridge->SaveKeyEventForRedispatch(event); return ui::PerformKeyEquivalentResult::kUnhandled; } } @@ -99,6 +95,8 @@ // highlighting of the NSMenu. CommandForKeyEventResult result = CommandForKeyEvent(event); if (result.found()) { + auto* bridge = + remote_cocoa::NativeWidgetNSWindowBridge::GetFromNativeWindow(window); if (bridge) { bool was_executed = false; bridge->host()->ExecuteCommand( @@ -109,8 +107,6 @@ } } - if (bridge) - bridge->SaveKeyEventForRedispatch(event); return ui::PerformKeyEquivalentResult::kUnhandled; }
diff --git a/chrome/browser/ui/cocoa/main_menu_builder.mm b/chrome/browser/ui/cocoa/main_menu_builder.mm index 37e3ea73..ba20044 100644 --- a/chrome/browser/ui/cocoa/main_menu_builder.mm +++ b/chrome/browser/ui/cocoa/main_menu_builder.mm
@@ -115,9 +115,7 @@ Item(IDS_CLOSE_TAB_MAC) .command_id(IDC_CLOSE_TAB) .remove_if(is_pwa), - Item(IDS_SAVE_PAGE_MAC) - .command_id(IDC_SAVE_PAGE) - .remove_if(is_pwa), + Item(IDS_SAVE_PAGE_MAC).command_id(IDC_SAVE_PAGE), Item().is_separator().remove_if(is_pwa), Item(IDS_SHARE_MAC).remove_if(is_pwa), Item().is_separator(), Item(IDS_PRINT).command_id(IDC_PRINT),
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index ac96d4b..e9ff6da 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -1459,6 +1459,12 @@ base::UTF8ToUTF16("Install Manifest test app\xE2\x80\xA6")); } +IN_PROC_BROWSER_TEST_P(HostedAppPWAOnlyTest, OverscrollEnabled) { + ASSERT_TRUE(https_server()->Start()); + InstallSecurePWA(); + EXPECT_TRUE(app_browser_->CanOverscrollContent()); +} + // Tests that mixed content is not loaded inside PWA windows. IN_PROC_BROWSER_TEST_P(HostedAppPWAOnlyTest, MixedContentInPWA) { ASSERT_TRUE(https_server()->Start());
diff --git a/chrome/browser/ui/global_media_controls/OWNERS b/chrome/browser/ui/global_media_controls/OWNERS new file mode 100644 index 0000000..c48e48e --- /dev/null +++ b/chrome/browser/ui/global_media_controls/OWNERS
@@ -0,0 +1 @@ +steimel@chromium.org
diff --git a/chrome/browser/ui/global_media_controls/media_toolbar_button_controller.cc b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller.cc new file mode 100644 index 0000000..27ab3ec0 --- /dev/null +++ b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller.cc
@@ -0,0 +1,49 @@ +// 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. + +#include "chrome/browser/ui/global_media_controls/media_toolbar_button_controller.h" + +#include "chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.h" +#include "services/media_session/public/mojom/constants.mojom.h" +#include "services/media_session/public/mojom/media_session.mojom.h" +#include "services/service_manager/public/cpp/connector.h" + +MediaToolbarButtonController::MediaToolbarButtonController( + service_manager::Connector* connector, + MediaToolbarButtonControllerDelegate* delegate) + : connector_(connector), delegate_(delegate) { + DCHECK(delegate_); + + // |connector| can be null in tests. + if (!connector_) + return; + + // Connect to the MediaControllerManager and create a MediaController that + // controls the active session so we can observe it. + media_session::mojom::MediaControllerManagerPtr controller_manager_ptr; + connector_->BindInterface(media_session::mojom::kServiceName, + mojo::MakeRequest(&controller_manager_ptr)); + controller_manager_ptr->CreateActiveMediaController( + mojo::MakeRequest(&media_controller_ptr_)); + + // Observe the active media controller for changes to playback state and + // supported actions. + media_session::mojom::MediaControllerObserverPtr media_controller_observer; + media_controller_observer_binding_.Bind( + mojo::MakeRequest(&media_controller_observer)); + media_controller_ptr_->AddObserver(std::move(media_controller_observer)); +} + +MediaToolbarButtonController::~MediaToolbarButtonController() = default; + +void MediaToolbarButtonController::MediaSessionInfoChanged( + media_session::mojom::MediaSessionInfoPtr session_info) { + if (session_info) { + // We only want to show if there's a controllable media session. However, as + // a MediaControllerObserver we should only receive a + // |MediaSessionInfoChanged()| call for a controllable session. + DCHECK(session_info->is_controllable); + delegate_->Show(); + } +}
diff --git a/chrome/browser/ui/global_media_controls/media_toolbar_button_controller.h b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller.h new file mode 100644 index 0000000..18206c9 --- /dev/null +++ b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller.h
@@ -0,0 +1,52 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_CONTROLLER_H_ +#define CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_CONTROLLER_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/media_session/public/mojom/media_controller.mojom.h" + +namespace service_manager { +class Connector; +} // namespace service_manager + +class MediaToolbarButtonControllerDelegate; + +// Controller for the MediaToolbarButtonView that decides when to show or hide +// the icon from the toolbar. +class MediaToolbarButtonController + : public media_session::mojom::MediaControllerObserver { + public: + MediaToolbarButtonController(service_manager::Connector* connector, + MediaToolbarButtonControllerDelegate* delegate); + ~MediaToolbarButtonController() override; + + // media_session::mojom::MediaControllerObserver implementation. + void MediaSessionInfoChanged( + media_session::mojom::MediaSessionInfoPtr session_info) override; + void MediaSessionMetadataChanged( + const base::Optional<media_session::MediaMetadata>& metadata) override {} + void MediaSessionActionsChanged( + const std::vector<media_session::mojom::MediaSessionAction>& actions) + override {} + void MediaSessionChanged( + const base::Optional<base::UnguessableToken>& request_id) override {} + + private: + service_manager::Connector* const connector_; + MediaToolbarButtonControllerDelegate* const delegate_; + + // Tracks current media session state/metadata. + media_session::mojom::MediaControllerPtr media_controller_ptr_; + + // Used to receive updates to the active media controller. + mojo::Binding<media_session::mojom::MediaControllerObserver> + media_controller_observer_binding_{this}; + + DISALLOW_COPY_AND_ASSIGN(MediaToolbarButtonController); +}; + +#endif // CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_CONTROLLER_H_
diff --git a/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.cc b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.cc new file mode 100644 index 0000000..1229ee5 --- /dev/null +++ b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.cc
@@ -0,0 +1,8 @@ +// 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. + +#include "chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.h" + +MediaToolbarButtonControllerDelegate::~MediaToolbarButtonControllerDelegate() = + default;
diff --git a/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.h b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.h new file mode 100644 index 0000000..caa71613 --- /dev/null +++ b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.h
@@ -0,0 +1,18 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_CONTROLLER_DELEGATE_H_ +#define CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_CONTROLLER_DELEGATE_H_ + +// Delegate for MediaToolbarButtonController that is told when to show by the +// controller. +class MediaToolbarButtonControllerDelegate { + public: + virtual void Show() = 0; + + protected: + virtual ~MediaToolbarButtonControllerDelegate(); +}; + +#endif // CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_CONTROLLER_DELEGATE_H_
diff --git a/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc new file mode 100644 index 0000000..62838e4 --- /dev/null +++ b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc
@@ -0,0 +1,60 @@ +// 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. + +#include "chrome/browser/ui/global_media_controls/media_toolbar_button_controller.h" + +#include <memory> + +#include "chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.h" +#include "services/media_session/public/mojom/media_session.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using media_session::mojom::MediaSessionInfo; +using media_session::mojom::MediaSessionInfoPtr; + +namespace { + +class MockMediaToolbarButtonControllerDelegate + : public MediaToolbarButtonControllerDelegate { + public: + MockMediaToolbarButtonControllerDelegate() = default; + ~MockMediaToolbarButtonControllerDelegate() override = default; + + // MediaToolbarButtonControllerDelegate implementation. + MOCK_METHOD0(Show, void()); +}; + +} // anonymous namespace + +class MediaToolbarButtonControllerTest : public testing::Test { + public: + MediaToolbarButtonControllerTest() = default; + ~MediaToolbarButtonControllerTest() override = default; + + void SetUp() override { + controller_ = + std::make_unique<MediaToolbarButtonController>(nullptr, &delegate_); + } + + protected: + void SimulatePlayingControllableMedia() { + MediaSessionInfoPtr session_info(MediaSessionInfo::New()); + session_info->is_controllable = true; + controller_->MediaSessionInfoChanged(std::move(session_info)); + } + + MockMediaToolbarButtonControllerDelegate& delegate() { return delegate_; } + + private: + std::unique_ptr<MediaToolbarButtonController> controller_; + MockMediaToolbarButtonControllerDelegate delegate_; + + DISALLOW_COPY_AND_ASSIGN(MediaToolbarButtonControllerTest); +}; + +TEST_F(MediaToolbarButtonControllerTest, CallsShowForControllableMedia) { + EXPECT_CALL(delegate(), Show()); + SimulatePlayingControllableMedia(); +}
diff --git a/chrome/browser/ui/search/local_ntp_js_browsertest.cc b/chrome/browser/ui/search/local_ntp_js_browsertest.cc index b639240..09245a8 100644 --- a/chrome/browser/ui/search/local_ntp_js_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_js_browsertest.cc
@@ -7,6 +7,7 @@ #include "build/build_config.h" #include "chrome/browser/search/search.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/search/instant_test_utils.h" #include "chrome/browser/ui/search/local_ntp_test_utils.h" #include "chrome/common/url_constants.h" @@ -62,21 +63,16 @@ EXPECT_TRUE(success); } -// TODO(crbug.com/971853): renable the windows on Windows when flakiness is -// resolved. -#if defined(OS_WIN) -#define MAYBE_CustomBackgroundsTests DISABLED_CustomBackgroundsTests -#else -#define MAYBE_CustomBackgroundsTests CustomBackgroundsTests -#endif - // This runs a bunch of pure JS-side tests for custom backgrounds, i.e. those // that don't require any interaction from the native side. -IN_PROC_BROWSER_TEST_F(LocalNTPJavascriptTest, MAYBE_CustomBackgroundsTests) { +IN_PROC_BROWSER_TEST_F(LocalNTPJavascriptTest, CustomBackgroundsTests) { content::WebContents* active_tab = local_ntp_test_utils::OpenNewTab( browser(), GURL(chrome::kChromeUINewTabURL)); ASSERT_TRUE(search::IsInstantNTP(active_tab)); + // Ensure the window is big enough the the customize button is visible. + browser()->window()->SetBounds(gfx::Rect(0, 0, 1000, 1000)); + // Run the tests. bool success = false; ASSERT_TRUE(instant_test_utils::GetBoolFromJS(
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index f2d0153..15671385 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -792,7 +792,8 @@ return; is_selected_ = is_selected; - NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); + if (is_selected) + NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); RefreshStyle(); }
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc index 031181b1..d7bba80 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc
@@ -19,6 +19,8 @@ #include "ui/accessibility/ax_node_data.h" #include "ui/events/base_event_utils.h" #include "ui/events/test/event_generator.h" +#include "ui/views/accessibility/ax_event_manager.h" +#include "ui/views/accessibility/ax_event_observer.h" #include "ui/views/widget/widget_utils.h" namespace { @@ -44,6 +46,28 @@ {autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY, 1}, }; +class TestAXEventObserver : public views::AXEventObserver { + public: + TestAXEventObserver() : selection_event_count_(0) { + views::AXEventManager::Get()->AddObserver(this); + } + ~TestAXEventObserver() override { + views::AXEventManager::Get()->RemoveObserver(this); + } + + void OnViewEvent(views::View*, ax::mojom::Event event_type) override { + if (event_type == ax::mojom::Event::kSelection) + ++selection_event_count_; + } + + size_t GetSelectionEventCount() { return selection_event_count_; } + void ResetSelectionEventCount() { selection_event_count_ = 0; } + + private: + size_t selection_event_count_; + DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver); +}; + class AutofillPopupViewNativeViewsTest : public ChromeViewsTestBase { public: AutofillPopupViewNativeViewsTest() = default; @@ -105,6 +129,36 @@ view()->Hide(); } +TEST_F(AutofillPopupViewNativeViewsTest, AccessibilitySelectedEvent) { + TestAXEventObserver observer; + CreateAndShowView({autofill::POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY, + autofill::POPUP_ITEM_ID_SEPARATOR, + autofill::POPUP_ITEM_ID_AUTOFILL_OPTIONS}); + + // Checks that a selection event is not sent when the view's |is_selected_| + // member does not change. + view()->GetRowsForTesting()[0]->SetSelected(false); + EXPECT_EQ(0U, observer.GetSelectionEventCount()); + observer.ResetSelectionEventCount(); + + // Checks that a selection event is sent when an unselected view becomes + // selected. + view()->GetRowsForTesting()[0]->SetSelected(true); + EXPECT_EQ(1U, observer.GetSelectionEventCount()); + observer.ResetSelectionEventCount(); + + // Checks that a selection event is not sent when the view's |is_selected_| + // member does not change. + view()->GetRowsForTesting()[0]->SetSelected(true); + EXPECT_EQ(0U, observer.GetSelectionEventCount()); + observer.ResetSelectionEventCount(); + + // Checks that a selection event is not sent when a selected view becomes + // unselected. + view()->GetRowsForTesting()[0]->SetSelected(false); + EXPECT_EQ(0U, observer.GetSelectionEventCount()); +} + TEST_F(AutofillPopupViewNativeViewsTest, AccessibilityTest) { CreateAndShowView({autofill::POPUP_ITEM_ID_DATALIST_ENTRY, autofill::POPUP_ITEM_ID_SEPARATOR,
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc index d963686..c2056ad 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -216,6 +216,8 @@ auto icon = std::make_unique<ToolbarActionView>(actions_.back().get(), this); icon->set_owned_by_client(); icon->SetVisible(IsActionVisibleOnToolbar(actions_.back().get())); + icon->AddButtonObserver(this); + icon->AddObserver(this); AddChildView(icon.get()); icons_[action_id] = std::move(icon);
diff --git a/chrome/browser/ui/views/global_media_controls/OWNERS b/chrome/browser/ui/views/global_media_controls/OWNERS new file mode 100644 index 0000000..399a33f --- /dev/null +++ b/chrome/browser/ui/views/global_media_controls/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/ui/global_media_controls/OWNERS
diff --git a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc new file mode 100644 index 0000000..abd3c8fc --- /dev/null +++ b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc
@@ -0,0 +1,52 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h" + +#include "chrome/browser/themes/theme_properties.h" +#include "components/vector_icons/vector_icons.h" +#include "ui/base/theme_provider.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/native_theme/native_theme.h" + +MediaToolbarButtonView::MediaToolbarButtonView( + service_manager::Connector* connector) + : ToolbarButton(this), + connector_(connector), + controller_(connector_, this) { + set_notify_action(Button::NOTIFY_ON_PRESS); + EnableCanvasFlippingForRTLUI(false); + ToolbarButton::Init(); + + // We start hidden and only show once |controller_| tells us to. + SetVisible(false); +} + +MediaToolbarButtonView::~MediaToolbarButtonView() = default; + +void MediaToolbarButtonView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + // TODO(https://crbug.com/973491): Toggle the MediaDialogView. +} + +void MediaToolbarButtonView::Show() { + SetVisible(true); + PreferredSizeChanged(); +} + +void MediaToolbarButtonView::UpdateIcon() { + // TODO(https://crbug.com/973500): Use actual icon instead of this + // placeholder. + const gfx::VectorIcon& icon = ::vector_icons::kPlayArrowIcon; + + // TODO(https://crbug.com/973500): When adding the actual icon, have the size + // of the icon in the icon definition so we don't need to specify a size here. + const int dip_size = 18; + + SetImage( + views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(icon, dip_size, + GetThemeProvider()->GetColor( + ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON))); +}
diff --git a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h new file mode 100644 index 0000000..91acd53 --- /dev/null +++ b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_VIEW_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/global_media_controls/media_toolbar_button_controller.h" +#include "chrome/browser/ui/global_media_controls/media_toolbar_button_controller_delegate.h" +#include "chrome/browser/ui/views/toolbar/toolbar_button.h" + +namespace service_manager { +class Connector; +} // namespace service_manager + +// Media icon shown in the trusted area of toolbar. Its lifetime is tied to that +// of its parent ToolbarView. The icon is made visible when there is an active +// media session. +class MediaToolbarButtonView : public ToolbarButton, + public MediaToolbarButtonControllerDelegate, + public views::ButtonListener { + public: + explicit MediaToolbarButtonView(service_manager::Connector* connector); + ~MediaToolbarButtonView() override; + + // MediaToolbarButtonControllerDelegate implementation. + void Show() override; + + // views::ButtonListener implementation. + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + // Updates the icon image. + void UpdateIcon(); + + private: + service_manager::Connector* connector_; + MediaToolbarButtonController controller_; + + DISALLOW_COPY_AND_ASSIGN(MediaToolbarButtonView); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_GLOBAL_MEDIA_CONTROLS_MEDIA_TOOLBAR_BUTTON_VIEW_H_
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc index 31124ee5..c5b06085 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
@@ -97,17 +97,22 @@ ui::AXNodeData node_data; view->GetAccessibleNodeData(&node_data); if (event_type == ax::mojom::Event::kTextChanged && - node_data.role == ax::mojom::Role::kListBoxOption) { + node_data.role == ax::mojom::Role::kListBoxOption) text_changed_on_listboxoption_count_++; - } + else if (event_type == ax::mojom::Event::kSelectedChildrenChanged) + selected_children_changed_count_++; } int text_changed_on_listboxoption_count() { return text_changed_on_listboxoption_count_; } + int selected_children_changed_count() { + return selected_children_changed_count_; + } private: int text_changed_on_listboxoption_count_ = 0; + int selected_children_changed_count_ = 0; DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver); }; @@ -367,14 +372,72 @@ IN_PROC_BROWSER_TEST_F(OmniboxPopupContentsViewTest, EmitTextChangedAccessibilityEvent) { - // Set the result to what we want and update. + // Creation and population of the popup should not result in a text/name + // change accessibility event. TestAXEventObserver observer; + CreatePopupForTestQuery(); + ACMatches matches; + AutocompleteMatch match(nullptr, 500, false, + AutocompleteMatchType::HISTORY_TITLE); + AutocompleteController* controller = popup_model()->autocomplete_controller(); + match.contents = base::ASCIIToUTF16("https://foobar.com"); + matches.push_back(match); + match.contents = base::ASCIIToUTF16("https://foobarbaz.com"); + matches.push_back(match); + controller->result_.AppendMatches(controller->input_, matches); popup_view()->UpdatePopupAppearance(); EXPECT_EQ(observer.text_changed_on_listboxoption_count(), 0); - // Calling it again should emit the event. + // Changing the user text while in the input rather than the list should not + // result in a text/name change accessibility event. edit_model()->SetUserText(base::ASCIIToUTF16("bar")); edit_model()->StartAutocomplete(false, false); popup_view()->UpdatePopupAppearance(); + EXPECT_EQ(observer.text_changed_on_listboxoption_count(), 0); + + // Each time the selection changes, we should have a text/name change event. + // This makes it possible for screen readers to have the updated match content + // when they are notified the selection changed. + popup_view()->model()->SetSelectedLine(1, false, false); EXPECT_EQ(observer.text_changed_on_listboxoption_count(), 1); + + popup_view()->model()->SetSelectedLine(2, false, false); + EXPECT_EQ(observer.text_changed_on_listboxoption_count(), 2); +} + +IN_PROC_BROWSER_TEST_F(OmniboxPopupContentsViewTest, + EmitSelectedChildrenChangedAccessibilityEvent) { + // Create a popup for the matches. + GetPopupWidget(); + edit_model()->SetUserText(base::ASCIIToUTF16("foo")); + AutocompleteInput input( + base::ASCIIToUTF16("foo"), metrics::OmniboxEventProto::BLANK, + ChromeAutocompleteSchemeClassifier(browser()->profile())); + input.set_want_asynchronous_matches(false); + popup_model()->autocomplete_controller()->Start(input); + + // Create a match to populate the autocomplete. + base::string16 match_url = base::ASCIIToUTF16("https://foobar.com"); + AutocompleteMatch match(nullptr, 500, false, + AutocompleteMatchType::HISTORY_TITLE); + match.contents = match_url; + match.contents_class.push_back( + ACMatchClassification(0, ACMatchClassification::URL)); + match.destination_url = GURL(match_url); + match.description = base::ASCIIToUTF16("Foobar"); + match.allowed_to_be_default_match = true; + + AutocompleteController* autocomplete_controller = + popup_model()->autocomplete_controller(); + AutocompleteResult& results = autocomplete_controller->result_; + ACMatches matches; + matches.push_back(match); + results.AppendMatches(input, matches); + + // Lets check that arrowing up and down emits the event. + TestAXEventObserver observer; + EXPECT_EQ(observer.selected_children_changed_count(), 0); + // This is equiverlent of the user arrowing down in the omnibox. + popup_view()->model()->SetSelectedLine(1, false, false); + EXPECT_EQ(observer.selected_children_changed_count(), 1); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index ba7ee37d..e837aff 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -112,7 +112,6 @@ Invalidate(); Layout(); - EmitTextChangedAccessiblityEvent(); } void OmniboxResultView::ShowKeyword(bool show_keyword) { @@ -215,6 +214,14 @@ void OmniboxResultView::OnSelected() { DCHECK(IsSelected()); + // Immediately before notifying screen readers that the selected item has + // changed, we want to update the name of the newly-selected item so that any + // cached values get updated prior to the selection change. + EmitTextChangedAccessiblityEvent(); + + // Send accessibility event on the popup box that its selection has changed. + EmitSelectedChildrenChangedAccessibilityEvent(); + // The text is also accessible via text/value change events in the omnibox but // this selection event allows the screen reader to get more details about the // list and the user's position within it. @@ -471,6 +478,9 @@ if (!popup_contents_view_->IsOpen()) return; + // The omnibox results list reuses the same items, but the text displayed for + // these items is updated as the value of omnibox changes. The displayed text + // for a given item is exposed to screen readers as the item's name/label. base::string16 current_name = AutocompleteMatchType::ToAccessibilityLabel( match_, match_.contents, false); if (accessible_name_ != current_name) { @@ -479,6 +489,11 @@ } } +void OmniboxResultView::EmitSelectedChildrenChangedAccessibilityEvent() { + popup_contents_view_->NotifyAccessibilityEvent( + ax::mojom::Event::kSelectedChildrenChanged, true); +} + //////////////////////////////////////////////////////////////////////////////// // OmniboxResultView, private:
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.h b/chrome/browser/ui/views/omnibox/omnibox_result_view.h index fe8d1d70..580cb9b 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.h
@@ -88,8 +88,9 @@ // Removes the shown |match_| from history, if possible. void RemoveSuggestion() const; - // Call when updating |match_| to possibly fire Accessiblity events. + // Helper to emit accessibility events (may only emit if conditions are met). void EmitTextChangedAccessiblityEvent(); + void EmitSelectedChildrenChangedAccessibilityEvent(); // views::View: void Layout() override;
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc index 412fbcf1..8ad94a81 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -55,20 +55,9 @@ void PwaInstallView::OnExecuting(PageActionIconView::ExecuteSource source) { base::RecordAction(base::UserMetricsAction("PWAInstallIcon")); - content::WebContents* web_contents = GetWebContents(); - // TODO(https://crbug.com/956810): Make AppBannerManager listen for - // installations instead of having to notify it from every installation UI - // surface. - auto* manager = banners::AppBannerManager::FromWebContents(web_contents); - web_app::CreateWebAppFromManifest( - web_contents, WebappInstallSource::OMNIBOX_INSTALL_ICON, - base::BindOnce( - [](base::WeakPtr<banners::AppBannerManager> manager, - const web_app::AppId& app_id, web_app::InstallResultCode code) { - if (manager && code == web_app::InstallResultCode::kSuccess) - manager->OnInstall(false, blink::kWebDisplayModeStandalone); - }, - manager ? manager->GetWeakPtr() : nullptr)); + web_app::CreateWebAppFromManifest(GetWebContents(), + WebappInstallSource::OMNIBOX_INSTALL_ICON, + base::DoNothing()); } views::BubbleDialogDelegateView* PwaInstallView::GetBubble() const {
diff --git a/chrome/browser/ui/views/page_info/chosen_object_view.cc b/chrome/browser/ui/views/page_info/chosen_object_view.cc index eddac546..ca2da014 100644 --- a/chrome/browser/ui/views/page_info/chosen_object_view.cc +++ b/chrome/browser/ui/views/page_info/chosen_object_view.cc
@@ -65,27 +65,27 @@ layout->StartRowWithPadding(1.0, column_set_id, views::GridLayout::kFixedSize, list_item_padding); // Create the chosen object icon. - icon_ = new views::ImageView(); - layout->AddView(icon_); + icon_ = layout->AddView(std::make_unique<views::ImageView>()); // Create the label that displays the chosen object name. - views::Label* label = new views::Label( + auto label = std::make_unique<views::Label>( PageInfoUI::ChosenObjectToUIString(*info_), CONTEXT_BODY_TEXT_LARGE); icon_->SetImage( PageInfoUI::GetChosenObjectIcon(*info_, false, label->enabled_color())); - layout->AddView(label); + layout->AddView(std::move(label)); // Create the delete button. - delete_button_ = views::CreateVectorImageButton(this).release(); + std::unique_ptr<views::ImageButton> delete_button = + views::CreateVectorImageButton(this); views::SetImageFromVectorIcon( - delete_button_, vector_icons::kCloseRoundedIcon, + delete_button.get(), vector_icons::kCloseRoundedIcon, views::style::GetColor(*this, CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_PRIMARY)); - delete_button_->SetFocusForPlatform(); - delete_button_->set_request_focus_on_press(true); - delete_button_->SetTooltipText( + delete_button->SetFocusForPlatform(); + delete_button->set_request_focus_on_press(true); + delete_button->SetTooltipText( l10n_util::GetStringUTF16(info_->ui_info.delete_tooltip_string_id)); - layout->AddView(delete_button_); + delete_button_ = layout->AddView(std::move(delete_button)); // Display secondary text underneath the name of the chosen object to describe // what the chosen object actually is. @@ -94,14 +94,14 @@ // Disable the delete button for policy controlled objects and display the // allowed by policy string below for |secondary_label|. - views::Label* secondary_label = nullptr; + std::unique_ptr<views::Label> secondary_label; if (info_->chooser_object->source == content_settings::SettingSource::SETTING_SOURCE_POLICY) { delete_button_->SetEnabled(false); - secondary_label = new views::Label(l10n_util::GetStringUTF16( + secondary_label = std::make_unique<views::Label>(l10n_util::GetStringUTF16( info_->ui_info.allowed_by_policy_description_string_id)); } else { - secondary_label = new views::Label( + secondary_label = std::make_unique<views::Label>( l10n_util::GetStringUTF16(info_->ui_info.description_string_id)); } @@ -114,11 +114,11 @@ int preferred_width = secondary_label->GetPreferredSize().width(); constexpr int kMaxSecondaryLabelWidth = 140; if (preferred_width > kMaxSecondaryLabelWidth) { - layout->AddView(secondary_label, /*col_span=*/1, /*row_span=*/1, + layout->AddView(std::move(secondary_label), /*col_span=*/1, /*row_span=*/1, views::GridLayout::LEADING, views::GridLayout::CENTER, kMaxSecondaryLabelWidth, /*pref_height=*/0); } else { - layout->AddView(secondary_label, /*col_span=*/1, /*row_span=*/1, + layout->AddView(std::move(secondary_label), /*col_span=*/1, /*row_span=*/1, views::GridLayout::FILL, views::GridLayout::CENTER); }
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc index f16f4a1f..fc55d5a 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -247,31 +247,34 @@ layout->StartRow(views::GridLayout::kFixedSize, label_column_status); - security_details_label_ = - new views::StyledLabel(base::string16(), styled_label_listener); - security_details_label_->SetID( + auto security_details_label = std::make_unique<views::StyledLabel>( + base::string16(), styled_label_listener); + security_details_label->SetID( PageInfoBubbleView::VIEW_ID_PAGE_INFO_LABEL_SECURITY_DETAILS); - layout->AddView(security_details_label_, 1.0, 1.0, views::GridLayout::FILL, - views::GridLayout::LEADING); + security_details_label_ = + layout->AddView(std::move(security_details_label), 1.0, 1.0, + views::GridLayout::FILL, views::GridLayout::LEADING); layout->StartRow(views::GridLayout::kFixedSize, label_column_status); - ev_certificate_label_container_ = new views::View(); - ev_certificate_label_container_->SetLayoutManager( + auto ev_certificate_label_container = std::make_unique<views::View>(); + ev_certificate_label_container->SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); - layout->AddView(ev_certificate_label_container_, 1.0, 1.0, - views::GridLayout::FILL, views::GridLayout::LEADING); + ev_certificate_label_container_ = + layout->AddView(std::move(ev_certificate_label_container), 1.0, 1.0, + views::GridLayout::FILL, views::GridLayout::LEADING); layout->StartRow(views::GridLayout::kFixedSize, label_column_status); - reset_decisions_label_container_ = new views::View(); - reset_decisions_label_container_->SetLayoutManager( + auto reset_decisions_label_container = std::make_unique<views::View>(); + reset_decisions_label_container->SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); - layout->AddView(reset_decisions_label_container_, 1.0, 1.0, - views::GridLayout::FILL, views::GridLayout::LEADING); + reset_decisions_label_container_ = + layout->AddView(std::move(reset_decisions_label_container), 1.0, 1.0, + views::GridLayout::FILL, views::GridLayout::LEADING); layout->StartRow(views::GridLayout::kFixedSize, label_column_status); - password_reuse_button_container_ = new views::View(); - layout->AddView(password_reuse_button_container_, 1, 1, - views::GridLayout::FILL, views::GridLayout::LEADING); + password_reuse_button_container_ = + layout->AddView(std::make_unique<views::View>(), 1, 1, + views::GridLayout::FILL, views::GridLayout::LEADING); } BubbleHeaderView::~BubbleHeaderView() {} @@ -539,32 +542,29 @@ views::GridLayout::USE_PREF, 0, 0); layout->StartRow(views::GridLayout::kFixedSize, kColumnId); - header_ = new BubbleHeaderView(this, this, side_margin); - layout->AddView(header_); + header_ = layout->AddView( + std::make_unique<BubbleHeaderView>(this, this, side_margin)); layout->StartRow(views::GridLayout::kFixedSize, kColumnId); - permissions_view_ = new views::View; - layout->AddView(permissions_view_); + permissions_view_ = layout->AddView(std::make_unique<views::View>()); layout->StartRow(views::GridLayout::kFixedSize, kColumnId); - layout->AddView(new views::Separator()); + layout->AddView(std::make_unique<views::Separator>()); layout->StartRowWithPadding(views::GridLayout::kFixedSize, kColumnId, views::GridLayout::kFixedSize, hover_list_spacing); - site_settings_view_ = CreateSiteSettingsView(); - layout->AddView(site_settings_view_); + site_settings_view_ = layout->AddView(CreateSiteSettingsView()); if (!profile->IsGuestSession()) { layout->StartRowWithPadding(views::GridLayout::kFixedSize, kColumnId, views::GridLayout::kFixedSize, 0); - layout->AddView(CreateSiteSettingsLink(side_margin, this).release()); + layout->AddView(CreateSiteSettingsLink(side_margin, this)); } #if defined(OS_WIN) && BUILDFLAG(ENABLE_VR) layout->StartRow(views::GridLayout::kFixedSize, kColumnId); - page_feature_info_view_ = new views::View; - layout->AddView(page_feature_info_view_); + page_feature_info_view_ = layout->AddView(std::make_unique<views::View>()); #endif views::BubbleDialogDelegateView::CreateBubble(this); @@ -789,7 +789,7 @@ // The view takes ownership of the object info. auto object_view = std::make_unique<ChosenObjectView>(std::move(object)); object_view->AddObserver(this); - layout->AddView(object_view.release()); + layout->AddView(std::move(object_view)); } layout->AddPaddingRow(views::GridLayout::kFixedSize, list_item_padding); @@ -1002,8 +1002,8 @@ } #endif -views::View* PageInfoBubbleView::CreateSiteSettingsView() { - views::View* site_settings_view = new views::View(); +std::unique_ptr<views::View> PageInfoBubbleView::CreateSiteSettingsView() { + auto site_settings_view = std::make_unique<views::View>(); auto* box_layout = site_settings_view->SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); box_layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_bubble_view.h index 385c0fa..d1f8f8a3 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.h +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
@@ -159,7 +159,7 @@ // Creates the contents of the |site_settings_view_|. The ownership of the // returned view is transferred to the caller. - views::View* CreateSiteSettingsView() WARN_UNUSED_RESULT; + std::unique_ptr<views::View> CreateSiteSettingsView() WARN_UNUSED_RESULT; // Posts a task to HandleMoreInfoRequestAsync() below. void HandleMoreInfoRequest(views::View* source);
diff --git a/chrome/browser/ui/views/page_info/permission_selector_row.cc b/chrome/browser/ui/views/page_info/permission_selector_row.cc index ed0449d..cf67130 100644 --- a/chrome/browser/ui/views/page_info/permission_selector_row.cc +++ b/chrome/browser/ui/views/page_info/permission_selector_row.cc
@@ -167,15 +167,14 @@ views::GridLayout::kFixedSize, list_item_padding); // Create the permission icon and label. - icon_ = new NonAccessibleImageView(); - layout->AddView(icon_); + icon_ = layout->AddView(std::make_unique<NonAccessibleImageView>()); // Create the label that displays the permission type. - label_ = - new views::Label(PageInfoUI::PermissionTypeToUIString(permission.type), - CONTEXT_BODY_TEXT_LARGE); + auto label = std::make_unique<views::Label>( + PageInfoUI::PermissionTypeToUIString(permission.type), + CONTEXT_BODY_TEXT_LARGE); icon_->SetImage( - PageInfoUI::GetPermissionIcon(permission, label_->enabled_color())); - layout->AddView(label_); + PageInfoUI::GetPermissionIcon(permission, label->enabled_color())); + label_ = layout->AddView(std::move(label)); // Create the menu model. menu_model_.reset(new PermissionMenuModel( profile, url, permission, @@ -191,7 +190,7 @@ if (!reason.empty()) { layout->StartRow(1.0, PageInfoBubbleView::kPermissionColumnSetId); layout->SkipColumns(1); - views::Label* secondary_label = new views::Label(reason); + auto secondary_label = std::make_unique<views::Label>(reason); secondary_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); secondary_label->SetEnabledColor(PageInfoUI::GetSecondaryTextColor()); // The |secondary_label| should wrap when it's too long instead of @@ -212,11 +211,11 @@ // display. constexpr int kMaxSecondaryLabelWidth = 140; if (preferred_width > kMaxSecondaryLabelWidth) { - layout->AddView(secondary_label, column_span, 1.0, + layout->AddView(std::move(secondary_label), column_span, 1.0, views::GridLayout::LEADING, views::GridLayout::CENTER, kMaxSecondaryLabelWidth, 0); } else { - layout->AddView(secondary_label, column_span, 1.0, + layout->AddView(std::move(secondary_label), column_span, 1.0, views::GridLayout::FILL, views::GridLayout::CENTER); } } @@ -272,13 +271,13 @@ permission.source == content_settings::SETTING_SOURCE_USER; combobox_model_adapter_.reset( new internal::ComboboxModelAdapter(menu_model_.get())); - combobox_ = new internal::PermissionCombobox(combobox_model_adapter_.get(), - button_enabled, true); - combobox_->SetEnabled(button_enabled); - combobox_->SetTooltipText(l10n_util::GetStringFUTF16( + auto combobox = std::make_unique<internal::PermissionCombobox>( + combobox_model_adapter_.get(), button_enabled, true); + combobox->SetEnabled(button_enabled); + combobox->SetTooltipText(l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SELECTOR_TOOLTIP, PageInfoUI::PermissionTypeToUIString(permission.type))); - layout->AddView(combobox_); + combobox_ = layout->AddView(std::move(combobox)); } void PermissionSelectorRow::PermissionChanged(
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc index b1afc55..d0bd4a3 100644 --- a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc +++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc
@@ -50,20 +50,17 @@ BuildColumnSet(layout); layout->StartRow(views::GridLayout::kFixedSize, 0); - layout->AddView( - autofill::CreateLabelWithColorReadabilityDisabled( - suggestion, ChromeTextContext::CONTEXT_BODY_TEXT_LARGE, - state == PasswordGenerationPopupController::kOfferGeneration - ? views::style::STYLE_PRIMARY - : STYLE_SECONDARY) - .release()); + layout->AddView(autofill::CreateLabelWithColorReadabilityDisabled( + suggestion, ChromeTextContext::CONTEXT_BODY_TEXT_LARGE, + state == PasswordGenerationPopupController::kOfferGeneration + ? views::style::STYLE_PRIMARY + : STYLE_SECONDARY)); DCHECK(!password_label_); - password_label_ = autofill::CreateLabelWithColorReadabilityDisabled( - password, ChromeTextContext::CONTEXT_BODY_TEXT_LARGE, - STYLE_SECONDARY_MONOSPACED) - .release(); - layout->AddView(password_label_); + password_label_ = + layout->AddView(autofill::CreateLabelWithColorReadabilityDisabled( + password, ChromeTextContext::CONTEXT_BODY_TEXT_LARGE, + STYLE_SECONDARY_MONOSPACED)); } void UpdatePassword(const base::string16& password) {
diff --git a/chrome/browser/ui/views/passwords/password_items_view.cc b/chrome/browser/ui/views/passwords/password_items_view.cc index ea905336..66ac926 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.cc +++ b/chrome/browser/ui/views/passwords/password_items_view.cc
@@ -204,8 +204,8 @@ CreateUndoButton(this, GetDisplayUsername(*password_form_)); StartRow(layout, UNDO_COLUMN_SET); - layout->AddView(text.release()); - layout->AddView(undo_button.release()); + layout->AddView(std::move(text)); + layout->AddView(std::move(undo_button)); } void PasswordItemsView::PasswordRow::AddPasswordRow(views::GridLayout* layout) { @@ -216,9 +216,9 @@ std::unique_ptr<views::ImageButton> delete_button = CreateDeleteButton(this, GetDisplayUsername(*password_form_)); StartRow(layout, PASSWORD_COLUMN_SET); - layout->AddView(username_label.release()); - layout->AddView(password_label.release()); - layout->AddView(delete_button.release()); + layout->AddView(std::move(username_label)); + layout->AddView(std::move(password_label)); + layout->AddView(std::move(delete_button)); } void PasswordItemsView::PasswordRow::ButtonPressed(views::Button* sender,
diff --git a/chrome/browser/ui/views/passwords/password_pending_view.cc b/chrome/browser/ui/views/passwords/password_pending_view.cc index 24b4227..fb92ff9 100644 --- a/chrome/browser/ui/views/passwords/password_pending_view.cc +++ b/chrome/browser/ui/views/passwords/password_pending_view.cc
@@ -91,10 +91,11 @@ // |password_view_button| is an optional field. If it is a nullptr, a // DOUBLE_VIEW_COLUMN_SET_PASSWORD will be used for password row instead of // TRIPLE_VIEW_COLUMN_SET. -void BuildCredentialRows(views::GridLayout* layout, - views::View* username_field, - views::View* password_field, - views::ToggleImageButton* password_view_button) { +void BuildCredentialRows( + views::GridLayout* layout, + std::unique_ptr<views::View> username_field, + std::unique_ptr<views::View> password_field, + std::unique_ptr<views::ToggleImageButton> password_view_button) { // Username row. BuildColumnSet(layout, DOUBLE_VIEW_COLUMN_SET_USERNAME); layout->StartRow(views::GridLayout::kFixedSize, @@ -112,9 +113,9 @@ int fields_height = std::max(username_field->GetPreferredSize().height(), password_field->GetPreferredSize().height()); - layout->AddView(username_label.release(), 1, 1, views::GridLayout::LEADING, + layout->AddView(std::move(username_label), 1, 1, views::GridLayout::LEADING, views::GridLayout::FILL, labels_width, 0); - layout->AddView(username_field, 1, 1, views::GridLayout::FILL, + layout->AddView(std::move(username_field), 1, 1, views::GridLayout::FILL, views::GridLayout::FILL, 0, fields_height); layout->AddPaddingRow(views::GridLayout::kFixedSize, @@ -127,13 +128,13 @@ : DOUBLE_VIEW_COLUMN_SET_PASSWORD; BuildColumnSet(layout, type); layout->StartRow(views::GridLayout::kFixedSize, type); - layout->AddView(password_label.release(), 1, 1, views::GridLayout::LEADING, + layout->AddView(std::move(password_label), 1, 1, views::GridLayout::LEADING, views::GridLayout::FILL, labels_width, 0); - layout->AddView(password_field, 1, 1, views::GridLayout::FILL, + layout->AddView(std::move(password_field), 1, 1, views::GridLayout::FILL, views::GridLayout::FILL, 0, fields_height); // The eye icon is also added to the layout if it was passed. if (password_view_button) { - layout->AddView(password_view_button); + layout->AddView(std::move(password_view_button)); } } @@ -230,22 +231,25 @@ credential_view->SetEnabled(false); AddChildView(credential_view); } else { - username_dropdown_ = - CreateUsernameEditableCombobox(password_form).release(); - username_dropdown_->set_listener(this); - password_dropdown_ = - CreatePasswordEditableCombobox(password_form, are_passwords_revealed_) - .release(); - password_dropdown_->set_listener(this); + std::unique_ptr<views::EditableCombobox> username_dropdown = + CreateUsernameEditableCombobox(password_form); + username_dropdown->set_listener(this); + std::unique_ptr<views::EditableCombobox> password_dropdown = + CreatePasswordEditableCombobox(password_form, are_passwords_revealed_); + password_dropdown->set_listener(this); - password_view_button_ = - CreatePasswordViewButton(this, are_passwords_revealed_).release(); + std::unique_ptr<views::ToggleImageButton> password_view_button = + CreatePasswordViewButton(this, are_passwords_revealed_); views::GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>()); - BuildCredentialRows(layout, username_dropdown_, password_dropdown_, - password_view_button_); + username_dropdown_ = username_dropdown.get(); + password_dropdown_ = password_dropdown.get(); + password_view_button_ = password_view_button.get(); + BuildCredentialRows(layout, std::move(username_dropdown), + std::move(password_dropdown), + std::move(password_view_button)); } }
diff --git a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc index 30b2e2f..66ebda7a 100644 --- a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc +++ b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h" -#include <memory> #include <utility> #include "base/bind.h" @@ -53,8 +52,8 @@ views::CONTROL, views::TEXT); } -views::Label* CreateText(const base::string16& message) { - views::Label* text = new views::Label(message); +std::unique_ptr<views::Label> CreateText(const base::string16& message) { + auto text = std::make_unique<views::Label>(message); text->SetFontList(gfx::FontList().Derive(kFontSizeDelta, gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM)); text->SetEnabledColor(gfx::kGoogleGrey700); @@ -67,7 +66,6 @@ EnterpriseStartupDialogView::EnterpriseStartupDialogView( EnterpriseStartupDialog::DialogResultCallback callback) : callback_(std::move(callback)), - can_show_browser_window_(false), weak_factory_(this) { SetBorder(views::CreateEmptyBorder(GetDialogInsets())); CreateDialogWidget(this, nullptr, nullptr)->Show(); @@ -84,27 +82,27 @@ const base::string16& information) { ResetDialog(false); - views::Label* text = CreateText(information); - views::Throbber* throbber = new views::Throbber(); + std::unique_ptr<views::Label> text = CreateText(information); + auto throbber = std::make_unique<views::Throbber>(); gfx::Size throbber_size = gfx::Size(kIconSize, kIconSize); throbber->SetPreferredSize(throbber_size); throbber->Start(); - SetupLayout(throbber, text); + SetupLayout(std::move(throbber), std::move(text)); } void EnterpriseStartupDialogView::DisplayErrorMessage( const base::string16& error_message, const base::Optional<base::string16>& accept_button) { ResetDialog(accept_button.has_value()); - views::Label* text = CreateText(error_message); - views::ImageView* error_icon = new views::ImageView(); + std::unique_ptr<views::Label> text = CreateText(error_message); + auto error_icon = std::make_unique<views::ImageView>(); error_icon->SetImage(gfx::CreateVectorIcon(kBrowserToolsErrorIcon, kIconSize, gfx::kGoogleRed700)); if (accept_button) GetDialogClientView()->ok_button()->SetText(*accept_button); - SetupLayout(error_icon, text); + SetupLayout(std::move(error_icon), std::move(text)); } void EnterpriseStartupDialogView::CloseDialog() { @@ -204,8 +202,9 @@ RemoveAllChildViews(true); } -void EnterpriseStartupDialogView::SetupLayout(views::View* icon, - views::View* text) { +void EnterpriseStartupDialogView::SetupLayout( + std::unique_ptr<views::View> icon, + std::unique_ptr<views::View> text) { // Padding between icon and text int text_padding = ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_TEXTFIELD_HORIZONTAL_TEXT_PADDING); @@ -226,8 +225,8 @@ layout->AddPaddingRow(1.0, 0); layout->StartRow(views::GridLayout::kFixedSize, 0); - layout->AddView(icon); - layout->AddView(text); + layout->AddView(std::move(icon)); + layout->AddView(std::move(text)); layout->AddPaddingRow(1.0, 0); GetDialogClientView()->Layout();
diff --git a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h index 9a1a4f05..8950ce1 100644 --- a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h +++ b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_VIEWS_POLICY_ENTERPRISE_STARTUP_DIALOG_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_POLICY_ENTERPRISE_STARTUP_DIALOG_VIEW_H_ +#include <memory> #include <string> #include "base/callback_forward.h" @@ -58,10 +59,11 @@ // Remove all existing child views from the dialog, show/hide dialog buttons. void ResetDialog(bool show_accept_button); // Append child views to the content area, setup the layout. - void SetupLayout(views::View* icon, views::View* text); + void SetupLayout(std::unique_ptr<views::View> icon, + std::unique_ptr<views::View> text); EnterpriseStartupDialog::DialogResultCallback callback_; - bool can_show_browser_window_; + bool can_show_browser_window_ = false; base::WeakPtrFactory<EnterpriseStartupDialogView> weak_factory_;
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc index 14ffd0342..c69cb2c 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -408,7 +408,7 @@ views::GridLayout::kFixedSize, views::GridLayout::FIXED, menu_width_, menu_width_); layout->StartRow(1.0, 0); - layout->AddView(scroll_view.release()); + layout->AddView(std::move(scroll_view)); if (GetBubbleFrameView()) { SizeToContents(); // SizeToContents() will perform a layout, but only if the size changed.
diff --git a/chrome/browser/ui/views/sync/dice_signin_button_view.cc b/chrome/browser/ui/views/sync/dice_signin_button_view.cc index 5a0230d..ec756b94 100644 --- a/chrome/browser/ui/views/sync/dice_signin_button_view.cc +++ b/chrome/browser/ui/views/sync/dice_signin_button_view.cc
@@ -63,26 +63,26 @@ use_account_name_as_title ? base::UTF8ToUTF16(account.full_name) : l10n_util::GetStringUTF16(IDS_PROFILES_DICE_NOT_SYNCING_TITLE); - HoverButton* account_card = - new HoverButton(button_listener, std::move(account_icon_view), card_title, - base::ASCIIToUTF16(account_->email)); + auto account_card = std::make_unique<HoverButton>( + button_listener, std::move(account_icon_view), card_title, + base::ASCIIToUTF16(account_->email)); account_card->SetBorder(nullptr); account_card->SetEnabled(false); - grid_layout->AddView(account_card); + grid_layout->AddView(std::move(account_card)); if (show_drop_down_arrow) { // Add a non-stretching column for the the drop down arrow. columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, views::GridLayout::kFixedSize, views::GridLayout::USE_PREF, 0, 0); - arrow_ = new HoverButton( + auto arrow = std::make_unique<HoverButton>( button_listener, gfx::CreateVectorIcon(kSigninButtonDropDownArrowIcon, kDropDownArrowIconSize, SK_ColorBLACK), base::string16()); - arrow_->SetTooltipText(l10n_util::GetStringUTF16( + arrow->SetTooltipText(l10n_util::GetStringUTF16( IDS_PROFILES_DICE_SIGNIN_WITH_ANOTHER_ACCOUNT_BUTTON)); - grid_layout->AddView(arrow_); + arrow_ = grid_layout->AddView(std::move(arrow)); } grid_layout->AddPaddingRow(views::GridLayout::kFixedSize, 16); @@ -92,12 +92,10 @@ // Add a stretching column for the sign in button. columns->AddColumn(views::GridLayout::FILL, views::GridLayout::TRAILING, 1.0, views::GridLayout::USE_PREF, 0, 0); - auto button = views::MdTextButton::Create( - button_listener, - l10n_util::GetStringUTF16(IDS_PROFILES_DICE_SIGNIN_BUTTON)); - button->SetProminent(true); - grid_layout->AddView(button.get()); - signin_button_ = button.release(); + signin_button_ = + grid_layout->AddView(views::MdTextButton::CreateSecondaryUiBlueButton( + button_listener, + l10n_util::GetStringUTF16(IDS_PROFILES_DICE_SIGNIN_BUTTON))); } DiceSigninButtonView::~DiceSigninButtonView() = default;
diff --git a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc index bc1f90a6..ad1f705 100644 --- a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc +++ b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
@@ -96,20 +96,22 @@ layout->StartRow(views::GridLayout::kFixedSize, 0); - views::Label* label = new views::Label(l10n_util::GetStringFUTF16( + auto label = std::make_unique<views::Label>(l10n_util::GetStringFUTF16( IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE_NEW, email_)); label->SetMultiLine(true); label->SetHorizontalAlignment(gfx::ALIGN_LEFT); label->SizeToFit(kMinimumDialogLabelWidth); - layout->AddView(label); + layout->AddView(std::move(label)); layout->StartRow(views::GridLayout::kFixedSize, 0); - learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); - learn_more_link_->set_listener(this); - learn_more_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT); - layout->AddView(learn_more_link_, 1, 1, views::GridLayout::TRAILING, - views::GridLayout::CENTER); + auto learn_more_link = + std::make_unique<views::Link>(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); + learn_more_link->set_listener(this); + learn_more_link->SetHorizontalAlignment(gfx::ALIGN_LEFT); + learn_more_link_ = + layout->AddView(std::move(learn_more_link), 1, 1, + views::GridLayout::TRAILING, views::GridLayout::CENTER); } base::string16 OneClickSigninDialogView::GetWindowTitle() const {
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc index 476d819..246e943 100644 --- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc +++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -156,7 +156,7 @@ // Create business icon. int business_icon_size = 20; - views::ImageView* business_icon = new views::ImageView(); + auto business_icon = std::make_unique<views::ImageView>(); business_icon->SetImage(gfx::CreateVectorIcon(gfx::IconDescription( vector_icons::kBusinessIcon, business_icon_size, gfx::kChromeIconGrey, base::TimeDelta(), gfx::kNoneIcon))); @@ -170,7 +170,7 @@ l10n_util::GetStringFUTF16( IDS_ENTERPRISE_SIGNIN_ALERT, domain, &offset); - views::StyledLabel* prompt_label = new views::StyledLabel(prompt_text, this); + auto prompt_label = std::make_unique<views::StyledLabel>(prompt_text, this); prompt_label->SetDisplayedOnBackgroundColor(kPromptBarBackgroundColor); views::StyledLabel::RangeStyleInfo bold_style; @@ -179,7 +179,7 @@ gfx::Range(offset, offset + domain.size()), bold_style); // Create the prompt bar. - views::View* prompt_bar = new views::View; + auto prompt_bar = std::make_unique<views::View>(); prompt_bar->SetBorder(views::CreateSolidSidedBorder( 1, 0, 1, 0, ui::GetSigninConfirmationPromptBarColor(GetNativeTheme(), 0x1F))); @@ -195,8 +195,8 @@ IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITH_PROFILE_CREATION : IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITHOUT_PROFILE_CREATION, username, learn_more_text, &offsets); - views::StyledLabel* explanation_label = - new views::StyledLabel(signin_explanation_text, this); + auto explanation_label = + std::make_unique<views::StyledLabel>(signin_explanation_text, this); explanation_label->AddStyleRange( gfx::Range(offsets[1], offsets[1] + learn_more_text.size()), views::StyledLabel::RangeStyleInfo::CreateForLink()); @@ -232,17 +232,16 @@ views::GridLayout::USE_PREF, 0, 0); prompt_layout->StartRow(views::GridLayout::kFixedSize, kPromptBarColumnSetId); - prompt_layout->AddView(business_icon); - prompt_layout->AddView(prompt_label); + prompt_layout->AddView(std::move(business_icon)); + prompt_layout->AddView(std::move(prompt_label)); // Use a column set with no padding. dialog_layout->AddColumnSet(0)->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1.0, views::GridLayout::USE_PREF, 0, 0); dialog_layout->StartRow(views::GridLayout::kFixedSize, 0); - dialog_layout->AddView( - prompt_bar, 1, 1, - views::GridLayout::FILL, views::GridLayout::FILL, 0, 0); + dialog_layout->AddView(std::move(prompt_bar), 1, 1, views::GridLayout::FILL, + views::GridLayout::FILL, 0, 0); // Use a new column set for the explanation label so we can add padding. dialog_layout->AddPaddingRow(views::GridLayout::kFixedSize, @@ -260,9 +259,11 @@ dialog_layout->StartRow(views::GridLayout::kFixedSize, kExplanationColumnSetId); const int kPreferredWidth = 440; - dialog_layout->AddView(explanation_label, 1, 1, views::GridLayout::FILL, - views::GridLayout::FILL, kPreferredWidth, - explanation_label->GetHeightForWidth(kPreferredWidth)); + int explanation_label_height = + explanation_label->GetHeightForWidth(kPreferredWidth); + dialog_layout->AddView(std::move(explanation_label), 1, 1, + views::GridLayout::FILL, views::GridLayout::FILL, + kPreferredWidth, explanation_label_height); } void ProfileSigninConfirmationDialogViews::WindowClosing() {
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index c9a9b07e..656de71 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -17,6 +17,7 @@ #include "base/macros.h" #include "base/metrics/user_metrics.h" #include "base/numerics/ranges.h" +#include "base/scoped_observer.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "build/build_config.h" @@ -112,6 +113,42 @@ } // namespace +// Helper class that observes the tab's close button. +class Tab::TabCloseButtonObserver : public views::ViewObserver { + public: + explicit TabCloseButtonObserver(Tab* tab, + views::View* close_button, + TabController* controller) + : tab_(tab), close_button_(close_button), controller_(controller) { + DCHECK(close_button_); + tab_close_button_observer_.Add(close_button_); + } + + ~TabCloseButtonObserver() override { + tab_close_button_observer_.Remove(close_button_); + } + + private: + void OnViewFocused(views::View* observed_view) override { + controller_->UpdateHoverCard(tab_, /* should_show */ true); + } + + void OnViewBlurred(views::View* observed_view) override { + // Only hide hover card if not keyboard navigating. + if (!controller_->IsFocusInTabs()) + controller_->UpdateHoverCard(nullptr, /* should_show */ false); + } + + ScopedObserver<views::View, views::ViewObserver> tab_close_button_observer_{ + this}; + + Tab* tab_; + views::View* close_button_; + TabController* controller_; + + DISALLOW_COPY_AND_ASSIGN(TabCloseButtonObserver); +}; + // Tab ------------------------------------------------------------------------- // static @@ -156,7 +193,9 @@ this, base::BindRepeating(&TabController::OnMouseEventInTab, base::Unretained(controller_))); AddChildView(close_button_); - close_button_->AddObserver(this); + + tab_close_button_observer_ = std::make_unique<TabCloseButtonObserver>( + this, close_button_, controller_); set_context_menu_controller(this); @@ -168,7 +207,8 @@ } Tab::~Tab() { - close_button_->RemoveObserver(this); + // Observer must be unregistered before child views are destroyed. + tab_close_button_observer_.reset(); controller_->UpdateHoverCard(this, /* should_show */ false); } @@ -597,18 +637,19 @@ } void Tab::OnFocus() { - controller_->UpdateHoverCard(this, /* should_show */ true); View::OnFocus(); + controller_->UpdateHoverCard(this, /* should_show */ true); +} + +void Tab::OnBlur() { + View::OnBlur(); + controller_->UpdateHoverCard(nullptr, /* should_show */ false); } void Tab::OnThemeChanged() { UpdateForegroundColors(); } -void Tab::OnViewFocused(views::View* observed_view) { - controller_->UpdateHoverCard(this, /* should_show */ true); -} - void Tab::SetClosing(bool closing) { closing_ = closing; ActiveStateChanged();
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h index e26dd4f..6c28cd1a 100644 --- a/chrome/browser/ui/views/tabs/tab.h +++ b/chrome/browser/ui/views/tabs/tab.h
@@ -99,11 +99,9 @@ void OnPaint(gfx::Canvas* canvas) override; void AddedToWidget() override; void OnFocus() override; + void OnBlur() override; void OnThemeChanged() override; - // views::ViewObserver: - void OnViewFocused(views::View* observed_view) override; - TabController* controller() const { return controller_; } // Used to set/check whether this Tab is being animated closed. @@ -188,6 +186,7 @@ TabAlertState alert_state); private: + class TabCloseButtonObserver; friend class AlertIndicatorTest; friend class TabTest; friend class TabStripTest; @@ -195,6 +194,8 @@ FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabCloseButtonVisibilityWhenNotStacked); FRIEND_TEST_ALL_PREFIXES(TabTest, TitleTextHasSufficientContrast); + FRIEND_TEST_ALL_PREFIXES(TabHoverCardBubbleViewBrowserTest, + WidgetVisibleOnTabCloseButtonFocusAfterTabFocus); // Invoked from Layout to adjust the position of the favicon or alert // indicator for pinned tabs. The visual_width parameter is how wide the @@ -289,6 +290,8 @@ // the view bounds. bool mouse_hovered_ = false; + std::unique_ptr<TabCloseButtonObserver> tab_close_button_observer_; + // Focus ring for accessibility. std::unique_ptr<views::FocusRing> focus_ring_;
diff --git a/chrome/browser/ui/views/tabs/tab_controller.h b/chrome/browser/ui/views/tabs/tab_controller.h index aabed99..900ecfa0 100644 --- a/chrome/browser/ui/views/tabs/tab_controller.h +++ b/chrome/browser/ui/views/tabs/tab_controller.h
@@ -76,6 +76,9 @@ virtual bool IsFirstVisibleTab(const Tab* tab) const = 0; virtual bool IsLastVisibleTab(const Tab* tab) const = 0; + // Returns true if any tab or one of its children has focus. + virtual bool IsFocusInTabs() const = 0; + // Potentially starts a drag for the specified Tab. virtual void MaybeStartDrag( Tab* tab,
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index 8a3dc44..9ea9985 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -377,8 +377,15 @@ kMaxHoverCardReshowTimeDelta, kHoverCardHistogramBucketCount); } - bool show_immediately = !last_visible_timestamp_.is_null() && - elapsed_time <= kShowWithoutDelayTimeBuffer; + bool within_delay_time_buffer = !last_visible_timestamp_.is_null() && + elapsed_time <= kShowWithoutDelayTimeBuffer; + // Hover cards should be shown without delay if triggered within the time + // buffer or if the tab or its children have focus which indicates that the + // tab is keyboard focused. + const views::FocusManager* tab_focus_manager = tab->GetFocusManager(); + bool show_immediately = + within_delay_time_buffer || tab->HasFocus() || + (tab_focus_manager && tab->Contains(tab_focus_manager->GetFocusedView())); fade_animation_delegate_->CancelFadeOut(); @@ -404,8 +411,7 @@ } if (!widget_->IsVisible()) { - if (disable_animations_for_testing_ || show_immediately || - tab->HasFocus()) { + if (disable_animations_for_testing_ || show_immediately) { widget_->SetOpacity(1.0f); widget_->Show(); } else {
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc index 2c701e91..f0fe341 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/tabs/tab.h" +#include "chrome/browser/ui/views/tabs/tab_close_button.h" #include "chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/grit/generated_resources.h" @@ -183,6 +184,79 @@ EXPECT_FALSE(widget->IsVisible()); } +// Verify hover card is visible when tab is focused. +IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, + WidgetVisibleOnTabFocus) { + TabStrip* tab_strip = + BrowserView::GetBrowserViewForBrowser(browser())->tabstrip(); + Tab* tab = tab_strip->tab_at(0); + tab_strip->GetFocusManager()->SetFocusedView(tab); + TabHoverCardBubbleView* hover_card = GetHoverCard(tab_strip); + Widget* widget = GetHoverCardWidget(hover_card); + HoverCardVisibleWaiter waiter(widget); + waiter.Wait(); + EXPECT_TRUE(widget != nullptr); + EXPECT_TRUE(widget->IsVisible()); +} + +// Verify hover card is visible when focus moves from the tab to tab close +// button. +IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, + WidgetVisibleOnTabCloseButtonFocusAfterTabFocus) { + TabStrip* tab_strip = + BrowserView::GetBrowserViewForBrowser(browser())->tabstrip(); + Tab* tab = tab_strip->tab_at(0); + tab_strip->GetFocusManager()->SetFocusedView(tab); + TabHoverCardBubbleView* hover_card = GetHoverCard(tab_strip); + Widget* widget = GetHoverCardWidget(hover_card); + HoverCardVisibleWaiter waiter(widget); + waiter.Wait(); + EXPECT_TRUE(widget != nullptr); + EXPECT_TRUE(widget->IsVisible()); + tab_strip->GetFocusManager()->SetFocusedView(tab->close_button_); + waiter.Wait(); + EXPECT_TRUE(widget != nullptr); + EXPECT_TRUE(widget->IsVisible()); +} + +// Verify hover card is visible when tab is focused and a key is pressed. +IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, + WidgetVisibleOnKeyPressAfterTabFocus) { + TabStrip* tab_strip = + BrowserView::GetBrowserViewForBrowser(browser())->tabstrip(); + Tab* tab = tab_strip->tab_at(0); + tab_strip->GetFocusManager()->SetFocusedView(tab); + TabHoverCardBubbleView* hover_card = GetHoverCard(tab_strip); + Widget* widget = GetHoverCardWidget(hover_card); + HoverCardVisibleWaiter waiter(widget); + waiter.Wait(); + EXPECT_TRUE(widget != nullptr); + EXPECT_TRUE(widget->IsVisible()); + + ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0); + tab->OnKeyPressed(key_event); + EXPECT_TRUE(widget->IsVisible()); +} + +// Verify hover card is not visible when tab is focused and the mouse is +// pressed. +IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, + WidgetNotVisibleOnMousePressAfterTabFocus) { + TabStrip* tab_strip = + BrowserView::GetBrowserViewForBrowser(browser())->tabstrip(); + Tab* tab = tab_strip->tab_at(0); + tab_strip->GetFocusManager()->SetFocusedView(tab); + TabHoverCardBubbleView* hover_card = GetHoverCard(tab_strip); + Widget* widget = GetHoverCardWidget(hover_card); + HoverCardVisibleWaiter waiter(widget); + waiter.Wait(); + EXPECT_TRUE(widget != nullptr); + EXPECT_TRUE(widget->IsVisible()); + + ClickMouseOnTab(); + EXPECT_FALSE(widget->IsVisible()); +} + // Verify hover card is not visible after clicking on a tab. IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, WidgetNotVisibleOnClick) {
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index e56e5ff1..ed0456e 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -147,8 +147,8 @@ protected: // ui::EventTarget: void OnKeyEvent(ui::KeyEvent* event) override { - if (!tab_strip_->pane_has_focus()) - hover_card_->FadeOutToHide(); + if (!tab_strip_->IsFocusInTabs()) + tab_strip_->UpdateHoverCard(nullptr, false); } void OnMouseEvent(ui::MouseEvent* event) override { @@ -1525,6 +1525,11 @@ return GetLastVisibleTab() == tab; } +bool TabStrip::IsFocusInTabs() const { + return GetFocusManager() && Contains(GetFocusManager()->GetFocusedView()) && + GetFocusManager()->GetFocusedView() != new_tab_button_; +} + void TabStrip::MaybeStartDrag( Tab* tab, const ui::LocatedEvent& event,
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index 478519e..7c56a2d 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -239,6 +239,7 @@ bool IsTabPinned(const Tab* tab) const override; bool IsFirstVisibleTab(const Tab* tab) const override; bool IsLastVisibleTab(const Tab* tab) const override; + bool IsFocusInTabs() const override; void MaybeStartDrag( Tab* tab, const ui::LocatedEvent& event,
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc index 20c43fe2..a81a2993 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc
@@ -200,6 +200,8 @@ DCHECK_EQ(bounds.size(), static_cast<size_t>(tabs->view_size())); int trailing_x = 0; for (size_t i = 0; i < bounds.size(); i++) { + if (tabs->view_at(i)->dragging()) + continue; tabs->view_at(i)->SetBoundsRect(bounds[i]); trailing_x = std::max(trailing_x, bounds[i].right()); // TODO(958173): We shouldn't need to update the cached widths here, since
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc index b7059dd6..56fa08da 100644 --- a/chrome/browser/ui/views/tabs/tab_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -64,6 +64,7 @@ bool IsTabPinned(const Tab* tab) const override { return false; } bool IsFirstVisibleTab(const Tab* tab) const override { return false; } bool IsLastVisibleTab(const Tab* tab) const override { return false; } + bool IsFocusInTabs() const override { return false; } void MaybeStartDrag( Tab* tab, const ui::LocatedEvent& event,
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index b7c6acc..cf2e4218 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/i18n/number_formatting.h" #include "base/metrics/user_metrics.h" #include "base/strings/utf_string_conversions.h" @@ -39,6 +40,7 @@ #include "chrome/browser/ui/views/extensions/extensions_toolbar_button.h" #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h" #include "chrome/browser/ui/views/location_bar/star_view.h" #include "chrome/browser/ui/views/media_router/cast_toolbar_button.h" #include "chrome/browser/ui/views/page_action/omnibox_page_action_icon_container_view.h" @@ -64,6 +66,8 @@ #include "components/vector_icons/vector_icons.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/service_manager_connection.h" +#include "media/base/media_switches.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/material_design/material_design_controller.h" @@ -236,6 +240,12 @@ if (media_router::MediaRouterEnabled(browser_->profile())) cast = media_router::CastToolbarButton::Create(browser_); + std::unique_ptr<MediaToolbarButtonView> media_button; + if (base::FeatureList::IsEnabled(media::kGlobalMediaControls)) { + media_button = std::make_unique<MediaToolbarButtonView>( + content::ServiceManagerConnection::GetForProcess()->GetConnector()); + } + std::unique_ptr<ToolbarPageActionIconContainerView> toolbar_page_action_container; bool show_avatar_toolbar_button = true; @@ -281,6 +291,9 @@ if (cast) cast_ = AddChildView(std::move(cast)); + if (media_button) + media_button_ = AddChildView(std::move(media_button)); + if (toolbar_page_action_container) toolbar_page_action_container_ = AddChildView(std::move(toolbar_page_action_container)); @@ -856,6 +869,9 @@ if (cast_) cast_->UpdateIcon(); + if (media_button_) + media_button_->UpdateIcon(); + if (avatar_) avatar_->UpdateIcon();
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.h b/chrome/browser/ui/views/toolbar/toolbar_view.h index 1e235bef..307dc295 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_view.h
@@ -44,6 +44,7 @@ class ExtensionsToolbarButton; class ExtensionsToolbarContainer; class HomeButton; +class MediaToolbarButtonView; class ReloadButton; class ToolbarButton; class ToolbarPageActionIconContainerView; @@ -140,6 +141,7 @@ LocationBarView* location_bar() const { return location_bar_; } CustomTabBarView* custom_tab_bar() { return custom_tab_bar_; } media_router::CastToolbarButton* cast_button() const { return cast_; } + MediaToolbarButtonView* media_button() const { return media_button_; } ToolbarPageActionIconContainerView* toolbar_page_action_container() const { return toolbar_page_action_container_; } @@ -267,6 +269,7 @@ media_router::CastToolbarButton* cast_ = nullptr; ToolbarPageActionIconContainerView* toolbar_page_action_container_ = nullptr; AvatarToolbarButton* avatar_ = nullptr; + MediaToolbarButtonView* media_button_ = nullptr; BrowserAppMenuButton* app_menu_button_ = nullptr; Browser* const browser_;
diff --git a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc index 6d47ae8..cca4faeb 100644 --- a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc +++ b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
@@ -1121,9 +1121,8 @@ views::Button::STATE_NORMAL, gfx::CreateVectorIcon(kInactiveToastCloseIcon, kBodyColor)); close_button->set_tag(static_cast<int>(ButtonTag::CLOSE_BUTTON)); - close_button_ = close_button.get(); DCHECK_EQ(close_button->GetPreferredSize().width(), kCloseButtonWidth); - layout->AddView(close_button.release(), 1, 2); + close_button_ = layout->AddView(std::move(close_button), 1, 2); close_button_->SetVisible(false); } else { layout->SkipColumns(1); @@ -1131,7 +1130,7 @@ // Second row. layout->StartRow(views::GridLayout::kFixedSize, 0); - layout->AddView(logo.release()); + layout->AddView(std::move(logo)); // All variants have a main header. auto header = std::make_unique<views::Label>( l10n_util::GetStringUTF16(kExperiments[group_].heading_id), @@ -1140,7 +1139,7 @@ header->SetEnabledColor(kHeaderColor); header->SetMultiLine(true); header->SetHorizontalAlignment(gfx::ALIGN_LEFT); - layout->AddView(header.release()); + layout->AddView(std::move(header)); layout->SkipColumns(1); // Third row: May have text or may be blank. @@ -1153,7 +1152,7 @@ body_text->SetEnabledColor(kBodyColor); body_text->SetMultiLine(true); body_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); - layout->AddView(body_text.release()); + layout->AddView(std::move(body_text)); } // Fourth row: one or two buttons depending on group. @@ -1179,10 +1178,10 @@ this, l10n_util::GetStringUTF16(IDS_WIN10_TOAST_NO_THANKS), TryChromeButtonType::NO_THANKS); no_thanks_button->set_tag(static_cast<int>(ButtonTag::NO_THANKS_BUTTON)); - buttons->AddChildView(no_thanks_button.release()); + buttons->AddChildView(std::move(no_thanks_button)); } - layout->AddView(buttons.release()); + layout->AddView(std::move(buttons)); layout->AddPaddingRow(views::GridLayout::kFixedSize, kTextButtonPadding - kTryChromeBorderThickness);
diff --git a/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc b/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc index d8f17a20..d8d6948d 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc
@@ -65,8 +65,7 @@ views::style::CONTEXT_LABEL, views::style::STYLE_PRIMARY); pin_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); pin_label->SetEnabledColor(gfx::kGoogleBlue500); - auto* pin_label_ptr = pin_label.get(); - layout->AddView(pin_label.release()); + auto* pin_label_ptr = layout->AddView(std::move(pin_label)); views::View* confirmation_label_ptr = nullptr; if (show_confirmation_text_field_) { @@ -76,21 +75,19 @@ confirmation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); confirmation_label->SetEnabledColor(gfx::kGoogleBlue500); confirmation_label_ptr = confirmation_label.get(); - layout->AddView(confirmation_label.release()); + layout->AddView(std::move(confirmation_label)); } layout->StartRow(views::GridLayout::kFixedSize, 0); - auto pin_text_field = MakePinTextField(this, pin_label_ptr); - pin_text_field_ = pin_text_field.get(); - layout->AddView(pin_text_field.release()); + pin_text_field_ = layout->AddView(MakePinTextField(this, pin_label_ptr)); if (show_confirmation_text_field_) { DCHECK(confirmation_label_ptr); auto confirmation_text_field = MakePinTextField(this, confirmation_label_ptr); confirmation_text_field_ = confirmation_text_field.get(); - layout->AddView(confirmation_text_field.release()); + layout->AddView(std::move(confirmation_text_field)); } layout->StartRow(views::GridLayout::kFixedSize, 0); @@ -100,8 +97,8 @@ views::style::STYLE_PRIMARY); error_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); error_label->SetEnabledColor(gfx::kGoogleRed500); - error_label_ = error_label.get(); - layout->AddView(error_label.release(), 3 /* col_span */, 1 /* row_span */); + error_label_ = layout->AddView(std::move(error_label), 3 /* col_span */, + 1 /* row_span */); } AuthenticatorClientPinEntryView::~AuthenticatorClientPinEntryView() = default;
diff --git a/chrome/browser/ui/web_applications/web_app_ui_service.cc b/chrome/browser/ui/web_applications/web_app_ui_service.cc index 256a7963..eb57e403 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_service.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_service.cc
@@ -11,8 +11,14 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/web_app_ui_service_factory.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" +#endif + namespace web_app { // static @@ -30,7 +36,8 @@ } BrowserList::AddObserver(this); - WebAppProvider::Get(profile_)->set_ui_delegate(this); + auto* provider = WebAppProvider::Get(profile_); + provider->set_ui_delegate(this); } WebAppUiService::~WebAppUiService() = default; @@ -60,6 +67,13 @@ windows_closed_requests_map_[app_id].push_back(std::move(callback)); } +void WebAppUiService::MigrateOSAttributes(const AppId& from, const AppId& to) { +#if defined(OS_CHROMEOS) + app_list::AppListSyncableServiceFactory::GetForProfile(profile_) + ->TransferItemAttributes(from, to); +#endif +} + void WebAppUiService::OnBrowserAdded(Browser* browser) { base::Optional<AppId> app_id = GetAppIdForBrowser(browser); if (!app_id.has_value())
diff --git a/chrome/browser/ui/web_applications/web_app_ui_service.h b/chrome/browser/ui/web_applications/web_app_ui_service.h index e175429..7dc64da 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_service.h +++ b/chrome/browser/ui/web_applications/web_app_ui_service.h
@@ -10,6 +10,7 @@ #include "base/callback_forward.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/optional.h" #include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/web_applications/components/web_app_ui_delegate.h" @@ -21,7 +22,6 @@ namespace web_app { // This KeyedService is a UI counterpart for WebAppProvider. -// It tracks the open windows for each web app. class WebAppUiService : public KeyedService, public BrowserListObserver, public WebAppUiDelegate { @@ -38,6 +38,7 @@ size_t GetNumWindowsForApp(const AppId& app_id) override; void NotifyOnAllAppWindowsClosed(const AppId& app_id, base::OnceClosure callback) override; + void MigrateOSAttributes(const AppId& from, const AppId& to) override; // BrowserListObserver void OnBrowserAdded(Browser* browser) override; @@ -51,6 +52,8 @@ std::map<AppId, std::vector<base::OnceClosure>> windows_closed_requests_map_; std::map<AppId, size_t> num_windows_for_apps_map_; + base::WeakPtrFactory<WebAppUiService> weak_ptr_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(WebAppUiService); };
diff --git a/chrome/browser/ui/web_applications/web_app_ui_service_browsertest.cc b/chrome/browser/ui/web_applications/web_app_ui_service_browsertest.cc index f5974b33..653be5e 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_service_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_service_browsertest.cc
@@ -13,12 +13,22 @@ #include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/in_process_browser_test.h" #include "extensions/common/extension.h" #include "url/gurl.h" +#if defined(OS_CHROMEOS) +#include "ash/public/cpp/app_list/internal_app_id_constants.h" +#include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" +#include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" +#endif + namespace web_app { namespace { @@ -171,47 +181,81 @@ } } -// Tests that callbacks are correctly called when there is more than one -// request. -IN_PROC_BROWSER_TEST_F(WebAppUiServiceBrowserTest, - NotifyOnAllAppWindowsClosed_MultipleRequests) { - const auto* foo_app = InstallWebApp(kFooUrl); - const auto* bar_app = InstallWebApp(kBarUrl); +#if defined(OS_CHROMEOS) +class WebAppUiServiceMigrationBrowserTest : public WebAppUiServiceBrowserTest { + public: + void SetUp() override { + // Disable System Web Apps so that the Internal Apps are installed. + scoped_feature_list_.InitAndDisableFeature(features::kSystemWebApps); + WebAppUiServiceBrowserTest::SetUp(); + } - auto* foo_window1 = LaunchApp(foo_app); - auto* foo_window2 = LaunchApp(foo_app); - auto* bar_window = LaunchApp(bar_app); + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; - bool callback_ran1 = false; - bool callback_ran2 = false; +// Tests that the Settings app migrates the launcher and app list details from +// the Settings internal app. +IN_PROC_BROWSER_TEST_F(WebAppUiServiceMigrationBrowserTest, + SettingsSystemWebAppMigration) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kSystemWebApps); - base::RunLoop run_loop; - auto barrier_closure = base::BarrierClosure(2, run_loop.QuitClosure()); - ui_service()->NotifyOnAllAppWindowsClosed(foo_app->id(), - base::BindLambdaForTesting([&]() { - callback_ran1 = true; - barrier_closure.Run(); - })); - ui_service()->NotifyOnAllAppWindowsClosed(foo_app->id(), - base::BindLambdaForTesting([&]() { - callback_ran2 = true; - barrier_closure.Run(); - })); + auto& system_web_app_manager = + web_app::WebAppProvider::Get(browser()->profile()) + ->system_web_app_manager(); - CloseAndWait(foo_window1); - // The callback shouldn't have run yet because there is still one window - // opened. - EXPECT_FALSE(callback_ran1); - EXPECT_FALSE(callback_ran2); + auto* app_list_service = + app_list::AppListSyncableServiceFactory::GetForProfile( + browser()->profile()); - CloseAndWait(bar_window); - EXPECT_FALSE(callback_ran1); - EXPECT_FALSE(callback_ran2); + // Pin the Settings Internal App. + syncer::StringOrdinal pin_position = + syncer::StringOrdinal::CreateInitialOrdinal(); + pin_position = pin_position.CreateAfter().CreateAfter(); + app_list_service->SetPinPosition(app_list::kInternalAppIdSettings, + pin_position); - CloseAndWait(foo_window2); - run_loop.Run(); - EXPECT_TRUE(callback_ran1); - EXPECT_TRUE(callback_ran2); + // Add the Settings Internal App to a folder. + AppListModelUpdater* updater = + test::GetModelUpdater(test::GetAppListClient()); + updater->MoveItemToFolder(app_list::kInternalAppIdSettings, "asdf"); + + // Install the Settings System Web App, which should be immediately migrated + // to the Settings Internal App's details. + system_web_app_manager.InstallSystemAppsForTesting(); + std::string settings_system_web_app_id = + *system_web_app_manager.GetAppIdForSystemApp(SystemAppType::SETTINGS); + { + const app_list::AppListSyncableService::SyncItem* web_app_item = + app_list_service->GetSyncItem(settings_system_web_app_id); + const app_list::AppListSyncableService::SyncItem* internal_app_item = + app_list_service->GetSyncItem(app_list::kInternalAppIdSettings); + + EXPECT_TRUE(internal_app_item->item_pin_ordinal.Equals( + web_app_item->item_pin_ordinal)); + EXPECT_TRUE( + internal_app_item->item_ordinal.Equals(web_app_item->item_ordinal)); + EXPECT_EQ(internal_app_item->parent_id, web_app_item->parent_id); + } + + // Change Settings System Web App properties. + app_list_service->SetPinPosition( + settings_system_web_app_id, + syncer::StringOrdinal::CreateInitialOrdinal()); + updater->MoveItemToFolder(settings_system_web_app_id, std::string()); + + // Do migration again with the already-installed app. Should be a no-op. + system_web_app_manager.InstallSystemAppsForTesting(); + { + const app_list::AppListSyncableService::SyncItem* web_app_item = + app_list_service->GetSyncItem(settings_system_web_app_id); + + EXPECT_TRUE(syncer::StringOrdinal::CreateInitialOrdinal().Equals( + web_app_item->item_pin_ordinal)); + EXPECT_EQ(std::string(), web_app_item->parent_id); + } } +#endif // defined(OS_CHROMEOS) } // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_ui_service_factory.cc b/chrome/browser/ui/web_applications/web_app_ui_service_factory.cc index 1ef4395..1c2cb9d8 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_service_factory.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_service_factory.cc
@@ -10,6 +10,10 @@ #include "chrome/browser/web_applications/web_app_provider_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" +#endif + namespace web_app { // static @@ -26,9 +30,12 @@ WebAppUiServiceFactory::WebAppUiServiceFactory() : BrowserContextKeyedServiceFactory( - "WebAppUiDelegate", + "WebAppUiService", BrowserContextDependencyManager::GetInstance()) { DependsOn(WebAppProviderFactory::GetInstance()); +#if defined(OS_CHROMEOS) + DependsOn(app_list::AppListSyncableServiceFactory::GetInstance()); +#endif } WebAppUiServiceFactory::~WebAppUiServiceFactory() = default;
diff --git a/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc b/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc index b090037..c74e9651 100644 --- a/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc +++ b/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc
@@ -13,7 +13,6 @@ #include "base/strings/string16.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/bookmarks/bookmarks_message_handler.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/localized_string.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" @@ -179,7 +178,6 @@ // Set up the chrome://bookmarks/ source. Profile* profile = Profile::FromWebUI(web_ui); auto* source = CreateBookmarksUIHTMLSource(profile); - DarkModeHandler::Initialize(web_ui, source); ManagedUIHandler::Initialize(web_ui, source); content::WebUIDataSource::Add(profile, source);
diff --git a/chrome/browser/ui/webui/browser_switch/browser_switch_ui.cc b/chrome/browser/ui/webui/browser_switch/browser_switch_ui.cc index 273e5ce..89a2482 100644 --- a/chrome/browser/ui/webui/browser_switch/browser_switch_ui.cc +++ b/chrome/browser/ui/webui/browser_switch/browser_switch_ui.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" @@ -474,12 +473,10 @@ BrowserSwitchUI::BrowserSwitchUI(content::WebUI* web_ui) : WebUIController(web_ui) { - content::WebUIDataSource* data_source = - CreateBrowserSwitchUIHTMLSource(web_ui); - DarkModeHandler::Initialize(web_ui, data_source); web_ui->AddMessageHandler(std::make_unique<BrowserSwitchHandler>()); // Set up the chrome://browser-switch source. Profile* profile = Profile::FromWebUI(web_ui); - content::WebUIDataSource::Add(profile, data_source); + content::WebUIDataSource::Add(profile, + CreateBrowserSwitchUIHTMLSource(web_ui)); }
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc index 65ab20f..212c5f4 100644 --- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc +++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
@@ -373,7 +373,7 @@ base::trace_event::TraceConfig config( "-*,exo,viz,toplevel,gpu,cc,blink,disabled-by-default-android " - "gfx,disabled-by-default-android hal", + "gfx,disabled-by-default-android hal,disabled-by-default-android view", base::trace_event::RECORD_CONTINUOUSLY); config.EnableSystrace(); tracing_active_ = true;
diff --git a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc index 670f76e..e0f4c10 100644 --- a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc +++ b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
@@ -8,8 +8,11 @@ #include <stdint.h> #include <fstream> +#include <map> #include <memory> +#include <string> #include <utility> +#include <vector> #include "base/bind.h" #include "base/bind_helpers.h" @@ -24,6 +27,8 @@ #include "base/strings/stringprintf.h" #include "base/system/sys_info.h" #include "base/task/post_task.h" +#include "base/task/task_traits.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/chromeos/drive/debug_info_collector.h" #include "chrome/browser/chromeos/drive/drive_integration_service.h" #include "chrome/browser/chromeos/drive/file_system_util.h" @@ -33,7 +38,10 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" +#include "chrome/services/file_util/public/cpp/zip_file_creator.h" #include "chromeos/constants/chromeos_features.h" +#include "components/download/content/public/all_download_item_notifier.h" +#include "components/download/public/common/download_item.h" #include "components/drive/drive.pb.h" #include "components/drive/drive_api_util.h" #include "components/drive/drive_notification_manager.h" @@ -42,10 +50,14 @@ #include "components/drive/job_list.h" #include "components/drive/service/drive_service_interface.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "content/public/browser/web_ui_message_handler.h" +#include "content/public/common/service_manager_connection.h" #include "google_apis/drive/auth_service.h" #include "google_apis/drive/drive_api_error_codes.h" #include "google_apis/drive/drive_api_parser.h" @@ -277,6 +289,11 @@ return {inode, std::move(result)}; } +class DriveInternalsWebUIHandler; + +void ZipLogs(Profile* profile, + base::WeakPtr<DriveInternalsWebUIHandler> drive_internals); + // Class to handle messages from chrome://drive-internals. class DriveInternalsWebUIHandler : public content::WebUIMessageHandler { public: @@ -285,6 +302,13 @@ ~DriveInternalsWebUIHandler() override {} + void DownloadLogsZip(const base::FilePath& path) { + web_ui()->GetWebContents()->GetController().LoadURL( + net::FilePathToFileURL(path), {}, {}, {}); + } + + void OnZipDone() { MaybeCallJavascript("onZipDone", base::Value()); } + private: void MaybeCallJavascript(const std::string& function, base::Value data1, @@ -327,6 +351,10 @@ "listFileEntries", base::BindRepeating(&DriveInternalsWebUIHandler::ListFileEntries, weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "zipLogs", + base::BindRepeating(&DriveInternalsWebUIHandler::ZipDriveFsLogs, + weak_ptr_factory_.GetWeakPtr())); } // Called when the page is first loaded. @@ -877,6 +905,19 @@ UpdateFileSystemContentsSection(); } + void ZipDriveFsLogs(const base::ListValue* args) { + AllowJavascript(); + + drive::DriveIntegrationService* integration_service = + GetIntegrationService(); + if (!integration_service || + integration_service->GetDriveFsLogPath().empty()) { + return; + } + + ZipLogs(profile(), weak_ptr_factory_.GetWeakPtr()); + } + // Called after file system reset for ResetDriveFileSystem is done. void ResetFinished(bool success) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -929,6 +970,107 @@ DISALLOW_COPY_AND_ASSIGN(DriveInternalsWebUIHandler); }; +class LogsZipper : public download::AllDownloadItemNotifier::Observer { + public: + LogsZipper(Profile* profile, + base::WeakPtr<DriveInternalsWebUIHandler> drive_internals) + : profile_(profile), + logs_directory_( + drive::DriveIntegrationServiceFactory::FindForProfile(profile) + ->GetDriveFsLogPath() + .DirName()), + zip_path_(logs_directory_.AppendASCII(kLogsZipName)), + drive_internals_(std::move(drive_internals)) {} + + void Start() { + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, + base::BindOnce(&LogsZipper::EnumerateLogFiles, logs_directory_, + zip_path_), + base::BindOnce(&LogsZipper::ZipLogFiles, base::Unretained(this))); + } + + private: + static constexpr char kLogsZipName[] = "drivefs_logs.zip"; + + void ZipLogFiles(const std::vector<base::FilePath>& files) { + (new ZipFileCreator( + base::BindRepeating(&LogsZipper::OnZipDone, base::Unretained(this)), + logs_directory_, files, zip_path_)) + ->Start( + content::ServiceManagerConnection::GetForProcess()->GetConnector()); + } + + static std::vector<base::FilePath> EnumerateLogFiles( + base::FilePath logs_path, + base::FilePath zip_path) { + // Note: this may be racy if multiple attempts to export logs are run + // concurrently, but it's a debug page and it requires explicit action to + // cause problems. + base::DeleteFile(zip_path, false); + std::vector<base::FilePath> log_files; + base::FileEnumerator enumerator(logs_path, false /* recursive */, + base::FileEnumerator::FILES); + + for (base::FilePath current = enumerator.Next(); !current.empty(); + current = enumerator.Next()) { + if (!current.MatchesExtension(".zip")) { + log_files.push_back(current.BaseName()); + } + } + return log_files; + } + + void OnZipDone(bool success) { + if (!drive_internals_ || !success) { + CleanUp(); + return; + } + download_notifier_ = std::make_unique<download::AllDownloadItemNotifier>( + content::BrowserContext::GetDownloadManager(profile_), this); + drive_internals_->DownloadLogsZip(zip_path_); + } + + void OnDownloadUpdated(content::DownloadManager* manager, + download::DownloadItem* item) override { + if (item->GetState() == download::DownloadItem::IN_PROGRESS || + item->GetURL() != net::FilePathToFileURL(zip_path_)) { + return; + } + CleanUp(); + } + + void CleanUp() { + base::PostTaskWithTraits( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(base::IgnoreResult(&base::DeleteFile), zip_path_, + false)); + download_notifier_.reset(); + if (drive_internals_) { + drive_internals_->OnZipDone(); + } + base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); + } + + Profile* const profile_; + const base::FilePath logs_directory_; + const base::FilePath zip_path_; + + const base::WeakPtr<DriveInternalsWebUIHandler> drive_internals_; + + std::unique_ptr<download::AllDownloadItemNotifier> download_notifier_; + + DISALLOW_COPY_AND_ASSIGN(LogsZipper); +}; + +constexpr char LogsZipper::kLogsZipName[]; + +void ZipLogs(Profile* profile, + base::WeakPtr<DriveInternalsWebUIHandler> drive_internals) { + auto* logs_zipper = new LogsZipper(profile, std::move(drive_internals)); + logs_zipper->Start(); +} + } // namespace DriveInternalsUI::DriveInternalsUI(content::WebUI* web_ui)
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 40d1619..c48c2b1 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -831,6 +831,8 @@ user_context.SetAuthFlow(using_saml ? UserContext::AUTH_FLOW_GAIA_WITH_SAML : UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML); + if (using_saml) + user_context.SetIsUsingSamlPrincipalsApi(using_saml_api_); user_context.SetGAPSCookie(gaps_cookie); if (using_saml && ExtractSamlPasswordAttributesEnabled()) { user_context.SetSamlPasswordAttributes(password_attributes); @@ -983,6 +985,8 @@ user_context.SetAuthFlow(using_saml ? UserContext::AUTH_FLOW_GAIA_WITH_SAML : UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML); + if (using_saml) + user_context.SetIsUsingSamlPrincipalsApi(using_saml_api_); if (using_saml && ExtractSamlPasswordAttributesEnabled()) { user_context.SetSamlPasswordAttributes(password_attributes);
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h index 5dcd490d..27a2759 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -334,6 +334,10 @@ // If the user authenticated via SAML, this indicates whether the principals // API was used. + // TODO(emaxx): This is also currently set when the user authenticated via + // Gaia, since Gaia uses the same API for passing the password to Chrome. + // Either fix this behavior, or change the naming and the comments to reflect + // it. bool using_saml_api_ = false; // Test credentials.
diff --git a/chrome/browser/ui/webui/cookies_tree_model_util.cc b/chrome/browser/ui/webui/cookies_tree_model_util.cc index 799d6fb..9c94abc4 100644 --- a/chrome/browser/ui/webui/cookies_tree_model_util.cc +++ b/chrome/browser/ui/webui/cookies_tree_model_util.cc
@@ -299,16 +299,13 @@ } void CookiesTreeModelUtil::GetChildNodeDetails(const CookieTreeNode* parent, - int start, - int count, bool include_quota_nodes, base::ListValue* list) { std::string id_path = GetTreeNodeId(parent); - for (int i = 0; i < count; ++i) { - const CookieTreeNode* child = parent->GetChild(start + i); - int cookie_count = child->child_count(); - std::string cookie_id_path = id_path + "," + GetTreeNodeId(child) + ","; - for (int k = 0; k < cookie_count; ++k) { + for (const auto& child : parent->children()) { + std::string cookie_id_path = + id_path + "," + GetTreeNodeId(child.get()) + ","; + for (int k = 0; k < child->child_count(); ++k) { const CookieTreeNode* details = child->GetChild(k); std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); if (GetCookieTreeNodeDictionary(*details, include_quota_nodes,
diff --git a/chrome/browser/ui/webui/cookies_tree_model_util.h b/chrome/browser/ui/webui/cookies_tree_model_util.h index bac87974..9573508b 100644 --- a/chrome/browser/ui/webui/cookies_tree_model_util.h +++ b/chrome/browser/ui/webui/cookies_tree_model_util.h
@@ -29,10 +29,8 @@ // Finds or creates an ID for given |node| and returns it as string. std::string GetTreeNodeId(const CookieTreeNode* node); - // Append the details of the child nodes of |parent| in specified range. + // Append the details of the child nodes of |parent|. void GetChildNodeDetails(const CookieTreeNode* parent, - int start, - int count, bool include_quota_nodes, base::ListValue* list);
diff --git a/chrome/browser/ui/webui/dark_mode_handler.cc b/chrome/browser/ui/webui/dark_mode_handler.cc deleted file mode 100644 index d8ddd9c7..0000000 --- a/chrome/browser/ui/webui/dark_mode_handler.cc +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2018 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/dark_mode_handler.h" - -#include "base/bind.h" -#include "base/feature_list.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/chrome_features.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_data_source.h" -#include "ui/native_theme/native_theme.h" - -DarkModeHandler::~DarkModeHandler() {} - -// static -void DarkModeHandler::Initialize(content::WebUI* web_ui, - content::WebUIDataSource* source) { - InitializeInternal(web_ui, source, ui::NativeTheme::GetInstanceForNativeUi(), - Profile::FromWebUI(web_ui)); -} - -// static -void DarkModeHandler::InitializeInternal(content::WebUI* web_ui, - content::WebUIDataSource* source, - ui::NativeTheme* theme, - Profile* profile) { - auto handler = base::WrapUnique(new DarkModeHandler(theme, profile)); - source->AddLocalizedStrings(*handler->GetDataSourceUpdate()); - handler->source_name_ = source->GetSource(); - web_ui->AddMessageHandler(std::move(handler)); -} - -DarkModeHandler::DarkModeHandler(ui::NativeTheme* theme, Profile* profile) - : profile_(profile), - dark_mode_observer_( - theme, - base::BindRepeating(&DarkModeHandler::OnDarkModeChanged, - base::Unretained(this))) { - dark_mode_observer_.Start(); -} - -void DarkModeHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "observeDarkMode", - base::BindRepeating(&DarkModeHandler::HandleObserveDarkMode, - base::Unretained(this))); -} - -void DarkModeHandler::HandleObserveDarkMode(const base::ListValue* /*args*/) { - AllowJavascript(); -} - -bool DarkModeHandler::UseDarkMode() const { - return base::FeatureList::IsEnabled(features::kWebUIDarkMode) && - dark_mode_observer_.InDarkMode(); -} - -std::unique_ptr<base::DictionaryValue> DarkModeHandler::GetDataSourceUpdate() - const { - auto update = std::make_unique<base::DictionaryValue>(); - bool use_dark_mode = UseDarkMode(); - update->SetKey("dark", base::Value(use_dark_mode ? "dark" : "")); - return update; -} - -void DarkModeHandler::OnDarkModeChanged(bool /*dark_mode*/) { - content::WebUIDataSource::Update(profile_, source_name_, - GetDataSourceUpdate()); - if (IsJavascriptAllowed()) - FireWebUIListener("dark-mode-changed", base::Value(UseDarkMode())); -}
diff --git a/chrome/browser/ui/webui/dark_mode_handler.h b/chrome/browser/ui/webui/dark_mode_handler.h deleted file mode 100644 index 5215589..0000000 --- a/chrome/browser/ui/webui/dark_mode_handler.h +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2018 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_DARK_MODE_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_DARK_MODE_HANDLER_H_ - -#include <memory> -#include <string> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "content/public/browser/web_ui_message_handler.h" -#include "ui/native_theme/dark_mode_observer.h" -#include "ui/native_theme/native_theme.h" - -namespace base { -class ListValue; -} // namespace base - -namespace content { -class WebUI; -class WebUIDataSource; -} // namespace content - -namespace ui { -class NativeTheme; -} // namespace ui - -class Profile; - -class DarkModeHandler : public content::WebUIMessageHandler { - public: - ~DarkModeHandler() override; - - // Sets load-time constants on |source|. This handles a flicker-free initial - // page load (i.e. $i18n{dark}, loadTimeData.getBoolean('darkMode')). Adds a - // DarkModeHandler to |web_ui| if WebUI dark mode enhancements are enabled. - // If enabled, continually updates |source| by name if dark mode changes. This - // is so page refreshes will have fresh, correct data. Neither |web_ui| nor - // |source| may be nullptr. - static void Initialize(content::WebUI* web_ui, - content::WebUIDataSource* source); - - protected: - // Protected for testing. - static void InitializeInternal(content::WebUI* web_ui, - content::WebUIDataSource* source, - ui::NativeTheme* theme, - Profile* profile); - - explicit DarkModeHandler(ui::NativeTheme* theme, Profile* profile); - - private: - // content::WebUIMessageHandler: - void RegisterMessages() override; - - // Handles the "observeDarkMode" message. No arguments. Protected for testing. - void HandleObserveDarkMode(const base::ListValue* args); - - bool UseDarkMode() const; - - // Generates a dictionary with "dark" i18n key based on |using_dark_|. Called - // in Initialize() and on each change for notifications. - std::unique_ptr<base::DictionaryValue> GetDataSourceUpdate() const; - - void OnDarkModeChanged(bool dark_mode); - - // Profile to update data sources on. Injected for testing. - Profile* const profile_; - - ui::DarkModeObserver dark_mode_observer_; - - // Populated if feature is enabled. - std::string source_name_; - - DISALLOW_COPY_AND_ASSIGN(DarkModeHandler); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_DARK_MODE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/dark_mode_handler_unittest.cc b/chrome/browser/ui/webui/dark_mode_handler_unittest.cc deleted file mode 100644 index 81a5339..0000000 --- a/chrome/browser/ui/webui/dark_mode_handler_unittest.cc +++ /dev/null
@@ -1,212 +0,0 @@ -// Copyright 2018 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/dark_mode_handler.h" - -#include "base/test/scoped_feature_list.h" -#include "base/token.h" -#include "base/values.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/chrome_features.h" -#include "chrome/test/base/testing_profile.h" -#include "content/public/browser/web_ui_data_source.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_web_ui.h" -#include "content/public/test/test_web_ui_data_source.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/native_theme/test_native_theme.h" - -class TestDarkModeHandler : public DarkModeHandler { - public: - using DarkModeHandler::InitializeInternal; -}; - -class DarkModeHandlerTest : public testing::Test { - public: - DarkModeHandlerTest() - : source_(content::TestWebUIDataSource::Create( - base::Token::CreateRandom().ToString())) { - // We use a random source_name here as calling Add() can replace existing - // sources with the same name (which might destroy the memory addressed by - // |source()->GetWebUIDataSource()|. - content::WebUIDataSource::Add(&profile_, source()->GetWebUIDataSource()); - } - - content::TestBrowserThreadBundle* bundle() { return &bundle_; } - content::TestWebUI* web_ui() { return &web_ui_; } - ui::TestNativeTheme* theme() { return &theme_; } - base::test::ScopedFeatureList* features() { return &features_; } - content::TestWebUIDataSource* source() { return source_.get(); } - - void InitializeHandler() { - TestDarkModeHandler::InitializeInternal( - web_ui(), source()->GetWebUIDataSource(), theme(), &profile_); - } - - bool IsSourceDark() { - const auto* replacements = source()->GetReplacements(); - const auto dark_it = replacements->find("dark"); - - if (dark_it == replacements->end()) { - ADD_FAILURE(); - return false; - } - - return dark_it->second == "dark"; - } - - private: - content::TestBrowserThreadBundle bundle_; - TestingProfile profile_; - base::test::ScopedFeatureList features_; - content::TestWebUI web_ui_; - ui::TestNativeTheme theme_; - std::unique_ptr<content::TestWebUIDataSource> source_; -}; - -TEST_F(DarkModeHandlerTest, WebUIDarkModeDisabledLightMode) { - features()->InitAndDisableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(false); - - InitializeHandler(); - - EXPECT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - EXPECT_FALSE(IsSourceDark()); -} - -TEST_F(DarkModeHandlerTest, WebUIDarkModeDisabledDarkMode) { - features()->InitAndDisableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(true); - - InitializeHandler(); - - EXPECT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - // Even if in dark mode, if the feature's disabled we shouldn't be telling the - // page to be dark. - EXPECT_FALSE(IsSourceDark()); -} - -TEST_F(DarkModeHandlerTest, WebUIDarkModeDisabledNoNotifications) { - features()->InitAndDisableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(false); - - InitializeHandler(); - - EXPECT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - EXPECT_FALSE(IsSourceDark()); - - theme()->SetDarkMode(true); - theme()->NotifyObservers(); - - EXPECT_EQ(web_ui()->call_data().size(), 0u); - EXPECT_FALSE(IsSourceDark()); -} - -TEST_F(DarkModeHandlerTest, WebUIDarkModeEnabledInLightMode) { - features()->InitAndEnableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(false); - - InitializeHandler(); - - EXPECT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - EXPECT_FALSE(IsSourceDark()); -} - -TEST_F(DarkModeHandlerTest, WebUIDarkModeEnabledInDarkMode) { - features()->InitAndEnableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(true); - - InitializeHandler(); - - EXPECT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - EXPECT_TRUE(IsSourceDark()); -} - -TEST_F(DarkModeHandlerTest, NotifiesAndUpdatesOnChange) { - features()->InitAndEnableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(false); - - InitializeHandler(); - - ASSERT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - EXPECT_FALSE(IsSourceDark()); - - web_ui()->HandleReceivedMessage("observeDarkMode", /*args=*/nullptr); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - // Theme changes unrelated to dark mode should not notify. - theme()->NotifyObservers(); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - theme()->SetDarkMode(true); - theme()->NotifyObservers(); - bundle()->RunUntilIdle(); - - EXPECT_TRUE(IsSourceDark()); - ASSERT_EQ(web_ui()->call_data().size(), 1u); - - EXPECT_STREQ(web_ui()->call_data()[0]->function_name().c_str(), - "cr.webUIListenerCallback"); - - ASSERT_TRUE(web_ui()->call_data()[0]->arg1()); - ASSERT_TRUE(web_ui()->call_data()[0]->arg1()->is_string()); - EXPECT_STREQ(web_ui()->call_data()[0]->arg1()->GetString().c_str(), - "dark-mode-changed"); - - ASSERT_TRUE(web_ui()->call_data()[0]->arg2()); - ASSERT_TRUE(web_ui()->call_data()[0]->arg2()->is_bool()); - EXPECT_TRUE(web_ui()->call_data()[0]->arg2()->GetBool()); -} - -TEST_F(DarkModeHandlerTest, DarkModeChangeBeforeJsAllowed) { - features()->InitAndEnableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(false); - - InitializeHandler(); - - EXPECT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - EXPECT_FALSE(IsSourceDark()); - - theme()->SetDarkMode(true); - theme()->NotifyObservers(); - - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - bundle()->RunUntilIdle(); - EXPECT_TRUE(IsSourceDark()); -} - -TEST_F(DarkModeHandlerTest, DarkModeChangeWhileJsDisallowed) { - features()->InitAndEnableFeature(features::kWebUIDarkMode); - theme()->SetDarkMode(false); - - InitializeHandler(); - - EXPECT_EQ(web_ui()->GetHandlersForTesting()->size(), 1u); - EXPECT_EQ(web_ui()->call_data().size(), 0u); - EXPECT_FALSE(IsSourceDark()); - - web_ui()->HandleReceivedMessage("observeDarkMode", /*args=*/nullptr); - web_ui()->GetHandlersForTesting()->front()->DisallowJavascript(); - - theme()->SetDarkMode(true); - theme()->NotifyObservers(); - - EXPECT_EQ(web_ui()->call_data().size(), 0u); - - bundle()->RunUntilIdle(); - EXPECT_TRUE(IsSourceDark()); -}
diff --git a/chrome/browser/ui/webui/downloads/downloads_ui.cc b/chrome/browser/ui/webui/downloads/downloads_ui.cc index 0a90fa6e..b2b55ef5 100644 --- a/chrome/browser/ui/webui/downloads/downloads_ui.cc +++ b/chrome/browser/ui/webui/downloads/downloads_ui.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/defaults.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/downloads/downloads_dom_handler.h" #include "chrome/browser/ui/webui/localized_string.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" @@ -167,7 +166,6 @@ // Set up the chrome://downloads/ source. content::WebUIDataSource* source = CreateDownloadsUIHTMLSource(profile); - DarkModeHandler::Initialize(web_ui, source); ManagedUIHandler::Initialize(web_ui, source); content::WebUIDataSource::Add(profile, source); content::URLDataSource::Add(profile, std::make_unique<ThemeSource>(profile));
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 05ea729..b08cee7d 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/chrome_extension_browser_constants.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/localized_string.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" @@ -325,7 +324,6 @@ base::Bind(&ExtensionsUI::OnDevModeChanged, base::Unretained(this))); source = CreateMdExtensionsSource(profile, *in_dev_mode_); - DarkModeHandler::Initialize(web_ui, source); ManagedUIHandler::Initialize(web_ui, source); #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/flags_ui.cc b/chrome/browser/ui/webui/flags_ui.cc index ad3e0322..fb09bb6 100644 --- a/chrome/browser/ui/webui/flags_ui.cc +++ b/chrome/browser/ui/webui/flags_ui.cc
@@ -51,10 +51,6 @@ #include "components/user_manager/user_manager.h" #endif -#if !defined(OS_ANDROID) -#include "chrome/browser/ui/webui/dark_mode_handler.h" -#endif - using content::WebContents; using content::WebUIMessageHandler; @@ -351,13 +347,7 @@ #endif // Set up the about:flags source. - auto* source = CreateFlagsUIHTMLSource(); -#if !defined(OS_ANDROID) - // Android hasn't implemented NativeTheme::SystemDarkModeEnabled() yet, which - // DarkModeHandler relies on to determine "darkness". - DarkModeHandler::Initialize(web_ui, source); -#endif - content::WebUIDataSource::Add(profile, source); + content::WebUIDataSource::Add(profile, CreateFlagsUIHTMLSource()); } FlagsUI::~FlagsUI() {
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc index 215689d..8c4b735 100644 --- a/chrome/browser/ui/webui/history_ui.cc +++ b/chrome/browser/ui/webui/history_ui.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/webui/browsing_history_handler.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/foreign_session_handler.h" #include "chrome/browser/ui/webui/history_login_handler.h" #include "chrome/browser/ui/webui/localized_string.h" @@ -178,7 +177,6 @@ HistoryUI::HistoryUI(content::WebUI* web_ui) : WebUIController(web_ui) { Profile* profile = Profile::FromWebUI(web_ui); content::WebUIDataSource* data_source = CreateHistoryUIHTMLSource(profile); - DarkModeHandler::Initialize(web_ui, data_source); ManagedUIHandler::Initialize(web_ui, data_source); content::WebUIDataSource::Add(profile, data_source);
diff --git a/chrome/browser/ui/webui/management_ui.cc b/chrome/browser/ui/webui/management_ui.cc index 8801658..32098159 100644 --- a/chrome/browser/ui/webui/management_ui.cc +++ b/chrome/browser/ui/webui/management_ui.cc
@@ -10,7 +10,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/localized_string.h" #include "chrome/browser/ui/webui/management_ui_handler.h" #include "chrome/common/url_constants.h" @@ -173,7 +172,6 @@ content::WebUIDataSource* source = CreateManagementUIHtmlSource(Profile::FromWebUI(web_ui)); ManagementUIHandler::Initialize(web_ui, source); - DarkModeHandler::Initialize(web_ui, source); content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source); }
diff --git a/chrome/browser/ui/webui/page_not_available_for_guest/page_not_available_for_guest_ui.cc b/chrome/browser/ui/webui/page_not_available_for_guest/page_not_available_for_guest_ui.cc index 1cf3620..b33b6ad 100644 --- a/chrome/browser/ui/webui/page_not_available_for_guest/page_not_available_for_guest_ui.cc +++ b/chrome/browser/ui/webui/page_not_available_for_guest/page_not_available_for_guest_ui.cc
@@ -6,7 +6,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" @@ -49,7 +48,5 @@ const std::string& host_name) : WebUIController(web_ui) { Profile* profile = Profile::FromWebUI(web_ui); - auto* source = CreateHTMLSource(profile, host_name); - DarkModeHandler::Initialize(web_ui, source); - content::WebUIDataSource::Add(profile, source); + content::WebUIDataSource::Add(profile, CreateHTMLSource(profile, host_name)); }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index 260a56b9..46b7e8d 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -144,6 +144,7 @@ FIT_TO_PAGE, DEFAULT_DPI, NON_DEFAULT_DPI, + PIN, PRINT_SETTINGS_BUCKET_BOUNDARY }; @@ -401,6 +402,11 @@ : NON_DEFAULT_DPI); } } + +#if defined(OS_CHROMEOS) + if (print_settings.FindStringKey(kSettingPinValue)) + ReportPrintSettingHistogram(PIN); +#endif // defined(OS_CHROMEOS) } UserActionBuckets DetermineUserAction(const base::Value& settings) {
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 f90198e..d79c41a 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/printing/print_preview_data_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/localized_string.h" #include "chrome/browser/ui/webui/metrics_handler.h" #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h" @@ -479,9 +478,7 @@ handler_(CreatePrintPreviewHandlers(web_ui)) { // Set up the chrome://print/ data source. Profile* profile = Profile::FromWebUI(web_ui); - content::WebUIDataSource* source = CreatePrintPreviewUISource(profile); - DarkModeHandler::Initialize(web_ui, source); - content::WebUIDataSource::Add(profile, source); + content::WebUIDataSource::Add(profile, CreatePrintPreviewUISource(profile)); // Set up the chrome://theme/ source. content::URLDataSource::Add(profile, std::make_unique<ThemeSource>(profile));
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc index d9c9442..0e8f700 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -13,7 +13,6 @@ #include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" #include "build/build_config.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" #include "chrome/browser/ui/webui/plural_string_handler.h" @@ -144,7 +143,6 @@ IDS_OS_SETTINGS_PROFILE_LABEL); web_ui->AddMessageHandler(std::move(plural_string_handler)); - DarkModeHandler::Initialize(web_ui, html_source); ManagedUIHandler::Initialize(web_ui, html_source); content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
diff --git a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc index 6fa7096..0e1ed21 100644 --- a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
@@ -458,9 +458,7 @@ // Passing false for |include_quota_nodes| since they don't reflect reality // until bug http://crbug.com/642955 is fixed and local/session storage is // counted against the total. - model_util_->GetChildNodeDetails(parent, /*start=*/0, parent->child_count(), - /*include_quota_nodes=*/false, - children.get()); + model_util_->GetChildNodeDetails(parent, false, children.get()); base::DictionaryValue args; if (parent == cookies_tree_model_->GetRoot())
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index 7b8f140..8e5a417 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -20,7 +20,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" #include "chrome/browser/ui/webui/settings/about_handler.h" @@ -340,7 +339,6 @@ AddLocalizedStrings(html_source, profile); - DarkModeHandler::Initialize(web_ui, html_source); ManagedUIHandler::Initialize(web_ui, html_source); content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc index b4801fd..87208b1 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/signin/sync_confirmation_handler.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" @@ -105,7 +104,6 @@ g_browser_process->GetApplicationLocale(), &strings); source->AddLocalizedStrings(strings); - DarkModeHandler::Initialize(web_ui, source); content::WebUIDataSource::Add(profile, source); }
diff --git a/chrome/browser/ui/webui/signin/user_manager_ui.cc b/chrome/browser/ui/webui/signin/user_manager_ui.cc index 5b44baee..9e65e526 100644 --- a/chrome/browser/ui/webui/signin/user_manager_ui.cc +++ b/chrome/browser/ui/webui/signin/user_manager_ui.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_shortcut_manager.h" #include "chrome/browser/signin/signin_util.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/signin/signin_create_profile_handler.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h" @@ -43,9 +42,7 @@ Profile* profile = Profile::FromWebUI(web_ui); // Set up the chrome://md-user-manager/ source. - auto* user_source = CreateUIDataSource(localized_strings); - DarkModeHandler::Initialize(web_ui, user_source); - content::WebUIDataSource::Add(profile, user_source); + content::WebUIDataSource::Add(profile, CreateUIDataSource(localized_strings)); // Set up the chrome://theme/ source content::URLDataSource::Add(profile, std::make_unique<ThemeSource>(profile));
diff --git a/chrome/browser/ui/webui/site_settings_helper.cc b/chrome/browser/ui/webui/site_settings_helper.cc index 6dd81e1..d2a3a45a4 100644 --- a/chrome/browser/ui/webui/site_settings_helper.cc +++ b/chrome/browser/ui/webui/site_settings_helper.cc
@@ -116,6 +116,8 @@ {CONTENT_SETTINGS_TYPE_BACKGROUND_FETCH, nullptr}, {CONTENT_SETTINGS_TYPE_INTENT_PICKER_DISPLAY, nullptr}, {CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC, nullptr}, + {CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN, nullptr}, + {CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM, nullptr}, }; static_assert(base::size(kContentSettingsTypeGroupNames) == // ContentSettingsType starts at -1, so add 1 here.
diff --git a/chrome/browser/ui/webui/welcome/welcome_ui.cc b/chrome/browser/ui/webui/welcome/welcome_ui.cc index a7b4644..5002a57 100644 --- a/chrome/browser/ui/webui/welcome/welcome_ui.cc +++ b/chrome/browser/ui/webui/welcome/welcome_ui.cc
@@ -9,7 +9,6 @@ #include "base/stl_util.h" #include "build/build_config.h" #include "chrome/browser/signin/account_consistency_mode_manager.h" -#include "chrome/browser/ui/webui/dark_mode_handler.h" #include "chrome/browser/ui/webui/localized_string.h" #include "chrome/browser/ui/webui/welcome/nux/bookmark_handler.h" #include "chrome/browser/ui/webui/welcome/nux/constants.h" @@ -149,8 +148,6 @@ content::WebUIDataSource* html_source = content::WebUIDataSource::Create(url.host()); - DarkModeHandler::Initialize(web_ui, html_source); - // There are multiple possible configurations that affects the layout, but // first add resources that are shared across all layouts. html_source->AddResourcePath("logo.png", IDR_PRODUCT_LOGO_128);
diff --git a/chrome/browser/wake_lock/OWNERS b/chrome/browser/wake_lock/OWNERS new file mode 100644 index 0000000..077be6b --- /dev/null +++ b/chrome/browser/wake_lock/OWNERS
@@ -0,0 +1,6 @@ +file://third_party/blink/renderer/modules/wake_lock/OWNERS + +per-file *permission_context*=file://chrome/browser/permissions/PERMISSIONS_OWNERS + +# COMPONENT: Blink>WakeLock +# TEAM: device-dev@chromium.org
diff --git a/chrome/browser/wake_lock/wake_lock_permission_context.cc b/chrome/browser/wake_lock/wake_lock_permission_context.cc new file mode 100644 index 0000000..5b8226f --- /dev/null +++ b/chrome/browser/wake_lock/wake_lock_permission_context.cc
@@ -0,0 +1,40 @@ +// 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. + +#include "chrome/browser/wake_lock/wake_lock_permission_context.h" + +#include "base/logging.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h" + +WakeLockPermissionContext::WakeLockPermissionContext( + Profile* profile, + ContentSettingsType content_settings_type) + : PermissionContextBase(profile, + content_settings_type, + blink::mojom::FeaturePolicyFeature::kWakeLock), + content_settings_type_(content_settings_type) { + DCHECK(content_settings_type == CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN || + content_settings_type == CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM); +} + +WakeLockPermissionContext::~WakeLockPermissionContext() {} + +ContentSetting WakeLockPermissionContext::GetPermissionStatusInternal( + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + const GURL& embedding_origin) const { + switch (content_settings_type_) { + case CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN: + return CONTENT_SETTING_ALLOW; + case CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM: + return CONTENT_SETTING_BLOCK; + default: + NOTREACHED(); + return CONTENT_SETTING_BLOCK; + } +} + +bool WakeLockPermissionContext::IsRestrictedToSecureOrigins() const { + return true; +}
diff --git a/chrome/browser/wake_lock/wake_lock_permission_context.h b/chrome/browser/wake_lock/wake_lock_permission_context.h new file mode 100644 index 0000000..d444722 --- /dev/null +++ b/chrome/browser/wake_lock/wake_lock_permission_context.h
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WAKE_LOCK_WAKE_LOCK_PERMISSION_CONTEXT_H_ +#define CHROME_BROWSER_WAKE_LOCK_WAKE_LOCK_PERMISSION_CONTEXT_H_ + +#include "base/macros.h" +#include "chrome/browser/permissions/permission_context_base.h" +#include "components/content_settings/core/common/content_settings_types.h" + +class WakeLockPermissionContext : public PermissionContextBase { + public: + WakeLockPermissionContext(Profile* profile, + ContentSettingsType content_settings_type); + + ~WakeLockPermissionContext() override; + + private: + // PermissionContextBase: + ContentSetting GetPermissionStatusInternal( + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + const GURL& embedding_origin) const override; + bool IsRestrictedToSecureOrigins() const override; + + ContentSettingsType content_settings_type_; + + DISALLOW_COPY_AND_ASSIGN(WakeLockPermissionContext); +}; + +#endif // CHROME_BROWSER_WAKE_LOCK_WAKE_LOCK_PERMISSION_CONTEXT_H_
diff --git a/chrome/browser/wake_lock/wake_lock_permission_context_unittest.cc b/chrome/browser/wake_lock/wake_lock_permission_context_unittest.cc new file mode 100644 index 0000000..3130df0 --- /dev/null +++ b/chrome/browser/wake_lock/wake_lock_permission_context_unittest.cc
@@ -0,0 +1,67 @@ +// 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. + +#include "chrome/browser/wake_lock/wake_lock_permission_context.h" + +#include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/common/content_settings.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class WakeLockPermissionContextTests : public testing::Test { + public: + TestingProfile* profile() { return &profile_; } + + private: + content::TestBrowserThreadBundle thread_bundle_; + TestingProfile profile_; +}; + +TEST_F(WakeLockPermissionContextTests, InsecureOriginsAreRejected) { + GURL insecure_url("http://www.example.com"); + GURL secure_url("https://www.example.com"); + + const ContentSettingsType kWakeLockTypes[] = { + CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN, + CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM}; + + for (const auto& content_settings_type : kWakeLockTypes) { + WakeLockPermissionContext permission_context(profile(), + content_settings_type); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + permission_context + .GetPermissionStatus(/*render_frame_host=*/nullptr, + insecure_url, insecure_url) + .content_setting); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + permission_context + .GetPermissionStatus(/*render_frame_host=*/nullptr, + insecure_url, secure_url) + .content_setting); + } +} + +TEST_F(WakeLockPermissionContextTests, TestScreenLockPermissionRequest) { + WakeLockPermissionContext permission_context( + profile(), CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN); + GURL url("https://www.example.com"); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + permission_context + .GetPermissionStatus(/*render_frame_host=*/nullptr, url, url) + .content_setting); +} + +TEST_F(WakeLockPermissionContextTests, TestSystemLockPermissionRequest) { + WakeLockPermissionContext permission_context( + profile(), CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM); + GURL url("https://www.example.com"); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + permission_context + .GetPermissionStatus(/*render_frame_host=*/nullptr, url, url) + .content_setting); +} + +} // namespace
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index e745545..f51c682 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -49,7 +49,10 @@ ] if (is_chromeos) { - deps += [ "//chromeos/constants" ] + deps += [ + "//ash/public/cpp:cpp", + "//chromeos/constants", + ] } public_deps = [
diff --git a/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc index e76b6979..fe8aebb 100644 --- a/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc
@@ -167,6 +167,7 @@ std::unique_ptr<KeyedService> CreateWebAppProvider(Profile* profile) { auto provider = std::make_unique<TestWebAppProvider>(profile); + provider->Init(); auto test_pending_app_manager = std::make_unique<TestPendingAppManager>(); test_pending_app_manager_ = test_pending_app_manager.get();
diff --git a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc index 9018776..98dfb6a 100644 --- a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc
@@ -155,9 +155,9 @@ test_system_web_app_manager_ = test_system_web_app_manager.get(); provider->SetSystemWebAppManager(std::move(test_system_web_app_manager)); - base::flat_map<SystemAppType, GURL> system_apps; - system_apps[SystemAppType::SETTINGS] = - content::GetWebUIURL("test-system-app/pwa.html"); + base::flat_map<SystemAppType, SystemAppInfo> system_apps; + system_apps[SystemAppType::SETTINGS] = { + content::GetWebUIURL("test-system-app/pwa.html")}; test_system_web_app_manager_->SetSystemApps(std::move(system_apps)); // Start registry and all dependent subsystems:
diff --git a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc index 3712e38..a9b3c74f 100644 --- a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc +++ b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/web_applications/components/test_pending_app_manager.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/test/test_system_web_app_manager.h" +#include "chrome/browser/web_applications/test/test_web_app_ui_delegate.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" @@ -101,11 +102,14 @@ return system_web_app_manager_; } + TestWebAppUiDelegate* ui_delegate() { return &ui_delegate_; } + private: base::test::ScopedFeatureList scoped_feature_list_; TestWebAppProviderCreator test_web_app_provider_creator_; TestPendingAppManager* test_pending_app_manager_ = nullptr; TestSystemWebAppManager* system_web_app_manager_ = nullptr; + TestWebAppUiDelegate ui_delegate_; DISALLOW_COPY_AND_ASSIGN(SystemWebAppManagerTest); }; @@ -117,11 +121,11 @@ SimulatePreviouslyInstalledApp(kAppUrl1, InstallSource::kSystemInstalled); - base::flat_map<SystemAppType, GURL> system_apps; - system_apps[SystemAppType::SETTINGS] = kAppUrl1; + base::flat_map<SystemAppType, SystemAppInfo> system_apps; + system_apps[SystemAppType::SETTINGS] = {kAppUrl1}; system_web_app_manager()->SetSystemApps(std::move(system_apps)); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); @@ -135,12 +139,12 @@ // Test that System Apps do install with the feature enabled. TEST_F(SystemWebAppManagerTest, Enabled) { - base::flat_map<SystemAppType, GURL> system_apps; - system_apps[SystemAppType::SETTINGS] = kAppUrl1; - system_apps[SystemAppType::DISCOVER] = kAppUrl2; + base::flat_map<SystemAppType, SystemAppInfo> system_apps; + system_apps[SystemAppType::SETTINGS] = {kAppUrl1}; + system_apps[SystemAppType::DISCOVER] = {kAppUrl2}; system_web_app_manager()->SetSystemApps(std::move(system_apps)); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); const auto& apps_to_install = pending_app_manager()->install_requests(); @@ -154,11 +158,11 @@ SimulatePreviouslyInstalledApp(kAppUrl1, InstallSource::kSystemInstalled); SimulatePreviouslyInstalledApp(kAppUrl2, InstallSource::kSystemInstalled); SimulatePreviouslyInstalledApp(kAppUrl3, InstallSource::kInternal); - base::flat_map<SystemAppType, GURL> system_apps; - system_apps[SystemAppType::SETTINGS] = kAppUrl1; + base::flat_map<SystemAppType, SystemAppInfo> system_apps; + system_apps[SystemAppType::SETTINGS] = {kAppUrl1}; system_web_app_manager()->SetSystemApps(std::move(system_apps)); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); @@ -178,21 +182,21 @@ system_web_app_manager()->SetUpdatePolicy( SystemWebAppManager::UpdatePolicy::kAlwaysUpdate); - base::flat_map<SystemAppType, GURL> system_apps; - system_apps[SystemAppType::SETTINGS] = kAppUrl1; + base::flat_map<SystemAppType, SystemAppInfo> system_apps; + system_apps[SystemAppType::SETTINGS] = {kAppUrl1}; system_web_app_manager()->SetSystemApps(system_apps); system_web_app_manager()->set_current_version(base::Version("1.0.0.0")); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1u, pending_app_manager()->install_requests().size()); // Create another app. The version hasn't changed but the app should still // install. - system_apps[SystemAppType::DISCOVER] = kAppUrl2; + system_apps[SystemAppType::DISCOVER] = {kAppUrl2}; system_web_app_manager()->SetSystemApps(system_apps); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(3u, pending_app_manager()->install_requests().size()); @@ -202,14 +206,14 @@ base::test::ScopedFeatureList disable_feature_list; disable_feature_list.InitWithFeatures({}, {features::kSystemWebApps}); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(2u, pending_app_manager()->uninstall_requests().size()); } // Re-enabling System Web Apps installs without a version change. - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(5u, pending_app_manager()->install_requests().size()); @@ -219,21 +223,21 @@ system_web_app_manager()->SetUpdatePolicy( SystemWebAppManager::UpdatePolicy::kOnVersionChange); - base::flat_map<SystemAppType, GURL> system_apps; - system_apps[SystemAppType::SETTINGS] = kAppUrl1; + base::flat_map<SystemAppType, SystemAppInfo> system_apps; + system_apps[SystemAppType::SETTINGS] = {kAppUrl1}; system_web_app_manager()->SetSystemApps(system_apps); system_web_app_manager()->set_current_version(base::Version("1.0.0.0")); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1u, pending_app_manager()->install_requests().size()); // Create another app. The version hasn't changed so the install won't // process. - system_apps[SystemAppType::DISCOVER] = kAppUrl2; + system_apps[SystemAppType::DISCOVER] = {kAppUrl2}; system_web_app_manager()->SetSystemApps(system_apps); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1u, pending_app_manager()->install_requests().size()); @@ -241,7 +245,7 @@ // Bump the version number, and the install will trigger, and request // installation of both apps. system_web_app_manager()->set_current_version(base::Version("2.0.0.0")); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(3u, pending_app_manager()->install_requests().size()); @@ -251,14 +255,14 @@ base::test::ScopedFeatureList disable_feature_list; disable_feature_list.InitWithFeatures({}, {features::kSystemWebApps}); - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(2u, pending_app_manager()->uninstall_requests().size()); } // Re-enabling System Web Apps installs even without a version change. - system_web_app_manager()->Start(); + system_web_app_manager()->Start(ui_delegate()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(5u, pending_app_manager()->install_requests().size());
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm index 79f0cdf..31e6cdc 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm +++ b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm
@@ -211,7 +211,7 @@ return false; } -bool AppShimsDisabledForTest() { +bool AppShimCreationDisabledForTest() { // Disable app shims in tests because shims created in ~/Applications will not // be cleaned up. return base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType); @@ -630,7 +630,7 @@ } bool AppShimLaunchDisabled() { - return AppShimsDisabledForTest() && + return AppShimCreationDisabledForTest() && !g_app_shims_allow_update_and_launch_in_tests; } @@ -644,13 +644,13 @@ base::FilePath WebAppShortcutCreator::GetApplicationsShortcutPath( bool avoid_conflicts) const { + if (g_app_shims_allow_update_and_launch_in_tests) + return app_data_dir_.Append(GetShortcutBasename()); + base::FilePath applications_dir = GetApplicationsDirname(); if (applications_dir.empty()) return base::FilePath(); - if (g_app_shims_allow_update_and_launch_in_tests) - return app_data_dir_.Append(GetShortcutBasename()); - if (!avoid_conflicts) return applications_dir.Append(GetShortcutBasename()); @@ -871,30 +871,18 @@ LOG(ERROR) << "Failed to localize " << applications_dir.value(); } - // Get the list of paths to (re)create. - std::vector<base::FilePath> app_paths; - if (g_app_shims_allow_update_and_launch_in_tests) { - // Never look in ~/Applications or search the system for a bundle ID in a - // test since that relies on global system state and potentially cruft that - // may be leftover from prior/crashed test runs. - // TODO(tapted): Remove this check when tests that arrive here via setting - // |g_app_shims_allow_update_and_launch_in_tests| can properly mock out all - // the calls below. - app_paths.push_back(app_data_dir_.Append(GetShortcutBasename())); - } else { - // Update all copies located by bundle id (wherever it was moved or copied - // by the user). - app_paths = GetAppBundlesById(); + // Get the list of paths to (re)create by bundle id (wherever it was moved + // or copied by the user). + std::vector<base::FilePath> app_paths = GetAppBundlesById(); - // If that path does not exist, create a new entry in ~/Applications if - // requested. - if (app_paths.empty() && create_if_needed) { - app_paths.push_back( - GetApplicationsShortcutPath(true /* avoid_conflicts */)); - } - if (app_paths.empty()) - return false; + // If that path does not exist, create a new entry in ~/Applications if + // requested. + if (app_paths.empty() && create_if_needed) { + app_paths.push_back( + GetApplicationsShortcutPath(true /* avoid_conflicts */)); } + if (app_paths.empty()) + return false; CreateShortcutsAt(app_paths, updated_paths); return updated_paths->size() == app_paths.size(); @@ -1061,6 +1049,15 @@ // Sort the matches by preference. base::FilePath default_path = GetApplicationsShortcutPath(false /* avoid_conflicts */); + + // When testing, use only the default path. + if (g_app_shims_allow_update_and_launch_in_tests) { + paths.clear(); + if (base::PathExists(default_path)) + paths.push_back(default_path); + return paths; + } + base::FilePath apps_dir = GetApplicationsDirname(); auto compare = [default_path, apps_dir](const base::FilePath& a, const base::FilePath& b) { @@ -1155,7 +1152,7 @@ const ShortcutInfo& shortcut_info) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); - if (AppShimsDisabledForTest()) + if (AppShimCreationDisabledForTest()) return true; WebAppShortcutCreator shortcut_creator(app_data_path, &shortcut_info); @@ -1181,8 +1178,12 @@ web_app::WebAppShortcutCreator shortcut_creator(app_data_path, &shortcut_info); std::vector<base::FilePath> updated_shim_paths; - shortcut_creator.UpdateShortcuts(false /* create_if_needed */, - &updated_shim_paths); + bool create_if_needed = false; + // Tests use web_app::UpdateAllShortcuts to force shim creation (rather than + // relying on asynchronous creation at installation. + if (g_app_shims_allow_update_and_launch_in_tests) + create_if_needed = true; + shortcut_creator.UpdateShortcuts(create_if_needed, &updated_shim_paths); } void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) {
diff --git a/chrome/browser/web_applications/components/web_app_ui_delegate.h b/chrome/browser/web_applications/components/web_app_ui_delegate.h index 1ae5e90..4eb84b37 100644 --- a/chrome/browser/web_applications/components/web_app_ui_delegate.h +++ b/chrome/browser/web_applications/components/web_app_ui_delegate.h
@@ -18,6 +18,10 @@ virtual void NotifyOnAllAppWindowsClosed(const AppId& app_id, base::OnceClosure callback) = 0; + + // Migrates an app's OS attributes (e.g pin position, app list + // folder/position, shortcuts). + virtual void MigrateOSAttributes(const AppId& from, const AppId& to) = 0; }; } // namespace web_app
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc index a616157..5c6020c 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc
@@ -113,7 +113,7 @@ for (const auto& id_and_url : web_app::ExternallyInstalledWebAppPrefs::BuildAppIdsMap( profile_->GetPrefs(), install_source)) { - if (registrar_->IsInstalled(id_and_url.second)) + if (registrar_->IsInstalled(id_and_url.first)) installed_apps.push_back(id_and_url.second); }
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index dad7c61..b247cd8 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -14,6 +14,7 @@ #include "base/version.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/components/web_app_constants.h" +#include "chrome/browser/web_applications/components/web_app_ui_delegate.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" @@ -23,6 +24,7 @@ #include "content/public/common/content_switches.h" #if defined(OS_CHROMEOS) +#include "ash/public/cpp/app_list/internal_app_id_constants.h" #include "chromeos/constants/chromeos_features.h" #endif // defined(OS_CHROMEOS) @@ -30,30 +32,32 @@ namespace { -base::flat_map<SystemAppType, GURL> CreateSystemWebApps() { - base::flat_map<SystemAppType, GURL> urls; - +base::flat_map<SystemAppType, SystemAppInfo> CreateSystemWebApps() { + base::flat_map<SystemAppType, SystemAppInfo> infos; // TODO(calamity): Split this into per-platform functions. #if defined(OS_CHROMEOS) if (base::FeatureList::IsEnabled(chromeos::features::kDiscoverApp)) - urls[SystemAppType::DISCOVER] = GURL(chrome::kChromeUIDiscoverURL); + infos[SystemAppType::DISCOVER] = {GURL(chrome::kChromeUIDiscoverURL)}; if (base::FeatureList::IsEnabled(chromeos::features::kSplitSettings)) { constexpr char kChromeSettingsPWAURL[] = "chrome://os-settings/pwa.html"; - urls[SystemAppType::SETTINGS] = GURL(kChromeSettingsPWAURL); + infos[SystemAppType::SETTINGS] = {GURL(kChromeSettingsPWAURL), + app_list::kInternalAppIdSettings}; } else { constexpr char kChromeSettingsPWAURL[] = "chrome://settings/pwa.html"; - urls[SystemAppType::SETTINGS] = GURL(kChromeSettingsPWAURL); + infos[SystemAppType::SETTINGS] = {GURL(kChromeSettingsPWAURL), + app_list::kInternalAppIdSettings}; } #endif // OS_CHROMEOS - return urls; + return infos; } -InstallOptions CreateInstallOptionsForSystemApp(const GURL& url) { - DCHECK_EQ(content::kChromeUIScheme, url.scheme()); +InstallOptions CreateInstallOptionsForSystemApp(const SystemAppInfo& info) { + DCHECK_EQ(content::kChromeUIScheme, info.install_url.scheme()); - web_app::InstallOptions install_options(url, LaunchContainer::kWindow, + web_app::InstallOptions install_options(info.install_url, + LaunchContainer::kWindow, InstallSource::kSystemInstalled); install_options.add_to_applications_menu = false; install_options.add_to_desktop = false; @@ -86,12 +90,14 @@ // Dev builds should update every launch. update_policy_ = UpdatePolicy::kAlwaysUpdate; #endif - system_app_urls_ = CreateSystemWebApps(); + system_app_infos_ = CreateSystemWebApps(); } SystemWebAppManager::~SystemWebAppManager() = default; -void SystemWebAppManager::Start() { +void SystemWebAppManager::Start(WebAppUiDelegate* ui_delegate) { + ui_delegate_ = ui_delegate; + // Clear the last update pref here to force uninstall, and to ensure that when // the flag is enabled again, an update is triggered. if (!IsEnabled()) @@ -100,10 +106,20 @@ if (!NeedsUpdate()) return; + std::vector<GURL> installed_apps = pending_app_manager_->GetInstalledAppUrls( + InstallSource::kSystemInstalled); + + std::set<SystemAppType> installed_app_types; + for (const auto& it : system_app_infos_) { + if (std::find(installed_apps.begin(), installed_apps.end(), + it.second.install_url) != installed_apps.end()) + installed_app_types.insert(it.first); + } + std::vector<InstallOptions> install_options_list; if (IsEnabled()) { // Skipping this will uninstall all System Apps currently installed. - for (const auto& app : system_app_urls_) { + for (const auto& app : system_app_infos_) { install_options_list.push_back( CreateInstallOptionsForSystemApp(app.second)); } @@ -112,13 +128,13 @@ pending_app_manager_->SynchronizeInstalledApps( std::move(install_options_list), InstallSource::kSystemInstalled, base::BindOnce(&SystemWebAppManager::OnAppsSynchronized, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), installed_app_types)); } void SystemWebAppManager::InstallSystemAppsForTesting() { on_apps_synchronized_.reset(new base::OneShotEvent()); - system_app_urls_ = CreateSystemWebApps(); - Start(); + system_app_infos_ = CreateSystemWebApps(); + Start(ui_delegate_); // Wait for the System Web Apps to install. base::RunLoop run_loop; @@ -128,12 +144,12 @@ base::Optional<AppId> SystemWebAppManager::GetAppIdForSystemApp( SystemAppType id) const { - auto app_url_it = system_app_urls_.find(id); + auto app_url_it = system_app_infos_.find(id); - if (app_url_it == system_app_urls_.end()) + if (app_url_it == system_app_infos_.end()) return base::Optional<AppId>(); - return pending_app_manager_->LookupAppId(app_url_it->second); + return pending_app_manager_->LookupAppId(app_url_it->second.install_url); } bool SystemWebAppManager::IsSystemWebApp(const AppId& app_id) const { @@ -142,8 +158,8 @@ } void SystemWebAppManager::SetSystemAppsForTesting( - base::flat_map<SystemAppType, GURL> system_app_urls) { - system_app_urls_ = std::move(system_app_urls); + base::flat_map<SystemAppType, SystemAppInfo> system_apps) { + system_app_infos_ = std::move(system_apps); } void SystemWebAppManager::SetUpdatePolicyForTesting(UpdatePolicy policy) { @@ -166,12 +182,16 @@ } void SystemWebAppManager::OnAppsSynchronized( + std::set<SystemAppType> already_installed, PendingAppManager::SynchronizeResult result) { if (IsEnabled()) { pref_service_->SetString(prefs::kSystemWebAppLastUpdateVersion, CurrentVersion().GetString()); } + MigrateSystemWebApps(already_installed); + + // May be called more than once in tests. if (!on_apps_synchronized_->is_signaled()) on_apps_synchronized_->Signal(); } @@ -188,4 +208,20 @@ last_update_version != CurrentVersion(); } +void SystemWebAppManager::MigrateSystemWebApps( + std::set<SystemAppType> already_installed) { + DCHECK(ui_delegate_); + + for (const auto& type_and_info : system_app_infos_) { + // Migrate if a migration source is specified and the app has been newly + // installed. + if (!type_and_info.second.migration_source.empty() && + !base::Contains(already_installed, type_and_info.first)) { + ui_delegate_->MigrateOSAttributes( + type_and_info.second.migration_source, + *GetAppIdForSystemApp(type_and_info.first)); + } + } +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/system_web_app_manager.h b/chrome/browser/web_applications/system_web_app_manager.h index 9d87e05..597c06e1 100644 --- a/chrome/browser/web_applications/system_web_app_manager.h +++ b/chrome/browser/web_applications/system_web_app_manager.h
@@ -28,6 +28,8 @@ namespace web_app { +class WebAppUiDelegate; + // An enum that lists the different System Apps that exist. Can be used to // retrieve the App ID from the underlying Web App system. enum class SystemAppType { @@ -35,6 +37,16 @@ DISCOVER, }; +// The configuration options for a System App. +struct SystemAppInfo { + // The URL that the System App will be installed from. + GURL install_url; + + // If specified, the app with AppId |migration_source| will have its data + // migrated to this System App. + AppId migration_source; +}; + // Installs, uninstalls, and updates System Web Apps. class SystemWebAppManager { public: @@ -52,7 +64,7 @@ SystemWebAppManager(Profile* profile, PendingAppManager* pending_app_manager); virtual ~SystemWebAppManager(); - void Start(); + void Start(WebAppUiDelegate* ui_delegate); static bool IsEnabled(); @@ -62,6 +74,9 @@ // // Call this to install apps for SystemWebApp specific tests, e.g if a test // needs to open OS Settings. + // + // This can also be called multiple times to simulate reinstallation from + // system restart, e.g. void InstallSystemAppsForTesting(); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); @@ -78,25 +93,33 @@ protected: void SetSystemAppsForTesting( - base::flat_map<SystemAppType, GURL> system_app_urls); + base::flat_map<SystemAppType, SystemAppInfo> system_apps); void SetUpdatePolicyForTesting(UpdatePolicy policy); virtual const base::Version& CurrentVersion() const; private: - void OnAppsSynchronized(PendingAppManager::SynchronizeResult result); + void OnAppsSynchronized(std::set<SystemAppType> already_installed, + PendingAppManager::SynchronizeResult result); bool NeedsUpdate() const; + // TODO(calamity): Move migration into the install task once the install task + // is able to distinguish between an update install and a fresh install. + void MigrateSystemWebApps(std::set<SystemAppType> already_installed); + std::unique_ptr<base::OneShotEvent> on_apps_synchronized_; UpdatePolicy update_policy_; - base::flat_map<SystemAppType, GURL> system_app_urls_; + base::flat_map<SystemAppType, SystemAppInfo> system_app_infos_; PrefService* pref_service_; + // Used to install, uninstall, and update apps. Should outlive this class. PendingAppManager* pending_app_manager_; + WebAppUiDelegate* ui_delegate_ = nullptr; + base::WeakPtrFactory<SystemWebAppManager> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(SystemWebAppManager);
diff --git a/chrome/browser/web_applications/test/test_system_web_app_manager.cc b/chrome/browser/web_applications/test/test_system_web_app_manager.cc index 40d16b1..2cb878b 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_manager.cc +++ b/chrome/browser/web_applications/test/test_system_web_app_manager.cc
@@ -13,14 +13,14 @@ Profile* profile, PendingAppManager* pending_app_manager) : SystemWebAppManager(profile, pending_app_manager) { - SetSystemApps(base::flat_map<SystemAppType, GURL>()); + SetSystemApps(base::flat_map<SystemAppType, SystemAppInfo>()); } TestSystemWebAppManager::~TestSystemWebAppManager() = default; void TestSystemWebAppManager::SetSystemApps( - base::flat_map<SystemAppType, GURL> system_app_urls) { - SetSystemAppsForTesting(std::move(system_app_urls)); + base::flat_map<SystemAppType, SystemAppInfo> system_apps) { + SetSystemAppsForTesting(std::move(system_apps)); } void TestSystemWebAppManager::SetUpdatePolicy(
diff --git a/chrome/browser/web_applications/test/test_system_web_app_manager.h b/chrome/browser/web_applications/test/test_system_web_app_manager.h index 5a83b8e..a1b397b 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_manager.h +++ b/chrome/browser/web_applications/test/test_system_web_app_manager.h
@@ -22,7 +22,7 @@ PendingAppManager* pending_app_manager); ~TestSystemWebAppManager() override; - void SetSystemApps(base::flat_map<SystemAppType, GURL> system_apps); + void SetSystemApps(base::flat_map<SystemAppType, SystemAppInfo> system_apps); void SetUpdatePolicy(SystemWebAppManager::UpdatePolicy policy);
diff --git a/chrome/browser/web_applications/test/test_web_app_ui_delegate.h b/chrome/browser/web_applications/test/test_web_app_ui_delegate.h index 40ec6015..ecd44999 100644 --- a/chrome/browser/web_applications/test/test_web_app_ui_delegate.h +++ b/chrome/browser/web_applications/test/test_web_app_ui_delegate.h
@@ -23,6 +23,7 @@ size_t GetNumWindowsForApp(const AppId& app_id) override; void NotifyOnAllAppWindowsClosed(const AppId& app_id, base::OnceClosure callback) override; + void MigrateOSAttributes(const AppId& from, const AppId& to) override {} private: std::map<AppId, size_t> app_id_to_num_windows_map_;
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 8f1a325..d071c8b0 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -172,7 +172,8 @@ if (!base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) { web_app_policy_manager_->Start(); - system_web_app_manager_->Start(); + DCHECK(ui_delegate_); + system_web_app_manager_->Start(ui_delegate_); // Start ExternalWebApps subsystem: ScanForExternalWebApps(
diff --git a/chrome/common/search/BUILD.gn b/chrome/common/search/BUILD.gn index f4ba1c6..3175d5b 100644 --- a/chrome/common/search/BUILD.gn +++ b/chrome/common/search/BUILD.gn
@@ -6,6 +6,7 @@ executable("generate_colors_info") { sources = [ + "chrome_colors_icon_template.h", "generate_colors_info.cc", "selected_colors_info.h", ]
diff --git a/chrome/common/search/chrome_colors_icon_template.h b/chrome/common/search/chrome_colors_icon_template.h new file mode 100644 index 0000000..663ef94 --- /dev/null +++ b/chrome/common/search/chrome_colors_icon_template.h
@@ -0,0 +1,151 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_SEARCH_CHROME_COLORS_ICON_TEMPLATE_H_ +#define CHROME_COMMON_SEARCH_CHROME_COLORS_ICON_TEMPLATE_H_ + +// Template for the icon svg. +// $1 - primary color +// $2 - secondary color +// $3 - active tab text color +const char kChromeColorsIconTemplate[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<svg width=\"176px\" height=\"120px\" viewBox=\"0 0 176 120\" " + "version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" " + "xmlns:xlink=\"http://www.w3.org/1999/xlink\">" + " <title>theme-oceanic</title>" + " <desc>Created with Sketch.</desc>" + " <g id=\"theme-oceanic\" stroke=\"none\" stroke-width=\"1\" " + "fill=\"none\" fill-rule=\"evenodd\">" + " <path d=\"M4,0 L172,0 C174.209139,-4.05812251e-16 176,1.790861 " + "176,4 L176,80 L0,80 L0,4 C-2.705415e-16,1.790861 1.790861,4.05812251e-16 " + "4,0 Z\" id=\"window-frame\" fill=$1 fill-rule=\"nonzero\"></path>" + " <path d=\"M0,80 L176,80 L176,116 C176,118.209139 174.209139,120 " + "172,120 L4,120 C1.790861,120 2.705415e-16,118.209139 0,116 L0,80 Z\" " + "id=\"window-frame\" fill=$2 fill-rule=\"nonzero\"></path>" + " <path d=\"M8.60546875,45 L8.60546875,27 C8.60546875,22.581722 " + "12.1871908,19 16.6054688,19 L70.1908482,19 C74.6091262,19 " + "78.1908482,22.581722 78.1908482,27 L78.1908482,45 L176,45 L176,80 " + "L3.55271368e-13,80 L3.55271368e-13,45 L8.60546875,45 Z\" id=\"toolbar\" " + "fill=$2 fill-rule=\"nonzero\"></path>" + " <rect id=\"omnibox\" fill=\"#F2F3F5\" fill-rule=\"nonzero\" " + "x=\"9\" y=\"52\" width=\"126\" height=\"21\" rx=\"10.5\"></rect>" + " <path d=\"M153.428571,56 C156.977143,56 159.857143,58.88 " + "159.857143,62.4285714 C159.857143,65.9771429 156.977143,68.8571429 " + "153.428571,68.8571429 C149.88,68.8571429 147,65.9771429 147,62.4285714 " + "C147,58.88 149.88,56 153.428571,56 Z M153.428571,57.9285714 " + "C152.361429,57.9285714 151.5,58.79 151.5,59.8571429 C151.5,60.9242857 " + "152.361429,61.7857143 153.428571,61.7857143 C154.495714,61.7857143 " + "155.357143,60.9242857 155.357143,59.8571429 C155.357143,58.79 " + "154.495714,57.9285714 153.428571,57.9285714 Z M153.428571,67.0571429 " + "C155.035714,67.0571429 156.456429,66.2342857 157.285714,64.9871429 " + "C157.266429,63.7078571 154.707857,63.0071429 153.428571,63.0071429 " + "C152.142857,63.0071429 149.590714,63.7078571 149.571429,64.9871429 " + "C150.400714,66.2342857 151.821429,67.0571429 153.428571,67.0571429 Z " + "M23.2548828,36 L22.2929688,36 L18.8701172,30.5019531 " + "L18.8408203,30.5117188 L18.8408203,36 L17.8789062,36 " + "L17.8789062,28.890625 L18.8408203,28.890625 L22.2636719,34.3789062 " + "L22.2929688,34.3691406 L22.2929688,28.890625 L23.2548828,28.890625 " + "L23.2548828,36 Z M27.2295423,36.1025391 C26.4938615,36.1025391 " + "25.9087437,35.8575871 25.4741712,35.3676758 C25.0395987,34.8777645 " + "24.8223157,34.2421914 24.8223157,33.4609375 L24.8223157,33.2460938 " + "C24.8223157,32.4941369 25.046109,31.8683293 25.4937024,31.3686523 " + "C25.9412958,30.8689754 26.4710757,30.6191406 27.0830579,30.6191406 " + "C27.7959521,30.6191406 28.3346837,30.8339822 28.6992688,31.2636719 " + "C29.063854,31.6933615 29.2461438,32.2662725 29.2461438,32.9824219 " + "L29.2461438,33.5830078 L25.8184095,33.5830078 L25.803761,33.6074219 " + "C25.8135267,34.1152369 25.9421061,34.5327132 26.1895032,34.8598633 " + "C26.4369003,35.1870134 26.7835765,35.3505859 27.2295423,35.3505859 " + "C27.5550647,35.3505859 27.8407064,35.3041997 28.0864759,35.2114258 " + "C28.3322453,35.1186519 28.5446455,34.9908862 28.7236829,34.828125 " + "L29.0996595,35.453125 C28.9108564,35.6386728 28.6618355,35.7932937 " + "28.3525891,35.9169922 C28.0433428,36.0406907 27.6689976,36.1025391 " + "27.2295423,36.1025391 Z M27.0830579,31.3759766 C26.7607907,31.3759766 " + "26.4857283,31.5118802 26.2578626,31.7836914 C26.0299969,32.0555027 " + "25.8900243,32.3964823 25.8379407,32.8066406 L25.8477063,32.8310547 " + "L28.2842298,32.8310547 L28.2842298,32.7041016 C28.2842298,32.3264955 " + "28.1833193,32.0107435 27.9814954,31.7568359 C27.7796715,31.5029284 " + "27.4801953,31.3759766 27.0830579,31.3759766 Z M31.8829127,34.0761719 " + "L31.9952173,34.7158203 L32.0245142,34.7158203 L32.161233,34.0761719 " + "L33.2159205,30.7167969 L33.9874048,30.7167969 L35.0469752,34.0761719 " + "L35.1983423,34.7890625 L35.2276392,34.7890625 L35.3692408,34.0761719 " + "L36.1993189,30.7167969 L37.1563502,30.7167969 L35.623147,36 " + "L34.8467798,36 L33.826272,32.7822266 L33.6065455,31.8837891 " + "L33.5772486,31.8886719 L33.3672877,32.7822266 L32.3614283,36 " + "L31.5850611,36 L30.051858,30.7167969 L31.0088892,30.7167969 " + "L31.8829127,34.0761719 Z M42.2638722,29.4423828 L42.2638722,30.7167969 " + "L43.2648487,30.7167969 L43.2648487,31.4296875 L42.2638722,31.4296875 " + "L42.2638722,34.6376953 C42.2638722,34.8850924 42.3151412,35.0592443 " + "42.4176808,35.1601562 C42.5202203,35.2610682 42.6561239,35.3115234 " + "42.8253956,35.3115234 C42.8807344,35.3115234 42.941769,35.3050131 " + "43.0085011,35.2919922 C43.0752332,35.2789713 43.1346401,35.2626954 " + "43.1867237,35.2431641 L43.3136769,35.9023438 C43.2420619,35.9609378 " + "43.1370825,36.0089516 42.9987355,36.0463867 C42.8603884,36.0838218 " + "42.7212296,36.1025391 42.581255,36.1025391 C42.190628,36.1025391 " + "41.8797587,35.9845389 41.6486378,35.7485352 C41.4175169,35.5125314 " + "41.3019581,35.1422551 41.3019581,34.6376953 L41.3019581,31.4296875 " + "L40.4621144,31.4296875 L40.4621144,30.7167969 L41.3019581,30.7167969 " + "L41.3019581,29.4423828 L42.2638722,29.4423828 Z M47.9035707,36 " + "C47.8710184,35.840494 47.8457908,35.6997076 47.8278871,35.5776367 " + "C47.8099834,35.4555658 47.799404,35.3326829 47.7961488,35.2089844 " + "C47.6171115,35.4628919 47.3835526,35.6752921 47.0954652,35.8461914 " + "C46.8073778,36.0170907 46.4973223,36.1025391 46.1652894,36.1025391 " + "C45.6151565,36.1025391 45.1960526,35.9617527 44.9079652,35.6801758 " + "C44.6198778,35.3985989 44.4758363,35.0104191 44.4758363,34.515625 " + "C44.4758363,34.0110652 44.6800986,33.6163751 45.0886293,33.331543 " + "C45.49716,33.0467108 46.0513536,32.9042969 46.7512269,32.9042969 " + "L47.7961488,32.9042969 L47.7961488,32.3818359 C47.7961488,32.0725896 " + "47.7017487,31.8276376 47.5129457,31.6469727 C47.3241427,31.4663077 " + "47.0572182,31.3759766 46.7121644,31.3759766 C46.4029181,31.3759766 " + "46.1514558,31.4549146 45.9577699,31.612793 C45.764084,31.7706714 " + "45.6672426,31.9602854 45.6672426,32.1816406 L44.7492738,32.1816406 " + "L44.7395082,32.1523438 C44.7199768,31.7682272 44.9014529,31.4166683 " + "45.2839418,31.0976562 C45.6664307,30.7786442 46.1604036,30.6191406 " + "46.7658754,30.6191406 C47.3648367,30.6191406 47.8466027,30.7713201 " + "48.2111879,31.0756836 C48.575773,31.3800471 48.7580629,31.818682 " + "48.7580629,32.3916016 L48.7580629,34.9355469 C48.7580629,35.1243499 " + "48.7678284,35.3066397 48.7873598,35.4824219 C48.8068911,35.658204 " + "48.842698,35.8307283 48.8947816,36 L47.9035707,36 Z M46.306891,35.296875 " + "C46.6552,35.296875 46.9693245,35.2073577 47.2492738,35.0283203 " + "C47.5292231,34.849283 47.711513,34.6442069 47.7961488,34.4130859 " + "L47.7961488,33.5537109 L46.7170473,33.5537109 C46.3296755,33.5537109 " + "46.01962,33.6513662 45.7868715,33.8466797 C45.5541229,34.0419932 " + "45.4377504,34.2714831 45.4377504,34.5351562 C45.4377504,34.7695324 " + "45.5109918,34.9550774 45.6574769,35.0917969 C45.803962,35.2285163 " + "46.0204312,35.296875 46.306891,35.296875 Z M54.8713942,33.5585938 " + "C54.8713942,34.3203163 54.6882906,34.9347307 54.3220778,35.4018555 " + "C53.955865,35.8689802 53.4521266,36.1025391 52.8108473,36.1025391 " + "C52.4625383,36.1025391 52.1598069,36.0349942 51.9026442,35.8999023 " + "C51.6454815,35.7648105 51.4322674,35.565431 51.2629958,35.3017578 " + "L51.1458083,36 L50.3596754,36 L50.3596754,28.3828125 " + "L51.3215895,28.3828125 L51.3215895,31.3417969 C51.487606,31.1074207 " + "51.6934958,30.928386 51.9392653,30.8046875 C52.1850348,30.680989 " + "52.472304,30.6191406 52.8010817,30.6191406 C53.4521266,30.6191406 " + "53.959934,30.8795547 54.3245192,31.4003906 C54.6891044,31.9212266 " + "54.8713942,32.6064411 54.8713942,33.4560547 L54.8713942,33.5585938 Z " + "M53.9094801,33.4560547 C53.9094801,32.8505829 53.7979904,32.35661 " + "53.5750075,31.9741211 C53.3520246,31.5916322 53.0126725,31.4003906 " + "52.5569411,31.4003906 C52.2607156,31.4003906 52.0108809,31.4728183 " + "51.8074294,31.6176758 C51.6039778,31.7625333 51.4420328,31.95703 " + "51.3215895,32.2011719 L51.3215895,34.4912109 C51.445288,34.7516289 " + "51.607233,34.9550774 51.8074294,35.1015625 C52.0076257,35.2480476 " + "52.2607156,35.3212891 52.5667067,35.3212891 C53.0191829,35.3212891 " + "53.3560936,35.1601579 53.5774489,34.8378906 C53.7988042,34.5156234 " + "53.9094801,34.0891954 53.9094801,33.5585938 L53.9094801,33.4560547 Z\" " + "id=\"icon-text\" fill=$3 fill-rule=\"nonzero\"></path>" + " <path d=\"M154.833333,30.1666667 L158.166667,30.1666667 " + "C158.626904,30.1666667 159,30.5397627 159,31 C159,31.4602373 " + "158.626904,31.8333333 158.166667,31.8333333 L154.833333,31.8333333 " + "L154.833333,35.1666667 C154.833333,35.626904 154.460237,36 154,36 " + "C153.539763,36 153.166667,35.626904 153.166667,35.1666667 " + "L153.166667,31.8333333 L149.833333,31.8333333 C149.373096,31.8333333 " + "149,31.4602373 149,31 C149,30.5397627 149.373096,30.1666667 " + "149.833333,30.1666667 L153.166667,30.1666667 L153.166667,26.8333333 " + "C153.166667,26.373096 153.539763,26 154,26 C154.460237,26 " + "154.833333,26.373096 154.833333,26.8333333 L154.833333,30.1666667 Z\" " + "id=\"Combined-Shape\" fill=$3></path>" + " </g>" + "</svg>"; + +#endif // CHROME_COMMON_SEARCH_CHROME_COLORS_ICON_TEMPLATE_H_
diff --git a/chrome/common/search/generate_colors_info.cc b/chrome/common/search/generate_colors_info.cc index c396de5..1dabde8 100644 --- a/chrome/common/search/generate_colors_info.cc +++ b/chrome/common/search/generate_colors_info.cc
@@ -7,39 +7,10 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "chrome/common/search/chrome_colors_icon_template.h" #include "chrome/common/search/selected_colors_info.h" #include "chrome/common/themes/autogenerated_theme_util.h" -// TODO(gayane): Replace with real template. -// Template for the icon svg. -// $1 - primary color -// $2 - secondary color -const char kIconTemplate[] = - "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" - "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " - "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" - "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" " - "xmlns:xlink=\"http://www.w3.org/1999/xlink\" " - "preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 176 120\" " - "width=\"176\" height=\"120\"><defs><path d=\"M176 3.75C176 27 176 93 176 " - "116.25C176 118.32 173.52 120 170.46 120C136.37 120 39.63 120 5.54 " - "120C2.48 120 0 118.32 0 116.25C0 93 0 27 0 3.75C0 1.68 2.48 0 5.54 " - "0C39.63 0 136.37 0 170.46 0C173.52 0 176 1.68 176 3.75Z\" " - "id=\"b6Au8TbqXk\"></path><path d=\"M176 28.79C176 47.03 176 98.39 176 " - "116.63C176 118.49 173.66 120 170.78 120C143.04 120 65.01 120 37.27 " - "120C34.39 120 32.05 118.49 32.05 116.63C32.05 98.39 32.05 47.03 32.05 " - "28.79C32.05 26.93 34.39 25.42 37.27 25.42C65.01 25.42 143.04 25.42 170.78 " - "25.42C173.66 25.42 176 26.93 176 28.79Z\" " - "id=\"aPbYI6QVm\"></path></defs><g><g><g><use xlink:href=\"#b6Au8TbqXk\" " - "opacity=\"1\" fill=$1 fill-opacity=\"1\"></use><g><use " - "xlink:href=\"#b6Au8TbqXk\" opacity=\"1\" fill-opacity=\"0\" " - "stroke=\"#000000\" stroke-width=\"1\" " - "stroke-opacity=\"0\"></use></g></g><g><use xlink:href=\"#aPbYI6QVm\" " - "opacity=\"1\" fill=$2 fill-opacity=\"1\"></use><g><use " - "xlink:href=\"#aPbYI6QVm\" opacity=\"1\" fill-opacity=\"0\" " - "stroke=\"#000000\" stroke-width=\"1\" " - "stroke-opacity=\"0\"></use></g></g></g></g></svg>"; - // Template for color info line. // $1 - color id // $2 - red value of primary color @@ -94,10 +65,12 @@ std::vector<std::string> subst; subst.push_back(SkColorToHexString(colors.frame_color)); subst.push_back(SkColorToHexString(colors.active_tab_color)); + subst.push_back(SkColorToHexString(colors.active_tab_text_color)); std::string svg_base64; base::Base64Encode( - base::ReplaceStringPlaceholders(kIconTemplate, subst, NULL), &svg_base64); + base::ReplaceStringPlaceholders(kChromeColorsIconTemplate, subst, NULL), + &svg_base64); return svg_base64; }
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc index 0e0a9c20..43c06bc 100644 --- a/chrome/renderer/net/net_error_helper.cc +++ b/chrome/renderer/net/net_error_helper.cc
@@ -376,8 +376,7 @@ // Since the page is trying to fetch cross-origin resources (which would // be protected by CORB in no-cors mode), we need to ask for CORS. See also // https://crbug.com/932542. - resource_request->fetch_request_mode = - network::mojom::FetchRequestMode::kCors; + resource_request->mode = network::mojom::RequestMode::kCors; resource_request->headers.SetHeader(net::HttpRequestHeaders::kOrigin, origin.ToString().Ascii()); return resource_request;
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index d2426dac..ba4dbd0 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc
@@ -170,7 +170,7 @@ // The NetworkChangeNotifier must be created after ThreadPool because it // posts tasks to it. - network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); + network_change_notifier_ = net::NetworkChangeNotifier::Create(); network_connection_tracker_ = std::make_unique<InProcessNetworkConnectionTracker>();
diff --git a/chrome/services/ble_scan_parser/BUILD.gn b/chrome/services/ble_scan_parser/BUILD.gn deleted file mode 100644 index 07e7f7b..0000000 --- a/chrome/services/ble_scan_parser/BUILD.gn +++ /dev/null
@@ -1,51 +0,0 @@ -# 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. - -assert(is_chromeos) -import("//testing/libfuzzer/fuzzer_test.gni") - -source_set("lib") { - sources = [ - "ble_scan_parser_impl.cc", - "ble_scan_parser_impl.h", - "ble_scan_parser_service.cc", - "ble_scan_parser_service.h", - ] - - deps = [ - "//base", - "//device/bluetooth/public/mojom/", - "//mojo/public/cpp/bindings", - "//services/service_manager/public/cpp", - ] - - public_deps = [ - "//chrome/services/ble_scan_parser/public/mojom", - ] -} - -source_set("unit_tests") { - testonly = true - - sources = [ - "ble_scan_parser_impl_unittest.cc", - ] - - deps = [ - ":lib", - "//base", - "//base/test:test_support", - "//services/service_manager/public/cpp/test:test_support", - "//testing/gtest", - ] -} - -fuzzer_test("ble_scan_parser_fuzzer") { - sources = [ - "ble_scan_parser_impl_fuzzer.cc", - ] - deps = [ - ":lib", - ] -}
diff --git a/chrome/services/ble_scan_parser/DEPS b/chrome/services/ble_scan_parser/DEPS deleted file mode 100644 index 1c7539ea..0000000 --- a/chrome/services/ble_scan_parser/DEPS +++ /dev/null
@@ -1,10 +0,0 @@ -include_rules = [ - "+mojo", # By definition. - - # Services have to list which other services they depend on. - "-chrome/services", - "-services", - "+services/service_manager/public", # Every service talks to Service Manager. - "+chrome/services/ble_scan_parser", - "+device/bluetooth/public", -]
diff --git a/chrome/services/ble_scan_parser/OWNERS b/chrome/services/ble_scan_parser/OWNERS deleted file mode 100644 index b5fa4e4..0000000 --- a/chrome/services/ble_scan_parser/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://device/bluetooth/OWNERS
diff --git a/chrome/services/ble_scan_parser/ble_scan_parser_service.cc b/chrome/services/ble_scan_parser/ble_scan_parser_service.cc deleted file mode 100644 index 922262a..0000000 --- a/chrome/services/ble_scan_parser/ble_scan_parser_service.cc +++ /dev/null
@@ -1,30 +0,0 @@ -// 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. - -#include "chrome/services/ble_scan_parser/ble_scan_parser_service.h" -#include "chrome/services/ble_scan_parser/ble_scan_parser_impl.h" -#include "mojo/public/cpp/bindings/strong_binding.h" - -namespace ble_scan_parser { - -BleScanParserService::BleScanParserService( - service_manager::mojom::ServiceRequest request) - : binding_(this, std::move(request)), - keepalive_(&binding_, base::TimeDelta::FromSeconds(0)) {} - -BleScanParserService::~BleScanParserService() = default; - -void BleScanParserService::OnBindInterface( - const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) { - if (interface_name == mojom::BleScanParser::Name_) { - mojo::MakeStrongBinding( - std::make_unique<BleScanParserImpl>(keepalive_.CreateRef()), - ble_scan_parser::mojom::BleScanParserRequest( - std::move(interface_pipe))); - } -} - -} // namespace ble_scan_parser
diff --git a/chrome/services/ble_scan_parser/ble_scan_parser_service.h b/chrome/services/ble_scan_parser/ble_scan_parser_service.h deleted file mode 100644 index c8982b8..0000000 --- a/chrome/services/ble_scan_parser/ble_scan_parser_service.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_SERVICES_BLE_SCAN_PARSER_BLE_SCAN_PARSER_SERVICE_H_ -#define CHROME_SERVICES_BLE_SCAN_PARSER_BLE_SCAN_PARSER_SERVICE_H_ - -#include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_binding.h" -#include "services/service_manager/public/cpp/service_keepalive.h" - -#include "base/macros.h" -#include "chrome/services/ble_scan_parser/public/mojom/ble_scan_parser.mojom.h" - -namespace ble_scan_parser { - -class BleScanParserService : public service_manager::Service { - public: - explicit BleScanParserService(service_manager::mojom::ServiceRequest request); - ~BleScanParserService() override; - - private: - // service_manager::Service: - void OnBindInterface(const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) override; - - service_manager::ServiceBinding binding_; - service_manager::ServiceKeepalive keepalive_; - - DISALLOW_COPY_AND_ASSIGN(BleScanParserService); -}; - -} // namespace ble_scan_parser - -#endif // CHROME_SERVICES_BLE_SCAN_PARSER_BLE_SCAN_PARSER_SERVICE_H_
diff --git a/chrome/services/ble_scan_parser/public/cpp/BUILD.gn b/chrome/services/ble_scan_parser/public/cpp/BUILD.gn deleted file mode 100644 index 7b5fba3..0000000 --- a/chrome/services/ble_scan_parser/public/cpp/BUILD.gn +++ /dev/null
@@ -1,20 +0,0 @@ -# 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. - -assert(is_chromeos) - -source_set("manifest") { - sources = [ - "manifest.cc", - "manifest.h", - ] - - deps = [ - "//base", - "//chrome:strings", - "//chrome/services/ble_scan_parser/public/mojom", - "//services/preferences/public/mojom", - "//services/service_manager/public/cpp", - ] -}
diff --git a/chrome/services/ble_scan_parser/public/cpp/OWNERS b/chrome/services/ble_scan_parser/public/cpp/OWNERS deleted file mode 100644 index dad81cc..0000000 --- a/chrome/services/ble_scan_parser/public/cpp/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -per-file manifest.h=set noparent -per-file manifest.h=file://ipc/SECURITY_OWNERS -per-file manifest.cc=set noparent -per-file manifest.cc=file://ipc/SECURITY_OWNERS
diff --git a/chrome/services/ble_scan_parser/public/cpp/manifest.cc b/chrome/services/ble_scan_parser/public/cpp/manifest.cc deleted file mode 100644 index 5a6d737..0000000 --- a/chrome/services/ble_scan_parser/public/cpp/manifest.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// 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. - -#include "chrome/services/ble_scan_parser/public/cpp/manifest.h" - -#include "base/no_destructor.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/services/ble_scan_parser/public/mojom/ble_scan_parser.mojom.h" -#include "chrome/services/ble_scan_parser/public/mojom/constants.mojom.h" -#include "services/service_manager/public/cpp/manifest_builder.h" - -namespace ble_scan_parser { - -const service_manager::Manifest GetManifest() { - return service_manager::ManifestBuilder() - .WithServiceName(mojom::kServiceName) - .WithDisplayName(IDS_UTILITY_PROCESS_BLE_SCAN_PARSER_NAME) - .ExposeCapability( - mojom::kParseBleScanCapability, - service_manager::Manifest::InterfaceList<mojom::BleScanParser>()) - .Build(); -} - -} // namespace ble_scan_parser
diff --git a/chrome/services/ble_scan_parser/public/cpp/manifest.h b/chrome/services/ble_scan_parser/public/cpp/manifest.h deleted file mode 100644 index 2db3b71..0000000 --- a/chrome/services/ble_scan_parser/public/cpp/manifest.h +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#ifndef CHROME_SERVICES_BLE_SCAN_PARSER_PUBLIC_CPP_MANIFEST_H_ -#define CHROME_SERVICES_BLE_SCAN_PARSER_PUBLIC_CPP_MANIFEST_H_ - -#include "services/service_manager/public/cpp/manifest.h" - -namespace ble_scan_parser { - -const service_manager::Manifest GetManifest(); - -} // namespace ble_scan_parser - -#endif // CHROME_SERVICES_BLE_SCAN_PARSER_PUBLIC_CPP_MANIFEST_H_
diff --git a/chrome/services/ble_scan_parser/public/mojom/BUILD.gn b/chrome/services/ble_scan_parser/public/mojom/BUILD.gn deleted file mode 100644 index a246beab..0000000 --- a/chrome/services/ble_scan_parser/public/mojom/BUILD.gn +++ /dev/null
@@ -1,26 +0,0 @@ -# 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. - -assert(is_chromeos) -import("//mojo/public/tools/bindings/mojom.gni") - -mojom("mojom") { - sources = [ - "ble_scan_parser.mojom", - ] - - public_deps = [ - ":constants", - ] - - deps = [ - "//device/bluetooth/public/mojom/", - ] -} - -mojom("constants") { - sources = [ - "constants.mojom", - ] -}
diff --git a/chrome/services/ble_scan_parser/public/mojom/OWNERS b/chrome/services/ble_scan_parser/public/mojom/OWNERS deleted file mode 100644 index 16d2e7a7..0000000 --- a/chrome/services/ble_scan_parser/public/mojom/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS -
diff --git a/chrome/services/ble_scan_parser/public/mojom/constants.mojom b/chrome/services/ble_scan_parser/public/mojom/constants.mojom deleted file mode 100644 index 1263a28..0000000 --- a/chrome/services/ble_scan_parser/public/mojom/constants.mojom +++ /dev/null
@@ -1,8 +0,0 @@ -// 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. - -module ble_scan_parser.mojom; - -const string kServiceName = "ble_scan_parser"; -const string kParseBleScanCapability = "parse_ble_scan";
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 02e87121..62da5c0 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -936,7 +936,7 @@ "../browser/ntp_snippets/content_suggestions_service_factory_browsertest.cc", "../browser/ntp_tiles/ntp_tiles_browsertest.cc", "../browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc", - "../browser/page_load_metrics/observers/amp_ukm_observer_browsertest.cc", + "../browser/page_load_metrics/observers/amp_page_load_metrics_observer_browsertest.cc", "../browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer_browsertest.cc", "../browser/page_load_metrics/observers/data_use_metrics_observer_browsertest.cc", "../browser/page_load_metrics/observers/foreground_duration_ukm_observer_browsertest.cc", @@ -2943,6 +2943,7 @@ "../browser/performance_manager/performance_manager_unittest.cc", "../browser/performance_manager/persistence/site_data/exponential_moving_average_unittest.cc", "../browser/performance_manager/persistence/site_data/leveldb_site_data_store_unittest.cc", + "../browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc", "../browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc", "../browser/performance_manager/persistence/site_data/site_data_impl_unittest.cc", "../browser/performance_manager/persistence/site_data/site_data_reader_unittest.cc", @@ -3043,6 +3044,7 @@ "../browser/sessions/chrome_serialized_navigation_driver_unittest.cc", "../browser/sessions/restore_on_startup_policy_handler_unittest.cc", "../browser/sessions/session_common_utils_unittest.cc", + "../browser/sharing/sharing_fcm_handler_unittest.cc", "../browser/sharing/sharing_sync_preference_unittest.cc", "../browser/sharing/vapid_key_manager_unittest.cc", "../browser/shell_integration_win_unittest.cc", @@ -3117,6 +3119,7 @@ "../browser/update_client/chrome_update_query_params_delegate_unittest.cc", "../browser/vr/metrics/session_metrics_helper_unittest.cc", "../browser/vr/vr_tab_helper_unittest.cc", + "../browser/wake_lock/wake_lock_permission_context_unittest.cc", "../browser/webauthn/authenticator_request_scheduler_unittest.cc", "../browser/webauthn/chrome_authenticator_request_delegate_unittest.cc", "../browser/win/chrome_elf_init_unittest.cc", @@ -3626,6 +3629,7 @@ "../browser/ui/extensions/extension_action_view_controller_unittest.cc", "../browser/ui/extensions/extension_message_bubble_bridge_unittest.cc", "../browser/ui/global_error/global_error_service_unittest.cc", + "../browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc", "../browser/ui/hid/hid_chooser_controller_unittest.cc", "../browser/ui/in_product_help/active_tab_tracker_unittest.cc", "../browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc", @@ -3664,7 +3668,6 @@ "../browser/ui/toolbar/toolbar_actions_model_unittest.cc", "../browser/ui/web_applications/app_browser_controller_unittest.cc", "../browser/ui/webui/browsing_history_handler_unittest.cc", - "../browser/ui/webui/dark_mode_handler_unittest.cc", "../browser/ui/webui/downloads/downloads_dom_handler_unittest.cc", "../browser/ui/webui/downloads/downloads_list_tracker_unittest.cc", "../browser/ui/webui/downloads/mock_downloads_page.cc", @@ -3929,7 +3932,6 @@ "//ash/public/cpp/resources:ash_public_unscaled_resources", "//ash/strings", "//chrome/browser/resources/chromeos/zip_archiver/cpp:ziparchiver_unittests", - "//chrome/services/ble_scan_parser:unit_tests", ] if (use_new_tcmalloc) { sources += [ "../browser/metrics/perf/heap_collector_unittest.cc" ]
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc index 7f730c3..6196b16b 100644 --- a/chrome/test/chromedriver/element_commands.cc +++ b/chrome/test/chromedriver/element_commands.cc
@@ -32,8 +32,8 @@ #include "third_party/webdriver/atoms.h" const int kFlickTouchEventsPerSecond = 30; -const std::set<std::string> textControlTypes = {"text", "search", "tel", "url", - "password"}; +const std::set<std::string> textControlTypes = {"text", "search", "tel", + "url", "email", "password"}; namespace { @@ -92,8 +92,8 @@ Status status = FocusToElement(session, web_view, element_id); if (status.IsError()) return Status(kElementNotInteractable); - // Move cursor/caret to append the input - // keys if element's type is text-related + // Move cursor/caret to append the input keys if element's type is + // text-related if (is_text) { base::ListValue args; args.Append(CreateElement(element_id)); @@ -441,46 +441,6 @@ return web_view->SetFileInputFiles(session->GetCurrentFrameId(), *element, paths, multiple); } else { - std::unique_ptr<base::Value> get_content_editable; - base::ListValue args; - args.Append(CreateElement(element_id)); - status = web_view->CallFunction(session->GetCurrentFrameId(), - "element => element.isContentEditable", - args, &get_content_editable); - if (status.IsError()) - return status; - bool is_content_editable; - if (get_content_editable->GetAsBoolean(&is_content_editable) && - is_content_editable) { - // If element is contentEditable, will move caret - // at end of element text. W3C mandates that the - // caret be moved "after any child content" - std::unique_ptr<base::Value> result; - status = web_view->CallFunction( - session->GetCurrentFrameId(), - "function(element) {" - "var range = document.createRange();" - "range.selectNodeContents(element);" - "range.collapse();" - "var sel = window.getSelection();" - "sel.removeAllRanges();" - "sel.addRange(range);" - "while (element.parentElement.isContentEditable) {" - " element = element.parentElement;" - " }" - "return element;" - "}", - args, &result); - if (status.IsError()) - return status; - const base::DictionaryValue* element_dict; - std::string target_element_id; - if (!result->GetAsDictionary(&element_dict) || - !element_dict->GetString(GetElementKey(), &target_element_id)) - return Status(kUnknownError, "no element reference returned by script"); - return SendKeysToElement(session, web_view, target_element_id, false, - key_list); - } // If element_type is in textControlTypes, sendKeys should append bool is_text = is_input && textControlTypes.find(element_type) != textControlTypes.end();
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 59541f3..4c3a52c2 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -1897,14 +1897,21 @@ image.src = 'data:image/png;base64,%s'; """ % png_data_in_base64.replace("'", "\\'")) + def takeScreenshotAndVerifyCorrect(self, element): + """ Takes screenshot of given element and returns + 'PASS' if all pixels in screenshot are rgb(255, 0, 0) + and 'FAIL' otherwise + """ + elementScreenshotPNGBase64 = element.TakeElementScreenshot() + self.assertIsNotNone(elementScreenshotPNGBase64) + return self._driver.ExecuteAsyncScript( + ChromeDriverTest.MakeRedImageTestScript(elementScreenshotPNGBase64)) + def testTakeElementScreenshot(self): self._driver.Load(self.GetHttpUrlForFile( '/chromedriver/page_with_redbox.html')) - elementScreenshotPNGBase64 = self._driver.FindElement( - 'css selector', '#box').TakeElementScreenshot() - self.assertIsNotNone(elementScreenshotPNGBase64) - analysisResult = self._driver.ExecuteAsyncScript( - ChromeDriverTest.MakeRedImageTestScript(elementScreenshotPNGBase64)) + redElement = self._driver.FindElement('css selector', '#box') + analysisResult = self.takeScreenshotAndVerifyCorrect(redElement) self.assertEquals('PASS', analysisResult) def testTakeElementScreenshotInIframe(self): @@ -1912,22 +1919,16 @@ '/chromedriver/page_with_iframe_redbox.html')) frame = self._driver.FindElement('css selector', '#frm') self._driver.SwitchToFrame(frame) - elementScreenshotPNGBase64 = self._driver.FindElement( - 'css selector', '#box').TakeElementScreenshot() - self.assertIsNotNone(elementScreenshotPNGBase64) - analysisResult = self._driver.ExecuteAsyncScript( - ChromeDriverTest.MakeRedImageTestScript(elementScreenshotPNGBase64)) + redElement = self._driver.FindElement('css selector', '#box') + analysisResult = self.takeScreenshotAndVerifyCorrect(redElement) self.assertEquals('PASS', analysisResult) def testTakeLargeElementScreenshot(self): self._driver.Load(self.GetHttpUrlForFile( '/chromedriver/large_element.html')) self._driver.SetWindowRect(500, 500, 0, 0) - elementScreenshotPNGBase64 = self._driver.FindElement( - 'css selector','#A').TakeElementScreenshot() - self.assertIsNotNone(elementScreenshotPNGBase64) - analysisResult = self._driver.ExecuteAsyncScript( - ChromeDriverTest.MakeRedImageTestScript(elementScreenshotPNGBase64)) + redElement = self._driver.FindElement('css selector', '#A') + analysisResult = self.takeScreenshotAndVerifyCorrect(redElement) self.assertEquals('PASS', analysisResult) def testGenerateTestReport(self): @@ -1965,44 +1966,16 @@ def testSendKeysToElementAppend(self): self._driver.Load(self.GetHttpUrlForFile( '/chromedriver/empty.html')) - textControlTypes = ["text", "search", "tel", "url", "password"] - for textType in textControlTypes: - element = self._driver.ExecuteScript( - 'document.body.innerHTML = ' - '\'<input type="{}" value="send_this_value">\';' - 'var input = document.getElementsByTagName("input")[0];' - 'input.focus();' - 'input.setSelectionRange(0,0);' - 'return input;'.format(textType)) - element.SendKeys('hello') - value = self._driver.ExecuteScript('return arguments[0].value;', - element) - self.assertEquals('send_this_valuehello', value) - - def testSendKeysToEditableElement(self): - self._driver.Load(self.GetHttpUrlForFile( - '/chromedriver/empty.html')) element = self._driver.ExecuteScript( 'document.body.innerHTML = ' - '\'<p contentEditable="true"> <i>hello-></i> ' - '<b>send_this_value </b> </p>\';' - 'var input = document.getElementsByTagName("i")[0];' + '\'<input type="text" value="send_this_value">\';' + 'var input = document.getElementsByTagName("input")[0];' 'input.focus();' + 'input.setSelectionRange(0,0);' 'return input;') element.SendKeys('hello') - self.assertEquals(u'hello->hello', element.GetText()) - - self._driver.Load(self.GetHttpUrlForFile( - '/chromedriver/empty.html')) - element = self._driver.ExecuteScript( - 'document.body.innerHTML = ' - '\'<p contentEditable="true"> <i>hello</i> ' - '<b>-></b> </p>\';' - 'var input = document.getElementsByTagName("p")[0];' - 'input.focus();' - 'return input;') - element.SendKeys('hello') - self.assertEquals(u'hello ->hello', element.GetText()) + value = self._driver.ExecuteScript('return arguments[0].value;', element) + self.assertEquals('send_this_valuehello', value) def testUnexpectedAlertOpenExceptionMessage(self): self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
diff --git a/chrome/test/data/arc_graphics_tracing/trace_input.dat.gz b/chrome/test/data/arc_graphics_tracing/trace_input.dat.gz new file mode 100644 index 0000000..148857d --- /dev/null +++ b/chrome/test/data/arc_graphics_tracing/trace_input.dat.gz Binary files differ
diff --git a/chrome/test/data/webui/print_preview/advanced_dialog_test.js b/chrome/test/data/webui/print_preview/advanced_dialog_test.js index dba036f..405744ea 100644 --- a/chrome/test/data/webui/print_preview/advanced_dialog_test.js +++ b/chrome/test/data/webui/print_preview/advanced_dialog_test.js
@@ -8,6 +8,7 @@ AdvancedSettings1Option: 'advanced settings 1 option', AdvancedSettings2Options: 'advanced settings 2 options', AdvancedSettingsApply: 'advanced settings apply', + AdvancedSettingsApplyWithEnter: 'advanced settings apply with enter', AdvancedSettingsClose: 'advanced settings close', AdvancedSettingsFilter: 'advanced settings filter', }; @@ -129,6 +130,34 @@ }); }); + // Tests that the advanced settings dialog updates the settings value for + // vendor items if Enter is pressed on a cr-input. + test(assert(TestNames.AdvancedSettingsApplyWithEnter), function() { + setupDialog(3); + setItemValues(); + + const items = dialog.shadowRoot.querySelectorAll( + 'print-preview-advanced-settings-item'); + const typedItemInput = items[2].$$('cr-input'); // Watermark + + // Simulate typing a value and then pressing enter. + typedItemInput.value = 'Hello World'; + typedItemInput.dispatchEvent( + new CustomEvent('input', {composed: true, bubbles: true})); + + const whenDialogClose = test_util.eventToPromise('close', dialog); + MockInteractions.keyEventOn( + typedItemInput, 'keydown', 'Enter', [], 'Enter'); + + return whenDialogClose.then(() => { + // Check that the setting has been set. + const setting = dialog.getSettingValue('vendorItems'); + assertEquals(6, setting.printArea); + assertEquals(1, setting.paperType); + assertEquals('Hello World', setting.watermark); + }); + }); + // Tests that the advanced settings dialog does not update the settings // value for vendor items when the close button is clicked. test(assert(TestNames.AdvancedSettingsClose), function() {
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js index 2cce32a..1c05220 100644 --- a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -786,6 +786,13 @@ this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettingsApply); }); +TEST_F( + 'PrintPreviewAdvancedDialogTest', 'AdvancedSettingsApplyWithEnter', + function() { + this.runMochaTest( + advanced_dialog_test.TestNames.AdvancedSettingsApplyWithEnter); + }); + TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettingsClose', function() { this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettingsClose); });
diff --git a/chrome/test/data/webui/set_time_dialog_browsertest.js b/chrome/test/data/webui/set_time_dialog_browsertest.js index ae6014f..f921cabc 100644 --- a/chrome/test/data/webui/set_time_dialog_browsertest.js +++ b/chrome/test/data/webui/set_time_dialog_browsertest.js
@@ -48,7 +48,7 @@ /** @override */ setTimezone(timezone) { - this.methodCalled('setTimezone'); + this.methodCalled('setTimezone', timezone); } /** @override */ @@ -64,12 +64,18 @@ } suiteSetup(function() { + // Must use existing timezones in the test. loadTimeData.overrideValues({ - currentTimezoneId: 'Westeros/Highgarden', + currentTimezoneId: 'America/Sao_Paulo', timezoneList: [ - ['Westeros/Highgarden', '(KNG-2:00) The Reach Time (Highgarden)'], - ['Westeros/Winterfell', '(KNG-1:00) The North Time (Winterfell)'], - ['Westeros/Sunspear', '(KNG+2:00) Dorne Time (Sunspear)'], + [ + 'America/Los_Angeles', + '(GMT-7:00) Pacific Daylight Time (Los Angeles)' + ], + [ + 'America/Sao_Paulo', '(GMT-3:00) Brasilis Standard Time (Sao Paulo)' + ], + ['Asia/Seoul', '(GMT+9:00) Korean Standard Time (Seoul)'], ], }); }); @@ -128,14 +134,58 @@ test('SystemTimezoneChanged', () => { const timezoneSelect = setTimeElement.$$('#timezoneSelect'); assertTrue(!!timezoneSelect); - expectEquals('Westeros/Highgarden', timezoneSelect.value); + expectEquals('America/Sao_Paulo', timezoneSelect.value); cr.webUIListenerCallback( - 'system-timezone-changed', 'Westeros/Winterfell'); - expectEquals('Westeros/Winterfell', timezoneSelect.value); + 'system-timezone-changed', 'America/Los_Angeles'); + expectEquals('America/Los_Angeles', timezoneSelect.value); - cr.webUIListenerCallback('system-timezone-changed', 'Westeros/Sunspear'); - expectEquals('Westeros/Sunspear', timezoneSelect.value); + cr.webUIListenerCallback('system-timezone-changed', 'Asia/Seoul'); + expectEquals('Asia/Seoul', timezoneSelect.value); + }); + + test('SetDateAndTimezone', () => { + const dateInput = setTimeElement.$$('#dateInput'); + assertTrue(!!dateInput); + + const timeInput = setTimeElement.$$('#timeInput'); + assertTrue(!!timeInput); + + const timezoneSelect = setTimeElement.$$('#timezoneSelect'); + assertTrue(!!timezoneSelect); + expectEquals('America/Sao_Paulo', timezoneSelect.value); + + // Simulate the user changing the time by forwarding it 15 minutes. + const originalTime = dateInput.valueAsDate; + originalTime.setMilliseconds(timeInput.valueAsNumber); + const updatedTime = new Date(originalTime.getTime() + 15 * 60 * 1000); + dateInput.focus(); + dateInput.valueAsDate = updatedTime; + setTimeElement.$$('#doneButton').click(); + + // Simulate timezone change. + cr.webUIListenerCallback( + 'system-timezone-changed', 'America/Los_Angeles'); + expectEquals('America/Los_Angeles', timezoneSelect.value); + + // Make sure that time on input field was updated. + const updatedTimeAndTimezone = dateInput.valueAsDate; + updatedTimeAndTimezone.setMilliseconds(timeInput.valueAsNumber); + // updatedTimeAndTimezone reflects the new timezone so it should be + // smaller, because it is more to the west than the original + // one, therefore even with the 15 minutes forwarded it should be smaller. + expectGT(updatedTime.getHours(), updatedTimeAndTimezone.getHours()); + + + return testBrowserProxy.whenCalled('setTimeInSeconds') + .then(timeInSeconds => { + const todaySeconds = originalTime.getTime() / 1000; + // The exact value isn't important (it depends on the current time). + // timeInSeconds should be bigger, because this timestamp is seconds + // since epoch and it does not hold any information regarding the + // current timezone. + assertGT(timeInSeconds, todaySeconds); + }); }); });
diff --git a/chrome/test/data/webui/settings/bluetooth_page_tests.js b/chrome/test/data/webui/settings/bluetooth_page_tests.js index 5e143d3..73ca0ef 100644 --- a/chrome/test/data/webui/settings/bluetooth_page_tests.js +++ b/chrome/test/data/webui/settings/bluetooth_page_tests.js
@@ -136,7 +136,7 @@ assertTrue(bluetoothPage.isToggleEnabled_()); // Test that tapping the single settings-box div enables bluetooth. - const div = bluetoothPage.$$('div.settings-box'); + const div = bluetoothPage.$$('.link-wrapper'); assertTrue(!!div); div.click(); @@ -200,7 +200,7 @@ }); Polymer.dom.flush(); - const div = bluetoothPage.$$('div.settings-box'); + const div = bluetoothPage.$$('.link-wrapper'); div.click(); await flushAsync();
diff --git a/chrome/test/data/webui/settings/multidevice_page_tests.js b/chrome/test/data/webui/settings/multidevice_page_tests.js index 00c6df15..73401a1 100644 --- a/chrome/test/data/webui/settings/multidevice_page_tests.js +++ b/chrome/test/data/webui/settings/multidevice_page_tests.js
@@ -98,7 +98,9 @@ multidevicePage.remove(); }); - const getLabel = () => multidevicePage.$$('#multidevice-label').textContent; + const getLabel = () => { + return multidevicePage.$$('#multidevice-label').textContent.trim(); + }; const getSubpage = () => multidevicePage.$$('settings-multidevice-subpage'); @@ -132,7 +134,7 @@ setHostData(mode); assertEquals( multidevicePage.isHostSet(), - !!multidevicePage.$$('#multidevice-item').hasAttribute('actionable')); + !!multidevicePage.$$('.link-wrapper').hasAttribute('actionable')); } }); @@ -141,7 +143,7 @@ function() { setHostData(settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED); assertFalse(!!getSubpage()); - multidevicePage.$$('#multidevice-item').click(); + multidevicePage.$$('.link-wrapper').click(); assertTrue(!!getSubpage()); assertTrue(!!getSubpage().$$('settings-multidevice-feature-item')); }); @@ -153,7 +155,7 @@ settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, multidevice.HOST_DEVICE); assertFalse(!!getSubpage()); - multidevicePage.$$('#multidevice-item').click(); + multidevicePage.$$('.link-wrapper').click(); assertTrue(!!getSubpage()); assertFalse(!!getSubpage().$$('settings-multidevice-feature-item')); });
diff --git a/chrome/test/data/webui/settings/multidevice_subpage_tests.js b/chrome/test/data/webui/settings/multidevice_subpage_tests.js index 89aa09b9..fb689a2d 100644 --- a/chrome/test/data/webui/settings/multidevice_subpage_tests.js +++ b/chrome/test/data/webui/settings/multidevice_subpage_tests.js
@@ -134,7 +134,7 @@ }); test('clicking SmartLock item routes to SmartLock subpage', function() { - multideviceSubpage.$$('#smartLockItem').$.card.click(); + multideviceSubpage.$$('#smartLockItem').$$('.link-wrapper').click(); assertEquals(settings.getCurrentRoute(), settings.routes.SMART_LOCK); });
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index 287a9553..6d1acb43 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -149,7 +149,6 @@ if (is_chromeos) { deps += [ - "//chrome/services/ble_scan_parser:lib", "//chrome/services/file_util:lib", "//chromeos/assistant:buildflags", "//chromeos/services/ime:lib",
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index 4540dd8..73bdb14 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -1,8 +1,6 @@ include_rules = [ "+chrome/grit", "+chrome/installer/util", - "+chrome/services/ble_scan_parser/ble_scan_parser_service.h", - "+chrome/services/ble_scan_parser/public/mojom", "+chrome/services/cups_ipp_parser/cups_ipp_parser_service.h", "+chrome/services/cups_ipp_parser/public/mojom", "+chrome/services/file_util/file_util_service.h",
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 74b83489..c9ece16e 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -70,8 +70,6 @@ #endif #if defined(OS_CHROMEOS) -#include "chrome/services/ble_scan_parser/ble_scan_parser_service.h" -#include "chrome/services/ble_scan_parser/public/mojom/constants.mojom.h" #include "chromeos/assistant/buildflags.h" // nogncheck #include "chromeos/services/ime/ime_service.h" #include "chromeos/services/ime/public/mojom/constants.mojom.h" @@ -320,11 +318,6 @@ if (service_name == chromeos::ime::mojom::kServiceName) return std::make_unique<chromeos::ime::ImeService>(std::move(request)); - if (service_name == ble_scan_parser::mojom::kServiceName) { - return std::make_unique<ble_scan_parser::BleScanParserService>( - std::move(request)); - } - #if BUILDFLAG(ENABLE_PRINTING) if (service_name == cups_ipp_parser::mojom::kCupsIppParserServiceName) return std::make_unique<cups_ipp_parser::CupsIppParserService>(
diff --git a/chrome/utility/importer/firefox_importer.cc b/chrome/utility/importer/firefox_importer.cc index ead3566..ae35b07 100644 --- a/chrome/utility/importer/firefox_importer.cc +++ b/chrome/utility/importer/firefox_importer.cc
@@ -118,9 +118,6 @@ void FirefoxImporter::StartImport(const importer::SourceProfile& source_profile, uint16_t items, ImporterBridge* bridge) { - UMA_HISTOGRAM_BOOLEAN("Import.IncludesPasswords.Firefox", - !!(items & importer::PASSWORDS)); - bridge_ = bridge; source_path_ = source_profile.source_path; app_path_ = source_profile.app_path;
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS index cd5ebfc..3e66c31 100644 --- a/chromecast/browser/DEPS +++ b/chromecast/browser/DEPS
@@ -55,6 +55,7 @@ "+services/service_manager/embedder", "+third_party/blink/public/common", "+third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h", + "+third_party/skia/include/core/SkColor.h", "+ui/accessibility", "+ui/aura", "+ui/base",
diff --git a/chromecast/browser/cast_web_contents.h b/chromecast/browser/cast_web_contents.h index a51b49f..db8738d 100644 --- a/chromecast/browser/cast_web_contents.h +++ b/chromecast/browser/cast_web_contents.h
@@ -11,9 +11,11 @@ #include "base/containers/flat_set.h" #include "base/observer_list.h" #include "base/optional.h" +#include "base/strings/string16.h" #include "chromecast/common/mojom/feature_manager.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "ui/gfx/geometry/rect.h" #include "url/gurl.h" namespace content { @@ -96,9 +98,26 @@ public: class Delegate { public: + // Notify that an inner WebContents was created. |inner_contents| is created + // in a default-initialized state with no delegate, and can be safely + // initialized by the delegate. + virtual void InnerContentsCreated(CastWebContents* inner_contents, + CastWebContents* outer_contents) {} + + protected: + virtual ~Delegate() {} + }; + + // Observer class. The Observer should *not* destroy CastWebContents during + // any of these events, otherwise other observers might try to use a freed + // pointer to |cast_web_contents|. + class Observer { + public: + Observer(); + // Advertises page state for the CastWebContents. // Use CastWebContents::page_state() to get the new state. - virtual void OnPageStateChanged(CastWebContents* cast_web_contents) = 0; + virtual void OnPageStateChanged(CastWebContents* cast_web_contents) {} // Called when the page has stopped. e.g.: A 404 occurred when loading the // page or if the render process for the main frame crashes. |error_code| @@ -113,24 +132,21 @@ // DESTROYED: Page was closed due to deletion of WebContents. The // CastWebContents instance is no longer usable and should be deleted. virtual void OnPageStopped(CastWebContents* cast_web_contents, - int error_code) = 0; + int error_code) {} - // Notify that an inner WebContents was created. |inner_contents| is created - // in a default-initialized state with no delegate, and can be safely - // initialized by the delegate. - virtual void InnerContentsCreated(CastWebContents* inner_contents, - CastWebContents* outer_contents) {} + // A new RenderFrame was created for the WebContents. |frame_interfaces| are + // provided by the new frame. + virtual void RenderFrameCreated( + int render_process_id, + int render_frame_id, + service_manager::InterfaceProvider* frame_interfaces) {} - protected: - virtual ~Delegate() {} - }; - - class Observer { - public: - Observer(); - - virtual void RenderFrameCreated(int render_process_id, - int render_frame_id) {} + // These methods are calls forwarded from WebContentsObserver. + virtual void MainFrameResized(const gfx::Rect& bounds) {} + virtual void UpdateTitle(const base::string16& title) {} + virtual void UpdateFaviconURL(GURL icon_url) {} + virtual void DidFinishBlockedNavigation(GURL url) {} + virtual void DidFirstVisuallyNonEmptyPaint() {} // Notifies that a resource for the main frame failed to load. virtual void ResourceLoadFailed(CastWebContents* cast_web_contents) {} @@ -152,6 +168,13 @@ CastWebContents* cast_web_contents_; }; + enum class BackgroundColor { + NONE, + WHITE, + BLACK, + TRANSPARENT, + }; + // Initialization parameters for CastWebContents. struct InitParams { // Delegate for CastWebContents. This can be null for an inner WebContents. @@ -171,6 +194,9 @@ bool handle_inner_contents = false; // Construct internal media blocker and enable BlockMediaLoading(). bool use_media_blocker = false; + // Background color for the WebContents view. If not provided, the color + // will fall back to the platform default. + BackgroundColor background_color = BackgroundColor::NONE; }; // Page state for the main frame.
diff --git a/chromecast/browser/cast_web_contents_browsertest.cc b/chromecast/browser/cast_web_contents_browsertest.cc index 7773646..24a623d 100644 --- a/chromecast/browser/cast_web_contents_browsertest.cc +++ b/chromecast/browser/cast_web_contents_browsertest.cc
@@ -85,9 +85,6 @@ MockCastWebContentsDelegate() {} ~MockCastWebContentsDelegate() override = default; - MOCK_METHOD1(OnPageStateChanged, void(CastWebContents* cast_web_contents)); - MOCK_METHOD2(OnPageStopped, - void(CastWebContents* cast_web_contents, int error_code)); MOCK_METHOD2(InnerContentsCreated, void(CastWebContents* inner_contents, CastWebContents* outer_contents)); @@ -101,8 +98,13 @@ MockCastWebContentsObserver() {} ~MockCastWebContentsObserver() override = default; - MOCK_METHOD2(RenderFrameCreated, - void(int render_process_id, int render_frame_id)); + MOCK_METHOD1(OnPageStateChanged, void(CastWebContents* cast_web_contents)); + MOCK_METHOD2(OnPageStopped, + void(CastWebContents* cast_web_contents, int error_code)); + MOCK_METHOD3(RenderFrameCreated, + void(int render_process_id, + int render_frame_id, + service_manager::InterfaceProvider* frame_interfaces)); MOCK_METHOD1(ResourceLoadFailed, void(CastWebContents* cast_web_contents)); private: @@ -207,11 +209,11 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::LOADED))) .WillOnce(InvokeWithoutArgs(quit_closure)); @@ -226,11 +228,11 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::LOADED))) .WillOnce(InvokeWithoutArgs(quit_closure)); @@ -245,8 +247,8 @@ // =========================================================================== // Test: Inject an iframe, verify no events are received for the frame. // =========================================================================== - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(_, _)).Times(0); std::string script = "var iframe = document.createElement('iframe');" "document.body.appendChild(iframe);" @@ -256,8 +258,8 @@ // =========================================================================== // Test: Inject an iframe and navigate it to an error page. Verify no events. // =========================================================================== - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(_, _)).Times(0); script = "iframe.src = 'https://www.fake-non-existent-cast-page.com';"; ASSERT_TRUE(ExecJs(web_contents_.get(), script)); @@ -268,7 +270,7 @@ // =========================================================================== EXPECT_CALL(mock_wc_delegate_, CloseContents(web_contents_.get())) .Times(AtLeast(1)); - EXPECT_CALL(mock_cast_wc_delegate_, + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::CLOSED), net::OK)) @@ -281,7 +283,7 @@ // Test: Destroy the underlying WebContents. Verify DESTROYED state. // =========================================================================== EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::DESTROYED))); web_contents_.reset(); @@ -299,11 +301,11 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::LOADED))) .WillOnce(InvokeWithoutArgs(quit_closure)); @@ -316,7 +318,7 @@ // Test: Destroy the WebContents. Verify OnPageStopped(DESTROYED, net::OK). // =========================================================================== EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStopped(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::DESTROYED), net::OK)); @@ -337,11 +339,11 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::LOADED))) .WillOnce(InvokeWithoutArgs(quit_closure)); @@ -350,7 +352,7 @@ cast_web_contents_->LoadUrl(GURL(url::kAboutBlankURL)); run_loop->Run(); - EXPECT_CALL(mock_cast_wc_delegate_, + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::ERROR), net::ERR_UNEXPECTED)); @@ -371,10 +373,10 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); - EXPECT_CALL(mock_cast_wc_delegate_, + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::ERROR), _)) @@ -400,11 +402,11 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::LOADED))) .WillOnce(InvokeWithoutArgs(quit_closure)); @@ -414,8 +416,8 @@ run_loop->Run(); // Create a sub-frame. - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(_, _)).Times(0); std::string script = "var iframe = document.createElement('iframe');" "document.body.appendChild(iframe);" @@ -437,8 +439,8 @@ // =========================================================================== // Test: Ignore main frame load failures with net::ERR_ABORTED. // =========================================================================== - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); - EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(_, _)).Times(0); cast_web_contents_->DidFailLoad( web_contents_->GetMainFrame(), web_contents_->GetMainFrame()->GetLastCommittedURL(), net::ERR_ABORTED, @@ -447,7 +449,7 @@ // =========================================================================== // Test: If main frame fails to load, page should enter ERROR state. // =========================================================================== - EXPECT_CALL(mock_cast_wc_delegate_, + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::ERROR), net::ERR_FAILED)); @@ -476,10 +478,10 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); - EXPECT_CALL(mock_cast_wc_delegate_, + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::ERROR), net::ERR_FAILED)) @@ -520,10 +522,10 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); - EXPECT_CALL(mock_cast_wc_delegate_, + EXPECT_CALL(mock_cast_wc_observer_, OnPageStopped(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::ERROR), net::ERR_ADDRESS_UNREACHABLE)) @@ -553,11 +555,11 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::LOADED))) .WillOnce(InvokeWithoutArgs(quit_closure)); @@ -582,11 +584,11 @@ { InSequence seq; EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState( cast_web_contents_.get(), CastWebContents::PageState::LOADING))); EXPECT_CALL( - mock_cast_wc_delegate_, + mock_cast_wc_observer_, OnPageStateChanged(CheckPageState(cast_web_contents_.get(), CastWebContents::PageState::LOADED))) .WillOnce(InvokeWithoutArgs(quit_closure));
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc index 92b156d..411dc2e 100644 --- a/chromecast/browser/cast_web_contents_impl.cc +++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -11,6 +11,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chromecast/base/chromecast_switches.h" +#include "chromecast/base/metrics/cast_metrics_helper.h" #include "chromecast/browser/cast_browser_process.h" #include "chromecast/browser/devtools/remote_debugging_server.h" #include "chromecast/common/mojom/media_playback_options.mojom.h" @@ -21,12 +22,15 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/common/bindings_policy.h" +#include "content/public/common/favicon_url.h" #include "content/public/common/resource_load_info.mojom.h" #include "net/base/net_errors.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/skia/include/core/SkColor.h" #include "url/gurl.h" namespace chromecast { @@ -63,6 +67,7 @@ enabled_for_dev_(init_params.enabled_for_dev), use_cma_renderer_(init_params.use_cma_renderer), handle_inner_contents_(init_params.handle_inner_contents), + view_background_color_(init_params.background_color), remote_debugging_server_( shell::CastBrowserProcess::GetInstance()->remote_debugging_server()), media_blocker_(init_params.use_media_blocker @@ -142,7 +147,7 @@ ui::PAGE_TRANSITION_TYPED, ""); UpdatePageState(); DCHECK_EQ(PageState::LOADING, page_state_); - NotifyObservers(); + NotifyPageState(); } void CastWebContentsImpl::ClosePage() { @@ -166,7 +171,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (stopped_) { UpdatePageState(); - NotifyObservers(); + NotifyPageState(); return; } last_error_ = error_code; @@ -176,7 +181,7 @@ DCHECK_NE(PageState::IDLE, page_state_); DCHECK_NE(PageState::LOADING, page_state_); DCHECK_NE(PageState::LOADED, page_state_); - NotifyObservers(); + NotifyPageState(); } void CastWebContentsImpl::BlockMediaLoading(bool blocked) { @@ -254,15 +259,15 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(render_frame_host); - // New render frame has been created, we need to add it to the app - // whitelisting session so URL requests are handled correctly. This must be - // done before URL requests are executed within render frame. auto* process = render_frame_host->GetProcess(); const int render_process_id = process->GetID(); const int render_frame_id = render_frame_host->GetRoutingID(); + // Allow observers to use remote interfaces which are hosted by the new + // RenderFrame. for (Observer& observer : observer_list_) { - observer.RenderFrameCreated(render_process_id, render_frame_id); + observer.RenderFrameCreated(render_process_id, render_frame_id, + render_frame_host->GetRemoteInterfaces()); } chromecast::shell::mojom::FeatureManagerPtr feature_manager_ptr; @@ -285,6 +290,12 @@ } } +void CastWebContentsImpl::RenderFrameHostChanged( + content::RenderFrameHost* old_host, + content::RenderFrameHost* new_host) { + RenderFrameCreated(new_host); +} + std::vector<chromecast::shell::mojom::FeaturePtr> CastWebContentsImpl::GetRendererFeatures() { std::vector<chromecast::shell::mojom::FeaturePtr> features; @@ -316,6 +327,24 @@ } } +void CastWebContentsImpl::RenderViewCreated( + content::RenderViewHost* render_view_host) { + content::RenderWidgetHostView* view = + render_view_host->GetWidget()->GetView(); + if (!view) + return; + if (view_background_color_ == BackgroundColor::WHITE) { + view->SetBackgroundColor(SK_ColorWHITE); + } else if (view_background_color_ == BackgroundColor::BLACK) { + view->SetBackgroundColor(SK_ColorBLACK); + } else if (view_background_color_ == BackgroundColor::TRANSPARENT) { + view->SetBackgroundColor(SK_ColorTRANSPARENT); + } else { + view->SetBackgroundColor(chromecast::GetSwitchValueColor( + switches::kCastAppBackgroundColor, SK_ColorBLACK)); + } +} + void CastWebContentsImpl::RenderProcessGone(base::TerminationStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); LOG(INFO) << "Render process for main frame exited unexpectedly."; @@ -342,18 +371,33 @@ TracePageLoadBegin(loading_url); UpdatePageState(); DCHECK_EQ(page_state_, PageState::LOADING); - NotifyObservers(); + NotifyPageState(); } void CastWebContentsImpl::DidFinishNavigation( content::NavigationHandle* navigation_handle) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + const net::Error error_code = navigation_handle->GetNetErrorCode(); + // If the navigation was not committed, it means either the page was a // download or error 204/205, or the navigation never left the previous // URL. Ignore these navigations. if (!navigation_handle->HasCommitted()) { LOG(WARNING) << "Navigation did not commit: url=" << navigation_handle->GetURL(); + + // Detect if there was a blocked navigation. Some pages may disallow + // navigation, such as with a web-based window manager. In this case, the + // page can handle the navigation by opening a new tab or simply ignoring + // the request. + if (navigation_handle->HasUserGesture() && + (error_code == net::ERR_ABORTED)) { + for (Observer& observer : observer_list_) { + observer.DidFinishBlockedNavigation(navigation_handle->GetURL()); + } + } + return; } @@ -364,8 +408,6 @@ if (!navigation_handle->IsErrorPage()) return; - net::Error error_code = navigation_handle->GetNetErrorCode(); - // If we abort errors in an iframe, it can create a really confusing // and fragile user experience. Rather than create a list of errors // that are most likely to occur, we ignore all of them for now. @@ -463,7 +505,7 @@ main_frame_loaded_ = true; UpdatePageState(); DCHECK(page_state_ == PageState::LOADED); - NotifyObservers(); + NotifyPageState(); } void CastWebContentsImpl::UpdatePageState() { @@ -487,25 +529,37 @@ } } -void CastWebContentsImpl::NotifyObservers() { +void CastWebContentsImpl::NotifyPageState() { if (!delegate_) return; // Don't notify if the page state didn't change. if (last_state_ == page_state_) return; - // Don't recursively notify the delegate. + // Don't recursively notify the observers. if (notifying_) return; notifying_ = true; if (stopped_ && !stop_notified_) { stop_notified_ = true; - delegate_->OnPageStopped(this, last_error_); + for (auto& observer : observer_list_) { + observer.OnPageStopped(this, last_error_); + } } else { - delegate_->OnPageStateChanged(this); + for (auto& observer : observer_list_) { + observer.OnPageStateChanged(this); + } } notifying_ = false; } +void CastWebContentsImpl::MainFrameWasResized(bool width_changed) { + if (!web_contents_) + return; + for (auto& observer : observer_list_) { + observer.MainFrameResized(web_contents_->GetContainerBounds()); + } +} + void CastWebContentsImpl::ResourceLoadComplete( content::RenderFrameHost* render_frame_host, const content::GlobalRequestID& request_id, @@ -531,10 +585,29 @@ inner_web_contents, InitParams{nullptr, enabled_for_dev_, false /* use_cma_renderer */, false /* is_root_window */, false /* handle_inner_contents */, - false /* use_media_blocker */})); + false /* use_media_blocker */, view_background_color_})); delegate_->InnerContentsCreated(result.first->get(), this); } +void CastWebContentsImpl::TitleWasSet(content::NavigationEntry* entry) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!entry) + return; + for (Observer& observer : observer_list_) { + observer.UpdateTitle(entry->GetTitle()); + } +} + +void CastWebContentsImpl::DidFirstVisuallyNonEmptyPaint() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + metrics::CastMetricsHelper::GetInstance()->LogTimeToFirstPaint(); + + for (Observer& observer : observer_list_) { + observer.DidFirstVisuallyNonEmptyPaint(); + } +} + void CastWebContentsImpl::WebContentsDestroyed() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); closing_ = false; @@ -547,6 +620,53 @@ DCHECK_EQ(PageState::DESTROYED, page_state_); } +void CastWebContentsImpl::DidUpdateFaviconURL( + const std::vector<content::FaviconURL>& candidates) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (candidates.empty()) + return; + GURL icon_url; + bool found_touch_icon = false; + // icon search order: + // 1) apple-touch-icon-precomposed + // 2) apple-touch-icon + // 3) icon + for (auto& favicon : candidates) { + if (favicon.icon_type == + content::FaviconURL::IconType::kTouchPrecomposedIcon) { + icon_url = favicon.icon_url; + break; + } else if ((favicon.icon_type == + content::FaviconURL::IconType::kTouchIcon) && + !found_touch_icon) { + found_touch_icon = true; + icon_url = favicon.icon_url; + } else if (!found_touch_icon) { + icon_url = favicon.icon_url; + } + } + + for (Observer& observer : observer_list_) { + observer.UpdateFaviconURL(icon_url); + } +} + +void CastWebContentsImpl::MediaStartedPlaying( + const MediaPlayerInfo& video_type, + const content::MediaPlayerId& id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + metrics::CastMetricsHelper::GetInstance()->LogMediaPlay(); +} + +void CastWebContentsImpl::MediaStoppedPlaying( + const MediaPlayerInfo& video_type, + const content::MediaPlayerId& id, + content::WebContentsObserver::MediaStoppedReason reason) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + metrics::CastMetricsHelper::GetInstance()->LogMediaPause(); +} + void CastWebContentsImpl::TracePageLoadBegin(const GURL& url) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT_ASYNC_BEGIN1("browser,navigation", "CastWebContentsImpl Launch",
diff --git a/chromecast/browser/cast_web_contents_impl.h b/chromecast/browser/cast_web_contents_impl.h index 3553575..e0394a9a 100644 --- a/chromecast/browser/cast_web_contents_impl.h +++ b/chromecast/browser/cast_web_contents_impl.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/sequence_checker.h" #include "base/time/time.h" #include "chromecast/browser/cast_media_blocker.h" @@ -62,10 +63,13 @@ // content::WebContentsObserver implementation: void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; + void RenderFrameHostChanged(content::RenderFrameHost* old_host, + content::RenderFrameHost* new_host) override; void OnInterfaceRequestFromFrame( content::RenderFrameHost* /* render_frame_host */, const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe) override; + void RenderViewCreated(content::RenderViewHost* render_view_host) override; void RenderProcessGone(base::TerminationStatus status) override; void DidStartNavigation( content::NavigationHandle* navigation_handle) override; @@ -77,19 +81,30 @@ const GURL& validated_url, int error_code, const base::string16& error_description) override; + void MainFrameWasResized(bool width_changed) override; void ResourceLoadComplete( content::RenderFrameHost* render_frame_host, const content::GlobalRequestID& request_id, const content::mojom::ResourceLoadInfo& resource_load_info) override; void InnerWebContentsCreated( content::WebContents* inner_web_contents) override; + void TitleWasSet(content::NavigationEntry* entry) override; + void DidFirstVisuallyNonEmptyPaint() override; void WebContentsDestroyed() override; + void DidUpdateFaviconURL( + const std::vector<content::FaviconURL>& candidates) override; + void MediaStartedPlaying(const MediaPlayerInfo& video_type, + const content::MediaPlayerId& id) override; + void MediaStoppedPlaying( + const MediaPlayerInfo& video_type, + const content::MediaPlayerId& id, + content::WebContentsObserver::MediaStoppedReason reason) override; private: void OnPageLoading(); void OnPageLoaded(); void UpdatePageState(); - void NotifyObservers(); + void NotifyPageState(); void TracePageLoadBegin(const GURL& url); void TracePageLoadEnd(const GURL& url); void DisableDebugging(); @@ -103,6 +118,7 @@ const bool enabled_for_dev_; bool use_cma_renderer_; const bool handle_inner_contents_; + BackgroundColor view_background_color_; shell::RemoteDebuggingServer* const remote_debugging_server_; std::unique_ptr<CastMediaBlocker> media_blocker_;
diff --git a/chromecast/browser/cast_web_view.cc b/chromecast/browser/cast_web_view.cc index 0c23447..986e5f25 100644 --- a/chromecast/browser/cast_web_view.cc +++ b/chromecast/browser/cast_web_view.cc
@@ -31,4 +31,6 @@ CastWebView::CreateParams::CreateParams() {} +CastWebView::CreateParams::CreateParams(const CreateParams& other) = default; + } // namespace chromecast
diff --git a/chromecast/browser/cast_web_view.h b/chromecast/browser/cast_web_view.h index fd46530..905e0ed 100644 --- a/chromecast/browser/cast_web_view.h +++ b/chromecast/browser/cast_web_view.h
@@ -70,9 +70,6 @@ // Identifies the activity that is hosted by this CastWebView. std::string activity_id = ""; - // Whether this CastWebView has a transparent background. - bool transparent = false; - // Whether this CastWebView is granted media access. bool allow_media_access = false; @@ -87,6 +84,7 @@ std::string log_prefix = ""; CreateParams(); + CreateParams(const CreateParams& other); }; CastWebView();
diff --git a/chromecast/browser/cast_web_view_default.cc b/chromecast/browser/cast_web_view_default.cc index b80a761..04517ba 100644 --- a/chromecast/browser/cast_web_view_default.cc +++ b/chromecast/browser/cast_web_view_default.cc
@@ -17,7 +17,6 @@ #include "chromecast/browser/cast_web_contents_manager.h" #include "chromecast/chromecast_buildflags.h" #include "content/public/browser/media_capture_devices.h" -#include "content/public/browser/media_player_id.h" #include "content/public/browser/media_session.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" @@ -64,7 +63,6 @@ browser_context_(browser_context), site_instance_(std::move(site_instance)), delegate_(params.delegate), - transparent_(params.transparent), allow_media_access_(params.allow_media_access), log_prefix_(params.log_prefix), web_contents_(CreateWebContents(browser_context_, site_instance_)), @@ -286,22 +284,6 @@ : WebContentsDelegate::RunBluetoothChooser(frame, event_handler); } -void CastWebViewDefault::RenderViewCreated( - content::RenderViewHost* render_view_host) { - content::RenderWidgetHostView* view = - render_view_host->GetWidget()->GetView(); - if (view) { - view->SetBackgroundColor( - transparent_ ? SK_ColorTRANSPARENT - : chromecast::GetSwitchValueColor( - switches::kCastAppBackgroundColor, SK_ColorBLACK)); - } -} - -void CastWebViewDefault::DidFirstVisuallyNonEmptyPaint() { - metrics::CastMetricsHelper::GetInstance()->LogTimeToFirstPaint(); -} - void CastWebViewDefault::DidStartNavigation( content::NavigationHandle* navigation_handle) { if (!resize_window_when_navigation_starts_) { @@ -319,16 +301,4 @@ #endif } -void CastWebViewDefault::MediaStartedPlaying(const MediaPlayerInfo& media_info, - const content::MediaPlayerId& id) { - metrics::CastMetricsHelper::GetInstance()->LogMediaPlay(); -} - -void CastWebViewDefault::MediaStoppedPlaying( - const MediaPlayerInfo& media_info, - const content::MediaPlayerId& id, - WebContentsObserver::MediaStoppedReason reason) { - metrics::CastMetricsHelper::GetInstance()->LogMediaPause(); -} - } // namespace chromecast
diff --git a/chromecast/browser/cast_web_view_default.h b/chromecast/browser/cast_web_view_default.h index 8ace8b4..66de3de 100644 --- a/chromecast/browser/cast_web_view_default.h +++ b/chromecast/browser/cast_web_view_default.h
@@ -20,9 +20,7 @@ namespace content { class BrowserContext; -class RenderViewHost; class SiteInstance; -struct MediaPlayerId; } // namespace content namespace chromecast { @@ -56,16 +54,8 @@ private: // WebContentsObserver implementation: - void RenderViewCreated(content::RenderViewHost* render_view_host) override; - void DidFirstVisuallyNonEmptyPaint() override; void DidStartNavigation( content::NavigationHandle* navigation_handle) override; - void MediaStartedPlaying(const MediaPlayerInfo& media_info, - const content::MediaPlayerId& id) override; - void MediaStoppedPlaying( - const MediaPlayerInfo& media_info, - const content::MediaPlayerId& id, - WebContentsObserver::MediaStoppedReason reason) override; // WebContentsDelegate implementation: content::WebContents* OpenURLFromTab( @@ -94,7 +84,6 @@ const scoped_refptr<content::SiteInstance> site_instance_; Delegate* const delegate_; - const bool transparent_; const bool allow_media_access_; const std::string log_prefix_;
diff --git a/chromecast/browser/service/cast_service_simple.cc b/chromecast/browser/service/cast_service_simple.cc index be825acd..01da7d67 100644 --- a/chromecast/browser/service/cast_service_simple.cc +++ b/chromecast/browser/service/cast_service_simple.cc
@@ -90,12 +90,6 @@ cast_web_view_.reset(); } -void CastServiceSimple::OnPageStopped(CastWebContents* cast_web_contents, - int error_code) {} - -void CastServiceSimple::OnPageStateChanged(CastWebContents* cast_web_contents) { -} - void CastServiceSimple::OnWindowDestroyed() {} void CastServiceSimple::OnKeyEvent(const ui::KeyEvent& key_event) {}
diff --git a/chromecast/browser/service/cast_service_simple.h b/chromecast/browser/service/cast_service_simple.h index 512a10f..9ead9ae 100644 --- a/chromecast/browser/service/cast_service_simple.h +++ b/chromecast/browser/service/cast_service_simple.h
@@ -35,11 +35,6 @@ void StartInternal() override; void StopInternal() override; - // CastWebView::Delegate implementation: - void OnPageStopped(CastWebContents* cast_web_contents, - int error_code) override; - void OnPageStateChanged(CastWebContents* cast_web_contents) override; - // CastContentWindow::Delegate implementation: void OnWindowDestroyed() override; void OnKeyEvent(const ui::KeyEvent& key_event) override;
diff --git a/chromecast/browser/test/cast_browser_test.cc b/chromecast/browser/test/cast_browser_test.cc index a686ba311..6c392cc 100644 --- a/chromecast/browser/test/cast_browser_test.cc +++ b/chromecast/browser/test/cast_browser_test.cc
@@ -84,11 +84,6 @@ return web_contents; } -void CastBrowserTest::OnPageStateChanged(CastWebContents* cast_web_contents) {} - -void CastBrowserTest::OnPageStopped(CastWebContents* cast_web_contents, - int error_code) {} - void CastBrowserTest::OnWindowDestroyed() {} void CastBrowserTest::OnKeyEvent(const ui::KeyEvent& key_event) {}
diff --git a/chromecast/browser/test/cast_browser_test.h b/chromecast/browser/test/cast_browser_test.h index e6b7386..187f170f 100644 --- a/chromecast/browser/test/cast_browser_test.h +++ b/chromecast/browser/test/cast_browser_test.h
@@ -44,9 +44,6 @@ private: // CastWebView::Delegate implementation: - void OnPageStateChanged(CastWebContents* cast_web_contents) override; - void OnPageStopped(CastWebContents* cast_web_contents, - int error_code) override; void OnWindowDestroyed() override; void OnKeyEvent(const ui::KeyEvent& key_event) override; void OnVisibilityChange(VisibilityType visibility_type) override;
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.cc b/chromecast/media/cma/pipeline/media_pipeline_impl.cc index 26add94..2840785 100644 --- a/chromecast/media/cma/pipeline/media_pipeline_impl.cc +++ b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
@@ -44,12 +44,6 @@ constexpr base::TimeDelta kHighBufferThresholdMediaSource( base::TimeDelta::FromMilliseconds(1000)); -// Buffering parameters when load_type is kLoadTypeCommunication. -constexpr base::TimeDelta kLowBufferThresholdCommunication( - base::TimeDelta::FromMilliseconds(0)); -constexpr base::TimeDelta kHighBufferThresholdCommunication( - base::TimeDelta::FromMilliseconds(20)); - // Interval between two updates of the media time. constexpr base::TimeDelta kTimeUpdateInterval( base::TimeDelta::FromMilliseconds(250)); @@ -133,9 +127,6 @@ if (load_type == kLoadTypeMediaSource) { low_threshold = kLowBufferThresholdMediaSource; high_threshold = kHighBufferThresholdMediaSource; - } else if (load_type == kLoadTypeCommunication) { - low_threshold = kLowBufferThresholdCommunication; - high_threshold = kHighBufferThresholdCommunication; } scoped_refptr<BufferingConfig> buffering_config( new BufferingConfig(low_threshold, high_threshold));
diff --git a/chromecast/net/network_change_notifier_factory_cast.cc b/chromecast/net/network_change_notifier_factory_cast.cc index 4c1cd60..42d27e43 100644 --- a/chromecast/net/network_change_notifier_factory_cast.cc +++ b/chromecast/net/network_change_notifier_factory_cast.cc
@@ -9,9 +9,11 @@ namespace chromecast { -net::NetworkChangeNotifier* NetworkChangeNotifierFactoryCast::CreateInstance() { +std::unique_ptr<net::NetworkChangeNotifier> +NetworkChangeNotifierFactoryCast::CreateInstance() { // Caller assumes ownership. - return new net::NetworkChangeNotifierLinux(GetIgnoredInterfaces()); + return std::make_unique<net::NetworkChangeNotifierLinux>( + GetIgnoredInterfaces()); } NetworkChangeNotifierFactoryCast::~NetworkChangeNotifierFactoryCast() {
diff --git a/chromecast/net/network_change_notifier_factory_cast.h b/chromecast/net/network_change_notifier_factory_cast.h index a2a6d315..f9ef70f 100644 --- a/chromecast/net/network_change_notifier_factory_cast.h +++ b/chromecast/net/network_change_notifier_factory_cast.h
@@ -18,7 +18,7 @@ ~NetworkChangeNotifierFactoryCast() override; // net::NetworkChangeNotifierFactory implementation: - net::NetworkChangeNotifier* CreateInstance() override; + std::unique_ptr<net::NetworkChangeNotifier> CreateInstance() override; private: DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierFactoryCast);
diff --git a/chromecast/net/network_change_notifier_factory_fuchsia.cc b/chromecast/net/network_change_notifier_factory_fuchsia.cc index 9c2bb72e..d8315a4 100644 --- a/chromecast/net/network_change_notifier_factory_fuchsia.cc +++ b/chromecast/net/network_change_notifier_factory_fuchsia.cc
@@ -12,7 +12,7 @@ namespace chromecast { -net::NetworkChangeNotifier* +std::unique_ptr<net::NetworkChangeNotifier> NetworkChangeNotifierFactoryFuchsia::CreateInstance() { uint32_t required_features = GetSwitchValueBoolean(switches::kRequireWlan, false) @@ -20,7 +20,7 @@ : 0; // Caller assumes ownership. - return new net::NetworkChangeNotifierFuchsia(required_features); + return std::make_unique<net::NetworkChangeNotifierFuchsia>(required_features); } NetworkChangeNotifierFactoryFuchsia::NetworkChangeNotifierFactoryFuchsia() =
diff --git a/chromecast/net/network_change_notifier_factory_fuchsia.h b/chromecast/net/network_change_notifier_factory_fuchsia.h index 0cf0818..0a97e24e 100644 --- a/chromecast/net/network_change_notifier_factory_fuchsia.h +++ b/chromecast/net/network_change_notifier_factory_fuchsia.h
@@ -17,7 +17,7 @@ ~NetworkChangeNotifierFactoryFuchsia() override; // net::NetworkChangeNotifierFactory implementation: - net::NetworkChangeNotifier* CreateInstance() override; + std::unique_ptr<net::NetworkChangeNotifier> CreateInstance() override; private: DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierFactoryFuchsia);
diff --git a/chromeos/dbus/audio/cras_audio_client_unittest.cc b/chromeos/dbus/audio/cras_audio_client_unittest.cc index 5ec4151c..2a2cbabd 100644 --- a/chromeos/dbus/audio/cras_audio_client_unittest.cc +++ b/chromeos/dbus/audio/cras_audio_client_unittest.cc
@@ -10,8 +10,8 @@ #include <vector> #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "dbus/message.h" #include "dbus/mock_bus.h" #include "dbus/mock_object_proxy.h" @@ -437,7 +437,7 @@ // The interface name. const std::string interface_name_; // A message loop to emulate asynchronous behavior. - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; // The mock bus. scoped_refptr<dbus::MockBus> mock_bus_; // The mock object proxy. @@ -476,7 +476,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { output_mute_changed_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -490,7 +490,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { input_mute_changed_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -504,7 +504,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { nodes_changed_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -518,7 +518,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { active_output_node_changed_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -532,7 +532,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { active_input_node_changed_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -546,7 +546,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { output_node_volume_changed_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -560,7 +560,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { hotword_triggered_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -574,7 +574,7 @@ dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) { number_of_active_streams_changed_handler_ = signal_callback; const bool success = true; - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*on_connected_callback), interface_name, signal_name, success)); } @@ -588,7 +588,7 @@ EXPECT_EQ(expected_method_name_, method_call->GetMember()); dbus::MessageReader reader(method_call); argument_checker_.Run(&reader); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(std::move(*response), response_)); }
diff --git a/chromeos/dbus/fake_concierge_client.cc b/chromeos/dbus/fake_concierge_client.cc index 4b03e09..6a338595 100644 --- a/chromeos/dbus/fake_concierge_client.cc +++ b/chromeos/dbus/fake_concierge_client.cc
@@ -164,8 +164,10 @@ void FakeConciergeClient::WaitForServiceToBeAvailable( dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) { + wait_for_service_to_be_available_called_ = true; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), true)); + FROM_HERE, base::BindOnce(std::move(callback), + wait_for_service_to_be_available_response_)); } void FakeConciergeClient::GetContainerSshKeys(
diff --git a/chromeos/dbus/fake_concierge_client.h b/chromeos/dbus/fake_concierge_client.h index 71169415..0532d38ee 100644 --- a/chromeos/dbus/fake_concierge_client.h +++ b/chromeos/dbus/fake_concierge_client.h
@@ -137,6 +137,10 @@ DBusMethodCallback<vm_tools::concierge::ListUsbDeviceResponse> callback) override; + // Indicates whether WaitForServiceToBeAvailable has been called. + bool wait_for_service_to_be_available_called() const { + return wait_for_service_to_be_available_called_; + } // Indicates whether CreateDiskImage has been called bool create_disk_image_called() const { return create_disk_image_called_; } // Indicates whether DestroyDiskImage has been called @@ -169,6 +173,11 @@ is_disk_image_progress_signal_connected_ = connected; } + void set_wait_for_service_to_be_available_response( + bool wait_for_service_to_be_available_response) { + wait_for_service_to_be_available_response_ = + wait_for_service_to_be_available_response; + } void set_create_disk_image_response( const vm_tools::concierge::CreateDiskImageResponse& create_disk_image_response) { @@ -254,6 +263,7 @@ void OnDiskImageProgress( const vm_tools::concierge::DiskImageStatusResponse& signal); + bool wait_for_service_to_be_available_called_ = false; bool create_disk_image_called_ = false; bool destroy_disk_image_called_ = false; bool import_disk_image_called_ = false; @@ -269,6 +279,7 @@ bool is_container_startup_failed_signal_connected_ = true; bool is_disk_image_progress_signal_connected_ = true; + bool wait_for_service_to_be_available_response_ = true; vm_tools::concierge::CreateDiskImageResponse create_disk_image_response_; vm_tools::concierge::DestroyDiskImageResponse destroy_disk_image_response_; vm_tools::concierge::ImportDiskImageResponse import_disk_image_response_;
diff --git a/chromeos/login/auth/user_context.cc b/chromeos/login/auth/user_context.cc index 1ee55bbe..9ba9f54 100644 --- a/chromeos/login/auth/user_context.cc +++ b/chromeos/login/auth/user_context.cc
@@ -113,6 +113,10 @@ return auth_flow_; } +bool UserContext::IsUsingSamlPrincipalsApi() const { + return is_using_saml_principals_api_; +} + user_manager::UserType UserContext::GetUserType() const { return user_type_; } @@ -196,6 +200,11 @@ auth_flow_ = auth_flow; } +void UserContext::SetIsUsingSamlPrincipalsApi( + bool is_using_saml_principals_api) { + is_using_saml_principals_api_ = is_using_saml_principals_api; +} + void UserContext::SetPublicSessionLocale(const std::string& locale) { public_session_locale_ = locale; }
diff --git a/chromeos/login/auth/user_context.h b/chromeos/login/auth/user_context.h index c6d5b1e..1ba35e5 100644 --- a/chromeos/login/auth/user_context.h +++ b/chromeos/login/auth/user_context.h
@@ -79,6 +79,7 @@ bool IsUsingPin() const; bool IsForcingDircrypto() const; AuthFlow GetAuthFlow() const; + bool IsUsingSamlPrincipalsApi() const; user_manager::UserType GetUserType() const; const std::string& GetPublicSessionLocale() const; const std::string& GetPublicSessionInputMethod() const; @@ -105,6 +106,7 @@ void SetIsUsingPin(bool is_using_pin); void SetIsForcingDircrypto(bool is_forcing_dircrypto); void SetAuthFlow(AuthFlow auth_flow); + void SetIsUsingSamlPrincipalsApi(bool is_using_saml_principals_api); void SetPublicSessionLocale(const std::string& locale); void SetPublicSessionInputMethod(const std::string& input_method); void SetDeviceId(const std::string& device_id); @@ -130,6 +132,7 @@ bool is_using_pin_ = false; bool is_forcing_dircrypto_ = false; AuthFlow auth_flow_ = AUTH_FLOW_OFFLINE; + bool is_using_saml_principals_api_ = false; user_manager::UserType user_type_ = user_manager::USER_TYPE_REGULAR; std::string public_session_locale_; std::string public_session_input_method_;
diff --git a/chromeos/services/ime/decoder/decoder_engine.cc b/chromeos/services/ime/decoder/decoder_engine.cc index 84c9d1b..f657153 100644 --- a/chromeos/services/ime/decoder/decoder_engine.cc +++ b/chromeos/services/ime/decoder/decoder_engine.cc
@@ -4,6 +4,7 @@ #include "chromeos/services/ime/decoder/decoder_engine.h" +#include "base/bind_helpers.h" #include "base/files/file_path.h" #include "build/buildflag.h" #include "chromeos/services/ime/public/cpp/buildflags.h" @@ -13,17 +14,52 @@ namespace { +// TODO(https://crbug.com/837156): Use define instead. #if BUILDFLAG(ENABLE_CROS_IME_EXAMPLE_SO) const char kDecoderLibName[] = "input_decoder_example"; #else const char kDecoderLibName[] = "input_decoder_engine"; #endif +// A client delegate that makes calls on client side. +class ClientDelegate : public ImeClientDelegate { + public: + ClientDelegate(const std::string& ime_spec, + mojo::PendingRemote<mojom::InputChannel> remote) + : ime_spec_(ime_spec), client_remote_(std::move(remote)) { + client_remote_.set_disconnect_handler(base::BindOnce( + &ClientDelegate::OnDisconnected, base::Unretained(this))); + } + + ~ClientDelegate() override {} + + const char* ImeSpec() override { return ime_spec_.c_str(); } + + void Process(const uint8_t* data, size_t size) override { + if (client_remote_ && client_remote_.is_bound()) { + std::vector<uint8_t> msg(data, data + size); + client_remote_->ProcessMessage(msg, base::DoNothing()); + } + } + + void Destroy() override {} + + private: + void OnDisconnected() { + client_remote_.reset(); + LOG(ERROR) << "Client remote is disconnected." << ime_spec_; + } + + // The ime specification which is unique in the scope of engine. + std::string ime_spec_; + + // The InputChannel remote used to talk to the client. + mojo::Remote<mojom::InputChannel> client_remote_; +}; + } // namespace -DecoderEngine::DecoderEngine( - service_manager::Connector* connector, - scoped_refptr<base::SequencedTaskRunner> task_runner) { +DecoderEngine::DecoderEngine(ImeCrosPlatform* platform) : platform_(platform) { // TODO(https://crbug.com/837156): Connect utility services for InputEngine // via connector(). Eg. take advantage of the file and network services to // download relevant language models required by the decocers to the device. @@ -31,39 +67,52 @@ // Load the decoder library. base::NativeLibraryLoadError load_error; base::FilePath lib_path(base::GetNativeLibraryName(kDecoderLibName)); - library_.Reset(base::LoadNativeLibrary(lib_path, &load_error)); + library_ = base::ScopedNativeLibrary(lib_path); if (!library_.is_valid()) { - LOG(ERROR) << "Failed to load a decoder shared library."; + LOG(ERROR) << "Failed to load a decoder shared library, error: " + << library_.GetError()->ToString(); return; } - // TODO(https://crbug.com/837156): Based on the defined function pointer types - // in DecoderAPILibrary, load all required function pointers. + ImeMainEntryCreateFn createMainEntryFn = + reinterpret_cast<ImeMainEntryCreateFn>( + library_.GetFunctionPointer(IME_MAIN_ENTRY_CREATE_FN_NAME)); + + engine_main_entry_ = createMainEntryFn(platform_); + LOG(ERROR) << "Loaded SO main_entry in DecoderEngine!"; } DecoderEngine::~DecoderEngine() {} -bool DecoderEngine::BindRequest(const std::string& ime_spec, - mojom::InputChannelRequest request, - mojom::InputChannelPtr client, - const std::vector<uint8_t>& extra) { - if (!IsImeSupported(ime_spec)) +bool DecoderEngine::BindRequest( + const std::string& ime_spec, + mojo::PendingReceiver<mojom::InputChannel> receiver, + mojo::PendingRemote<mojom::InputChannel> remote, + const std::vector<uint8_t>& extra) { + // If the shared library supports this ime_spec. + if (IsImeSupported(ime_spec)) { + // Activates an IME engine via the shared library. Passing a + // |ClientDelegate| for engine instance created by the shared library to + // make safe calls on the client. + if (engine_main_entry_->ActivateIme( + ime_spec.c_str(), + new ClientDelegate(ime_spec, std::move(remote)))) { + channel_receivers_.Add(this, std::move(receiver)); + // TODO(https://crbug.com/837156): Registry connection error handler. + return true; + } return false; - // TODO(https://crbug.com/837156): Notify the input logic loaded from the - // shared library about the change by forwarding the information received. - // Moreover, in order to make safe calls on the clientPtr inside the input - // logic with multiple threads, we will send a wrapper of the clientPtr, - // where we make sure it runs in the correct SequencedTaskRunner. - channel_bindings_.AddBinding(this, std::move(request)); - // TODO(https://crbug.com/837156): Registry connection error handler. - return true; + } + + // Otherwise, try the rule-based engine for this ime_spec. + return InputEngine::BindRequest(ime_spec, std::move(receiver), + std::move(remote), extra); } bool DecoderEngine::IsImeSupported(const std::string& ime_spec) { - // TODO(https://crbug.com/837156): Check the capability of the loaded shared - // library first. - return InputEngine::IsImeSupported(ime_spec); + return engine_main_entry_ && + engine_main_entry_->IsImeSupported(ime_spec.c_str()); } void DecoderEngine::ProcessMessage(const std::vector<uint8_t>& message,
diff --git a/chromeos/services/ime/decoder/decoder_engine.h b/chromeos/services/ime/decoder/decoder_engine.h index 86b32cc..e211b8e3 100644 --- a/chromeos/services/ime/decoder/decoder_engine.h +++ b/chromeos/services/ime/decoder/decoder_engine.h
@@ -7,6 +7,7 @@ #include "base/scoped_native_library.h" #include "chromeos/services/ime/input_engine.h" +#include "chromeos/services/ime/public/cpp/shared_lib/interfaces.h" #include "chromeos/services/ime/public/mojom/input_engine.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/connector.h" @@ -23,15 +24,16 @@ // a premium typing experience. class DecoderEngine : public InputEngine { public: - DecoderEngine(service_manager::Connector* connector, - scoped_refptr<base::SequencedTaskRunner> task_runner); + explicit DecoderEngine(ImeCrosPlatform* platform); ~DecoderEngine() override; // InputEngine overrides: bool BindRequest(const std::string& ime_spec, - mojom::InputChannelRequest request, - mojom::InputChannelPtr client, + mojo::PendingReceiver<mojom::InputChannel> receiver, + mojo::PendingRemote<mojom::InputChannel> remote, const std::vector<uint8_t>& extra) override; + + // Returns whether the loaded shared library supports this ime_spec. bool IsImeSupported(const std::string& ime_spec) override; void ProcessMessage(const std::vector<uint8_t>& message, ProcessMessageCallback callback) override; @@ -40,7 +42,11 @@ // Shared library handle of the implementation for input logic with decoders. base::ScopedNativeLibrary library_; - mojo::BindingSet<mojom::InputChannel> channel_bindings_; + ImeEngineMainEntry* engine_main_entry_ = nullptr; + + ImeCrosPlatform* platform_ = nullptr; + + mojo::ReceiverSet<mojom::InputChannel> channel_receivers_; DISALLOW_COPY_AND_ASSIGN(DecoderEngine); };
diff --git a/chromeos/services/ime/decoder/downloader_impl.cc b/chromeos/services/ime/decoder/downloader_impl.cc index 68c820a..90b66fdd 100644 --- a/chromeos/services/ime/decoder/downloader_impl.cc +++ b/chromeos/services/ime/decoder/downloader_impl.cc
@@ -18,7 +18,7 @@ int DownloaderImpl::DownloadToFile(const char* url, const DownloadOptions& options, const char* file_path, - DownloadCallback callback) { + ImeCrosDownloadCallback callback) { // TODO(crbug/946913): Implement this. return 0; }
diff --git a/chromeos/services/ime/decoder/downloader_impl.h b/chromeos/services/ime/decoder/downloader_impl.h index f11140c..90c2d8e 100644 --- a/chromeos/services/ime/decoder/downloader_impl.h +++ b/chromeos/services/ime/decoder/downloader_impl.h
@@ -11,7 +11,7 @@ namespace chromeos { namespace ime { -class DownloaderImpl : public Downloader { +class DownloaderImpl : public ImeCrosDownloader { public: explicit DownloaderImpl(); ~DownloaderImpl() override; @@ -19,7 +19,7 @@ int DownloadToFile(const char* url, const DownloadOptions& options, const char* file_path, - DownloadCallback callback) override; + ImeCrosDownloadCallback callback) override; void Cancel(int request_id) override;
diff --git a/chromeos/services/ime/ime_service.cc b/chromeos/services/ime/ime_service.cc index e50eefa1..8f9d425 100644 --- a/chromeos/services/ime/ime_service.cc +++ b/chromeos/services/ime/ime_service.cc
@@ -29,8 +29,7 @@ &ImeService::OnConnectionLost, base::Unretained(this))); #if BUILDFLAG(ENABLE_CROS_IME_DECODER) - input_engine_ = std::make_unique<DecoderEngine>( - service_binding_.GetConnector(), base::SequencedTaskRunnerHandle::Get()); + input_engine_ = std::make_unique<DecoderEngine>(this); #else input_engine_ = std::make_unique<InputEngine>(); #endif @@ -68,5 +67,31 @@ } } +const char* ImeService::GetImeBundleDir() { + return ""; +} + +const char* ImeService::GetImeGlobalDir() { + return ""; +} + +const char* ImeService::GetImeUserHomeDir() { + return ""; +} + +int ImeService::SimpleDownloadToFile(const char* url, + const char* file_path, + SimpleDownloadCallback callback) { + // TODO(https://crbug.com/837156): Create a download with PlatformAccess + // Mojo remote. Make sure the parent of |file_path| is ImeUserHomeDir. + return 0; +} + +ImeCrosDownloader* ImeService::GetDownloader() { + // TODO(https://crbug.com/837156): Create a ImeCrosDownloader based on its + // specification in interfaces. The caller should free it after use. + return nullptr; +} + } // namespace ime } // namespace chromeos
diff --git a/chromeos/services/ime/ime_service.h b/chromeos/services/ime/ime_service.h index 9cd050da..27a378a 100644 --- a/chromeos/services/ime/ime_service.h +++ b/chromeos/services/ime/ime_service.h
@@ -6,6 +6,7 @@ #define CHROMEOS_SERVICES_IME_IME_SERVICE_H_ #include "chromeos/services/ime/input_engine.h" +#include "chromeos/services/ime/public/cpp/shared_lib/interfaces.h" #include "chromeos/services/ime/public/mojom/input_engine.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -19,7 +20,8 @@ namespace ime { class ImeService : public service_manager::Service, - public mojom::InputEngineManager { + public mojom::InputEngineManager, + public ImeCrosPlatform { public: explicit ImeService( mojo::PendingReceiver<service_manager::mojom::Service> receiver); @@ -40,6 +42,15 @@ const std::vector<uint8_t>& extra, ConnectToImeEngineCallback callback) override; + // ImeCrosPlatform overrides: + const char* GetImeBundleDir() override; + const char* GetImeGlobalDir() override; + const char* GetImeUserHomeDir() override; + int SimpleDownloadToFile(const char* url, + const char* file_path, + SimpleDownloadCallback callback) override; + ImeCrosDownloader* GetDownloader() override; + // Adds a mojom::InputEngineManager receiver to this object. void AddInputEngineManagerReceiver( mojo::PendingReceiver<mojom::InputEngineManager> receiver);
diff --git a/chromeos/services/ime/public/cpp/shared_lib/interfaces.h b/chromeos/services/ime/public/cpp/shared_lib/interfaces.h index 3a75944..af04bee 100644 --- a/chromeos/services/ime/public/cpp/shared_lib/interfaces.h +++ b/chromeos/services/ime/public/cpp/shared_lib/interfaces.h
@@ -63,7 +63,10 @@ // issued |request_id| (as returned by DownloadToFile()) and an |error_code| (as // defined at // https://cs.chromium.org/chromium/src/net/base/net_error_list.h?rcl=f9c935b73381772d508eebba1e216c437139d475). -typedef void (*DownloadCallback)(int request_id, int status_code); +typedef void (*ImeCrosDownloadCallback)(int request_id, int status_code); + +// A simple downloading callback. +typedef void (*SimpleDownloadCallback)(int status_code, const char* file_path); // Based on RequestPriority defined at // https://cs.chromium.org/chromium/src/net/base/request_priority.h?rcl=f9c935b73381772d508eebba1e216c437139d475 @@ -97,9 +100,9 @@ }; // Provides CrOS network download service to the shared library. -class Downloader { +class ImeCrosDownloader { protected: - virtual ~Downloader() = default; + virtual ~ImeCrosDownloader() = default; public: // Download data from the given |url| and store into a file located at the @@ -114,7 +117,7 @@ virtual int DownloadToFile(const char* url, const DownloadOptions& options, const char* file_path, - DownloadCallback callback) = 0; + ImeCrosDownloadCallback callback) = 0; // Cancel the download whose |request_id| is given (|request_id| is issued // in the return value of each DownloadToFile() call). The callback of a @@ -124,14 +127,14 @@ virtual void Cancel(int request_id) = 0; }; -// This defines the `Platform` interface, which is used throughout the shared -// library to manage platform-specific data/operations. +// This defines the `ImeCrosPlatform` interface, which is used throughout the +// shared library to manage platform-specific data/operations. // // This class should be provided by the IME service before creating an // `ImeEngineMainEntry` and be always owned by the IME service. -class Platform { +class ImeCrosPlatform { protected: - virtual ~Platform() = default; + virtual ~ImeCrosPlatform() = default; public: // The three methods below are Getters of the local data directories on the @@ -154,8 +157,15 @@ // Get the Downloader that provides CrOS network download service. Ownership // of the returned Downloader instance is never transferred, i.e. it remains // owned by the IME service / Platform at all times. - virtual Downloader* GetDownloader() = 0; - + virtual ImeCrosDownloader* GetDownloader() = 0; + + // A shortcut for starting a downloading by the network |SimpleURLLoader|. + // Each SimpleDownloadToFile can only be used for a single request. + // Make a call after the previous task completes or cancels. + virtual int SimpleDownloadToFile(const char* url, + const char* file_path, + SimpleDownloadCallback callback) = 0; + // TODO(https://crbug.com/837156): Provide Logger for main entry. }; @@ -224,7 +234,7 @@ // name defined in IME_MAIN_ENTRY_CREATE_FN_NAME. // // Returns an instance of ImeEngineMainEntry from the IME shared library. -typedef ImeEngineMainEntry* (*ImeMainEntryCreateFn)(Platform*); +typedef ImeEngineMainEntry* (*ImeMainEntryCreateFn)(ImeCrosPlatform*); // Defined name of ImeMainEntryCreateFn exported from shared library. #define IME_MAIN_ENTRY_CREATE_FN_NAME "CreateImeMainEntry"
diff --git a/components/arc/session/arc_bridge_host_impl.cc b/components/arc/session/arc_bridge_host_impl.cc index 2aefe7f..88359e4c 100644 --- a/components/arc/session/arc_bridge_host_impl.cc +++ b/components/arc/session/arc_bridge_host_impl.cc
@@ -37,6 +37,7 @@ #include "components/arc/common/metrics.mojom.h" #include "components/arc/common/midis.mojom.h" #include "components/arc/common/net.mojom.h" +#include "components/arc/common/notifications.mojom.h" #include "components/arc/common/obb_mounter.mojom.h" #include "components/arc/common/oemcrypto.mojom.h" #include "components/arc/common/pip.mojom.h"
diff --git a/components/arc/video_accelerator/gpu_arc_video_protected_buffer_allocator.cc b/components/arc/video_accelerator/gpu_arc_video_protected_buffer_allocator.cc index c62068e..e37df87 100644 --- a/components/arc/video_accelerator/gpu_arc_video_protected_buffer_allocator.cc +++ b/components/arc/video_accelerator/gpu_arc_video_protected_buffer_allocator.cc
@@ -92,10 +92,15 @@ } VLOGF(2) << "format=" << media::VideoPixelFormatToString(pixel_format) << ", picture_size=" << picture_size.ToString(); + + auto buffer_format = VideoPixelFormatToGfxBufferFormat(pixel_format); + if (!buffer_format) { + std::move(callback).Run(false); + return; + } std::move(callback).Run( protected_buffer_allocator_->AllocateProtectedNativePixmap( - std::move(fd), media::VideoPixelFormatToGfxBufferFormat(pixel_format), - picture_size)); + std::move(fd), *buffer_format, picture_size)); return; }
diff --git a/components/autofill/core/browser/autocomplete_history_manager.cc b/components/autofill/core/browser/autocomplete_history_manager.cc index 865575043e..d078f58 100644 --- a/components/autofill/core/browser/autocomplete_history_manager.cc +++ b/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -183,23 +183,9 @@ return; } - // We put the following restriction on stored FormFields: - // - non-empty name - // - non-empty value - // - text field - // - autocomplete is not disabled - // - value is not a credit card number - // - value is not a SSN - // - field was not identified as a CVC field (this is handled in - // AutofillManager) - // - field is focusable - // - not a presentation field std::vector<FormFieldData> values; for (const FormFieldData& field : form.fields) { - if (!field.value.empty() && !field.name.empty() && IsTextField(field) && - field.should_autocomplete && !IsValidCreditCardNumber(field.value) && - !IsSSN(field.value) && field.is_focusable && - field.role != FormFieldData::RoleAttribute::kPresentation) { + if (IsFieldValueSaveable(field)) { values.push_back(field); } } @@ -366,4 +352,33 @@ }); } +// We put the following restriction on stored FormFields: +// - non-empty name +// - non-empty nor whitespace only value +// - text field +// - autocomplete is not disabled +// - value is not a credit card number +// - value is not a SSN +// - field was not identified as a CVC field (this is handled in +// AutofillManager) +// - field is focusable +// - not a presentation field +bool AutocompleteHistoryManager::IsFieldValueSaveable( + const FormFieldData& field) { + // We don't want to save a trimmed string, but we want to make sure that the + // value is non-empty nor only whitespaces. + bool is_value_valid = false; + for (const char& c : field.value) { + if (c != ' ') { + is_value_valid = true; + break; + } + } + + return is_value_valid && !field.name.empty() && IsTextField(field) && + field.should_autocomplete && !IsValidCreditCardNumber(field.value) && + !IsSSN(field.value) && field.is_focusable && + field.role != FormFieldData::RoleAttribute::kPresentation; +} + } // namespace autofill
diff --git a/components/autofill/core/browser/autocomplete_history_manager.h b/components/autofill/core/browser/autocomplete_history_manager.h index 6c9a70a7..79eaee4 100644 --- a/components/autofill/core/browser/autocomplete_history_manager.h +++ b/components/autofill/core/browser/autocomplete_history_manager.h
@@ -195,6 +195,10 @@ void OnAutofillCleanupReturned(WebDataServiceBase::Handle current_handle, std::unique_ptr<WDTypedResult> result); + // Returns true if the given |field| and its value are valid to be saved as a + // new or updated Autocomplete entry. + bool IsFieldValueSaveable(const FormFieldData& field); + // Must outlive this object. scoped_refptr<AutofillWebDataService> profile_database_;
diff --git a/components/autofill/core/browser/autocomplete_history_manager_unittest.cc b/components/autofill/core/browser/autocomplete_history_manager_unittest.cc index 53f1c850..919ac449b 100644 --- a/components/autofill/core/browser/autocomplete_history_manager_unittest.cc +++ b/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
@@ -257,6 +257,42 @@ /*is_autocomplete_enabled=*/false); } +// Verify that we don't save invalid values in Autocomplete. +TEST_F(AutocompleteHistoryManagerTest, InvalidValues) { + FormData form; + form.name = ASCIIToUTF16("MyForm"); + form.url = GURL("http://myform.com/form.html"); + form.action = GURL("http://myform.com/submit.html"); + + // Search field. + FormFieldData search_field; + + // Empty value. + search_field.label = ASCIIToUTF16("Search"); + search_field.name = ASCIIToUTF16("search"); + search_field.value = ASCIIToUTF16(""); + search_field.form_control_type = "search"; + form.fields.push_back(search_field); + + // Single whitespace. + search_field.label = ASCIIToUTF16("Search2"); + search_field.name = ASCIIToUTF16("other search"); + search_field.value = ASCIIToUTF16(" "); + search_field.form_control_type = "search"; + form.fields.push_back(search_field); + + // Multiple whitespaces. + search_field.label = ASCIIToUTF16("Search3"); + search_field.name = ASCIIToUTF16("other search"); + search_field.value = ASCIIToUTF16(" "); + search_field.form_control_type = "search"; + form.fields.push_back(search_field); + + EXPECT_CALL(*(web_data_service_.get()), AddFormFields(_)).Times(0); + autocomplete_manager_->OnWillSubmitForm(form, + /*is_autocomplete_enabled=*/true); +} + // Tests that text entered into fields specifying autocomplete="off" is not sent // to the WebDatabase to be saved. Note this is also important as the mechanism // for preventing CVCs from being saved.
diff --git a/components/autofill/core/common/autofill_regex_constants.cc b/components/autofill/core/common/autofill_regex_constants.cc index 6af11a1..6874f809 100644 --- a/components/autofill/core/common/autofill_regex_constants.cc +++ b/components/autofill/core/common/autofill_regex_constants.cc
@@ -88,18 +88,19 @@ const char kCountryLocationRe[] = "location"; const char kZipCodeRe[] = "zip|postal|post.*code|pcode" - "|pin.?code" // en-IN - "|postleitzahl" // de-DE - "|\\bcp\\b" // es - "|\\bcdp\\b" // fr-FR - "|\\bcap\\b" // it-IT - "|郵便番号" // ja-JP - "|codigo|codpos|\\bcep\\b" // pt-BR, pt-PT - "|Почтовый.?Индекс" // ru - "|पिन.?कोड" // hi - "|邮政编码|邮编" // zh-CN - "|郵遞區號" // zh-TW - "|우편.?번호"; // ko-KR + "|pin.?code" // en-IN + "|postleitzahl" // de-DE + "|\\bcp\\b" // es + "|\\bcdp\\b" // fr-FR + "|\\bcap\\b" // it-IT + "|郵便番号" // ja-JP + "|codigo|codpos|\\bcep\\b" // pt-BR, pt-PT + "|Почтовый.?Индекс" // ru + "|पिन.?कोड" // hi + "|പിന്കോഡ്" // ml + "|邮政编码|邮编" // zh-CN + "|郵遞區號" // zh-TW + "|우편.?번호"; // ko-KR const char kZip4Re[] = "zip|^-$|post2" "|codpos2"; // pt-BR, pt-PT @@ -118,6 +119,7 @@ "|شهر" // fa "|शहर" // hi for city "|ग्राम|गाँव" // hi for village + "|നഗരം|ഗ്രാമം" // ml for town|village "|^시[^도·・]|시[·・]?군[·・]?구"; // ko-KR const char kStateRe[] = "(?<!(united|hist|history).?)state|county|region|province" @@ -127,6 +129,7 @@ "|область" // ru "|省" // zh-CN "|地區" // zh-TW + "|സംസ്ഥാനം" // ml "|استان" // fa "|राज्य" // hi "|^시[·・]?도"; // ko-KR @@ -255,12 +258,14 @@ ///////////////////////////////////////////////////////////////////////////// const char kEmailRe[] = "e.?mail" - "|courriel" // fr - "|correo.*electr(o|ó)nico" // es-ES - "|メールアドレス" // ja-JP - "|Электронной.?Почты" // ru - "|邮件|邮箱" // zh-CN - "|電郵地址" // zh-TW + "|courriel" // fr + "|correo.*electr(o|ó)nico" // es-ES + "|メールアドレス" // ja-JP + "|Электронной.?Почты" // ru + "|邮件|邮箱" // zh-CN + "|電郵地址" // zh-TW + "|ഇ-മെയില്|ഇലക്ട്രോണിക്.?" + "മെയിൽ" // ml "|ایمیل|پست.*الکترونیک" // fa "|ईमेल|इलॅक्ट्रॉनिक.?मेल" // hi "|(?:이메일|전자.?우편|[Ee]-?mail)(.?주소)?"; // ko-KR @@ -297,7 +302,8 @@ "|Имя" // ru "|نام" // fa "|이름" // ko-KR - "|^नाम"; // hi + "|പേര്" // ml + "|नाम"; // hi const char kMiddleInitialRe[] = "middle.*initial|m\\.i\\.|mi$|\\bmi\\b"; const char kMiddleNameRe[] = "middle.*name|mname|middle$" @@ -317,6 +323,7 @@ "|Фамилия" // ru "|نام.*خانوادگی" // fa "|उपनाम" // hi + "|മറുപേര്" // ml "|\\b성(?:[^명]|\\b)"; // ko-KR ///////////////////////////////////////////////////////////////////////////// @@ -332,6 +339,7 @@ "|телефон" // ru "|मोबाइल" // hi for mobile "|电话" // zh-CN + "|മൊബൈല്" // ml for mobile "|(?:전화|핸드폰|휴대폰|휴대전화)(?:.?번호)?"; // ko-KR const char kCountryCodeRe[] = "country.*code|ccode|_cc|phone.*code|user.*phone.*code";
diff --git a/components/autofill_assistant/browser/service.cc b/components/autofill_assistant/browser/service.cc index 353c614..cbe0051 100644 --- a/components/autofill_assistant/browser/service.cc +++ b/components/autofill_assistant/browser/service.cc
@@ -169,8 +169,7 @@ auto resource_request = std::make_unique<::network::ResourceRequest>(); resource_request->method = "POST"; - resource_request->fetch_redirect_mode = - ::network::mojom::FetchRedirectMode::kError; + resource_request->redirect_mode = ::network::mojom::RedirectMode::kError; resource_request->allow_credentials = false; if (access_token_.empty()) { std::string query_str = base::StrCat({"key=", api_key_});
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc index dbc65d4..5dec17bb 100644 --- a/components/browser_sync/profile_sync_components_factory_impl.cc +++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -320,8 +320,18 @@ #if defined(OS_CHROMEOS) if (!disabled_types.Has(syncer::PRINTERS)) { - controllers.push_back( - CreateModelTypeControllerForModelRunningOnUIThread(syncer::PRINTERS)); + // TODO(crbug.com/867801) This still uses a proxy delegate even though the + // model lives on the UI thread. Switching to forwarding delegate causes + // cryptic test failures on chromeos. Fix that and switch to the forwarding + // delegate. + controllers.push_back(std::make_unique<ModelTypeController>( + syncer::PRINTERS, + std::make_unique<syncer::ProxyModelTypeControllerDelegate>( + ui_thread_, + base::BindRepeating(&browser_sync::BrowserSyncClient:: + GetControllerDelegateForModelType, + base::Unretained(sync_client_), + syncer::PRINTERS)))); } #endif
diff --git a/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc b/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc index 6831878..86075bf 100644 --- a/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc +++ b/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc
@@ -686,10 +686,6 @@ for (size_t i = 0; i < num_concurrent_encoders; i++) { ASSERT_EQ(notes[i]->Wait(), ClientState::ENCODE_PASS); } -#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) - // TODO(wtlee): Enable DMA-buf test for V4L2 JEA once it supports DMA-buf - // encoding. -#else for (size_t i = 0; i < num_concurrent_encoders; i++) { encoder_thread.task_runner()->PostTask( FROM_HERE, base::BindOnce(&JpegClient::StartEncodeDmaBuf, @@ -698,9 +694,12 @@ for (size_t i = 0; i < num_concurrent_encoders; i++) { ASSERT_EQ(notes[i]->Wait(), ClientState::ENCODE_PASS); } -#endif } +#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) + // For unaligned images, V4L2 may not be able to encode them so skip for V4L2 + // cases. +#else for (size_t index = 0; index < test_images_.size(); index++) { int buffer_id = index + test_aligned_images_.size(); VLOG(3) << buffer_id @@ -715,20 +714,9 @@ } for (size_t i = 0; i < num_concurrent_encoders; i++) { -// For unaligned images, V4L2 may not be able to encode them. -#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) - ClientState status = notes[i]->Wait(); - ASSERT_TRUE(status == ClientState::ENCODE_PASS || - status == ClientState::ERROR); -#else ASSERT_EQ(notes[i]->Wait(), ClientState::ENCODE_PASS); -#endif } -#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) - // TODO(wtlee): Enable DMA-buf test for V4L2 JEA once it supports DMA-buf - // encoding. -#else for (size_t i = 0; i < num_concurrent_encoders; i++) { encoder_thread.task_runner()->PostTask( FROM_HERE, @@ -739,8 +727,8 @@ for (size_t i = 0; i < num_concurrent_encoders; i++) { ASSERT_EQ(notes[i]->Wait(), ClientState::ENCODE_PASS); } -#endif } +#endif for (size_t i = 0; i < num_concurrent_encoders; i++) { encoder_thread.task_runner()->PostTask(
diff --git a/components/content_settings/OWNERS b/components/content_settings/OWNERS index 728b3dc0..b27914a 100644 --- a/components/content_settings/OWNERS +++ b/components/content_settings/OWNERS
@@ -1,6 +1,5 @@ engedy@chromium.org jochen@chromium.org msramek@chromium.org -raymes@chromium.org # COMPONENT: Internals>Permissions>Model
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc index d15daf8b..65eefa6 100644 --- a/components/content_settings/core/browser/host_content_settings_map.cc +++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -37,6 +37,7 @@ #include "components/content_settings/core/browser/user_modifiable_provider.h" #include "components/content_settings/core/browser/website_settings_registry.h" #include "components/content_settings/core/common/content_settings_pattern.h" +#include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/content_settings_utils.h" #include "components/content_settings/core/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -638,6 +639,7 @@ ContentSettingsForOneType settings; GetSettingsForOneType(content_type, std::string(), &settings); size_t num_exceptions = 0; + size_t num_third_party_cookie_allow_exceptions = 0; base::flat_map<ContentSetting, size_t> num_exceptions_with_setting; const content_settings::ContentSettingsInfo* content_info = content_setting_registry->Get(content_type); @@ -677,6 +679,12 @@ if (content_info) ++num_exceptions_with_setting[setting_entry.GetContentSetting()]; ++num_exceptions; + if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && + setting_entry.primary_pattern.MatchesAllHosts() && + !setting_entry.secondary_pattern.MatchesAllHosts() && + setting_entry.GetContentSetting() == CONTENT_SETTING_ALLOW) { + num_third_party_cookie_allow_exceptions++; + } } } @@ -699,6 +707,11 @@ 1, 1000, 30); } } + if (content_type == CONTENT_SETTINGS_TYPE_COOKIES) { + base::UmaHistogramCustomCounts( + "ContentSettings.Exceptions.cookies.AllowThirdParty", + num_third_party_cookie_allow_exceptions, 1, 1000, 30); + } } }
diff --git a/components/content_settings/core/common/content_settings.cc b/components/content_settings/core/common/content_settings.cc index 71bd6c60..f80d8a1 100644 --- a/components/content_settings/core/common/content_settings.cc +++ b/components/content_settings/core/common/content_settings.cc
@@ -75,6 +75,8 @@ {CONTENT_SETTINGS_TYPE_BLUETOOTH_SCANNING, 51}, {CONTENT_SETTINGS_TYPE_HID_GUARD, 52}, {CONTENT_SETTINGS_TYPE_HID_CHOOSER_DATA, 53}, + {CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN, 54}, + {CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM, 55}, }; } // namespace
diff --git a/components/content_settings/core/common/content_settings_types.h b/components/content_settings/core/common/content_settings_types.h index 3aa7f2a..89c24b9 100644 --- a/components/content_settings/core/common/content_settings_types.h +++ b/components/content_settings/core/common/content_settings_types.h
@@ -153,6 +153,12 @@ CONTENT_SETTINGS_TYPE_HID_GUARD, CONTENT_SETTINGS_TYPE_HID_CHOOSER_DATA, + // Wake Lock API, which has two lock types: screen and system locks. + // Currently, screen locks do not need any additional permission, and system + // locks are always denied while the right UI is worked out. + CONTENT_SETTINGS_TYPE_WAKE_LOCK_SCREEN, + CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM, + CONTENT_SETTINGS_NUM_TYPES, };
diff --git a/components/cronet/android/cronet_library_loader.cc b/components/cronet/android/cronet_library_loader.cc index 121f662f..d4516d7 100644 --- a/components/cronet/android/cronet_library_loader.cc +++ b/components/cronet/android/cronet_library_loader.cc
@@ -55,7 +55,7 @@ base::SingleThreadTaskExecutor* g_init_task_executor = nullptr; #if !BUILDFLAG(INTEGRATED_MODE) -net::NetworkChangeNotifier* g_network_change_notifier = nullptr; +std::unique_ptr<net::NetworkChangeNotifier> g_network_change_notifier; #endif base::WaitableEvent g_init_thread_init_done(
diff --git a/components/download/internal/common/download_utils.cc b/components/download/internal/common/download_utils.cc index 29a52c5..bba99e06 100644 --- a/components/download/internal/common/download_utils.cc +++ b/components/download/internal/common/download_utils.cc
@@ -268,7 +268,7 @@ // See also: // - https://crbug.com/952834 // - https://github.com/whatwg/fetch/issues/896#issuecomment-484423278 - request->fetch_request_mode = network::mojom::FetchRequestMode::kNavigate; + request->mode = network::mojom::RequestMode::kNavigate; bool has_upload_data = false; if (params->post_body()) {
diff --git a/components/exo/pointer_unittest.cc b/components/exo/pointer_unittest.cc index 46aab77..2807ed1 100644 --- a/components/exo/pointer_unittest.cc +++ b/components/exo/pointer_unittest.cc
@@ -633,18 +633,64 @@ pointer.reset(); } -TEST_F(MAYBE_PointerTest, IgnorePointerEventDuringModal) { +TEST_F(MAYBE_PointerTest, RegisterPointerEventsOnModal) { + // Create modal surface. + std::unique_ptr<Surface> surface(new Surface); + std::unique_ptr<ShellSurface> shell_surface( + new ShellSurface(surface.get(), gfx::Point(), true, false, + ash::kShellWindowId_SystemModalContainer)); + shell_surface->DisableMovement(); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5)))); + surface->Attach(buffer.get()); + surface->Commit(); + ash::wm::CenterWindow(shell_surface->GetWidget()->GetNativeWindow()); + // Make the window modal. + shell_surface->SetSystemModal(true); + EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen()); + + MockPointerDelegate delegate; + std::unique_ptr<Pointer> pointer(new Pointer(&delegate)); + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + + EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber()); + EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get())) + .WillRepeatedly(testing::Return(true)); + + // Pointer events on modal window should be registered. + gfx::Point origin = surface->window()->GetBoundsInScreen().origin(); + { + testing::InSequence sequence; + EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0)); + generator.MoveMouseTo(origin); + + EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1))); + generator.MoveMouseTo(origin + gfx::Vector2d(1, 1)); + + EXPECT_CALL(delegate, + OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true)); + EXPECT_CALL(delegate, + OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false)); + generator.ClickLeftButton(); + + EXPECT_CALL(delegate, + OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false)); + EXPECT_CALL(delegate, OnPointerScrollStop(testing::_)); + generator.ScrollSequence(origin, base::TimeDelta(), 1, 1, 1, 1); + } + + EXPECT_CALL(delegate, OnPointerDestroying(pointer.get())); + pointer.reset(); +} + +TEST_F(MAYBE_PointerTest, IgnorePointerEventsOnNonModalWhenModalIsOpen) { + // Create surface for non-modal window. std::unique_ptr<Surface> surface(new Surface); std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); std::unique_ptr<Buffer> buffer( new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)))); surface->Attach(buffer.get()); surface->Commit(); - gfx::Point location = surface->window()->GetBoundsInScreen().origin(); - - MockPointerDelegate delegate; - std::unique_ptr<Pointer> pointer(new Pointer(&delegate)); - ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); // Create surface for modal window. std::unique_ptr<Surface> surface2(new Surface); @@ -657,134 +703,158 @@ surface2->Attach(buffer2.get()); surface2->Commit(); ash::wm::CenterWindow(shell_surface2->GetWidget()->GetNativeWindow()); - gfx::Point location2 = surface2->window()->GetBoundsInScreen().origin(); - // Make the window modal. shell_surface2->SetSystemModal(true); EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen()); + MockPointerDelegate delegate; + std::unique_ptr<Pointer> pointer(new Pointer(&delegate)); + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber()); EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get())) .WillRepeatedly(testing::Return(true)); EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface2.get())) .WillRepeatedly(testing::Return(true)); - // Check if pointer events on modal window are registered. - { - testing::InSequence sequence; - EXPECT_CALL(delegate, OnPointerEnter(surface2.get(), gfx::PointF(), 0)); - } - generator.MoveMouseTo(location2); - - { - testing::InSequence sequence; - EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1))); - } - generator.MoveMouseTo(location2 + gfx::Vector2d(1, 1)); - - { - testing::InSequence sequence; - EXPECT_CALL(delegate, - OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true)); - EXPECT_CALL(delegate, - OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false)); - } - generator.ClickLeftButton(); - - { - testing::InSequence sequence; - EXPECT_CALL(delegate, - OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false)); - EXPECT_CALL(delegate, OnPointerScrollStop(testing::_)); - } - generator.ScrollSequence(location2, base::TimeDelta(), 1, 1, 1, 1); - - { - testing::InSequence sequence; - EXPECT_CALL(delegate, OnPointerLeave(surface2.get())); - } - generator.MoveMouseTo(surface2->window()->GetBoundsInScreen().bottom_right()); - // Check if pointer events on non-modal window are ignored. + gfx::Point nonModalOrigin = surface->window()->GetBoundsInScreen().origin(); { testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0)) .Times(0); - } - generator.MoveMouseTo(location); + generator.MoveMouseTo(nonModalOrigin); - { - testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1))) .Times(0); - } - generator.MoveMouseTo(location + gfx::Vector2d(1, 1)); + generator.MoveMouseTo(nonModalOrigin + gfx::Vector2d(1, 1)); - { - testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true)) .Times(0); EXPECT_CALL(delegate, OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false)) .Times(0); - } - generator.ClickLeftButton(); + generator.ClickLeftButton(); - { - testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false)) .Times(0); EXPECT_CALL(delegate, OnPointerScrollStop(testing::_)).Times(0); - } - generator.ScrollSequence(location, base::TimeDelta(), 1, 1, 1, 1); + generator.ScrollSequence(nonModalOrigin, base::TimeDelta(), 1, 1, 1, 1); - { - testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerLeave(surface.get())).Times(0); + generator.MoveMouseTo( + surface->window()->GetBoundsInScreen().bottom_right()); } - generator.MoveMouseTo(surface->window()->GetBoundsInScreen().bottom_right()); - // Make the window non-modal. - shell_surface2->SetSystemModal(false); - EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen()); + EXPECT_CALL(delegate, OnPointerDestroying(pointer.get())); + pointer.reset(); +} - // Check if pointer events on non-modal window are registered. +TEST_F(MAYBE_PointerTest, IgnorePointerLeaveOnModal) { + // Create modal surface. + std::unique_ptr<Surface> surface(new Surface); + std::unique_ptr<ShellSurface> shell_surface( + new ShellSurface(surface.get(), gfx::Point(), true, false, + ash::kShellWindowId_SystemModalContainer)); + shell_surface->DisableMovement(); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5)))); + surface->Attach(buffer.get()); + surface->Commit(); + ash::wm::CenterWindow(shell_surface->GetWidget()->GetNativeWindow()); + // Make the window modal. + shell_surface->SetSystemModal(true); + EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen()); + + MockPointerDelegate delegate; + std::unique_ptr<Pointer> pointer(new Pointer(&delegate)); + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + + EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber()); + EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get())) + .WillRepeatedly(testing::Return(true)); + + gfx::Point origin = surface->window()->GetBoundsInScreen().origin(); + { testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0)); - } - generator.MoveMouseTo(location); + generator.MoveMouseTo(origin); + // OnPointerLeave should not be called on the modal surface when the pointer + // moves out of its bounds. + EXPECT_CALL(delegate, OnPointerLeave(surface.get())).Times(0); + generator.MoveMouseTo( + surface->window()->GetBoundsInScreen().bottom_right()); + } + + EXPECT_CALL(delegate, OnPointerDestroying(pointer.get())); + pointer.reset(); +} + +TEST_F(MAYBE_PointerTest, RegisterPointerEventsOnNonModal) { + // Create surface for non-modal window. + std::unique_ptr<Surface> surface(new Surface); + std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)))); + surface->Attach(buffer.get()); + surface->Commit(); + + // Create another surface for a non-modal window. + std::unique_ptr<Surface> surface2(new Surface); + std::unique_ptr<ShellSurface> shell_surface2( + new ShellSurface(surface2.get(), gfx::Point(), true, false, + ash::kShellWindowId_SystemModalContainer)); + shell_surface2->DisableMovement(); + std::unique_ptr<Buffer> buffer2( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5)))); + surface2->Attach(buffer2.get()); + surface2->Commit(); + ash::wm::CenterWindow(shell_surface2->GetWidget()->GetNativeWindow()); + + MockPointerDelegate delegate; + std::unique_ptr<Pointer> pointer(new Pointer(&delegate)); + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + + EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber()); + EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get())) + .WillRepeatedly(testing::Return(true)); + EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface2.get())) + .WillRepeatedly(testing::Return(true)); + + // Ensure second window is non-modal. + shell_surface2->SetSystemModal(false); + EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen()); + + // Check if pointer events on first non-modal window are registered. + gfx::Point firstWindowOrigin = + surface->window()->GetBoundsInScreen().origin(); { testing::InSequence sequence; + EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0)); + generator.MoveMouseTo(firstWindowOrigin); + EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1))); - } - generator.MoveMouseTo(location + gfx::Vector2d(1, 1)); + generator.MoveMouseTo(firstWindowOrigin + gfx::Vector2d(1, 1)); - { - testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true)); EXPECT_CALL(delegate, OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false)); - } - generator.ClickLeftButton(); + generator.ClickLeftButton(); - { - testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false)); EXPECT_CALL(delegate, OnPointerScrollStop(testing::_)); - } - generator.ScrollSequence(location, base::TimeDelta(), 1, 1, 1, 1); + generator.ScrollSequence(firstWindowOrigin, base::TimeDelta(), 1, 1, 1, 1); - { - testing::InSequence sequence; EXPECT_CALL(delegate, OnPointerLeave(surface.get())); + generator.MoveMouseTo( + surface->window()->GetBoundsInScreen().bottom_right()); } - generator.MoveMouseTo(surface->window()->GetBoundsInScreen().bottom_right()); EXPECT_CALL(delegate, OnPointerDestroying(pointer.get())); pointer.reset();
diff --git a/components/exo/wayland/fuzzer/BUILD.gn b/components/exo/wayland/fuzzer/BUILD.gn index 8c5b3f70..0f0a6433 100644 --- a/components/exo/wayland/fuzzer/BUILD.gn +++ b/components/exo/wayland/fuzzer/BUILD.gn
@@ -2,10 +2,53 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//components/exo/wayland/fuzzer/wayland_templater.gni") import("//testing/libfuzzer/fuzzer_test.gni") import("//third_party/libprotobuf-mutator/fuzzable_proto_library.gni") import("//third_party/protobuf/proto_library.gni") +# This is the canonical list of protocols which the generators should use +# (though they don't have to) +kDefaultWaylandProtocols = [ + "//third_party/wayland/src/protocol/wayland.xml", + "//third_party/wayland-protocols/src/unstable/xdg-shell/xdg-shell-unstable-v6.xml", +] + +wayland_templater("protocol_dump") { + sources = [ + "misc/dump.tmpl", + ] + protocols = kDefaultWaylandProtocols +} + +wayland_templater("protocol_graph") { + sources = [ + "misc/graph.dot.tmpl", + ] + protocols = kDefaultWaylandProtocols +} + +wayland_templater("actions_tmpl") { + sources = [ + "actions.proto.tmpl", + ] + protocols = kDefaultWaylandProtocols +} + +wayland_templater("harness_h_tmpl") { + sources = [ + "harness.h.tmpl", + ] + protocols = kDefaultWaylandProtocols +} + +wayland_templater("harness_cc_tmpl") { + sources = [ + "harness.cc.tmpl", + ] + protocols = kDefaultWaylandProtocols +} + if (use_libfuzzer) { fuzzer_test("wayland_fuzzer") { sources = [ @@ -64,20 +107,27 @@ } source_set("harness") { - sources = [ - "harness.cc", - "harness.h", - ] + sources = get_target_outputs(":harness_h_tmpl") + + get_target_outputs(":harness_cc_tmpl") deps = [ ":actions", + ":harness_cc_tmpl", + ":harness_h_tmpl", "//base", "//third_party/wayland:wayland_client", + "//third_party/wayland-protocols:xdg_shell_protocol", ] } fuzzable_proto_library("actions") { - sources = [ - "actions.proto", + sources = get_target_outputs(":actions_tmpl") + + # Since the .proto file is under gen/ we need to manually tell the + # output directory to rebase under the source root. + proto_out_dir = rebase_path(".", "//") + + deps = [ + ":actions_tmpl", ] }
diff --git a/components/exo/wayland/fuzzer/OWNERS b/components/exo/wayland/fuzzer/OWNERS index d1a2824d..dad46bb 100644 --- a/components/exo/wayland/fuzzer/OWNERS +++ b/components/exo/wayland/fuzzer/OWNERS
@@ -1 +1 @@ -hollingum@chromium.org +hollingum@google.com
diff --git a/components/exo/wayland/fuzzer/actions.proto b/components/exo/wayland/fuzzer/actions.proto deleted file mode 100644 index 98f91c2..0000000 --- a/components/exo/wayland/fuzzer/actions.proto +++ /dev/null
@@ -1,46 +0,0 @@ -// 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. - -syntax = "proto3"; -option optimize_for = LITE_RUNTIME; -package exo.wayland_fuzzer; - -// Enumerates all the expected globals which the fuzzer might target. It is -// reasonable for the fuzzer to target the "unspecified" global, in which case -// we will attempt to bind an index that does not exist. -enum global { - GLOBAL_UNSPECIFIED = 0; - wayland_wl_compositor = 1; - wayland_wl_shm = 2; -} - -message action { - oneof act { - wayland_wl_display_get_registry act_wayland_wl_display_get_registry = 3; - wayland_wl_display_sync act_wayland_wl_display_sync = 4; - wayland_wl_registry_bind act_wayland_wl_registry_bind = 5; - } -} - -message actions { - repeated action acts = 1; -} - -message wayland_wl_display_get_registry { - uint32 receiver = 1; -} - -message wayland_wl_display_sync { - uint32 receiver = 1; -} - -// Bind is a special case where we want the fuzzer to grab global interfaces we -// know about (so we use an enum) but the other fields are free game. -// -// Next available id: 4 -message wayland_wl_registry_bind { - uint32 receiver = 1; - - global global = 2; -}
diff --git a/components/exo/wayland/fuzzer/actions.proto.tmpl b/components/exo/wayland/fuzzer/actions.proto.tmpl new file mode 100644 index 0000000..886ec84 --- /dev/null +++ b/components/exo/wayland/fuzzer/actions.proto.tmpl
@@ -0,0 +1,59 @@ +// 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. + +syntax = "proto3"; +option optimize_for = LITE_RUNTIME; +package exo.wayland_fuzzer.actions; + +enum small_value { + ZERO = 0; + ONE = 1; + TWO = 2; + THREE = 3; +} + +// Enumerates all the expected globals which the fuzzer might target. It is +// reasonable for the fuzzer to target the "unspecified" global, in which case +// we will attempt to bind an index that does not exist. +enum global { + GLOBAL_UNSPECIFIED = 0; + {% for interface in interfaces if interface.is_global %} + {{interface.name}} = {{interface.idx + 1}}; + {% endfor %} +} + +message action { + oneof act { + {% for interface in interfaces %} + {% for request in interface.requests %} + {{interface.name}}_{{request.name}} act_{{interface.name}}_{{request.name}} = {{request.idx + 1}}; + {% endfor %} + {% endfor %} + } +} + +message actions { + repeated action acts = 1; +} + +{% for interface in interfaces %} + {% for request in interface.requests %} + {% if request.name != "bind" or interface.name != "wl_registry" %} + message {{interface.name}}_{{request.name}} { + small_value receiver = 1; + {% for arg in request.args if arg.proto_type %} + {{arg.proto_type}} {{arg.name}} = {{loop.index + 1}}; + {% endfor %} + } + {% endif %} + {% endfor %} +{% endfor %} + +// Bind is a special case where we want the fuzzer to grab global interfaces we +// know about (so we use an enum) but the other fields are free game. +message wl_registry_bind { + small_value receiver = 1; + + global global = 2; +}
diff --git a/components/exo/wayland/fuzzer/fuzzer.cc b/components/exo/wayland/fuzzer/fuzzer.cc index 629b5f0..bec68bf 100644 --- a/components/exo/wayland/fuzzer/fuzzer.cc +++ b/components/exo/wayland/fuzzer/fuzzer.cc
@@ -18,7 +18,7 @@ exo::wayland_fuzzer::ServerEnvironment server_environment_; }; -DEFINE_TEXT_PROTO_FUZZER(const exo::wayland_fuzzer::actions& acts) { +DEFINE_TEXT_PROTO_FUZZER(const exo::wayland_fuzzer::actions::actions& acts) { static base::AtExitManager exit_manager; static FuzzerEnvironment environment;
diff --git a/components/exo/wayland/fuzzer/harness.cc b/components/exo/wayland/fuzzer/harness.cc deleted file mode 100644 index 79090fc..0000000 --- a/components/exo/wayland/fuzzer/harness.cc +++ /dev/null
@@ -1,169 +0,0 @@ -// 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. - -#include "components/exo/wayland/fuzzer/harness.h" - -#include <wayland-client-core.h> -#include <wayland-client-protocol.h> -#include <wayland-util.h> - -#include <cstring> -#include <functional> - -#include "base/logging.h" -#include "components/exo/wayland/fuzzer/actions.pb.h" - -namespace exo { -namespace wayland_fuzzer { - -namespace wayland { -namespace wl_display { -void sync(Harness* harness, - const wayland_fuzzer::wayland_wl_display_sync& action); -void get_registry(Harness* harness, - const wayland_wl_display_get_registry& action); -} // namespace wl_display -namespace wl_registry { -void bind(Harness* harness, const wayland_wl_registry_bind& action); -void global(void* data, - struct wl_registry* registry, - uint32_t name, - const char* interface, - uint32_t version); -void global_remove(void* data, struct wl_registry* registry, uint32_t name); -static const struct wl_registry_listener kListener = {global, global_remove}; -} // namespace wl_registry -namespace wl_callback { -void done(void* data, struct wl_callback* receiver, uint32_t callback_data); -static const struct wl_callback_listener kListener = {done}; -} // namespace wl_callback - -namespace wl_compositor {} - -namespace wl_shm { -void format(void* data, struct wl_shm* receiver, uint32_t format); -static const struct wl_shm_listener kListener = {format}; -} // namespace wl_shm -} // namespace wayland - -void wayland::wl_display::sync( - Harness* harness, - const wayland_fuzzer::wayland_wl_display_sync& action) { - struct wl_display* receiver = harness->get_wl_display(action.receiver()); - if (!receiver) - return; - struct wl_callback* callback = wl_display_sync(receiver); - wl_callback_add_listener(callback, &wayland::wl_callback::kListener, harness); - harness->add_wl_callback(callback); -} - -void wayland::wl_display::get_registry( - Harness* harness, - const wayland_fuzzer::wayland_wl_display_get_registry& action) { - struct wl_display* receiver = harness->get_wl_display(action.receiver()); - if (!receiver) - return; - struct wl_registry* new_object = wl_display_get_registry(receiver); - wl_registry_add_listener(new_object, &wayland::wl_registry::kListener, - harness); - harness->add_wl_registry(new_object); -} - -void wayland::wl_registry::bind(Harness* harness, - const wayland_wl_registry_bind& action) { - struct wl_registry* receiver = harness->get_wl_registry(action.receiver()); - if (!receiver) - return; - void* new_object = nullptr; - switch (action.global()) { - case global::wayland_wl_compositor: - if (harness->wl_compositor_globals_.empty()) - return; - new_object = wl_registry_bind( - receiver, harness->wl_compositor_globals_[0].first, - &wl_compositor_interface, harness->wl_compositor_globals_[0].second); - harness->add_wl_compositor( - static_cast<struct wl_compositor*>(new_object)); - break; - case global::wayland_wl_shm: - if (harness->wl_shm_globals_.empty()) - return; - new_object = wl_registry_bind(receiver, harness->wl_shm_globals_[0].first, - &wl_shm_interface, - harness->wl_shm_globals_[0].second); - - wl_shm_add_listener(static_cast<struct wl_shm*>(new_object), - &wayland::wl_shm::kListener, harness); - harness->add_wl_shm(static_cast<struct wl_shm*>(new_object)); - break; - default: - return; - } -} - -void wayland::wl_registry::global(void* data, - struct wl_registry* registry, - uint32_t name, - const char* interface, - uint32_t version) { -#define GLOBL(WLT) \ - if (strcmp(interface, #WLT) == 0) { \ - harness->WLT##_globals_.emplace_back(name, version); \ - } - - Harness* harness = static_cast<Harness*>(data); - GLOBL(wl_display); - GLOBL(wl_registry); - GLOBL(wl_callback); - GLOBL(wl_compositor); - GLOBL(wl_shm); -#undef GLOBL -} - -void wayland::wl_registry::global_remove(void* data, - struct wl_registry* registry, - uint32_t name) {} - -void wayland::wl_callback::done(void* data, - struct wl_callback* receiver, - uint32_t callback_data) {} - -void wayland::wl_shm::format(void* data, - struct wl_shm* receiver, - uint32_t format) {} - -Harness::Harness() { - wl_display_list_.emplace_back(wl_display_connect(nullptr)); - DCHECK(wl_display_list_.front()); -} - -Harness::~Harness() { - wl_display_disconnect(wl_display_list_.front()); -} - -void Harness::Run(const wayland_fuzzer::actions& actions) { - for (const wayland_fuzzer::action& act : actions.acts()) - Run(act); -} - -void Harness::Run(const wayland_fuzzer::action& action) { - switch (action.act_case()) { - case action::ActCase::ACT_NOT_SET: - wl_display_roundtrip(wl_display_list_.front()); - break; - case action::ActCase::kActWaylandWlDisplayGetRegistry: - wayland::wl_display::get_registry( - this, action.act_wayland_wl_display_get_registry()); - break; - case action::ActCase::kActWaylandWlDisplaySync: - wayland::wl_display::sync(this, action.act_wayland_wl_display_sync()); - break; - case action::ActCase::kActWaylandWlRegistryBind: - wayland::wl_registry::bind(this, action.act_wayland_wl_registry_bind()); - break; - } -} - -} // namespace wayland_fuzzer -} // namespace exo
diff --git a/components/exo/wayland/fuzzer/harness.cc.tmpl b/components/exo/wayland/fuzzer/harness.cc.tmpl new file mode 100644 index 0000000..e1151aec --- /dev/null +++ b/components/exo/wayland/fuzzer/harness.cc.tmpl
@@ -0,0 +1,174 @@ +// 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. + +#include "components/exo/wayland/fuzzer/harness.h" + +#include <wayland-util.h> +{% for protocol in protocol_names %} + {% if protocol == 'wayland' %} + #include <wayland-client-core.h> + #include <wayland-client-protocol.h> + {% else %} + #include <{{protocol | replace('_','-')}}-client-protocol.h> + {% endif %} +{% endfor %} + +#include <cstring> +#include <functional> + +#include "base/logging.h" +#include "components/exo/wayland/fuzzer/actions.pb.h" + +namespace exo { +namespace wayland_fuzzer { + +{% for interface in interfaces if interface.has_listener and interface.name != 'wl_display' %} + namespace {{interface.name}} { + {% for event in interface.events %} + void {{event.name}}( + void* data, + ::{{interface.name}}* receiver + {% for arg in event.args %} + , {{arg.cpp_type}} {{arg.name}} + {% endfor %} + ); + {% endfor %} + static const ::{{interface.name}}_listener kListener = { + {% for event in interface.events %} + {{event.name}}, + {% endfor %} + }; + } // namespace {{interface.name}} +{% endfor %} + + +{% for interface in interfaces if interface.name != 'wl_registry' %} + namespace {{interface.name}} { + {% for event in interface.events %} + void {{event.name}}( + void* data, + ::{{interface.name}}* receiver + {% for arg in event.args %} + , {{arg.cpp_type}} {{arg.name}} + {% endfor %} + ){ + {% if event.is_constructor %} + Harness* harness = static_cast<Harness*>(data); + {% for arg in event.args if arg.type == 'new_id' %} + {{arg.cpp_type}} new_object = {{arg.name}}; + {% endfor %} + {% if event.constructed_has_listener %} + {{event.constructed}}_add_listener(new_object, &{{event.constructed}}::kListener, harness); + {% endif %} + harness->add_{{event.constructed}}(new_object); + {% endif %} + } + {% endfor %} + {% for request in interface.requests %} + void {{request.name}}(Harness* harness, + const actions::{{interface.name}}_{{request.name}}& action) { + ::{{interface.name}}* receiver = harness->get_{{interface.name}}(action.receiver()); + if (!receiver) + return; + {% if request.is_constructor %} + ::{{request.constructed}}* new_object = + {% endif %} + {{interface.name}}_{{request.name}}(receiver + {% for arg in request.args %} + {% if arg.type == 'object' %} + , harness->get_{{arg.interface}}(action.{{arg.name}}()) + {% elif arg.type != 'new_id' %} + , action.{{arg.name}}(){% if arg.type == 'string' %}.c_str(){% endif %} + {% endif %} + {% endfor %} + ); + {% if request.is_constructor %} + {% if request.constructed_has_listener %} + {{request.constructed}}_add_listener(new_object, &{{request.constructed}}::kListener, harness); + {% endif %} + harness->add_{{request.constructed}}(new_object); + {% endif %} + } + {% endfor %} + } // namespace {{interface.name}} +{% endfor %} + +namespace wl_registry { + +void bind(Harness* harness, const actions::wl_registry_bind& action) { + ::wl_registry* receiver = harness->get_wl_registry(action.receiver()); + if (!receiver) + return; + switch (action.global()) { + {% for interface in interfaces if interface.is_global %} + case actions::global::{{interface.name}}: { + if (harness->{{interface.name}}_globals_.empty()) + return; + void* new_object = wl_registry_bind( + receiver, harness->{{interface.name}}_globals_[0].first, + &{{interface.name}}_interface, harness->{{interface.name}}_globals_[0].second); + {% if interface.has_listener and interface.name != 'wl_display' %} + {{interface.name}}_add_listener(static_cast<::{{interface.name}}*>(new_object), &{{interface.name}}::kListener, harness); + {% endif %} + harness->add_{{interface.name}}( + static_cast<::{{interface.name}}*>(new_object)); + break; + } + {% endfor %} + case actions::global::global_INT_MIN_SENTINEL_DO_NOT_USE_: + case actions::global::global_INT_MAX_SENTINEL_DO_NOT_USE_: + case actions::global::GLOBAL_UNSPECIFIED: + break; + } +} + +void global(void* data, + ::wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) { + Harness* harness = static_cast<Harness*>(data); + {% for interface in interfaces if interface.is_global %} + if (strcmp(interface, "{{interface.name}}") == 0) { + harness->{{interface.name}}_globals_.emplace_back(name, version); + return; + } + {% endfor %} +} + +} // namespace wl_registry + +void wl_registry::global_remove(void* data, ::wl_registry* registry, uint32_t name) {} + +Harness::Harness() { + wl_display_list_.emplace_back(wl_display_connect(nullptr)); + DCHECK(wl_display_list_.front()); +} + +Harness::~Harness() { + wl_display_disconnect(wl_display_list_.front()); +} + +void Harness::Run(const actions::actions& all_steps) { + for (const actions::action& current : all_steps.acts()) + Run(current); +} + +void Harness::Run(const actions::action& current_step) { + switch (current_step.act_case()) { + case actions::action::ActCase::ACT_NOT_SET: + wl_display_roundtrip(wl_display_list_.front()); + break; + {% for interface in interfaces %} + {% for request in interface.requests %} + case actions::action::ActCase::kAct{{(interface.name + "_" + request.name) | replace('_', ' ') | title | replace(' ', '')}}: + {{interface.name}}::{{request.name}}(this, current_step.act_{{interface.name}}_{{request.name}}()); + break; + {% endfor %} + {% endfor %} + } +} + +} // namespace wayland_fuzzer +} // namespace exo
diff --git a/components/exo/wayland/fuzzer/harness.h b/components/exo/wayland/fuzzer/harness.h deleted file mode 100644 index 241233f..0000000 --- a/components/exo/wayland/fuzzer/harness.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_EXO_WAYLAND_FUZZER_HARNESS_H_ -#define COMPONENTS_EXO_WAYLAND_FUZZER_HARNESS_H_ - -#include <memory> - -#include "base/macros.h" -#include "components/exo/wayland/fuzzer/actions.pb.h" - -struct wl_display; -struct wl_registry; -struct wl_callback; -struct wl_compositor; -struct wl_shm; - -namespace exo { -namespace wayland_fuzzer { - -// When using LPM to fuzz wayland, the wauland_fuzzer::actions proto defines the -// sequence of events that the fuzzer wants to perform. It then falls to this -// harness to actually convert that sequence into the relevant calls, as if it -// were a normal wayland client. -class Harness { - public: - Harness(); - - ~Harness(); - - void Run(const wayland_fuzzer::action& actions); - - void Run(const wayland_fuzzer::actions& actions); - - // TODO(hollingum): This is a macro for now but when we move to autogenerated - // code this will be generated directly. -#define GET_AND_SET(WLT) \ - std::vector<struct WLT*> WLT##_list_; \ - void add_##WLT(struct WLT* new_obj) { WLT##_list_.push_back(new_obj); } \ - struct WLT* get_##WLT(uint32_t idx) const { \ - return idx < WLT##_list_.size() ? WLT##_list_[idx] : nullptr; \ - } \ - std::vector<std::pair<uint32_t, uint32_t>> WLT##_globals_ - - GET_AND_SET(wl_display); - GET_AND_SET(wl_registry); - GET_AND_SET(wl_callback); - GET_AND_SET(wl_compositor); - GET_AND_SET(wl_shm); -#undef GET_AND_SET - - private: - DISALLOW_COPY_AND_ASSIGN(Harness); -}; - -} // namespace wayland_fuzzer -} // namespace exo - -#endif // COMPONENTS_EXO_WAYLAND_FUZZER_HARNESS_H_
diff --git a/components/exo/wayland/fuzzer/harness.h.tmpl b/components/exo/wayland/fuzzer/harness.h.tmpl new file mode 100644 index 0000000..41511349 --- /dev/null +++ b/components/exo/wayland/fuzzer/harness.h.tmpl
@@ -0,0 +1,59 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_WAYLAND_FUZZER_HARNESS_H_ +#define COMPONENTS_EXO_WAYLAND_FUZZER_HARNESS_H_ + +#include <memory> + +#include "base/macros.h" +#include "components/exo/wayland/fuzzer/actions.pb.h" + +// Forwards declarations for the wayland-defined structs. +{% for interface in interfaces %} + struct {{interface.name}}; +{% endfor %} + +namespace exo { +namespace wayland_fuzzer { + +// When using LPM to fuzz wayland, the wayland_fuzzer::actions proto defines the +// sequence of events that the fuzzer wants to perform. It then falls to this +// harness to actually convert that sequence into the relevant calls, as if it +// were a normal wayland client. +class Harness { + public: + Harness(); + + ~Harness(); + + void Run(const actions::action& current_step); + + void Run(const actions::actions& all_steps); + + {% for interface in interfaces %} + std::vector<::{{interface.name}}*> {{interface.name}}_list_; + + void add_{{interface.name}}(::{{interface.name}}* new_obj) { + {{interface.name}}_list_.push_back(new_obj); + } + + ::{{interface.name}}* get_{{interface.name}}(uint32_t idx) const { + return idx < {{interface.name}}_list_.size() + ? {{interface.name}}_list_[idx] + : nullptr; + } + {% if interface.is_global %} + std::vector<std::pair<uint32_t, uint32_t>> {{interface.name}}_globals_; + {% endif %} + {% endfor %} + + private: + DISALLOW_COPY_AND_ASSIGN(Harness); +}; + +} // namespace wayland_fuzzer +} // namespace exo + +#endif // COMPONENTS_EXO_WAYLAND_FUZZER_HARNESS_H_
diff --git a/components/exo/wayland/fuzzer/harness_unittest.cc b/components/exo/wayland/fuzzer/harness_unittest.cc index 24d3146..446eb5b 100644 --- a/components/exo/wayland/fuzzer/harness_unittest.cc +++ b/components/exo/wayland/fuzzer/harness_unittest.cc
@@ -46,9 +46,9 @@ }; void RunHarness(Harness* harness, base::WaitableEvent* event) { - wayland_fuzzer::actions acts; - acts.add_acts()->mutable_act_wayland_wl_display_get_registry()->set_receiver( - 0); + actions::actions acts; + acts.add_acts()->mutable_act_wl_display_get_registry()->set_receiver( + actions::small_value::ZERO); acts.add_acts(); harness->Run(acts); event->Signal();
diff --git a/components/exo/wayland/fuzzer/misc/README.md b/components/exo/wayland/fuzzer/misc/README.md new file mode 100644 index 0000000..3de6416e8 --- /dev/null +++ b/components/exo/wayland/fuzzer/misc/README.md
@@ -0,0 +1,5 @@ +fuzzer/misc +=========== + +This directory contains miscellaneous utilities to help with inspecting the +wayland specifications which are being fuzzed.
diff --git a/components/exo/wayland/fuzzer/misc/dump.tmpl b/components/exo/wayland/fuzzer/misc/dump.tmpl new file mode 100644 index 0000000..2ecfff2 --- /dev/null +++ b/components/exo/wayland/fuzzer/misc/dump.tmpl
@@ -0,0 +1,25 @@ +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. + +{% for protocol in protocol_names %} +PROTOCOL: {{protocol}} +{% endfor %} + +{% for interface in interfaces %} +INTERFACE: {{interface}} +{% endfor %} + +{% for interface in interfaces %} +{% for message in interface.requests + interface.events %} +MESSAGE: {{interface.name}} {{message}} +{% endfor %} +{% endfor %} + +{% for interface in interfaces %} +{% for message in interface.requests + interface.events %} +{% for arg in message.args %} +ARG: {{interface.name}} {{message.name}} {{arg}} +{% endfor %} +{% endfor %} +{% endfor %}
diff --git a/components/exo/wayland/fuzzer/misc/graph.dot.tmpl b/components/exo/wayland/fuzzer/misc/graph.dot.tmpl new file mode 100644 index 0000000..457e7e1 --- /dev/null +++ b/components/exo/wayland/fuzzer/misc/graph.dot.tmpl
@@ -0,0 +1,41 @@ +// 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. + +digraph g { +pack=false; +start="random"; +overlap=false; +splines=true; +graph [rankdir = "LR"]; + +"_unknown_" [label="?" shape=diamond] +{% for interface in interfaces %} + "{{interface.name}}" [shape=box] + {% for request in interface.requests %} + "{{interface.name}}_{{request.name}}" [label="{{request.name}}", shape=ellipse] + {% endfor %} + {% for event in interface.events %} + "{{interface.name}}_{{event.name}}" [label="{{event.name}}", shape=hexagon] + {% endfor %} +{% endfor %} + +{% for interface in interfaces %} + "{{interface.name}}" [shape=box] + {% for message in interface.requests + interface.events %} + "{{interface.name}}" -> "{{interface.name}}_{{message.name}}" [style=bold] + {% for arg in message.args %} + {% if arg.type == "object" %} + "{{arg.interface | default("_unknown_", true)}}" -> "{{interface.name}}_{{message.name}}" [ + style=dotted + ] + {% elif arg.type == "new_id" %} + "{{interface.name}}_{{message.name}}" -> "{{arg.interface | default("_unknown_", true)}}" [ + style=bold + ] + {% endif %} + {% endfor %} + {% endfor %} +{% endfor %} + +}
diff --git a/components/exo/wayland/fuzzer/wayland_templater.gni b/components/exo/wayland/fuzzer/wayland_templater.gni new file mode 100644 index 0000000..0c59cc0 --- /dev/null +++ b/components/exo/wayland/fuzzer/wayland_templater.gni
@@ -0,0 +1,62 @@ +# 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. + +# A wayland templater takes one or more |protocols| and processes its +# |sources| so as to instantiate a template for fuzzing wayland. +# The output of the wayland source will be the input's path, rebased +# under the gen/ directory and with the .tmpl suffix removed. +# +# This templater is used for all kinds of files (i.e. more than just +# c++), so we do not provide a convenient source_set target to depend +# on. Instead you must manually depend on the outputs like: +# +# wayland_templater("foo_tmpl") { +# ... +# } +# +# source_set("foo") { +# sources = get_target_outputs(":foo_tmpl") +# deps = [ +# ":foo_tmpl", +# ] +# } +template("wayland_templater") { + assert(defined(invoker.sources), "Need sources for wayland_templater") + assert(defined(invoker.protocols), "Need protocols for wayland_templater") + + # Process the inputs to determine the output: + # "//a/b/c.xyz.tmpl" -> "gen/a/b/c.xyz" + template_outputs = [] + foreach(src, invoker.sources) { + dir = get_path_info(src, "dir") + name = get_path_info(src, "name") + template_outputs += [ "${target_gen_dir}/${dir}/${name}" ] + } + + # Jinja2 doesnt like having ".." in the target path, so we give it the + # source-tree's path rather than the build-directory's relative path (which + # usually contains ".."). + build_to_src_path = rebase_path("//", root_build_dir) + src_path_to_inputs = rebase_path(invoker.sources, "//") + build_path_to_outputs = rebase_path(template_outputs, root_build_dir) + build_path_to_protocols = rebase_path(invoker.protocols, root_build_dir) + + action(target_name) { + script = "//third_party/blink/renderer/build/scripts/run_with_pythonpath.py" + sources = [ + script, + "wayland_templater.py", + ] + invoker.sources + invoker.protocols + outputs = template_outputs + args = [ + "-I", + rebase_path("//third_party", root_build_dir), + rebase_path("wayland_templater.py", root_build_dir), + "--directory", + build_to_src_path, + "--input", + ] + src_path_to_inputs + [ "--output" ] + build_path_to_outputs + + [ "--spec" ] + build_path_to_protocols + } +}
diff --git a/components/exo/wayland/fuzzer/wayland_templater.py b/components/exo/wayland/fuzzer/wayland_templater.py new file mode 100644 index 0000000..c87df3a --- /dev/null +++ b/components/exo/wayland/fuzzer/wayland_templater.py
@@ -0,0 +1,258 @@ +# Copyright (c) 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. +"""Templatize a file based on wayland specifications. + +The templating engine takes an input template and one or more wayland +specifications (see third_party/wayland/src/protocol/wayland.dtd), and +instantiates the template based on the wayland content. +""" + +from __future__ import absolute_import +from __future__ import print_function + +import argparse +import sys +from xml.etree import ElementTree + +import jinja2 + +proto_type_conversions = { + 'object': 'small_value', + 'int': 'int32', + 'uint': 'uint32', + 'string': 'string', + 'fd': 'uint32', +} + +cpp_type_conversions = { + 'int': 'int32_t', + 'uint': 'uint32_t', + 'fixed': 'wl_fixed_t', + 'string': 'const char*', + 'array': 'struct wl_array*', + 'fd': 'int32_t', +} + + +def AllInterfaces(protocols): + """Get the interfaces in these protocols. + + Args: + protocols: the list of protocols you want the interfaces of. + + Yields: + Tuples (p, i) of (p)rotocol (i)nterface. + """ + for p in protocols: + for i in p.findall('interface'): + yield (p, i) + + +def AllMessages(protocols): + """Get the messages in these protocols. + + Args: + protocols: the list of protocols you want the messages of. + + Yields: + Tuples (p, i, m) of (p)rotocol, (i)nterface, and (m)essage. + """ + for (p, i) in AllInterfaces(protocols): + for r in i.findall('request'): + yield (p, i, r) + for e in i.findall('event'): + yield (p, i, e) + + +def GetConstructorArg(message): + """Get the argument that this message constructs, or None. + + Args: + message: the message which you want to find the constructor arg of. + + Returns: + The argument (as an ElementTree node) that constructs a new interface, or + None. + """ + return message.find('arg[@type="new_id"]') + + +def IsConstructor(message): + """Check if a message is a constructor. + + Args: + message: the message which you want to check. + + Returns: + True if the message constructs an object (via new_id), False otherwise. + """ + return GetConstructorArg(message) is not None + + +def GetConstructedInterface(message): + """Gets the interface constructed by a message. + + Note that even if IsConstructor(message) returns true, get_constructed can + still return None when the message constructs an unknown interface (e.g. + wl_registry.bind()). + + Args: + message: the event/request which may be a constructor. + + Returns: + The name of the constructed interface (if there is one), or None. + """ + cons_arg = GetConstructorArg(message) + if cons_arg is None: + return None + return cons_arg.attrib.get('interface') + + +def NeedsListener(interface): + return interface.find('event') is not None + + +def GetCppType(arg): + ty = arg.attrib['type'] + if ty in ['object', 'new_id']: + return ('::' if 'interface' in arg.attrib else '') + arg.attrib.get( + 'interface', 'void') + '*' + return cpp_type_conversions[ty] + + +class TemplaterContext(object): + """The context object used for recording stateful/expensive things. + + An instance of this class is used when generating the template data, we use + it to cache pre-computed information, as well as to side-effect stateful + queries (such as counters) while generating the template data. + """ + + def __init__(self, protocols): + self.non_global_names = { + GetConstructedInterface(m) for _, _, m in AllMessages(protocols) + } - {None} + self.interfaces_with_listeners = { + i.attrib['name'] + for p, i in AllInterfaces(protocols) + if NeedsListener(i) + } + self.counts = {} + + def GetAndIncrementCount(self, counter): + """Return the number of times the given key has been counted. + + Args: + counter: the key used to identify this count value. + + Returns: + An int which is the number of times this method has been called before + with this counter's key. + """ + self.counts[counter] = self.counts.get(counter, 0) + 1 + return self.counts[counter] - 1 + + +def GetArg(arg): + ty = arg.attrib['type'] + return { + 'name': arg.attrib['name'], + 'type': ty, + 'proto_type': proto_type_conversions.get(ty), + 'cpp_type': GetCppType(arg), + 'interface': arg.attrib.get('interface'), + } + + +def GetMessage(message, context): + name = message.attrib['name'] + constructed = GetConstructedInterface(message) + return { + 'name': + name, + 'idx': + context.GetAndIncrementCount('message_index'), + 'args': [GetArg(a) for a in message.findall('arg')], + 'is_constructor': + IsConstructor(message), + 'constructed': + constructed, + 'constructed_has_listener': + constructed in context.interfaces_with_listeners, + } + + +def GetInterface(interface, context): + name = interface.attrib['name'] + return { + 'name': + name, + 'idx': + context.GetAndIncrementCount('interface_index'), + 'is_global': + name not in context.non_global_names, + 'events': [GetMessage(m, context) for m in interface.findall('event')], + 'requests': [ + GetMessage(m, context) for m in interface.findall('request') + ], + 'has_listener': + NeedsListener(interface) + } + + +def GetTemplateData(protocol_paths): + protocols = [ElementTree.parse(path).getroot() for path in protocol_paths] + context = TemplaterContext(protocols) + interfaces = [] + for p in protocols: + for i in p.findall('interface'): + interfaces.append(GetInterface(i, context)) + return { + 'protocol_names': [p.attrib['name'] for p in protocols], + 'interfaces': interfaces, + } + + +def main(argv): + """Execute the templater, based on the user provided args. + + Args: + argv: the command line arguments (including the script name) + """ + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '-d', + '--directory', + help='treat input paths as relative to this directory', + default='.') + parser.add_argument( + '-i', + '--input', + help='path to the input template file (relative to -d)', + required=True) + parser.add_argument( + '-o', + '--output', + help='path to write the generated file to', + required=True) + parser.add_argument( + '-s', + '--spec', + help='path(s) to the wayland specification(s)', + nargs='+', + required=True) + parsed_args = parser.parse_args(argv[1:]) + + env = jinja2.Environment( + loader=jinja2.FileSystemLoader(parsed_args.directory), + keep_trailing_newline=True, # newline-terminate generated files + lstrip_blocks=True, + trim_blocks=True) # so don't need {%- -%} everywhere + template = env.get_template(parsed_args.input) + with open(parsed_args.output, 'w') as out_fi: + out_fi.write(template.render(GetTemplateData(parsed_args.spec))) + + +if __name__ == '__main__': + main(sys.argv)
diff --git a/components/feedback/OWNERS b/components/feedback/OWNERS index b7d64ae..ac4e4a1 100644 --- a/components/feedback/OWNERS +++ b/components/feedback/OWNERS
@@ -1,7 +1,8 @@ afakhry@chromium.org bsimonnet@chromium.org +jkardatzke@chromium.org zork@chromium.org -per-file anonymizer_tool*=battre@chromium.org +per-file anonymizer_tool*=jkardatzke@chromium.org # COMPONENT: Platform>Apps>Feedback
diff --git a/components/feedback/anonymizer_tool.cc b/components/feedback/anonymizer_tool.cc index b5acfd76..d6d6fbb4 100644 --- a/components/feedback/anonymizer_tool.cc +++ b/components/feedback/anonymizer_tool.cc
@@ -57,6 +57,10 @@ // Serial numbers "(?i-s)(serial\\s*(?:number)?\\s*[:=]\\s*)([0-9a-zA-Z\\-\"]+)()", + + // GAIA IDs + R"xxx((\"?\bgaia_id\"?[=:]['\"])(\d+)(\b['\"]))xxx", + R"xxx((\{id: )(\d+)(, email:))xxx", }; bool MaybeUnmapAddress(net::IPAddress* addr) {
diff --git a/components/feedback/anonymizer_tool_unittest.cc b/components/feedback/anonymizer_tool_unittest.cc index c2f9a6e..4bb2faa 100644 --- a/components/feedback/anonymizer_tool_unittest.cc +++ b/components/feedback/anonymizer_tool_unittest.cc
@@ -119,6 +119,12 @@ AnonymizeCustomPatterns("SerialNumber: EVT23-17BA01-004")); EXPECT_EQ("serial=4", AnonymizeCustomPatterns("serial=\"1234AA5678\"")); + EXPECT_EQ("\"gaia_id\":\"1\"", + AnonymizeCustomPatterns("\"gaia_id\":\"1234567890\"")); + EXPECT_EQ("gaia_id='2'", AnonymizeCustomPatterns("gaia_id='987654321'")); + EXPECT_EQ("{id: 1, email:", + AnonymizeCustomPatterns("{id: 123454321, email:")); + EXPECT_EQ("<email: 1>", AnonymizeCustomPatterns("foo@bar.com")); EXPECT_EQ("Email: <email: 1>.",
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html index ef53417b..84eff8c 100644 --- a/components/flags_ui/resources/flags.html +++ b/components/flags_ui/resources/flags.html
@@ -1,6 +1,5 @@ <!doctype html> -<html dir="ltr" lang="en" - <if expr="not is_ios and not is_android">$i18n{dark}</if>> +<html dir="ltr" lang="en"> <head> <meta charset="utf-8"> <if expr="not is_ios">
diff --git a/components/media_message_center/media_notification_background.cc b/components/media_message_center/media_notification_background.cc index 8c736c7..3d6f49f33 100644 --- a/components/media_message_center/media_notification_background.cc +++ b/components/media_message_center/media_notification_background.cc
@@ -339,12 +339,17 @@ } SkColor MediaNotificationBackground::GetBackgroundColor() const { - return background_color_.value_or(kMediaNotificationDefaultBackgroundColor); + if (background_color_.has_value()) + return *background_color_; + return kMediaNotificationDefaultBackgroundColor; } SkColor MediaNotificationBackground::GetForegroundColor() const { - const SkColor foreground = foreground_color_.value_or(views::style::GetColor( - *owner_, views::style::CONTEXT_LABEL, views::style::STYLE_PRIMARY)); + const SkColor foreground = + foreground_color_.has_value() + ? *foreground_color_ + : views::style::GetColor(*owner_, views::style::CONTEXT_LABEL, + views::style::STYLE_PRIMARY); return color_utils::BlendForMinContrast(foreground, GetBackgroundColor()) .color; }
diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc index 31cc2fec..6e46442 100644 --- a/components/nacl/renderer/ppb_nacl_private_impl.cc +++ b/components/nacl/renderer/ppb_nacl_private_impl.cc
@@ -333,13 +333,11 @@ // Follow the original behavior in the trusted plugin and // PepperURLLoaderHost. if (document.GetSecurityOrigin().CanRequest(gurl)) { - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kSameOrigin); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kSameOrigin); + request.SetMode(network::mojom::RequestMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kSameOrigin); } else { - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); } // Plug-ins should not load via service workers as plug-ins may have their own
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index e160f3ce..923b7f5 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -218,6 +218,7 @@ ":in_memory_url_index_cache_proto", "//base:i18n", "//components/bookmarks/browser", + "//components/component_updater", "//components/favicon/core", "//components/favicon_base", "//components/keyed_service/core",
diff --git a/components/omnibox/browser/DEPS b/components/omnibox/browser/DEPS index 0d2c08f..cbd5f470 100644 --- a/components/omnibox/browser/DEPS +++ b/components/omnibox/browser/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/bookmarks/browser", "+components/bookmarks/test", + "+components/component_updater", "+components/favicon_base", "+components/favicon/core", "+components/grit",
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h index bd0192d..f2f09c6 100644 --- a/components/omnibox/browser/autocomplete_controller.h +++ b/components/omnibox/browser/autocomplete_controller.h
@@ -147,6 +147,8 @@ FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest, RedundantKeywordsIgnoredInResult); FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest, UpdateAssistedQueryStats); + FRIEND_TEST_ALL_PREFIXES(OmniboxPopupContentsViewTest, + EmitTextChangedAccessibilityEvent); FRIEND_TEST_ALL_PREFIXES(OmniboxViewTest, DoesNotUpdateAutocompleteOnBlur); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, FriendlyAccessibleLabel); @@ -154,6 +156,8 @@ FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, MaintainCursorAfterFocusCycle); FRIEND_TEST_ALL_PREFIXES(OmniboxPopupModelTest, SetSelectedLine); FRIEND_TEST_ALL_PREFIXES(OmniboxPopupModelTest, TestFocusFixing); + FRIEND_TEST_ALL_PREFIXES(OmniboxPopupContentsViewTest, + EmitSelectedChildrenChangedAccessibilityEvent); // Updates |result_| to reflect the current provider state and fires // notifications. If |regenerate_result| then we clear the result
diff --git a/components/omnibox/browser/autocomplete_provider_client.h b/components/omnibox/browser/autocomplete_provider_client.h index af00181b..6e175c2 100644 --- a/components/omnibox/browser/autocomplete_provider_client.h +++ b/components/omnibox/browser/autocomplete_provider_client.h
@@ -43,6 +43,10 @@ class SharedURLLoaderFactory; } +namespace component_updater { +class ComponentUpdateService; +} + class TemplateURLService; class AutocompleteProviderClient { @@ -95,6 +99,11 @@ // tab. virtual base::Time GetCurrentVisitTimestamp() const = 0; + // The component update service instance which will be used by on device + // suggestion provider to observe the model update event. + virtual component_updater::ComponentUpdateService* + GetComponentUpdateService() = 0; + virtual bool IsOffTheRecord() const = 0; virtual bool SearchSuggestEnabled() const = 0;
diff --git a/components/omnibox/browser/mock_autocomplete_provider_client.h b/components/omnibox/browser/mock_autocomplete_provider_client.h index 970fd1b..3806411 100644 --- a/components/omnibox/browser/mock_autocomplete_provider_client.h +++ b/components/omnibox/browser/mock_autocomplete_provider_client.h
@@ -77,6 +77,11 @@ return nullptr; } + component_updater::ComponentUpdateService* GetComponentUpdateService() + override { + return nullptr; + } + MOCK_CONST_METHOD0(GetAcceptLanguages, std::string()); MOCK_CONST_METHOD0(GetEmbedderRepresentationOfAboutScheme, std::string()); MOCK_METHOD0(GetBuiltinURLs, std::vector<base::string16>());
diff --git a/components/omnibox/browser/on_device_head_provider.cc b/components/omnibox/browser/on_device_head_provider.cc index 95f942aa..68328ee1 100644 --- a/components/omnibox/browser/on_device_head_provider.cc +++ b/components/omnibox/browser/on_device_head_provider.cc
@@ -74,7 +74,15 @@ serving_(nullptr), task_runner_(base::SequencedTaskRunnerHandle::Get()), on_device_search_request_id_(0), - weak_ptr_factory_(this) {} + observer_(this), + weak_ptr_factory_(this) { + if (client_ != nullptr) { + auto* component_update_service = client_->GetComponentUpdateService(); + if (component_update_service != nullptr) { + observer_.Add(component_update_service); + } + } +} OnDeviceHeadProvider::~OnDeviceHeadProvider() { serving_.reset(); @@ -204,3 +212,16 @@ done_ = true; listener_->OnProviderUpdate(true); } + +// We use component updater to fetch the on device model, which will fire +// Events::COMPONENT_UPDATED when the download is finished. In this case we will +// reload the new model and maybe clean up the old one. +void OnDeviceHeadProvider::OnEvent(Events event, const std::string& id) { + // TODO(crbug.com/925072): Returns early if the given id does not match on + // device head model updater. + if (event != Events::COMPONENT_UPDATED) + return; + + CreateOnDeviceHeadServingInstance(); + // TODO(crbug.com/925072): Cleans up the old model. +}
diff --git a/components/omnibox/browser/on_device_head_provider.h b/components/omnibox/browser/on_device_head_provider.h index 396e620..bd7070a 100644 --- a/components/omnibox/browser/on_device_head_provider.h +++ b/components/omnibox/browser/on_device_head_provider.h
@@ -7,6 +7,8 @@ #include <memory> +#include "base/scoped_observer.h" +#include "components/component_updater/component_updater_service.h" #include "components/omnibox/browser/autocomplete_provider.h" #include "components/omnibox/browser/autocomplete_provider_client.h" #include "components/omnibox/browser/on_device_head_serving.h" @@ -18,7 +20,8 @@ // help users get suggestions when they are in poor network. // All matches provided by this provider will have a relevance no greater than // 99, such that its matches will not show before any other providers. -class OnDeviceHeadProvider : public AutocompleteProvider { +class OnDeviceHeadProvider : public AutocompleteProvider, + public component_updater::ServiceObserver { public: static OnDeviceHeadProvider* Create(AutocompleteProviderClient* client, AutocompleteProviderListener* listener); @@ -56,6 +59,9 @@ // fetches by DoSearch and then calls OnProviderUpdate. void SearchDone(std::unique_ptr<OnDeviceHeadProviderParams> params); + // Required by component_updater::ServiceObserver. + void OnEvent(Events event, const std::string& id) override; + AutocompleteProviderClient* client_; AutocompleteProviderListener* listener_; @@ -71,6 +77,12 @@ // The id will be increased whenever a new request is received from the // AutocompleteController. size_t on_device_search_request_id_; + + // Tracks component update service for model update. + ScopedObserver<component_updater::ComponentUpdateService, + OnDeviceHeadProvider> + observer_; + base::WeakPtrFactory<OnDeviceHeadProvider> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(OnDeviceHeadProvider);
diff --git a/components/printing/browser/print_composite_client.cc b/components/printing/browser/print_composite_client.cc index b77ea68..61d1bc854 100644 --- a/components/printing/browser/print_composite_client.cc +++ b/components/printing/browser/print_composite_client.cc
@@ -206,12 +206,7 @@ mojom::PdfCompositor::CompositePageToPdfCallback callback, mojom::PdfCompositor::Status status, base::ReadOnlySharedMemoryRegion region) { - // Due to https://crbug.com/742517, we can not add and use COUNT for enums in - // mojo. - UMA_HISTOGRAM_ENUMERATION( - "CompositePageToPdf.Status", status, - static_cast<int32_t>(mojom::PdfCompositor::Status::COMPOSTING_FAILURE) + - 1); + UMA_HISTOGRAM_ENUMERATION("CompositePageToPdf.Status", status); std::move(callback).Run(status, std::move(region)); } @@ -224,12 +219,7 @@ // Clear all stored printed subframes. printed_subframes_.erase(document_cookie); - // Due to https://crbug.com/742517, we can not add and use COUNT for enums in - // mojo. - UMA_HISTOGRAM_ENUMERATION( - "CompositeDocToPdf.Status", status, - static_cast<int32_t>(mojom::PdfCompositor::Status::COMPOSTING_FAILURE) + - 1); + UMA_HISTOGRAM_ENUMERATION("CompositeDocToPdf.Status", status); std::move(callback).Run(status, std::move(region)); }
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h index 59a806c..98a123e4 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h
@@ -185,10 +185,6 @@ // Redispatch a keyboard event using the widget's window's CommandDispatcher. // Return true if the event is handled. bool RedispatchKeyEvent(NSEvent* event); - // Save an NSEvent to be used at the mojo version of RedispatchKeyEvent, - // rather than (inaccurately) reconstructing the NSEvent. - // https://crbug.com/942690 - void SaveKeyEventForRedispatch(NSEvent* event); // display::DisplayObserver: void OnDisplayMetricsChanged(const display::Display& display, @@ -241,12 +237,8 @@ void UpdateTooltip() override; void AcquireCapture() override; void ReleaseCapture() override; - void RedispatchKeyEvent(uint64_t type, - uint64_t modifier_flags, - double timestamp, - const base::string16& characters, - const base::string16& characters_ignoring_modifiers, - uint32_t key_code) override; + void RedispatchKeyEvent( + const std::vector<uint8_t>& native_event_data) override; // Return true if [NSApp updateWindows] needs to be called after updating the // TextInputClient. @@ -302,7 +294,6 @@ base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_; base::scoped_nsobject<NSObject<CommandDispatcherDelegate>> window_command_dispatcher_delegate_; - base::scoped_nsobject<NSEvent> saved_redispatch_event_; base::scoped_nsobject<BridgedContentView> bridged_view_; std::unique_ptr<remote_cocoa::ScopedNSViewIdMapping> bridged_view_id_mapping_;
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index d0feca6..aeb1b4a 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -39,6 +39,7 @@ #include "ui/base/layout.h" #include "ui/base/ui_base_switches.h" #include "ui/display/screen.h" +#include "ui/events/cocoa/cocoa_event_utils.h" #include "ui/gfx/geometry/dip_util.h" #import "ui/gfx/mac/coordinate_conversion.h" #import "ui/gfx/mac/nswindow_frame_controls.h" @@ -1096,10 +1097,6 @@ return [[window_ commandDispatcher] redispatchKeyEvent:event]; } -void NativeWidgetNSWindowBridge::SaveKeyEventForRedispatch(NSEvent* event) { - saved_redispatch_event_.reset([event retain]); -} - NSWindow* NativeWidgetNSWindowBridge::ns_window() { return window_.get(); } @@ -1251,42 +1248,8 @@ } void NativeWidgetNSWindowBridge::RedispatchKeyEvent( - uint64_t type, - uint64_t modifier_flags, - double timestamp, - const base::string16& characters, - const base::string16& characters_ignoring_modifiers, - uint32_t key_code) { - // If we saved an event for redispatch, and that event looks similar to the - // (potentially mangled) event parameters that we received, then use the saved - // event. - // https://crbug.com/942690 - if (saved_redispatch_event_) { - // Consider two events to have the same timestamp if they are within 0.1 ms. - constexpr double kTimestampThreshold = 0.0001; - if ([saved_redispatch_event_ type] == type && - base::SysNSStringToUTF16([saved_redispatch_event_ characters]) == - characters && - std::fabs([saved_redispatch_event_ timestamp] - timestamp) < - kTimestampThreshold) { - RedispatchKeyEvent(saved_redispatch_event_.autorelease()); - return; - } - saved_redispatch_event_.reset(); - } - NSEvent* event = - [NSEvent keyEventWithType:static_cast<NSEventType>(type) - location:NSZeroPoint - modifierFlags:modifier_flags - timestamp:timestamp - windowNumber:[window_ windowNumber] - context:nil - characters:base::SysUTF16ToNSString(characters) - charactersIgnoringModifiers:base::SysUTF16ToNSString( - characters_ignoring_modifiers) - isARepeat:NO - keyCode:key_code]; - RedispatchKeyEvent(event); + const std::vector<uint8_t>& native_event_data) { + RedispatchKeyEvent(ui::EventFromData(native_event_data)); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/components/remote_cocoa/common/native_widget_ns_window.mojom b/components/remote_cocoa/common/native_widget_ns_window.mojom index fa90eff0..a9f2a137 100644 --- a/components/remote_cocoa/common/native_widget_ns_window.mojom +++ b/components/remote_cocoa/common/native_widget_ns_window.mojom
@@ -204,15 +204,5 @@ ReleaseCapture(); // Redispatch a keyboard event using the widget's window's CommandDispatcher. - // Note that the callers of this method use content::NativeWebKeyboardEvent, - // which would introduce a layering violation here. Specify explicitly as - // arguments only what is used in constructing the |os_event| member of - // content::NativeWebKeyboardEvent, to avoid this layering violation. - RedispatchKeyEvent( - uint64 type, - uint64 modifier_flags, - double timestamp, - mojo_base.mojom.String16 characters, - mojo_base.mojom.String16 characters_ignoring_modifiers, - uint32 key_code); + RedispatchKeyEvent(array<uint8> native_event_data); };
diff --git a/components/services/pdf_compositor/pdf_compositor_impl.cc b/components/services/pdf_compositor/pdf_compositor_impl.cc index db27ccb..d7ea512a 100644 --- a/components/services/pdf_compositor/pdf_compositor_impl.cc +++ b/components/services/pdf_compositor/pdf_compositor_impl.cc
@@ -178,7 +178,7 @@ base::ReadOnlySharedMemoryMapping mapping = serialized_content.Map(); if (!mapping.IsValid()) { DLOG(ERROR) << "HandleCompositionRequest: Cannot map input."; - std::move(callback).Run(mojom::PdfCompositor::Status::HANDLE_MAP_ERROR, + std::move(callback).Run(mojom::PdfCompositor::Status::kHandleMapError, base::ReadOnlySharedMemoryRegion()); return; } @@ -208,7 +208,7 @@ base::ReadOnlySharedMemoryRegion* region) { if (!shared_mem.IsValid()) { DLOG(ERROR) << "CompositeToPdf: Invalid input."; - return mojom::PdfCompositor::Status::HANDLE_MAP_ERROR; + return mojom::PdfCompositor::Status::kHandleMapError; } DeserializationContext subframes = @@ -219,14 +219,14 @@ int page_count = SkMultiPictureDocumentReadPageCount(&stream); if (!page_count) { DLOG(ERROR) << "CompositeToPdf: No page is read."; - return mojom::PdfCompositor::Status::CONTENT_FORMAT_ERROR; + return mojom::PdfCompositor::Status::kContentFormatError; } std::vector<SkDocumentPage> pages(page_count); SkDeserialProcs procs = DeserializationProcs(&subframes); if (!SkMultiPictureDocumentRead(&stream, pages.data(), page_count, &procs)) { DLOG(ERROR) << "CompositeToPdf: Page reading failed."; - return mojom::PdfCompositor::Status::CONTENT_FORMAT_ERROR; + return mojom::PdfCompositor::Status::kContentFormatError; } SkDynamicMemoryWStream wstream; @@ -243,12 +243,12 @@ mojo::CreateReadOnlySharedMemoryRegion(wstream.bytesWritten()); if (!region_mapping.IsValid()) { DLOG(ERROR) << "CompositeToPdf: Cannot create new shared memory region."; - return mojom::PdfCompositor::Status::HANDLE_MAP_ERROR; + return mojom::PdfCompositor::Status::kHandleMapError; } wstream.copyToAndReset(region_mapping.mapping.memory()); *region = std::move(region_mapping.region); - return mojom::PdfCompositor::Status::SUCCESS; + return mojom::PdfCompositor::Status::kSuccess; } void PdfCompositorImpl::CompositeSubframe(FrameInfo* frame_info) {
diff --git a/components/services/pdf_compositor/pdf_compositor_service_unittest.cc b/components/services/pdf_compositor/pdf_compositor_service_unittest.cc index 0882708..94bb196a 100644 --- a/components/services/pdf_compositor/pdf_compositor_service_unittest.cc +++ b/components/services/pdf_compositor/pdf_compositor_service_unittest.cc
@@ -44,7 +44,7 @@ void OnCompositeToPdfCallback(mojom::PdfCompositor::Status status, base::ReadOnlySharedMemoryRegion region) { - if (status == mojom::PdfCompositor::Status::SUCCESS) + if (status == mojom::PdfCompositor::Status::kSuccess) CallbackOnCompositeSuccess(region); else CallbackOnCompositeStatus(status); @@ -123,7 +123,7 @@ auto serialized_content = base::ReadOnlySharedMemoryRegion::Create(10); EXPECT_CALL(*this, CallbackOnCompositeStatus( - mojom::PdfCompositor::Status::CONTENT_FORMAT_ERROR)) + mojom::PdfCompositor::Status::kContentFormatError)) .Times(1); compositor_->CompositeDocumentToPdf( 5u, std::move(serialized_content.region), ContentToFrameMap(),
diff --git a/components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom b/components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom index 0fba3601..f788a459 100644 --- a/components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom +++ b/components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom
@@ -14,10 +14,10 @@ // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum Status { - SUCCESS = 0, - HANDLE_MAP_ERROR = 1, - CONTENT_FORMAT_ERROR = 2, - COMPOSTING_FAILURE = 3, + kSuccess = 0, + kHandleMapError = 1, + kContentFormatError = 2, + kCompositingFailure = 3, }; // Notifies that a subframe is unavailable, such as the render frame process
diff --git a/components/sessions/ios/ios_live_tab.h b/components/sessions/ios/ios_live_tab.h index 14f3d89..dc7133ed6 100644 --- a/components/sessions/ios/ios_live_tab.h +++ b/components/sessions/ios/ios_live_tab.h
@@ -52,7 +52,7 @@ web::WebState* web_state_; // Needed to return an empty string in GetUserAgentOverride(). - static std::string user_agent_override_; + std::string user_agent_override_; DISALLOW_COPY_AND_ASSIGN(IOSLiveTab); };
diff --git a/components/sessions/ios/ios_live_tab.mm b/components/sessions/ios/ios_live_tab.mm index 9a50135..1b7fbba9a 100644 --- a/components/sessions/ios/ios_live_tab.mm +++ b/components/sessions/ios/ios_live_tab.mm
@@ -12,8 +12,6 @@ namespace sessions { -std::string IOSLiveTab::user_agent_override_; - // static IOSLiveTab* IOSLiveTab::GetForWebState(web::WebState* web_state) { if (!web_state->GetUserData(kIOSLiveTabWebStateUserDataKey)) {
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc index 87a8c630a..f684359 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.cc +++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -959,7 +959,15 @@ RecordLogoutRequestState(LogoutRequestState::kStarted); gaia_auth_fetcher_ = signin_client_->CreateGaiaAuthFetcher(this, requests_.front().source()); - gaia_auth_fetcher_->StartLogOut(); + bool use_continue_url = false; +#if defined(OS_ANDROID) + use_continue_url = base::FeatureList::IsEnabled(signin::kMiceFeature); +#endif + if (use_continue_url) { + gaia_auth_fetcher_->StartLogOutWithBlankContinueURL(); + } else { + gaia_auth_fetcher_->StartLogOut(); + } } void GaiaCookieManagerService::StartFetchingListAccounts() {
diff --git a/components/signin/core/browser/identity_manager_wrapper.cc b/components/signin/core/browser/identity_manager_wrapper.cc index e03d9a1..a7f12f6ed 100644 --- a/components/signin/core/browser/identity_manager_wrapper.cc +++ b/components/signin/core/browser/identity_manager_wrapper.cc
@@ -8,6 +8,7 @@ #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "services/identity/public/cpp/accounts_cookie_mutator.h" #include "services/identity/public/cpp/accounts_mutator.h" #include "services/identity/public/cpp/diagnostics_provider.h"
diff --git a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h index f65b275b..f9f1521 100644 --- a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h +++ b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h
@@ -54,17 +54,6 @@ void ReloadAccountsFromSystem( const CoreAccountId& primary_account_id) override; - // Reloads accounts from the provider. Fires |OnRefreshTokenAvailable| for - // each new account. Fires |OnRefreshTokenRevoked| for each account that was - // removed. - // It expects that there is already a primary account id. - void ReloadCredentials(); - - // Sets the primary account and then reloads the accounts from the provider. - // Should be called when the user signs in to a new account. - // |primary_account_id| must not be an empty string. - void ReloadCredentials(const CoreAccountId& primary_account_id); - // Adds |account_id| to |accounts_| if it does not exist or udpates // the auth error state of |account_id| if it exists. Fires // |OnRefreshTokenAvailable| if the account info is updated. @@ -79,6 +68,14 @@ friend class ProfileOAuth2TokenServiceIOSDelegateTest; FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceIOSDelegateTest, LoadRevokeCredentialsClearsExcludedAccounts); + FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceIOSDelegateTest, + ReloadCredentials); + FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceIOSDelegateTest, + ReloadCredentialsWithPrimaryAccountId); + FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceIOSDelegateTest, + UpdateAuthErrorAfterRevokeCredentials); + FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceIOSDelegateTest, + GetAuthError); struct AccountStatus { GoogleServiceAuthError last_auth_error; @@ -88,12 +85,14 @@ // to information about the account. typedef std::map<CoreAccountId, AccountStatus> AccountStatusMap; + // Reloads accounts from the provider. Fires |OnRefreshTokenAvailable| for + // each new account. Fires |OnRefreshTokenRevoked| for each account that was + // removed. + void ReloadCredentials(); + // Clears exclude secondary accounts preferences. void ClearExcludedSecondaryAccounts(); - // The primary account id. - CoreAccountId primary_account_id_; - // Info about the existing accounts. AccountStatusMap accounts_; @@ -103,7 +102,7 @@ base::ThreadChecker thread_checker_; // The client with which this instance was initialied, or NULL. - SigninClient* client_; + SigninClient* client_ = nullptr; std::unique_ptr<ProfileOAuth2TokenServiceIOSProvider> provider_; AccountTrackerService* account_tracker_service_;
diff --git a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm index 9eeaf05..9d4c8cc 100644 --- a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm +++ b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
@@ -186,27 +186,14 @@ return; } - ReloadCredentials(primary_account_id); + ReloadCredentials(); set_load_credentials_state(LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS); FireRefreshTokensLoaded(); } -void ProfileOAuth2TokenServiceIOSDelegate::ReloadCredentials( - const CoreAccountId& primary_account_id) { - DCHECK(!primary_account_id.empty()); - DCHECK(primary_account_id_.empty() || - primary_account_id_ == primary_account_id); - primary_account_id_ = primary_account_id; - ReloadCredentials(); -} - void ProfileOAuth2TokenServiceIOSDelegate::ReloadCredentials() { DCHECK(thread_checker_.CalledOnValidThread()); - if (primary_account_id_.empty()) { - // Avoid loading the credentials if there is no primary account id. - return; - } // Get the list of new account ids. std::set<std::string> new_account_ids; @@ -266,7 +253,6 @@ RemoveAccount(accountStatus.first); DCHECK_EQ(0u, accounts_.size()); - primary_account_id_ = CoreAccountId(); ClearExcludedSecondaryAccounts(); } @@ -277,10 +263,8 @@ void ProfileOAuth2TokenServiceIOSDelegate::ReloadAccountsFromSystem( const CoreAccountId& primary_account_id) { - if (primary_account_id.empty()) - return; - - ReloadCredentials(primary_account_id); + DCHECK(!primary_account_id.empty()); + ReloadCredentials(); } OAuth2AccessTokenFetcher*
diff --git a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm index 4ac4d661..2999689 100644 --- a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm +++ b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm
@@ -201,26 +201,10 @@ } TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, - ReloadCredentialsIgnoredIfNoPrimaryAccountId) { - ProviderAccount account1 = fake_provider_->AddAccount("gaia_1", "email_1@x"); - ProviderAccount account2 = fake_provider_->AddAccount("gaia_2", "email_2@x"); - oauth2_delegate_->ReloadCredentials(); - - EXPECT_EQ(0, token_available_count_); - EXPECT_EQ(0, tokens_loaded_count_); - EXPECT_EQ(0, token_revoked_count_); - EXPECT_EQ(0U, oauth2_delegate_->GetAccounts().size()); - EXPECT_FALSE( - oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1))); - EXPECT_FALSE( - oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2))); -} - -TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, ReloadCredentialsWithPrimaryAccountId) { ProviderAccount account1 = fake_provider_->AddAccount("gaia_1", "email_1@x"); ProviderAccount account2 = fake_provider_->AddAccount("gaia_2", "email_2@x"); - oauth2_delegate_->ReloadCredentials(GetAccountId(account1)); + oauth2_delegate_->ReloadCredentials(); EXPECT_EQ(2, token_available_count_); EXPECT_EQ(0, tokens_loaded_count_); @@ -285,7 +269,7 @@ TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, UpdateAuthErrorAfterRevokeCredentials) { ProviderAccount account1 = fake_provider_->AddAccount("gaia_1", "email_1@x"); - oauth2_delegate_->ReloadCredentials(GetAccountId(account1)); + oauth2_delegate_->ReloadCredentials(); base::RunLoop().RunUntilIdle(); ResetObserverCounts(); @@ -303,7 +287,7 @@ TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, GetAuthError) { // Accounts have no error by default. ProviderAccount account1 = fake_provider_->AddAccount("gaia_1", "email_1@x"); - oauth2_delegate_->ReloadCredentials(GetAccountId(account1)); + oauth2_delegate_->ReloadCredentials(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), oauth2_delegate_->GetAuthError("gaia_1"));
diff --git a/components/test/data/autofill/heuristics/input/158_i18n_ml.html b/components/test/data/autofill/heuristics/input/158_i18n_ml.html new file mode 100644 index 0000000..1f7095e07 --- /dev/null +++ b/components/test/data/autofill/heuristics/input/158_i18n_ml.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + <form action="http://www.google.com/" method="post"> + <label for="fn">പേര്:</label> <input type="text" id="fn"><br> + <label for="ln">മറുപേര്:</label> <input type="text" id="ln"><br> + <label for="ct">നഗരം:</label> <input type="text" id="ct"><br> + <label for="st">സംസ്ഥാനം:</label> <input type="text" id="st"><br> + <label for="zc">പിന്കോഡ്:</label> <input type="text" id="zc"><br> + <label for="em">ഇ-മെയില്:</label> <input type="text" id="em"><br> + <label for="ph">മൊബൈല്:</label> <input type="text" id="ph"><br> + </form> + </body> +</html>
diff --git a/components/test/data/autofill/heuristics/output/158_i18n_ml.out b/components/test/data/autofill/heuristics/output/158_i18n_ml.out new file mode 100644 index 0000000..a53d8a1d --- /dev/null +++ b/components/test/data/autofill/heuristics/output/158_i18n_ml.out
@@ -0,0 +1,7 @@ +NAME_FIRST | fn | പേര്: | | fn_1-default +NAME_LAST | ln | മറുപേര്: | | fn_1-default +ADDRESS_HOME_CITY | ct | നഗരം: | | fn_1-default +ADDRESS_HOME_STATE | st | സംസ്ഥാനം: | | fn_1-default +ADDRESS_HOME_ZIP | zc | പിന്കോഡ്: | | fn_1-default +EMAIL_ADDRESS | em | ഇ-മെയില്: | | fn_1-default +PHONE_HOME_WHOLE_NUMBER | ph | മൊബൈല്: | | fn_1-default
diff --git a/components/ui_devtools/protocol.json b/components/ui_devtools/protocol.json index f6fbaf9..dea96ea1 100644 --- a/components/ui_devtools/protocol.json +++ b/components/ui_devtools/protocol.json
@@ -423,6 +423,82 @@ ] }, { + "id": "RuleMatch", + "description": "Match data for a CSS rule.", + "type": "object", + "properties": [ + { + "name": "rule", + "$ref": "CSSRule", + "description": "CSS rule in the match." + }, + { + "name": "matchingSelectors", + "type": "array", + "items": { + "type": "integer" + }, + "description": "Matching selector indices in the rule's selectorList selectors (0-based)." + } + ] + }, + { + "id": "Value", + "type": "object", + "properties": [ + { + "name": "text", + "type": "string", + "description": "Value text." + }, + { + "name": "range", + "$ref": "SourceRange", + "optional": true, + "description": "Value range in the underlying resource (if available)." + } + ], + "description": "Data for a simple selector (these are delimited by commas in a selector list)." + }, + { + "id": "SelectorList", + "type": "object", + "properties": [ + { + "name": "selectors", + "type": "array", + "items": { + "$ref": "Value" + }, + "description": "Selectors in the list." + } + ], + "description": "Selector list data." + }, + { + "id": "CSSRule", + "description": "CSS rule representation.", + "type": "object", + "properties": [ + { + "name": "styleSheetId", + "$ref": "StyleSheetId", + "optional": true, + "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from." + }, + { + "name": "selectorList", + "$ref": "SelectorList", + "description": "Rule selector data." + }, + { + "name": "style", + "$ref": "CSSStyle", + "description": "Associated style declaration." + } + ] + }, + { "id": "StyleDeclarationEdit", "description": "A descriptor of operation to mutate style declaration text.", "type": "object",
diff --git a/components/ui_devtools/views/element_utility.cc b/components/ui_devtools/views/element_utility.cc index d61e5c5..042b721 100644 --- a/components/ui_devtools/views/element_utility.cc +++ b/components/ui_devtools/views/element_utility.cc
@@ -15,6 +15,11 @@ layer->layer_mask_layer() ? "true" : "false"); const cc::Layer* cc_layer = layer->cc_layer_for_testing(); if (cc_layer) { + // Property trees must be updated in order to get valid render surface + // reasons. + if (!cc_layer->layer_tree_host() || + cc_layer->layer_tree_host()->property_trees()->needs_rebuild) + return; cc::RenderSurfaceReason render_surface = cc_layer->GetRenderSurfaceReason(); if (render_surface != cc::RenderSurfaceReason::kNone) { ret->emplace_back("render-surface-reason",
diff --git a/components/user_manager/known_user.cc b/components/user_manager/known_user.cc index 74ebcdb..992837de 100644 --- a/components/user_manager/known_user.cc +++ b/components/user_manager/known_user.cc
@@ -43,6 +43,9 @@ // Key of whether this user ID refers to a SAML user. const char kUsingSAMLKey[] = "using_saml"; +// Key of whether this user authenticated via SAML using the principals API. +const char kIsUsingSAMLPrincipalsAPI[] = "using_saml_principals_api"; + // Key of Device Id. const char kDeviceId[] = "device_id"; @@ -72,6 +75,7 @@ kObjGuidKey, kAccountTypeKey, kUsingSAMLKey, + kIsUsingSAMLPrincipalsAPI, kDeviceId, kGAPSCookie, kReauthReasonKey, @@ -519,6 +523,23 @@ return false; } +void USER_MANAGER_EXPORT +UpdateIsUsingSAMLPrincipalsAPI(const AccountId& account_id, + bool is_using_saml_principals_api) { + SetBooleanPref(account_id, kIsUsingSAMLPrincipalsAPI, + is_using_saml_principals_api); +} + +bool USER_MANAGER_EXPORT +GetIsUsingSAMLPrincipalsAPI(const AccountId& account_id) { + bool is_using_saml_principals_api; + if (GetBooleanPref(account_id, kIsUsingSAMLPrincipalsAPI, + &is_using_saml_principals_api)) { + return is_using_saml_principals_api; + } + return false; +} + void SetProfileRequiresPolicy(const AccountId& account_id, ProfileRequiresPolicy required) { DCHECK_NE(required, ProfileRequiresPolicy::kUnknown);
diff --git a/components/user_manager/known_user.h b/components/user_manager/known_user.h index b703c3e9..1e22339 100644 --- a/components/user_manager/known_user.h +++ b/components/user_manager/known_user.h
@@ -152,6 +152,15 @@ // returns false. bool USER_MANAGER_EXPORT IsUsingSAML(const AccountId& account_id); +// Setter and getter for the known user preference that stores whether the user +// authenticated via SAML using the principals API. +void USER_MANAGER_EXPORT +UpdateIsUsingSAMLPrincipalsAPI(const AccountId& account_id, + bool is_using_saml_principals_api); + +bool USER_MANAGER_EXPORT +GetIsUsingSAMLPrincipalsAPI(const AccountId& account_id); + // Enum describing whether a user's profile requires policy. If kPolicyRequired, // the profile initialization code will ensure that valid policy is loaded // before session initialization completes.
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index e3371df..00d43e3 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -60,6 +60,7 @@ deps = [ "//base", + "//components/crash/core/common:crash_key", "//ui/gfx", "//ui/gl", ]
diff --git a/components/viz/common/gpu/DEPS b/components/viz/common/gpu/DEPS index cd1304f..48e1a21b 100644 --- a/components/viz/common/gpu/DEPS +++ b/components/viz/common/gpu/DEPS
@@ -13,6 +13,7 @@ specific_include_rules = { "metal_api_proxy.mm": [ + "+components/crash/core/common/crash_key.h", "+ui/gl", ] }
diff --git a/components/viz/common/gpu/metal_api_proxy.h b/components/viz/common/gpu/metal_api_proxy.h index 8db4dac..697fb3d1c 100644 --- a/components/viz/common/gpu/metal_api_proxy.h +++ b/components/viz/common/gpu/metal_api_proxy.h
@@ -21,6 +21,18 @@ @interface MTLDeviceProxy : NSObject <MTLDevice> { base::scoped_nsprotocol<id<MTLDevice>> device_; + // Weak pointer to the most vertexMain and fragmentMain MTLFunctions most + // recently present in the result from a -newLibraryWithSource. Used for + // comparison only in -newRenderPipelineStateWithDescriptor. + // https://crbug.com/974219 + id vertexSourceFunction_; + id fragmentSourceFunction_; + + // The source used in the -newLibraryWithSource functions that created + // the above functions. + std::string vertexSource_; + std::string fragmentSource_; + // Weak pointer to the progress reporter used to avoid watchdog timeouts. // This must be re-set to nullptr when it is no longer known to be valid. gl::ProgressReporter* progressReporter_;
diff --git a/components/viz/common/gpu/metal_api_proxy.mm b/components/viz/common/gpu/metal_api_proxy.mm index 1f255e1..bfca8f4 100644 --- a/components/viz/common/gpu/metal_api_proxy.mm +++ b/components/viz/common/gpu/metal_api_proxy.mm
@@ -4,8 +4,16 @@ #include "components/viz/common/gpu/metal_api_proxy.h" +#include "base/debug/crash_logging.h" +#include "base/strings/sys_string_conversions.h" +#include "components/crash/core/common/crash_key.h" #include "ui/gl/progress_reporter.h" +namespace { +// Maximum length of a shader to be uploaded with a crash report. +constexpr uint32_t kShaderCrashDumpLength = 8128; +} + @implementation MTLDeviceProxy - (id)initWithDevice:(id<MTLDevice>)device { if (self = [super init]) @@ -160,13 +168,46 @@ dispatch_data_t, error, __autoreleasing NSError**) -PROXY_METHOD3_SLOW(nullable id<MTLLibrary>, - newLibraryWithSource, - NSString*, - options, - nullable MTLCompileOptions*, - error, - __autoreleasing NSError**) +- (nullable id<MTLLibrary>) + newLibraryWithSource:(NSString*)source + options:(nullable MTLCompileOptions*)options + error:(__autoreleasing NSError**)error { + gl::ScopedProgressReporter scoped_reporter(progressReporter_); + + // Capture the shader's source in a crash key in case newLibraryWithSource + // hangs. + // https://crbug.com/974219 + static crash_reporter::CrashKeyString<kShaderCrashDumpLength> shaderKey( + "MTLShaderSource"); + std::string sourceAsSysString = base::SysNSStringToUTF8(source); + if (sourceAsSysString.size() > kShaderCrashDumpLength) + DLOG(WARNING) << "Truncating shader in crash log."; + + shaderKey.Set(sourceAsSysString); + id<MTLLibrary> library = [device_ newLibraryWithSource:source + options:options + error:error]; + shaderKey.Clear(); + + // Shaders from Skia will have either a vertexMain or fragmentMain function. + // Save the source and a weak pointer to the function, so we can capture + // the shader source in -newRenderPipelineStateWithDescriptor (see further + // remarks in that function). + base::scoped_nsprotocol<id<MTLFunction>> vertexFunction( + [library newFunctionWithName:@"vertexMain"]); + if (vertexFunction) { + vertexSourceFunction_ = vertexFunction; + vertexSource_ = sourceAsSysString; + } + base::scoped_nsprotocol<id<MTLFunction>> fragmentFunction( + [library newFunctionWithName:@"fragmentMain"]); + if (fragmentFunction) { + fragmentSourceFunction_ = fragmentFunction; + fragmentSource_ = sourceAsSysString; + } + + return library; +} PROXY_METHOD3_SLOW(void, newLibraryWithSource, NSString*, @@ -174,11 +215,37 @@ nullable MTLCompileOptions*, completionHandler, MTLNewLibraryCompletionHandler) -PROXY_METHOD2_SLOW(nullable id<MTLRenderPipelineState>, - newRenderPipelineStateWithDescriptor, - MTLRenderPipelineDescriptor*, - error, - __autoreleasing NSError**) +- (nullable id<MTLRenderPipelineState>) + newRenderPipelineStateWithDescriptor: + (MTLRenderPipelineDescriptor*)descriptor + error:(__autoreleasing NSError**)error { + // Capture the vertex and shader source being used. Skia's use pattern is to + // compile two MTLLibraries before creating a MTLRenderPipelineState -- one + // with vertexMain and the other with fragmentMain. The two immediately + // previous -newLibraryWithSource calls should have saved the sources for + // these two functions. + // https://crbug.com/974219 + static crash_reporter::CrashKeyString<kShaderCrashDumpLength> vertexShaderKey( + "MTLVertexSource"); + if (vertexSourceFunction_ == [descriptor vertexFunction]) + vertexShaderKey.Set(vertexSource_); + else + DLOG(WARNING) << "Failed to capture vertex shader."; + static crash_reporter::CrashKeyString<kShaderCrashDumpLength> + fragmentShaderKey("MTLFragmentSource"); + if (fragmentSourceFunction_ == [descriptor fragmentFunction]) + fragmentShaderKey.Set(fragmentSource_); + else + DLOG(WARNING) << "Failed to capture fragment shader."; + + gl::ScopedProgressReporter scoped_reporter(progressReporter_); + id<MTLRenderPipelineState> pipelineState = + [device_ newRenderPipelineStateWithDescriptor:descriptor error:error]; + + vertexShaderKey.Clear(); + fragmentShaderKey.Clear(); + return pipelineState; +} PROXY_METHOD4_SLOW(nullable id<MTLRenderPipelineState>, newRenderPipelineStateWithDescriptor, MTLRenderPipelineDescriptor*,
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 3b93c6b..37fdb1e 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -908,13 +908,16 @@ // Crop the source image to the backdrop_filter_bounds. gfx::Rect filter_clip = gfx::ToEnclosingRect(cc::MathUtil::MapClippedRect( backdrop_filter_bounds_transform, backdrop_filter_bounds->rect())); - filter_clip.Intersect(gfx::Rect(src_image->width(), src_image->height())); + gfx::Rect src_rect(src_image->width(), src_image->height()); + filter_clip.Intersect(src_rect); if (filter_clip.IsEmpty()) return FinalizeImage(surface); - src_image = src_image->makeSubset(RectToSkIRect(filter_clip)); - src_image_rect = gfx::RectF(filter_clip.width(), filter_clip.height()); - dest_rect = RectToSkRect( - ScaleToEnclosingRect(filter_clip, params->backdrop_filter_quality)); + if (filter_clip != src_rect) { + src_image = src_image->makeSubset(RectToSkIRect(filter_clip)); + src_image_rect = gfx::RectF(filter_clip.width(), filter_clip.height()); + dest_rect = RectToSkRect( + ScaleToEnclosingRect(filter_clip, params->backdrop_filter_quality)); + } } SkIPoint offset;
diff --git a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm index f94cd81..93885435 100644 --- a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm +++ b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
@@ -20,6 +20,7 @@ #include "mojo/public/cpp/bindings/strong_associated_binding.h" #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" #include "ui/base/cocoa/remote_accessibility_api.h" +#include "ui/events/cocoa/cocoa_event_utils.h" namespace remote_cocoa { @@ -66,12 +67,8 @@ void ForwardKeyboardEvent(const content::NativeWebKeyboardEvent& key_event, const ui::LatencyInfo& latency_info) override { - const blink::WebKeyboardEvent* web_event = - static_cast<const blink::WebKeyboardEvent*>(&key_event); - std::unique_ptr<content::InputEvent> input_event = - std::make_unique<content::InputEvent>(*web_event, latency_info); - host_->ForwardKeyboardEvent(std::move(input_event), - key_event.skip_in_browser); + std::vector<content::EditCommand> commands; + ForwardKeyboardEventWithCommands(key_event, latency_info, commands); } void ForwardKeyboardEventWithCommands( const content::NativeWebKeyboardEvent& key_event, @@ -81,8 +78,11 @@ static_cast<const blink::WebKeyboardEvent*>(&key_event); std::unique_ptr<content::InputEvent> input_event = std::make_unique<content::InputEvent>(*web_event, latency_info); + std::vector<uint8_t> native_event_data = + ui::EventToData(key_event.os_event); host_->ForwardKeyboardEventWithCommands( - std::move(input_event), key_event.skip_in_browser, commands); + std::move(input_event), native_event_data, key_event.skip_in_browser, + commands); } void RouteOrProcessMouseEvent( const blink::WebMouseEvent& web_event) override {
diff --git a/content/browser/appcache/appcache_subresource_url_factory.cc b/content/browser/appcache/appcache_subresource_url_factory.cc index 42f7e48..d728d1d3 100644 --- a/content/browser/appcache/appcache_subresource_url_factory.cc +++ b/content/browser/appcache/appcache_subresource_url_factory.cc
@@ -399,8 +399,7 @@ // Subresource requests from renderer processes should not be allowed to use // network::mojom::FetchRequestMode::kNavigate. - if (request.fetch_request_mode == - network::mojom::FetchRequestMode::kNavigate) { + if (request.mode == network::mojom::RequestMode::kNavigate) { mojo::ReportBadMessage("APPCACHE_SUBRESOURCE_URL_FACTORY_NAVIGATE"); return; }
diff --git a/content/browser/background_fetch/background_fetch_delegate_proxy.cc b/content/browser/background_fetch/background_fetch_delegate_proxy.cc index 19168b00..5d963130 100644 --- a/content/browser/background_fetch/background_fetch_delegate_proxy.cc +++ b/content/browser/background_fetch/background_fetch_delegate_proxy.cc
@@ -151,9 +151,9 @@ // Append the Origin header for requests whose CORS flag is set, or whose // request method is not GET or HEAD. See section 3.1 of the standard: // https://fetch.spec.whatwg.org/#origin-header - if (fetch_request->mode == network::mojom::FetchRequestMode::kCors || + if (fetch_request->mode == network::mojom::RequestMode::kCors || fetch_request->mode == - network::mojom::FetchRequestMode::kCorsWithForcedPreflight || + network::mojom::RequestMode::kCorsWithForcedPreflight || (fetch_request->method != "GET" && fetch_request->method != "HEAD")) { headers.SetHeader("Origin", origin.Serialize()); }
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index f62d97f..ac2101cb 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc
@@ -52,6 +52,7 @@ #include "content/public/common/service_manager_connection.h" #include "mojo/public/cpp/system/platform_handle.h" #include "net/websockets/websocket_basic_stream.h" +#include "net/websockets/websocket_channel.h" #include "services/service_manager/embedder/switches.h" #include "services/service_manager/public/cpp/constants.h" @@ -313,6 +314,7 @@ *base::CommandLine::ForCurrentProcess(); static const char* const kForwardSwitches[] = { net::kWebSocketReadBufferSize, + net::kWebSocketReceiveQuotaThreshold, service_manager::switches::kDisableInProcessStackTraces, switches::kDisableBestEffortTasks, switches::kDisableLogging,
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index ee81c2c3..3f8b0f8d 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -707,7 +707,7 @@ // On Android if reduced mode started network service this would already be // created. if (!net::NetworkChangeNotifier::HasNetworkChangeNotifier()) - network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); + network_change_notifier_ = net::NetworkChangeNotifier::Create(); } { TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:ScreenlockMonitor");
diff --git a/content/browser/devtools/protocol/browser_handler.cc b/content/browser/devtools/protocol/browser_handler.cc index 91a1f18..09229d26 100644 --- a/content/browser/devtools/protocol/browser_handler.cc +++ b/content/browser/devtools/protocol/browser_handler.cc
@@ -147,6 +147,10 @@ } else if (type == protocol::Browser::PermissionTypeEnum::PeriodicBackgroundSync) { *out_type = PermissionType::PERIODIC_BACKGROUND_SYNC; + } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockScreen) { + *out_type = PermissionType::WAKE_LOCK_SCREEN; + } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockSystem) { + *out_type = PermissionType::WAKE_LOCK_SYSTEM; } else { return Response::InvalidParams("Unknown permission type: " + type); }
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index ba6a36e..04c0ffcc 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -398,6 +398,13 @@ callback->sendFailure(Response::InternalError()); return; } + + // In the case of inspecting a GuestView (e.g. a PDF), we should reload + // the outer web contents (embedder), since otherwise reloading the guest by + // itself will fail. + if (web_contents->GetOuterWebContents()) + web_contents = web_contents->GetOuterWebContents(); + // It is important to fallback before triggering reload, so that // renderer could prepare beforehand. callback->fallThrough();
diff --git a/content/browser/download/file_download_url_loader_factory_getter.cc b/content/browser/download/file_download_url_loader_factory_getter.cc index 52582d0..2f478adc 100644 --- a/content/browser/download/file_download_url_loader_factory_getter.cc +++ b/content/browser/download/file_download_url_loader_factory_getter.cc
@@ -35,13 +35,12 @@ DCHECK(download::GetIOTaskRunner()->BelongsToCurrentThread()); network::mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info; - mojo::MakeStrongBinding( - std::make_unique<FileURLLoaderFactory>( - profile_path_, shared_cors_origin_access_list_, - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), - MakeRequest(&url_loader_factory_ptr_info)); + mojo::MakeStrongBinding(std::make_unique<FileURLLoaderFactory>( + profile_path_, shared_cors_origin_access_list_, + // USER_VISIBLE because download should progress + // even when there is high priority work to do. + base::TaskPriority::USER_VISIBLE), + MakeRequest(&url_loader_factory_ptr_info)); return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>( std::move(url_loader_factory_ptr_info));
diff --git a/content/browser/download/save_file_manager.cc b/content/browser/download/save_file_manager.cc index 78d9257d..dfa7554 100644 --- a/content/browser/download/save_file_manager.cc +++ b/content/browser/download/save_file_manager.cc
@@ -246,7 +246,7 @@ // top-level page (e.g. in SAVE_PAGE_TYPE_AS_ONLY_HTML mode). This is // probably also okay for subresources downloaded in // SAVE_PAGE_TYPE_AS_COMPLETE_HTML mode. - request->fetch_request_mode = network::mojom::FetchRequestMode::kNavigate; + request->mode = network::mojom::RequestMode::kNavigate; network::mojom::URLLoaderFactory* factory = nullptr; std::unique_ptr<DataURLLoaderFactory> data_url_loader_factory;
diff --git a/content/browser/file_url_loader_factory.cc b/content/browser/file_url_loader_factory.cc index 5a2d068..4af7207a 100644 --- a/content/browser/file_url_loader_factory.cc +++ b/content/browser/file_url_loader_factory.cc
@@ -720,11 +720,13 @@ const base::FilePath& profile_path, scoped_refptr<const SharedCorsOriginAccessList> shared_cors_origin_access_list, - scoped_refptr<base::SequencedTaskRunner> task_runner) + base::TaskPriority task_priority) : profile_path_(profile_path), shared_cors_origin_access_list_( std::move(shared_cors_origin_access_list)), - task_runner_(std::move(task_runner)) {} + task_runner_(base::CreateSequencedTaskRunner( + {base::MayBlock(), task_priority, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {} FileURLLoaderFactory::~FileURLLoaderFactory() = default; @@ -738,10 +740,8 @@ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - bool cors_flag = - request.fetch_request_mode != - network::mojom::FetchRequestMode::kNavigate && - request.fetch_request_mode != network::mojom::FetchRequestMode::kNoCors; + bool cors_flag = request.mode != network::mojom::RequestMode::kNavigate && + request.mode != network::mojom::RequestMode::kNoCors; // CORS mode requires a valid |request_inisiator|. Check this condition first // so that kDisableWebSecurity should not hide program errors in tests. @@ -881,9 +881,7 @@ // it? return std::make_unique<content::FileURLLoaderFactory>( profile_path, shared_cors_origin_access_list, - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); + base::TaskPriority::USER_VISIBLE); } } // namespace content
diff --git a/content/browser/file_url_loader_factory.h b/content/browser/file_url_loader_factory.h index bbad55d..97e20e7 100644 --- a/content/browser/file_url_loader_factory.h +++ b/content/browser/file_url_loader_factory.h
@@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" +#include "base/task/task_traits.h" #include "base/threading/thread_checker.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/binding_set.h" @@ -27,14 +28,13 @@ : public network::mojom::URLLoaderFactory, public base::SupportsWeakPtr<FileURLLoaderFactory> { public: - // SequencedTaskRunner must be allowed to block and should have background - // priority since it will be used to schedule synchronous file I/O tasks. // |shared_cors_origin_access_list| can be nullptr if only "no-cors" requests - // will be made. + // will be made. Thread pool tasks posted by the constructed + // FileURLLoadedFactory use |priority|. FileURLLoaderFactory(const base::FilePath& profile_path, scoped_refptr<const SharedCorsOriginAccessList> shared_cors_origin_access_list, - scoped_refptr<base::SequencedTaskRunner> task_runner); + base::TaskPriority task_priority); ~FileURLLoaderFactory() override; private:
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 424deca..d38d9d0 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -416,8 +416,7 @@ if (was_previously_loading) { if (navigation_request_ && navigation_request_->navigation_handle()) { // Mark the old request as aborted. - navigation_request_->navigation_handle()->set_net_error_code( - net::ERR_ABORTED); + navigation_request_->set_net_error(net::ERR_ABORTED); } ResetNavigationRequest(true, true); } @@ -534,8 +533,7 @@ if (navigation_request_) { int expected_pending_nav_entry_id = navigation_request_->nav_entry_id(); if (navigation_request_->navigation_handle()) { - navigation_request_->navigation_handle()->set_net_error_code( - net::ERR_ABORTED); + navigation_request_->set_net_error(net::ERR_ABORTED); expected_pending_nav_entry_id = navigation_request_->navigation_handle()->pending_nav_entry_id(); }
diff --git a/content/browser/frame_host/navigation_controller_android.cc b/content/browser/frame_host/navigation_controller_android.cc index 3c08d56..448ee7e1 100644 --- a/content/browser/frame_host/navigation_controller_android.cc +++ b/content/browser/frame_host/navigation_controller_android.cc
@@ -346,7 +346,7 @@ bool NavigationControllerAndroid::GetUseDesktopUserAgent( JNIEnv* env, const JavaParamRef<jobject>& obj) { - NavigationEntry* entry = navigation_controller_->GetVisibleEntry(); + NavigationEntry* entry = navigation_controller_->GetLastCommittedEntry(); return entry && entry->GetIsOverridingUserAgent(); } @@ -359,7 +359,7 @@ return; // Make sure the navigation entry actually exists. - NavigationEntry* entry = navigation_controller_->GetVisibleEntry(); + NavigationEntry* entry = navigation_controller_->GetLastCommittedEntry(); if (!entry) return;
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 0dd95ed..d08ff01 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -58,7 +58,6 @@ int pending_nav_entry_id, net::HttpRequestHeaders request_headers) : navigation_request_(navigation_request), - net_error_code_(net::OK), request_headers_(std::move(request_headers)), pending_nav_entry_id_(pending_nav_entry_id), navigation_id_(CreateUniqueHandleID()), @@ -117,7 +116,7 @@ TRACE_EVENT_ASYNC_END2("navigation", "Navigation StartToCommit", this, "URL", navigation_request_->common_params().url.spec(), - "Net Error Code", net_error_code_); + "Net Error Code", GetNetErrorCode()); } TRACE_EVENT_ASYNC_END0("navigation", "NavigationHandle", this); } @@ -210,7 +209,7 @@ } net::Error NavigationHandleImpl::GetNetErrorCode() { - return net_error_code_; + return navigation_request_->net_error(); } RenderFrameHostImpl* NavigationHandleImpl::GetRenderFrameHost() {
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index a6445b6..6519d7a97 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -157,10 +157,6 @@ // will not have a NavigationEntry associated with it, and this will return 0. int pending_nav_entry_id() const { return pending_nav_entry_id_; } - void set_net_error_code(net::Error net_error_code) { - net_error_code_ = net_error_code; - } - void InitServiceWorkerHandle( ServiceWorkerContextWrapper* service_worker_context); ServiceWorkerNavigationHandle* service_worker_handle() const { @@ -270,9 +266,6 @@ // The NavigationRequest that owns this NavigationHandle. NavigationRequest* navigation_request_; - // See NavigationHandle for a description of those member variables. - net::Error net_error_code_; - // The headers used for the request. net::HttpRequestHeaders request_headers_;
diff --git a/content/browser/frame_host/navigation_handle_impl_unittest.cc b/content/browser/frame_host/navigation_handle_impl_unittest.cc index ef6f9a0..738c820 100644 --- a/content/browser/frame_host/navigation_handle_impl_unittest.cc +++ b/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -122,7 +122,7 @@ const base::Optional<net::SSLInfo> ssl_info = base::nullopt) { was_callback_called_ = false; callback_result_ = NavigationThrottle::DEFER; - test_handle()->set_net_error_code(net_error_code); + request_->set_net_error(net_error_code); // It's safe to use base::Unretained since the NavigationHandle is owned by // the NavigationHandleImplTest.
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 2171144..988e426 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -1098,7 +1098,7 @@ return; if (should_override_url_loading) { - navigation_handle_->set_net_error_code(net::ERR_ABORTED); + net_error_ = net::ERR_ABORTED; common_params_.url = redirect_info.new_url; common_params_.method = redirect_info.new_method; // Update the navigation handle to point to the new url to ensure @@ -1286,10 +1286,8 @@ // Response that will not commit should be marked as aborted in the // NavigationHandle. - if (!response_should_be_rendered_) { - navigation_handle_->set_net_error_code(net::ERR_ABORTED); + if (!response_should_be_rendered_) net_error_ = net::ERR_ABORTED; - } // Update the AppCache params of the commit params. commit_params_.appcache_host_id = @@ -1370,7 +1368,7 @@ // TODO(clamy): Rename ShouldTransferNavigation once PlzNavigate ships. if (!frame_tree_node_->navigator()->GetDelegate()->ShouldTransferNavigation( frame_tree_node_->IsMainFrame())) { - navigation_handle_->set_net_error_code(net::ERR_ABORTED); + net_error_ = net::ERR_ABORTED; frame_tree_node_->ResetNavigationRequest(false, true); return; } @@ -1496,10 +1494,6 @@ TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationRequest", this, "OnRequestFailed", "error", status.error_code); state_ = FAILED; - if (navigation_handle_.get()) { - navigation_handle_->set_net_error_code( - static_cast<net::Error>(status.error_code)); - } int expected_pending_entry_id = navigation_handle_.get() ? navigation_handle_->pending_nav_entry_id() @@ -1507,7 +1501,7 @@ frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded( expected_pending_entry_id); - net_error_ = status.error_code; + net_error_ = static_cast<net::Error>(status.error_code); // If the request was canceled by the user do not show an error page. if (status.error_code == net::ERR_ABORTED) { @@ -1846,9 +1840,8 @@ NavigationThrottle::ThrottleCheckResult result) { DCHECK(result.action() != NavigationThrottle::DEFER); - int old_net_error = net_error_; + net::Error old_net_error = net_error_; net_error_ = result.net_error_code(); - navigation_handle_->set_net_error_code(static_cast<net::Error>(net_error_)); // TODO(crbug.com/774663): We may want to take result.action() into account. if (net::ERR_ABORTED == result.net_error_code()) { @@ -1898,8 +1891,7 @@ resource_request->request_initiator = common_params_.initiator_origin; resource_request->referrer = common_params_.referrer.url; resource_request->has_user_gesture = common_params_.has_user_gesture; - resource_request->fetch_request_mode = - network::mojom::FetchRequestMode::kNavigate; + resource_request->mode = network::mojom::RequestMode::kNavigate; BrowserContext* browser_context = frame_tree_node_->navigator()->GetController()->GetBrowserContext();
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 7586ffe..cb210ba 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -226,7 +226,8 @@ return navigation_handle_.get(); } - int net_error() { return net_error_; } + net::Error net_error() { return net_error_; } + void set_net_error(net::Error net_error) { net_error_ = net_error; } const std::string& GetMimeType() { return response_ ? response_->head.mime_type : base::EmptyString(); @@ -794,7 +795,7 @@ // Holds information for the navigation while the WillFailRequest // checks are performed by the NavigationHandle. bool has_stale_copy_in_cache_; - int net_error_; + net::Error net_error_ = net::OK; // Identifies in which RenderProcessHost this navigation is expected to // commit.
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index ed459a4..946b431 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -750,12 +750,8 @@ void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node, bool inform_renderer) { - if (frame_tree_node->navigation_request() && - frame_tree_node->navigation_request()->navigation_handle()) { - frame_tree_node->navigation_request() - ->navigation_handle() - ->set_net_error_code(net::ERR_ABORTED); - } + if (frame_tree_node->navigation_request()) + frame_tree_node->navigation_request()->set_net_error(net::ERR_ABORTED); frame_tree_node->ResetNavigationRequest(false, inform_renderer); if (frame_tree_node->IsMainFrame()) navigation_data_.reset();
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 7513200..cc766f90 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1477,7 +1477,6 @@ #endif IPC_MESSAGE_HANDLER(FrameHostMsg_RequestOverlayRoutingToken, OnRequestOverlayRoutingToken) - IPC_MESSAGE_HANDLER(FrameHostMsg_ShowCreatedWindow, OnShowCreatedWindow) IPC_END_MESSAGE_MAP() // No further actions here, since we may have been deleted. @@ -1650,8 +1649,8 @@ owned_render_widget_host_->RendererExited(); // The renderer process is gone, so this frame can no longer be loading. - if (GetNavigationHandle()) - GetNavigationHandle()->set_net_error_code(net::ERR_ABORTED); + if (navigation_request()) + navigation_request()->set_net_error(net::ERR_ABORTED); ResetNavigationRequests(); ResetLoadingState(); @@ -2234,10 +2233,9 @@ // return early if navigation_handle_ is null, once we prevent that case from // happening in practice. See https://crbug.com/605289. - // Update the error code in the NavigationHandle of the navigation. - if (GetNavigationHandle()) { - GetNavigationHandle()->set_net_error_code( - static_cast<net::Error>(error_code)); + // Update the error code in the NavigationRequest. + if (navigation_request()) { + navigation_request()->set_net_error(static_cast<net::Error>(error_code)); } frame_tree_node_->navigator()->DidFailProvisionalLoadWithError( @@ -3674,10 +3672,10 @@ keep_alive_handle_factory_->SetTimeout(keep_alive_timeout_); } -void RenderFrameHostImpl::OnShowCreatedWindow(int pending_widget_routing_id, - WindowOpenDisposition disposition, - const gfx::Rect& initial_rect, - bool user_gesture) { +void RenderFrameHostImpl::ShowCreatedWindow(int pending_widget_routing_id, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture) { delegate_->ShowCreatedWindow(GetProcess()->GetID(), pending_widget_routing_id, disposition, initial_rect, user_gesture); } @@ -4350,9 +4348,7 @@ // event from wiping out the is_waiting_for_beforeunload_ack_ state. if (frame_tree_node_->navigation_request() && frame_tree_node_->navigation_request()->navigation_handle()) { - frame_tree_node_->navigation_request() - ->navigation_handle() - ->set_net_error_code(net::ERR_ABORTED); + frame_tree_node_->navigation_request()->set_net_error(net::ERR_ABORTED); } frame_tree_node_->ResetNavigationRequest(false, true); } @@ -4859,9 +4855,8 @@ auto file_factory = std::make_unique<FileURLLoaderFactory>( browser_context->GetPath(), browser_context->GetSharedCorsOriginAccessList(), - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); + // A user-initiated navigation is USER_BLOCKING. + base::TaskPriority::USER_BLOCKING); non_network_url_loader_factories_.emplace(url::kFileScheme, std::move(file_factory)); } @@ -6443,7 +6438,7 @@ base::debug::SetCrashKeyString( base::debug::AllocateCrashKeyString( - "net_error_code", base::debug::CrashKeySize::Size32), + "net_error", base::debug::CrashKeySize::Size32), base::NumberToString(navigation_request->net_error())); base::debug::SetCrashKeyString(
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index c95aaef..358814f 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1180,11 +1180,6 @@ // create one if needed. Either way, it will send it to the frame. void OnRequestOverlayRoutingToken(); - void OnShowCreatedWindow(int pending_widget_routing_id, - WindowOpenDisposition disposition, - const gfx::Rect& initial_rect, - bool user_gesture); - // mojom::FrameHost: void CreateNewWindow(mojom::CreateNewWindowParamsPtr params, CreateNewWindowCallback callback) override; @@ -1251,6 +1246,10 @@ int error_code, const base::string16& error_description) override; void TransferUserActivationFrom(int32_t source_routing_id) override; + void ShowCreatedWindow(int32_t pending_widget_routing_id, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture) override; #if defined(OS_ANDROID) void UpdateUserGestureCarryoverInfo() override; #endif
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc index fce25b04..cb4ed5a 100644 --- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -52,6 +52,10 @@ #include "services/service_manager/public/mojom/interface_provider.mojom-test-utils.h" #include "testing/gmock/include/gmock/gmock.h" +#if defined(OS_ANDROID) +#include "base/android/build_info.h" +#endif // defined(OS_ANDROID) + namespace content { namespace { @@ -2389,6 +2393,15 @@ // Test deduplication of SameSite cookie deprecation messages. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, SameSiteCookieDeprecationMessages) { +#if defined(OS_ANDROID) + // TODO(crbug.com/974701): This test is broken on Android that is + // Marshmallow or older. + if (base::android::BuildInfo::GetInstance()->sdk_int() <= + base::android::SDK_VERSION_MARSHMALLOW) { + return; + } +#endif // defined(OS_ANDROID) + base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(features::kCookieDeprecationMessages);
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 237923a..be24ce1c 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -945,12 +945,8 @@ if (render_frame_host == speculative_render_frame_host_.get()) { // TODO(nasko, clamy): This should just clean up the speculative RFH // without canceling the request. See https://crbug.com/636119. - if (frame_tree_node_->navigation_request() && - frame_tree_node_->navigation_request()->navigation_handle()) { - frame_tree_node_->navigation_request() - ->navigation_handle() - ->set_net_error_code(net::ERR_ABORTED); - } + if (frame_tree_node_->navigation_request()) + frame_tree_node_->navigation_request()->set_net_error(net::ERR_ABORTED); frame_tree_node_->ResetNavigationRequest(false, true); } }
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index f725eab1..b35db7e4 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -26,7 +26,6 @@ #include "build/build_config.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/indexed_db/indexed_db_blob_info.h" -#include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_data_format_version.h" #include "content/browser/indexed_db/indexed_db_database_error.h" @@ -39,6 +38,7 @@ #include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" #include "content/browser/indexed_db/leveldb/leveldb_database.h" +#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" #include "content/public/browser/browser_task_traits.h" @@ -515,12 +515,14 @@ IndexedDBBackingStore::IndexedDBBackingStore( Mode backing_store_mode, IndexedDBFactory* indexed_db_factory, + indexed_db::LevelDBFactory* leveldb_factory, const Origin& origin, const FilePath& blob_path, std::unique_ptr<LevelDBDatabase> db, base::SequencedTaskRunner* task_runner) : backing_store_mode_(backing_store_mode), indexed_db_factory_(indexed_db_factory), + leveldb_factory_(leveldb_factory), origin_(origin), blob_path_(blob_path), origin_identifier_(ComputeOriginIdentifier(origin)), @@ -571,7 +573,7 @@ const std::string data_version_key = DataVersionKey::Encode(); scoped_refptr<LevelDBTransaction> transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); + leveldb_factory_->CreateLevelDBTransaction(db_.get()); int64_t db_schema_version = 0; IndexedDBDataFormatVersion db_data_version; @@ -771,7 +773,7 @@ #endif const std::string schema_version_key = SchemaVersionKey::Encode(); scoped_refptr<LevelDBTransaction> transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); + leveldb_factory_->CreateLevelDBTransaction(db_.get()); PutInt(transaction.get(), schema_version_key, 2); Status s = transaction->Commit(); @@ -787,7 +789,7 @@ #endif const std::string schema_version_key = SchemaVersionKey::Encode(); scoped_refptr<LevelDBTransaction> transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); + leveldb_factory_->CreateLevelDBTransaction(db_.get()); int64_t db_schema_version = 0; bool found = false; @@ -1340,8 +1342,8 @@ DCHECK(!succeeded || bytes_written >= 0); waiting_for_callback_ = false; if (delegate_.get()) // Only present for Blob, not File. - content::BrowserThread::DeleteSoon( - content::BrowserThread::IO, FROM_HERE, delegate_.release()); + content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, + delegate_.release()); if (aborted_) { self_ref_ = nullptr; return; @@ -1582,7 +1584,7 @@ bool all_blobs = blob_key == DatabaseMetaDataKey::kAllBlobsKey; DCHECK(all_blobs || DatabaseMetaDataKey::IsValidBlobKey(blob_key)); scoped_refptr<LevelDBTransaction> transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); + leveldb_factory_->CreateLevelDBTransaction(db_.get()); BlobJournalType live_blob_journal, primary_journal; if (!GetLiveBlobJournal(transaction.get(), &live_blob_journal).ok()) @@ -1704,7 +1706,7 @@ IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournal"); DCHECK(!committing_transaction_count_); scoped_refptr<LevelDBTransaction> journal_transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); + leveldb_factory_->CreateLevelDBTransaction(db_.get()); BlobJournalType journal; Status s = GetBlobJournal(level_db_key, journal_transaction.get(), &journal); @@ -1876,12 +1878,8 @@ EncodeIDBKey(key, &encoded_key); const std::string index_data_key = - IndexDataKey::Encode(database_id, - object_store_id, - index_id, - encoded_key, - record_identifier.primary_key(), - 0); + IndexDataKey::Encode(database_id, object_store_id, index_id, encoded_key, + record_identifier.primary_key(), 0); std::string data; EncodeVarInt(record_identifier.version(), &data); @@ -2325,8 +2323,8 @@ protected: std::string EncodeKey(const IndexedDBKey& key) override { - return ObjectStoreDataKey::Encode( - cursor_options_.database_id, cursor_options_.object_store_id, key); + return ObjectStoreDataKey::Encode(cursor_options_.database_id, + cursor_options_.object_store_id, key); } std::string EncodeKey(const IndexedDBKey& key, const IndexedDBKey& primary_key) override { @@ -2399,8 +2397,8 @@ protected: std::string EncodeKey(const IndexedDBKey& key) override { - return ObjectStoreDataKey::Encode( - cursor_options_.database_id, cursor_options_.object_store_id, key); + return ObjectStoreDataKey::Encode(cursor_options_.database_id, + cursor_options_.object_store_id, key); } std::string EncodeKey(const IndexedDBKey& key, const IndexedDBKey& primary_key) override { @@ -2484,16 +2482,13 @@ std::string EncodeKey(const IndexedDBKey& key) override { return IndexDataKey::Encode(cursor_options_.database_id, cursor_options_.object_store_id, - cursor_options_.index_id, - key); + cursor_options_.index_id, key); } std::string EncodeKey(const IndexedDBKey& key, const IndexedDBKey& primary_key) override { return IndexDataKey::Encode(cursor_options_.database_id, cursor_options_.object_store_id, - cursor_options_.index_id, - key, - primary_key); + cursor_options_.index_id, key, primary_key); } private: @@ -2598,16 +2593,13 @@ std::string EncodeKey(const IndexedDBKey& key) override { return IndexDataKey::Encode(cursor_options_.database_id, cursor_options_.object_store_id, - cursor_options_.index_id, - key); + cursor_options_.index_id, key); } std::string EncodeKey(const IndexedDBKey& key, const IndexedDBKey& primary_key) override { return IndexDataKey::Encode(cursor_options_.database_id, cursor_options_.object_store_id, - cursor_options_.index_id, - key, - primary_key); + cursor_options_.index_id, key, primary_key); } private: @@ -2652,8 +2644,7 @@ DCHECK_EQ(index_data_key.DatabaseId(), database_id_); primary_leveldb_key_ = ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), - index_data_key.ObjectStoreId(), - *primary_key_); + index_data_key.ObjectStoreId(), *primary_key_); std::string result; bool found = false; @@ -2807,9 +2798,12 @@ journal_cleaning_timer_.FireNow(); } +// |backing_store| can be null in unittests (see FakeTransaction). IndexedDBBackingStore::Transaction::Transaction( IndexedDBBackingStore* backing_store) : backing_store_(backing_store), + leveldb_factory_(backing_store ? backing_store->leveldb_factory_ + : nullptr), database_id_(-1), committing_(false), ptr_factory_(this) {} @@ -2821,8 +2815,8 @@ void IndexedDBBackingStore::Transaction::Begin() { IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); DCHECK(!transaction_.get()); - transaction_ = IndexedDBClassFactory::Get()->CreateLevelDBTransaction( - backing_store_->db_.get()); + transaction_ = + leveldb_factory_->CreateLevelDBTransaction(backing_store_->db_.get()); // If incognito, this snapshots blobs just as the above transaction_ // constructor snapshots the leveldb. @@ -2845,8 +2839,7 @@ // Create LevelDBTransaction for the name generator seed and add-journal. scoped_refptr<LevelDBTransaction> pre_transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction( - backing_store_->db_.get()); + leveldb_factory_->CreateLevelDBTransaction(backing_store_->db_.get()); for (auto& iter : blob_change_map_) { std::vector<IndexedDBBlobInfo*> new_blob_keys; @@ -2999,8 +2992,7 @@ // Read the persisted states of the primary/live blob journals, // so that they can be updated correctly by the transaction. scoped_refptr<LevelDBTransaction> journal_transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction( - backing_store_->db_.get()); + leveldb_factory_->CreateLevelDBTransaction(backing_store_->db_.get()); s = GetPrimaryBlobJournal(journal_transaction.get(), &primary_journal); if (!s.ok()) return s; @@ -3070,8 +3062,7 @@ } scoped_refptr<LevelDBTransaction> update_journal_transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction( - backing_store_->db_.get()); + leveldb_factory_->CreateLevelDBTransaction(backing_store_->db_.get()); UpdatePrimaryBlobJournal(update_journal_transaction.get(), saved_primary_journal); s = update_journal_transaction->Commit(); @@ -3149,8 +3140,7 @@ int64_t object_store_id) : key_(key), object_store_id_(object_store_id) {} -IndexedDBBackingStore::BlobChangeRecord::~BlobChangeRecord() { -} +IndexedDBBackingStore::BlobChangeRecord::~BlobChangeRecord() = default; void IndexedDBBackingStore::BlobChangeRecord::SetBlobInfo( std::vector<IndexedDBBlobInfo>* blob_info) { @@ -3245,8 +3235,7 @@ file_path_(file_path), key_(key), size_(size), - last_modified_(last_modified) { -} + last_modified_(last_modified) {} IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( const WriteDescriptor& other) = default;
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h index 411b1bd3..3d13eb5 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.h +++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -51,12 +51,15 @@ } namespace content { - class IndexedDBFactory; class LevelDBComparator; class LevelDBDatabase; struct IndexedDBValue; +namespace indexed_db { +class LevelDBFactory; +} + namespace indexed_db_backing_store_unittest { class IndexedDBBackingStoreTest; FORWARD_DECLARE_TEST(IndexedDBBackingStoreTest, ReadCorruptionInfo); @@ -264,6 +267,7 @@ // transactions & connections before destroying the backing store. // TODO(dmurph): Convert to WeakPtr. https://crbug.com/960992 IndexedDBBackingStore* backing_store_; + indexed_db::LevelDBFactory* const leveldb_factory_; scoped_refptr<LevelDBTransaction> transaction_; std::map<std::string, std::unique_ptr<BlobChangeRecord>> blob_change_map_; std::map<std::string, std::unique_ptr<BlobChangeRecord>> @@ -394,6 +398,7 @@ IndexedDBBackingStore(Mode backing_store_mode, IndexedDBFactory* indexed_db_factory, + indexed_db::LevelDBFactory* leveldb_factory, const url::Origin& origin, const base::FilePath& blob_path, std::unique_ptr<LevelDBDatabase> db, @@ -625,6 +630,7 @@ Mode backing_store_mode_; IndexedDBFactory* indexed_db_factory_; + indexed_db::LevelDBFactory* const leveldb_factory_; const url::Origin origin_; base::FilePath blob_path_;
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index 0f5d533..2d89cacc 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -63,12 +63,14 @@ public: TestableIndexedDBBackingStore(IndexedDBBackingStore::Mode backing_store_mode, IndexedDBFactory* indexed_db_factory, + indexed_db::LevelDBFactory* leveldb_factory, const url::Origin& origin, const base::FilePath& blob_path, std::unique_ptr<LevelDBDatabase> db, base::SequencedTaskRunner* task_runner) : IndexedDBBackingStore(backing_store_mode, indexed_db_factory, + leveldb_factory, origin, blob_path, std::move(db), @@ -134,20 +136,22 @@ public: explicit TestIDBFactory(IndexedDBContextImpl* idb_context) : IndexedDBFactoryImpl(idb_context, - indexed_db::GetDefaultLevelDBFactory(), + indexed_db::LevelDBFactory::Get(), + IndexedDBClassFactory::Get(), base::DefaultClock::GetInstance()) {} ~TestIDBFactory() override = default; protected: std::unique_ptr<IndexedDBBackingStore> CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, + indexed_db::LevelDBFactory* leveldb_factory, const url::Origin& origin, const base::FilePath& blob_path, std::unique_ptr<LevelDBDatabase> db, base::SequencedTaskRunner* task_runner) override { return std::make_unique<TestableIndexedDBBackingStore>( - backing_store_mode, this, origin, blob_path, std::move(db), - task_runner); + backing_store_mode, this, leveldb_factory, origin, blob_path, + std::move(db), task_runner); } private: @@ -168,7 +172,6 @@ idb_context_ = base::MakeRefCounted<IndexedDBContextImpl>( temp_dir_.GetPath(), special_storage_policy_, quota_manager_proxy_, - indexed_db::GetDefaultLevelDBFactory(), base::DefaultClock::GetInstance()); idb_context_->SetTaskRunnerForTesting( base::SequencedTaskRunnerHandle::Get()); @@ -1336,7 +1339,7 @@ // Set the schema to 2, which was before blob support. auto transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction( + indexed_db::LevelDBFactory::Get()->CreateLevelDBTransaction( backing_store()->db()); const std::string schema_version_key = SchemaVersionKey::Encode(); indexed_db::PutInt(transaction.get(), schema_version_key, 2); @@ -1370,7 +1373,7 @@ // Test that we upgraded. auto transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction( + indexed_db::LevelDBFactory::Get()->CreateLevelDBTransaction( backing_store()->db()); const std::string schema_version_key = SchemaVersionKey::Encode(); int64_t found_int = 0; @@ -1469,7 +1472,7 @@ // Set the schema to 2, which was before blob support. auto transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction( + indexed_db::LevelDBFactory::Get()->CreateLevelDBTransaction( backing_store()->db()); const std::string schema_version_key = SchemaVersionKey::Encode(); indexed_db::PutInt(transaction.get(), schema_version_key, 2);
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 72d138c..75b3af1 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -30,6 +30,7 @@ #include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_factory_impl.h" +#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h" @@ -78,6 +79,7 @@ void SetUp() override { GetTestClassFactory()->Reset(); IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetIDBClassFactory); + indexed_db::LevelDBFactory::SetFactoryGetterForTesting(GetLevelDBFactory); ContentBrowserTest::SetUp(); } @@ -235,6 +237,10 @@ return GetTestClassFactory(); } + static indexed_db::LevelDBFactory* GetLevelDBFactory() { + return GetTestClassFactory(); + } + private: DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest); };
diff --git a/content/browser/indexed_db/indexed_db_class_factory.cc b/content/browser/indexed_db/indexed_db_class_factory.cc index 04aec78c..f39b249 100644 --- a/content/browser/indexed_db/indexed_db_class_factory.cc +++ b/content/browser/indexed_db/indexed_db_class_factory.cc
@@ -30,7 +30,7 @@ return s_factory.Pointer(); } -std::unique_ptr<IndexedDBDatabase> +std::pair<std::unique_ptr<IndexedDBDatabase>, leveldb::Status> IndexedDBClassFactory::CreateIndexedDBDatabase( const base::string16& name, IndexedDBBackingStore* backing_store, @@ -40,10 +40,17 @@ std::unique_ptr<IndexedDBMetadataCoding> metadata_coding, const IndexedDBDatabase::Identifier& unique_identifier, ScopesLockManager* transaction_lock_manager) { - return base::WrapUnique(new IndexedDBDatabase( - name, backing_store, factory, std::move(error_callback), - std::move(destroy_me), std::move(metadata_coding), unique_identifier, - transaction_lock_manager)); + DCHECK(backing_store); + DCHECK(factory); + std::unique_ptr<IndexedDBDatabase> database = + base::WrapUnique(new IndexedDBDatabase( + name, backing_store, factory, this, std::move(error_callback), + std::move(destroy_me), std::move(metadata_coding), unique_identifier, + transaction_lock_manager)); + leveldb::Status s = database->OpenInternal(); + if (!s.ok()) + database = nullptr; + return {std::move(database), s}; } std::unique_ptr<IndexedDBTransaction> @@ -59,17 +66,4 @@ mode, backing_store_transaction)); } -scoped_refptr<LevelDBTransaction> -IndexedDBClassFactory::CreateLevelDBTransaction(LevelDBDatabase* db) { - return new LevelDBTransaction(db); -} - -std::unique_ptr<LevelDBIteratorImpl> IndexedDBClassFactory::CreateIteratorImpl( - std::unique_ptr<leveldb::Iterator> iterator, - LevelDBDatabase* db, - const leveldb::Snapshot* snapshot) { - return base::WrapUnique( - new LevelDBIteratorImpl(std::move(iterator), db, snapshot)); -} - } // namespace content
diff --git a/content/browser/indexed_db/indexed_db_class_factory.h b/content/browser/indexed_db/indexed_db_class_factory.h index 18922b8a..6ef45f8 100644 --- a/content/browser/indexed_db/indexed_db_class_factory.h +++ b/content/browser/indexed_db/indexed_db_class_factory.h
@@ -9,6 +9,7 @@ #include <memory> #include <set> +#include <utility> #include "base/callback.h" #include "base/lazy_instance.h" @@ -19,21 +20,13 @@ #include "content/common/content_export.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" - -namespace leveldb { -class Iterator; -class Snapshot; -} // namespace leveldb +#include "third_party/leveldatabase/src/include/leveldb/status.h" namespace content { - class IndexedDBBackingStore; class IndexedDBConnection; class IndexedDBFactory; class IndexedDBTransaction; -class LevelDBDatabase; -class LevelDBIteratorImpl; -class LevelDBTransaction; // Use this factory to create some IndexedDB objects. Exists solely to // facilitate tests which sometimes need to inject mock objects into the system. @@ -51,8 +44,13 @@ static void SetIndexedDBClassFactoryGetter(GetterCallback* cb); - // See IndexedDBDatabase::Create. - virtual std::unique_ptr<IndexedDBDatabase> CreateIndexedDBDatabase( + // Returns a constructed database, or a leveldb::Status error if there was a + // problem initializing the database. |error_callback| is called when a + // backing store operation has failed. The database will be closed + // (IndexedDBFactory::ForceClose) when the callback is called. |destroy_me| + // will destroy the IndexedDBDatabase object. + virtual std::pair<std::unique_ptr<IndexedDBDatabase>, leveldb::Status> + CreateIndexedDBDatabase( const base::string16& name, IndexedDBBackingStore* backing_store, IndexedDBFactory* factory, @@ -71,14 +69,6 @@ blink::mojom::IDBTransactionMode mode, IndexedDBBackingStore::Transaction* backing_store_transaction); - virtual std::unique_ptr<LevelDBIteratorImpl> CreateIteratorImpl( - std::unique_ptr<leveldb::Iterator> iterator, - LevelDBDatabase* db, - const leveldb::Snapshot* snapshot); - - virtual scoped_refptr<LevelDBTransaction> CreateLevelDBTransaction( - LevelDBDatabase* db); - protected: IndexedDBClassFactory() {} virtual ~IndexedDBClassFactory() {}
diff --git a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc index 0cdcbabd..30fe032 100644 --- a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc +++ b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
@@ -15,8 +15,10 @@ #include "base/test/scoped_task_environment.h" #include "base/threading/sequenced_task_runner_handle.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" +#include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/leveldb/fake_leveldb_factory.h" #include "content/browser/indexed_db/leveldb/leveldb_database.h" +#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/env_chromium.h" @@ -39,11 +41,12 @@ auto task_runner = base::SequencedTaskRunnerHandle::Get(); std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique<IndexedDBBackingStore>( - IndexedDBBackingStore::Mode::kInMemory, nullptr, origin, path, + IndexedDBBackingStore::Mode::kInMemory, nullptr, + indexed_db::LevelDBFactory::Get(), origin, path, std::make_unique<LevelDBDatabase>( indexed_db::FakeLevelDBFactory::GetBrokenLevelDB( leveldb::Status::IOError("It's broken!"), path), - task_runner.get(), + indexed_db::LevelDBFactory::Get(), task_runner.get(), LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase), task_runner.get()); leveldb::Status s = backing_store->Initialize(false); @@ -71,11 +74,12 @@ for (leveldb::Status error_status : errors) { std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique<IndexedDBBackingStore>( - IndexedDBBackingStore::Mode::kInMemory, nullptr, origin, path, + IndexedDBBackingStore::Mode::kInMemory, nullptr, + indexed_db::LevelDBFactory::Get(), origin, path, std::make_unique<LevelDBDatabase>( indexed_db::FakeLevelDBFactory::GetBrokenLevelDB(error_status, path), - task_runner.get(), + indexed_db::LevelDBFactory::Get(), task_runner.get(), LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase), task_runner.get()); leveldb::Status s = backing_store->Initialize(false);
diff --git a/content/browser/indexed_db/indexed_db_connection.cc b/content/browser/indexed_db/indexed_db_connection.cc index ebe2dc5..64bafc0f 100644 --- a/content/browser/indexed_db/indexed_db_connection.cc +++ b/content/browser/indexed_db/indexed_db_connection.cc
@@ -26,6 +26,7 @@ IndexedDBConnection::IndexedDBConnection( int child_process_id, IndexedDBOriginStateHandle origin_state_handle, + IndexedDBClassFactory* indexed_db_class_factory, base::WeakPtr<IndexedDBDatabase> database, base::RepeatingClosure on_version_change_ignored, base::OnceCallback<void(IndexedDBConnection*)> on_close, @@ -34,6 +35,7 @@ : id_(g_next_indexed_db_connection_id++), child_process_id_(child_process_id), origin_state_handle_(std::move(origin_state_handle)), + indexed_db_class_factory_(indexed_db_class_factory), database_(std::move(database)), on_version_change_ignored_(std::move(on_version_change_ignored)), on_close_(std::move(on_close)), @@ -124,7 +126,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK_EQ(GetTransaction(id), nullptr) << "Duplicate transaction id." << id; std::unique_ptr<IndexedDBTransaction> transaction = - IndexedDBClassFactory::Get()->CreateIndexedDBTransaction( + indexed_db_class_factory_->CreateIndexedDBTransaction( id, this, error_callback_, scope, mode, backing_store_transaction); IndexedDBTransaction* transaction_ptr = transaction.get(); transactions_[id] = std::move(transaction);
diff --git a/content/browser/indexed_db/indexed_db_connection.h b/content/browser/indexed_db/indexed_db_connection.h index bcf1524..7f8d1b5 100644 --- a/content/browser/indexed_db/indexed_db_connection.h +++ b/content/browser/indexed_db/indexed_db_connection.h
@@ -33,6 +33,7 @@ IndexedDBConnection(int child_process_id, IndexedDBOriginStateHandle origin_state_handle, + IndexedDBClassFactory* indexed_db_class_factory, base::WeakPtr<IndexedDBDatabase> database, base::RepeatingClosure on_version_change_ignored, base::OnceCallback<void(IndexedDBConnection*)> on_close, @@ -107,6 +108,7 @@ // Keeps the factory for this origin alive. IndexedDBOriginStateHandle origin_state_handle_; + IndexedDBClassFactory* const indexed_db_class_factory_; base::WeakPtr<IndexedDBDatabase> database_; base::RepeatingClosure on_version_change_ignored_;
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index 96de4a6e..1bd400a 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -23,6 +23,7 @@ #include "base/trace_event/trace_event.h" #include "base/values.h" #include "content/browser/browser_main_loop.h" +#include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_connection.h" #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" @@ -85,7 +86,6 @@ const base::FilePath& data_path, scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy, scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, - indexed_db::LevelDBFactory* leveldb_factory, base::Clock* clock) : force_keep_session_state_(false), special_storage_policy_(special_storage_policy), @@ -95,7 +95,6 @@ base::TaskPriority::USER_VISIBLE, // BLOCK_SHUTDOWN to support clearing session-only storage. base::TaskShutdownBehavior::BLOCK_SHUTDOWN})), - leveldb_factory_(leveldb_factory), clock_(clock) { IDB_TRACE("init"); if (!data_path.empty()) @@ -109,8 +108,11 @@ // Prime our cache of origins with existing databases so we can // detect when dbs are newly created. GetOriginSet(); - indexeddb_factory_ = - std::make_unique<IndexedDBFactoryImpl>(this, leveldb_factory_, clock_); + indexeddb_factory_ = std::make_unique<IndexedDBFactoryImpl>( + this, + leveldb_factory_for_testing_ ? leveldb_factory_for_testing_ + : indexed_db::LevelDBFactory::Get(), + IndexedDBClassFactory::Get(), clock_); } return indexeddb_factory_.get(); } @@ -494,6 +496,10 @@ QueryDiskAndUpdateQuotaUsage(origin); } +void IndexedDBContextImpl::BlobFilesCleaned(const url::Origin& origin) { + QueryDiskAndUpdateQuotaUsage(origin); +} + void IndexedDBContextImpl::AddObserver( IndexedDBContextImpl::Observer* observer) { DCHECK(!observers_.HasObserver(observer)); @@ -520,8 +526,10 @@ } } -void IndexedDBContextImpl::BlobFilesCleaned(const url::Origin& origin) { - QueryDiskAndUpdateQuotaUsage(origin); +void IndexedDBContextImpl::SetLevelDBFactoryForTesting( + indexed_db::LevelDBFactory* factory) { + DCHECK(factory); + leveldb_factory_for_testing_ = factory; } IndexedDBContextImpl::~IndexedDBContextImpl() {
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index cac327b..001d7f7 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -19,7 +19,6 @@ #include "base/macros.h" #include "content/browser/browser_main_loop.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" -#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/public/browser/indexed_db_context.h" #include "storage/browser/quota/quota_manager_proxy.h" #include "storage/browser/quota/special_storage_policy.h" @@ -40,6 +39,10 @@ class IndexedDBConnection; class IndexedDBFactoryImpl; +namespace indexed_db { +class LevelDBFactory; +} + class CONTENT_EXPORT IndexedDBContextImpl : public IndexedDBContext { public: // Recorded in histograms, so append only. @@ -74,7 +77,6 @@ const base::FilePath& data_path, scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy, scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, - indexed_db::LevelDBFactory* leveldb_factory, base::Clock* clock); IndexedDBFactoryImpl* GetIDBFactory(); @@ -152,6 +154,8 @@ const base::string16& database_name, const base::string16& object_store_name); + void SetLevelDBFactoryForTesting(indexed_db::LevelDBFactory* factory); + protected: ~IndexedDBContextImpl() override; @@ -194,7 +198,7 @@ std::unique_ptr<std::set<url::Origin>> origin_set_; std::map<url::Origin, int64_t> origin_size_map_; base::ObserverList<Observer>::Unchecked observers_; - indexed_db::LevelDBFactory* leveldb_factory_; + indexed_db::LevelDBFactory* leveldb_factory_for_testing_ = nullptr; base::Clock* clock_; DISALLOW_COPY_AND_ASSIGN(IndexedDBContextImpl);
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 0594a4d..d8ca38083 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -454,32 +454,11 @@ DISALLOW_COPY_AND_ASSIGN(DeleteRequest); }; -// static -std::tuple<std::unique_ptr<IndexedDBDatabase>, Status> -IndexedDBDatabase::Create( - const base::string16& name, - IndexedDBBackingStore* backing_store, - IndexedDBFactory* factory, - ErrorCallback error_callback, - base::OnceClosure destroy_me, - std::unique_ptr<IndexedDBMetadataCoding> metadata_coding, - const Identifier& unique_identifier, - ScopesLockManager* transaction_lock_manager) { - std::unique_ptr<IndexedDBDatabase> database = - IndexedDBClassFactory::Get()->CreateIndexedDBDatabase( - name, backing_store, factory, std::move(error_callback), - std::move(destroy_me), std::move(metadata_coding), unique_identifier, - transaction_lock_manager); - Status s = database->OpenInternal(); - if (!s.ok()) - database = nullptr; - return {std::move(database), s}; -} - IndexedDBDatabase::IndexedDBDatabase( const base::string16& name, IndexedDBBackingStore* backing_store, IndexedDBFactory* factory, + IndexedDBClassFactory* class_factory, ErrorCallback error_callback, base::OnceClosure destroy_me, std::unique_ptr<IndexedDBMetadataCoding> metadata_coding, @@ -492,6 +471,7 @@ kInvalidId), identifier_(unique_identifier), factory_(factory), + class_factory_(class_factory), metadata_coding_(std::move(metadata_coding)), lock_manager_(transaction_lock_manager), error_callback_(std::move(error_callback)), @@ -593,7 +573,7 @@ int child_process_id) { std::unique_ptr<IndexedDBConnection> connection = std::make_unique<IndexedDBConnection>( - child_process_id, std::move(origin_state_handle), + child_process_id, std::move(origin_state_handle), class_factory_, weak_factory_.GetWeakPtr(), base::BindRepeating(&IndexedDBDatabase::VersionChangeIgnored, weak_factory_.GetWeakPtr()),
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index e89b312b..c2b5cb1e 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -48,7 +48,7 @@ } namespace content { - +class IndexedDBClassFactory; class IndexedDBConnection; class IndexedDBDatabaseCallbacks; class IndexedDBFactory; @@ -69,20 +69,6 @@ static const int64_t kInvalidId = 0; static const int64_t kMinimumIndexId = 30; - // |error_callback| is called when a backing store operation has failed. The - // database will be closed (IndexedDBFactory::ForceClose) when the callback is - // called. - // |destroy_me| will destroy the IndexedDBDatabase object. - static std::tuple<std::unique_ptr<IndexedDBDatabase>, leveldb::Status> Create( - const base::string16& name, - IndexedDBBackingStore* backing_store, - IndexedDBFactory* factory, - ErrorCallback error_callback, - base::OnceClosure destroy_me, - std::unique_ptr<IndexedDBMetadataCoding> metadata_coding, - const Identifier& unique_identifier, - ScopesLockManager* lock_manager); - virtual ~IndexedDBDatabase(); const Identifier& identifier() const { return identifier_; } @@ -318,6 +304,7 @@ IndexedDBDatabase(const base::string16& name, IndexedDBBackingStore* backing_store, IndexedDBFactory* factory, + IndexedDBClassFactory* class_factory, ErrorCallback error_callback, base::OnceClosure destroy_me, std::unique_ptr<IndexedDBMetadataCoding> metadata_coding, @@ -328,6 +315,7 @@ virtual size_t GetUsableMessageSizeInBytes() const; private: + friend class MockBrowserTestIndexedDBClassFactory; friend class IndexedDBClassFactory; FRIEND_TEST_ALL_PREFIXES(IndexedDBDatabaseTest, OpenDeleteClear); @@ -393,6 +381,7 @@ const Identifier identifier_; // TODO(dmurph): Remove the need for this to be here (and then remove it). IndexedDBFactory* factory_; + IndexedDBClassFactory* const class_factory_; std::unique_ptr<IndexedDBMetadataCoding> metadata_coding_; ScopesLockManager* lock_manager_;
diff --git a/content/browser/indexed_db/indexed_db_database_unittest.cc b/content/browser/indexed_db/indexed_db_database_unittest.cc index e15ac399..a54481e 100644 --- a/content/browser/indexed_db/indexed_db_database_unittest.cc +++ b/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -66,7 +66,7 @@ metadata_coding_ = metadata_coding.get(); leveldb::Status s; - std::tie(db_, s) = IndexedDBDatabase::Create( + std::tie(db_, s) = IndexedDBClassFactory::Get()->CreateIndexedDBDatabase( ASCIIToUTF16("db"), backing_store_.get(), factory_.get(), GetErrorCallback(), base::BindLambdaForTesting([&]() { db_.reset(); @@ -447,7 +447,7 @@ std::make_unique<FakeIndexedDBMetadataCoding>(); metadata_coding_ = metadata_coding.get(); leveldb::Status s; - std::tie(db_, s) = IndexedDBDatabase::Create( + std::tie(db_, s) = IndexedDBClassFactory::Get()->CreateIndexedDBDatabase( ASCIIToUTF16("db"), backing_store_.get(), factory_.get(), GetErrorCallback(), base::BindLambdaForTesting([&]() { db_.reset();
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc index 545b31e..337a095 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
@@ -184,7 +184,6 @@ CreateAndReturnTempDir(&temp_dir_), special_storage_policy_, quota_manager_->proxy(), - indexed_db::GetDefaultLevelDBFactory(), base::DefaultClock::GetInstance())), host_(new IndexedDBDispatcherHost( kFakeProcessId,
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc index 304e7ae..ef9c3bc 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.cc +++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -79,8 +79,17 @@ IndexedDBFactoryImpl::IndexedDBFactoryImpl( IndexedDBContextImpl* context, indexed_db::LevelDBFactory* leveldb_factory, + IndexedDBClassFactory* indexed_db_class_factory, base::Clock* clock) - : context_(context), leveldb_factory_(leveldb_factory), clock_(clock) {} + : context_(context), + leveldb_factory_(leveldb_factory), + indexed_db_class_factory_(indexed_db_class_factory), + clock_(clock) { + DCHECK(context); + DCHECK(leveldb_factory); + DCHECK(indexed_db_class_factory); + DCHECK(clock); +} IndexedDBFactoryImpl::~IndexedDBFactoryImpl() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -189,7 +198,7 @@ return; } std::unique_ptr<IndexedDBDatabase> database; - std::tie(database, s) = IndexedDBDatabase::Create( + std::tie(database, s) = indexed_db_class_factory_->CreateIndexedDBDatabase( name, factory->backing_store(), this, base::BindRepeating(&IndexedDBFactoryImpl::OnDatabaseError, weak_factory_.GetWeakPtr(), origin), @@ -275,7 +284,7 @@ } std::unique_ptr<IndexedDBDatabase> database; - std::tie(database, s) = IndexedDBDatabase::Create( + std::tie(database, s) = indexed_db_class_factory_->CreateIndexedDBDatabase( name, factory->backing_store(), this, base::BindRepeating(&IndexedDBFactoryImpl::OnDatabaseError, weak_factory_.GetWeakPtr(), origin), @@ -573,9 +582,9 @@ IndexedDBBackingStore::Mode backing_store_mode = is_in_memory ? IndexedDBBackingStore::Mode::kInMemory : IndexedDBBackingStore::Mode::kOnDisk; - std::unique_ptr<IndexedDBBackingStore> backing_store = - CreateBackingStore(backing_store_mode, origin, blob_path, - std::move(database), context_->TaskRunner()); + std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore( + backing_store_mode, leveldb_factory_, origin, blob_path, + std::move(database), context_->TaskRunner()); bool first_open_since_startup = backends_opened_since_startup_.insert(origin).second; @@ -587,16 +596,17 @@ return {IndexedDBOriginStateHandle(), s, CreateDefaultError(), data_loss_info}; - it = factories_per_origin_ - .emplace(origin, - std::make_unique<IndexedDBOriginState>( - is_in_memory, clock_, &earliest_sweep_, - base::BindOnce( - &IndexedDBFactoryImpl::RemoveOriginState, - origin_state_destruction_weak_factory_.GetWeakPtr(), - origin), - std::move(backing_store))) - .first; + it = + factories_per_origin_ + .emplace(origin, + std::make_unique<IndexedDBOriginState>( + is_in_memory, clock_, leveldb_factory_, &earliest_sweep_, + base::BindOnce( + &IndexedDBFactoryImpl::RemoveOriginState, + origin_state_destruction_weak_factory_.GetWeakPtr(), + origin), + std::move(backing_store))) + .first; context_->FactoryOpened(origin); return {it->second->CreateHandle(), s, IndexedDBDatabaseError(), data_loss_info}; @@ -604,12 +614,14 @@ std::unique_ptr<IndexedDBBackingStore> IndexedDBFactoryImpl::CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, + indexed_db::LevelDBFactory* leveldb_factory, const url::Origin& origin, const base::FilePath& blob_path, std::unique_ptr<LevelDBDatabase> db, base::SequencedTaskRunner* task_runner) { return std::make_unique<IndexedDBBackingStore>( - backing_store_mode, this, origin, blob_path, std::move(db), task_runner); + backing_store_mode, this, leveldb_factory, origin, blob_path, + std::move(db), task_runner); } void IndexedDBFactoryImpl::RemoveOriginState(const url::Origin& origin) {
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.h b/content/browser/indexed_db/indexed_db_factory_impl.h index 6455764..88a4dcf 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.h +++ b/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -39,6 +39,7 @@ namespace content { class LevelDBDatabase; +class IndexedDBClassFactory; class IndexedDBContextImpl; class IndexedDBFactoryImpl; class IndexedDBOriginState; @@ -47,6 +48,7 @@ public: IndexedDBFactoryImpl(IndexedDBContextImpl* context, indexed_db::LevelDBFactory* leveldb_factory, + IndexedDBClassFactory* indexed_db_class_factory, base::Clock* clock); ~IndexedDBFactoryImpl() override; @@ -131,6 +133,7 @@ // Used by unittests to allow subclassing of IndexedDBBackingStore. virtual std::unique_ptr<IndexedDBBackingStore> CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, + indexed_db::LevelDBFactory* leveldb_factory, const url::Origin& origin, const base::FilePath& blob_path, std::unique_ptr<LevelDBDatabase> db, @@ -177,7 +180,8 @@ SEQUENCE_CHECKER(sequence_checker_); IndexedDBContextImpl* context_; - indexed_db::LevelDBFactory* leveldb_factory_; + indexed_db::LevelDBFactory* const leveldb_factory_; + IndexedDBClassFactory* indexed_db_class_factory_; base::Clock* clock_; base::Time earliest_sweep_;
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc index 133a6de..a393243 100644 --- a/content/browser/indexed_db/indexed_db_factory_unittest.cc +++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -111,7 +111,6 @@ context_ = base::MakeRefCounted<IndexedDBContextImpl>( CreateAndReturnTempDir(&temp_dir_), /*special_storage_policy=*/nullptr, quota_manager_proxy_.get(), - indexed_db::GetDefaultLevelDBFactory(), base::DefaultClock::GetInstance()); context_->SetTaskRunnerForTesting(base::SequencedTaskRunnerHandle::Get()); } @@ -120,7 +119,6 @@ context_ = base::MakeRefCounted<IndexedDBContextImpl>( base::FilePath(), /*special_storage_policy=*/nullptr, quota_manager_proxy_.get(), - indexed_db::GetDefaultLevelDBFactory(), base::DefaultClock::GetInstance()); context_->SetTaskRunnerForTesting(base::SequencedTaskRunnerHandle::Get()); } @@ -129,8 +127,8 @@ base::Clock* clock) { context_ = base::MakeRefCounted<IndexedDBContextImpl>( CreateAndReturnTempDir(&temp_dir_), - /*special_storage_policy=*/nullptr, quota_manager_proxy_.get(), factory, - clock); + /*special_storage_policy=*/nullptr, quota_manager_proxy_.get(), clock); + context_->SetLevelDBFactoryForTesting(factory); context_->SetTaskRunnerForTesting(base::SequencedTaskRunnerHandle::Get()); } @@ -305,7 +303,7 @@ {kIDBTombstoneStatistics}); base::SimpleTestClock clock; clock.SetNow(base::Time::Now()); - SetupContextWithFactories(indexed_db::GetDefaultLevelDBFactory(), &clock); + SetupContextWithFactories(indexed_db::LevelDBFactory::Get(), &clock); const Origin origin = Origin::Create(GURL("http://localhost:81"));
diff --git a/content/browser/indexed_db/indexed_db_fake_backing_store.cc b/content/browser/indexed_db/indexed_db_fake_backing_store.cc index 2217816..a1793434 100644 --- a/content/browser/indexed_db/indexed_db_fake_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_fake_backing_store.cc
@@ -6,6 +6,7 @@ #include "base/files/file_path.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "content/browser/indexed_db/leveldb/leveldb_env.h" namespace content { namespace { @@ -18,6 +19,7 @@ IndexedDBFakeBackingStore::IndexedDBFakeBackingStore() : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kInMemory, nullptr /* indexed_db_factory */, + indexed_db::LevelDBFactory::Get(), url::Origin::Create(GURL("http://localhost:81")), base::FilePath(), std::unique_ptr<LevelDBDatabase>(), @@ -27,6 +29,7 @@ base::SequencedTaskRunner* task_runner) : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kOnDisk, factory, + indexed_db::LevelDBFactory::Get(), url::Origin::Create(GURL("http://localhost:81")), base::FilePath(), std::unique_ptr<LevelDBDatabase>(),
diff --git a/content/browser/indexed_db/indexed_db_leveldb_operations.cc b/content/browser/indexed_db/indexed_db_leveldb_operations.cc index e11fb15..e4a0c0b 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_operations.cc +++ b/content/browser/indexed_db/indexed_db_leveldb_operations.cc
@@ -167,7 +167,7 @@ return {nullptr, status, is_disk_full}; } std::unique_ptr<LevelDBDatabase> database = std::make_unique<LevelDBDatabase>( - std::move(state), std::move(task_runner), + std::move(state), ldb_factory, std::move(task_runner), LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase); ReportOpenStatus( indexed_db::INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS, origin); @@ -747,7 +747,7 @@ // The leveldb database is successfully opened. DCHECK(status.ok()); database = std::make_unique<LevelDBDatabase>( - std::move(state), std::move(task_runner), + std::move(state), ldb_factory, std::move(task_runner), LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase); // Check for previous corruption or invalid schemas.
diff --git a/content/browser/indexed_db/indexed_db_metadata_coding.cc b/content/browser/indexed_db/indexed_db_metadata_coding.cc index 954db45..b645a36 100644 --- a/content/browser/indexed_db/indexed_db_metadata_coding.cc +++ b/content/browser/indexed_db/indexed_db_metadata_coding.cc
@@ -11,6 +11,7 @@ #include "content/browser/indexed_db/indexed_db_reporting.h" #include "content/browser/indexed_db/indexed_db_tracing.h" #include "content/browser/indexed_db/leveldb/leveldb_database.h" +#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" #include "third_party/blink/public/common/indexeddb/indexeddb_metadata.h" @@ -518,7 +519,7 @@ IndexedDBDatabaseMetadata* metadata) { // TODO(jsbell): Don't persist metadata if open fails. http://crbug.com/395472 scoped_refptr<LevelDBTransaction> transaction = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db); + indexed_db::LevelDBFactory::Get()->CreateLevelDBTransaction(db); int64_t row_id = 0; Status s = indexed_db::GetNewDatabaseId(transaction.get(), &row_id);
diff --git a/content/browser/indexed_db/indexed_db_origin_state.cc b/content/browser/indexed_db/indexed_db_origin_state.cc index fefd258b..60a718f3 100644 --- a/content/browser/indexed_db/indexed_db_origin_state.cc +++ b/content/browser/indexed_db/indexed_db_origin_state.cc
@@ -78,11 +78,13 @@ IndexedDBOriginState::IndexedDBOriginState( bool persist_for_incognito, base::Clock* clock, + indexed_db::LevelDBFactory* leveldb_factory, base::Time* earliest_global_sweep_time, base::OnceClosure destruct_myself, std::unique_ptr<IndexedDBBackingStore> backing_store) : persist_for_incognito_(persist_for_incognito), clock_(clock), + leveldb_factory_(leveldb_factory), earliest_global_sweep_time_(earliest_global_sweep_time), lock_manager_(kIndexedDBLockLevelCount), backing_store_(std::move(backing_store)), @@ -297,8 +299,7 @@ // A sweep will happen now, so reset the sweep timers. *earliest_global_sweep_time_ = GenerateNextGlobalSweepTime(now); scoped_refptr<LevelDBTransaction> txn = - IndexedDBClassFactory::Get()->CreateLevelDBTransaction( - backing_store_->db()); + leveldb_factory_->CreateLevelDBTransaction(backing_store_->db()); indexed_db::SetEarliestSweepTime(txn.get(), GenerateNextOriginSweepTime(now)); s = txn->Commit();
diff --git a/content/browser/indexed_db/indexed_db_origin_state.h b/content/browser/indexed_db/indexed_db_origin_state.h index 654cd93..642b4e8 100644 --- a/content/browser/indexed_db/indexed_db_origin_state.h +++ b/content/browser/indexed_db/indexed_db_origin_state.h
@@ -28,6 +28,10 @@ class IndexedDBFactoryImpl; class IndexedDBPreCloseTaskQueue; +namespace indexed_db { +class LevelDBFactory; +} // namespace indexed_db + CONTENT_EXPORT extern const base::Feature kIDBTombstoneStatistics; CONTENT_EXPORT extern const base::Feature kIDBTombstoneDeletion; @@ -78,6 +82,7 @@ // |earliest_global_sweep_time| is expected to outlive this object. IndexedDBOriginState(bool persist_for_incognito, base::Clock* clock, + indexed_db::LevelDBFactory* leveldb_factory, base::Time* earliest_global_sweep_time, base::OnceClosure destruct_myself, std::unique_ptr<IndexedDBBackingStore> backing_store); @@ -161,6 +166,7 @@ bool has_blobs_outstanding_ = false; bool skip_closing_sequence_ = false; base::Clock* clock_; + indexed_db::LevelDBFactory* const leveldb_factory_; // This is safe because it is owned by IndexedDBFactoryImpl, which owns this // object. base::Time* earliest_global_sweep_time_;
diff --git a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc index 0b44567..60672bbc6 100644 --- a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc +++ b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -19,7 +19,6 @@ #include "base/time/default_clock.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_quota_client.h" -#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/public/browser/storage_partition.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -59,7 +58,6 @@ idb_context_ = new IndexedDBContextImpl( browser_context_->GetPath(), browser_context_->GetSpecialStoragePolicy(), quota_manager->proxy(), - indexed_db::GetDefaultLevelDBFactory(), base::DefaultClock::GetInstance()); base::RunLoop().RunUntilIdle(); setup_temp_dir();
diff --git a/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc b/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc index c31c8f2..e2b82fde 100644 --- a/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc +++ b/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc
@@ -140,12 +140,12 @@ scoped_refptr<LevelDBState> level_db_state; leveldb::Status s; std::tie(level_db_state, s, std::ignore) = - indexed_db::GetDefaultLevelDBFactory()->OpenLevelDBState( + indexed_db::LevelDBFactory::Get()->OpenLevelDBState( base::FilePath(), indexed_db::GetDefaultIndexedDBComparator(), indexed_db::GetDefaultLevelDBComparator()); ASSERT_TRUE(s.ok()); in_memory_db_ = std::make_unique<LevelDBDatabase>( - std::move(level_db_state), nullptr, + std::move(level_db_state), indexed_db::LevelDBFactory::Get(), nullptr, LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase); sweeper_ = std::make_unique<IndexedDBTombstoneSweeper>( GetParam(), kRoundIterations, kMaxIterations, in_memory_db_->db());
diff --git a/content/browser/indexed_db/indexed_db_transaction_unittest.cc b/content/browser/indexed_db/indexed_db_transaction_unittest.cc index 3621a19..c08d75b8 100644 --- a/content/browser/indexed_db/indexed_db_transaction_unittest.cc +++ b/content/browser/indexed_db/indexed_db_transaction_unittest.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "content/browser/indexed_db/fake_indexed_db_metadata_coding.h" +#include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_connection.h" #include "content/browser/indexed_db/indexed_db_database_error.h" #include "content/browser/indexed_db/indexed_db_factory_impl.h" @@ -59,7 +60,7 @@ // "peculiarity of C++". More info at // https://github.com/google/googletest/blob/master/googletest/docs/FAQ.md#my-compiler-complains-that-a-constructor-or-destructor-cannot-return-a-value-whats-going-on leveldb::Status s; - std::tie(db_, s) = IndexedDBDatabase::Create( + std::tie(db_, s) = IndexedDBClassFactory::Get()->CreateIndexedDBDatabase( base::ASCIIToUTF16("db"), backing_store_.get(), factory_.get(), GetErrorCallback(), base::BindLambdaForTesting([&]() { db_.reset(); }), std::make_unique<FakeIndexedDBMetadataCoding>(), @@ -87,8 +88,9 @@ std::unique_ptr<IndexedDBConnection> CreateConnection(int process_id) { return std::unique_ptr<IndexedDBConnection>( std::make_unique<IndexedDBConnection>( - kFakeProcessId, IndexedDBOriginStateHandle(), db_->AsWeakPtr(), - base::DoNothing(), base::DoNothing(), GetErrorCallback(), + kFakeProcessId, IndexedDBOriginStateHandle(), + IndexedDBClassFactory::Get(), db_->AsWeakPtr(), base::DoNothing(), + base::DoNothing(), GetErrorCallback(), new MockIndexedDBDatabaseCallbacks())); }
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index 53f0fe8d..ae047b4 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -90,7 +90,6 @@ CreateAndReturnTempDir(&temp_dir_), /*special_storage_policy=*/special_storage_policy_.get(), quota_manager_proxy_.get(), - indexed_db::GetDefaultLevelDBFactory(), base::DefaultClock::GetInstance())) { special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin.GetURL()); }
diff --git a/content/browser/indexed_db/leveldb/leveldb_database.cc b/content/browser/indexed_db/leveldb/leveldb_database.cc index 96ca28b..6c35875 100644 --- a/content/browser/indexed_db/leveldb/leveldb_database.cc +++ b/content/browser/indexed_db/leveldb/leveldb_database.cc
@@ -75,9 +75,11 @@ LevelDBDatabase::LevelDBDatabase( scoped_refptr<LevelDBState> level_db_state, + indexed_db::LevelDBFactory* class_factory, scoped_refptr<base::SequencedTaskRunner> task_runner, size_t max_open_iterators) : level_db_state_(std::move(level_db_state)), + class_factory_(class_factory), clock_(new base::DefaultClock()), iterator_lru_(max_open_iterators) { if (task_runner) { @@ -176,8 +178,7 @@ // for the iterator until it's first Seek call. std::unique_ptr<leveldb::Iterator> i(db()->NewIterator(options)); return std::unique_ptr<LevelDBIterator>( - IndexedDBClassFactory::Get()->CreateIteratorImpl(std::move(i), this, - options.snapshot)); + class_factory_->CreateIteratorImpl(std::move(i), this, options.snapshot)); } void LevelDBDatabase::Compact(const base::StringPiece& start,
diff --git a/content/browser/indexed_db/leveldb/leveldb_database.h b/content/browser/indexed_db/leveldb/leveldb_database.h index 7a204d9..b68f2f0 100644 --- a/content/browser/indexed_db/leveldb/leveldb_database.h +++ b/content/browser/indexed_db/leveldb/leveldb_database.h
@@ -32,12 +32,15 @@ } namespace content { - class LevelDBComparator; class LevelDBDatabase; class LevelDBIterator; class LevelDBWriteBatch; +namespace indexed_db { +class LevelDBFactory; +} // namespace indexed_db + class LevelDBSnapshot { private: friend class LevelDBDatabase; @@ -62,6 +65,7 @@ // |max_open_cursors| cannot be 0. // All calls to this class should be done on |task_runner|. LevelDBDatabase(scoped_refptr<LevelDBState> level_db_state, + indexed_db::LevelDBFactory* factory, scoped_refptr<base::SequencedTaskRunner> task_runner, size_t max_open_iterators); @@ -95,6 +99,10 @@ leveldb::Env* env() { return level_db_state_->in_memory_env(); } base::Time LastModified() const { return last_modified_; } + indexed_db::LevelDBFactory* leveldb_class_factory() const { + return class_factory_; + } + void SetClockForTesting(std::unique_ptr<base::Clock> clock); private: @@ -111,6 +119,7 @@ void CloseDatabase(); scoped_refptr<LevelDBState> level_db_state_; + indexed_db::LevelDBFactory* class_factory_; base::Time last_modified_; std::unique_ptr<base::Clock> clock_;
diff --git a/content/browser/indexed_db/leveldb/leveldb_env.cc b/content/browser/indexed_db/leveldb/leveldb_env.cc index 926fd3f0..1ea3e9b 100644 --- a/content/browser/indexed_db/leveldb/leveldb_env.cc +++ b/content/browser/indexed_db/leveldb/leveldb_env.cc
@@ -11,6 +11,8 @@ #include "content/browser/indexed_db/indexed_db_leveldb_operations.h" #include "content/browser/indexed_db/indexed_db_reporting.h" #include "content/browser/indexed_db/indexed_db_tracing.h" +#include "content/browser/indexed_db/leveldb/leveldb_iterator_impl.h" +#include "content/browser/indexed_db/leveldb/leveldb_transaction.h" #include "third_party/leveldatabase/leveldb_chrome.h" #include "third_party/leveldatabase/src/include/leveldb/filter_policy.h" @@ -46,6 +48,22 @@ return options; } +static LevelDBFactory::GetterCallback* s_ldb_factory_getter; + +// static +LevelDBFactory* LevelDBFactory::Get() { + static base::NoDestructor<DefaultLevelDBFactory> singleton; + if (s_ldb_factory_getter) + return (*s_ldb_factory_getter)(); + return singleton.get(); +} + +// static +void LevelDBFactory::SetFactoryGetterForTesting( + LevelDBFactory::GetterCallback* cb) { + s_ldb_factory_getter = cb; +} + std::tuple<std::unique_ptr<leveldb::DB>, leveldb::Status> DefaultLevelDBFactory::OpenDB(const leveldb_env::Options& options, const std::string& name) { @@ -129,6 +147,19 @@ status, false}; } +scoped_refptr<LevelDBTransaction> +DefaultLevelDBFactory::CreateLevelDBTransaction(LevelDBDatabase* db) { + return base::WrapRefCounted(new LevelDBTransaction(db)); +} + +std::unique_ptr<LevelDBIteratorImpl> DefaultLevelDBFactory::CreateIteratorImpl( + std::unique_ptr<leveldb::Iterator> iterator, + LevelDBDatabase* db, + const leveldb::Snapshot* snapshot) { + return base::WrapUnique( + new LevelDBIteratorImpl(std::move(iterator), db, snapshot)); +} + leveldb::Status DefaultLevelDBFactory::DestroyLevelDB( scoped_refptr<LevelDBState> level_db_state) { DCHECK(level_db_state); @@ -153,11 +184,5 @@ return leveldb::DestroyDB(path.AsUTF8Unsafe(), options); } -// static -DefaultLevelDBFactory* GetDefaultLevelDBFactory() { - static base::NoDestructor<DefaultLevelDBFactory> singleton; - return singleton.get(); -} - } // namespace indexed_db } // namespace content
diff --git a/content/browser/indexed_db/leveldb/leveldb_env.h b/content/browser/indexed_db/leveldb/leveldb_env.h index 93c1a4a34..ea81437 100644 --- a/content/browser/indexed_db/leveldb/leveldb_env.h +++ b/content/browser/indexed_db/leveldb/leveldb_env.h
@@ -24,7 +24,15 @@ class NoDestructor; } +namespace leveldb { +class Iterator; +class Snapshot; +} // namespace leveldb + namespace content { +class LevelDBIteratorImpl; +class LevelDBDatabase; +class LevelDBTransaction; // The leveldb::Env used by the Indexed DB backend. class LevelDBEnv : public leveldb_env::ChromiumEnv { @@ -51,6 +59,15 @@ // for tests. class CONTENT_EXPORT LevelDBFactory { public: + using GetterCallback = LevelDBFactory*(); + + // Returns a singleton factory, which can be customized below for testing. + // Note: it is best to avoid using this method, and instead acquiring a + // LevelDBFactory through dependency injection. + static LevelDBFactory* Get(); + + static void SetFactoryGetterForTesting(LevelDBFactory::GetterCallback* cb); + virtual ~LevelDBFactory() = default; virtual std::tuple<std::unique_ptr<leveldb::DB>, leveldb::Status> OpenDB( @@ -66,6 +83,14 @@ const LevelDBComparator* idb_comparator, const leveldb::Comparator* ldb_comparator) = 0; + virtual std::unique_ptr<LevelDBIteratorImpl> CreateIteratorImpl( + std::unique_ptr<leveldb::Iterator> iterator, + LevelDBDatabase* db, + const leveldb::Snapshot* snapshot) = 0; + + virtual scoped_refptr<LevelDBTransaction> CreateLevelDBTransaction( + LevelDBDatabase* db) = 0; + // A somewhat safe way to destroy a leveldb database. This asserts that there // are no other references to the given LevelDBState, and deletes the database // on disk. |level_db_state| must only have one ref. @@ -89,14 +114,17 @@ OpenLevelDBState(const base::FilePath& file_name, const LevelDBComparator* idb_comparator, const leveldb::Comparator* ldb_comparator) override; + std::unique_ptr<LevelDBIteratorImpl> CreateIteratorImpl( + std::unique_ptr<leveldb::Iterator> iterator, + LevelDBDatabase* db, + const leveldb::Snapshot* snapshot) override; + scoped_refptr<LevelDBTransaction> CreateLevelDBTransaction( + LevelDBDatabase* db) override; leveldb::Status DestroyLevelDB( scoped_refptr<LevelDBState> output_state) override; leveldb::Status DestroyLevelDB(const base::FilePath& path) override; }; -// Returns a singleton default factory. -CONTENT_EXPORT DefaultLevelDBFactory* GetDefaultLevelDBFactory(); - } // namespace indexed_db } // namespace content
diff --git a/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h b/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h index 5ebfdd3..93166cb 100644 --- a/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h +++ b/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h
@@ -20,6 +20,10 @@ namespace content { class LevelDBDatabase; +namespace indexed_db { +class DefaultLevelDBFactory; +} // namespace indexed_db + class CONTENT_EXPORT LevelDBIteratorImpl : public content::LevelDBIterator { public: ~LevelDBIteratorImpl() override; @@ -46,7 +50,7 @@ // Notifies the database of iterator usage and recreates iterator if needed. void WillUseDBIterator(); - friend class IndexedDBClassFactory; + friend class indexed_db::DefaultLevelDBFactory; friend class MockBrowserTestIndexedDBClassFactory; std::unique_ptr<leveldb::Iterator> iterator_;
diff --git a/content/browser/indexed_db/leveldb/leveldb_transaction.h b/content/browser/indexed_db/leveldb/leveldb_transaction.h index 5586fd3..ae80c15 100644 --- a/content/browser/indexed_db/leveldb/leveldb_transaction.h +++ b/content/browser/indexed_db/leveldb/leveldb_transaction.h
@@ -21,6 +21,10 @@ namespace content { class LevelDBWriteBatch; +namespace indexed_db { +class DefaultLevelDBFactory; +} // namespace indexed_db + class CONTENT_EXPORT LevelDBTransaction : public base::RefCounted<LevelDBTransaction> { public: @@ -45,7 +49,7 @@ protected: virtual ~LevelDBTransaction(); explicit LevelDBTransaction(LevelDBDatabase* db); - friend class IndexedDBClassFactory; + friend class indexed_db::DefaultLevelDBFactory; private: friend class base::RefCounted<LevelDBTransaction>;
diff --git a/content/browser/indexed_db/leveldb/leveldb_transaction_unittest.cc b/content/browser/indexed_db/leveldb/leveldb_transaction_unittest.cc index ad8af3a..13e690f8 100644 --- a/content/browser/indexed_db/leveldb/leveldb_transaction_unittest.cc +++ b/content/browser/indexed_db/leveldb/leveldb_transaction_unittest.cc
@@ -37,14 +37,15 @@ scoped_refptr<LevelDBState> ldb_state; leveldb::Status status; std::tie(ldb_state, status, std::ignore) = - indexed_db::GetDefaultLevelDBFactory()->OpenLevelDBState( + indexed_db::LevelDBFactory::Get()->OpenLevelDBState( temp_directory_.GetPath(), LevelDBComparator::BytewiseComparator(), leveldb::BytewiseComparator()); EXPECT_TRUE(status.ok()); ASSERT_TRUE(ldb_state); ASSERT_TRUE(ldb_state->db()); - leveldb_ = std::make_unique<LevelDBDatabase>(std::move(ldb_state), nullptr, - kTestingMaxOpenCursors); + leveldb_ = std::make_unique<LevelDBDatabase>( + std::move(ldb_state), indexed_db::LevelDBFactory::Get(), nullptr, + kTestingMaxOpenCursors); ASSERT_TRUE(leveldb_); } void TearDown() override {}
diff --git a/content/browser/indexed_db/leveldb/leveldb_unittest.cc b/content/browser/indexed_db/leveldb/leveldb_unittest.cc index d371e9c..42214f1 100644 --- a/content/browser/indexed_db/leveldb/leveldb_unittest.cc +++ b/content/browser/indexed_db/leveldb/leveldb_unittest.cc
@@ -64,7 +64,7 @@ std::tuple<scoped_refptr<LevelDBState>, leveldb::Status, bool /* disk_full*/> OpenLevelDB(base::FilePath file_name) { - return indexed_db::GetDefaultLevelDBFactory()->OpenLevelDBState( + return indexed_db::LevelDBFactory::Get()->OpenLevelDBState( file_name, SimpleComparator::Get(), SimpleLDBComparator::Get()); } @@ -82,8 +82,9 @@ OpenLevelDB(temp_directory.GetPath()); EXPECT_TRUE(status.ok()); - std::unique_ptr<LevelDBDatabase> leveldb = std::make_unique<LevelDBDatabase>( - std::move(ldb_state), nullptr, kDefaultMaxOpenIteratorsPerDatabase); + std::unique_ptr<LevelDBDatabase> leveldb = + std::make_unique<LevelDBDatabase>(std::move(ldb_state), nullptr, nullptr, + kDefaultMaxOpenIteratorsPerDatabase); EXPECT_TRUE(leveldb); put_value = value; status = leveldb->Put(key, &put_value); @@ -94,8 +95,9 @@ std::tie(ldb_state, status, std::ignore) = OpenLevelDB(temp_directory.GetPath()); EXPECT_TRUE(status.ok()); - leveldb = std::make_unique<LevelDBDatabase>( - std::move(ldb_state), nullptr, kDefaultMaxOpenIteratorsPerDatabase); + leveldb = + std::make_unique<LevelDBDatabase>(std::move(ldb_state), nullptr, nullptr, + kDefaultMaxOpenIteratorsPerDatabase); EXPECT_TRUE(leveldb); bool found = false; status = leveldb->Get(key, &got_value, &found); @@ -113,15 +115,16 @@ EXPECT_FALSE(status.ok()); EXPECT_TRUE(status.IsCorruption()); - status = indexed_db::GetDefaultLevelDBFactory()->DestroyLevelDB( + status = indexed_db::LevelDBFactory::Get()->DestroyLevelDB( temp_directory.GetPath()); EXPECT_TRUE(status.ok()); std::tie(ldb_state, status, std::ignore) = OpenLevelDB(temp_directory.GetPath()); EXPECT_TRUE(status.ok()); - leveldb = std::make_unique<LevelDBDatabase>( - std::move(ldb_state), nullptr, kDefaultMaxOpenIteratorsPerDatabase); + leveldb = + std::make_unique<LevelDBDatabase>(std::move(ldb_state), nullptr, nullptr, + kDefaultMaxOpenIteratorsPerDatabase); ASSERT_TRUE(leveldb); status = leveldb->Get(key, &got_value, &found); EXPECT_TRUE(status.ok()); @@ -166,8 +169,9 @@ std::tie(ldb_state, status, std::ignore) = OpenLevelDB(base::FilePath()); EXPECT_TRUE(status.ok()); - std::unique_ptr<LevelDBDatabase> leveldb = std::make_unique<LevelDBDatabase>( - std::move(ldb_state), nullptr, kDefaultMaxOpenIteratorsPerDatabase); + std::unique_ptr<LevelDBDatabase> leveldb = + std::make_unique<LevelDBDatabase>(std::move(ldb_state), nullptr, nullptr, + kDefaultMaxOpenIteratorsPerDatabase); ASSERT_TRUE(leveldb); leveldb->SetClockForTesting(std::move(test_clock)); // Calling |Put| sets time modified.
diff --git a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc index 7f7fafb2..10609f4 100644 --- a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc +++ b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc
@@ -53,6 +53,7 @@ const base::string16& name, IndexedDBBackingStore* backing_store, IndexedDBFactory* factory, + IndexedDBClassFactory* class_factory, ErrorCallback error_callback, base::OnceClosure destroy_me, std::unique_ptr<IndexedDBMetadataCoding> metadata_coding, @@ -61,6 +62,7 @@ : IndexedDBDatabase(name, backing_store, factory, + class_factory, std::move(error_callback), std::move(destroy_me), std::move(metadata_coding), @@ -272,7 +274,7 @@ MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() { } -std::unique_ptr<IndexedDBDatabase> +std::pair<std::unique_ptr<IndexedDBDatabase>, leveldb::Status> MockBrowserTestIndexedDBClassFactory::CreateIndexedDBDatabase( const base::string16& name, IndexedDBBackingStore* backing_store, @@ -282,10 +284,15 @@ std::unique_ptr<IndexedDBMetadataCoding> metadata_coding, const IndexedDBDatabase::Identifier& unique_identifier, ScopesLockManager* transaction_lock_manager) { - return std::make_unique<IndexedDBTestDatabase>( - name, backing_store, factory, std::move(error_callback), - std::move(destroy_me), std::move(metadata_coding), unique_identifier, - transaction_lock_manager); + std::unique_ptr<IndexedDBTestDatabase> database = + std::make_unique<IndexedDBTestDatabase>( + name, backing_store, factory, this, std::move(error_callback), + std::move(destroy_me), std::move(metadata_coding), unique_identifier, + transaction_lock_manager); + leveldb::Status s = database->OpenInternal(); + if (!s.ok()) + database.reset(); + return {std::move(database), s}; } std::unique_ptr<IndexedDBTransaction> @@ -318,7 +325,7 @@ failure_method_, fail_on_call_num_[FAIL_CLASS_LEVELDB_TRANSACTION]); } else { - return IndexedDBClassFactory::CreateLevelDBTransaction(db); + return DefaultLevelDBFactory::CreateLevelDBTransaction(db); } } } @@ -342,8 +349,8 @@ std::move(iterator), db, snapshot, failure_method_, fail_on_call_num_[FAIL_CLASS_LEVELDB_ITERATOR]); } else { - return base::WrapUnique( - new LevelDBIteratorImpl(std::move(iterator), db, snapshot)); + return DefaultLevelDBFactory::CreateIteratorImpl(std::move(iterator), db, + snapshot); } } }
diff --git a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h index 381251a6..acf1405 100644 --- a/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h +++ b/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h
@@ -14,6 +14,7 @@ #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_database.h" +#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/browser/indexed_db/scopes/scopes_lock_manager.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" @@ -38,16 +39,15 @@ FAIL_METHOD_SEEK, }; -// TODO(dmurph): Remove the need for this class. We should be solving these -// problems with dependency injection, factories, using a failing fake leveldb -// database, or test-specific settings (like -// SetUsableMessageSizeInBytesForTesting). -class MockBrowserTestIndexedDBClassFactory : public IndexedDBClassFactory { +class MockBrowserTestIndexedDBClassFactory + : public IndexedDBClassFactory, + public indexed_db::DefaultLevelDBFactory { public: MockBrowserTestIndexedDBClassFactory(); ~MockBrowserTestIndexedDBClassFactory() override; - std::unique_ptr<IndexedDBDatabase> CreateIndexedDBDatabase( + std::pair<std::unique_ptr<IndexedDBDatabase>, leveldb::Status> + CreateIndexedDBDatabase( const base::string16& name, IndexedDBBackingStore* backing_store, IndexedDBFactory* factory, @@ -63,6 +63,7 @@ const std::set<int64_t>& scope, blink::mojom::IDBTransactionMode mode, IndexedDBBackingStore::Transaction* backing_store_transaction) override; + scoped_refptr<LevelDBTransaction> CreateLevelDBTransaction( LevelDBDatabase* db) override; std::unique_ptr<LevelDBIteratorImpl> CreateIteratorImpl(
diff --git a/content/browser/indexed_db/scopes/leveldb_scopes_test_utils.cc b/content/browser/indexed_db/scopes/leveldb_scopes_test_utils.cc index 0dd6eb7..0174bfa 100644 --- a/content/browser/indexed_db/scopes/leveldb_scopes_test_utils.cc +++ b/content/browser/indexed_db/scopes/leveldb_scopes_test_utils.cc
@@ -39,7 +39,7 @@ } leveldb_.reset(); if (temp_directory_.IsValid()) { - indexed_db::GetDefaultLevelDBFactory()->DestroyLevelDB( + indexed_db::LevelDBFactory::Get()->DestroyLevelDB( temp_directory_.GetPath()); ASSERT_TRUE(temp_directory_.Delete()); } @@ -52,7 +52,7 @@ ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); leveldb::Status status; std::tie(leveldb_, status, std::ignore) = - indexed_db::GetDefaultLevelDBFactory()->OpenLevelDBState( + indexed_db::LevelDBFactory::Get()->OpenLevelDBState( temp_directory_.GetPath(), LevelDBComparator::BytewiseComparator(), leveldb::BytewiseComparator()); ASSERT_TRUE(status.ok());
diff --git a/content/browser/loader/cross_origin_read_blocking_checker.cc b/content/browser/loader/cross_origin_read_blocking_checker.cc index 3aee65b7..22b9e7a 100644 --- a/content/browser/loader/cross_origin_read_blocking_checker.cc +++ b/content/browser/loader/cross_origin_read_blocking_checker.cc
@@ -29,7 +29,7 @@ corb_analyzer_ = std::make_unique<network::CrossOriginReadBlocking::ResponseAnalyzer>( request.url, request.request_initiator, response, - request_initiator_site_lock, request.fetch_request_mode); + request_initiator_site_lock, request.mode); if (corb_analyzer_->ShouldBlock()) { OnBlocked(); return;
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc index fe50cc2..82b6a80 100644 --- a/content/browser/loader/cross_site_document_blocking_browsertest.cc +++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -311,8 +311,8 @@ request_initiator_to_inject_ = request_initiator; } - void InjectFetchMode(network::mojom::FetchRequestMode fetch_mode) { - fetch_mode_to_inject_ = fetch_mode; + void InjectFetchMode(network::mojom::RequestMode request_mode) { + request_mode_to_inject_ = request_mode; } private: @@ -371,8 +371,8 @@ // Modify |params| if requested. if (request_initiator_to_inject_.has_value()) params->url_request.request_initiator = request_initiator_to_inject_; - if (fetch_mode_to_inject_.has_value()) - params->url_request.fetch_request_mode = fetch_mode_to_inject_.value(); + if (request_mode_to_inject_.has_value()) + params->url_request.mode = request_mode_to_inject_.value(); // Inject |test_client_| into the request. DCHECK(!original_client_); @@ -439,7 +439,7 @@ URLLoaderInterceptor interceptor_; base::Optional<url::Origin> request_initiator_to_inject_; - base::Optional<network::mojom::FetchRequestMode> fetch_mode_to_inject_; + base::Optional<network::mojom::RequestMode> request_mode_to_inject_; // |test_client_ptr_info_| below is used to transition results of // |test_client_.CreateInterfacePtr()| into IO thread. @@ -1110,7 +1110,7 @@ } // Tests that renderer will be terminated if it asks AppCache to initiate a -// cross-origin request with network::mojom::FetchRequestMode::kNavigate. +// cross-origin request with network::mojom::RequestMode::kNavigate. IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, AppCache_NoNavigationsEnforcement) { embedded_test_server()->StartAcceptingConnections(); @@ -1134,7 +1134,7 @@ // RenderFrameHostImpl is created. GURL cross_site_url("http://cross-origin.com/site_isolation/nosniff.json"); RequestInterceptor interceptor(cross_site_url); - interceptor.InjectFetchMode(network::mojom::FetchRequestMode::kNavigate); + interceptor.InjectFetchMode(network::mojom::RequestMode::kNavigate); // Load the main page twice. The second navigation should have AppCache // initialized for the page.
diff --git a/content/browser/loader/cross_site_document_resource_handler.cc b/content/browser/loader/cross_site_document_resource_handler.cc index d514c10..d05076c 100644 --- a/content/browser/loader/cross_site_document_resource_handler.cc +++ b/content/browser/loader/cross_site_document_resource_handler.cc
@@ -221,10 +221,10 @@ CrossSiteDocumentResourceHandler::CrossSiteDocumentResourceHandler( std::unique_ptr<ResourceHandler> next_handler, net::URLRequest* request, - network::mojom::FetchRequestMode fetch_request_mode) + network::mojom::RequestMode request_mode) : LayeredResourceHandler(request, std::move(next_handler)), weak_next_handler_(next_handler_.get()), - fetch_request_mode_(fetch_request_mode), + request_mode_(request_mode), weak_this_(this) {} CrossSiteDocumentResourceHandler::~CrossSiteDocumentResourceHandler() {} @@ -237,7 +237,7 @@ if (network::CrossOriginResourcePolicy::kBlock == network::CrossOriginResourcePolicy::Verify( request()->url(), request()->initiator(), response->head, - fetch_request_mode_, kNonNetworkServiceInitiatorLock)) { + request_mode_, kNonNetworkServiceInitiatorLock)) { blocked_read_completed_ = true; blocked_by_cross_origin_resource_policy_ = true; controller->Cancel(); @@ -257,7 +257,7 @@ if (network::CrossOriginResourcePolicy::kBlock == network::CrossOriginResourcePolicy::Verify( request()->url(), request()->initiator(), response->head, - fetch_request_mode_, kNonNetworkServiceInitiatorLock)) { + request_mode_, kNonNetworkServiceInitiatorLock)) { blocked_read_completed_ = true; blocked_by_cross_origin_resource_policy_ = true; controller->Cancel(); @@ -638,7 +638,7 @@ analyzer_ = std::make_unique<network::CrossOriginReadBlocking::ResponseAnalyzer>( request()->url(), request()->initiator(), response.head, - kNonNetworkServiceInitiatorLock, fetch_request_mode_); + kNonNetworkServiceInitiatorLock, request_mode_); if (analyzer_->ShouldAllow()) return false; @@ -665,7 +665,7 @@ // additionally PDF doesn't _really_ make *cross*-origin requests - it just // seems that way because of the usage of the Chrome extension). if (info->GetResourceType() == ResourceType::kPluginResource && - fetch_request_mode_ == network::mojom::FetchRequestMode::kNoCors && + request_mode_ == network::mojom::RequestMode::kNoCors && network::CrossOriginReadBlocking::ShouldAllowForPlugin( info->GetChildID())) { return false;
diff --git a/content/browser/loader/cross_site_document_resource_handler.h b/content/browser/loader/cross_site_document_resource_handler.h index bb39be8..dd5fa1304 100644 --- a/content/browser/loader/cross_site_document_resource_handler.h +++ b/content/browser/loader/cross_site_document_resource_handler.h
@@ -60,7 +60,7 @@ CrossSiteDocumentResourceHandler( std::unique_ptr<ResourceHandler> next_handler, net::URLRequest* request, - network::mojom::FetchRequestMode fetch_request_mode); + network::mojom::RequestMode request_mode); ~CrossSiteDocumentResourceHandler() override; // LayeredResourceHandler overrides: @@ -144,7 +144,7 @@ std::unique_ptr<network::CrossOriginReadBlocking::ResponseAnalyzer> analyzer_; // Fetch request mode (e.g. 'no-cors' VS 'cors' VS 'same-origin', etc.). - network::mojom::FetchRequestMode fetch_request_mode_; + network::mojom::RequestMode request_mode_; // Tracks whether OnResponseStarted has been called, to ensure that it happens // before OnWillRead and OnReadCompleted.
diff --git a/content/browser/loader/cross_site_document_resource_handler_unittest.cc b/content/browser/loader/cross_site_document_resource_handler_unittest.cc index 323c46f..c0b60b7 100644 --- a/content/browser/loader/cross_site_document_resource_handler_unittest.cc +++ b/content/browser/loader/cross_site_document_resource_handler_unittest.cc
@@ -1197,11 +1197,11 @@ stream_sink_ = stream_sink->GetWeakPtr(); // Create the CrossSiteDocumentResourceHandler. - auto fetch_request_mode = cors_request == OriginHeader::kOmit - ? network::mojom::FetchRequestMode::kNoCors - : network::mojom::FetchRequestMode::kCors; + auto request_mode = cors_request == OriginHeader::kOmit + ? network::mojom::RequestMode::kNoCors + : network::mojom::RequestMode::kCors; auto document_blocker = std::make_unique<CrossSiteDocumentResourceHandler>( - std::move(stream_sink), request_.get(), fetch_request_mode); + std::move(stream_sink), request_.get(), request_mode); document_blocker_ = document_blocker.get(); first_handler_ = std::move(document_blocker);
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index fa94e2e05..d9d6c73 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -228,10 +228,9 @@ new_request->has_user_gesture = request_info->common_params.has_user_gesture; new_request->enable_load_timing = true; - new_request->fetch_request_mode = network::mojom::FetchRequestMode::kNavigate; - new_request->fetch_credentials_mode = - network::mojom::FetchCredentialsMode::kInclude; - new_request->fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual; + new_request->mode = network::mojom::RequestMode::kNavigate; + new_request->credentials_mode = network::mojom::CredentialsMode::kInclude; + new_request->redirect_mode = network::mojom::RedirectMode::kManual; new_request->fetch_request_context_type = static_cast<int>(request_info->begin_params->request_context_type); new_request->upgrade_if_insecure = request_info->upgrade_if_insecure; @@ -1584,9 +1583,8 @@ std::make_unique<FileURLLoaderFactory>( partition->browser_context()->GetPath(), partition->browser_context()->GetSharedCorsOriginAccessList(), - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); + // USER_VISIBLE because loaded file resources may affect the UI. + base::TaskPriority::USER_VISIBLE); if (frame_tree_node) { // May be nullptr in some unit tests. devtools_instrumentation::WillCreateURLLoaderFactory(
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 89e10f6..c4db9c9 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1045,7 +1045,7 @@ return AddStandardHandlers( request, static_cast<ResourceType>(request_data.resource_type), - resource_context, request_data.fetch_request_mode, + resource_context, request_data.mode, static_cast<blink::mojom::RequestContextType>( request_data.fetch_request_context_type), url_loader_options, requester_info->appcache_service(), child_id, @@ -1057,7 +1057,7 @@ net::URLRequest* request, ResourceType resource_type, ResourceContext* resource_context, - network::mojom::FetchRequestMode fetch_request_mode, + network::mojom::RequestMode request_mode, blink::mojom::RequestContextType fetch_request_context_type, uint32_t url_loader_options, AppCacheService* appcache_service, @@ -1119,8 +1119,8 @@ if (!IsResourceTypeFrame(resource_type)) { // Add a handler to block cross-site documents from the renderer process. - handler.reset(new CrossSiteDocumentResourceHandler( - std::move(handler), request, fetch_request_mode)); + handler.reset(new CrossSiteDocumentResourceHandler(std::move(handler), + request, request_mode)); } // Insert a buffered event handler to sniff the mime type. @@ -1545,7 +1545,7 @@ // by the ResourceScheduler. currently it's a no-op. handler = AddStandardHandlers( new_request.get(), resource_type, resource_context, - network::mojom::FetchRequestMode::kNoCors, + network::mojom::RequestMode::kNoCors, info.begin_params->request_context_type, url_loader_options, appcache_handle_core ? appcache_handle_core->GetAppCacheService() : nullptr,
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h index fc20c92..e6f8e75 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.h +++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -568,7 +568,7 @@ net::URLRequest* request, ResourceType resource_type, ResourceContext* resource_context, - network::mojom::FetchRequestMode fetch_request_mode, + network::mojom::RequestMode request_mode, blink::mojom::RequestContextType fetch_request_context_type, uint32_t url_loader_options, AppCacheService* appcache_service, @@ -617,7 +617,7 @@ static void RecordFetchRequestMode(const GURL& url, base::StringPiece method, - network::mojom::FetchRequestMode mode); + network::mojom::RequestMode request_mode); static net::NetworkTrafficAnnotationTag GetTrafficAnnotation();
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc index d698c59..75a05f47 100644 --- a/content/browser/permissions/permission_service_impl.cc +++ b/content/browser/permissions/permission_service_impl.cc
@@ -18,6 +18,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/render_frame_host.h" +#include "third_party/blink/public/mojom/permissions/permission.mojom-shared.h" using blink::mojom::PermissionDescriptorPtr; using blink::mojom::PermissionName; @@ -91,6 +92,22 @@ case PermissionName::PERIODIC_BACKGROUND_SYNC: *permission_type = PermissionType::PERIODIC_BACKGROUND_SYNC; return true; + case PermissionName::WAKE_LOCK: + if (descriptor->extension && descriptor->extension->is_wake_lock()) { + switch (descriptor->extension->get_wake_lock()->type) { + case blink::mojom::WakeLockType::kScreen: + *permission_type = PermissionType::WAKE_LOCK_SCREEN; + break; + case blink::mojom::WakeLockType::kSystem: + *permission_type = PermissionType::WAKE_LOCK_SYSTEM; + break; + default: + NOTREACHED(); + return false; + } + return true; + } + break; } NOTREACHED();
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 23a4833..21a19bd 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -340,11 +340,9 @@ void OnDisplayChanged(const display::Display& display) override; void BeginKeyboardEvent() override; void EndKeyboardEvent() override; - - void ForwardKeyboardEvent(std::unique_ptr<InputEvent> event, - bool skip_in_browser) override; void ForwardKeyboardEventWithCommands( std::unique_ptr<InputEvent> event, + const std::vector<uint8_t>& native_event_data, bool skip_in_browser, const std::vector<EditCommand>& commands) override; void RouteOrProcessMouseEvent(std::unique_ptr<InputEvent> event) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index d450d95..2edb742 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -57,6 +57,7 @@ #include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/events/cocoa/cocoa_event_utils.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/dom_keyboard_layout_map.h" @@ -1927,24 +1928,9 @@ // mojom::RenderWidgetHostNSViewHost functions that translate events and // forward them to the RenderWidgetHostNSViewHostHelper implementation: -void RenderWidgetHostViewMac::ForwardKeyboardEvent( - std::unique_ptr<InputEvent> input_event, - bool skip_in_browser) { - if (!input_event || !input_event->web_event || - !blink::WebInputEvent::IsKeyboardEventType( - input_event->web_event->GetType())) { - DLOG(ERROR) << "Absent or non-KeyboardEventType event."; - return; - } - const blink::WebKeyboardEvent& keyboard_event = - static_cast<const blink::WebKeyboardEvent&>(*input_event->web_event); - NativeWebKeyboardEvent native_event(keyboard_event, nil); - native_event.skip_in_browser = skip_in_browser; - ForwardKeyboardEvent(native_event, input_event->latency_info); -} - void RenderWidgetHostViewMac::ForwardKeyboardEventWithCommands( std::unique_ptr<InputEvent> input_event, + const std::vector<uint8_t>& native_event_data, bool skip_in_browser, const std::vector<EditCommand>& commands) { if (!input_event || !input_event->web_event || @@ -1957,6 +1943,12 @@ static_cast<const blink::WebKeyboardEvent&>(*input_event->web_event); NativeWebKeyboardEvent native_event(keyboard_event, nil); native_event.skip_in_browser = skip_in_browser; + // The NSEvent constructed from the InputEvent sent over mojo is not even + // close to the original NSEvent, resulting in all sorts of bugs. Use the + // native event serialization to reconstruct the NSEvent. + // https://crbug.com/919167,943197,964052 + [native_event.os_event release]; + native_event.os_event = [ui::EventFromData(native_event_data) retain]; ForwardKeyboardEventWithCommands(native_event, input_event->latency_info, commands); }
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc index a0fa38e..4c564a8 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -91,9 +91,9 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode credentials_mode, - network::mojom::FetchRedirectMode redirect_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, + network::mojom::RedirectMode redirect_mode, const std::string& integrity, bool keepalive, ResourceType resource_type, @@ -536,28 +536,16 @@ } ServiceWorkerVersion* -ServiceWorkerControlleeRequestHandler::GetServiceWorkerVersion( - ServiceWorkerMetrics::URLRequestJobResult* result) { - if (!provider_host_) { - *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST; +ServiceWorkerControlleeRequestHandler::GetServiceWorkerVersion() { + if (!provider_host_) return nullptr; - } - if (!provider_host_->controller()) { - *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION; - return nullptr; - } return provider_host_->controller(); } -bool ServiceWorkerControlleeRequestHandler::RequestStillValid( - ServiceWorkerMetrics::URLRequestJobResult* result) { +bool ServiceWorkerControlleeRequestHandler::RequestStillValid() { // A null |provider_host_| probably means the tab was closed. The null value // would cause problems down the line, so bail out. - if (!provider_host_) { - *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST; - return false; - } - return true; + return !!provider_host_; } void ServiceWorkerControlleeRequestHandler::MainResourceLoadFailed() {
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.h b/content/browser/service_worker/service_worker_controllee_request_handler.h index c6febed..0421e6a 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.h +++ b/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -43,9 +43,9 @@ ServiceWorkerControlleeRequestHandler( base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode credentials_mode, - network::mojom::FetchRedirectMode redirect_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, + network::mojom::RedirectMode redirect_mode, const std::string& integrity, bool keepalive, ResourceType resource_type, @@ -107,10 +107,8 @@ disallow_controller); // ServiceWorkerNavigationLoader::Delegate implementation: - ServiceWorkerVersion* GetServiceWorkerVersion( - ServiceWorkerMetrics::URLRequestJobResult* result) override; - bool RequestStillValid( - ServiceWorkerMetrics::URLRequestJobResult* result) override; + ServiceWorkerVersion* GetServiceWorkerVersion() override; + bool RequestStillValid() override; void MainResourceLoadFailed() override; // Sets |job_| to nullptr, and clears all extra response info associated with @@ -125,9 +123,9 @@ const base::WeakPtr<ServiceWorkerProviderHost> provider_host_; const ResourceType resource_type_; std::unique_ptr<ServiceWorkerNavigationLoaderWrapper> loader_wrapper_; - network::mojom::FetchRequestMode request_mode_; - network::mojom::FetchCredentialsMode credentials_mode_; - network::mojom::FetchRedirectMode redirect_mode_; + network::mojom::RequestMode request_mode_; + network::mojom::CredentialsMode credentials_mode_; + network::mojom::RedirectMode redirect_mode_; std::string integrity_; const bool keepalive_; blink::mojom::RequestContextType request_context_type_;
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc index a58aeeef..bca1ff7a 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -45,8 +45,8 @@ ServiceWorkerControlleeRequestHandlerTest* test, const GURL& url, ResourceType type, - network::mojom::FetchRequestMode fetch_type = - network::mojom::FetchRequestMode::kNoCors) + network::mojom::RequestMode request_mode = + network::mojom::RequestMode::kNoCors) : resource_type_(type), request_(test->url_request_context_.CreateRequest( url, @@ -56,9 +56,9 @@ handler_(new ServiceWorkerControlleeRequestHandler( test->context()->AsWeakPtr(), test->provider_host_, - fetch_type, - network::mojom::FetchCredentialsMode::kOmit, - network::mojom::FetchRedirectMode::kFollow, + request_mode, + network::mojom::CredentialsMode::kOmit, + network::mojom::RedirectMode::kFollow, std::string() /* integrity */, false /* keepalive */, type,
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index 309c505e..663ab5cc 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -130,38 +130,6 @@ return "_UNKNOWN"; } -ServiceWorkerMetrics::WorkerPreparationType GetWorkerPreparationType( - EmbeddedWorkerStatus initial_worker_status, - ServiceWorkerMetrics::StartSituation start_situation) { - using Situation = ServiceWorkerMetrics::StartSituation; - using Preparation = ServiceWorkerMetrics::WorkerPreparationType; - switch (initial_worker_status) { - case EmbeddedWorkerStatus::STOPPED: { - switch (start_situation) { - case Situation::DURING_STARTUP: - return Preparation::START_DURING_STARTUP; - case Situation::NEW_PROCESS: - return Preparation::START_IN_NEW_PROCESS; - case Situation::EXISTING_UNREADY_PROCESS: - return Preparation::START_IN_EXISTING_UNREADY_PROCESS; - case Situation::EXISTING_READY_PROCESS: - return Preparation::START_IN_EXISTING_READY_PROCESS; - case Situation::UNKNOWN: - break; - } - break; - } - case EmbeddedWorkerStatus::STARTING: - return Preparation::STARTING; - case EmbeddedWorkerStatus::RUNNING: - return Preparation::RUNNING; - case EmbeddedWorkerStatus::STOPPING: - return Preparation::STOPPING; - } - NOTREACHED() << static_cast<int>(initial_worker_status); - return Preparation::UNKNOWN; -} - void RecordURLMetricOnUI(const std::string& metric_name, const GURL& url) { DCHECK_CURRENTLY_ON(BrowserThread::UI); GetContentClient()->browser()->RecordURLMetric(metric_name, url); @@ -411,40 +379,6 @@ } } -void ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( - base::TimeDelta time, - EmbeddedWorkerStatus initial_worker_status, - StartSituation start_situation, - bool did_navigation_preload, - const GURL& url) { - // Record the worker preparation type. - WorkerPreparationType preparation = - GetWorkerPreparationType(initial_worker_status, start_situation); - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type", preparation); - std::string suffix = - GetContentClient()->browser()->GetMetricSuffixForURL(url); - if (!suffix.empty()) { - base::UmaHistogramEnumeration( - base::StrCat( - {"ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type.", - suffix}), - preparation); - } - - if (did_navigation_preload) { - // TODO(falken): Consider removing this UMA if it turns out the same as - // ServiceWorker.NavPreload.WorkerPreparationType. That UMA is logged at - // the same time as the other NavPreload metrics (which requires both the - // worker to start and the nav preload response to arrive successfuly), so - // they are more safely compared together. - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type_" - "NavigationPreloadEnabled", - preparation); - } -} - void ServiceWorkerMetrics::RecordWorkerStopped(StopStatus status) { UMA_HISTOGRAM_ENUMERATION("ServiceWorker.WorkerStopped", status); } @@ -595,36 +529,6 @@ } } -void ServiceWorkerMetrics::RecordURLRequestJobResult( - bool is_main_resource, - URLRequestJobResult result) { - if (is_main_resource) { - UMA_HISTOGRAM_ENUMERATION("ServiceWorker.URLRequestJob.MainResource.Result", - result, NUM_REQUEST_JOB_RESULT_TYPES); - } else { - UMA_HISTOGRAM_ENUMERATION("ServiceWorker.URLRequestJob.Subresource.Result", - result, NUM_REQUEST_JOB_RESULT_TYPES); - } -} - -void ServiceWorkerMetrics::RecordStatusZeroResponseError( - bool is_main_resource, - blink::mojom::ServiceWorkerResponseError error) { - if (is_main_resource) { - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.URLRequestJob.MainResource.StatusZeroError", error); - } else { - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.URLRequestJob.Subresource.StatusZeroError", error); - } -} - -void ServiceWorkerMetrics::RecordFallbackedRequestMode( - network::mojom::FetchRequestMode mode) { - UMA_HISTOGRAM_ENUMERATION("ServiceWorker.URLRequestJob.FallbackedRequestMode", - mode); -} - void ServiceWorkerMetrics::RecordProcessCreated(bool is_new_process) { UMA_HISTOGRAM_BOOLEAN("EmbeddedWorkerInstance.ProcessCreated", is_new_process);
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index 6fb9b4e..6f49051 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -24,8 +24,6 @@ namespace content { -enum class EmbeddedWorkerStatus; - class ServiceWorkerMetrics { public: // Used for UMA. Append-only. @@ -53,76 +51,6 @@ }; // Used for UMA. Append-only. - enum URLRequestJobResult { - // The service worker fell back to network. - REQUEST_JOB_FALLBACK_RESPONSE = 0, - - // The service worker fell back to network and CORS check is needed. - REQUEST_JOB_FALLBACK_FOR_CORS = 1, - - // The service worker responded with headers only (no body). - REQUEST_JOB_HEADERS_ONLY_RESPONSE = 2, - - // The service worker responded with a stream body. - REQUEST_JOB_STREAM_RESPONSE = 3, - - // The service worker responded with a blob body. - REQUEST_JOB_BLOB_RESPONSE = 4, - - // The renderer responded with network error (see - // RecordStatusZeroResponseError() for error reasons). - REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO = 5, - - // The renderer returned a response blob that could not be read. - REQUEST_JOB_ERROR_BAD_BLOB = 6, - - // The provider host for the request was destroyed before the request - // could start. - REQUEST_JOB_ERROR_NO_PROVIDER_HOST = 7, - - // The service worker assigned to the request could not be found, when - // the request tried to start. - REQUEST_JOB_ERROR_NO_ACTIVE_VERSION = 8, - - // Obsolete. - // REQUEST_JOB_ERROR_NO_REQUEST = 9, - - // An error occurred attempting to dispatch the event to the service worker. - REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH = 10, - - // An error occurred while reading the blob response. - REQUEST_JOB_ERROR_BLOB_READ = 11, - - // The connection to the stream response was destroyed before all the data - // was read. - REQUEST_JOB_ERROR_STREAM_ABORTED = 12, - - // The request job destructed before it finished. - REQUEST_JOB_ERROR_KILLED = 13, - - // The request job destructed before it finished. It was reading - // a blob response. - REQUEST_JOB_ERROR_KILLED_WITH_BLOB = 14, - - // The request job was destructed before it finished. It was reading - // a stream response. - REQUEST_JOB_ERROR_KILLED_WITH_STREAM = 15, - - // Obsolete. - // REQUEST_JOB_ERROR_DESTROYED = 16, - // REQUEST_JOB_ERROR_DESTROYED_WITH_BLOB = 17, - // REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM = 18, - - // The request job delegate behaved incorrectly. - REQUEST_JOB_ERROR_BAD_DELEGATE = 19, - - // The browser failed to construct the request body. - REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED = 20, - - NUM_REQUEST_JOB_RESULT_TYPES, - }; - - // Used for UMA. Append-only. enum class StopStatus { NORMAL, DETACH_BY_REGISTRY, @@ -210,37 +138,6 @@ }; // Used for UMA. Append only. - // This enum describes how an activated worker was found and prepared (i.e., - // reached the RUNNING status) in order to dispatch a fetch event to. - enum class WorkerPreparationType { - UNKNOWN = 0, - // The worker was already starting up. We waited for it to finish. - STARTING = 1, - // The worker was already running. - RUNNING = 2, - // The worker was stopping. We waited for it to stop, and then started it - // up. - STOPPING = 3, - // The worker was in the stopped state. We started it up, and startup - // required a new process to be created. - START_IN_NEW_PROCESS = 4, - // Deprecated 07/2017; replaced by START_IN_EXISTING_UNREADY_PROCESS and - // START_IN_EXISTING_READY_PROCESS. - // START_IN_EXISTING_PROCESS = 5, - // The worker was in the stopped state. We started it up, and this occurred - // during browser startup. - START_DURING_STARTUP = 6, - // The worker was in the stopped state. We started it up, and it used an - // existing unready process. - START_IN_EXISTING_UNREADY_PROCESS = 7, - // The worker was in the stopped state. We started it up, and it used an - // existing ready process. - START_IN_EXISTING_READY_PROCESS = 8, - // Add new types here. - kMaxValue = START_IN_EXISTING_READY_PROCESS, - }; - - // Used for UMA. Append only. // Describes the outcome of a time measurement taken between processes. enum class CrossProcessTimeDelta { NORMAL, @@ -342,15 +239,6 @@ StartSituation start_situation, EventType purpose); - // Records metrics for the preparation of an activated Service Worker for a - // main frame navigation. - CONTENT_EXPORT static void RecordActivatedWorkerPreparationForMainFrame( - base::TimeDelta time, - EmbeddedWorkerStatus initial_worker_status, - StartSituation start_situation, - bool did_navigation_preload, - const GURL& url); - // Records the result of trying to stop a worker. static void RecordWorkerStopped(StopStatus status); @@ -373,21 +261,6 @@ static void RecordFetchEventStatus(bool is_main_resource, blink::ServiceWorkerStatusCode status); - // Records result of a ServiceWorkerURLRequestJob that was forwarded to - // the service worker. - static void RecordURLRequestJobResult(bool is_main_resource, - URLRequestJobResult result); - - // Records the error code provided when the renderer returns a response with - // status zero to a fetch request. - static void RecordStatusZeroResponseError( - bool is_main_resource, - blink::mojom::ServiceWorkerResponseError error); - - // Records the mode of request that was fallbacked to the network. - static void RecordFallbackedRequestMode( - network::mojom::FetchRequestMode mode); - static void RecordProcessCreated(bool is_new_process); CONTENT_EXPORT static void RecordStartWorkerTiming(const StartTimes& times,
diff --git a/content/browser/service_worker/service_worker_metrics_unittest.cc b/content/browser/service_worker/service_worker_metrics_unittest.cc index ed6a8db..9ec4f4c 100644 --- a/content/browser/service_worker/service_worker_metrics_unittest.cc +++ b/content/browser/service_worker/service_worker_metrics_unittest.cc
@@ -11,120 +11,17 @@ namespace content { -namespace service_worker_metrics_unittest { -const std::string kNavigationPreloadSuffix = "_NavigationPreloadEnabled"; -const std::string kStartWorkerDuringStartupSuffix = "_StartWorkerDuringStartup"; -const std::string kWorkerStartOccurred = "_WorkerStartOccurred"; -const std::string kStartWorkerExistingReadyProcessSuffix = - "_StartWorkerExistingReadyProcess"; -const std::string kPreparationType = - "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type"; -const std::string kPreparationTypeSearch = - "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type.search"; +namespace { base::TimeTicks AdvanceTime(base::TimeTicks* time, int milliseconds) { *time += base::TimeDelta::FromMilliseconds(milliseconds); return *time; } +} // namespace + using CrossProcessTimeDelta = ServiceWorkerMetrics::CrossProcessTimeDelta; using StartSituation = ServiceWorkerMetrics::StartSituation; -using WorkerPreparationType = ServiceWorkerMetrics::WorkerPreparationType; - -class MetricTestContentBrowserClient : public TestContentBrowserClient { - public: - std::string GetMetricSuffixForURL(const GURL& url) override { - if (url.host() == "search.example.com") - return "search"; - return std::string(); - } -}; - -TEST(ServiceWorkerMetricsTest, ActivatedWorkerPreparation) { - base::TimeDelta time = base::TimeDelta::FromMilliseconds(123); - { - // Test preparation when the worker was STARTING. - base::HistogramTester histogram_tester; - ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( - time, EmbeddedWorkerStatus::STARTING, - ServiceWorkerMetrics::StartSituation::UNKNOWN, - false /* did_navigation_preload */, GURL("https://example.com")); - histogram_tester.ExpectUniqueSample( - kPreparationType, static_cast<int>(WorkerPreparationType::STARTING), 1); - histogram_tester.ExpectTotalCount( - kPreparationType + kNavigationPreloadSuffix, 0); - } - - { - // Test preparation when the worker started up during startup. - base::HistogramTester histogram_tester; - ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( - time, EmbeddedWorkerStatus::STOPPED, StartSituation::DURING_STARTUP, - true /* did_navigation_preload */, GURL("https://example.com")); - histogram_tester.ExpectUniqueSample( - kPreparationType, - static_cast<int>(WorkerPreparationType::START_DURING_STARTUP), 1); - histogram_tester.ExpectUniqueSample( - kPreparationType + kNavigationPreloadSuffix, - static_cast<int>(WorkerPreparationType::START_DURING_STARTUP), 1); - } - - { - // Test preparation when the worker started up in an existing process. - base::HistogramTester histogram_tester; - ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( - time, EmbeddedWorkerStatus::STOPPED, - StartSituation::EXISTING_READY_PROCESS, - true /* did_navigation_preload */, GURL("https://example.com")); - histogram_tester.ExpectUniqueSample( - kPreparationType, - static_cast<int>( - WorkerPreparationType::START_IN_EXISTING_READY_PROCESS), - 1); - histogram_tester.ExpectUniqueSample( - kPreparationType + kNavigationPreloadSuffix, - static_cast<int>( - WorkerPreparationType::START_IN_EXISTING_READY_PROCESS), - 1); - } - - // Suffixed metric test. - MetricTestContentBrowserClient test_browser_client; - ContentBrowserClient* old_browser_client = - SetBrowserClientForTesting(&test_browser_client); - { - base::HistogramTester histogram_tester; - ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( - time, EmbeddedWorkerStatus::STOPPED, - StartSituation::EXISTING_READY_PROCESS, - true /* did_navigation_preload */, GURL("https://search.example.com")); - histogram_tester.ExpectUniqueSample( - kPreparationType, - static_cast<int>( - WorkerPreparationType::START_IN_EXISTING_READY_PROCESS), - 1); - histogram_tester.ExpectUniqueSample( - kPreparationTypeSearch, - static_cast<int>( - WorkerPreparationType::START_IN_EXISTING_READY_PROCESS), - 1); - } - { - base::HistogramTester histogram_tester; - ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( - time, EmbeddedWorkerStatus::STOPPED, - StartSituation::EXISTING_READY_PROCESS, - true /* did_navigation_preload */, - GURL("https://notsearch.example.com")); - histogram_tester.ExpectUniqueSample( - kPreparationType, - static_cast<int>( - WorkerPreparationType::START_IN_EXISTING_READY_PROCESS), - 1); - histogram_tester.ExpectTotalCount(kPreparationTypeSearch, 0); - } - SetBrowserClientForTesting(old_browser_client); -} TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming) { ServiceWorkerMetrics::StartTimes times; @@ -274,5 +171,4 @@ CrossProcessTimeDelta::NEGATIVE, 1); } -} // namespace service_worker_metrics_unittest } // namespace content
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc index 4fba757..0b0ebb5 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.cc +++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -189,10 +189,7 @@ "ServiceWorkerNavigationLoader::StartRequest", this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - ServiceWorkerMetrics::URLRequestJobResult result = - ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE; - ServiceWorkerVersion* active_worker = - delegate_->GetServiceWorkerVersion(&result); + ServiceWorkerVersion* active_worker = delegate_->GetServiceWorkerVersion(); if (!active_worker) { CommitCompleted(net::ERR_FAILED, "No active worker"); return; @@ -302,16 +299,6 @@ response_head_.load_timing.send_end = now; devtools_attached_ = version->embedded_worker()->devtools_attached(); - - // Note that we don't record worker preparation time in S13nServiceWorker - // path for now. If we want to measure worker preparation time we can - // calculate it from response_head_.service_worker_ready_time and - // response_head_.load_timing.request_start. - // https://crbug.com/852664 - ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( - base::TimeDelta(), initial_worker_status, - version->embedded_worker()->start_situation(), did_navigation_preload_, - resource_request_.url); } void ServiceWorkerNavigationLoader::DidDispatchFetchEvent( @@ -332,9 +319,7 @@ ServiceWorkerMetrics::RecordFetchEventStatus(true /* is_main_resource */, status); - ServiceWorkerMetrics::URLRequestJobResult result = - ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE; - if (!delegate_ || !delegate_->RequestStillValid(&result)) { + if (!delegate_ || !delegate_->RequestStillValid()) { // The navigation or shared worker startup is cancelled. Just abort. CommitCompleted(net::ERR_ABORTED, "No delegate"); return;
diff --git a/content/browser/service_worker/service_worker_navigation_loader.h b/content/browser/service_worker/service_worker_navigation_loader.h index ddbd19e7a..9b31b990 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.h +++ b/content/browser/service_worker/service_worker_navigation_loader.h
@@ -50,15 +50,13 @@ // Returns the ServiceWorkerVersion fetch events for this request job should // be dispatched to. If no appropriate worker can be determined, returns - // nullptr and sets |*result| to an appropriate error. - virtual ServiceWorkerVersion* GetServiceWorkerVersion( - ServiceWorkerMetrics::URLRequestJobResult* result) = 0; + // nullptr. + virtual ServiceWorkerVersion* GetServiceWorkerVersion() = 0; // Called after dispatching the fetch event to determine if processing of // the request should still continue, or if processing should be aborted. - // When false is returned, this sets |*result| to an appropriate error. - virtual bool RequestStillValid( - ServiceWorkerMetrics::URLRequestJobResult* result) = 0; + // TODO(falken): This can probably be deleted. + virtual bool RequestStillValid() = 0; // Called to signal that loading failed, and that the resource being loaded // was a main resource.
diff --git a/content/browser/service_worker/service_worker_navigation_loader_unittest.cc b/content/browser/service_worker/service_worker_navigation_loader_unittest.cc index 05bd96b..0b84ae8 100644 --- a/content/browser/service_worker/service_worker_navigation_loader_unittest.cc +++ b/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
@@ -6,6 +6,7 @@ #include <string> #include <utility> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/run_loop.h" @@ -467,24 +468,19 @@ std::make_unique<network::ResourceRequest>(); request->url = GURL("https://www.example.com/"); request->method = "GET"; - request->fetch_request_mode = network::mojom::FetchRequestMode::kNavigate; - request->fetch_credentials_mode = - network::mojom::FetchCredentialsMode::kInclude; - request->fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual; + request->mode = network::mojom::RequestMode::kNavigate; + request->credentials_mode = network::mojom::CredentialsMode::kInclude; + request->redirect_mode = network::mojom::RedirectMode::kManual; return request; } protected: // ServiceWorkerNavigationLoader::Delegate ----------------------------------- - ServiceWorkerVersion* GetServiceWorkerVersion( - ServiceWorkerMetrics::URLRequestJobResult* result) override { + ServiceWorkerVersion* GetServiceWorkerVersion() override { return version_.get(); } - bool RequestStillValid( - ServiceWorkerMetrics::URLRequestJobResult* result) override { - return true; - } + bool RequestStillValid() override { return true; } void MainResourceLoadFailed() override { was_main_resource_load_failed_called_ = true; @@ -923,10 +919,9 @@ network::ResourceRequest request; request.url = GURL("https://www.example.com/"); request.method = "GET"; - request.fetch_request_mode = network::mojom::FetchRequestMode::kNavigate; - request.fetch_credentials_mode = - network::mojom::FetchCredentialsMode::kInclude; - request.fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual; + request.mode = network::mojom::RequestMode::kNavigate; + request.credentials_mode = network::mojom::CredentialsMode::kInclude; + request.redirect_mode = network::mojom::RedirectMode::kManual; SingleRequestURLLoaderFactory::RequestHandler handler; auto loader = std::make_unique<ServiceWorkerNavigationLoader>( @@ -1001,10 +996,9 @@ network::ResourceRequest request; request.url = GURL("https://www.example.com/"); request.method = "GET"; - request.fetch_request_mode = network::mojom::FetchRequestMode::kNavigate; - request.fetch_credentials_mode = - network::mojom::FetchCredentialsMode::kInclude; - request.fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual; + request.mode = network::mojom::RequestMode::kNavigate; + request.credentials_mode = network::mojom::CredentialsMode::kInclude; + request.redirect_mode = network::mojom::RedirectMode::kManual; SingleRequestURLLoaderFactory::RequestHandler handler; auto loader = std::make_unique<ServiceWorkerNavigationLoader>(
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index ec9e7cc..c8661214 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -617,9 +617,9 @@ std::unique_ptr<NavigationLoaderInterceptor> ServiceWorkerProviderHost::CreateLoaderInterceptor( - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode credentials_mode, - network::mojom::FetchRedirectMode redirect_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, + network::mojom::RedirectMode redirect_mode, const std::string& integrity, bool keepalive, ResourceType resource_type,
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 5629bdb..42c7124 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -292,9 +292,9 @@ // Returns an interceptor for a main resource request. May return nullptr if // the request doesn't require interception. std::unique_ptr<NavigationLoaderInterceptor> CreateLoaderInterceptor( - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode credentials_mode, - network::mojom::FetchRedirectMode redirect_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, + network::mojom::RedirectMode redirect_mode, const std::string& integrity, bool keepalive, ResourceType resource_type,
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc index 427094f..d1ddad3e 100644 --- a/content/browser/service_worker/service_worker_request_handler.cc +++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -72,9 +72,9 @@ ? ResourceType::kMainFrame : ResourceType::kSubFrame; return (*out_provider_host) - ->CreateLoaderInterceptor(network::mojom::FetchRequestMode::kNavigate, - network::mojom::FetchCredentialsMode::kInclude, - network::mojom::FetchRedirectMode::kManual, + ->CreateLoaderInterceptor(network::mojom::RequestMode::kNavigate, + network::mojom::CredentialsMode::kInclude, + network::mojom::RedirectMode::kManual, std::string() /* integrity */, false /* keepalive */, resource_type, request_info.begin_params->request_context_type, @@ -102,9 +102,8 @@ } return host->CreateLoaderInterceptor( - resource_request.fetch_request_mode, - resource_request.fetch_credentials_mode, - resource_request.fetch_redirect_mode, resource_request.fetch_integrity, + resource_request.mode, resource_request.credentials_mode, + resource_request.redirect_mode, resource_request.fetch_integrity, resource_request.keepalive, static_cast<ResourceType>(resource_request.resource_type), resource_request.resource_type == static_cast<int>(ResourceType::kWorker)
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index b453846..a7bd3e3 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -72,6 +72,7 @@ #include "content/browser/storage_partition_impl.h" #include "content/browser/url_loader_factory_getter.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/frame.mojom-test-utils.h" #include "content/common/frame_messages.h" #include "content/common/input/actions_parser.h" #include "content/common/input/synthetic_pinch_gesture_params.h" @@ -7893,8 +7894,8 @@ EXPECT_EQ(orig_site_instance, child->current_frame_host()->GetSiteInstance()); } -// Helper filter class to wait for a ShowCreatedWindow or ShowWidget message, -// record the routing ID from the message, and then drop the message. +// Helper filter class to wait for a ShowWidget message, record the routing ID +// from the message, and then drop the message. const uint32_t kMessageClasses[] = {ViewMsgStart, FrameMsgStart}; class PendingWidgetMessageFilter : public BrowserMessageFilter { public: @@ -7905,7 +7906,6 @@ bool OnMessageReceived(const IPC::Message& message) override { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PendingWidgetMessageFilter, message) - IPC_MESSAGE_HANDLER(FrameHostMsg_ShowCreatedWindow, OnShowCreatedWindow) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -7947,6 +7947,38 @@ DISALLOW_COPY_AND_ASSIGN(PendingWidgetMessageFilter); }; +// Intercepts calls to RenderFramHost's ShowCreatedWindow mojo method, and +// invokes the provided callback. +class ShowCreatedWindowInterceptor + : public mojom::FrameHostInterceptorForTesting { + public: + ShowCreatedWindowInterceptor( + RenderFrameHostImpl* render_frame_host, + base::RepeatingCallback<void(int32_t pending_widget_routing_id)> + test_callback) + : render_frame_host_(render_frame_host), + test_callback_(std::move(test_callback)) { + render_frame_host_->frame_host_binding_for_testing().SwapImplForTesting( + this); + } + + ~ShowCreatedWindowInterceptor() override {} + + FrameHost* GetForwardingInterface() override { return render_frame_host_; } + + void ShowCreatedWindow(int32_t pending_widget_routing_id, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture) override { + test_callback_.Run(pending_widget_routing_id); + } + + private: + RenderFrameHostImpl* render_frame_host_; + base::RepeatingCallback<void(int32_t pending_widget_routing_id)> + test_callback_; +}; + // Test for https://crbug.com/612276. Simultaneously open two new windows from // two subframes in different processes, where each subframe process's next // routing ID is the same. Make sure that both windows are created properly. @@ -7965,44 +7997,55 @@ FrameTreeNode* root = web_contents()->GetFrameTree()->root(); FrameTreeNode* child1 = root->child_at(0); FrameTreeNode* child2 = root->child_at(1); - RenderProcessHost* process1 = child1->current_frame_host()->GetProcess(); - RenderProcessHost* process2 = child2->current_frame_host()->GetProcess(); + RenderFrameHostImpl* frame1 = child1->current_frame_host(); + RenderFrameHostImpl* frame2 = child2->current_frame_host(); + RenderProcessHost* process1 = frame1->GetProcess(); + RenderProcessHost* process2 = frame2->GetProcess(); // Call window.open simultaneously in both subframes to create two popups. - // Wait for and then drop both FrameHostMsg_ShowCreatedWindow messages. This - // will ensure that both CreateNewWindow calls happen before either - // ShowCreatedWindow call. - scoped_refptr<PendingWidgetMessageFilter> filter1 = - new PendingWidgetMessageFilter(); - process1->AddFilter(filter1.get()); + // Wait for and then drop both ShowCreatedWindow messages. This will ensure + // that both CreateNewWindow calls happen before either ShowCreatedWindow + // call. + base::RunLoop run_loop1; + int32_t routing_id1; + ShowCreatedWindowInterceptor interceptor1( + frame1, + base::BindLambdaForTesting([&](int32_t pending_widget_routing_id) { + routing_id1 = pending_widget_routing_id; + run_loop1.Quit(); + })); EXPECT_TRUE(ExecuteScript(child1, "window.open();")); - filter1->Wait(); + run_loop1.Run(); - scoped_refptr<PendingWidgetMessageFilter> filter2 = - new PendingWidgetMessageFilter(); - process2->AddFilter(filter2.get()); + base::RunLoop run_loop2; + int32_t routing_id2; + ShowCreatedWindowInterceptor interceptor2( + frame2, + base::BindLambdaForTesting([&](int32_t pending_widget_routing_id) { + routing_id2 = pending_widget_routing_id; + run_loop2.Quit(); + })); + EXPECT_TRUE(ExecuteScript(child2, "window.open();")); - filter2->Wait(); + run_loop2.Run(); // At this point, we should have two pending WebContents. - EXPECT_TRUE(base::Contains( - web_contents()->pending_contents_, - GlobalRoutingID(process1->GetID(), filter1->routing_id()))); - EXPECT_TRUE(base::Contains( - web_contents()->pending_contents_, - GlobalRoutingID(process2->GetID(), filter2->routing_id()))); + EXPECT_TRUE(base::Contains(web_contents()->pending_contents_, + GlobalRoutingID(process1->GetID(), routing_id1))); + EXPECT_TRUE(base::Contains(web_contents()->pending_contents_, + GlobalRoutingID(process2->GetID(), routing_id2))); // Both subframes were set up in the same way, so the next routing ID for the // new popup windows should match up (this led to the collision in the // pending contents map in the original bug). - EXPECT_EQ(filter1->routing_id(), filter2->routing_id()); + EXPECT_EQ(routing_id1, routing_id2); // Now, simulate that both FrameHostMsg_ShowCreatedWindow messages arrive by // showing both of the pending WebContents. - web_contents()->ShowCreatedWindow(process1->GetID(), filter1->routing_id(), + web_contents()->ShowCreatedWindow(process1->GetID(), routing_id1, WindowOpenDisposition::NEW_FOREGROUND_TAB, gfx::Rect(), true); - web_contents()->ShowCreatedWindow(process2->GetID(), filter2->routing_id(), + web_contents()->ShowCreatedWindow(process2->GetID(), routing_id2, WindowOpenDisposition::NEW_FOREGROUND_TAB, gfx::Rect(), true);
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index a640fbb6..6f533db1 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -38,7 +38,6 @@ #include "content/browser/cookie_store/cookie_store_context.h" #include "content/browser/fileapi/browser_file_system_helper.h" #include "content/browser/gpu/shader_cache_factory.h" -#include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/browser/loader/prefetch_url_loader_service.h" #include "content/browser/native_file_system/native_file_system_manager_impl.h" #include "content/browser/notifications/platform_notification_context_impl.h" @@ -733,7 +732,6 @@ base::FilePath path = in_memory ? base::FilePath() : partition_path; partition->indexed_db_context_ = new IndexedDBContextImpl( path, context->GetSpecialStoragePolicy(), quota_manager_proxy, - indexed_db::GetDefaultLevelDBFactory(), base::DefaultClock::GetInstance()); partition->cache_storage_context_ = new CacheStorageContextImpl(context);
diff --git a/content/browser/tracing/background_tracing_config_impl.cc b/content/browser/tracing/background_tracing_config_impl.cc index 4e48aea..2cbac09a 100644 --- a/content/browser/tracing/background_tracing_config_impl.cc +++ b/content/browser/tracing/background_tracing_config_impl.cc
@@ -8,10 +8,12 @@ #include <utility> #include "base/macros.h" +#include "base/system/sys_info.h" #include "base/values.h" #include "build/build_config.h" #include "components/tracing/common/trace_startup_config.h" #include "content/browser/tracing/background_tracing_rule.h" +#include "net/base/network_change_notifier.h" using base::trace_event::TraceConfig; @@ -46,7 +48,42 @@ const char kConfigCategoryBlinkStyle[] = "BLINK_STYLE"; const char kConfigCategoryCustom[] = "CUSTOM"; -const size_t kDefaultTraceBufferSizeInKb = 10 * 1024; +// The memory overhead of running background tracing. +// TODO(ssid): Consider making these limits configurable by experiments. +constexpr size_t kLowRamBufferSizeKb = 200; +constexpr size_t kMediumRamBufferSizeKb = 2 * 1024; +#if defined(OS_ANDROID) +// Connectivity is also relevant for setting the buffer size because the +// uploader will fail if we sent large trace and device runs on mobile +// network. +constexpr size_t kMobileNetworkBufferSizeKb = 300; +constexpr size_t kMaxBufferSizeKb = 4 * 1024; +#else +constexpr size_t kMaxBufferSizeKb = 25 * 1024; +#endif + +// This function gives the trace buffer size based on device RAM and +// connectivity. +size_t GetMaximumTraceBufferSizeKb() { + int64_t ram_mb = base::SysInfo::AmountOfPhysicalMemoryMB(); + if (ram_mb > 0 && ram_mb <= 1024) { + return kLowRamBufferSizeKb; + } +#if defined(OS_ANDROID) + auto connection_type = net::NetworkChangeNotifier::GetConnectionType(); + if (connection_type != net::NetworkChangeNotifier::CONNECTION_WIFI && + connection_type != net::NetworkChangeNotifier::CONNECTION_ETHERNET && + connection_type != net::NetworkChangeNotifier::CONNECTION_BLUETOOTH) { + return kMobileNetworkBufferSizeKb; + } +#endif + + if (ram_mb > 0 && ram_mb <= 2 * 1024) { + return kMediumRamBufferSizeKb; + } + + return kMaxBufferSizeKb; +} } // namespace @@ -241,7 +278,7 @@ chrome_config.EnableArgumentFilter(); } - chrome_config.SetTraceBufferSizeInKb(kDefaultTraceBufferSizeInKb); + chrome_config.SetTraceBufferSizeInKb(GetMaximumTraceBufferSizeKb()); #if defined(OS_ANDROID) // Set low trace buffer size on Android in order to upload small trace files.
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc index 0a964ce..d4ab269 100644 --- a/content/browser/tracing/background_tracing_manager_impl.cc +++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -18,6 +18,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/values.h" +#include "build/build_config.h" #include "components/tracing/common/trace_startup_config.h" #include "content/browser/tracing/background_memory_tracing_observer.h" #include "content/browser/tracing/background_startup_tracing_observer.h" @@ -37,6 +38,7 @@ #include "content/public/common/child_process_host.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" +#include "net/base/network_change_notifier.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" #include "services/tracing/public/cpp/trace_event_agent.h" #include "services/tracing/public/cpp/tracing_features.h" @@ -45,6 +47,37 @@ namespace content { +namespace { + +// All the upload limits below are set for uncompressed trace log. On +// compression the data size usually reduces by 3x for size < 10MB, and the +// compression ratio grows up to 8x if the buffer size is around 100MB. +// TODO(ssid): Consider making these limits configurable by experiments. +#if defined(OS_ANDROID) +// TODO(ssid): If we see too many failures while uploading then consider +// lowering this limit. +constexpr size_t kUploadLimitNoWifiKb = 300; // ~100KB compressed size. +constexpr size_t kUploadLimitOnWifiKb = 5 * 1024; // ~1MB compressed size. +#else +constexpr size_t kUploadLimitKb = 30 * 1024; // Less than 10MB compressed size. +#endif + +bool IsTraceLogUploadAllowed(size_t trace_size_kb) { +#if defined(OS_ANDROID) + auto connection_type = net::NetworkChangeNotifier::GetConnectionType(); + if (connection_type != net::NetworkChangeNotifier::CONNECTION_WIFI && + connection_type != net::NetworkChangeNotifier::CONNECTION_ETHERNET && + connection_type != net::NetworkChangeNotifier::CONNECTION_BLUETOOTH) { + return kUploadLimitNoWifiKb; + } + return kUploadLimitOnWifiKb; +#else + return kUploadLimitKb; +#endif +} + +} // namespace + // static void BackgroundTracingManagerImpl::RecordMetric(Metrics metric) { UMA_HISTOGRAM_ENUMERATION("Tracing.Background.ScenarioState", metric, @@ -192,7 +225,20 @@ bool BackgroundTracingManagerImpl::HasTraceToUpload() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return !trace_to_upload_.empty(); + // Send the logs only when the trace size is within limits. If the connection + // type changes and we have a bigger than expected trace, then the next time + // service asks us when wifi is available, the trace will be sent. If we did + // collect a trace that is bigger than expected, then we will end up never + // uploading, and drop the trace. This should never happen because the trace + // buffer limits are set appropriately. + if (trace_to_upload_.empty()) { + return false; + } + if (!IsTraceLogUploadAllowed(trace_to_upload_.size())) { + RecordMetric(Metrics::LARGE_UPLOAD_WAITING_TO_RETRY); + return false; + } + return true; } std::string BackgroundTracingManagerImpl::GetLatestTraceToUpload() {
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h index 982aa09..88b44c09c 100644 --- a/content/browser/tracing/background_tracing_manager_impl.h +++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -80,6 +80,7 @@ UPLOAD_FAILED = 10, UPLOAD_SUCCEEDED = 11, STARTUP_SCENARIO_TRIGGERED = 12, + LARGE_UPLOAD_WAITING_TO_RETRY = 13, NUMBER_OF_BACKGROUND_TRACING_METRICS, }; static void RecordMetric(Metrics metric);
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.cc b/content/browser/web_package/prefetched_signed_exchange_cache.cc index 346e3cd..e2d3351 100644 --- a/content/browser/web_package/prefetched_signed_exchange_cache.cc +++ b/content/browser/web_package/prefetched_signed_exchange_cache.cc
@@ -151,7 +151,7 @@ } if (network::cors::ShouldCheckCors(request.url, request.request_initiator, - request.fetch_request_mode)) { + request.mode)) { const auto error_status = network::cors::CheckAccess( request.url, response_.headers->response_code(), GetHeaderString( @@ -160,7 +160,7 @@ GetHeaderString( response_, network::cors::header_names::kAccessControlAllowCredentials), - request.fetch_credentials_mode, *request.request_initiator); + request.credentials_mode, *request.request_initiator); if (error_status) { client_->OnComplete(network::URLLoaderCompletionStatus(*error_status)); return;
diff --git a/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc b/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc index 0d17831..ef5a0ec 100644 --- a/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc +++ b/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc
@@ -36,6 +36,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "content/shell/common/shell_switches.h" #include "net/base/features.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_cache.h" @@ -807,6 +808,12 @@ } ~SignedExchangeSubresourcePrefetchBrowserTest() = default; + void SetUpCommandLine(base::CommandLine* command_line) override { + PrefetchBrowserTestBase::SetUpCommandLine(command_line); + // Needed to call internals.scheduleBlinkGC(). + command_line->AppendSwitch(switches::kExposeInternalsForTesting); + } + void SetUp() override { const bool network_service_enabled = GetParam(); @@ -1950,6 +1957,106 @@ network::CrossOriginReadBlocking::Action::kBlockedWithoutSniffing); } +IN_PROC_BROWSER_TEST_P(SignedExchangeSubresourcePrefetchBrowserTest, + ScriptSXGNotGCed) { + const char* prefetch_page_path = "/prefetch.html"; + const char* page_sxg_path = "/target.sxg"; + const char* page_inner_url_path = "/target.html"; + const char* script_sxg_path = "/script.sxg"; + const char* script_inner_url_path = "/script.js"; + + auto script_sxg_request_counter = + RequestCounter::CreateAndMonitor(embedded_test_server(), script_sxg_path); + auto script_request_counter = RequestCounter::CreateAndMonitor( + embedded_test_server(), script_inner_url_path); + RegisterRequestHandler(embedded_test_server()); + ASSERT_TRUE(embedded_test_server()->Start()); + + const GURL prefetch_page_url = + embedded_test_server()->GetURL(prefetch_page_path); + const GURL sxg_page_url = embedded_test_server()->GetURL(page_sxg_path); + const GURL inner_url_page_url = + embedded_test_server()->GetURL(page_inner_url_path); + const GURL sxg_script_url = embedded_test_server()->GetURL(script_sxg_path); + const GURL inner_url_script_url = + embedded_test_server()->GetURL(script_inner_url_path); + + const net::SHA256HashValue page_header_integrity = {{0x01}}; + const net::SHA256HashValue script_header_integrity = {{0x02}}; + + const std::string outer_link_header = + CreateAlternateLinkHeader(sxg_script_url, inner_url_script_url); + const std::string inner_link_headers = + std::string("Link: ") + + base::JoinString( + {CreateAllowedAltSxgLinkHeader(inner_url_script_url, + script_header_integrity), + CreatePreloadLinkHeader(inner_url_script_url, "script")}, + ","); + + RegisterResponse(prefetch_page_path, + ResponseEntry(base::StringPrintf( + "<body><link rel='prefetch' href='%s'></body>", + sxg_page_url.spec().c_str()))); + RegisterResponse( + page_sxg_path, + CreateSignedExchangeResponseEntry( + "<head><title>Prefetch Target (SXG)</title>" + "<script src=\"./script.js\" async defer></script></head>", + {{"link", outer_link_header}})); + RegisterResponse(script_sxg_path, CreateSignedExchangeResponseEntry( + "document.title=\"done\";", {})); + MockSignedExchangeHandlerFactory factory( + {MockSignedExchangeHandlerParams( + sxg_page_url, SignedExchangeLoadResult::kSuccess, net::OK, + inner_url_page_url, "text/html", {inner_link_headers}, + page_header_integrity), + MockSignedExchangeHandlerParams( + sxg_script_url, SignedExchangeLoadResult::kSuccess, net::OK, + inner_url_script_url, "text/javascript", + // Set "cache-control: public" to keep the script in the memory + // cache. + {"cache-control: public, max-age=600"}, script_header_integrity)}); + ScopedSignedExchangeHandlerFactory scoped_factory(&factory); + + EXPECT_EQ(0, GetPrefetchURLLoaderCallCount()); + NavigateToURL(shell(), prefetch_page_url); + + WaitUntilLoaded(sxg_page_url); + WaitUntilLoaded(sxg_script_url); + + EXPECT_EQ(1, script_sxg_request_counter->GetRequestCount()); + EXPECT_EQ(0, script_request_counter->GetRequestCount()); + EXPECT_EQ(2, GetPrefetchURLLoaderCallCount()); + + const auto cached_exchanges = GetCachedExchanges(shell()); + EXPECT_EQ(2u, cached_exchanges.size()); + + NavigateToURLAndWaitTitle(sxg_page_url, "done"); + + EXPECT_EQ(1, script_sxg_request_counter->GetRequestCount()); + EXPECT_EQ(0, script_request_counter->GetRequestCount()); + + // Clears the title. + EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "document.title = '';")); + + const char* next_page_path = "/next_page.html"; + const GURL next_page_url = embedded_test_server()->GetURL(next_page_path); + RegisterResponse( + next_page_path, + ResponseEntry( + "<head><title>Next page</title>" + "<script src=\"./script.js\" async defer></script></head>")); + // Triggers GC. + EXPECT_TRUE( + ExecuteScript(shell()->web_contents(), "internals.scheduleBlinkGC();")); + // The script which was served via SXG must be kept in memory cache and must + // be reused. + NavigateToURLAndWaitTitle(next_page_url, "done"); + + EXPECT_EQ(0, script_request_counter->GetRequestCount()); +} + INSTANTIATE_TEST_SUITE_P(SignedExchangeSubresourcePrefetchBrowserTest, SignedExchangeSubresourcePrefetchBrowserTest, ::testing::Bool());
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc index 8b8fbeaa..0783fe3 100644 --- a/content/browser/worker_host/dedicated_worker_host.cc +++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -68,7 +68,7 @@ void StartScriptLoad( const GURL& script_url, const url::Origin& request_initiator_origin, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, blink::mojom::BlobURLTokenPtr blob_url_token, blink::mojom::DedicatedWorkerHostFactoryClientPtr client) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -330,7 +330,7 @@ void CreateWorkerHostAndStartScriptLoad( const GURL& script_url, const url::Origin& request_initiator_origin, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, blink::mojom::BlobURLTokenPtr blob_url_token, blink::mojom::DedicatedWorkerHostFactoryClientPtr client) override { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/worker_host/shared_worker_service_impl.cc b/content/browser/worker_host/shared_worker_service_impl.cc index d4b9829..522adf3 100644 --- a/content/browser/worker_host/shared_worker_service_impl.cc +++ b/content/browser/worker_host/shared_worker_service_impl.cc
@@ -216,8 +216,7 @@ // TODO(nhiroki): The document's renderer should provide credentials mode // specified by WorkerOptions for module script. // (https://crbug.com/824646, https://crbug.com/907749) - const auto credentials_mode = - network::mojom::FetchCredentialsMode::kSameOrigin; + const auto credentials_mode = network::mojom::CredentialsMode::kSameOrigin; WorkerScriptFetchInitiator::Start( process_id, weak_host->instance()->url(),
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc index a6fb43ef..b834b67 100644 --- a/content/browser/worker_host/worker_script_fetch_initiator.cc +++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -52,7 +52,7 @@ int process_id, const GURL& script_url, const url::Origin& request_initiator, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, ResourceType resource_type, scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, AppCacheNavigationHandleCore* appcache_handle_core, @@ -106,8 +106,8 @@ // CorsURLLoaderFactory::IsSane(). // TODO(https://crbug.com/799935): Unify |LOAD_DO_NOT_*| into // |allow_credentials|. - resource_request->fetch_credentials_mode = credentials_mode; - if (credentials_mode == network::mojom::FetchCredentialsMode::kOmit) { + resource_request->credentials_mode = credentials_mode; + if (credentials_mode == network::mojom::CredentialsMode::kOmit) { resource_request->allow_credentials = false; const auto load_flags_pattern = net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES | @@ -188,9 +188,8 @@ auto file_factory = std::make_unique<FileURLLoaderFactory>( storage_partition->browser_context()->GetPath(), storage_partition->browser_context()->GetSharedCorsOriginAccessList(), - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); + // USER_VISIBLE because worker script fetch may affect the UI. + base::TaskPriority::USER_VISIBLE); network::mojom::URLLoaderFactoryPtr file_factory_ptr; mojo::MakeStrongBinding(std::move(file_factory), mojo::MakeRequest(&file_factory_ptr));
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.h b/content/browser/worker_host/worker_script_fetch_initiator.h index 1240f6e..e481e8f 100644 --- a/content/browser/worker_host/worker_script_fetch_initiator.h +++ b/content/browser/worker_host/worker_script_fetch_initiator.h
@@ -60,7 +60,7 @@ int process_id, const GURL& script_url, const url::Origin& request_initiator, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, ResourceType resource_type, scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, AppCacheNavigationHandleCore* appcache_handle_core,
diff --git a/content/common/fetch/fetch_request_type_converters.cc b/content/common/fetch/fetch_request_type_converters.cc index 100f515..c02b5f00 100644 --- a/content/common/fetch/fetch_request_type_converters.cc +++ b/content/common/fetch/fetch_request_type_converters.cc
@@ -30,14 +30,14 @@ output->referrer = blink::mojom::Referrer::New( input.referrer, content::Referrer::NetReferrerPolicyToBlinkReferrerPolicy( input.referrer_policy)); - output->mode = input.fetch_request_mode; + output->mode = input.mode; output->is_main_resource_load = content::ServiceWorkerUtils::IsMainResourceType( static_cast<content::ResourceType>(input.resource_type)); - output->credentials_mode = input.fetch_credentials_mode; + output->credentials_mode = input.credentials_mode; output->cache_mode = content::ServiceWorkerUtils::GetCacheModeFromLoadFlags(input.load_flags); - output->redirect_mode = input.fetch_redirect_mode; + output->redirect_mode = input.redirect_mode; output->request_context_type = static_cast<blink::mojom::RequestContextType>( input.fetch_request_context_type); output->is_reload = ui::PageTransitionCoreTypeIs(
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index e8ad0f810..3f78b3f3 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -528,5 +528,13 @@ // user activation state of the frames in the frame tree in the non-source and // non-target renderer processes. TransferUserActivationFrom(int32 source_routing_id); + + // Causes a window previously opened via RenderMessageFilter::CreateNewWindow + // to be shown on the screen. This message is routed to the preexisting frame + // that opened the window, and |pending_widget_routing_id| corresponds to the + // widget routing id from the CreateNewWindow reply. + ShowCreatedWindow(int32 pending_widget_routing_id, + ui.mojom.WindowOpenDisposition disposition, + gfx.mojom.Rect rect, bool opened_by_user_gesture); };
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 0e86d044..4c53747 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -736,16 +736,6 @@ IPC_STRUCT_END() #endif -// Causes a window previously opened via RenderMessageFilter::CreateNewWindow to -// be shown on the screen. This message is routed to the preexisting frame that -// opened the window, and |pending_widget_routing_id| corresponds to the -// widget routing id from the CreateNewWindow reply. -IPC_MESSAGE_ROUTED4(FrameHostMsg_ShowCreatedWindow, - int /* pending_widget_routing_id */, - WindowOpenDisposition /* disposition */, - gfx::Rect /* initial_rect */, - bool /* opened_by_user_gesture */) - #if BUILDFLAG(ENABLE_PLUGINS) IPC_STRUCT_TRAITS_BEGIN(content::PepperRendererInstanceData) IPC_STRUCT_TRAITS_MEMBER(render_process_id)
diff --git a/content/common/input/input_event_struct_traits.cc b/content/common/input/input_event_struct_traits.cc index 0e044a3..909da64 100644 --- a/content/common/input/input_event_struct_traits.cc +++ b/content/common/input/input_event_struct_traits.cc
@@ -215,12 +215,26 @@ } } - gesture_event->SetNeedsWheelEvent(false); + if (gesture_data->pinch_begin_data && + type == blink::WebInputEvent::Type::kGesturePinchBegin) { + gesture_event->data.pinch_begin.needs_wheel_event = + gesture_data->pinch_begin_data->needs_wheel_event; + } - if (gesture_data->pinch_data && + if (gesture_data->pinch_update_data && type == blink::WebInputEvent::Type::kGesturePinchUpdate) { - gesture_event->data.pinch_update.zoom_disabled = false; - gesture_event->data.pinch_update.scale = gesture_data->pinch_data->scale; + gesture_event->data.pinch_update.zoom_disabled = + gesture_data->pinch_update_data->zoom_disabled; + gesture_event->data.pinch_update.scale = + gesture_data->pinch_update_data->scale; + gesture_event->data.pinch_update.needs_wheel_event = + gesture_data->pinch_update_data->needs_wheel_event; + } + + if (gesture_data->pinch_end_data && + type == blink::WebInputEvent::Type::kGesturePinchEnd) { + gesture_event->data.pinch_end.needs_wheel_event = + gesture_data->pinch_end_data->needs_wheel_event; } if (gesture_data->tap_data) { @@ -231,6 +245,8 @@ case blink::WebInputEvent::Type::kGestureTapUnconfirmed: case blink::WebInputEvent::Type::kGestureDoubleTap: gesture_event->data.tap.tap_count = gesture_data->tap_data->tap_count; + gesture_event->data.tap.needs_wheel_event = + gesture_data->tap_data->needs_wheel_event; break; } } @@ -425,8 +441,9 @@ case blink::WebInputEvent::Type::kGestureDoubleTap: gesture_data->contact_size = gfx::Size(gesture_event->data.tap.width, gesture_event->data.tap.height); - gesture_data->tap_data = - content::mojom::TapData::New(gesture_event->data.tap.tap_count); + gesture_data->tap_data = content::mojom::TapData::New( + gesture_event->data.tap.tap_count, + gesture_event->data.tap.needs_wheel_event); break; case blink::WebInputEvent::Type::kGestureLongPress: case blink::WebInputEvent::Type::kGestureLongTap: @@ -477,9 +494,19 @@ 0, 0, gesture_event->data.fling_cancel.target_viewport, gesture_event->data.fling_cancel.prevent_boosting); break; + case blink::WebInputEvent::Type::kGesturePinchBegin: + gesture_data->pinch_begin_data = content::mojom::PinchBeginData::New( + gesture_event->data.pinch_begin.needs_wheel_event); + break; case blink::WebInputEvent::Type::kGesturePinchUpdate: - gesture_data->pinch_data = content::mojom::PinchData::New( - gesture_event->data.pinch_update.scale); + gesture_data->pinch_update_data = content::mojom::PinchUpdateData::New( + gesture_event->data.pinch_update.scale, + gesture_event->data.pinch_update.zoom_disabled, + gesture_event->data.pinch_update.needs_wheel_event); + break; + case blink::WebInputEvent::Type::kGesturePinchEnd: + gesture_data->pinch_end_data = content::mojom::PinchEndData::New( + gesture_event->data.pinch_end.needs_wheel_event); break; } return gesture_data;
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom index 8ef794e..a2bbde9e 100644 --- a/content/common/input/input_handler.mojom +++ b/content/common/input/input_handler.mojom
@@ -89,8 +89,18 @@ ScrollUpdate? update_details; }; -struct PinchData { +struct PinchBeginData { + bool needs_wheel_event; +}; + +struct PinchUpdateData { float scale; + bool zoom_disabled; + bool needs_wheel_event; +}; + +struct PinchEndData { + bool needs_wheel_event; }; struct FlingData { @@ -102,6 +112,7 @@ struct TapData { int32 tap_count; + bool needs_wheel_event; }; struct GestureData { @@ -114,7 +125,9 @@ int32 resending_plugin_id; gfx.mojom.Size? contact_size; ScrollData? scroll_data; - PinchData? pinch_data; + PinchBeginData? pinch_begin_data; + PinchUpdateData? pinch_update_data; + PinchEndData? pinch_end_data; TapData? tap_data; FlingData? fling_data; };
diff --git a/content/common/render_widget_host_ns_view.mojom b/content/common/render_widget_host_ns_view.mojom index 3b0787c..2c70decc 100644 --- a/content/common/render_widget_host_ns_view.mojom +++ b/content/common/render_widget_host_ns_view.mojom
@@ -136,9 +136,9 @@ // Forward a keyboard event to the RenderWidgetHost that is currently handling // the key-down event. - ForwardKeyboardEvent(content.mojom.Event event, bool skip_in_browser); ForwardKeyboardEventWithCommands( content.mojom.Event event, + array<uint8> native_event_data, bool skip_in_browser, array<content.mojom.EditCommand> commands);
diff --git a/content/common/service_worker/service_worker_types_unittest.cc b/content/common/service_worker/service_worker_types_unittest.cc index 48737247..970a12c5 100644 --- a/content/common/service_worker/service_worker_types_unittest.cc +++ b/content/common/service_worker/service_worker_types_unittest.cc
@@ -16,7 +16,7 @@ TEST(ServiceWorkerRequestTest, SerialiazeDeserializeRoundTrip) { auto request = blink::mojom::FetchAPIRequest::New(); - request->mode = network::mojom::FetchRequestMode::kSameOrigin; + request->mode = network::mojom::RequestMode::kSameOrigin; request->is_main_resource_load = true; request->request_context_type = blink::mojom::RequestContextType::IFRAME; request->url = GURL("foo.com"); @@ -25,9 +25,9 @@ request->referrer = blink::mojom::Referrer::New( GURL("bar.com"), network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade); - request->credentials_mode = network::mojom::FetchCredentialsMode::kSameOrigin; + request->credentials_mode = network::mojom::CredentialsMode::kSameOrigin; request->cache_mode = blink::mojom::FetchCacheMode::kForceCache; - request->redirect_mode = network::mojom::FetchRedirectMode::kManual; + request->redirect_mode = network::mojom::RedirectMode::kManual; request->integrity = "integrity"; request->keepalive = true; request->is_reload = true;
diff --git a/content/common/service_worker/service_worker_utils.cc b/content/common/service_worker/service_worker_utils.cc index d54e374..c44105e 100644 --- a/content/common/service_worker/service_worker_utils.cc +++ b/content/common/service_worker/service_worker_utils.cc
@@ -272,7 +272,7 @@ auto request_ptr = blink::mojom::FetchAPIRequest::New(); request_ptr->mode = - static_cast<network::mojom::FetchRequestMode>(request_proto.mode()); + static_cast<network::mojom::RequestMode>(request_proto.mode()); request_ptr->is_main_resource_load = request_proto.is_main_resource_load(); request_ptr->request_context_type = static_cast<blink::mojom::RequestContextType>( @@ -287,13 +287,12 @@ static_cast<network::mojom::ReferrerPolicy>( request_proto.referrer().policy())); request_ptr->is_reload = request_proto.is_reload(); - request_ptr->credentials_mode = - static_cast<network::mojom::FetchCredentialsMode>( - request_proto.credentials_mode()); + request_ptr->credentials_mode = static_cast<network::mojom::CredentialsMode>( + request_proto.credentials_mode()); request_ptr->cache_mode = static_cast<blink::mojom::FetchCacheMode>(request_proto.cache_mode()); - request_ptr->redirect_mode = static_cast<network::mojom::FetchRedirectMode>( - request_proto.redirect_mode()); + request_ptr->redirect_mode = + static_cast<network::mojom::RedirectMode>(request_proto.redirect_mode()); if (request_proto.has_integrity()) request_ptr->integrity = request_proto.integrity(); request_ptr->keepalive = request_proto.keepalive();
diff --git a/content/public/browser/permission_type.h b/content/public/browser/permission_type.h index 5082c001..df8c6616 100644 --- a/content/public/browser/permission_type.h +++ b/content/public/browser/permission_type.h
@@ -32,6 +32,8 @@ BACKGROUND_FETCH = 17, IDLE_DETECTION = 18, PERIODIC_BACKGROUND_SYNC = 19, + WAKE_LOCK_SCREEN = 20, + WAKE_LOCK_SYSTEM = 21, // Always keep this at the end. NUM,
diff --git a/content/public/renderer/associated_resource_fetcher.h b/content/public/renderer/associated_resource_fetcher.h index eef6b924..a7da31c 100644 --- a/content/public/renderer/associated_resource_fetcher.h +++ b/content/public/renderer/associated_resource_fetcher.h
@@ -58,12 +58,11 @@ // // |fetch_credentials_mode| is the credentials mode to use. See // https://fetch.spec.whatwg.org/#concept-request-credentials-mode - virtual void Start( - blink::WebLocalFrame* frame, - blink::mojom::RequestContextType request_context, - network::mojom::FetchRequestMode fetch_request_mode, - network::mojom::FetchCredentialsMode fetch_credentials_mode, - StartCallback callback) = 0; + virtual void Start(blink::WebLocalFrame* frame, + blink::mojom::RequestContextType request_context, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, + StartCallback callback) = 0; // Manually cancel the request. virtual void Cancel() = 0;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 9a1ee08c..6e77b42b 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -313,8 +313,6 @@ "media/webrtc/webrtc_video_track_source.h", "media/webrtc/webrtc_video_utils.cc", "media/webrtc/webrtc_video_utils.h", - "media/webrtc_local_audio_source_provider.cc", - "media/webrtc_local_audio_source_provider.h", "media/webrtc_logging.cc", "media/webrtc_logging.h", "media_recorder/media_recorder_handler.cc",
diff --git a/content/renderer/fetchers/associated_resource_fetcher_impl.cc b/content/renderer/fetchers/associated_resource_fetcher_impl.cc index d4cac57..34ad36e 100644 --- a/content/renderer/fetchers/associated_resource_fetcher_impl.cc +++ b/content/renderer/fetchers/associated_resource_fetcher_impl.cc
@@ -151,8 +151,8 @@ void AssociatedResourceFetcherImpl::Start( blink::WebLocalFrame* frame, blink::mojom::RequestContextType request_context, - network::mojom::FetchRequestMode fetch_request_mode, - network::mojom::FetchCredentialsMode fetch_credentials_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, StartCallback callback) { DCHECK(!loader_); DCHECK(!client_); @@ -162,8 +162,8 @@ request_.SetRequestContext(request_context); request_.SetSiteForCookies(frame->GetDocument().SiteForCookies()); - request_.SetFetchRequestMode(fetch_request_mode); - request_.SetFetchCredentialsMode(fetch_credentials_mode); + request_.SetMode(request_mode); + request_.SetCredentialsMode(credentials_mode); client_.reset(new ClientImpl(std::move(callback)));
diff --git a/content/renderer/fetchers/associated_resource_fetcher_impl.h b/content/renderer/fetchers/associated_resource_fetcher_impl.h index 0efd75c..ffba6454 100644 --- a/content/renderer/fetchers/associated_resource_fetcher_impl.h +++ b/content/renderer/fetchers/associated_resource_fetcher_impl.h
@@ -34,8 +34,8 @@ const blink::WebAssociatedURLLoaderOptions& options) override; void Start(blink::WebLocalFrame* frame, blink::mojom::RequestContextType request_context, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode fetch_credentials_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, StartCallback callback) override; private:
diff --git a/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc b/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc index 4cb0306..7cefd22b 100644 --- a/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc +++ b/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
@@ -56,8 +56,8 @@ fetcher_->SetCacheMode(cache_mode); fetcher_->Start( - frame, request_context, network::mojom::FetchRequestMode::kNoCors, - network::mojom::FetchCredentialsMode::kInclude, + frame, request_context, network::mojom::RequestMode::kNoCors, + network::mojom::CredentialsMode::kInclude, base::BindOnce(&MultiResolutionImageResourceFetcher::OnURLFetchComplete, base::Unretained(this))); }
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc index e8cbdc2..88e33b6f 100644 --- a/content/renderer/loader/resource_dispatcher_unittest.cc +++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -119,7 +119,7 @@ request->referrer_policy = Referrer::GetDefaultReferrerPolicy(); request->resource_type = static_cast<int>(ResourceType::kSubResource); request->priority = net::LOW; - request->fetch_request_mode = network::mojom::FetchRequestMode::kNoCors; + request->mode = network::mojom::RequestMode::kNoCors; const RequestExtraData extra_data; extra_data.CopyToResourceRequest(request.get());
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index 2fbe0bd..5eaf5ac 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -783,9 +783,9 @@ resource_request->is_external_request = request.IsExternalRequest(); resource_request->cors_preflight_policy = request.GetCorsPreflightPolicy(); resource_request->skip_service_worker = request.GetSkipServiceWorker(); - resource_request->fetch_request_mode = request.GetFetchRequestMode(); - resource_request->fetch_credentials_mode = request.GetFetchCredentialsMode(); - resource_request->fetch_redirect_mode = request.GetFetchRedirectMode(); + resource_request->mode = request.GetMode(); + resource_request->credentials_mode = request.GetCredentialsMode(); + resource_request->redirect_mode = request.GetRedirectMode(); resource_request->fetch_integrity = GetFetchIntegrityForWebURLRequest(request); resource_request->fetch_request_context_type =
diff --git a/content/renderer/media/stream/media_stream_center.cc b/content/renderer/media/stream/media_stream_center.cc index 089451e..cb9673a 100644 --- a/content/renderer/media/stream/media_stream_center.cc +++ b/content/renderer/media/stream/media_stream_center.cc
@@ -14,7 +14,6 @@ #include "content/public/common/content_switches.h" #include "content/public/renderer/render_thread.h" #include "content/renderer/media/stream/processed_local_audio_source.h" -#include "content/renderer/media/webrtc_local_audio_source_provider.h" #include "media/base/sample_format.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h" @@ -27,6 +26,7 @@ #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" +#include "third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h" #include "third_party/blink/public/web/web_frame.h" using blink::WebFrame; @@ -194,10 +194,7 @@ blink::WebMediaStreamSource source = track.Source(); DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeAudio); - // TODO(tommi): Rename WebRtcLocalAudioSourceProvider to - // WebAudioMediaStreamSink since it's not specific to any particular source. - // https://crbug.com/577874 - return new WebRtcLocalAudioSourceProvider(track, context_sample_rate); + return new blink::WebAudioMediaStreamAudioSink(track, context_sample_rate); } void MediaStreamCenter::DidStopMediaStreamSource(
diff --git a/content/renderer/pepper/pepper_url_loader_host.cc b/content/renderer/pepper/pepper_url_loader_host.cc index 10023df2..7466353c 100644 --- a/content/renderer/pepper/pepper_url_loader_host.cc +++ b/content/renderer/pepper/pepper_url_loader_host.cc
@@ -267,14 +267,13 @@ if (filled_in_request_data.allow_cross_origin_requests) { // Allow cross-origin requests with access control. The request specifies // if credentials are to be sent. - web_request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - web_request.SetFetchCredentialsMode( + web_request.SetMode(network::mojom::RequestMode::kCors); + web_request.SetCredentialsMode( filled_in_request_data.allow_credentials - ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kOmit); + ? network::mojom::CredentialsMode::kInclude + : network::mojom::CredentialsMode::kOmit); } else { - web_request.SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + web_request.SetMode(network::mojom::RequestMode::kSameOrigin); // Same-origin requests can always send credentials. Use the default // credentials mode "include". }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index de0ca411..6d48cd2c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -4479,8 +4479,9 @@ } void RenderFrameImpl::DidEnforceInsecureNavigationsSet( - const std::vector<uint32_t>& set) { - GetFrameHost()->EnforceInsecureNavigationsSet(set); + const WebVector<uint32_t>& set) { + GetFrameHost()->EnforceInsecureNavigationsSet( + const_cast<WebVector<uint32_t>&>(set).ReleaseVector()); } void RenderFrameImpl::DidChangeFramePolicy( @@ -5829,7 +5830,8 @@ params->origin = frame_origin; params->insecure_request_policy = frame_->GetInsecureRequestPolicy(); - params->insecure_navigations_set = frame_->GetInsecureRequestToUpgrade(); + params->insecure_navigations_set = + frame_->GetInsecureRequestToUpgrade().ReleaseVector(); params->has_potentially_trustworthy_unique_origin = frame_origin.IsUnique() && frame_origin.IsPotentiallyTrustworthy(); @@ -7086,12 +7088,12 @@ // TODO(clamy): Data urls should not be sent back to the browser either. // These values are assumed on the browser side for navigations. These checks // ensure the renderer has the correct values. - DCHECK_EQ(network::mojom::FetchRequestMode::kNavigate, - info->url_request.GetFetchRequestMode()); - DCHECK_EQ(network::mojom::FetchCredentialsMode::kInclude, - info->url_request.GetFetchCredentialsMode()); - DCHECK_EQ(network::mojom::FetchRedirectMode::kManual, - info->url_request.GetFetchRedirectMode()); + DCHECK_EQ(network::mojom::RequestMode::kNavigate, + info->url_request.GetMode()); + DCHECK_EQ(network::mojom::CredentialsMode::kInclude, + info->url_request.GetCredentialsMode()); + DCHECK_EQ(network::mojom::RedirectMode::kManual, + info->url_request.GetRedirectMode()); DCHECK(frame_->Parent() || info->frame_type == network::mojom::RequestContextFrameType::kTopLevel); @@ -7526,10 +7528,10 @@ // // This call happens only for renderer-created windows; for example, when a // tab is created by script via window.open(). - Send(new FrameHostMsg_ShowCreatedWindow( - GetRoutingID(), render_widget_to_show->routing_id(), + GetFrameHost()->ShowCreatedWindow( + render_widget_to_show->routing_id(), RenderViewImpl::NavigationPolicyToDisposition(policy), initial_rect, - opened_by_user_gesture)); + opened_by_user_gesture); } void RenderFrameImpl::RenderWidgetSetFocus(bool enable) {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index a8bb1d9..c36bd14 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -708,7 +708,7 @@ void DidEnforceInsecureRequestPolicy( blink::WebInsecureRequestPolicy policy) override; void DidEnforceInsecureNavigationsSet( - const std::vector<uint32_t>& set) override; + const blink::WebVector<uint32_t>& set) override; void DidChangeFramePolicy(blink::WebFrame* child_frame, const blink::FramePolicy& frame_policy) override; void DidSetFramePolicyHeaders(
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index bf2755a..2769497 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -711,10 +711,9 @@ // Navigations to normal HTTP URLs can be handled locally. blink::WebURLRequest request(GURL("http://foo.com")); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNavigate); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kInclude); - request.SetFetchRedirectMode(network::mojom::FetchRedirectMode::kManual); + request.SetMode(network::mojom::RequestMode::kNavigate); + request.SetCredentialsMode(network::mojom::CredentialsMode::kInclude); + request.SetRedirectMode(network::mojom::RedirectMode::kManual); request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL); request.SetRequestorOrigin(requestor_origin); auto navigation_info = std::make_unique<blink::WebNavigationInfo>(); @@ -901,8 +900,8 @@ // Empty url should never fork. blink::WebURLRequest request(empty_url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNavigate); - request.SetFetchRedirectMode(network::mojom::FetchRedirectMode::kManual); + request.SetMode(network::mojom::RequestMode::kNavigate); + request.SetRedirectMode(network::mojom::RedirectMode::kManual); request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL); request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(example_url)); auto navigation_info = std::make_unique<blink::WebNavigationInfo>(); @@ -925,8 +924,8 @@ // about:blank should never fork. blink::WebURLRequest request(blank_url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNavigate); - request.SetFetchRedirectMode(network::mojom::FetchRedirectMode::kManual); + request.SetMode(network::mojom::RequestMode::kNavigate); + request.SetRedirectMode(network::mojom::RedirectMode::kManual); request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL); request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(example_url)); auto navigation_info = std::make_unique<blink::WebNavigationInfo>();
diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc index a93dc0ea..f59a53d 100644 --- a/content/renderer/renderer_main_platform_delegate_win.cc +++ b/content/renderer/renderer_main_platform_delegate_win.cc
@@ -4,16 +4,13 @@ #include "content/renderer/renderer_main_platform_delegate.h" -#include <delayimp.h> #include <dwrite.h> #include <memory> #include "base/command_line.h" -#include "base/debug/alias.h" #include "base/logging.h" #include "base/strings/string16.h" -#include "base/strings/string_util.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" #include "content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.h" @@ -32,31 +29,6 @@ namespace content { -namespace { - -// Delay load failure hook that generates a crash report. By default a failure -// to delay load will trigger an exception handled by the delay load runtime and -// this won't generate a crash report. -extern "C" FARPROC WINAPI DelayLoadFailureHook(unsigned reason, - DelayLoadInfo* dll_info) { - char dll_name[256]; - base::strlcpy(dll_name, dll_info->szDll, base::size(dll_name)); - base::debug::Alias(&dll_name); - - CHECK(false); - return 0; -} - -// Set the delay load failure hook to the function above. -// -// The |__pfnDliFailureHook2| failure notification hook gets called -// automatically by the delay load runtime in case of failure, see -// https://docs.microsoft.com/en-us/cpp/build/reference/failure-hooks?view=vs-2019 -// for more information about this. -extern "C" const PfnDliHook __pfnDliFailureHook2 = DelayLoadFailureHook; - -} // namespace - RendererMainPlatformDelegate::RendererMainPlatformDelegate( const MainFunctionParams& parameters) : parameters_(parameters) {}
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index ddd5351..730194e 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -382,10 +382,9 @@ // response to Blink. // TODO(falken): Remove this mechanism after OOB-CORS ships. if (!network::features::ShouldEnableOutOfBlinkCors() && - ((resource_request_.fetch_request_mode == - network::mojom::FetchRequestMode::kCors || - resource_request_.fetch_request_mode == - network::mojom::FetchRequestMode::kCorsWithForcedPreflight) && + ((resource_request_.mode == network::mojom::RequestMode::kCors || + resource_request_.mode == + network::mojom::RequestMode::kCorsWithForcedPreflight) && (!resource_request_.request_initiator.has_value() || !resource_request_.request_initiator->IsSameOriginWith( url::Origin::Create(resource_request_.url))))) {
diff --git a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc index 5294460f..d89a5b4 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
@@ -1316,40 +1316,39 @@ CreateSubresourceLoaderFactory(); struct TestCase { - network::mojom::FetchRequestMode fetch_request_mode; + network::mojom::RequestMode request_mode; base::Optional<url::Origin> request_initiator; bool expected_was_fallback_required_by_service_worker; }; const TestCase kTests[] = { - {network::mojom::FetchRequestMode::kSameOrigin, - base::Optional<url::Origin>(), false}, - {network::mojom::FetchRequestMode::kNoCors, base::Optional<url::Origin>(), + {network::mojom::RequestMode::kSameOrigin, base::Optional<url::Origin>(), false}, - {network::mojom::FetchRequestMode::kCors, base::Optional<url::Origin>(), - true}, - {network::mojom::FetchRequestMode::kCorsWithForcedPreflight, + {network::mojom::RequestMode::kNoCors, base::Optional<url::Origin>(), + false}, + {network::mojom::RequestMode::kCors, base::Optional<url::Origin>(), true}, + {network::mojom::RequestMode::kCorsWithForcedPreflight, base::Optional<url::Origin>(), true}, - {network::mojom::FetchRequestMode::kNavigate, - base::Optional<url::Origin>(), false}, - {network::mojom::FetchRequestMode::kSameOrigin, + {network::mojom::RequestMode::kNavigate, base::Optional<url::Origin>(), + false}, + {network::mojom::RequestMode::kSameOrigin, url::Origin::Create(GURL("https://www.example.com/")), false}, - {network::mojom::FetchRequestMode::kNoCors, + {network::mojom::RequestMode::kNoCors, url::Origin::Create(GURL("https://www.example.com/")), false}, - {network::mojom::FetchRequestMode::kCors, + {network::mojom::RequestMode::kCors, url::Origin::Create(GURL("https://www.example.com/")), false}, - {network::mojom::FetchRequestMode::kCorsWithForcedPreflight, + {network::mojom::RequestMode::kCorsWithForcedPreflight, url::Origin::Create(GURL("https://www.example.com/")), false}, - {network::mojom::FetchRequestMode::kNavigate, + {network::mojom::RequestMode::kNavigate, url::Origin::Create(GURL("https://other.example.com/")), false}, - {network::mojom::FetchRequestMode::kSameOrigin, + {network::mojom::RequestMode::kSameOrigin, url::Origin::Create(GURL("https://other.example.com/")), false}, - {network::mojom::FetchRequestMode::kNoCors, + {network::mojom::RequestMode::kNoCors, url::Origin::Create(GURL("https://other.example.com/")), false}, - {network::mojom::FetchRequestMode::kCors, + {network::mojom::RequestMode::kCors, url::Origin::Create(GURL("https://other.example.com/")), true}, - {network::mojom::FetchRequestMode::kCorsWithForcedPreflight, + {network::mojom::RequestMode::kCorsWithForcedPreflight, url::Origin::Create(GURL("https://other.example.com/")), true}, - {network::mojom::FetchRequestMode::kNavigate, + {network::mojom::RequestMode::kNavigate, url::Origin::Create(GURL("https://other.example.com/")), false}}; for (const auto& test : kTests) { @@ -1357,14 +1356,14 @@ SCOPED_TRACE( ::testing::Message() - << "fetch_request_mode: " << static_cast<int>(test.fetch_request_mode) + << "fetch_request_mode: " << static_cast<int>(test.request_mode) << " request_initiator: " << (test.request_initiator ? test.request_initiator->Serialize() : std::string("null"))); // Perform the request. network::ResourceRequest request = CreateRequest(GURL("https://www.example.com/foo.png")); - request.fetch_request_mode = test.fetch_request_mode; + request.mode = test.request_mode; request.request_initiator = test.request_initiator; network::mojom::URLLoaderPtr loader; std::unique_ptr<network::TestURLLoaderClient> client;
diff --git a/content/renderer/worker/dedicated_worker_host_factory_client.cc b/content/renderer/worker/dedicated_worker_host_factory_client.cc index bb269a8..cb77ceef 100644 --- a/content/renderer/worker/dedicated_worker_host_factory_client.cc +++ b/content/renderer/worker/dedicated_worker_host_factory_client.cc
@@ -42,7 +42,7 @@ void DedicatedWorkerHostFactoryClient::CreateWorkerHost( const blink::WebURL& script_url, const blink::WebSecurityOrigin& script_origin, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, mojo::ScopedMessagePipeHandle blob_url_token) { DCHECK(blink::features::IsPlzDedicatedWorkerEnabled()); blink::mojom::DedicatedWorkerHostFactoryClientPtr client_ptr;
diff --git a/content/renderer/worker/dedicated_worker_host_factory_client.h b/content/renderer/worker/dedicated_worker_host_factory_client.h index 5b3e537..54ceac6 100644 --- a/content/renderer/worker/dedicated_worker_host_factory_client.h +++ b/content/renderer/worker/dedicated_worker_host_factory_client.h
@@ -44,7 +44,7 @@ const blink::WebSecurityOrigin& script_origin) override; void CreateWorkerHost(const blink::WebURL& script_url, const blink::WebSecurityOrigin& script_origin, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, mojo::ScopedMessagePipeHandle blob_url_token) override; scoped_refptr<blink::WebWorkerFetchContext> CloneWorkerFetchContext( blink::WebWorkerFetchContext* web_worker_fetch_context,
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc index 173d3234..29c281b0 100644 --- a/content/shell/browser/shell_permission_manager.cc +++ b/content/shell/browser/shell_permission_manager.cc
@@ -24,6 +24,7 @@ case PermissionType::SENSORS: case PermissionType::ACCESSIBILITY_EVENTS: case PermissionType::PAYMENT_HANDLER: + case PermissionType::WAKE_LOCK_SCREEN: // Background Sync and Background Fetch browser tests require // permission to be granted by default. @@ -43,6 +44,7 @@ case PermissionType::CLIPBOARD_READ: case PermissionType::CLIPBOARD_WRITE: case PermissionType::NUM: + case PermissionType::WAKE_LOCK_SYSTEM: return false; }
diff --git a/content/shell/browser/web_test/web_test_message_filter.cc b/content/shell/browser/web_test/web_test_message_filter.cc index b2e1510..b77391de 100644 --- a/content/shell/browser/web_test/web_test_message_filter.cc +++ b/content/shell/browser/web_test/web_test_message_filter.cc
@@ -206,6 +206,10 @@ type = PermissionType::BACKGROUND_FETCH; } else if (name == "periodic-background-sync") { type = PermissionType::PERIODIC_BACKGROUND_SYNC; + } else if (name == "wake-lock-screen") { + type = PermissionType::WAKE_LOCK_SCREEN; + } else if (name == "wake-lock-system") { + type = PermissionType::WAKE_LOCK_SYSTEM; } else { NOTREACHED(); type = PermissionType::NOTIFICATIONS;
diff --git a/content/shell/renderer/web_test/blink_test_runner.cc b/content/shell/renderer/web_test/blink_test_runner.cc index 4b5c304..8e706dda 100644 --- a/content/shell/renderer/web_test/blink_test_runner.cc +++ b/content/shell/renderer/web_test/blink_test_runner.cc
@@ -819,8 +819,8 @@ waiting_for_reset_ = true; auto request = blink::WebURLRequest(GURL(url::kAboutBlankURL)); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNavigate); - request.SetFetchRedirectMode(network::mojom::FetchRedirectMode::kManual); + request.SetMode(network::mojom::RequestMode::kNavigate); + request.SetRedirectMode(network::mojom::RedirectMode::kManual); request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL); request.SetRequestorOrigin(blink::WebSecurityOrigin::CreateUniqueOpaque()); main_frame->StartNavigation(request);
diff --git a/content/shell/tools/breakpad_integration_test.py b/content/shell/tools/breakpad_integration_test.py index 310d8af..0bedf59b5 100755 --- a/content/shell/tools/breakpad_integration_test.py +++ b/content/shell/tools/breakpad_integration_test.py
@@ -58,21 +58,26 @@ def clear_android_dumps(options, device): try: print '# Deleting stale crash dumps' - pending = ANDROID_CRASH_DIR + '/pending/' + pending = os.path.join(ANDROID_CRASH_DIR, 'pending') files = device.RunShellCommand(['ls', pending], as_root=True) for f in files: if f.endswith('.dmp'): - if options.verbose: - print ' deleting %s' % f - device.RunShellCommand(['rm', f], check_return=True, as_root=True) + dump = os.path.join(pending, f) + try: + if options.verbose: + print ' deleting %s' % dump + device.RunShellCommand(['rm', dump], check_return=True, as_root=True) + except: + print 'Failed to delete %s' % dump + except: - print 'Failed to delete android crash dir %s' % ANDROID_CRASH_DIR + print 'Failed to list dumps in android crash dir %s' % pending def get_android_dump(crash_dir): global failure - pending = ANDROID_CRASH_DIR + '/pending/' + pending = os.path.join(ANDROID_CRASH_DIR, 'pending') device = GetDevice() for attempts in range(5): @@ -89,9 +94,9 @@ print dumps raise Exception(failure) - device.PullFile(pending + dumps[0], crash_dir, as_root=True) - device.RunShellCommand(['rm', pending + dumps[0]], check_return=True, - as_root=True) + device.PullFile(os.path.join(pending, dumps[0]), crash_dir, as_root=True) + device.RunShellCommand(['rm', os.path.join(pending, dumps[0])], + check_return=True, as_root=True) return os.path.join(crash_dir, os.path.basename(dumps[0]))
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 4f52f08..6e07a7e3 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1883,7 +1883,6 @@ "../renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc", "../renderer/media/webrtc/webrtc_set_description_observer_unittest.cc", "../renderer/media/webrtc/webrtc_video_track_source_unittest.cc", - "../renderer/media/webrtc_local_audio_source_provider_unittest.cc", "../renderer/media_recorder/media_recorder_handler_unittest.cc", "../renderer/media_recorder/video_track_recorder_unittest.cc", "../renderer/p2p/filtering_network_manager_unittest.cc",
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index 4353b5e..c7788ad 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -89,6 +89,11 @@ void TransferUserActivationFrom(int32_t source_routing_id) override {} + void ShowCreatedWindow(int32_t pending_widget_routing_id, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture) override {} + protected: // mojom::FrameHost: void CreateNewWindow(mojom::CreateNewWindowParamsPtr,
diff --git a/device/bluetooth/bluetooth_device_winrt.cc b/device/bluetooth/bluetooth_device_winrt.cc index 7a14d92..b0c3d50 100644 --- a/device/bluetooth/bluetooth_device_winrt.cc +++ b/device/bluetooth/bluetooth_device_winrt.cc
@@ -18,6 +18,7 @@ #include "base/win/core_winrt_util.h" #include "base/win/post_async_results.h" #include "base/win/scoped_hstring.h" +#include "components/device_event_log/device_event_log.h" #include "device/bluetooth/bluetooth_adapter_winrt.h" #include "device/bluetooth/bluetooth_gatt_discoverer_winrt.h" #include "device/bluetooth/bluetooth_pairing_winrt.h" @@ -63,39 +64,39 @@ ComPtr<IDeviceInformationPairing> GetDeviceInformationPairing( ComPtr<IBluetoothLEDevice> ble_device) { if (!ble_device) { - VLOG(2) << "No BLE device instance present."; + BLUETOOTH_LOG(DEBUG) << "No BLE device instance present."; return nullptr; } ComPtr<IBluetoothLEDevice2> ble_device_2; HRESULT hr = ble_device.As(&ble_device_2); if (FAILED(hr)) { - VLOG(2) << "Obtaining IBluetoothLEDevice2 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Obtaining IBluetoothLEDevice2 failed: " + << logging::SystemErrorCodeToString(hr); return nullptr; } ComPtr<IDeviceInformation> device_information; hr = ble_device_2->get_DeviceInformation(&device_information); if (FAILED(hr)) { - VLOG(2) << "Getting Device Information failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Device Information failed: " + << logging::SystemErrorCodeToString(hr); return nullptr; } ComPtr<IDeviceInformation2> device_information_2; hr = device_information.As(&device_information_2); if (FAILED(hr)) { - VLOG(2) << "Obtaining IDeviceInformation2 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Obtaining IDeviceInformation2 failed: " + << logging::SystemErrorCodeToString(hr); return nullptr; } ComPtr<IDeviceInformationPairing> pairing; hr = device_information_2->get_Pairing(&pairing); if (FAILED(hr)) { - VLOG(2) << "DeviceInformation::get_Pairing() failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "DeviceInformation::get_Pairing() failed: " + << logging::SystemErrorCodeToString(hr); return nullptr; } @@ -109,14 +110,15 @@ ComPtr<IClosable> closable; HRESULT hr = ble_device.As(&closable); if (FAILED(hr)) { - VLOG(2) << "As IClosable failed: " << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "As IClosable failed: " + << logging::SystemErrorCodeToString(hr); return; } hr = closable->Close(); if (FAILED(hr)) { - VLOG(2) << "IClosable::close() failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "IClosable::close() failed: " + << logging::SystemErrorCodeToString(hr); } } @@ -124,8 +126,8 @@ EventRegistrationToken token) { HRESULT hr = ble_device->remove_ConnectionStatusChanged(token); if (FAILED(hr)) { - VLOG(2) << "Removing ConnectionStatus Handler failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Removing ConnectionStatus Handler failed: " + << logging::SystemErrorCodeToString(hr); } } @@ -133,8 +135,8 @@ EventRegistrationToken token) { HRESULT hr = ble_device->remove_GattServicesChanged(token); if (FAILED(hr)) { - VLOG(2) << "Removing Gatt Services Changed Handler failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Removing Gatt Services Changed Handler failed: " + << logging::SystemErrorCodeToString(hr); } } @@ -142,8 +144,8 @@ EventRegistrationToken token) { HRESULT hr = ble_device->remove_NameChanged(token); if (FAILED(hr)) { - VLOG(2) << "Removing NameChanged Handler failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Removing NameChanged Handler failed: " + << logging::SystemErrorCodeToString(hr); } } @@ -203,7 +205,8 @@ HSTRING name; HRESULT hr = ble_device_->get_Name(&name); if (FAILED(hr)) { - VLOG(2) << "Getting Name failed: " << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Name failed: " + << logging::SystemErrorCodeToString(hr); return local_name_; } @@ -218,20 +221,20 @@ ComPtr<IDeviceInformationPairing> pairing = GetDeviceInformationPairing(ble_device_); if (!pairing) { - VLOG(2) << "Failed to get DeviceInformationPairing."; + BLUETOOTH_LOG(DEBUG) << "Failed to get DeviceInformationPairing."; return false; } boolean is_paired; HRESULT hr = pairing->get_IsPaired(&is_paired); if (FAILED(hr)) { - VLOG(2) << "DeviceInformationPairing::get_IsPaired() failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "DeviceInformationPairing::get_IsPaired() failed: " + << logging::SystemErrorCodeToString(hr); return false; } - VLOG(2) << "BluetoothDeviceWinrt::IsPaired(): " - << (is_paired ? "True" : "False"); + BLUETOOTH_LOG(DEBUG) << "BluetoothDeviceWinrt::IsPaired(): " + << (is_paired ? "True" : "False"); return is_paired; } @@ -246,8 +249,8 @@ BluetoothConnectionStatus status; HRESULT hr = ble_device_->get_ConnectionStatus(&status); if (FAILED(hr)) { - VLOG(2) << "Getting ConnectionStatus failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting ConnectionStatus failed: " + << logging::SystemErrorCodeToString(hr); return false; } @@ -299,9 +302,9 @@ void BluetoothDeviceWinrt::Pair(PairingDelegate* pairing_delegate, const base::Closure& callback, const ConnectErrorCallback& error_callback) { - VLOG(2) << "BluetoothDeviceWinrt::Pair()"; + BLUETOOTH_LOG(DEBUG) << "BluetoothDeviceWinrt::Pair()"; if (pairing_) { - VLOG(2) << "Another Pair Operation is already in progress."; + BLUETOOTH_LOG(DEBUG) << "Another Pair Operation is already in progress."; PostTask(error_callback, ERROR_INPROGRESS); return; } @@ -309,7 +312,7 @@ ComPtr<IDeviceInformationPairing> pairing = GetDeviceInformationPairing(ble_device_); if (!pairing) { - VLOG(2) << "Failed to get DeviceInformationPairing."; + BLUETOOTH_LOG(DEBUG) << "Failed to get DeviceInformationPairing."; PostTask(error_callback, ERROR_UNKNOWN); return; } @@ -317,8 +320,8 @@ ComPtr<IDeviceInformationPairing2> pairing_2; HRESULT hr = pairing.As(&pairing_2); if (FAILED(hr)) { - VLOG(2) << "Obtaining IDeviceInformationPairing2 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Obtaining IDeviceInformationPairing2 failed: " + << logging::SystemErrorCodeToString(hr); PostTask(error_callback, ERROR_UNKNOWN); return; } @@ -326,8 +329,8 @@ ComPtr<IDeviceInformationCustomPairing> custom; hr = pairing_2->get_Custom(&custom); if (FAILED(hr)) { - VLOG(2) << "DeviceInformationPairing::get_Custom() failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "DeviceInformationPairing::get_Custom() failed: " + << logging::SystemErrorCodeToString(hr); PostTask(error_callback, ERROR_UNKNOWN); return; } @@ -425,8 +428,9 @@ ComPtr<IBluetoothLEDeviceStatics> device_statics; HRESULT hr = GetBluetoothLEDeviceStaticsActivationFactory(&device_statics); if (FAILED(hr)) { - VLOG(2) << "GetBluetoothLEDeviceStaticsActivationFactory failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "GetBluetoothLEDeviceStaticsActivationFactory failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidFailToConnectGatt, weak_ptr_factory_.GetWeakPtr(), @@ -442,8 +446,9 @@ hr = device_statics->FromBluetoothAddressAsync(raw_address_, &from_bluetooth_address_op); if (FAILED(hr)) { - VLOG(2) << "BluetoothLEDevice::FromBluetoothAddressAsync failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "BluetoothLEDevice::FromBluetoothAddressAsync failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidFailToConnectGatt, weak_ptr_factory_.GetWeakPtr(), @@ -457,8 +462,8 @@ weak_ptr_factory_.GetWeakPtr())); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidFailToConnectGatt, weak_ptr_factory_.GetWeakPtr(), @@ -494,7 +499,7 @@ ComPtr<IBluetoothLEDevice> ble_device) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!ble_device) { - VLOG(2) << "Getting Device From Bluetooth Address failed."; + BLUETOOTH_LOG(DEBUG) << "Getting Device From Bluetooth Address failed."; DidFailToConnectGatt(ConnectErrorCode::ERROR_FAILED); return; }
diff --git a/device/bluetooth/bluetooth_gatt_discoverer_winrt.cc b/device/bluetooth/bluetooth_gatt_discoverer_winrt.cc index ebd294ef..b7ec0d7 100644 --- a/device/bluetooth/bluetooth_gatt_discoverer_winrt.cc +++ b/device/bluetooth/bluetooth_gatt_discoverer_winrt.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/stl_util.h" #include "base/win/post_async_results.h" +#include "components/device_event_log/device_event_log.h" #include "device/bluetooth/bluetooth_remote_gatt_service_winrt.h" namespace device { @@ -67,28 +68,28 @@ bool CheckCommunicationStatus(IGattResult* gatt_result, bool allow_access_denied = false) { if (!gatt_result) { - VLOG(2) << "Getting GATT Results failed."; + BLUETOOTH_LOG(DEBUG) << "Getting GATT Results failed."; return false; } GattCommunicationStatus status; HRESULT hr = gatt_result->get_Status(&status); if (FAILED(hr)) { - VLOG(2) << "Getting GATT Communication Status failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting GATT Communication Status failed: " + << logging::SystemErrorCodeToString(hr); return false; } if (status != GattCommunicationStatus_Success) { if (status == GattCommunicationStatus_AccessDenied) { - VLOG(2) << "GATT access denied error"; + BLUETOOTH_LOG(DEBUG) << "GATT access denied error"; } else { - VLOG(2) << "Unexpected GattCommunicationStatus: " << status; + BLUETOOTH_LOG(DEBUG) << "Unexpected GattCommunicationStatus: " << status; } - VLOG(2) << "GATT Error Code: " - << static_cast<int>( - BluetoothRemoteGattServiceWinrt::GetGattErrorCode( - gatt_result)); + BLUETOOTH_LOG(DEBUG) + << "GATT Error Code: " + << static_cast<int>( + BluetoothRemoteGattServiceWinrt::GetGattErrorCode(gatt_result)); } return status == GattCommunicationStatus_Success || @@ -101,7 +102,8 @@ unsigned size; HRESULT hr = view->get_Size(&size); if (FAILED(hr)) { - VLOG(2) << "Getting Size failed: " << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Size failed: " + << logging::SystemErrorCodeToString(hr); return false; } @@ -110,8 +112,8 @@ ComPtr<I> entry; hr = view->GetAt(i, &entry); if (FAILED(hr)) { - VLOG(2) << "GetAt(" << i - << ") failed: " << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "GetAt(" << i << ") failed: " + << logging::SystemErrorCodeToString(hr); return false; } @@ -135,8 +137,8 @@ ComPtr<IBluetoothLEDevice3> ble_device_3; HRESULT hr = ble_device_.As(&ble_device_3); if (FAILED(hr)) { - VLOG(2) << "Obtaining IBluetoothLEDevice3 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Obtaining IBluetoothLEDevice3 failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -144,8 +146,8 @@ ComPtr<IAsyncOperation<GattDeviceServicesResult*>> get_gatt_services_op; hr = ble_device_3->GetGattServicesAsync(&get_gatt_services_op); if (FAILED(hr)) { - VLOG(2) << "BluetoothLEDevice::GetGattServicesAsync failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "BluetoothLEDevice::GetGattServicesAsync failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -156,8 +158,8 @@ weak_ptr_factory_.GetWeakPtr())); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); } } @@ -187,6 +189,7 @@ void BluetoothGattDiscovererWinrt::OnGetGattServices( ComPtr<IGattDeviceServicesResult> services_result) { if (!CheckCommunicationStatus(services_result.Get())) { + BLUETOOTH_LOG(DEBUG) << "Failed to get GATT services."; std::move(callback_).Run(false); return; } @@ -194,8 +197,8 @@ ComPtr<IVectorView<GattDeviceService*>> services; HRESULT hr = services_result->get_Services(&services); if (FAILED(hr)) { - VLOG(2) << "Getting GATT Services failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting GATT Services failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -207,11 +210,20 @@ num_services_ = gatt_services_.size(); for (const auto& gatt_service : gatt_services_) { + uint16_t service_attribute_handle; + hr = gatt_service->get_AttributeHandle(&service_attribute_handle); + if (FAILED(hr)) { + BLUETOOTH_LOG(DEBUG) << "Getting AttributeHandle failed: " + << logging::SystemErrorCodeToString(hr); + std::move(callback_).Run(false); + return; + } + ComPtr<IGattDeviceService3> gatt_service_3; hr = gatt_service.As(&gatt_service_3); if (FAILED(hr)) { - VLOG(2) << "Obtaining IGattDeviceService3 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Obtaining IGattDeviceService3 failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -220,8 +232,8 @@ hr = gatt_service_3->OpenAsync(GattSharingMode_SharedReadAndWrite, &open_op); if (FAILED(hr)) { - VLOG(2) << "GattDeviceService::OpenAsync() failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "GattDeviceService::OpenAsync() failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); } @@ -229,45 +241,31 @@ std::move(open_op), base::BindOnce(&BluetoothGattDiscovererWinrt::OnServiceOpen, weak_ptr_factory_.GetWeakPtr(), - std::move(gatt_service))); + std::move(gatt_service_3), service_attribute_handle)); } RunCallbackIfDone(); } void BluetoothGattDiscovererWinrt::OnServiceOpen( - ComPtr<IGattDeviceService> gatt_service, + ComPtr<IGattDeviceService3> gatt_service_3, + uint16_t service_attribute_handle, GattOpenStatus status) { if (status != GattOpenStatus_Success && status != GattOpenStatus_AlreadyOpened) { - VLOG(2) << "Failed to open GATT service: " << status; + BLUETOOTH_LOG(DEBUG) << "Failed to open service " + << service_attribute_handle << ": " << status; std::move(callback_).Run(false); return; } - uint16_t service_attribute_handle; - HRESULT hr = gatt_service->get_AttributeHandle(&service_attribute_handle); - if (FAILED(hr)) { - VLOG(2) << "Getting AttributeHandle failed: " - << logging::SystemErrorCodeToString(hr); - std::move(callback_).Run(false); - return; - } - - ComPtr<IGattDeviceService3> gatt_service_3; - hr = gatt_service.As(&gatt_service_3); - if (FAILED(hr)) { - VLOG(2) << "Obtaining IGattDeviceService3 failed: " - << logging::SystemErrorCodeToString(hr); - std::move(callback_).Run(false); - return; - } ComPtr<IAsyncOperation<GattCharacteristicsResult*>> get_characteristics_op; - hr = gatt_service_3->GetCharacteristicsAsync(&get_characteristics_op); + HRESULT hr = gatt_service_3->GetCharacteristicsAsync(&get_characteristics_op); if (FAILED(hr)) { - VLOG(2) << "GattDeviceService::GetCharacteristicsAsync() failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "GattDeviceService::GetCharacteristicsAsync() failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -278,8 +276,8 @@ weak_ptr_factory_.GetWeakPtr(), service_attribute_handle)); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); } } @@ -290,6 +288,8 @@ // A few GATT services like HID over GATT (short UUID 0x1812) are protected // by the OS, leading to an access denied error. if (!CheckCommunicationStatus(characteristics_result.Get(), true)) { + BLUETOOTH_LOG(DEBUG) << "Failed to get characteristics for service " + << service_attribute_handle << "."; std::move(callback_).Run(false); return; } @@ -297,8 +297,8 @@ ComPtr<IVectorView<GattCharacteristic*>> characteristics; HRESULT hr = characteristics_result->get_Characteristics(&characteristics); if (FAILED(hr)) { - VLOG(2) << "Getting Characteristics failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Characteristics failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -318,8 +318,8 @@ hr = gatt_characteristic->get_AttributeHandle( &characteristic_attribute_handle); if (FAILED(hr)) { - VLOG(2) << "Getting AttributeHandle failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting AttributeHandle failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -327,8 +327,8 @@ ComPtr<IGattCharacteristic3> gatt_characteristic_3; hr = gatt_characteristic.As(&gatt_characteristic_3); if (FAILED(hr)) { - VLOG(2) << "Obtaining IGattCharacteristic3 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Obtaining IGattCharacteristic3 failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -336,8 +336,9 @@ ComPtr<IAsyncOperation<GattDescriptorsResult*>> get_descriptors_op; hr = gatt_characteristic_3->GetDescriptorsAsync(&get_descriptors_op); if (FAILED(hr)) { - VLOG(2) << "GattCharacteristic::GetDescriptorsAsync() failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "GattCharacteristic::GetDescriptorsAsync() failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; } @@ -349,8 +350,8 @@ characteristic_attribute_handle)); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); } } @@ -362,6 +363,8 @@ uint16_t characteristic_attribute_handle, ComPtr<IGattDescriptorsResult> descriptors_result) { if (!CheckCommunicationStatus(descriptors_result.Get())) { + BLUETOOTH_LOG(DEBUG) << "Failed to get descriptors for characteristic " + << characteristic_attribute_handle << "."; std::move(callback_).Run(false); return; } @@ -369,8 +372,8 @@ ComPtr<IVectorView<GattDescriptor*>> descriptors; HRESULT hr = descriptors_result->get_Descriptors(&descriptors); if (FAILED(hr)) { - VLOG(2) << "Getting Descriptors failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting descriptors failed: " + << logging::SystemErrorCodeToString(hr); std::move(callback_).Run(false); return; }
diff --git a/device/bluetooth/bluetooth_gatt_discoverer_winrt.h b/device/bluetooth/bluetooth_gatt_discoverer_winrt.h index d174d23..47d13ff 100644 --- a/device/bluetooth/bluetooth_gatt_discoverer_winrt.h +++ b/device/bluetooth/bluetooth_gatt_discoverer_winrt.h
@@ -65,8 +65,9 @@ void OnServiceOpen( Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth:: - GenericAttributeProfile::IGattDeviceService> - gatt_service, + GenericAttributeProfile::IGattDeviceService3> + gatt_service_3, + uint16_t service_attribute_handle, ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattOpenStatus status);
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.cc index f471cc3..334e26b2 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.cc +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.cc
@@ -15,6 +15,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/win/post_async_results.h" #include "base/win/winrt_storage_util.h" +#include "components/device_event_log/device_event_log.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_gatt_discoverer_winrt.h" @@ -77,23 +78,24 @@ GUID guid; HRESULT hr = characteristic->get_Uuid(&guid); if (FAILED(hr)) { - VLOG(2) << "Getting UUID failed: " << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting UUID failed: " + << logging::SystemErrorCodeToString(hr); return nullptr; } GattCharacteristicProperties properties; hr = characteristic->get_CharacteristicProperties(&properties); if (FAILED(hr)) { - VLOG(2) << "Getting Properties failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Properties failed: " + << logging::SystemErrorCodeToString(hr); return nullptr; } uint16_t attribute_handle; hr = characteristic->get_AttributeHandle(&attribute_handle); if (FAILED(hr)) { - VLOG(2) << "Getting AttributeHandle failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting AttributeHandle failed: " + << logging::SystemErrorCodeToString(hr); return nullptr; } @@ -170,8 +172,9 @@ HRESULT hr = characteristic_->ReadValueWithCacheModeAsync( BluetoothCacheMode_Uncached, &read_value_op); if (FAILED(hr)) { - VLOG(2) << "GattCharacteristic::ReadValueWithCacheModeAsync failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "GattCharacteristic::ReadValueWithCacheModeAsync failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -185,8 +188,8 @@ weak_ptr_factory_.GetWeakPtr())); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -222,8 +225,8 @@ ComPtr<IGattCharacteristic3> characteristic_3; HRESULT hr = characteristic_.As(&characteristic_3); if (FAILED(hr)) { - VLOG(2) << "As IGattCharacteristic3 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "As IGattCharacteristic3 failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -234,8 +237,8 @@ ComPtr<IBuffer> buffer; hr = base::win::CreateIBufferFromData(value.data(), value.size(), &buffer); if (FAILED(hr)) { - VLOG(2) << "base::win::CreateIBufferFromData failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "base::win::CreateIBufferFromData failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -251,8 +254,9 @@ &write_value_op); if (FAILED(hr)) { - VLOG(2) << "GattCharacteristic::WriteValueWithResultAndOptionAsync failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "GattCharacteristic::WriteValueWithResultAndOptionAsync failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -267,8 +271,8 @@ weak_ptr_factory_.GetWeakPtr())); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -318,16 +322,16 @@ ComPtr<IGattCharacteristic3> characteristic_3; HRESULT hr = characteristic_.As(&characteristic_3); if (FAILED(hr)) { - VLOG(2) << "As IGattCharacteristic3 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "As IGattCharacteristic3 failed: " + << logging::SystemErrorCodeToString(hr); return false; } ComPtr<IBuffer> buffer; hr = base::win::CreateIBufferFromData(value.data(), value.size(), &buffer); if (FAILED(hr)) { - VLOG(2) << "base::win::CreateIBufferFromData failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "base::win::CreateIBufferFromData failed: " + << logging::SystemErrorCodeToString(hr); return false; } @@ -338,8 +342,9 @@ hr = characteristic_3->WriteValueWithResultAndOptionAsync( buffer.Get(), GattWriteOption_WriteWithoutResponse, &write_value_op); if (FAILED(hr)) { - VLOG(2) << "GattCharacteristic::WriteValueWithResultAndOptionAsync failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "GattCharacteristic::WriteValueWithResultAndOptionAsync failed: " + << logging::SystemErrorCodeToString(hr); return false; } @@ -348,8 +353,8 @@ hr = base::win::PostAsyncResults(std::move(write_value_op), base::DoNothing()); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); return false; } @@ -372,7 +377,7 @@ weak_ptr_factory_.GetWeakPtr())); if (!value_changed_token_) { - VLOG(2) << "Adding Value Changed Handler failed."; + BLUETOOTH_LOG(DEBUG) << "Adding Value Changed Handler failed."; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -454,8 +459,8 @@ ComPtr<IGattCharacteristic3> characteristic_3; HRESULT hr = characteristic_.As(&characteristic_3); if (FAILED(hr)) { - VLOG(2) << "As IGattCharacteristic3 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "As IGattCharacteristic3 failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -468,10 +473,11 @@ ->WriteClientCharacteristicConfigurationDescriptorWithResultAsync( value, &write_ccc_descriptor_op); if (FAILED(hr)) { - VLOG(2) << "GattCharacteristic::" - "WriteClientCharacteristicConfigurationDescriptorWithResultAsync" - " failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) + << "GattCharacteristic::" + "WriteClientCharacteristicConfigurationDescriptorWithResultAsync" + " failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -486,8 +492,8 @@ weak_ptr_factory_.GetWeakPtr())); if (FAILED(hr)) { - VLOG(2) << "PostAsyncResults failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "PostAsyncResults failed: " + << logging::SystemErrorCodeToString(hr); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(error_callback), @@ -514,20 +520,20 @@ GattCommunicationStatus status; HRESULT hr = read_result->get_Status(&status); if (FAILED(hr)) { - VLOG(2) << "Getting GATT Communication Status failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting GATT Communication Status failed: " + << logging::SystemErrorCodeToString(hr); std::move(pending_read_callbacks->error_callback) .Run(BluetoothGattService::GATT_ERROR_FAILED); return; } if (status != GattCommunicationStatus_Success) { - VLOG(2) << "Unexpected GattCommunicationStatus: " << status; + BLUETOOTH_LOG(DEBUG) << "Unexpected GattCommunicationStatus: " << status; ComPtr<IGattReadResult2> read_result_2; hr = read_result.As(&read_result_2); if (FAILED(hr)) { - VLOG(2) << "As IGattReadResult2 failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "As IGattReadResult2 failed: " + << logging::SystemErrorCodeToString(hr); std::move(pending_read_callbacks->error_callback) .Run(BluetoothGattService::GATT_ERROR_FAILED); return; @@ -542,8 +548,8 @@ ComPtr<IBuffer> value; hr = read_result->get_Value(&value); if (FAILED(hr)) { - VLOG(2) << "Getting Characteristic Value failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Characteristic Value failed: " + << logging::SystemErrorCodeToString(hr); std::move(pending_read_callbacks->error_callback) .Run(BluetoothGattService::GATT_ERROR_FAILED); return; @@ -553,8 +559,8 @@ uint32_t length = 0; hr = base::win::GetPointerToBufferData(value.Get(), &data, &length); if (FAILED(hr)) { - VLOG(2) << "Getting Pointer To Buffer Data failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Pointer To Buffer Data failed: " + << logging::SystemErrorCodeToString(hr); std::move(pending_read_callbacks->error_callback) .Run(BluetoothGattService::GATT_ERROR_FAILED); return; @@ -588,15 +594,15 @@ GattCommunicationStatus status; HRESULT hr = write_result->get_Status(&status); if (FAILED(hr)) { - VLOG(2) << "Getting GATT Communication Status failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting GATT Communication Status failed: " + << logging::SystemErrorCodeToString(hr); std::move(callbacks->error_callback) .Run(BluetoothGattService::GATT_ERROR_FAILED); return; } if (status != GattCommunicationStatus_Success) { - VLOG(2) << "Unexpected GattCommunicationStatus: " << status; + BLUETOOTH_LOG(DEBUG) << "Unexpected GattCommunicationStatus: " << status; std::move(callbacks->error_callback) .Run(BluetoothRemoteGattServiceWinrt::GetGattErrorCode( write_result.Get())); @@ -612,8 +618,8 @@ ComPtr<IBuffer> value; HRESULT hr = event_args->get_CharacteristicValue(&value); if (FAILED(hr)) { - VLOG(2) << "Getting Characteristic Value failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Characteristic Value failed: " + << logging::SystemErrorCodeToString(hr); return; } @@ -621,8 +627,8 @@ uint32_t length = 0; hr = base::win::GetPointerToBufferData(value.Get(), &data, &length); if (FAILED(hr)) { - VLOG(2) << "Getting Pointer To Buffer Data failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Getting Pointer To Buffer Data failed: " + << logging::SystemErrorCodeToString(hr); return; } @@ -635,8 +641,8 @@ DCHECK(value_changed_token_); HRESULT hr = characteristic_->remove_ValueChanged(*value_changed_token_); if (FAILED(hr)) { - VLOG(2) << "Removing the Value Changed Handler failed: " - << logging::SystemErrorCodeToString(hr); + BLUETOOTH_LOG(DEBUG) << "Removing the Value Changed Handler failed: " + << logging::SystemErrorCodeToString(hr); } value_changed_token_.reset();
diff --git a/device/fido/bio/enrollment.cc b/device/fido/bio/enrollment.cc index c33b14b..6608817 100644 --- a/device/fido/bio/enrollment.cc +++ b/device/fido/bio/enrollment.cc
@@ -10,6 +10,23 @@ namespace device { +static void SetPinAuth(BioEnrollmentRequest* request, + const pin::TokenResponse& token) { + request->pin_protocol = 1; + request->modality = BioEnrollmentModality::kFingerprint; + + std::vector<uint8_t> pin_auth; + if (request->params) + pin_auth = *cbor::Writer::Write(cbor::Value(request->params.value())); + + if (request->subcommand) + pin_auth.insert(pin_auth.begin(), static_cast<int>(*request->subcommand)); + + pin_auth.insert(pin_auth.begin(), static_cast<int>(*request->modality)); + + request->pin_auth = token.PinAuth(std::move(pin_auth)); +} + // static BioEnrollmentRequest BioEnrollmentRequest::ForGetModality() { BioEnrollmentRequest request; @@ -27,37 +44,24 @@ // static BioEnrollmentRequest BioEnrollmentRequest::ForEnrollBegin( - const pin::TokenResponse& response) { + const pin::TokenResponse& token) { BioEnrollmentRequest request; - request.pin_protocol = 1; - request.modality = BioEnrollmentModality::kFingerprint; request.subcommand = BioEnrollmentSubCommand::kEnrollBegin; - request.pin_auth = response.PinAuth( - std::vector<uint8_t>{static_cast<uint8_t>(*request.modality), - static_cast<uint8_t>(*request.subcommand)}); + SetPinAuth(&request, token); return request; } // static BioEnrollmentRequest BioEnrollmentRequest::ForEnrollNextSample( - const pin::TokenResponse& response, + const pin::TokenResponse& token, std::vector<uint8_t> template_id) { BioEnrollmentRequest request; - request.pin_protocol = 1; - request.modality = BioEnrollmentModality::kFingerprint; request.subcommand = BioEnrollmentSubCommand::kEnrollCaptureNextSample; request.params = cbor::Value::MapValue(); request.params->emplace( static_cast<int>(BioEnrollmentSubCommandParam::kTemplateId), cbor::Value(template_id)); - - std::vector<uint8_t> pin_auth = - *cbor::Writer::Write(cbor::Value(*request.params)); - pin_auth.insert(pin_auth.begin(), static_cast<int>(*request.subcommand)); - pin_auth.insert(pin_auth.begin(), static_cast<int>(*request.modality)); - - request.pin_auth = response.PinAuth(std::move(pin_auth)); - + SetPinAuth(&request, token); return request; } @@ -71,38 +75,25 @@ // static BioEnrollmentRequest BioEnrollmentRequest::ForEnumerate( - const pin::TokenResponse& response) { + const pin::TokenResponse& token) { BioEnrollmentRequest request; - request.modality = BioEnrollmentModality::kFingerprint; request.subcommand = BioEnrollmentSubCommand::kEnumerateEnrollments; - request.pin_protocol = 1; - request.pin_auth = response.PinAuth( - std::vector<uint8_t>{static_cast<int>(*request.modality), - static_cast<int>(*request.subcommand)}); + SetPinAuth(&request, token); return request; } // static BioEnrollmentRequest BioEnrollmentRequest::ForRename( - const pin::TokenResponse& response, + const pin::TokenResponse& token, std::vector<uint8_t> id, std::string name) { BioEnrollmentRequest request; - request.pin_protocol = 1; - request.modality = BioEnrollmentModality::kFingerprint; request.subcommand = BioEnrollmentSubCommand::kSetFriendlyName; request.params = cbor::Value::MapValue(); request.params->emplace( static_cast<int>(BioEnrollmentSubCommandParam::kTemplateId), cbor::Value(std::move(id))); - - std::vector<uint8_t> pin_auth = - *cbor::Writer::Write(cbor::Value(*request.params)); - pin_auth.insert(pin_auth.begin(), static_cast<int>(*request.subcommand)); - pin_auth.insert(pin_auth.begin(), static_cast<int>(*request.modality)); - - request.pin_auth = response.PinAuth(std::move(pin_auth)); - + SetPinAuth(&request, token); return request; }
diff --git a/device/fido/fido_authenticator.cc b/device/fido/fido_authenticator.cc index 1e2929a..fc3679c 100644 --- a/device/fido/fido_authenticator.cc +++ b/device/fido/fido_authenticator.cc
@@ -91,7 +91,7 @@ NOTREACHED(); } -void FidoAuthenticator::BioEnrollFingerprint(pin::TokenResponse, +void FidoAuthenticator::BioEnrollFingerprint(const pin::TokenResponse&, BioEnrollmentCallback) { NOTREACHED(); } @@ -100,12 +100,12 @@ NOTREACHED(); } -void FidoAuthenticator::BioEnrollEnumerate(pin::TokenResponse, +void FidoAuthenticator::BioEnrollEnumerate(const pin::TokenResponse&, BioEnrollmentCallback) { NOTREACHED(); } -void FidoAuthenticator::BioEnrollRename(pin::TokenResponse, +void FidoAuthenticator::BioEnrollRename(const pin::TokenResponse&, std::vector<uint8_t>, std::string, BioEnrollmentCallback) {
diff --git a/device/fido/fido_authenticator.h b/device/fido/fido_authenticator.h index ca04ead..54a96b9 100644 --- a/device/fido/fido_authenticator.h +++ b/device/fido/fido_authenticator.h
@@ -168,13 +168,15 @@ base::span<const uint8_t> credential_id, DeleteCredentialCallback callback); - // bio enrollment + // Biometric enrollment commands. virtual void GetModality(BioEnrollmentCallback callback); virtual void GetSensorInfo(BioEnrollmentCallback callback); - virtual void BioEnrollFingerprint(pin::TokenResponse, BioEnrollmentCallback); + virtual void BioEnrollFingerprint(const pin::TokenResponse&, + BioEnrollmentCallback); virtual void BioEnrollCancel(BioEnrollmentCallback); - virtual void BioEnrollEnumerate(pin::TokenResponse, BioEnrollmentCallback); - virtual void BioEnrollRename(pin::TokenResponse, + virtual void BioEnrollEnumerate(const pin::TokenResponse&, + BioEnrollmentCallback); + virtual void BioEnrollRename(const pin::TokenResponse&, std::vector<uint8_t>, std::string, BioEnrollmentCallback);
diff --git a/device/fido/fido_device_authenticator.cc b/device/fido/fido_device_authenticator.cc index 6c3e677..c8596387 100644 --- a/device/fido/fido_device_authenticator.cc +++ b/device/fido/fido_device_authenticator.cc
@@ -513,7 +513,7 @@ } void FidoDeviceAuthenticator::BioEnrollFingerprint( - pin::TokenResponse token, + const pin::TokenResponse& token, BioEnrollmentCallback callback) { DCHECK( Options()->bio_enrollment_availability_preview != @@ -527,7 +527,7 @@ base::BindOnce(&BioEnrollmentResponse::Parse)); } -void FidoDeviceAuthenticator::BioEnrollRename(pin::TokenResponse token, +void FidoDeviceAuthenticator::BioEnrollRename(const pin::TokenResponse& token, std::vector<uint8_t> id, std::string name, BioEnrollmentCallback callback) { @@ -535,13 +535,9 @@ Options()->bio_enrollment_availability_preview != AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - operation_ = std::make_unique< - Ctap2DeviceOperation<BioEnrollmentRequest, BioEnrollmentResponse>>( - device_.get(), + RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( BioEnrollmentRequest::ForRename(token, std::move(id), std::move(name)), - std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse), - /*string_fixup_predicate=*/nullptr); - operation_->Start(); + std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::OnBioEnroll( @@ -577,18 +573,15 @@ } void FidoDeviceAuthenticator::BioEnrollEnumerate( - pin::TokenResponse token, + const pin::TokenResponse& token, BioEnrollmentCallback callback) { DCHECK( Options()->bio_enrollment_availability_preview != AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - operation_ = std::make_unique< - Ctap2DeviceOperation<BioEnrollmentRequest, BioEnrollmentResponse>>( - device_.get(), BioEnrollmentRequest::ForEnumerate(std::move(token)), - std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse), - /*string_fixup_predicate=*/nullptr); - operation_->Start(); + RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( + BioEnrollmentRequest::ForEnumerate(std::move(token)), std::move(callback), + base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::Reset(ResetCallback callback) {
diff --git a/device/fido/fido_device_authenticator.h b/device/fido/fido_device_authenticator.h index 2b99479..111d02d 100644 --- a/device/fido/fido_device_authenticator.h +++ b/device/fido/fido_device_authenticator.h
@@ -81,10 +81,12 @@ void GetModality(BioEnrollmentCallback callback) override; void GetSensorInfo(BioEnrollmentCallback callback) override; - void BioEnrollFingerprint(pin::TokenResponse, BioEnrollmentCallback) override; + void BioEnrollFingerprint(const pin::TokenResponse&, + BioEnrollmentCallback) override; void BioEnrollCancel(BioEnrollmentCallback) override; - void BioEnrollEnumerate(pin::TokenResponse, BioEnrollmentCallback) override; - void BioEnrollRename(pin::TokenResponse, + void BioEnrollEnumerate(const pin::TokenResponse&, + BioEnrollmentCallback) override; + void BioEnrollRename(const pin::TokenResponse&, std::vector<uint8_t>, std::string, BioEnrollmentCallback) override;
diff --git a/device/fido/fido_request_handler.h b/device/fido/fido_request_handler.h index 92ae5e0..6862f3ca 100644 --- a/device/fido/fido_request_handler.h +++ b/device/fido/fido_request_handler.h
@@ -89,6 +89,12 @@ case CtapDeviceResponseCode::kCtap2ErrOperationDenied: return FidoReturnCode::kUserConsentDenied; + // External authenticators may return this error if internal user + // verification fails for a make credential request or if the pin token is + // not valid. + case CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid: + return FidoReturnCode::kUserConsentDenied; + case CtapDeviceResponseCode::kCtap2ErrKeyStoreFull: return FidoReturnCode::kStorageFull;
diff --git a/device/fido/get_assertion_handler_unittest.cc b/device/fido/get_assertion_handler_unittest.cc index e9ab17c..7dbe8df 100644 --- a/device/fido/get_assertion_handler_unittest.cc +++ b/device/fido/get_assertion_handler_unittest.cc
@@ -722,6 +722,24 @@ get_assertion_callback().status()); } +// If a device returns CTAP2_ERR_PIN_AUTH_INVALID, the request should complete +// with FidoReturnCode::kUserConsentDenied. +TEST_F(FidoGetAssertionHandlerTest, TestRequestWithPinAuthInvalid) { + auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation(); + device->ExpectCtap2CommandAndRespondWithError( + CtapRequestCommand::kAuthenticatorGetAssertion, + CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid); + + auto request_handler = CreateGetAssertionHandlerCtap(); + discovery()->WaitForCallToStartAndSimulateSuccess(); + discovery()->AddDevice(std::move(device)); + + scoped_task_environment_.FastForwardUntilNoTasksRemain(); + EXPECT_TRUE(get_assertion_callback().was_called()); + EXPECT_EQ(FidoReturnCode::kUserConsentDenied, + get_assertion_callback().status()); +} + MATCHER_P(IsCtap2Command, expected_command, "") { return !arg.empty() && arg[0] == base::strict_cast<uint8_t>(expected_command); }
diff --git a/device/fido/make_credential_handler_unittest.cc b/device/fido/make_credential_handler_unittest.cc index d6d15b2..e3b821d 100644 --- a/device/fido/make_credential_handler_unittest.cc +++ b/device/fido/make_credential_handler_unittest.cc
@@ -684,6 +684,28 @@ EXPECT_EQ(FidoReturnCode::kUserConsentDenied, callback().status()); } +// If a device returns CTAP2_ERR_PIN_AUTH_INVALID, the request should complete +// with FidoReturnCode::kUserConsentDenied. +TEST_F(FidoMakeCredentialHandlerTest, TestRequestWithPinAuthInvalid) { + auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation(); + device->ExpectCtap2CommandAndRespondWithError( + CtapRequestCommand::kAuthenticatorMakeCredential, + CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid); + + auto request_handler = + CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria( + AuthenticatorSelectionCriteria( + AuthenticatorAttachment::kAny, /*require_resident_key=*/false, + UserVerificationRequirement::kPreferred)); + + discovery()->WaitForCallToStartAndSimulateSuccess(); + discovery()->AddDevice(std::move(device)); + + scoped_task_environment_.FastForwardUntilNoTasksRemain(); + EXPECT_TRUE(callback().was_called()); + EXPECT_EQ(FidoReturnCode::kUserConsentDenied, callback().status()); +} + MATCHER_P(IsCtap2Command, expected_command, "") { return !arg.empty() && arg[0] == base::strict_cast<uint8_t>(expected_command); }
diff --git a/docs/design/sandbox.md b/docs/design/sandbox.md index ad060f18..655ee3ac 100644 --- a/docs/design/sandbox.md +++ b/docs/design/sandbox.md
@@ -46,9 +46,9 @@ usually the case if the OS security is used properly. * **Emulation is not security:** Emulation and virtual machine solutions do not by themselves provide security. The sandbox should not rely on code emulation, - code translation, or patching to provide security. - -## Sandbox windows architecture + code translation, or patching to provide security. + +## Sandbox Windows architecture The Windows sandbox is a user-mode only sandbox. There are no special kernel mode drivers, and the user does not need to be an administrator in order for the @@ -79,10 +79,10 @@ The broker should always outlive all the target processes that it spawned. The sandbox IPC is a low-level mechanism (different from Chromium's IPC) that is -used to transparently forward certain windows API calls from the target to the +used to transparently forward certain Windows API calls from the target to the broker: these calls are evaluated against the policy. The policy-allowed calls are then executed by the broker and the results returned to the target process -via the same IPC. The job of the interceptions manager is to patch the windows +via the same IPC. The job of the interceptions manager is to patch the Windows API calls that should be forwarded via IPC to the broker. ### The target process @@ -122,7 +122,7 @@ * A restricted token * The Windows _job_ object * The Windows _desktop_ object -* Windows Vista and above: The integrity levels +* Integrity levels These mechanisms are highly effective at protecting the OS, its configuration, and the user's data provided that: @@ -139,8 +139,7 @@ One issue that other similar sandbox projects face is how restricted can the token and job be while still having a properly functioning process. For the -Chromium sandbox, the most restrictive token for Windows XP takes the following -form: +Chromium sandbox, the most restrictive token takes the following form: #### Regular Groups * Logon SID : mandatory @@ -149,23 +148,22 @@ * S-1-0-0 : mandatory #### Privileges * None +#### Integrity +* Untrusted integrity level label (S-1-16-0x0) With the caveats described above, it is near impossible to find an existing resource that the OS will grant access with such a token. As long as the disk root directories have non-null security, even files with null security cannot be -accessed. In Vista, the most restrictive token is the same but it also includes -the low integrity level label. The Chromium renderer normally runs with this -token, which means that almost all resources that the renderer process uses have -been acquired by the Browser and their handles duplicated into the renderer -process. +accessed. The Chromium renderer runs with this token, which means that almost +all resources that the renderer process uses have been acquired by the Browser +and their handles duplicated into the renderer process. Note that the token is not derived from anonymous or from the guest token; it is derived from the user's token and thus associated to the user logon. As a result, any auditing that the system or the domain has in place can still be used. -By design, the sandbox token cannot protect the following non-securable -resources: +By design, the sandbox token cannot protect the non-securable resources such as: * Mounted FAT or FAT32 volumes: The security descriptor on them is effectively null. Malware running in the target can read and write to these volumes as @@ -173,10 +171,11 @@ * TCP/IP: The security of TCP/IP sockets in Windows 2000 and Windows XP (but not in Vista) is effectively null. It might be possible for malicious code in the target to send and receive network packets to any host. +* Some unlabelled objects, such as anonymous shared memory sections (e.g. + [bug 338538](https://crbug.com/338538)) -More information about the Windows token object can be -found -[here](http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsAToken.htm) +See NULL DACLs and Other Dangerous ACE Types, _Secure Coding Techniques_, 195-199 +for more information. ### The Job object @@ -197,7 +196,7 @@ * One active process limit (disallows creating child processes) Chromium renderers normally run with all these restrictions active. Each -renderers run in its own Job object. Using the Job object, the sandbox can (but +renderer runs in its own Job object. Using the Job object, the sandbox can (but currently does not) prevent: * Excessive use of CPU cycles @@ -205,7 +204,7 @@ * Excessive use of IO More information about Windows Job Objects can be -found [here](http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx) +found [here](https://docs.microsoft.com/en-us/windows/desktop/procthread/job-objects). ### The alternate desktop @@ -247,9 +246,11 @@ By default, a token can read an object of a higher integrity level, but not write to it. Most desktop applications run at medium integrity (MI), while less -trusted processes like Internet Explorer's protected mode and our own sandbox -run at low integrity (LI). A low integrity mode token can access only the -following shared resources: +trusted processes like Internet Explorer's protected mode and our GPU sandbox +run at low integrity (LI), while our renderer processes run at the lowest +Untrusted integrity level. + +A low integrity level token can access only the following shared resources: * Read access to most files * Write access to `%USER PROFILE%\AppData\LocalLow` @@ -263,6 +264,9 @@ * COM interfaces with LI (low integrity) launch activation rights * Named pipes exposed via LI (low integrity) labels +While an Untrusted integrity level can only write to resources which +have a null DACL or an explicit Untrusted Mandatory Level. + You'll notice that the previously described attributes of the token, job object, and alternate desktop are more restrictive, and would in fact block access to everything allowed in the above list. So, the integrity level is a bit redundant @@ -270,8 +274,15 @@ defense-in-depth, and its use has no visible impact on performance or resource usage. +The integrity level of different Chrome components will change over +time as functionality is split into smaller services. At M75 the +browser, crash handler, and network utility processes run at Medium +integrity, the GPU process at Low and most remaining services +including isolated renderers at Untrusted. + More information on integrity levels can be -found [here](http://msdn.microsoft.com/en-us/library/bb625963.aspx). +found [here](http://msdn.microsoft.com/en-us/library/bb625963.aspx) +and in Chapter 7 of *Windows Internals, Part 1, 7th Ed.*. ### Process mitigation policies
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.cc b/extensions/browser/api/web_request/web_request_proxying_websocket.cc index 8edc34b..f881dd2 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.cc +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.cc
@@ -217,15 +217,16 @@ void WebRequestProxyingWebSocket::OnAddChannelResponse( const std::string& selected_protocol, - const std::string& extensions) { + const std::string& extensions, + uint64_t receive_quota_threshold) { DCHECK(forwarding_handshake_client_); DCHECK(!is_done_); is_done_ = true; ExtensionWebRequestEventRouter::GetInstance()->OnCompleted( browser_context_, info_map_, &info_.value(), net::ERR_WS_UPGRADE); - forwarding_handshake_client_->OnAddChannelResponse(selected_protocol, - extensions); + forwarding_handshake_client_->OnAddChannelResponse( + selected_protocol, extensions, receive_quota_threshold); } void WebRequestProxyingWebSocket::OnAuthRequired(
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.h b/extensions/browser/api/web_request/web_request_proxying_websocket.h index 067780d..852e6ff 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.h +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.h
@@ -75,7 +75,8 @@ void OnFinishOpeningHandshake( network::mojom::WebSocketHandshakeResponsePtr response) override; void OnAddChannelResponse(const std::string& selected_protocol, - const std::string& extensions) override; + const std::string& extensions, + uint64_t receive_quota_threshold) override; // mojom::AuthenticationHandler method: void OnAuthRequired(const net::AuthChallengeInfo& auth_info,
diff --git a/google_apis/gaia/gaia_auth_fetcher.cc b/google_apis/gaia/gaia_auth_fetcher.cc index f580fdf..b90f1be 100644 --- a/google_apis/gaia/gaia_auth_fetcher.cc +++ b/google_apis/gaia/gaia_auth_fetcher.cc
@@ -219,6 +219,8 @@ list_accounts_gurl_( GaiaUrls::GetInstance()->ListAccountsURLWithSource(source_)), logout_gurl_(GaiaUrls::GetInstance()->LogOutURLWithSource(source_)), + logout_with_continue_gurl_( + GaiaUrls::GetInstance()->LogOutURLWithSourceAndContinueURL(source_)), get_check_connection_info_url_( GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource( source_)) {} @@ -792,6 +794,14 @@ } void GaiaAuthFetcher::StartLogOut() { + StartLogOutInternal(logout_gurl_); +} + +void GaiaAuthFetcher::StartLogOutWithBlankContinueURL() { + StartLogOutInternal(logout_with_continue_gurl_); +} + +void GaiaAuthFetcher::StartLogOutInternal(const GURL& logout_gurl) { DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; net::NetworkTrafficAnnotationTag traffic_annotation = @@ -821,7 +831,7 @@ } } })"); - CreateAndStartGaiaFetcher(std::string(), std::string(), logout_gurl_, + CreateAndStartGaiaFetcher(std::string(), std::string(), logout_gurl, net::LOAD_NORMAL, traffic_annotation); } @@ -1104,7 +1114,7 @@ OnOAuth2RevokeTokenFetched(data, net_error, response_code); } else if (url == list_accounts_gurl_) { OnListAccountsFetched(data, net_error, response_code); - } else if (url == logout_gurl_) { + } else if (url == logout_gurl_ || url == logout_with_continue_gurl_) { OnLogOutFetched(data, net_error, response_code); } else if (url == get_check_connection_info_url_) { OnGetCheckConnectionInfoFetched(data, net_error, response_code);
diff --git a/google_apis/gaia/gaia_auth_fetcher.h b/google_apis/gaia/gaia_auth_fetcher.h index 8709676..ec29c53 100644 --- a/google_apis/gaia/gaia_auth_fetcher.h +++ b/google_apis/gaia/gaia_auth_fetcher.h
@@ -160,6 +160,10 @@ // Starts a request to log out the accounts in the GAIA cookie. void StartLogOut(); + // Starts a request to log out the accounts in the GAIA cookie. Uses Logout + // endpoint with continue URL. + void StartLogOutWithBlankContinueURL(); + // Starts a request to get the list of URLs to check for connection info. // Returns token/URL pairs to check, and the resulting status can be given to // /MergeSession requests. @@ -250,6 +254,9 @@ static const char kOAuth2BearerHeaderFormat[]; static const char kOAuthMultiBearerHeaderFormat[]; + // Starts logout flow with an explicit GURL. + void StartLogOutInternal(const GURL& logout_gurl); + void OnURLLoadComplete(std::unique_ptr<std::string> response_body); void OnOAuth2TokenPairFetched(const std::string& data, @@ -348,6 +355,7 @@ const GURL oauth_multilogin_gurl_; const GURL list_accounts_gurl_; const GURL logout_gurl_; + const GURL logout_with_continue_gurl_; const GURL get_check_connection_info_url_; // While a fetch is going on:
diff --git a/google_apis/gaia/gaia_urls.cc b/google_apis/gaia/gaia_urls.cc index ffce9b4..c464feb 100644 --- a/google_apis/gaia/gaia_urls.cc +++ b/google_apis/gaia/gaia_urls.cc
@@ -31,6 +31,7 @@ const char kSigninChromeSyncDice[] = "signin/chrome/sync?ssp=1"; const char kServiceLoginAuthUrlSuffix[] = "ServiceLoginAuth"; const char kServiceLogoutUrlSuffix[] = "Logout"; +const char kContinueUrlForLogoutSuffix[] = "chrome/blank.html"; const char kGetUserInfoUrlSuffix[] = "GetUserInfo"; const char kTokenAuthUrlSuffix[] = "TokenAuth"; const char kMergeSessionUrlSuffix[] = "MergeSession"; @@ -117,6 +118,7 @@ signin_chrome_sync_dice_ = gaia_url_.Resolve(kSigninChromeSyncDice); service_login_auth_url_ = gaia_url_.Resolve(kServiceLoginAuthUrlSuffix); service_logout_url_ = gaia_url_.Resolve(kServiceLogoutUrlSuffix); + continue_url_for_logout_ = gaia_url_.Resolve(kContinueUrlForLogoutSuffix); get_user_info_url_ = gaia_url_.Resolve(kGetUserInfoUrlSuffix); token_auth_url_ = gaia_url_.Resolve(kTokenAuthUrlSuffix); merge_session_url_ = gaia_url_.Resolve(kMergeSessionUrlSuffix); @@ -297,6 +299,16 @@ base::StringPrintf("?source=%s", source.c_str())); } +GURL GaiaUrls::LogOutURLWithSourceAndContinueURL(const std::string& source) { + std::string params = + source.empty() + ? base::StringPrintf("?continue=%s", + continue_url_for_logout_.spec().c_str()) + : base::StringPrintf("?source=%s&continue=%s", source.c_str(), + continue_url_for_logout_.spec().c_str()); + return service_logout_url_.Resolve(params); +} + GURL GaiaUrls::GetCheckConnectionInfoURLWithSource(const std::string& source) { return source.empty() ? get_check_connection_info_url_
diff --git a/google_apis/gaia/gaia_urls.h b/google_apis/gaia/gaia_urls.h index f011761..68455c9 100644 --- a/google_apis/gaia/gaia_urls.h +++ b/google_apis/gaia/gaia_urls.h
@@ -52,6 +52,7 @@ GURL ListAccountsURLWithSource(const std::string& source); GURL LogOutURLWithSource(const std::string& source); + GURL LogOutURLWithSourceAndContinueURL(const std::string& source); GURL GetCheckConnectionInfoURLWithSource(const std::string& source); private: @@ -72,6 +73,7 @@ GURL signin_chrome_sync_dice_; GURL service_login_auth_url_; GURL service_logout_url_; + GURL continue_url_for_logout_; GURL get_user_info_url_; GURL token_auth_url_; GURL merge_session_url_;
diff --git a/google_apis/gaia/oauth2_access_token_manager.cc b/google_apis/gaia/oauth2_access_token_manager.cc index 4373c650..c6cef64 100644 --- a/google_apis/gaia/oauth2_access_token_manager.cc +++ b/google_apis/gaia/oauth2_access_token_manager.cc
@@ -6,7 +6,11 @@ #include "base/time/time.h" -OAuth2AccessTokenManager::OAuth2AccessTokenManager() = default; +OAuth2AccessTokenManager::OAuth2AccessTokenManager( + OAuth2TokenService* token_service) + : token_service_(token_service) { + DCHECK(token_service_); +} OAuth2AccessTokenManager::~OAuth2AccessTokenManager() = default; @@ -35,3 +39,47 @@ } return &token_iterator->second; } + +void OAuth2AccessTokenManager::ClearCache() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + for (const auto& entry : token_cache_) { + for (auto& observer : token_service_->GetDiagnicsObservers()) + observer.OnAccessTokenRemoved(entry.first.account_id, entry.first.scopes); + } + + token_cache_.clear(); +} + +void OAuth2AccessTokenManager::ClearCacheForAccount( + const CoreAccountId& account_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + for (OAuth2TokenService::TokenCache::iterator iter = token_cache_.begin(); + iter != token_cache_.end(); + /* iter incremented in body */) { + if (iter->first.account_id == account_id) { + for (auto& observer : token_service_->GetDiagnicsObservers()) + observer.OnAccessTokenRemoved(account_id, iter->first.scopes); + token_cache_.erase(iter++); + } else { + ++iter; + } + } +} + +bool OAuth2AccessTokenManager::RemoveCachedTokenResponse( + const OAuth2TokenService::RequestParameters& request_parameters, + const std::string& token_to_remove) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + OAuth2TokenService::OAuth2TokenService::TokenCache::iterator token_iterator = + token_cache_.find(request_parameters); + if (token_iterator != token_cache_.end() && + token_iterator->second.access_token == token_to_remove) { + for (auto& observer : token_service_->GetDiagnicsObservers()) { + observer.OnAccessTokenRemoved(request_parameters.account_id, + request_parameters.scopes); + } + token_cache_.erase(token_iterator); + return true; + } + return false; +}
diff --git a/google_apis/gaia/oauth2_access_token_manager.h b/google_apis/gaia/oauth2_access_token_manager.h index c808466..95bda00 100644 --- a/google_apis/gaia/oauth2_access_token_manager.h +++ b/google_apis/gaia/oauth2_access_token_manager.h
@@ -15,7 +15,10 @@ // Class that manages requests for OAuth2 access tokens. class OAuth2AccessTokenManager { public: - OAuth2AccessTokenManager(); + // TODO(https://crbug.com/967598): Remove |token_service| parameter once + // OAuth2AccessTokenManager fully manages access tokens independently of + // OAuth2TokenService. + explicit OAuth2AccessTokenManager(OAuth2TokenService* token_service); virtual ~OAuth2AccessTokenManager(); // Add a new entry to the cache. @@ -32,6 +35,14 @@ const OAuth2AccessTokenConsumer::TokenResponse* GetCachedTokenResponse( const OAuth2TokenService::RequestParameters& client_scopes); + // Clears the internal token cache. + void ClearCache(); + + // Clears all of the tokens belonging to |account_id| from the internal token + // cache. It does not matter what other parameters, like |client_id| were + // used to request the tokens. + void ClearCacheForAccount(const CoreAccountId& account_id); + private: // TODO(https://crbug.com/967598): Remove this once |token_cache_| management // is moved to OAuth2AccessTokenManager. @@ -39,8 +50,17 @@ OAuth2TokenService::TokenCache& token_cache() { return token_cache_; } + // Removes an access token for the given set of scopes from the cache. + // Returns true if the entry was removed, otherwise false. + bool RemoveCachedTokenResponse( + const OAuth2TokenService::RequestParameters& client_scopes, + const std::string& token_to_remove); + // The cache of currently valid tokens. OAuth2TokenService::TokenCache token_cache_; + // TODO(https://crbug.com/967598): Remove this once OAuth2AccessTokenManager + // fully manages access tokens independently of OAuth2TokenService. + OAuth2TokenService* token_service_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/google_apis/gaia/oauth2_token_service.cc b/google_apis/gaia/oauth2_token_service.cc index 9e43e6f..1d305e89 100644 --- a/google_apis/gaia/oauth2_token_service.cc +++ b/google_apis/gaia/oauth2_token_service.cc
@@ -394,7 +394,7 @@ : delegate_(std::move(delegate)), all_credentials_loaded_(false) { DCHECK(delegate_); AddObserver(this); - token_manager_ = std::make_unique<OAuth2AccessTokenManager>(); + token_manager_ = std::make_unique<OAuth2AccessTokenManager>(this); } OAuth2TokenService::~OAuth2TokenService() { @@ -657,8 +657,8 @@ const ScopeSet& scopes, const std::string& access_token) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - RemoveCachedTokenResponse(RequestParameters(client_id, account_id, scopes), - access_token); + token_manager_->RemoveCachedTokenResponse( + RequestParameters(client_id, account_id, scopes), access_token); delegate_->InvalidateAccessToken(account_id, client_id, scopes, access_token); } @@ -727,23 +727,6 @@ return token_manager_->GetCachedTokenResponse(request_parameters); } -bool OAuth2TokenService::RemoveCachedTokenResponse( - const RequestParameters& request_parameters, - const std::string& token_to_remove) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - TokenCache::iterator token_iterator = token_cache().find(request_parameters); - if (token_iterator != token_cache().end() && - token_iterator->second.access_token == token_to_remove) { - for (auto& observer : diagnostics_observer_list_) { - observer.OnAccessTokenRemoved(request_parameters.account_id, - request_parameters.scopes); - } - token_cache().erase(token_iterator); - return true; - } - return false; -} - void OAuth2TokenService::OnRefreshTokensLoaded() { all_credentials_loaded_ = true; } @@ -765,27 +748,12 @@ void OAuth2TokenService::ClearCache() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - for (const auto& entry : token_cache()) { - for (auto& observer : diagnostics_observer_list_) - observer.OnAccessTokenRemoved(entry.first.account_id, entry.first.scopes); - } - - token_cache().clear(); + token_manager_->ClearCache(); } void OAuth2TokenService::ClearCacheForAccount(const CoreAccountId& account_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - for (TokenCache::iterator iter = token_cache().begin(); - iter != token_cache().end(); - /* iter incremented in body */) { - if (iter->first.account_id == account_id) { - for (auto& observer : diagnostics_observer_list_) - observer.OnAccessTokenRemoved(account_id, iter->first.scopes); - token_cache().erase(iter++); - } else { - ++iter; - } - } + token_manager_->ClearCacheForAccount(account_id); } void OAuth2TokenService::CancelAllRequests() {
diff --git a/google_apis/gaia/oauth2_token_service.h b/google_apis/gaia/oauth2_token_service.h index d57bc9a..f5ab0535 100644 --- a/google_apis/gaia/oauth2_token_service.h +++ b/google_apis/gaia/oauth2_token_service.h
@@ -259,6 +259,11 @@ // OAuth2TokenServiceTest. OAuth2TokenService::TokenCache& token_cache(); + const base::ObserverList<DiagnosticsObserver, true>::Unchecked& + GetDiagnicsObservers() { + return diagnostics_observer_list_; + } + protected: // Implements a cancelable |OAuth2TokenService::Request|, which should be // operated on the UI thread. @@ -344,11 +349,6 @@ const ScopeSet& scopes, const std::string& access_token); - const base::ObserverList<DiagnosticsObserver, true>::Unchecked& - GetDiagnicsObservers() { - return diagnostics_observer_list_; - } - private: class Fetcher; friend class Fetcher; @@ -382,11 +382,6 @@ const OAuth2AccessTokenConsumer::TokenResponse* GetCachedTokenResponse( const RequestParameters& client_scopes); - // Removes an access token for the given set of scopes from the cache. - // Returns true if the entry was removed, otherwise false. - bool RemoveCachedTokenResponse(const RequestParameters& client_scopes, - const std::string& token_to_remove); - // Called when |fetcher| finishes fetching. void OnFetchComplete(Fetcher* fetcher);
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 052b441e..ceb3f8c 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -277,6 +277,7 @@ #define glFramebufferParameteri GLES2_GET_FUN(FramebufferParameteri) #define glBindImageTexture GLES2_GET_FUN(BindImageTexture) #define glDispatchCompute GLES2_GET_FUN(DispatchCompute) +#define glDispatchComputeIndirect GLES2_GET_FUN(DispatchComputeIndirect) #define glGetProgramInterfaceiv GLES2_GET_FUN(GetProgramInterfaceiv) #define glGetProgramResourceIndex GLES2_GET_FUN(GetProgramResourceIndex) #define glGetProgramResourceName GLES2_GET_FUN(GetProgramResourceName)
diff --git a/gpu/command_buffer/PRESUBMIT.py b/gpu/command_buffer/PRESUBMIT.py index 170c9ce..c1f484c 100644 --- a/gpu/command_buffer/PRESUBMIT.py +++ b/gpu/command_buffer/PRESUBMIT.py
@@ -1,7 +1,6 @@ # 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. - """Enforces command buffer autogen matches script output. See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts @@ -11,60 +10,84 @@ import os.path +def _IsGLES2CmdBufferFile(file): + filename = os.path.basename(file.LocalPath()) + if filename in [ + 'build_cmd_buffer_lib.py', 'build_gles2_cmd_buffer.py', + 'gles2_cmd_buffer_functions.txt', 'gl2.h', 'gl2ext.h', 'gl3.h', 'gl31.h', + 'gl2chromium.h', 'gl2extchromium.h' + ]: + return True + + return ((filename.startswith('gles2') or filename.startswith('context_state') + or filename.startswith('client_context_state')) and + filename.endswith('_autogen.h')) + + +def _IsRasterCmdBufferFile(file): + filename = os.path.basename(file.LocalPath()) + if filename in [ + 'build_cmd_buffer_lib.py', 'build_raster_cmd_buffer.py', + 'raster_cmd_buffer_functions.txt' + ]: + return True + + return filename.startswith('raster') and filename.endswith('_autogen.h') + + +def _IsWebGPUCmdBufferFile(file): + filename = os.path.basename(file.LocalPath()) + if filename in [ + 'build_cmd_buffer_lib.py', 'build_webgpu_cmd_buffer.py', + 'webgpu_cmd_buffer_functions.txt' + ]: + return True + + return filename.startswith('webgpu') and filename.endswith('_autogen.h') + + def CommonChecks(input_api, output_api): gles2_cmd_buffer_files = input_api.AffectedFiles( - file_filter=lambda x: os.path.basename(x.LocalPath()) in [ - 'build_cmd_buffer_lib.py', 'build_gles2_cmd_buffer.py', - 'gles2_cmd_buffer_functions.txt']) + file_filter=_IsGLES2CmdBufferFile) raster_cmd_buffer_files = input_api.AffectedFiles( - file_filter=lambda x: os.path.basename(x.LocalPath()) in [ - 'build_cmd_buffer_lib.py', 'build_raster_cmd_buffer.py', - 'raster_cmd_buffer_functions.txt']) + file_filter=_IsRasterCmdBufferFile) webgpu_cmd_buffer_files = input_api.AffectedFiles( - file_filter=lambda x: os.path.basename(x.LocalPath()) in [ - 'build_cmd_buffer_lib.py', 'build_webgpu_cmd_buffer.py', - 'webgpu_cmd_buffer_functions.txt']) - - autogen_files = input_api.AffectedFiles( - file_filter=lambda x: x.LocalPath().endswith('_autogen.h')) - - # Use input_api.change.AffectedFiles() to get files outside this directory. - external_gl_headers = input_api.change.AffectedFiles( - file_filter=lambda x: os.path.basename(x.LocalPath()) in [ - 'gl2.h', 'gl2ext.h', 'gl3.h', 'gl31.h', 'gl2chromium.h', - 'gl2extchromium.h' - ]) + file_filter=_IsWebGPUCmdBufferFile) messages = [] - if (len(autogen_files) > 0 and len(gles2_cmd_buffer_files) == 0 and - len(external_gl_headers) == 0 and len(raster_cmd_buffer_files) == 0 and - len(webgpu_cmd_buffer_files) == 0): - long_text = 'Changed files:\n' - for file in autogen_files: - long_text += file.LocalPath() + '\n' - long_text += '\n' - messages.append(output_api.PresubmitError( - 'Command buffer autogenerated files changed but generators did not.', - long_text=long_text)) - with input_api.temporary_directory() as temp_dir: commands = [] if len(gles2_cmd_buffer_files) > 0: - commands.append(input_api.Command(name='build_gles2_cmd_buffer', - cmd=[input_api.python_executable, 'build_gles2_cmd_buffer.py', - '--check', '--output-dir=' + temp_dir], - kwargs={}, message=output_api.PresubmitError)) + commands.append( + input_api.Command( + name='build_gles2_cmd_buffer', + cmd=[ + input_api.python_executable, 'build_gles2_cmd_buffer.py', + '--check', '--output-dir=' + temp_dir + ], + kwargs={}, + message=output_api.PresubmitError)) if len(raster_cmd_buffer_files) > 0: - commands.append(input_api.Command(name='build_raster_cmd_buffer', - cmd=[input_api.python_executable, 'build_raster_cmd_buffer.py', - '--check', '--output-dir=' + temp_dir], - kwargs={}, message=output_api.PresubmitError)) + commands.append( + input_api.Command( + name='build_raster_cmd_buffer', + cmd=[ + input_api.python_executable, 'build_raster_cmd_buffer.py', + '--check', '--output-dir=' + temp_dir + ], + kwargs={}, + message=output_api.PresubmitError)) if len(webgpu_cmd_buffer_files) > 0: - commands.append(input_api.Command(name='build_webgpu_cmd_buffer', - cmd=[input_api.python_executable, 'build_webgpu_cmd_buffer.py', - '--check', '--output-dir=' + temp_dir], - kwargs={}, message=output_api.PresubmitError)) + commands.append( + input_api.Command( + name='build_webgpu_cmd_buffer', + cmd=[ + input_api.python_executable, 'build_webgpu_cmd_buffer.py', + '--check', '--output-dir=' + temp_dir + ], + kwargs={}, + message=output_api.PresubmitError)) if len(commands) > 0: messages.extend(input_api.RunTests(commands))
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index e830f36..4a4fb94 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -2202,6 +2202,12 @@ 'es31': True, 'unit_test': False, }, + 'DispatchComputeIndirect': { + 'cmd_args': 'GLintptrNotNegative offset', + 'trace_level': 2, + 'es31': True, + 'unit_test': False, + }, 'DrawArrays': { 'type': 'Custom', 'impl_func': False,
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 1772133b..347bd73 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1272,6 +1272,9 @@ gles2::GetGLContext()->DispatchCompute(num_groups_x, num_groups_y, num_groups_z); } +void GL_APIENTRY GLES2DispatchComputeIndirect(GLintptr offset) { + gles2::GetGLContext()->DispatchComputeIndirect(offset); +} void GL_APIENTRY GLES2GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname, @@ -2967,6 +2970,10 @@ reinterpret_cast<GLES2FunctionPointer>(glDispatchCompute), }, { + "glDispatchComputeIndirect", + reinterpret_cast<GLES2FunctionPointer>(glDispatchComputeIndirect), + }, + { "glGetProgramInterfaceiv", reinterpret_cast<GLES2FunctionPointer>(glGetProgramInterfaceiv), },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index dbe1d60..cc930c0 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -2486,6 +2486,14 @@ } } +void DispatchComputeIndirect(GLintptr offset) { + gles2::cmds::DispatchComputeIndirect* c = + GetCmdSpace<gles2::cmds::DispatchComputeIndirect>(); + if (c) { + c->Init(offset); + } +} + void GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index dd25fd000..87020ece 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -890,6 +890,8 @@ GLuint num_groups_y, GLuint num_groups_z) override; +void DispatchComputeIndirect(GLintptr offset) override; + void GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 123fcfe0..b485a63 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3116,6 +3116,18 @@ CheckGLError(); } +void GLES2Implementation::DispatchComputeIndirect(GLintptr offset) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDispatchComputeIndirect(" + << offset << ")"); + if (offset < 0) { + SetGLError(GL_INVALID_VALUE, "glDispatchComputeIndirect", "offset < 0"); + return; + } + helper_->DispatchComputeIndirect(offset); + CheckGLError(); +} + void GLES2Implementation::GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index bc43ccd..0127b476 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -2724,6 +2724,17 @@ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, DispatchComputeIndirect) { + struct Cmds { + cmds::DispatchComputeIndirect cmd; + }; + Cmds expected; + expected.cmd.Init(1); + + gl_->DispatchComputeIndirect(1); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, GetProgramInterfaceiv) { struct Cmds { cmds::GetProgramInterfaceiv cmd;
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index dcf283b6..5d10eb5a 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -656,6 +656,7 @@ virtual void DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) = 0; +virtual void DispatchComputeIndirect(GLintptr offset) = 0; virtual void GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index bd728ed..6db43645 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -633,6 +633,7 @@ void DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) override; +void DispatchComputeIndirect(GLintptr offset) override; void GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 3057310..6644589f 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -859,6 +859,7 @@ void GLES2InterfaceStub::DispatchCompute(GLuint /* num_groups_x */, GLuint /* num_groups_y */, GLuint /* num_groups_z */) {} +void GLES2InterfaceStub::DispatchComputeIndirect(GLintptr /* offset */) {} void GLES2InterfaceStub::GetProgramInterfaceiv(GLuint /* program */, GLenum /* program_interface */, GLenum /* pname */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 6f6b8dde..8116948 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -633,6 +633,7 @@ void DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) override; +void DispatchComputeIndirect(GLintptr offset) override; void GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 4a0a5288..4ef7c32 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -1843,6 +1843,11 @@ gl_->DispatchCompute(num_groups_x, num_groups_y, num_groups_z); } +void GLES2TraceImplementation::DispatchComputeIndirect(GLintptr offset) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DispatchComputeIndirect"); + gl_->DispatchComputeIndirect(offset); +} + void GLES2TraceImplementation::GetProgramInterfaceiv(GLuint program, GLenum program_interface, GLenum pname,
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index cf009da4..01e551a8 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -12368,6 +12368,39 @@ static_assert(offsetof(DispatchCompute, num_groups_z) == 12, "offset of DispatchCompute num_groups_z should be 12"); +struct DispatchComputeIndirect { + typedef DispatchComputeIndirect ValueType; + static const CommandId kCmdId = kDispatchComputeIndirect; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(2); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLintptr _offset) { + SetHeader(); + offset = _offset; + } + + void* Set(void* cmd, GLintptr _offset) { + static_cast<ValueType*>(cmd)->Init(_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + int32_t offset; +}; + +static_assert(sizeof(DispatchComputeIndirect) == 8, + "size of DispatchComputeIndirect should be 8"); +static_assert(offsetof(DispatchComputeIndirect, header) == 0, + "offset of DispatchComputeIndirect header should be 0"); +static_assert(offsetof(DispatchComputeIndirect, offset) == 4, + "offset of DispatchComputeIndirect offset should be 4"); + struct GetProgramInterfaceiv { typedef GetProgramInterfaceiv ValueType; static const CommandId kCmdId = kGetProgramInterfaceiv;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index ee423c7..64a5457 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -4142,6 +4142,17 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, DispatchComputeIndirect) { + cmds::DispatchComputeIndirect& cmd = + *GetBufferAs<cmds::DispatchComputeIndirect>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLintptr>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::DispatchComputeIndirect::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLintptr>(11), cmd.offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetProgramInterfaceiv) { cmds::GetProgramInterfaceiv& cmd = *GetBufferAs<cmds::GetProgramInterfaceiv>();
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 3f3f1598..5b3e2e69 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -263,104 +263,105 @@ OP(FramebufferParameteri) /* 504 */ \ OP(BindImageTexture) /* 505 */ \ OP(DispatchCompute) /* 506 */ \ - OP(GetProgramInterfaceiv) /* 507 */ \ - OP(GetProgramResourceIndex) /* 508 */ \ - OP(GetProgramResourceName) /* 509 */ \ - OP(GetProgramResourceiv) /* 510 */ \ - OP(GetProgramResourceLocation) /* 511 */ \ - OP(MemoryBarrierEXT) /* 512 */ \ - OP(MemoryBarrierByRegion) /* 513 */ \ - OP(SwapBuffers) /* 514 */ \ - OP(GetMaxValueInBufferCHROMIUM) /* 515 */ \ - OP(EnableFeatureCHROMIUM) /* 516 */ \ - OP(MapBufferRange) /* 517 */ \ - OP(UnmapBuffer) /* 518 */ \ - OP(FlushMappedBufferRange) /* 519 */ \ - OP(ResizeCHROMIUM) /* 520 */ \ - OP(GetRequestableExtensionsCHROMIUM) /* 521 */ \ - OP(RequestExtensionCHROMIUM) /* 522 */ \ - OP(GetProgramInfoCHROMIUM) /* 523 */ \ - OP(GetUniformBlocksCHROMIUM) /* 524 */ \ - OP(GetTransformFeedbackVaryingsCHROMIUM) /* 525 */ \ - OP(GetUniformsES3CHROMIUM) /* 526 */ \ - OP(DescheduleUntilFinishedCHROMIUM) /* 527 */ \ - OP(GetTranslatedShaderSourceANGLE) /* 528 */ \ - OP(PostSubBufferCHROMIUM) /* 529 */ \ - OP(CopyTextureCHROMIUM) /* 530 */ \ - OP(CopySubTextureCHROMIUM) /* 531 */ \ - OP(DrawArraysInstancedANGLE) /* 532 */ \ - OP(DrawElementsInstancedANGLE) /* 533 */ \ - OP(VertexAttribDivisorANGLE) /* 534 */ \ - OP(ProduceTextureDirectCHROMIUMImmediate) /* 535 */ \ - OP(CreateAndConsumeTextureINTERNALImmediate) /* 536 */ \ - OP(BindUniformLocationCHROMIUMBucket) /* 537 */ \ - OP(BindTexImage2DCHROMIUM) /* 538 */ \ - OP(BindTexImage2DWithInternalformatCHROMIUM) /* 539 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 540 */ \ - OP(TraceBeginCHROMIUM) /* 541 */ \ - OP(TraceEndCHROMIUM) /* 542 */ \ - OP(DiscardFramebufferEXTImmediate) /* 543 */ \ - OP(LoseContextCHROMIUM) /* 544 */ \ - OP(UnpremultiplyAndDitherCopyCHROMIUM) /* 545 */ \ - OP(DrawBuffersEXTImmediate) /* 546 */ \ - OP(DiscardBackbufferCHROMIUM) /* 547 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 548 */ \ - OP(ScheduleCALayerSharedStateCHROMIUM) /* 549 */ \ - OP(ScheduleCALayerCHROMIUM) /* 550 */ \ - OP(ScheduleCALayerInUseQueryCHROMIUMImmediate) /* 551 */ \ - OP(CommitOverlayPlanesCHROMIUM) /* 552 */ \ - OP(FlushDriverCachesCHROMIUM) /* 553 */ \ - OP(ScheduleDCLayerCHROMIUM) /* 554 */ \ - OP(SetActiveURLCHROMIUM) /* 555 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 556 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 557 */ \ - OP(GenPathsCHROMIUM) /* 558 */ \ - OP(DeletePathsCHROMIUM) /* 559 */ \ - OP(IsPathCHROMIUM) /* 560 */ \ - OP(PathCommandsCHROMIUM) /* 561 */ \ - OP(PathParameterfCHROMIUM) /* 562 */ \ - OP(PathParameteriCHROMIUM) /* 563 */ \ - OP(PathStencilFuncCHROMIUM) /* 564 */ \ - OP(StencilFillPathCHROMIUM) /* 565 */ \ - OP(StencilStrokePathCHROMIUM) /* 566 */ \ - OP(CoverFillPathCHROMIUM) /* 567 */ \ - OP(CoverStrokePathCHROMIUM) /* 568 */ \ - OP(StencilThenCoverFillPathCHROMIUM) /* 569 */ \ - OP(StencilThenCoverStrokePathCHROMIUM) /* 570 */ \ - OP(StencilFillPathInstancedCHROMIUM) /* 571 */ \ - OP(StencilStrokePathInstancedCHROMIUM) /* 572 */ \ - OP(CoverFillPathInstancedCHROMIUM) /* 573 */ \ - OP(CoverStrokePathInstancedCHROMIUM) /* 574 */ \ - OP(StencilThenCoverFillPathInstancedCHROMIUM) /* 575 */ \ - OP(StencilThenCoverStrokePathInstancedCHROMIUM) /* 576 */ \ - OP(BindFragmentInputLocationCHROMIUMBucket) /* 577 */ \ - OP(ProgramPathFragmentInputGenCHROMIUM) /* 578 */ \ - OP(CoverageModulationCHROMIUM) /* 579 */ \ - OP(BlendBarrierKHR) /* 580 */ \ - OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 581 */ \ - OP(BindFragDataLocationIndexedEXTBucket) /* 582 */ \ - OP(BindFragDataLocationEXTBucket) /* 583 */ \ - OP(GetFragDataIndexEXT) /* 584 */ \ - OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 585 */ \ - OP(OverlayPromotionHintCHROMIUM) /* 586 */ \ - OP(SwapBuffersWithBoundsCHROMIUMImmediate) /* 587 */ \ - OP(SetDrawRectangleCHROMIUM) /* 588 */ \ - OP(SetEnableDCLayersCHROMIUM) /* 589 */ \ - OP(InitializeDiscardableTextureCHROMIUM) /* 590 */ \ - OP(UnlockDiscardableTextureCHROMIUM) /* 591 */ \ - OP(LockDiscardableTextureCHROMIUM) /* 592 */ \ - OP(TexStorage2DImageCHROMIUM) /* 593 */ \ - OP(SetColorSpaceMetadataCHROMIUM) /* 594 */ \ - OP(WindowRectanglesEXTImmediate) /* 595 */ \ - OP(CreateGpuFenceINTERNAL) /* 596 */ \ - OP(WaitGpuFenceCHROMIUM) /* 597 */ \ - OP(DestroyGpuFenceCHROMIUM) /* 598 */ \ - OP(SetReadbackBufferShadowAllocationINTERNAL) /* 599 */ \ - OP(FramebufferTextureMultiviewOVR) /* 600 */ \ - OP(MaxShaderCompilerThreadsKHR) /* 601 */ \ - OP(CreateAndTexStorage2DSharedImageINTERNALImmediate) /* 602 */ \ - OP(BeginSharedImageAccessDirectCHROMIUM) /* 603 */ \ - OP(EndSharedImageAccessDirectCHROMIUM) /* 604 */ + OP(DispatchComputeIndirect) /* 507 */ \ + OP(GetProgramInterfaceiv) /* 508 */ \ + OP(GetProgramResourceIndex) /* 509 */ \ + OP(GetProgramResourceName) /* 510 */ \ + OP(GetProgramResourceiv) /* 511 */ \ + OP(GetProgramResourceLocation) /* 512 */ \ + OP(MemoryBarrierEXT) /* 513 */ \ + OP(MemoryBarrierByRegion) /* 514 */ \ + OP(SwapBuffers) /* 515 */ \ + OP(GetMaxValueInBufferCHROMIUM) /* 516 */ \ + OP(EnableFeatureCHROMIUM) /* 517 */ \ + OP(MapBufferRange) /* 518 */ \ + OP(UnmapBuffer) /* 519 */ \ + OP(FlushMappedBufferRange) /* 520 */ \ + OP(ResizeCHROMIUM) /* 521 */ \ + OP(GetRequestableExtensionsCHROMIUM) /* 522 */ \ + OP(RequestExtensionCHROMIUM) /* 523 */ \ + OP(GetProgramInfoCHROMIUM) /* 524 */ \ + OP(GetUniformBlocksCHROMIUM) /* 525 */ \ + OP(GetTransformFeedbackVaryingsCHROMIUM) /* 526 */ \ + OP(GetUniformsES3CHROMIUM) /* 527 */ \ + OP(DescheduleUntilFinishedCHROMIUM) /* 528 */ \ + OP(GetTranslatedShaderSourceANGLE) /* 529 */ \ + OP(PostSubBufferCHROMIUM) /* 530 */ \ + OP(CopyTextureCHROMIUM) /* 531 */ \ + OP(CopySubTextureCHROMIUM) /* 532 */ \ + OP(DrawArraysInstancedANGLE) /* 533 */ \ + OP(DrawElementsInstancedANGLE) /* 534 */ \ + OP(VertexAttribDivisorANGLE) /* 535 */ \ + OP(ProduceTextureDirectCHROMIUMImmediate) /* 536 */ \ + OP(CreateAndConsumeTextureINTERNALImmediate) /* 537 */ \ + OP(BindUniformLocationCHROMIUMBucket) /* 538 */ \ + OP(BindTexImage2DCHROMIUM) /* 539 */ \ + OP(BindTexImage2DWithInternalformatCHROMIUM) /* 540 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 541 */ \ + OP(TraceBeginCHROMIUM) /* 542 */ \ + OP(TraceEndCHROMIUM) /* 543 */ \ + OP(DiscardFramebufferEXTImmediate) /* 544 */ \ + OP(LoseContextCHROMIUM) /* 545 */ \ + OP(UnpremultiplyAndDitherCopyCHROMIUM) /* 546 */ \ + OP(DrawBuffersEXTImmediate) /* 547 */ \ + OP(DiscardBackbufferCHROMIUM) /* 548 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 549 */ \ + OP(ScheduleCALayerSharedStateCHROMIUM) /* 550 */ \ + OP(ScheduleCALayerCHROMIUM) /* 551 */ \ + OP(ScheduleCALayerInUseQueryCHROMIUMImmediate) /* 552 */ \ + OP(CommitOverlayPlanesCHROMIUM) /* 553 */ \ + OP(FlushDriverCachesCHROMIUM) /* 554 */ \ + OP(ScheduleDCLayerCHROMIUM) /* 555 */ \ + OP(SetActiveURLCHROMIUM) /* 556 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 557 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 558 */ \ + OP(GenPathsCHROMIUM) /* 559 */ \ + OP(DeletePathsCHROMIUM) /* 560 */ \ + OP(IsPathCHROMIUM) /* 561 */ \ + OP(PathCommandsCHROMIUM) /* 562 */ \ + OP(PathParameterfCHROMIUM) /* 563 */ \ + OP(PathParameteriCHROMIUM) /* 564 */ \ + OP(PathStencilFuncCHROMIUM) /* 565 */ \ + OP(StencilFillPathCHROMIUM) /* 566 */ \ + OP(StencilStrokePathCHROMIUM) /* 567 */ \ + OP(CoverFillPathCHROMIUM) /* 568 */ \ + OP(CoverStrokePathCHROMIUM) /* 569 */ \ + OP(StencilThenCoverFillPathCHROMIUM) /* 570 */ \ + OP(StencilThenCoverStrokePathCHROMIUM) /* 571 */ \ + OP(StencilFillPathInstancedCHROMIUM) /* 572 */ \ + OP(StencilStrokePathInstancedCHROMIUM) /* 573 */ \ + OP(CoverFillPathInstancedCHROMIUM) /* 574 */ \ + OP(CoverStrokePathInstancedCHROMIUM) /* 575 */ \ + OP(StencilThenCoverFillPathInstancedCHROMIUM) /* 576 */ \ + OP(StencilThenCoverStrokePathInstancedCHROMIUM) /* 577 */ \ + OP(BindFragmentInputLocationCHROMIUMBucket) /* 578 */ \ + OP(ProgramPathFragmentInputGenCHROMIUM) /* 579 */ \ + OP(CoverageModulationCHROMIUM) /* 580 */ \ + OP(BlendBarrierKHR) /* 581 */ \ + OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 582 */ \ + OP(BindFragDataLocationIndexedEXTBucket) /* 583 */ \ + OP(BindFragDataLocationEXTBucket) /* 584 */ \ + OP(GetFragDataIndexEXT) /* 585 */ \ + OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 586 */ \ + OP(OverlayPromotionHintCHROMIUM) /* 587 */ \ + OP(SwapBuffersWithBoundsCHROMIUMImmediate) /* 588 */ \ + OP(SetDrawRectangleCHROMIUM) /* 589 */ \ + OP(SetEnableDCLayersCHROMIUM) /* 590 */ \ + OP(InitializeDiscardableTextureCHROMIUM) /* 591 */ \ + OP(UnlockDiscardableTextureCHROMIUM) /* 592 */ \ + OP(LockDiscardableTextureCHROMIUM) /* 593 */ \ + OP(TexStorage2DImageCHROMIUM) /* 594 */ \ + OP(SetColorSpaceMetadataCHROMIUM) /* 595 */ \ + OP(WindowRectanglesEXTImmediate) /* 596 */ \ + OP(CreateGpuFenceINTERNAL) /* 597 */ \ + OP(WaitGpuFenceCHROMIUM) /* 598 */ \ + OP(DestroyGpuFenceCHROMIUM) /* 599 */ \ + OP(SetReadbackBufferShadowAllocationINTERNAL) /* 600 */ \ + OP(FramebufferTextureMultiviewOVR) /* 601 */ \ + OP(MaxShaderCompilerThreadsKHR) /* 602 */ \ + OP(CreateAndTexStorage2DSharedImageINTERNALImmediate) /* 603 */ \ + OP(BeginSharedImageAccessDirectCHROMIUM) /* 604 */ \ + OP(EndSharedImageAccessDirectCHROMIUM) /* 605 */ enum CommandId { kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 20750bb..c2c4bcd3 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -1041,6 +1041,10 @@ "GL_RGB_YCBCR_420V_CHROMIUM", }, { + 0x78FD, + "GL_RGB_YCBCR_P010_CHROMIUM", + }, + { 0x8, "GL_CA_LAYER_EDGE_TOP_CHROMIUM", },
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index 7c3d121..33cfad11 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -272,6 +272,7 @@ GL_APICALL void GL_APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); GL_APICALL void GL_APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GL_APICALL void GL_APIENTRY glDispatchComputeIndirect (GLintptrNotNegative offset); GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLidProgram program, GLenum program_interface, GLenum pname, GLint* params); GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLidProgram program, GLenum program_interface, const char* name);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index d79dc20..fd594dd8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -4724,6 +4724,12 @@ return error::kUnknownCommand; } +error::Error GLES2DecoderImpl::HandleDispatchComputeIndirect( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + return error::kUnknownCommand; +} + error::Error GLES2DecoderImpl::HandleGetProgramInterfaceiv( uint32_t immediate_data_size, const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 1fb7aa15..6607d3d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -172,6 +172,7 @@ error::Error DoDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +error::Error DoDispatchComputeIndirect(GLintptr offset); error::Error DoDrawArrays(GLenum mode, GLint first, GLsizei count); error::Error DoDrawElements(GLenum mode, GLsizei count,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 96f77de..05c9bba 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -1124,6 +1124,15 @@ return error::kNoError; } +error::Error GLES2DecoderPassthroughImpl::DoDispatchComputeIndirect( + GLintptr offset) { + BindPendingImagesForSamplersIfNeeded(); + // TODO(jiajie.hu@intel.com): Use glDispatchComputeIndirectRobustANGLEFn() + // when it's ready in ANGLE. + api()->glDispatchComputeIndirectFn(offset); + return error::kNoError; +} + error::Error GLES2DecoderPassthroughImpl::DoDrawArrays(GLenum mode, GLint first, GLsizei count) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 0abeb0b..20c29481 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4020,6 +4020,22 @@ return error::kNoError; } +error::Error GLES2DecoderPassthroughImpl::HandleDispatchComputeIndirect( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + if (!feature_info_->IsWebGL2ComputeContext()) + return error::kUnknownCommand; + const volatile gles2::cmds::DispatchComputeIndirect& c = + *static_cast<const volatile gles2::cmds::DispatchComputeIndirect*>( + cmd_data); + GLintptr offset = static_cast<GLintptr>(c.offset); + error::Error error = DoDispatchComputeIndirect(offset); + if (error != error::kNoError) { + return error; + } + return error::kNoError; +} + error::Error GLES2DecoderPassthroughImpl::HandleGetProgramInterfaceiv( uint32_t immediate_data_size, const volatile void* cmd_data) {
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc index e8ce975..86a63c1 100644 --- a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc +++ b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc
@@ -55,7 +55,7 @@ DestructionCallback callback) { std::unique_ptr<gfx::ClientNativePixmap> native_pixmap = client_native_pixmap_factory->ImportFromHandle( - CloneHandleForIPC(handle.native_pixmap_handle), size, usage); + CloneHandleForIPC(handle.native_pixmap_handle), size, format, usage); DCHECK(native_pixmap); return base::WrapUnique(new GpuMemoryBufferImplNativePixmap(
diff --git a/gpu/vulkan/x/vulkan_implementation_x11.cc b/gpu/vulkan/x/vulkan_implementation_x11.cc index 612b7501..378ce1b4 100644 --- a/gpu/vulkan/x/vulkan_implementation_x11.cc +++ b/gpu/vulkan/x/vulkan_implementation_x11.cc
@@ -112,7 +112,9 @@ // TODO(samans): Add these extensions once Swiftshader supports them. // https://crbug.com/963988 if (!use_swiftshader()) { + extensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME); extensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME); + extensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME); extensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME); } if (using_surface_)
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 302e176..1bc2e70 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -2508,8 +2508,9 @@ } builders { name: "TSAN Release" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "Linux CFI" @@ -2546,13 +2547,15 @@ } builders { name: "TSAN Debug" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "UBSan vptr Release" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "Mac ASAN Release" @@ -2601,18 +2604,21 @@ } builders { name: "UBSan Release" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "ChromiumOS ASAN Release" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "ASAN Release Media" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "win-archive-dbg" @@ -2666,8 +2672,9 @@ builders { name: "ASan Debug (32-bit x86 with V8-ARM)" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "Linux remote_run Tester" @@ -2711,8 +2718,9 @@ } builders { name: "ASAN Debug" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "Mac deterministic" @@ -2785,8 +2793,9 @@ } builders { name: "ASAN Release" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "Libfuzzer Upload Linux ASan Debug" @@ -2893,8 +2902,9 @@ } builders { name: "ASan Release Media (32-bit x86 with V8-ARM)" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "mac-hermetic-upgrade-rel" @@ -2970,8 +2980,9 @@ } builders { name: "ASan Release (32-bit x86 with V8-ARM)" - dimensions: "os:Ubuntu-14.04" mixins: "fuzz-ci" + mixins: "linux-xenial" + mixins: "builderless" } builders { name: "WebKit Win10"
diff --git a/ios/build/bots/chromium.fyi/ios13-beta-simulator.json b/ios/build/bots/chromium.fyi/ios13-beta-simulator.json index a70ffdb..946380f 100644 --- a/ios/build/bots/chromium.fyi/ios13-beta-simulator.json +++ b/ios/build/bots/chromium.fyi/ios13-beta-simulator.json
@@ -22,7 +22,7 @@ "include": "eg2_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "pool":"Chrome", "host os": "Mac-10.14.4", "optional_dimensions": { @@ -36,7 +36,7 @@ "include": "eg2_tests.json", "device type": "iPad (6th generation)", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "pool":"Chrome", "host os": "Mac-10.14.4", "optional_dimensions": { @@ -105,7 +105,7 @@ "include": "common_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -118,7 +118,7 @@ "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -131,7 +131,7 @@ "include": "eg_cq_tests.json", "device type": "iPad Pro (12.9-inch)", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -144,7 +144,7 @@ "include": "eg_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -157,7 +157,7 @@ "include": "eg_tests.json", "device type": "iPad Air (3rd generation)", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -170,7 +170,7 @@ "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s Plus", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -183,7 +183,7 @@ "include": "screen_size_dependent_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -196,7 +196,7 @@ "include": "screen_size_dependent_tests.json", "device type": "iPad Air 2", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": {
diff --git a/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json b/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json index edaed1e..5dcb4f7 100644 --- a/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json +++ b/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json
@@ -2,7 +2,7 @@ "comments": [ "Runs tests on 64-bit iOS 11.4 and 12.1 and 13.0 tests" ], - "xcode build version": "11m336w", + "xcode build version": "11m337n", "gn_args": [ "goma_dir=\"$(goma_dir)\"", "is_component_build=false",
diff --git a/ios/build/bots/chromium.mac/ios13-beta-simulator.json b/ios/build/bots/chromium.mac/ios13-beta-simulator.json index 876869c..9028b26d 100644 --- a/ios/build/bots/chromium.mac/ios13-beta-simulator.json +++ b/ios/build/bots/chromium.mac/ios13-beta-simulator.json
@@ -24,7 +24,7 @@ "include": "eg2_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "pool":"Chrome", "host os": "Mac-10.14.4", "optional_dimensions": { @@ -38,7 +38,7 @@ "include": "eg2_tests.json", "device type": "iPad (6th generation)", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "pool":"Chrome", "host os": "Mac-10.14.4", "optional_dimensions": { @@ -107,7 +107,7 @@ "include": "common_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -120,7 +120,7 @@ "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -133,7 +133,7 @@ "include": "eg_cq_tests.json", "device type": "iPad Pro (12.9-inch)", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -146,7 +146,7 @@ "include": "eg_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -159,7 +159,7 @@ "include": "eg_tests.json", "device type": "iPad Air (3rd generation)", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -172,7 +172,7 @@ "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s Plus", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -185,7 +185,7 @@ "include": "screen_size_dependent_tests.json", "device type": "iPhone X", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": { @@ -198,7 +198,7 @@ "include": "screen_size_dependent_tests.json", "device type": "iPad Air 2", "os": "13.0", - "xcode build version": "11m336w", + "xcode build version": "11m337n", "host os": "Mac-10.14.4", "pool":"Chrome", "optional_dimensions": {
diff --git a/ios/build/bots/chromium.mac/ios13-sdk-simulator.json b/ios/build/bots/chromium.mac/ios13-sdk-simulator.json index 054d1a6..83bd054 100644 --- a/ios/build/bots/chromium.mac/ios13-sdk-simulator.json +++ b/ios/build/bots/chromium.mac/ios13-sdk-simulator.json
@@ -5,7 +5,7 @@ "Note: This file exists only to support the trybot.", "It should be kept in sync with the CI configuration in ../chromium.fyi/." ], - "xcode build version": "11m336w", + "xcode build version": "11m337n", "gn_args": [ "goma_dir=\"$(goma_dir)\"", "is_component_build=false",
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h index 829f360e..541af35 100644 --- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h +++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h
@@ -17,6 +17,10 @@ class UrlKeyedDataCollectionConsentHelper; } +namespace component_updater { +class ComponentUpdateService; +} + // AutocompleteProviderClientImpl provides iOS-specific implementation of // AutocompleteProviderClient interface. class AutocompleteProviderClientImpl : public AutocompleteProviderClient { @@ -53,6 +57,8 @@ // GetCurrentVisitTimestamp is only used by the contextual zero suggest // suggestions for desktop users. This implementation returns base::Time(). base::Time GetCurrentVisitTimestamp() const override; + component_updater::ComponentUpdateService* GetComponentUpdateService() + override; bool IsOffTheRecord() const override; bool SearchSuggestEnabled() const override; bool IsPersonalizedUrlDataCollectionActive() const override;
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm index d9ded109..b15dd770 100644 --- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm +++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
@@ -165,6 +165,11 @@ return base::Time(); } +component_updater::ComponentUpdateService* +AutocompleteProviderClientImpl::GetComponentUpdateService() { + return GetApplicationContext()->GetComponentUpdateService(); +} + bool AutocompleteProviderClientImpl::IsOffTheRecord() const { return browser_state_->IsOffTheRecord(); }
diff --git a/ios/chrome/browser/infobars/infobar_badge_tab_helper.h b/ios/chrome/browser/infobars/infobar_badge_tab_helper.h index 8429b44..d6cc4e4 100644 --- a/ios/chrome/browser/infobars/infobar_badge_tab_helper.h +++ b/ios/chrome/browser/infobars/infobar_badge_tab_helper.h
@@ -39,8 +39,8 @@ // Returns wheter an Infobar badge is being displayed for the TabHelper // Webstate. bool is_infobar_displaying(); - // Returns whether the Infobar badge is active. - bool is_badge_active(); + // Returns whether the Infobar badge is accepted. + bool is_badge_accepted(); // Returns the type of the Infobar being displayed. InfobarType infobar_type(); @@ -66,8 +66,8 @@ bool is_infobar_displaying_; // The type of the Infobar being displayed. InfobarType infobar_type_; - // Returns whether the Infobar badge is active. - bool is_badge_active_ = false; + // Returns whether the Infobar badge is accepted. + bool is_badge_accepted_ = false; WEB_STATE_USER_DATA_KEY_DECL(); DISALLOW_COPY_AND_ASSIGN(InfobarBadgeTabHelper);
diff --git a/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm b/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm index 9a76364a..73b5511 100644 --- a/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm +++ b/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm
@@ -45,7 +45,7 @@ void InfobarBadgeTabHelper::UpdateBadgeForInfobarAccepted() { delegate_.badgeState |= InfobarBadgeStateAccepted; - is_badge_active_ = true; + is_badge_accepted_ = true; } bool InfobarBadgeTabHelper::is_infobar_displaying() { @@ -56,8 +56,8 @@ return infobar_type_; } -bool InfobarBadgeTabHelper::is_badge_active() { - return is_badge_active_; +bool InfobarBadgeTabHelper::is_badge_accepted() { + return is_badge_accepted_; } InfobarBadgeTabHelper::~InfobarBadgeTabHelper() = default;
diff --git a/ios/chrome/browser/metrics/ukm_egtest.mm b/ios/chrome/browser/metrics/ukm_egtest.mm index deaf9d21..fb6b281 100644 --- a/ios/chrome/browser/metrics/ukm_egtest.mm +++ b/ios/chrome/browser/metrics/ukm_egtest.mm
@@ -30,7 +30,6 @@ #import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity.h" #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h" -#include "services/metrics/public/cpp/ukm_recorder.h" #include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -204,7 +203,7 @@ + (void)setUp { [super setUp]; - if (!base::FeatureList::IsEnabled(ukm::kUkmFeature)) { + if (![ChromeEarlGrey isUKMEnabled]) { // ukm::kUkmFeature feature is not enabled. You need to pass // --enable-features=Ukm command line argument in order to run this test. DCHECK(false);
diff --git a/ios/chrome/browser/translate/legacy_translate_infobar_egtest.mm b/ios/chrome/browser/translate/legacy_translate_infobar_egtest.mm index 8b6f772..5026745 100644 --- a/ios/chrome/browser/translate/legacy_translate_infobar_egtest.mm +++ b/ios/chrome/browser/translate/legacy_translate_infobar_egtest.mm
@@ -18,7 +18,6 @@ #include "components/translate/core/browser/translate_download_manager.h" #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/browser/translate_pref_names.h" -#include "components/translate/core/browser/translate_prefs.h" #include "components/translate/core/common/translate_constants.h" #include "components/translate/core/common/translate_switches.h" #include "components/translate/ios/browser/ios_translate_driver.h" @@ -279,7 +278,7 @@ + (void)setUp { [super setUp]; - if (base::FeatureList::IsEnabled(translate::kCompactTranslateInfobarIOS)) { + if ([ChromeEarlGrey isCompactTranslateInfobarIOSEnabled]) { // translate::kCompactTranslateInfobarIOS feature is enabled. You need // to pass --disable-features=CompactTranslateInfobarIOS command line // argument in order to run this test.
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm index 3949e1e..69c3cc6 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm
@@ -12,7 +12,6 @@ #include "base/feature_list.h" #include "base/strings/sys_string_conversions.h" #include "components/strings/grit/components_strings.h" -#include "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/tabs/tab.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/test/app/chrome_test_util.h" @@ -124,7 +123,7 @@ // TODO(crbug.com/931280): This should be 1, but for the time being will be 2 // to work around an NTP bug. int mainTabCount = 1; - if (base::FeatureList::IsEnabled(kBlockNewTabPagePendingLoad)) + if ([ChromeEarlGrey isBlockNewTabPagePendingLoadEnabled]) mainTabCount = 2; [ChromeEarlGrey waitForMainTabCount:mainTabCount]; }
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm index a74a7a2..09fed2c 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
@@ -190,12 +190,16 @@ infobarBadgeTabHelper->SetDelegate(self); if (self.consumer) { // Whenever the WebState changes ask the corresponding - // InfobarBadgeTabHelper if a badge should be displayed. + // InfobarBadgeTabHelper if a badge should be displayed, and if its + // Active or not. [self.consumer displayInfobarBadge:infobarBadgeTabHelper->is_infobar_displaying() type:infobarBadgeTabHelper->infobar_type()]; - [self.consumer - activeInfobarBadge:infobarBadgeTabHelper->is_badge_active()]; + if (infobarBadgeTabHelper->is_badge_accepted()) { + self.badgeState |= InfobarBadgeStateAccepted; + } else { + self.badgeState &= ~InfobarBadgeStateAccepted; + } } }
diff --git a/ios/chrome/browser/ui/payments/payment_request_modifiers_egtest.mm b/ios/chrome/browser/ui/payments/payment_request_modifiers_egtest.mm index da92854..2475994 100644 --- a/ios/chrome/browser/ui/payments/payment_request_modifiers_egtest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_modifiers_egtest.mm
@@ -66,8 +66,7 @@ - (void)setUp { [super setUp]; - if (!base::FeatureList::IsEnabled( - payments::features::kWebPaymentsModifiers)) { + if (![ChromeEarlGrey isWebPaymentsModifiersEnabled]) { // payments::features::kWebPaymentsModifiers feature is not enabled, // You have to pass --enable-features=WebPaymentsModifiers command line // argument in order to run this test.
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm index 4964348c..7897a8a 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm
@@ -35,7 +35,6 @@ #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h" -#import "ios/web/common/features.h" #import "ios/web/public/navigation_manager.h" #import "ios/web/public/reload_type.h" #import "ios/web/public/test/web_view_content_test_util.h" @@ -674,7 +673,7 @@ AssertIsShowingDistillablePage(false, distillableURL); // TODO(crbug.com/954248) This DCHECK's (but works) with slimnav disabled. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) { + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) { [ChromeEarlGrey goBack]; [ChromeEarlGrey goForward]; AssertIsShowingDistillablePage(false, distillableURL);
diff --git a/ios/chrome/browser/ui/settings/settings_egtest.mm b/ios/chrome/browser/ui/settings/settings_egtest.mm index d74428d4..7ef4d23 100644 --- a/ios/chrome/browser/ui/settings/settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/settings_egtest.mm
@@ -17,7 +17,6 @@ #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" -#include "components/ukm/ios/features.h" #include "components/unified_consent/feature.h" #import "ios/chrome/app/main_controller.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -370,7 +369,7 @@ // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF // - Services record data and upload data. - if (base::FeatureList::IsEnabled(kUmaCellular)) { + if ([ChromeEarlGrey isUMACellularEnabled]) { // kMetricsReportingEnabled OFF [self setMetricsReportingEnabled:NO]; } else { @@ -381,7 +380,7 @@ // I.e. no recording of data, and no uploading of what's been recorded. [self assertMetricsServiceDisabled:serviceType]; - if (base::FeatureList::IsEnabled(kUmaCellular)) { + if ([ChromeEarlGrey isUMACellularEnabled]) { // kMetricsReportingEnabled OFF [self setMetricsReportingEnabled:NO]; } else { @@ -400,7 +399,7 @@ // The values of the prefs and the wwan vs wifi state should be honored by // the services, turning on and off according to the rules laid out above. - if (!base::FeatureList::IsEnabled(kUmaCellular)) { + if (![ChromeEarlGrey isUMACellularEnabled]) { // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON. [self setMetricsReportingEnabled:YES wifiOnly:YES]; // Service should be enabled. @@ -430,7 +429,7 @@ // This tests that no matter the state change, pref or network connection, // services remain disabled. - if (!base::FeatureList::IsEnabled(kUmaCellular)) { + if (![ChromeEarlGrey isUMACellularEnabled]) { // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON [self setMetricsReportingEnabled:YES wifiOnly:YES]; // Service should remain disabled.
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm index 0a3a052..0206ce8f 100644 --- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm +++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
@@ -344,41 +344,65 @@ #pragma mark - Dismiss tests +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: setting menu. +// Interrupted at: user consent. - (void)testDismissSigninFromSettings { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromSettings tapSettingsLink:NO]; } +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: setting menu. +// Interrupted at: advanced sign-in. - (void)testDismissAdvancedSigninSettingsFromAdvancedSigninSettings { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromSettings tapSettingsLink:YES]; } +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: bookmark view. +// Interrupted at: user consent. - (void)testDismissSigninFromBookmarks { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromBookmarks tapSettingsLink:NO]; } +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: bookmark view. +// Interrupted at: advanced sign-in. - (void)testDismissAdvancedSigninBookmarksFromAdvancedSigninSettings { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromBookmarks tapSettingsLink:YES]; } +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: recent tabs. +// Interrupted at: user consent. - (void)testDismissSigninFromRecentTabs { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromRecentTabs tapSettingsLink:NO]; } +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: recent tabs. +// Interrupted at: advanced sign-in. - (void)testDismissSigninFromRecentTabsFromAdvancedSigninSettings { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromRecentTabs tapSettingsLink:YES]; } +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: tab switcher. +// Interrupted at: user consent. - (void)testDismissSigninFromTabSwitcher { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromTabSwitcher tapSettingsLink:NO]; } +// Tests to dismiss sign-in by opening an URL from another app. +// Sign-in opened from: tab switcher. +// Interrupted at: advanced sign-in. - (void)testDismissSigninFromTabSwitcherFromAdvancedSigninSettings { [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromTabSwitcher tapSettingsLink:YES]; @@ -386,6 +410,9 @@ #pragma mark - Utils +// Starts the sign-in workflow, and simulates opening an URL from another app. +// |openSigninMethod| is the way to start the sign-in. +// |tapSettingsLink| if YES, the setting link is tapped before opening the URL. - (void)assertOpenURLWhenSigninFromView:(OpenSigninMethod)openSigninMethod tapSettingsLink:(BOOL)tapSettingsLink { ChromeIdentity* identity = [SigninEarlGreyUtils fakeIdentity1];
diff --git a/ios/chrome/browser/web/browsing_egtest.mm b/ios/chrome/browser/web/browsing_egtest.mm index ec36186..2ee385e 100644 --- a/ios/chrome/browser/web/browsing_egtest.mm +++ b/ios/chrome/browser/web/browsing_egtest.mm
@@ -25,7 +25,6 @@ #include "ios/web/public/test/http_server/data_response_provider.h" #import "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" -#import "ios/web/public/web_client.h" #include "net/http/http_response_headers.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" @@ -334,7 +333,8 @@ [ChromeEarlGrey goBack]; [ChromeEarlGrey waitForWebStateContainingText:"Link"]; - if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) { // Using partial match for Omnibox text because the displayed URL is now // "http://origin/#" due to the link click. This is consistent with all // other browsers.
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm index ecc5cd5..a6f8a6f8 100644 --- a/ios/chrome/browser/web/forms_egtest.mm +++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -216,7 +216,7 @@ // WKBasedNavigationManager presents repost confirmation dialog before loading // stops. - if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) { [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload]; } else { // Legacy navigation manager presents repost confirmation dialog after @@ -233,7 +233,7 @@ // synchronization is not left disabled if the test fails. std::unique_ptr<ScopedSynchronizationDisabler> disabler = std::make_unique<ScopedSynchronizationDisabler>(); - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { disabler.reset(); } @@ -265,7 +265,7 @@ // WKWebView's back-forward cache. Force reload to trigger repost. Not using // [ChromeEarlGrey reload] because WKBasedNavigationManager presents repost // confirmation dialog before loading stops. - if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) { [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload]; } @@ -278,7 +278,7 @@ // synchronization is not left disabled if the test fails. std::unique_ptr<ScopedSynchronizationDisabler> disabler = std::make_unique<ScopedSynchronizationDisabler>(); - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { disabler.reset(); } @@ -309,7 +309,7 @@ // WKWebView's back-forward cache. Force reload to trigger repost. Not using // [ChromeEarlGrey reload] because WKBasedNavigationManager presents repost // confirmation dialog before loading stops. - if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) { [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload]; } @@ -322,7 +322,7 @@ // synchronization is not left disabled if the test fails. std::unique_ptr<ScopedSynchronizationDisabler> disabler = std::make_unique<ScopedSynchronizationDisabler>(); - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { disabler.reset(); } @@ -357,7 +357,7 @@ // Back-forward navigation with WKBasedNavigationManager is served from // WKWebView's app-cache, so it won't trigger repost warning. - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { [self confirmResendWarning]; } @@ -384,7 +384,7 @@ // WKWebView's back-forward cache. Force reload to trigger repost. Not using // [ChromeEarlGrey reload] because WKBasedNavigationManager presents repost // confirmation dialog before loading stops. - if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) { [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload]; } @@ -397,7 +397,7 @@ // synchronization is not left disabled if the test fails. std::unique_ptr<ScopedSynchronizationDisabler> disabler = std::make_unique<ScopedSynchronizationDisabler>(); - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { disabler.reset(); } @@ -409,7 +409,7 @@ // Expected behavior is different between the two navigation manager // implementations. - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { // LegacyNavigationManager displays repost on |goBack|. So after cancelling, // web view should show form URL. [ChromeEarlGrey waitForWebStateContainingText:(base::SysNSStringToUTF8( @@ -447,7 +447,7 @@ // WKBasedNavigationManager presents repost confirmation dialog before loading // stops. - if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) { [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload]; } else { // Legacy navigation manager presents repost confirmation dialog after @@ -463,7 +463,7 @@ // synchronization is not left disabled if the test fails. std::unique_ptr<ScopedSynchronizationDisabler> disabler = std::make_unique<ScopedSynchronizationDisabler>(); - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { disabler.reset(); }
diff --git a/ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm b/ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm index 592c687..7965b30 100644 --- a/ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm +++ b/ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm
@@ -15,7 +15,6 @@ #include "ios/net/url_test_util.h" #import "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" -#import "ios/web/public/web_client.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -135,7 +134,7 @@ performAction:grey_tap()]; // TODO(crbug.com/776606): WKWebView doesn't fire load event for back/forward // navigation and WKBasedNavigationManager inherits this behavior. - bool expectOnLoad = !web::GetWebClient()->IsSlimNavigationManagerEnabled(); + bool expectOnLoad = ![ChromeEarlGrey isSlimNavigationManagerEnabled]; [self assertStatusText:@"replaceStateHashWithObject" withOmniboxText:replaceStateHashWithObjectOmniboxText pageLoaded:expectOnLoad]; @@ -241,7 +240,7 @@ [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; // TODO(crbug.com/776606): WKWebView doesn't fire load event for back/forward // navigation and WKBasedNavigationManager inherits this behavior. - bool expectOnLoad = !web::GetWebClient()->IsSlimNavigationManagerEnabled(); + bool expectOnLoad = ![ChromeEarlGrey isSlimNavigationManagerEnabled]; [self assertStatusText:nil withOmniboxText:pushStateHashStringOmniboxText pageLoaded:expectOnLoad];
diff --git a/ios/chrome/browser/web/visible_url_egtest.mm b/ios/chrome/browser/web/visible_url_egtest.mm index bf5ad637..f571c5d 100644 --- a/ios/chrome/browser/web/visible_url_egtest.mm +++ b/ios/chrome/browser/web/visible_url_egtest.mm
@@ -18,7 +18,6 @@ #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_test_case.h" -#import "ios/web/common/features.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/test/http_server/html_response_provider.h" #import "ios/web/public/test/http_server/http_server.h" @@ -168,7 +167,7 @@ // pending back and forward navigations. - (void)testBackForwardNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -218,7 +217,7 @@ // pending navigations initialted from back history popover. - (void)testHistoryNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -261,7 +260,7 @@ // URL, not pending URL. - (void)testStoppingPendingBackNavigationAndReload { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -298,7 +297,7 @@ // back forward navigations initiated with JS. - (void)testJSBackForwardNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -348,7 +347,7 @@ // navigations initiated with JS. - (void)testJSGoNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -398,7 +397,7 @@ // back navigation started with pending reload in progress. - (void)testBackNavigationWithPendingReload { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -447,7 +446,7 @@ #endif - (void)MAYBE_testBackNavigationWithPendingRendererInitiatedNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -481,7 +480,7 @@ // progress. - (void)testRendererInitiatedNavigationWithPendingBackNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Purge web view caches and pause the server to make sure that tests can @@ -515,7 +514,7 @@ // issues 2 go back commands. - (void)testDoubleBackNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Create 3rd entry in the history, to be able to go back twice. @@ -550,7 +549,7 @@ // issues 2 go forward commands to WebUI page (crbug.com/711465). - (void)testDoubleForwardNavigationToWebUIPage { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Create 3rd entry in the history, to be able to go back twice. @@ -581,7 +580,7 @@ // window.history.back() twice. - (void)testDoubleBackJSNavigation { // TODO(crbug.com/874634): re-enable this test. - if (base::FeatureList::IsEnabled(web::features::kSlimNavigationManager)) + if ([ChromeEarlGrey isSlimNavigationManagerEnabled]) EARL_GREY_TEST_DISABLED(@"Test disabled on SlimNavigationManager."); // Create 3rd entry in the history, to be able to go back twice.
diff --git a/ios/chrome/browser/web/window_open_by_dom_egtest.mm b/ios/chrome/browser/web/window_open_by_dom_egtest.mm index ec4103c5..0d49bb7b 100644 --- a/ios/chrome/browser/web/window_open_by_dom_egtest.mm +++ b/ios/chrome/browser/web/window_open_by_dom_egtest.mm
@@ -107,6 +107,33 @@ [ChromeEarlGrey waitForMainTabCount:2]; } +// Tests opening a window with URL that ends with /..; +- (void)testWindowOpenWithSpecialURL { + const char ID[] = "webScenarioWindowOpenWithSpecialURL"; + [[EarlGrey selectElementWithMatcher:WebViewInWebState(GetCurrentWebState())] + performAction:web::WebViewTapElement( + GetCurrentWebState(), + [ElementSelector selectorWithElementID:ID])]; + if (@available(iOS 13, *)) { + // Starting from iOS 13 WebKit does not rewrite URL that ends with /..; + [ChromeEarlGrey waitForMainTabCount:2]; + } else if (@available(iOS 12, *)) { + // Prior to iOS 13 WebKit rewries URL that ends with /..; to invalid URL + // so Chrome opens about:blank for that invalid URL. + [ChromeEarlGrey waitForMainTabCount:2]; + [[EarlGrey selectElementWithMatcher:OmniboxText("about:blank")] + assertWithMatcher:grey_notNil()]; + } else { + // Prior to iOS 12 WebKit rewries URL that ends with /..; to invalid URL, + // but Chrome does not have a chance to open about:blank, so child window + // is not created. + [ChromeEarlGrey waitForWebStateNotContainingText:ID]; + [ChromeEarlGrey waitForMainTabCount:1]; + [[EarlGrey selectElementWithMatcher:OmniboxText("about:blank")] + assertWithMatcher:grey_notNil()]; + } +} + // Tests executing script that clicks a link with target="_blank". - (void)testLinkWithBlankTargetWithoutUserGesture { [ChromeEarlGrey setContentSettings:CONTENT_SETTING_BLOCK];
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index eaf4b44c..de12fcdc 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -225,11 +225,16 @@ deps = [ "//base", "//base/test:test_support", + "//components/payments/core:core", "//components/signin/core/browser", "//components/strings", "//components/sync/base", + "//components/translate/core/browser", + "//components/ukm/ios:features", "//components/unified_consent", "//ios/chrome/app/strings", + "//ios/chrome/browser/ntp:features", + "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/authentication:authentication", "//ios/chrome/browser/ui/authentication/cells", "//ios/chrome/browser/ui/bookmarks:bookmarks_ui", @@ -258,9 +263,11 @@ "//ios/third_party/material_components_ios", "//ios/web", "//ios/web:earl_grey_test_support", + "//ios/web/common", "//ios/web/public/deprecated", "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", + "//services/metrics/public/cpp:metrics_cpp", "//ui/base", "//ui/base:test_support", "//url", @@ -315,11 +322,16 @@ deps = [ "//base", "//base/test:test_support", + "//components/payments/core:core", "//components/signin/core/browser", "//components/strings", "//components/sync/base", + "//components/translate/core/browser", + "//components/ukm/ios:features", "//components/unified_consent", "//ios/chrome/app/strings", + "//ios/chrome/browser/ntp:features", + "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/authentication/cells", "//ios/chrome/browser/ui/bookmarks:bookmarks_ui", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", @@ -342,9 +354,12 @@ "//ios/testing/earl_grey:eg_app_support+eg2", "//ios/third_party/earl_grey2:app_framework+link", "//ios/web:eg_app_support+eg2", + "//ios/web/common", + "//ios/web/public", "//ios/web/public/deprecated", "//ios/web/public/test:element_selector", "//ios/web/public/test:util", + "//services/metrics/public/cpp:metrics_cpp", "//ui/base", "//ui/base:test_support", ]
diff --git a/ios/chrome/test/earl_grey/DEPS b/ios/chrome/test/earl_grey/DEPS index 3eb4b9c..371d256 100644 --- a/ios/chrome/test/earl_grey/DEPS +++ b/ios/chrome/test/earl_grey/DEPS
@@ -4,4 +4,10 @@ "chrome_test_case\.mm": [ "+ios/web/public/test/http_server", ], + # To compile base::Feature under EG2 + "chrome_earl_grey_app_interface\.mm":[ + "+components/payments/core/features.h", + "+components/ukm/ios/features.h", + "+services/metrics/public/cpp/ukm_recorder.h", + ], }
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h index bddc630..3cd4c055 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -318,6 +318,26 @@ // A GREYAssert is induced if cookies can not be returned. - (NSDictionary*)cookies; +#pragma mark - Feature enables checkers + +// Returns YES if SlimNavigationManager feature is enabled. +- (BOOL)isSlimNavigationManagerEnabled WARN_UNUSED_RESULT; + +// Returns YES if BlockNewTabPagePendingLoad feature is enabled. +- (BOOL)isBlockNewTabPagePendingLoadEnabled WARN_UNUSED_RESULT; + +// Returns YES if NewOmniboxPopupLayout feature is enabled. +- (BOOL)isNewOmniboxPopupLayoutEnabled WARN_UNUSED_RESULT; + +// Returns YES if UmaCellular feature is enabled. +- (BOOL)isUMACellularEnabled WARN_UNUSED_RESULT; + +// Returns YES if UKM feature is enabled. +- (BOOL)isUKMEnabled WARN_UNUSED_RESULT; + +// Returns YES if WebPaymentsModifiers feature is enabled. +- (BOOL)isWebPaymentsModifiersEnabled WARN_UNUSED_RESULT; + @end // Helpers that only compile under EarlGrey 1 are included in this "EG1"
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index 6567828..61a00c6 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -526,6 +526,32 @@ return result; } +#pragma mark - Check features + +- (BOOL)isSlimNavigationManagerEnabled { + return [ChromeEarlGreyAppInterface isSlimNavigationManagerEnabled]; +} + +- (BOOL)isBlockNewTabPagePendingLoadEnabled { + return [ChromeEarlGreyAppInterface isBlockNewTabPagePendingLoadEnabled]; +} + +- (BOOL)isNewOmniboxPopupLayoutEnabled { + return [ChromeEarlGreyAppInterface isNewOmniboxPopupLayoutEnabled]; +} + +- (BOOL)isUMACellularEnabled { + return [ChromeEarlGreyAppInterface isUMACellularEnabled]; +} + +- (BOOL)isUKMEnabled { + return [ChromeEarlGreyAppInterface isUKMEnabled]; +} + +- (BOOL)isWebPaymentsModifiersEnabled { + return [ChromeEarlGreyAppInterface isWebPaymentsModifiersEnabled]; +} + @end // The helpers below only compile under EarlGrey1.
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h index 21c99708..1e230ef 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -253,6 +253,30 @@ // otherwise returns object representing execution result. + (id)executeJavaScript:(NSString*)javaScript error:(NSError**)error; +#pragma mark - Check features + +// Helpers for checking feature state. These can't use FeatureList directly when +// invoked from test code, as the EG test code runs in a separate process and +// must query Chrome for the state. + +// Returns YES if SlimNavigationManager feature is enabled. ++ (BOOL)isSlimNavigationManagerEnabled WARN_UNUSED_RESULT; + +// Returns YES if BlockNewTabPagePendingLoad feature is enabled. ++ (BOOL)isBlockNewTabPagePendingLoadEnabled WARN_UNUSED_RESULT; + +// Returns YES if NewOmniboxPopupLayout feature is enabled. ++ (BOOL)isNewOmniboxPopupLayoutEnabled WARN_UNUSED_RESULT; + +// Returns YES if UmaCellular feature is enabled. ++ (BOOL)isUMACellularEnabled WARN_UNUSED_RESULT; + +// Returns YES if UKM feature is enabled. ++ (BOOL)isUKMEnabled WARN_UNUSED_RESULT; + +// Returns YES if WebPaymentsModifiers feature is enabled. ++ (BOOL)isWebPaymentsModifiersEnabled WARN_UNUSED_RESULT; + @end #endif // IOS_CHROME_TEST_EARL_GREY_CHROME_EARL_GREY_APP_INTERFACE_H_
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm index a6407b7..c8b352f 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -6,6 +6,10 @@ #import "base/test/ios/wait_util.h" #include "base/strings/sys_string_conversions.h" +#import "components/payments/core/features.h" +#import "components/ukm/ios/features.h" +#import "ios/chrome/browser/ntp/features.h" +#import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/test/app/bookmarks_test_util.h" #import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/app/history_test_util.h" @@ -15,11 +19,14 @@ #import "ios/chrome/test/app/sync_test_util.h" #import "ios/chrome/test/app/tab_test_util.h" #import "ios/testing/nserror_util.h" +#import "ios/web/common/features.h" #import "ios/web/public/deprecated/crw_js_injection_receiver.h" #import "ios/web/public/test/earl_grey/js_test_util.h" #import "ios/web/public/test/element_selector.h" #import "ios/web/public/test/web_view_content_test_util.h" #import "ios/web/public/test/web_view_interaction_test_util.h" +#import "ios/web/public/web_client.h" +#import "services/metrics/public/cpp/ukm_recorder.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -439,4 +446,30 @@ return blockResult; } +#pragma mark - Check features + ++ (BOOL)isSlimNavigationManagerEnabled { + return base::FeatureList::IsEnabled(web::features::kSlimNavigationManager); +} + ++ (BOOL)isBlockNewTabPagePendingLoadEnabled { + return base::FeatureList::IsEnabled(kBlockNewTabPagePendingLoad); +} + ++ (BOOL)isNewOmniboxPopupLayoutEnabled { + return base::FeatureList::IsEnabled(kNewOmniboxPopupLayout); +} + ++ (BOOL)isUMACellularEnabled { + return base::FeatureList::IsEnabled(kUmaCellular); +} + ++ (BOOL)isUKMEnabled { + return base::FeatureList::IsEnabled(ukm::kUkmFeature); +} ++ (BOOL)isWebPaymentsModifiersEnabled { + return base::FeatureList::IsEnabled( + payments::features::kWebPaymentsModifiers); +} + @end
diff --git a/ios/public/provider/chrome/browser/signin/chrome_identity_service.h b/ios/public/provider/chrome/browser/signin/chrome_identity_service.h index 19e57cf..cde7579 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_identity_service.h +++ b/ios/public/provider/chrome/browser/signin/chrome_identity_service.h
@@ -56,8 +56,15 @@ // Callback to dismiss Web and App settings details view. No-op, if this block // is more than once. // |animated| the view will be dismissed with animation if the value is YES. +// This type is obsolete and should be replaced by +// DismissASMViewControllerBlock. typedef void (^DismissWebAndAppSettingDetailsControllerBlock)(BOOL animated); +// Callback to dismiss ASM view. No-op, if this block is more than once. +// |animated| the view will be dismissed with animation if the value is YES. +// Replaces DismissWebAndAppSettingDetailsControllerBlock type. +typedef void (^DismissASMViewControllerBlock)(BOOL animated); + // Opaque type representing the MDM (Mobile Device Management) status of the // device. Checking for equality is guaranteed to be valid. typedef int MDMDeviceStatus; @@ -111,22 +118,22 @@ ChromeIdentity* identity, id<ChromeIdentityBrowserOpener> browser_opener); - // Returns a new Web and App Setting Details controller to present. - // Deprecated, crbug.com/905680. - // Please use PresentWebAndAppSettingDetailsController(). - virtual UINavigationController* CreateWebAndAppSettingDetailsController( + // Not implemented yet. Please use CreateAccountDetailsController(). + // See: crbug.com/858845. + virtual ios::DismissASMViewControllerBlock PresentAccountDetailsController( ChromeIdentity* identity, - id<ChromeIdentityBrowserOpener> browser_opener); + UIViewController* view_controller, + BOOL animated); // Presents a new Web and App Setting Details view. // |identity| the identity used to present the view. - // |viewController| the view to present the setting details. + // |view_controller| the view to present the setting details. // |animated| the view is presented with animation if YES. // Returns a block to dismiss the presented view. This block can be ignored if // not needed. - virtual DismissWebAndAppSettingDetailsControllerBlock + virtual DismissASMViewControllerBlock PresentWebAndAppSettingDetailsController(ChromeIdentity* identity, - UIViewController* viewController, + UIViewController* view_controller, BOOL animated); // Returns a new ChromeIdentityInteractionManager with |delegate| as its
diff --git a/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm b/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm index d90db5d8..88ed76b 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm +++ b/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm
@@ -33,17 +33,18 @@ return nil; } -UINavigationController* -ChromeIdentityService::CreateWebAndAppSettingDetailsController( +DismissASMViewControllerBlock +ChromeIdentityService::PresentAccountDetailsController( ChromeIdentity* identity, - id<ChromeIdentityBrowserOpener> browser_opener) { + UIViewController* view_controller, + BOOL animated) { return nil; } -DismissWebAndAppSettingDetailsControllerBlock +DismissASMViewControllerBlock ChromeIdentityService::PresentWebAndAppSettingDetailsController( ChromeIdentity* identity, - UIViewController* viewController, + UIViewController* view_controller, BOOL animated) { return nil; }
diff --git a/ios/testing/data/http_server_files/window_open.html b/ios/testing/data/http_server_files/window_open.html index 2ffbcaf2..65b011d5 100644 --- a/ios/testing/data/http_server_files/window_open.html +++ b/ios/testing/data/http_server_files/window_open.html
@@ -62,6 +62,18 @@ <td>about:blank opened in new window or tab<br>(via target)</td> </tr> + <tr id="_webScenarioWindowOpenWithSpecialURL"> + <td> + <a href="about:blank" + onclick="window.open('/..;','_blank');" + name="webScenarioWindowOpenWithSpecialURL" + id="webScenarioWindowOpenWithSpecialURL"> + webScenarioWindowOpenWithSpecialURL + </a> + </td> + <td>/..; opened in new window or tab</td> + </tr> + <tr id="_webScenarioWindowOpenRegularLinkMultipleTimes"> <td> <a href="about:blank"
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index c1717dc..71d50ab 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -240,6 +240,7 @@ "//ios/web/browsing_data:browsing_data_unittests", "//ios/web/common:unittests", "//ios/web/download:download_unittests", + "//ios/web/favicon:unittests", "//ios/web/find_in_page:find_in_page_unittests", "//ios/web/js_messaging:unittests", "//ios/web/security:unittests", @@ -556,7 +557,6 @@ "//ios/web/web_state:context_menu", "//ios/web/web_state/js", "//ios/web/web_state/ui:crw_context_menu_controller", - "//ios/web/web_state/ui:favicon_util", "//net:test_support", "//services/service_manager/public/cpp", "//testing/gmock", @@ -570,7 +570,6 @@ "web_state/ui/crw_web_view_content_view_unittest.mm", "web_state/ui/crw_web_view_proxy_impl_unittest.mm", "web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm", - "web_state/ui/favicon_util_unittest.mm", "web_state/ui/html_element_fetch_request_unittest.mm", "web_state/ui/web_view_js_utils_unittest.mm", "web_state/ui/wk_web_view_configuration_provider_unittest.mm",
diff --git a/ios/web/favicon/BUILD.gn b/ios/web/favicon/BUILD.gn index f4269b0d..f39a52b8 100644 --- a/ios/web/favicon/BUILD.gn +++ b/ios/web/favicon/BUILD.gn
@@ -12,6 +12,22 @@ sources = [ "favicon_status.cc", "favicon_url.cc", + "favicon_util.h", + "favicon_util.mm", + ] +} + +source_set("unittests") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + deps = [ + "//base", + "//ios/web/favicon", + "//ios/web/public/favicon", + "//testing/gtest", + ] + sources = [ + "favicon_util_unittest.mm", ] }
diff --git a/ios/web/web_state/ui/favicon_util.h b/ios/web/favicon/favicon_util.h similarity index 86% rename from ios/web/web_state/ui/favicon_util.h rename to ios/web/favicon/favicon_util.h index 97bc2eb..a745966e 100644 --- a/ios/web/web_state/ui/favicon_util.h +++ b/ios/web/favicon/favicon_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_WEB_STATE_UI_FAVICON_UTIL_H_ -#define IOS_WEB_WEB_STATE_UI_FAVICON_UTIL_H_ +#ifndef IOS_WEB_FAVICON_FAVICON_UTIL_H_ +#define IOS_WEB_FAVICON_FAVICON_UTIL_H_ #include "ios/web/public/favicon/favicon_url.h" @@ -24,4 +24,4 @@ std::vector<web::FaviconURL>* out_parameter); } // namespace web -#endif // IOS_WEB_WEB_STATE_UI_FAVICON_UTIL_H_ +#endif // IOS_WEB_FAVICON_FAVICON_UTIL_H_
diff --git a/ios/web/web_state/ui/favicon_util.mm b/ios/web/favicon/favicon_util.mm similarity index 98% rename from ios/web/web_state/ui/favicon_util.mm rename to ios/web/favicon/favicon_util.mm index 588e068f..dc93ef4 100644 --- a/ios/web/web_state/ui/favicon_util.mm +++ b/ios/web/favicon/favicon_util.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/web/web_state/ui/favicon_util.h" +#import "ios/web/favicon/favicon_util.h" #include <CoreFoundation/CoreFoundation.h> #import <WebKit/WebKit.h>
diff --git a/ios/web/web_state/ui/favicon_util_unittest.mm b/ios/web/favicon/favicon_util_unittest.mm similarity index 99% rename from ios/web/web_state/ui/favicon_util_unittest.mm rename to ios/web/favicon/favicon_util_unittest.mm index 108bca5..1cb8cc6 100644 --- a/ios/web/web_state/ui/favicon_util_unittest.mm +++ b/ios/web/favicon/favicon_util_unittest.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/web/web_state/ui/favicon_util.h" +#import "ios/web/favicon/favicon_util.h" #include "base/values.h" #include "ios/web/public/favicon/favicon_url.h"
diff --git a/ios/web/init/ios_global_state.mm b/ios/web/init/ios_global_state.mm index a8bb7df5..bb209eb 100644 --- a/ios/web/init/ios_global_state.mm +++ b/ios/web/init/ios_global_state.mm
@@ -58,7 +58,7 @@ void CreateNetworkChangeNotifier() { static dispatch_once_t once_token; dispatch_once(&once_token, ^{ - g_network_change_notifer = net::NetworkChangeNotifier::Create(); + g_network_change_notifer = net::NetworkChangeNotifier::Create().release(); }); }
diff --git a/ios/web/navigation/crw_wk_navigation_handler.mm b/ios/web/navigation/crw_wk_navigation_handler.mm index b500d0a..4e9131d 100644 --- a/ios/web/navigation/crw_wk_navigation_handler.mm +++ b/ios/web/navigation/crw_wk_navigation_handler.mm
@@ -273,6 +273,7 @@ loadParams.referrer = self.currentReferrer; self.webStateImpl->GetNavigationManager()->LoadURLWithParams(loadParams); + return; } }
diff --git a/ios/web/web_state/ui/BUILD.gn b/ios/web/web_state/ui/BUILD.gn index 87ff8b7..c9922bb8 100644 --- a/ios/web/web_state/ui/BUILD.gn +++ b/ios/web/web_state/ui/BUILD.gn
@@ -8,12 +8,12 @@ deps = [ ":crw_context_menu_controller", ":crw_web_view_navigation_proxy", - ":favicon_util", "//base", "//ios/net", "//ios/web:core", "//ios/web/browsing_data", "//ios/web/common", + "//ios/web/favicon", "//ios/web/find_in_page", "//ios/web/js_messaging", "//ios/web/navigation", @@ -121,19 +121,3 @@ configs += [ "//build/config/compiler:enable_arc" ] } - -source_set("favicon_util") { - deps = [ - "//base", - "//ios/web/public", - ] - - sources = [ - "favicon_util.h", - "favicon_util.mm", - ] - - libs = [ "WebKit.framework" ] - - configs += [ "//build/config/compiler:enable_arc" ] -}
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index b850dae..e4577ed 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -48,6 +48,7 @@ #include "ios/web/common/features.h" #include "ios/web/common/referrer_util.h" #include "ios/web/common/url_util.h" +#import "ios/web/favicon/favicon_util.h" #import "ios/web/find_in_page/find_in_page_manager_impl.h" #include "ios/web/history_state_util.h" #import "ios/web/js_messaging/crw_js_injector.h" @@ -112,7 +113,6 @@ #import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" #import "ios/web/web_state/ui/crw_wk_ui_handler.h" #import "ios/web/web_state/ui/crw_wk_ui_handler_delegate.h" -#import "ios/web/web_state/ui/favicon_util.h" #import "ios/web/web_state/ui/wk_security_origin_util.h" #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" #import "ios/web/web_state/user_interaction_state.h"
diff --git a/ios/web/web_state/ui/crw_wk_ui_handler.mm b/ios/web/web_state/ui/crw_wk_ui_handler.mm index 7f1c5346..9952809 100644 --- a/ios/web/web_state/ui/crw_wk_ui_handler.mm +++ b/ios/web/web_state/ui/crw_wk_ui_handler.mm
@@ -69,7 +69,7 @@ GURL requestURL = net::GURLWithNSURL(action.request.URL); if (!requestURL.is_empty() && !requestURL.is_valid()) { DLOG(WARNING) << "Unable to open a window with invalid URL: " - << requestURL.spec(); + << requestURL.possibly_invalid_spec(); return nil; }
diff --git a/ios/web_view/internal/sync/cwv_sync_controller.mm b/ios/web_view/internal/sync/cwv_sync_controller.mm index 0b1ff663..8cf7eb2 100644 --- a/ios/web_view/internal/sync/cwv_sync_controller.mm +++ b/ios/web_view/internal/sync/cwv_sync_controller.mm
@@ -198,7 +198,9 @@ } - (void)reloadCredentials { - _identityManager->LegacyReloadAccountsFromSystem(); + if (_currentIdentity != nil) { + _identityManager->LegacyReloadAccountsFromSystem(); + } } #pragma mark - Internal Methods
diff --git a/media/audio/fuchsia/audio_output_stream_fuchsia.cc b/media/audio/fuchsia/audio_output_stream_fuchsia.cc index 88c64942..4a79c4a 100644 --- a/media/audio/fuchsia/audio_output_stream_fuchsia.cc +++ b/media/audio/fuchsia/audio_output_stream_fuchsia.cc
@@ -71,7 +71,9 @@ DCHECK(!timer_.IsRunning()); callback_ = callback; - PumpSamples(); + // Start playback only after OnMinLeadTimeChanged is received. + if (min_lead_time_.has_value()) + PumpSamples(); } void AudioOutputStreamFuchsia::Stop() { @@ -117,7 +119,7 @@ // Ensure that |payload_buffer_| fits enough packets to cover min_lead_time_ // plus one extra packet. int min_packets = (AudioTimestampHelper::TimeToFrames( - min_lead_time_, parameters_.sample_rate()) + + min_lead_time_.value(), parameters_.sample_rate()) + parameters_.frames_per_buffer() - 1) / parameters_.frames_per_buffer() + 1; @@ -144,6 +146,8 @@ } void AudioOutputStreamFuchsia::OnMinLeadTimeChanged(int64_t min_lead_time) { + bool min_lead_time_was_unknown = !min_lead_time_.has_value(); + min_lead_time_ = base::TimeDelta::FromNanoseconds(min_lead_time); // When min_lead_time_ increases we may need to reallocate |payload_buffer_|. @@ -159,6 +163,13 @@ // AddPayloadBuffer() will fail if there are any packets in flight. audio_renderer_->DiscardAllPacketsNoReply(); } + + // If playback was started but we were waiting for MinLeadTime, then start + // pumping samples now. + if (callback_ && min_lead_time_was_unknown) { + DCHECK(!timer_.IsRunning()); + PumpSamples(); + } } void AudioOutputStreamFuchsia::OnRendererError(zx_status_t status) { @@ -186,27 +197,21 @@ base::TimeDelta delay; if (reference_time_.is_null()) { - delay = min_lead_time_; + delay = min_lead_time_.value() + parameters_.GetBufferDuration() / 2; + stream_position_samples_ = 0; } else { auto stream_time = GetCurrentStreamTime(); // Adjust stream position if we missed timer deadline. - if (now + min_lead_time_ > stream_time) { + if (now + min_lead_time_.value() > stream_time) { stream_position_samples_ += AudioTimestampHelper::TimeToFrames( - now + min_lead_time_ - stream_time, parameters_.sample_rate()); + now + min_lead_time_.value() - stream_time, + parameters_.sample_rate()); } delay = stream_time - now; } - // Start playback if the stream was previously stopped. - if (reference_time_.is_null()) { - stream_position_samples_ = 0; - reference_time_ = now + min_lead_time_; - audio_renderer_->PlayNoReply(reference_time_.ToZxTime(), - stream_position_samples_); - } - // Request more samples from |callback_|. int frames_filled = callback_->OnMoreData(delay, now, 0, audio_bus_.get()); DCHECK_EQ(frames_filled, audio_bus_->frames()); @@ -230,6 +235,13 @@ packet.flags = 0; audio_renderer_->SendPacketNoReply(std::move(packet)); + // Start playback if the stream was previously stopped. + if (reference_time_.is_null()) { + reference_time_ = now + delay; + audio_renderer_->PlayNoReply(reference_time_.ToZxTime(), + stream_position_samples_); + } + stream_position_samples_ += frames_filled; payload_buffer_pos_ = (payload_buffer_pos_ + packet_size) % payload_buffer_.size(); @@ -238,7 +250,8 @@ } void AudioOutputStreamFuchsia::SchedulePumpSamples(base::TimeTicks now) { - base::TimeTicks next_pump_time = GetCurrentStreamTime() - min_lead_time_ - + base::TimeTicks next_pump_time = GetCurrentStreamTime() - + min_lead_time_.value() - parameters_.GetBufferDuration() / 2; timer_.Start(FROM_HERE, next_pump_time - now, base::Bind(&AudioOutputStreamFuchsia::PumpSamples,
diff --git a/media/audio/fuchsia/audio_output_stream_fuchsia.h b/media/audio/fuchsia/audio_output_stream_fuchsia.h index 9727702..a454e424 100644 --- a/media/audio/fuchsia/audio_output_stream_fuchsia.h +++ b/media/audio/fuchsia/audio_output_stream_fuchsia.h
@@ -8,6 +8,7 @@ #include <fuchsia/media/cpp/fidl.h> #include "base/memory/shared_memory_mapping.h" +#include "base/optional.h" #include "base/timer/timer.h" #include "media/audio/audio_io.h" #include "media/base/audio_parameters.h" @@ -79,10 +80,9 @@ int64_t stream_position_samples_; - // Current min lead time for the stream. This value is updated by - // AudioRenderer::OnMinLeadTimeChanged event. Assume 50ms until we get the - // first OnMinLeadTimeChanged event. - base::TimeDelta min_lead_time_ = base::TimeDelta::FromMilliseconds(50); + // Current min lead time for the stream. This value is not set until the first + // AudioRenderer::OnMinLeadTimeChanged event. + base::Optional<base::TimeDelta> min_lead_time_; // Timer that's scheduled to call PumpSamples(). base::OneShotTimer timer_;
diff --git a/media/base/fake_audio_worker_unittest.cc b/media/base/fake_audio_worker_unittest.cc index a6f7ac4..b1ee9e6 100644 --- a/media/base/fake_audio_worker_unittest.cc +++ b/media/base/fake_audio_worker_unittest.cc
@@ -19,7 +19,10 @@ namespace media { -static const int kTestCallbacks = 5; +static const size_t kTestCallbacks = 5; + +using testing::Eq; +using testing::SizeIs; class FakeAudioWorkerTest : public testing::Test { public: @@ -44,16 +47,6 @@ &FakeAudioWorkerTest::CalledByFakeWorker, base::Unretained(this))); } - void RunOnceOnAudioThread() { - ASSERT_TRUE(TaskRunner()->BelongsToCurrentThread()); - RunOnAudioThread(); - // Start() should immediately post a task to run the callback, so we - // should end up with only a single callback being run. - TaskRunner()->PostTask(FROM_HERE, - base::BindOnce(&FakeAudioWorkerTest::EndTest, - base::Unretained(this), 1)); - } - void StopStartOnAudioThread() { ASSERT_TRUE(TaskRunner()->BelongsToCurrentThread()); fake_worker_.Stop(); @@ -75,14 +68,13 @@ base::Unretained(this), callbacks), time_between_callbacks_ / 2); } else { - EndTest(callbacks); + EndTest(); } } - void EndTest(size_t callbacks) { + void EndTest() { ASSERT_TRUE(TaskRunner()->BelongsToCurrentThread()); fake_worker_.Stop(); - EXPECT_LE(callbacks, callbacks_.size()); } scoped_refptr<base::SingleThreadTaskRunner> TaskRunner() { @@ -102,18 +94,24 @@ DISALLOW_COPY_AND_ASSIGN(FakeAudioWorkerTest); }; -// Ensure the worker runs on the audio thread and fires callbacks. -// TODO(https://crbug.com/945486): Flakily failing on Fuchsia. -#if defined(OS_FUCHSIA) -#define MAYBE_FakeBasicCallback DISABLED_FakeBasicCallback -#else -#define MAYBE_FakeBasicCallback FakeBasicCallback -#endif -TEST_F(FakeAudioWorkerTest, MAYBE_FakeBasicCallback) { - scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&FakeAudioWorkerTest::RunOnceOnAudioThread, - base::Unretained(this))); +TEST_F(FakeAudioWorkerTest, FakeBasicCallback) { + base::OnceClosure run_on_audio_thread = base::BindOnce( + &FakeAudioWorkerTest::RunOnAudioThread, base::Unretained(this)); + base::OnceClosure end_test = + base::BindOnce(&FakeAudioWorkerTest::EndTest, base::Unretained(this)); + + // Start() should immediately post a task to run the callback, so we + // should end up with only a single callback being run. + // + // PostTaskAndReply because we want to end_test after run_on_audio_thread is + // finished. This is because RunOnAudioThread may post other tasks which + // should run before we end_test. + scoped_task_environment_.GetMainThreadTaskRunner()->PostTaskAndReply( + FROM_HERE, std::move(run_on_audio_thread), std::move(end_test)); + scoped_task_environment_.RunUntilIdle(); + + EXPECT_THAT(callbacks_, SizeIs(1)); } // Ensure the time between callbacks is correct. @@ -124,6 +122,8 @@ base::Unretained(this), kTestCallbacks)); scoped_task_environment_.FastForwardUntilNoTasksRemain(); + EXPECT_THAT(callbacks_, SizeIs(Eq(kTestCallbacks))); + // There are only (kTestCallbacks - 1) intervals between kTestCallbacks. base::TimeTicks start_time = callbacks_.front(); std::vector<base::TimeTicks> expected_callback_times; @@ -144,21 +144,29 @@ // Ensure Start()/Stop() on the worker doesn't generate too many callbacks. See // http://crbug.com/159049. -// Flaky test; see crbug.com/974078 -TEST_F(FakeAudioWorkerTest, DISABLED_StartStopClearsCallbacks) { - TaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&FakeAudioWorkerTest::TimeCallbacksOnAudioThread, - base::Unretained(this), kTestCallbacks)); +TEST_F(FakeAudioWorkerTest, StartStopClearsCallbacks) { + TaskRunner()->PostTask(FROM_HERE, + base::BindOnce(&FakeAudioWorkerTest::RunOnAudioThread, + base::Unretained(this))); - // Issue a Stop() / Start() in between expected callbacks to maximize the - // chance of catching the worker doing the wrong thing. + // Issuing a Stop() / Start() in the middle of the callback period should not + // trigger a callback. scoped_task_environment_.FastForwardBy(time_between_callbacks_ / 2); + EXPECT_THAT(callbacks_, SizeIs(1)); TaskRunner()->PostTask( FROM_HERE, base::BindOnce(&FakeAudioWorkerTest::StopStartOnAudioThread, base::Unretained(this))); + scoped_task_environment_.FastForwardBy(time_between_callbacks_); + // We expect 3 callbacks: First Start(), Second Start(), and one for the + // period. If the first callback was not cancelled, we would get 4 callbacks, + // two on the first period. + TaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(&FakeAudioWorkerTest::EndTest, base::Unretained(this))); + // EndTest() will ensure the proper number of callbacks have occurred. scoped_task_environment_.FastForwardUntilNoTasksRemain(); + EXPECT_THAT(callbacks_, SizeIs(3)); } } // namespace media
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index d889d209..fa3efa5 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -242,10 +242,10 @@ const base::Feature kMemoryPressureBasedSourceBufferGC{ "MemoryPressureBasedSourceBufferGC", base::FEATURE_DISABLED_BY_DEFAULT}; -// Enable the instance from LinuxVideoDecoderFactory in MojoVideoDecoderService, -// replacing VdaVideoDecoder at Chrome OS platform. -const base::Feature kLinuxVideoDecoder{"LinuxVideoDecoder", - base::FEATURE_DISABLED_BY_DEFAULT}; +// Enable the instance from ChromeosVideoDecoderFactory in +// MojoVideoDecoderService, replacing VdaVideoDecoder at Chrome OS platform. +const base::Feature kChromeosVideoDecoder{"ChromeosVideoDecoder", + base::FEATURE_DISABLED_BY_DEFAULT}; // Enable The D3D11 Video decoder. const base::Feature kD3D11VideoDecoder{"D3D11VideoDecoder", @@ -264,6 +264,10 @@ const base::Feature kFallbackAfterDecodeError{"FallbackAfterDecodeError", base::FEATURE_ENABLED_BY_DEFAULT}; +// Show toolbar button that opens dialog for controlling media sessions. +const base::Feature kGlobalMediaControls{"GlobalMediaControls", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enable new cpu load estimator. Intended for evaluation in local // testing and origin-trial. // TODO(nisse): Delete once we have switched over to always using the
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index b411219..754d633 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -104,6 +104,7 @@ MEDIA_EXPORT extern const base::Feature kExternalClearKeyForTesting; MEDIA_EXPORT extern const base::Feature kFailUrlProvisionFetcherForTesting; MEDIA_EXPORT extern const base::Feature kFallbackAfterDecodeError; +MEDIA_EXPORT extern const base::Feature kGlobalMediaControls; MEDIA_EXPORT extern const base::Feature kHardwareMediaKeyHandling; MEDIA_EXPORT extern const base::Feature kHardwareSecureDecryption; MEDIA_EXPORT extern const base::Feature kInternalMediaSession; @@ -114,7 +115,7 @@ MEDIA_EXPORT extern const base::Feature kMediaEngagementHTTPSOnly; MEDIA_EXPORT extern const base::Feature kMediaLearningExperiment; MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC; -MEDIA_EXPORT extern const base::Feature kLinuxVideoDecoder; +MEDIA_EXPORT extern const base::Feature kChromeosVideoDecoder; MEDIA_EXPORT extern const base::Feature kNewEncodeCpuLoadEstimator; MEDIA_EXPORT extern const base::Feature kOverflowIconsForMediaControls; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo;
diff --git a/media/blink/resource_multibuffer_data_provider.cc b/media/blink/resource_multibuffer_data_provider.cc index be19f06e..551351c 100644 --- a/media/blink/resource_multibuffer_data_provider.cc +++ b/media/blink/resource_multibuffer_data_provider.cc
@@ -120,10 +120,9 @@ options.preflight_policy = network::mojom::CorsPreflightPolicy::kPreventPreflight; - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); + request.SetMode(network::mojom::RequestMode::kCors); if (url_data_->cors_mode() != UrlData::CORS_USE_CREDENTIALS) { - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kSameOrigin); } }
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc index 10c98ed..05a7d5a 100644 --- a/media/capture/video/chromeos/camera_device_delegate.cc +++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -14,6 +14,7 @@ #include "base/bind_helpers.h" #include "base/numerics/ranges.h" #include "base/posix/safe_strerror.h" +#include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" #include "media/base/bind_to_current_loop.h" #include "media/capture/mojom/image_capture_types.h" @@ -120,7 +121,7 @@ return std::string("StreamType::kYUVOutput"); default: return std::string("Unknown StreamType value: ") + - std::to_string(static_cast<int32_t>(stream_type)); + base::NumberToString(static_cast<int32_t>(stream_type)); } } // namespace media @@ -641,7 +642,7 @@ kCrosHalV3DeviceDelegateWrongNumberOfStreamsConfigured, FROM_HERE, std::string("Wrong number of streams configured: ") + - std::to_string(updated_config->streams.size())); + base::NumberToString(updated_config->streams.size())); return; }
diff --git a/media/capture/video/chromeos/camera_hal_delegate_unittest.cc b/media/capture/video/chromeos/camera_hal_delegate_unittest.cc index f9b515e..7c38d0ac 100644 --- a/media/capture/video/chromeos/camera_hal_delegate_unittest.cc +++ b/media/capture/video/chromeos/camera_hal_delegate_unittest.cc
@@ -215,9 +215,9 @@ ASSERT_EQ(3u, descriptors.size()); // We have workaround to always put front camera at first. - ASSERT_EQ(std::to_string(1), descriptors[0].device_id); + ASSERT_EQ("1", descriptors[0].device_id); ASSERT_EQ(VideoFacingMode::MEDIA_VIDEO_FACING_USER, descriptors[0].facing); - ASSERT_EQ(std::to_string(0), descriptors[1].device_id); + ASSERT_EQ("0", descriptors[1].device_id); ASSERT_EQ(VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT, descriptors[1].facing); ASSERT_EQ(kFakeDevicePath, descriptors[2].device_id);
diff --git a/media/capture/video/chromeos/request_manager.cc b/media/capture/video/chromeos/request_manager.cc index 8d7d403..a867e1d 100644 --- a/media/capture/video/chromeos/request_manager.cc +++ b/media/capture/video/chromeos/request_manager.cc
@@ -15,6 +15,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/posix/safe_strerror.h" +#include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" #include "media/capture/video/chromeos/camera_buffer_factory.h" #include "media/capture/video/chromeos/camera_device_context.h" @@ -374,7 +375,7 @@ kCrosHalV3BufferManagerInvalidPendingResultId, FROM_HERE, std::string("Invalid pending_result id: ") + - std::to_string(result_id)); + base::NumberToString(result_id)); return; } if (pending_result.partial_metadata_received.count(result_id)) { @@ -383,7 +384,7 @@ kCrosHalV3BufferManagerReceivedDuplicatedPartialMetadata, FROM_HERE, std::string("Received duplicated partial metadata: ") + - std::to_string(result_id)); + base::NumberToString(result_id)); return; } DVLOG(2) << "Received partial result " << result_id << " for frame " @@ -399,7 +400,7 @@ kCrosHalV3BufferManagerIncorrectNumberOfOutputBuffersReceived, FROM_HERE, std::string("Incorrect number of output buffers received: ") + - std::to_string(result->output_buffers->size())); + base::NumberToString(result->output_buffers->size())); return; } @@ -413,7 +414,7 @@ kCrosHalV3BufferManagerInvalidTypeOfOutputBuffersReceived, FROM_HERE, std::string("Invalid type of output buffers received: ") + - std::to_string(stream_buffer->stream_id)); + base::NumberToString(stream_buffer->stream_id)); return; } @@ -429,8 +430,9 @@ kCrosHalV3BufferManagerReceivedMultipleResultBuffersForFrame, FROM_HERE, std::string("Received multiple result buffers for frame ") + - std::to_string(frame_number) + std::string(" for stream ") + - std::to_string(stream_buffer->stream_id)); + base::NumberToString(frame_number) + + std::string(" for stream ") + + base::NumberToString(stream_buffer->stream_id)); return; } else if (last_received_frame_number_map_[stream_type] > frame_number) { @@ -440,8 +442,10 @@ FROM_HERE, std::string("Received frame is out-of-order; expect frame number " "greater than ") + - std::to_string(last_received_frame_number_map_[stream_type]) + - std::string(" but got ") + std::to_string(frame_number)); + base::NumberToString( + last_received_frame_number_map_[stream_type]) + + std::string(" but got ") + + base::NumberToString(frame_number)); } else { last_received_frame_number_map_[stream_type] = frame_number; } @@ -511,7 +515,7 @@ kCrosHalV3BufferManagerUnknownStreamInCamera3NotifyMsg, FROM_HERE, std::string("Unknown stream in Camera3NotifyMsg: ") + - std::to_string(error_stream_id)); + base::NumberToString(error_stream_id)); return; } cros::mojom::Camera3ErrorMsgCode error_code = error->error_code; @@ -528,7 +532,7 @@ kCrosHalV3BufferManagerReceivedInvalidShutterTime, FROM_HERE, std::string("Received invalid shutter time: ") + - std::to_string(shutter_time)); + base::NumberToString(shutter_time)); return; } CaptureResult& pending_result = pending_results_[frame_number]; @@ -573,7 +577,7 @@ // buffers will be reused in SubmitCaptureResult. warning_msg = std::string("An error occurred while processing request for frame ") + - std::to_string(frame_number); + base::NumberToString(frame_number); break; case cros::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_RESULT: @@ -583,7 +587,7 @@ warning_msg = std::string( "An error occurred while producing result " "metadata for frame ") + - std::to_string(frame_number); + base::NumberToString(frame_number); break; case cros::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_BUFFER: @@ -598,7 +602,7 @@ warning_msg = std::string( "An error occurred while filling output buffer for frame ") + - std::to_string(frame_number); + base::NumberToString(frame_number); break; default:
diff --git a/media/capture/video/chromeos/stream_buffer_manager.cc b/media/capture/video/chromeos/stream_buffer_manager.cc index 6ba6adf..95efff1 100644 --- a/media/capture/video/chromeos/stream_buffer_manager.cc +++ b/media/capture/video/chromeos/stream_buffer_manager.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/posix/safe_strerror.h" +#include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" #include "media/capture/video/chromeos/camera_buffer_factory.h" #include "media/capture/video/chromeos/camera_device_context.h" @@ -102,7 +103,7 @@ kCrosHalV3BufferManagerHalRequestedTooManyBuffers, FROM_HERE, std::string("Camera HAL requested ") + - std::to_string(stream->max_buffers) + + base::NumberToString(stream->max_buffers) + std::string(" buffers which exceeds the allowed maximum " "number of buffers")); return;
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index b3f43cd..f2b7c9d 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -81,10 +81,10 @@ libs = [] ldflags = [] - if (is_linux) { + if (is_chromeos) { public_deps += [ - "//media/gpu/linux", - "//media/gpu/linux:common", + "//media/gpu/chromeos", + "//media/gpu/chromeos:common", ] } @@ -350,8 +350,8 @@ deps = [] # generic_dmabuf_video_frame_mapper - if (is_linux) { - deps += [ "//media/gpu/linux:video_frame_mapper" ] + if (is_chromeos) { + deps += [ "//media/gpu/chromeos:video_frame_mapper" ] } # vaapi_dmabuf_video_frame_mapper @@ -554,8 +554,8 @@ "h264_decoder_unittest.cc", ] - if (is_linux) { - deps += [ "//media/gpu/linux:unit_tests" ] + if (is_chromeos) { + deps += [ "//media/gpu/chromeos:unit_tests" ] } if (use_vaapi) { deps += [ "//media/gpu/vaapi:unit_test" ]
diff --git a/media/gpu/linux/BUILD.gn b/media/gpu/chromeos/BUILD.gn similarity index 90% rename from media/gpu/linux/BUILD.gn rename to media/gpu/chromeos/BUILD.gn index 8119c38..090738714 100644 --- a/media/gpu/linux/BUILD.gn +++ b/media/gpu/chromeos/BUILD.gn
@@ -6,13 +6,13 @@ import("//build/config/ui.gni") import("//media/gpu/args.gni") -assert(is_linux) +assert(is_chromeos) -source_set("linux") { +source_set("chromeos") { defines = [ "MEDIA_GPU_IMPLEMENTATION" ] sources = [ - "linux_video_decoder_factory.cc", - "linux_video_decoder_factory.h", + "chromeos_video_decoder_factory.cc", + "chromeos_video_decoder_factory.h", ] deps = [ @@ -24,6 +24,10 @@ "//media/gpu:common", ] + if (use_vaapi) { + deps += [ "//media/gpu/vaapi" ] + } + if (use_v4l2_codec) { deps += [ "//media/gpu/v4l2" ] }
diff --git a/media/gpu/linux/OWNERS b/media/gpu/chromeos/OWNERS similarity index 100% rename from media/gpu/linux/OWNERS rename to media/gpu/chromeos/OWNERS
diff --git a/media/gpu/chromeos/chromeos_video_decoder_factory.cc b/media/gpu/chromeos/chromeos_video_decoder_factory.cc new file mode 100644 index 0000000..d86e96c --- /dev/null +++ b/media/gpu/chromeos/chromeos_video_decoder_factory.cc
@@ -0,0 +1,80 @@ +// 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. + +#include "media/gpu/chromeos/chromeos_video_decoder_factory.h" + +#include <utility> + +#include "base/sequenced_task_runner.h" +#include "media/base/video_decoder.h" +#include "media/gpu/buildflags.h" +#include "media/gpu/chromeos/mailbox_video_frame_converter.h" +#include "media/gpu/chromeos/platform_video_frame_pool.h" + +#if BUILDFLAG(USE_VAAPI) +#include "media/gpu/vaapi/vaapi_video_decoder.h" +#endif + +#if BUILDFLAG(USE_V4L2_CODEC) +#include "media/gpu/v4l2/v4l2_slice_video_decoder.h" +#endif + +namespace media { + +namespace { + +std::unique_ptr<VideoDecoder> CreateChromeosVideoDecoder( + scoped_refptr<base::SequencedTaskRunner> client_task_runner, + std::unique_ptr<DmabufVideoFramePool> frame_pool, + std::unique_ptr<VideoFrameConverter> frame_converter) { + if (!client_task_runner || !frame_pool || !frame_converter) + return nullptr; + + // TODO(dstaessens@): We first try VAAPI as USE_V4L2_CODEC might also be + // set, even though initialization of V4L2SliceVideoDecoder would fail. We + // need to implement a better way to select the correct decoder. +#if BUILDFLAG(USE_VAAPI) + return VaapiVideoDecoder::Create(std::move(client_task_runner), + std::move(frame_pool), + std::move(frame_converter)); +#elif BUILDFLAG(USE_V4L2_CODEC) + return V4L2SliceVideoDecoder::Create(std::move(client_task_runner), + std::move(frame_pool), + std::move(frame_converter)); +#endif + + return nullptr; +} + +} // namespace + +// static +std::unique_ptr<VideoDecoder> ChromeosVideoDecoderFactory::Create( + scoped_refptr<base::SequencedTaskRunner> client_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, + GetCommandBufferStubCB get_stub_cb) { + std::unique_ptr<DmabufVideoFramePool> frame_pool = + std::make_unique<PlatformVideoFramePool>(); + std::unique_ptr<VideoFrameConverter> frame_converter = + std::make_unique<MailboxVideoFrameConverter>( + base::BindRepeating(&DmabufVideoFramePool::UnwrapFrame, + base::Unretained(frame_pool.get())), + std::move(gpu_task_runner), std::move(get_stub_cb)); + + return CreateChromeosVideoDecoder(std::move(client_task_runner), + std::move(frame_pool), + std::move(frame_converter)); +} + +// static +std::unique_ptr<VideoDecoder> ChromeosVideoDecoderFactory::CreateForTesting( + scoped_refptr<base::SequencedTaskRunner> client_task_runner) { + // Use VideoFrameConverter because we don't convert the frame to + // Mailbox-backed. + return CreateChromeosVideoDecoder(std::move(client_task_runner), + std::make_unique<PlatformVideoFramePool>(), + std::make_unique<VideoFrameConverter>()); +} + +} // namespace media
diff --git a/media/gpu/linux/linux_video_decoder_factory.h b/media/gpu/chromeos/chromeos_video_decoder_factory.h similarity index 84% rename from media/gpu/linux/linux_video_decoder_factory.h rename to media/gpu/chromeos/chromeos_video_decoder_factory.h index 0c207244..2f09b5d 100644 --- a/media/gpu/linux/linux_video_decoder_factory.h +++ b/media/gpu/chromeos/chromeos_video_decoder_factory.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 MEDIA_GPU_LINUX_LINUX_VIDEO_DECODER_FACTORY_H_ -#define MEDIA_GPU_LINUX_LINUX_VIDEO_DECODER_FACTORY_H_ +#ifndef MEDIA_GPU_CHROMEOS_CHROMEOS_VIDEO_DECODER_FACTORY_H_ +#define MEDIA_GPU_CHROMEOS_CHROMEOS_VIDEO_DECODER_FACTORY_H_ #include <memory> @@ -23,7 +23,7 @@ class VideoDecoder; -class MEDIA_GPU_EXPORT LinuxVideoDecoderFactory { +class MEDIA_GPU_EXPORT ChromeosVideoDecoderFactory { public: using GetCommandBufferStubCB = base::OnceCallback<gpu::CommandBufferStub*()>; @@ -43,4 +43,4 @@ }; } // namespace media -#endif // MEDIA_GPU_LINUX_LINUX_VIDEO_DECODER_FACTORY_H_ +#endif // MEDIA_GPU_CHROMEOS_CHROMEOS_VIDEO_DECODER_FACTORY_H_
diff --git a/media/gpu/linux/dmabuf_video_frame_pool.cc b/media/gpu/chromeos/dmabuf_video_frame_pool.cc similarity index 90% rename from media/gpu/linux/dmabuf_video_frame_pool.cc rename to media/gpu/chromeos/dmabuf_video_frame_pool.cc index 9ee770e..a1e73e5 100644 --- a/media/gpu/linux/dmabuf_video_frame_pool.cc +++ b/media/gpu/chromeos/dmabuf_video_frame_pool.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 "media/gpu/linux/dmabuf_video_frame_pool.h" +#include "media/gpu/chromeos/dmabuf_video_frame_pool.h" namespace media {
diff --git a/media/gpu/linux/dmabuf_video_frame_pool.h b/media/gpu/chromeos/dmabuf_video_frame_pool.h similarity index 94% rename from media/gpu/linux/dmabuf_video_frame_pool.h rename to media/gpu/chromeos/dmabuf_video_frame_pool.h index cf920376..4f2f0b7 100644 --- a/media/gpu/linux/dmabuf_video_frame_pool.h +++ b/media/gpu/chromeos/dmabuf_video_frame_pool.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 MEDIA_GPU_LINUX_DMABUF_VIDEO_FRAME_POOL_H_ -#define MEDIA_GPU_LINUX_DMABUF_VIDEO_FRAME_POOL_H_ +#ifndef MEDIA_GPU_CHROMEOS_DMABUF_VIDEO_FRAME_POOL_H_ +#define MEDIA_GPU_CHROMEOS_DMABUF_VIDEO_FRAME_POOL_H_ #include "base/memory/scoped_refptr.h" #include "base/sequenced_task_runner.h" @@ -68,4 +68,4 @@ } // namespace media -#endif // MEDIA_GPU_LINUX_DMABUF_VIDEO_FRAME_POOL_H_ +#endif // MEDIA_GPU_CHROMEOS_DMABUF_VIDEO_FRAME_POOL_H_
diff --git a/media/gpu/linux/generic_dmabuf_video_frame_mapper.cc b/media/gpu/chromeos/generic_dmabuf_video_frame_mapper.cc similarity index 98% rename from media/gpu/linux/generic_dmabuf_video_frame_mapper.cc rename to media/gpu/chromeos/generic_dmabuf_video_frame_mapper.cc index f7b59c02..58d2563 100644 --- a/media/gpu/linux/generic_dmabuf_video_frame_mapper.cc +++ b/media/gpu/chromeos/generic_dmabuf_video_frame_mapper.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 "media/gpu/linux/generic_dmabuf_video_frame_mapper.h" +#include "media/gpu/chromeos/generic_dmabuf_video_frame_mapper.h" #include <sys/mman.h>
diff --git a/media/gpu/linux/generic_dmabuf_video_frame_mapper.h b/media/gpu/chromeos/generic_dmabuf_video_frame_mapper.h similarity index 82% rename from media/gpu/linux/generic_dmabuf_video_frame_mapper.h rename to media/gpu/chromeos/generic_dmabuf_video_frame_mapper.h index 89d19411..a5c7213 100644 --- a/media/gpu/linux/generic_dmabuf_video_frame_mapper.h +++ b/media/gpu/chromeos/generic_dmabuf_video_frame_mapper.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 MEDIA_GPU_LINUX_GENERIC_DMABUF_VIDEO_FRAME_MAPPER_H_ -#define MEDIA_GPU_LINUX_GENERIC_DMABUF_VIDEO_FRAME_MAPPER_H_ +#ifndef MEDIA_GPU_CHROMEOS_GENERIC_DMABUF_VIDEO_FRAME_MAPPER_H_ +#define MEDIA_GPU_CHROMEOS_GENERIC_DMABUF_VIDEO_FRAME_MAPPER_H_ #include "media/gpu/media_gpu_export.h" #include "media/gpu/video_frame_mapper.h" @@ -29,4 +29,4 @@ }; } // namespace media -#endif // MEDIA_GPU_LINUX_GENERIC_DMABUF_VIDEO_FRAME_MAPPER_H_ +#endif // MEDIA_GPU_CHROMEOS_GENERIC_DMABUF_VIDEO_FRAME_MAPPER_H_
diff --git a/media/gpu/linux/mailbox_video_frame_converter.cc b/media/gpu/chromeos/mailbox_video_frame_converter.cc similarity index 95% rename from media/gpu/linux/mailbox_video_frame_converter.cc rename to media/gpu/chromeos/mailbox_video_frame_converter.cc index 6b85baf..beb770b 100644 --- a/media/gpu/linux/mailbox_video_frame_converter.cc +++ b/media/gpu/chromeos/mailbox_video_frame_converter.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/gpu/linux/mailbox_video_frame_converter.h" +#include "media/gpu/chromeos/mailbox_video_frame_converter.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback_helpers.h" #include "base/optional.h" #include "base/task/post_task.h" +#include "media/gpu/chromeos/platform_video_frame_utils.h" #include "media/gpu/format_utils.h" -#include "media/gpu/linux/platform_video_frame_utils.h" #include "media/gpu/macros.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_pixmap.h" @@ -173,15 +173,19 @@ // Get NativePixmap. scoped_refptr<gfx::NativePixmap> pixmap; - gfx::BufferFormat buffer_format = + auto buffer_format = VideoPixelFormatToGfxBufferFormat(origin_frame->format()); + if (!buffer_format) { + VLOGF(1) << "Unsupported format: " << origin_frame->format(); + return; + }; #if defined(USE_OZONE) gfx::GpuMemoryBufferHandle handle = CreateGpuMemoryBufferHandle(origin_frame); pixmap = ui::OzonePlatform::GetInstance() ->GetSurfaceFactoryOzone() ->CreateNativePixmapFromHandle( gfx::kNullAcceleratedWidget, origin_frame->coded_size(), - buffer_format, std::move(handle.native_pixmap_handle)); + *buffer_format, std::move(handle.native_pixmap_handle)); #endif // defined(USE_OZONE) if (!pixmap) { VLOGF(1) << "Cannot create NativePixmap."; @@ -190,7 +194,7 @@ // Create GLImage. auto image = base::MakeRefCounted<gl::GLImageNativePixmap>( - origin_frame->coded_size(), buffer_format); + origin_frame->coded_size(), *buffer_format); if (!image->Initialize(std::move(pixmap))) { VLOGF(1) << "Failed to initialize GLImage."; return;
diff --git a/media/gpu/linux/mailbox_video_frame_converter.h b/media/gpu/chromeos/mailbox_video_frame_converter.h similarity index 94% rename from media/gpu/linux/mailbox_video_frame_converter.h rename to media/gpu/chromeos/mailbox_video_frame_converter.h index 67a5d23..fcf4928 100644 --- a/media/gpu/linux/mailbox_video_frame_converter.h +++ b/media/gpu/chromeos/mailbox_video_frame_converter.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 MEDIA_GPU_LINUX_MAILBOX_VIDEO_FRAME_CONVERTER_H_ -#define MEDIA_GPU_LINUX_MAILBOX_VIDEO_FRAME_CONVERTER_H_ +#ifndef MEDIA_GPU_CHROMEOS_MAILBOX_VIDEO_FRAME_CONVERTER_H_ +#define MEDIA_GPU_CHROMEOS_MAILBOX_VIDEO_FRAME_CONVERTER_H_ #include <map> @@ -20,7 +20,7 @@ namespace media { -// The linux VideoDecoder implementations request DMA-buf VideoFrame from the +// The ChromeOS VideoDecoder implementations request DMA-buf VideoFrame from the // DmabufVideoFramePool, and store the decoded data into DMA-buf. However the // client of the VideoDecoder may only accept mailbox VideoFrame. // This class is used for converting DMA-buf VideoFrame to mailbox VideoFrame. @@ -109,4 +109,4 @@ }; } // namespace media -#endif // MEDIA_GPU_LINUX_MAILBOX_VIDEO_FRAME_CONVERTER_H_ +#endif // MEDIA_GPU_CHROMEOS_MAILBOX_VIDEO_FRAME_CONVERTER_H_
diff --git a/media/gpu/linux/platform_video_frame_pool.cc b/media/gpu/chromeos/platform_video_frame_pool.cc similarity index 98% rename from media/gpu/linux/platform_video_frame_pool.cc rename to media/gpu/chromeos/platform_video_frame_pool.cc index b5a1ea5b..9adc12e0 100644 --- a/media/gpu/linux/platform_video_frame_pool.cc +++ b/media/gpu/chromeos/platform_video_frame_pool.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 "media/gpu/linux/platform_video_frame_pool.h" +#include "media/gpu/chromeos/platform_video_frame_pool.h" #include <utility> @@ -10,7 +10,7 @@ #include "base/optional.h" #include "base/task/post_task.h" #include "base/time/default_tick_clock.h" -#include "media/gpu/linux/platform_video_frame_utils.h" +#include "media/gpu/chromeos/platform_video_frame_utils.h" #include "media/gpu/macros.h" namespace media {
diff --git a/media/gpu/linux/platform_video_frame_pool.h b/media/gpu/chromeos/platform_video_frame_pool.h similarity index 95% rename from media/gpu/linux/platform_video_frame_pool.h rename to media/gpu/chromeos/platform_video_frame_pool.h index a4dab7cd1..0a6c6e9 100644 --- a/media/gpu/linux/platform_video_frame_pool.h +++ b/media/gpu/chromeos/platform_video_frame_pool.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 MEDIA_GPU_LINUX_PLATFORM_VIDEO_FRAME_POOL_H_ -#define MEDIA_GPU_LINUX_PLATFORM_VIDEO_FRAME_POOL_H_ +#ifndef MEDIA_GPU_CHROMEOS_PLATFORM_VIDEO_FRAME_POOL_H_ +#define MEDIA_GPU_CHROMEOS_PLATFORM_VIDEO_FRAME_POOL_H_ #include <stddef.h> @@ -15,7 +15,7 @@ #include "base/synchronization/lock.h" #include "base/thread_annotations.h" #include "media/base/video_frame.h" -#include "media/gpu/linux/dmabuf_video_frame_pool.h" +#include "media/gpu/chromeos/dmabuf_video_frame_pool.h" #include "media/gpu/media_gpu_export.h" namespace base { @@ -140,4 +140,4 @@ }; } // namespace media -#endif // MEDIA_GPU_LINUX_PLATFORM_VIDEO_FRAME_POOL_H_ +#endif // MEDIA_GPU_CHROMEOS_PLATFORM_VIDEO_FRAME_POOL_H_
diff --git a/media/gpu/linux/platform_video_frame_pool_unittest.cc b/media/gpu/chromeos/platform_video_frame_pool_unittest.cc similarity index 98% rename from media/gpu/linux/platform_video_frame_pool_unittest.cc rename to media/gpu/chromeos/platform_video_frame_pool_unittest.cc index 9aaafbc..8caa125 100644 --- a/media/gpu/linux/platform_video_frame_pool_unittest.cc +++ b/media/gpu/chromeos/platform_video_frame_pool_unittest.cc
@@ -9,7 +9,7 @@ #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_tick_clock.h" #include "base/threading/thread_task_runner_handle.h" -#include "media/gpu/linux/platform_video_frame_pool.h" +#include "media/gpu/chromeos/platform_video_frame_pool.h" #include "testing/gtest/include/gtest/gtest.h" namespace media {
diff --git a/media/gpu/linux/platform_video_frame_utils.cc b/media/gpu/chromeos/platform_video_frame_utils.cc similarity index 94% rename from media/gpu/linux/platform_video_frame_utils.cc rename to media/gpu/chromeos/platform_video_frame_utils.cc index d71bb94..ad7f596 100644 --- a/media/gpu/linux/platform_video_frame_utils.cc +++ b/media/gpu/chromeos/platform_video_frame_utils.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 "media/gpu/linux/platform_video_frame_utils.h" +#include "media/gpu/chromeos/platform_video_frame_utils.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -35,11 +35,13 @@ ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); DCHECK(factory); - gfx::BufferFormat buffer_format = - VideoPixelFormatToGfxBufferFormat(pixel_format); + auto buffer_format = VideoPixelFormatToGfxBufferFormat(pixel_format); + if (!buffer_format) + return nullptr; + auto pixmap = factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, VK_NULL_HANDLE, - coded_size, buffer_format, buffer_usage); + coded_size, *buffer_format, buffer_usage); if (!pixmap) return nullptr;
diff --git a/media/gpu/linux/platform_video_frame_utils.h b/media/gpu/chromeos/platform_video_frame_utils.h similarity index 84% rename from media/gpu/linux/platform_video_frame_utils.h rename to media/gpu/chromeos/platform_video_frame_utils.h index 35065764..7d388a4 100644 --- a/media/gpu/linux/platform_video_frame_utils.h +++ b/media/gpu/chromeos/platform_video_frame_utils.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 MEDIA_GPU_LINUX_PLATFORM_VIDEO_FRAME_UTILS_H_ -#define MEDIA_GPU_LINUX_PLATFORM_VIDEO_FRAME_UTILS_H_ +#ifndef MEDIA_GPU_CHROMEOS_PLATFORM_VIDEO_FRAME_UTILS_H_ +#define MEDIA_GPU_CHROMEOS_PLATFORM_VIDEO_FRAME_UTILS_H_ #include "media/base/video_frame.h" #include "media/gpu/media_gpu_export.h" @@ -31,4 +31,4 @@ } // namespace media -#endif // MEDIA_GPU_LINUX_PLATFORM_VIDEO_FRAME_UTILS_H_ +#endif // MEDIA_GPU_CHROMEOS_PLATFORM_VIDEO_FRAME_UTILS_H_
diff --git a/media/gpu/format_utils.cc b/media/gpu/format_utils.cc index 007bebc7..bd13fe5b 100644 --- a/media/gpu/format_utils.cc +++ b/media/gpu/format_utils.cc
@@ -37,7 +37,7 @@ } } -gfx::BufferFormat VideoPixelFormatToGfxBufferFormat( +base::Optional<gfx::BufferFormat> VideoPixelFormatToGfxBufferFormat( VideoPixelFormat pixel_format) { switch (pixel_format) { case PIXEL_FORMAT_ARGB: @@ -59,8 +59,8 @@ return gfx::BufferFormat::RGBX_8888; default: - LOG(FATAL) << "Unsupported VideoPixelFormat: " << pixel_format; - return gfx::BufferFormat::BGRX_8888; + DLOG(WARNING) << "Unsupported VideoPixelFormat: " << pixel_format; + return base::nullopt; } }
diff --git a/media/gpu/format_utils.h b/media/gpu/format_utils.h index 7044bba..3e05632 100644 --- a/media/gpu/format_utils.h +++ b/media/gpu/format_utils.h
@@ -5,6 +5,7 @@ #ifndef MEDIA_GPU_FORMAT_UTILS_H_ #define MEDIA_GPU_FORMAT_UTILS_H_ +#include "base/optional.h" #include "media/base/video_types.h" #include "media/gpu/media_gpu_export.h" #include "ui/gfx/buffer_types.h" @@ -14,8 +15,8 @@ MEDIA_GPU_EXPORT VideoPixelFormat GfxBufferFormatToVideoPixelFormat(gfx::BufferFormat format); -MEDIA_GPU_EXPORT gfx::BufferFormat VideoPixelFormatToGfxBufferFormat( - VideoPixelFormat pixel_format); +MEDIA_GPU_EXPORT base::Optional<gfx::BufferFormat> +VideoPixelFormatToGfxBufferFormat(VideoPixelFormat pixel_format); } // namespace media
diff --git a/media/gpu/linux/linux_video_decoder_factory.cc b/media/gpu/linux/linux_video_decoder_factory.cc deleted file mode 100644 index 448d2bd..0000000 --- a/media/gpu/linux/linux_video_decoder_factory.cc +++ /dev/null
@@ -1,69 +0,0 @@ -// 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. - -#include "media/gpu/linux/linux_video_decoder_factory.h" - -#include <utility> - -#include "base/sequenced_task_runner.h" -#include "media/base/video_decoder.h" -#include "media/gpu/buildflags.h" -#include "media/gpu/linux/mailbox_video_frame_converter.h" -#include "media/gpu/linux/platform_video_frame_pool.h" - -#if BUILDFLAG(USE_V4L2_CODEC) -#include "media/gpu/v4l2/v4l2_slice_video_decoder.h" -#endif - -namespace media { - -namespace { - -std::unique_ptr<VideoDecoder> CreateLinuxVideoDecoder( - scoped_refptr<base::SequencedTaskRunner> client_task_runner, - std::unique_ptr<DmabufVideoFramePool> frame_pool, - std::unique_ptr<VideoFrameConverter> frame_converter) { - if (!client_task_runner || !frame_pool || !frame_converter) - return nullptr; - -#if BUILDFLAG(USE_V4L2_CODEC) - return V4L2SliceVideoDecoder::Create(std::move(client_task_runner), - std::move(frame_pool), - std::move(frame_converter)); -#endif - - return nullptr; -} - -} // namespace - -// static -std::unique_ptr<VideoDecoder> LinuxVideoDecoderFactory::Create( - scoped_refptr<base::SequencedTaskRunner> client_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, - GetCommandBufferStubCB get_stub_cb) { - std::unique_ptr<DmabufVideoFramePool> frame_pool = - std::make_unique<PlatformVideoFramePool>(); - std::unique_ptr<VideoFrameConverter> frame_converter = - std::make_unique<MailboxVideoFrameConverter>( - base::BindRepeating(&DmabufVideoFramePool::UnwrapFrame, - base::Unretained(frame_pool.get())), - std::move(gpu_task_runner), std::move(get_stub_cb)); - - return CreateLinuxVideoDecoder(std::move(client_task_runner), - std::move(frame_pool), - std::move(frame_converter)); -} - -// static -std::unique_ptr<VideoDecoder> LinuxVideoDecoderFactory::CreateForTesting( - scoped_refptr<base::SequencedTaskRunner> client_task_runner) { - // Use VideoFrameConverter because we don't convert the frame to - // Mailbox-backed. - return CreateLinuxVideoDecoder(std::move(client_task_runner), - std::make_unique<PlatformVideoFramePool>(), - std::make_unique<VideoFrameConverter>()); -} - -} // namespace media
diff --git a/media/gpu/test/texture_ref.cc b/media/gpu/test/texture_ref.cc index da060e50..6a7b0f7df 100644 --- a/media/gpu/test/texture_ref.cc +++ b/media/gpu/test/texture_ref.cc
@@ -13,9 +13,11 @@ #if defined(OS_LINUX) #include <libdrm/drm_fourcc.h> +#endif // defined(OS_LINUX) -#include "media/gpu/linux/platform_video_frame_utils.h" -#endif +#if defined(OS_CHROMEOS) +#include "media/gpu/chromeos/platform_video_frame_utils.h" +#endif // defined(OS_CHROMEOS) namespace media { namespace test {
diff --git a/media/gpu/test/video_frame_file_writer.cc b/media/gpu/test/video_frame_file_writer.cc index 95c2e610..9129f30 100644 --- a/media/gpu/test/video_frame_file_writer.cc +++ b/media/gpu/test/video_frame_file_writer.cc
@@ -112,7 +112,6 @@ video_frame_mapper_ = VideoFrameMapperFactory::CreateMapper(video_frame->format()); LOG_ASSERT(video_frame_mapper_) << "Failed to create VideoFrameMapper"; - return; } switch (output_format_) {
diff --git a/media/gpu/test/video_frame_helpers.cc b/media/gpu/test/video_frame_helpers.cc index 4cc316a..1020d730 100644 --- a/media/gpu/test/video_frame_helpers.cc +++ b/media/gpu/test/video_frame_helpers.cc
@@ -15,7 +15,7 @@ #if defined(OS_CHROMEOS) #include "media/base/scopedfd_helper.h" -#include "media/gpu/linux/platform_video_frame_utils.h" +#include "media/gpu/chromeos/platform_video_frame_utils.h" #include "media/gpu/video_frame_mapper.h" #include "media/gpu/video_frame_mapper_factory.h" #endif
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.cc b/media/gpu/test/video_player/test_vda_video_decoder.cc index 10b890c0..0779afb 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.cc +++ b/media/gpu/test/video_player/test_vda_video_decoder.cc
@@ -16,14 +16,15 @@ #include "media/base/video_frame.h" #include "media/base/waiting.h" #include "media/gpu/gpu_video_decode_accelerator_factory.h" -#if defined(OS_LINUX) -#include "media/gpu/linux/platform_video_frame_utils.h" -#endif #include "media/gpu/macros.h" #include "media/gpu/test/video_player/frame_renderer.h" #include "media/gpu/test/video_player/video.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_CHROMEOS) +#include "media/gpu/chromeos/platform_video_frame_utils.h" +#endif // defined(OS_CHROMEOS) + namespace media { namespace test { @@ -172,16 +173,26 @@ void TestVDAVideoDecoder::ProvidePictureBuffers( uint32_t requested_num_of_buffers, - VideoPixelFormat pixel_format, + VideoPixelFormat format, uint32_t textures_per_buffer, - const gfx::Size& size, + const gfx::Size& dimensions, + uint32_t texture_target) { + NOTIMPLEMENTED() << "VDA must call ProvidePictureBuffersWithVisibleRect()"; +} + +void TestVDAVideoDecoder::ProvidePictureBuffersWithVisibleRect( + uint32_t requested_num_of_buffers, + VideoPixelFormat format, + uint32_t textures_per_buffer, + const gfx::Size& dimensions, + const gfx::Rect& visible_rect, uint32_t texture_target) { DCHECK_CALLED_ON_VALID_SEQUENCE(vda_wrapper_sequence_checker_); - ASSERT_NE(pixel_format, PIXEL_FORMAT_UNKNOWN); + ASSERT_NE(format, PIXEL_FORMAT_UNKNOWN); ASSERT_EQ(textures_per_buffer, 1u); DVLOGF(4) << "Requested " << requested_num_of_buffers - << " picture buffers with size " << size.height() << "x" - << size.height(); + << " picture buffers with size " << dimensions.height() << "x" + << dimensions.height(); std::vector<PictureBuffer> picture_buffers; @@ -189,7 +200,7 @@ case VideoDecodeAccelerator::Config::OutputMode::IMPORT: // If using import mode, create a set of DMABuf-backed video frames. for (uint32_t i = 0; i < requested_num_of_buffers; ++i) { - picture_buffers.emplace_back(GetNextPictureBufferId(), size); + picture_buffers.emplace_back(GetNextPictureBufferId(), dimensions); } decoder_->AssignPictureBuffers(picture_buffers); @@ -197,21 +208,21 @@ // handles to the video frame's data to the decoder. for (const PictureBuffer& picture_buffer : picture_buffers) { scoped_refptr<VideoFrame> video_frame; -#if defined(OS_LINUX) +#if defined(OS_CHROMEOS) video_frame = CreatePlatformVideoFrame( - pixel_format, size, gfx::Rect(size), size, base::TimeDelta(), - gfx::BufferUsage::SCANOUT_VDA_WRITE); + format, dimensions, visible_rect, visible_rect.size(), + base::TimeDelta(), gfx::BufferUsage::SCANOUT_VDA_WRITE); #endif LOG_ASSERT(video_frame) << "Failed to create video frame"; video_frames_.emplace(picture_buffer.id(), video_frame); gfx::GpuMemoryBufferHandle handle; -#if defined(OS_LINUX) +#if defined(OS_CHROMEOS) handle = CreateGpuMemoryBufferHandle(video_frame.get()); #else NOTREACHED(); #endif LOG_ASSERT(!handle.is_null()) << "Failed to create GPU memory handle"; - decoder_->ImportBufferForPicture(picture_buffer.id(), pixel_format, + decoder_->ImportBufferForPicture(picture_buffer.id(), format, std::move(handle)); } break; @@ -221,12 +232,12 @@ for (uint32_t i = 0; i < requested_num_of_buffers; ++i) { uint32_t texture_id; auto video_frame = frame_renderer_->CreateVideoFrame( - pixel_format, size, texture_target, &texture_id); + format, dimensions, texture_target, &texture_id); LOG_ASSERT(video_frame) << "Failed to create video frame"; int32_t picture_buffer_id = GetNextPictureBufferId(); PictureBuffer::TextureIds texture_ids(1, texture_id); - picture_buffers.emplace_back(picture_buffer_id, size, texture_ids, - texture_ids, texture_target, pixel_format); + picture_buffers.emplace_back(picture_buffer_id, dimensions, texture_ids, + texture_ids, texture_target, format); video_frames_.emplace(picture_buffer_id, std::move(video_frame)); } // The decoder requires an active GL context to allocate memory. @@ -271,8 +282,8 @@ picture.picture_buffer_id())); scoped_refptr<VideoFrame> wrapped_video_frame = VideoFrame::WrapVideoFrame( - *video_frame, video_frame->format(), video_frame->visible_rect(), - video_frame->visible_rect().size()); + *video_frame, video_frame->format(), picture.visible_rect(), + picture.visible_rect().size()); wrapped_video_frame->AddDestructionObserver(std::move(reuse_cb)); output_cb_.Run(wrapped_video_frame);
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.h b/media/gpu/test/video_player/test_vda_video_decoder.h index bc92adbf..6ea1ffb 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.h +++ b/media/gpu/test/video_player/test_vda_video_decoder.h
@@ -59,10 +59,16 @@ // media::VideoDecodeAccelerator::Client implementation void ProvidePictureBuffers(uint32_t requested_num_of_buffers, - VideoPixelFormat pixel_format, + VideoPixelFormat format, uint32_t textures_per_buffer, - const gfx::Size& size, + const gfx::Size& dimensions, uint32_t texture_target) override; + void ProvidePictureBuffersWithVisibleRect(uint32_t requested_num_of_buffers, + VideoPixelFormat format, + uint32_t textures_per_buffer, + const gfx::Size& dimensions, + const gfx::Rect& visible_rect, + uint32_t texture_target) override; void DismissPictureBuffer(int32_t picture_buffer_id) override; void PictureReady(const Picture& picture) override; void ReusePictureBufferTask(int32_t picture_buffer_id);
diff --git a/media/gpu/test/video_player/video_decoder_client.cc b/media/gpu/test/video_player/video_decoder_client.cc index 3063df4..660fa8a 100644 --- a/media/gpu/test/video_player/video_decoder_client.cc +++ b/media/gpu/test/video_player/video_decoder_client.cc
@@ -19,11 +19,11 @@ #include "media/gpu/test/video_player/test_vda_video_decoder.h" #include "media/gpu/test/video_player/video.h" -#if defined(OS_LINUX) -#include "media/gpu/linux/linux_video_decoder_factory.h" -#include "media/gpu/linux/platform_video_frame_pool.h" +#if defined(OS_CHROMEOS) +#include "media/gpu/chromeos/chromeos_video_decoder_factory.h" +#include "media/gpu/chromeos/platform_video_frame_pool.h" #include "media/gpu/video_frame_converter.h" -#endif // defined(OS_LINUX) +#endif // defined(OS_CHROMEOS) namespace media { namespace test { @@ -177,10 +177,10 @@ base::BindRepeating([](WaitingReason) { NOTIMPLEMENTED(); }); if (decoder_client_config_.use_vd) { -#if defined(OS_LINUX) - decoder_ = LinuxVideoDecoderFactory::CreateForTesting( +#if defined(OS_CHROMEOS) + decoder_ = ChromeosVideoDecoderFactory::CreateForTesting( base::ThreadTaskRunnerHandle::Get()); -#endif // defined(OS_LINUX) +#endif // defined(OS_CHROMEOS) LOG_ASSERT(decoder_) << "Failed to create decoder."; } else { // The video decoder client expects decoders to use the VD interface. We can
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn index d3b910e..b367c4300 100644 --- a/media/gpu/v4l2/BUILD.gn +++ b/media/gpu/v4l2/BUILD.gn
@@ -69,12 +69,13 @@ deps = [ "//base", + "//gpu/ipc/common", "//gpu/ipc/service", "//media", "//media/gpu:buildflags", "//media/gpu:common", "//media/gpu:image_processor_common", - "//media/gpu/linux:common", + "//media/gpu/chromeos:common", "//third_party/libyuv", "//ui/gfx/geometry", "//ui/ozone",
diff --git a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc index 25de2a4..3d0a77a 100644 --- a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc
@@ -12,8 +12,10 @@ #include <memory> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/numerics/ranges.h" #include "base/threading/thread_task_runner_handle.h" +#include "media/gpu/chromeos/platform_video_frame_utils.h" #include "media/gpu/macros.h" #include "media/gpu/v4l2/v4l2_device.h" #include "third_party/libyuv/include/libyuv.h" @@ -61,18 +63,37 @@ V4L2JpegEncodeAccelerator::JobRecord::JobRecord( scoped_refptr<VideoFrame> input_frame, + scoped_refptr<VideoFrame> output_frame, + int quality, + int32_t task_id, + BitstreamBuffer* exif_buffer) + : input_frame(input_frame), + output_frame(output_frame), + quality(quality), + task_id(task_id), + output_shm(base::SharedMemoryHandle(), 0, true), // dummy + exif_shm(nullptr) { + if (exif_buffer) { + exif_shm.reset(new UnalignedSharedMemory(exif_buffer->TakeRegion(), + exif_buffer->size(), false)); + exif_offset = exif_buffer->offset(); + } +} + +V4L2JpegEncodeAccelerator::JobRecord::JobRecord( + scoped_refptr<VideoFrame> input_frame, int quality, BitstreamBuffer* exif_buffer, BitstreamBuffer output_buffer) - : input_frame_(input_frame), + : input_frame(input_frame), quality(quality), - buffer_id_(output_buffer.id()), + task_id(output_buffer.id()), output_shm(output_buffer.TakeRegion(), output_buffer.size(), false), output_offset(output_buffer.offset()), exif_shm(nullptr) { if (exif_buffer) { exif_shm.reset(new UnalignedSharedMemory(exif_buffer->TakeRegion(), - exif_buffer->size(), true)); + exif_buffer->size(), false)); exif_offset = exif_buffer->offset(); } } @@ -654,16 +675,16 @@ I420BufferRecord& input_record = input_buffer_map_[index]; DCHECK(!input_record.at_device); - // Copy image from user memory to MMAP mempry. - uint8_t* src_y = job_record->input_frame_->data(VideoFrame::kYPlane); - uint8_t* src_u = job_record->input_frame_->data(VideoFrame::kUPlane); - uint8_t* src_v = job_record->input_frame_->data(VideoFrame::kVPlane); - size_t src_y_stride = job_record->input_frame_->stride(VideoFrame::kYPlane); - size_t src_u_stride = job_record->input_frame_->stride(VideoFrame::kUPlane); - size_t src_v_stride = job_record->input_frame_->stride(VideoFrame::kVPlane); + // Copy image from user memory to MMAP memory. + uint8_t* src_y = job_record->input_frame->data(VideoFrame::kYPlane); + uint8_t* src_u = job_record->input_frame->data(VideoFrame::kUPlane); + uint8_t* src_v = job_record->input_frame->data(VideoFrame::kVPlane); + size_t src_y_stride = job_record->input_frame->stride(VideoFrame::kYPlane); + size_t src_u_stride = job_record->input_frame->stride(VideoFrame::kUPlane); + size_t src_v_stride = job_record->input_frame->stride(VideoFrame::kVPlane); - size_t input_coded_width = job_record->input_frame_->coded_size().width(); - size_t input_coded_height = job_record->input_frame_->coded_size().height(); + size_t input_coded_width = job_record->input_frame->coded_size().width(); + size_t input_coded_height = job_record->input_frame->coded_size().height(); size_t dst_y_stride = bytes_per_line_[0]; size_t dst_u_stride; @@ -714,7 +735,7 @@ running_job_queue_.push(std::move(job_record)); free_input_buffers_.pop_back(); - DVLOGF(3) << "enqueued frame id=" << job_record->buffer_id_ << " to device."; + DVLOGF(3) << "enqueued frame id=" << job_record->task_id << " to device."; return true; } @@ -893,20 +914,782 @@ static_cast<uint8_t*>(job_record->output_shm.memory()), output_record, planes[0].bytesused, std::move(job_record->exif_shm)); if (!jpeg_size) { - NotifyError(job_record->buffer_id_, PLATFORM_FAILURE); + NotifyError(job_record->task_id, PLATFORM_FAILURE); return; } DVLOGF(4) << "Encoding finished, returning bitstream buffer, id=" - << job_record->buffer_id_; + << job_record->task_id; - parent_->VideoFrameReady(job_record->buffer_id_, jpeg_size); + parent_->VideoFrameReady(job_record->task_id, jpeg_size); } } -void V4L2JpegEncodeAccelerator::EncodedInstance::NotifyError(int32_t buffer_id, +void V4L2JpegEncodeAccelerator::EncodedInstance::NotifyError(int32_t task_id, Status status) { DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); - parent_->NotifyError(buffer_id, status); + parent_->NotifyError(task_id, status); +} + +V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::EncodedInstanceDmaBuf( + V4L2JpegEncodeAccelerator* parent) + : parent_(parent), + input_streamon_(false), + output_streamon_(false), + input_buffer_pixelformat_(0), + input_buffer_num_planes_(0), + output_buffer_pixelformat_(0) {} + +V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::~EncodedInstanceDmaBuf() {} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::DestroyTask() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + while (!input_job_queue_.empty()) + input_job_queue_.pop(); + while (!running_job_queue_.empty()) + running_job_queue_.pop(); + + DestroyInputBuffers(); + DestroyOutputBuffers(); +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::Initialize() { + device_ = V4L2Device::Create(); + gpu_memory_buffer_support_ = std::make_unique<gpu::GpuMemoryBufferSupport>(); + + if (!device_) { + VLOGF(1) << "Failed to Create V4L2Device"; + return false; + } + + output_buffer_pixelformat_ = V4L2_PIX_FMT_JPEG_RAW; + if (!device_->Open(V4L2Device::Type::kJpegEncoder, + output_buffer_pixelformat_)) { + VLOGF(1) << "Failed to open device"; + return false; + } + + // Capabilities check. + struct v4l2_capability caps; + const __u32 kCapsRequired = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; + memset(&caps, 0, sizeof(caps)); + if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) { + VPLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP"; + return false; + } + if ((caps.capabilities & kCapsRequired) != kCapsRequired) { + VLOGF(1) << "VIDIOC_QUERYCAP, caps check failed: 0x" << std::hex + << caps.capabilities; + return false; + } + + return true; +} + +// static +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::FillQuantizationTable( + int quality, + const uint8_t* basic_table, + uint8_t* dst_table) { + unsigned int temp; + + if (quality < 50) + quality = 5000 / quality; + else + quality = 200 - quality * 2; + + for (size_t i = 0; i < kDctSize; i++) { + temp = ((unsigned int)basic_table[kZigZag8x8[i]] * quality + 50) / 100; + /* limit the values to the valid range */ + dst_table[i] = base::ClampToRange(temp, 1u, 255u); + } +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::PrepareJpegMarkers( + gfx::Size coded_size) { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + // Quantization Tables. + // i = 0 for Luminance + // i = 1 for Chrominance + const int kNumDQT = 2; + for (size_t i = 0; i < kNumDQT; ++i) { + const uint8_t kQuantSegment[] = { + 0xFF, JPEG_DQT, 0x00, + 0x03 + kDctSize, // Segment length:67 (2-byte). + static_cast<uint8_t>(i) // Precision (4-bit high) = 0, + // Index (4-bit low) = i. + }; + for (size_t j = 0; j < sizeof(kQuantSegment); ++j) { + jpeg_markers_.push_back(kQuantSegment[j]); + } + + for (size_t j = 0; j < kDctSize; ++j) { + jpeg_markers_.push_back(quantization_table_[i].value[j]); + } + } + + // Start of Frame - Baseline. + const int kNumOfComponents = 3; + const uint8_t kStartOfFrame[] = { + 0xFF, + JPEG_SOF0, // Baseline. + 0x00, + 0x11, // Segment length:17 (2-byte). + 8, // Data precision. + static_cast<uint8_t>((coded_size.height() >> 8) & 0xFF), + static_cast<uint8_t>(coded_size.height() & 0xFF), + static_cast<uint8_t>((coded_size.width() >> 8) & 0xFF), + static_cast<uint8_t>(coded_size.width() & 0xFF), + kNumOfComponents, + }; + for (size_t i = 0; i < sizeof(kStartOfFrame); ++i) { + jpeg_markers_.push_back(kStartOfFrame[i]); + } + // i = 0 for Y Plane + // i = 1 for U Plane + // i = 2 for V Plane + for (size_t i = 0; i < kNumOfComponents; ++i) { + // These are the values for U and V planes. + uint8_t h_sample_factor = 1; + uint8_t v_sample_factor = 1; + uint8_t quant_table_number = 1; + if (!i) { + // These are the values for Y plane. + h_sample_factor = 2; + v_sample_factor = 2; + quant_table_number = 0; + } + + jpeg_markers_.push_back(i + 1); + // Horizontal Sample Factor (4-bit high), + // Vertical Sample Factor (4-bit low). + jpeg_markers_.push_back((h_sample_factor << 4) | v_sample_factor); + jpeg_markers_.push_back(quant_table_number); + } + + // Huffman Tables. + static const uint8_t kDcSegment[] = { + 0xFF, JPEG_DHT, 0x00, + 0x1F, // Segment length:31 (2-byte). + }; + static const uint8_t kAcSegment[] = { + 0xFF, JPEG_DHT, 0x00, + 0xB5, // Segment length:181 (2-byte). + }; + + // i = 0 for Luminance + // i = 1 for Chrominance + const int kNumHuffmanTables = 2; + for (size_t i = 0; i < kNumHuffmanTables; ++i) { + // DC Table. + for (size_t j = 0; j < sizeof(kDcSegment); ++j) { + jpeg_markers_.push_back(kDcSegment[j]); + } + + // Type (4-bit high) = 0:DC, Index (4-bit low). + jpeg_markers_.push_back(static_cast<uint8_t>(i)); + + const JpegHuffmanTable& dcTable = kDefaultDcTable[i]; + for (size_t j = 0; j < kNumDcRunSizeBits; ++j) + jpeg_markers_.push_back(dcTable.code_length[j]); + for (size_t j = 0; j < kNumDcCodeWordsHuffVal; ++j) + jpeg_markers_.push_back(dcTable.code_value[j]); + + // AC Table. + for (size_t j = 0; j < sizeof(kAcSegment); ++j) { + jpeg_markers_.push_back(kAcSegment[j]); + } + + // Type (4-bit high) = 1:AC, Index (4-bit low). + jpeg_markers_.push_back(0x10 | static_cast<uint8_t>(i)); + + const JpegHuffmanTable& acTable = kDefaultAcTable[i]; + for (size_t j = 0; j < kNumAcRunSizeBits; ++j) + jpeg_markers_.push_back(acTable.code_length[j]); + for (size_t j = 0; j < kNumAcCodeWordsHuffVal; ++j) + jpeg_markers_.push_back(acTable.code_value[j]); + } + + // Start of Scan. + static const uint8_t kStartOfScan[] = { + 0xFF, JPEG_SOS, 0x00, + 0x0C, // Segment Length:12 (2-byte). + 0x03 // Number of components in scan. + }; + for (size_t i = 0; i < sizeof(kStartOfScan); ++i) { + jpeg_markers_.push_back(kStartOfScan[i]); + } + + // i = 0 for Y Plane + // i = 1 for U Plane + // i = 2 for V Plane + for (uint8_t i = 0; i < kNumOfComponents; ++i) { + uint8_t dc_table_number = 1; + uint8_t ac_table_number = 1; + if (!i) { + dc_table_number = 0; + ac_table_number = 0; + } + + jpeg_markers_.push_back(i + 1); + // DC Table Selector (4-bit high), AC Table Selector (4-bit low). + jpeg_markers_.push_back((dc_table_number << 4) | ac_table_number); + } + jpeg_markers_.push_back(0x00); // 0 for Baseline. + jpeg_markers_.push_back(0x3F); // 63 for Baseline. + jpeg_markers_.push_back(0x00); // 0 for Baseline. +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::SetUpJpegParameters( + int quality, + gfx::Size coded_size) { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + + memset(&ctrls, 0, sizeof(ctrls)); + memset(&ctrl, 0, sizeof(ctrl)); + + ctrls.ctrl_class = V4L2_CTRL_CLASS_JPEG; + ctrls.controls = &ctrl; + ctrls.count = 1; + + switch (output_buffer_pixelformat_) { + case V4L2_PIX_FMT_JPEG_RAW: + FillQuantizationTable(quality, kDefaultQuantTable[0].value, + quantization_table_[0].value); + FillQuantizationTable(quality, kDefaultQuantTable[1].value, + quantization_table_[1].value); + + ctrl.id = V4L2_CID_JPEG_LUMA_QUANTIZATION; + ctrl.size = kDctSize; + ctrl.ptr = quantization_table_[0].value; + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_EXT_CTRLS, &ctrls); + + ctrl.id = V4L2_CID_JPEG_CHROMA_QUANTIZATION; + ctrl.size = kDctSize; + ctrl.ptr = quantization_table_[1].value; + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_EXT_CTRLS, &ctrls); + + // We need to prepare our own JPEG Markers. + PrepareJpegMarkers(coded_size); + break; + + default: + NOTREACHED(); + } + + return true; +} + +size_t +V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::InputBufferQueuedCount() { + return kBufferCount - free_input_buffers_.size(); +} + +size_t +V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::OutputBufferQueuedCount() { + return kBufferCount - free_output_buffers_.size(); +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::CreateBuffers( + gfx::Size coded_size, + const VideoFrameLayout& input_layout, + size_t output_buffer_size) { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + + // The order of set output/input formats matters. + // rk3399 reset input format when we set output format. + if (!SetOutputBufferFormat(coded_size, output_buffer_size)) { + return false; + } + + if (!SetInputBufferFormat(coded_size, input_layout)) { + return false; + } + + if (!RequestInputBuffers()) { + return false; + } + + if (!RequestOutputBuffers()) { + return false; + } + + return true; +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::SetInputBufferFormat( + gfx::Size coded_size, + const VideoFrameLayout& input_layout) { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + DCHECK(!input_streamon_); + DCHECK(input_job_queue_.empty()); + + constexpr uint32_t input_pix_fmt_candidates[] = {V4L2_PIX_FMT_NV12M, + V4L2_PIX_FMT_NV12}; + + struct v4l2_format format; + input_buffer_pixelformat_ = 0; + for (const auto input_pix_fmt : input_pix_fmt_candidates) { + DCHECK_EQ(V4L2Device::V4L2PixFmtToVideoPixelFormat(input_pix_fmt), + PIXEL_FORMAT_NV12); + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + format.fmt.pix_mp.num_planes = kMaxNV12Plane; + format.fmt.pix_mp.pixelformat = input_pix_fmt; + format.fmt.pix_mp.field = V4L2_FIELD_ANY; + format.fmt.pix_mp.width = coded_size.width(); + format.fmt.pix_mp.height = coded_size.height(); + + auto num_planes = input_layout.num_planes(); + for (size_t i = 0; i < num_planes; i++) { + format.fmt.pix_mp.plane_fmt[i].sizeimage = input_layout.buffer_sizes()[i]; + format.fmt.pix_mp.plane_fmt[i].bytesperline = + input_layout.planes()[i].stride; + } + + if (device_->Ioctl(VIDIOC_S_FMT, &format) == 0 && + format.fmt.pix_mp.pixelformat == input_pix_fmt) { + device_input_layout_ = V4L2Device::V4L2FormatToVideoFrameLayout(format); + + // Save V4L2 returned values. + input_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; + input_buffer_num_planes_ = format.fmt.pix_mp.num_planes; + input_buffer_height_ = format.fmt.pix_mp.height; + break; + } + } + + if (input_buffer_pixelformat_ == 0) { + VLOGF(1) << "Neither NV12 nor NV12M is supported."; + return false; + } + + if (format.fmt.pix_mp.width != static_cast<uint32_t>(coded_size.width()) || + format.fmt.pix_mp.height != static_cast<uint32_t>(coded_size.height())) { + VLOGF(1) << "Width " << coded_size.width() << "->" + << format.fmt.pix_mp.width << ",Height " << coded_size.height() + << "->" << format.fmt.pix_mp.height; + return false; + } + return true; +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::SetOutputBufferFormat( + gfx::Size coded_size, + size_t buffer_size) { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + DCHECK(!output_streamon_); + DCHECK(running_job_queue_.empty()); + + struct v4l2_format format; + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + format.fmt.pix_mp.num_planes = kMaxJpegPlane; + format.fmt.pix_mp.pixelformat = output_buffer_pixelformat_; + format.fmt.pix_mp.field = V4L2_FIELD_ANY; + format.fmt.pix_mp.plane_fmt[0].sizeimage = buffer_size; + format.fmt.pix_mp.width = coded_size.width(); + format.fmt.pix_mp.height = coded_size.height(); + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); + DCHECK_EQ(format.fmt.pix_mp.pixelformat, output_buffer_pixelformat_); + + return true; +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::RequestInputBuffers() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + struct v4l2_format format; + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + format.fmt.pix_mp.pixelformat = input_buffer_pixelformat_; + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_FMT, &format); + + struct v4l2_requestbuffers reqbufs; + memset(&reqbufs, 0, sizeof(reqbufs)); + reqbufs.count = kBufferCount; + reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + reqbufs.memory = V4L2_MEMORY_DMABUF; + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); + + DCHECK(free_input_buffers_.empty()); + for (size_t i = 0; i < reqbufs.count; ++i) { + free_input_buffers_.push_back(i); + } + + return true; +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::RequestOutputBuffers() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + struct v4l2_requestbuffers reqbufs; + memset(&reqbufs, 0, sizeof(reqbufs)); + reqbufs.count = kBufferCount; + reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + reqbufs.memory = V4L2_MEMORY_DMABUF; + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); + + DCHECK(free_output_buffers_.empty()); + for (size_t i = 0; i < reqbufs.count; ++i) { + free_output_buffers_.push_back(i); + } + + return true; +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::DestroyInputBuffers() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + free_input_buffers_.clear(); + + if (input_streamon_) { + __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMOFF, &type); + input_streamon_ = false; + } + + struct v4l2_requestbuffers reqbufs; + memset(&reqbufs, 0, sizeof(reqbufs)); + reqbufs.count = 0; + reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + reqbufs.memory = V4L2_MEMORY_DMABUF; + IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); + + input_buffer_num_planes_ = 0; +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::DestroyOutputBuffers() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + free_output_buffers_.clear(); + + if (output_streamon_) { + __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMOFF, &type); + output_streamon_ = false; + } + + struct v4l2_requestbuffers reqbufs; + memset(&reqbufs, 0, sizeof(reqbufs)); + reqbufs.count = 0; + reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + reqbufs.memory = V4L2_MEMORY_DMABUF; + IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::ServiceDevice() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + + if (!running_job_queue_.empty()) { + Dequeue(); + } + + EnqueueInput(); + EnqueueOutput(); + + DVLOGF(3) << "buffer counts: INPUT[" << input_job_queue_.size() + << "] => DEVICE[" << free_input_buffers_.size() << "/" + << "->" << free_output_buffers_.size() << "]"; +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::EnqueueInput() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + while (!input_job_queue_.empty() && !free_input_buffers_.empty()) { + if (!EnqueueInputRecord()) + return; + } + + if (!input_streamon_ && InputBufferQueuedCount()) { + __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type); + input_streamon_ = true; + } +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::EnqueueOutput() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + while (running_job_queue_.size() > OutputBufferQueuedCount() && + !free_output_buffers_.empty()) { + if (!EnqueueOutputRecord()) + return; + } + + if (!output_streamon_ && OutputBufferQueuedCount()) { + __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type); + output_streamon_ = true; + } +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::EnqueueInputRecord() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + DCHECK(!input_job_queue_.empty()); + DCHECK(!free_input_buffers_.empty()); + + // Enqueue an input (VIDEO_OUTPUT) buffer for an input video frame. + std::unique_ptr<JobRecord> job_record = std::move(input_job_queue_.front()); + input_job_queue_.pop(); + const int index = free_input_buffers_.back(); + + struct v4l2_buffer qbuf; + struct v4l2_plane planes[kMaxNV12Plane]; + memset(&qbuf, 0, sizeof(qbuf)); + memset(planes, 0, sizeof(planes)); + qbuf.index = index; + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_DMABUF; + qbuf.length = base::size(planes); + qbuf.m.planes = planes; + + const auto& frame = job_record->input_frame; + for (size_t i = 0; i < input_buffer_num_planes_; i++) { + if (device_input_layout_->num_buffers() == 1) { + qbuf.m.planes[i].bytesused = VideoFrame::AllocationSize( + frame->format(), device_input_layout_->coded_size()); + } else { + DCHECK_EQ(device_input_layout_->num_buffers(), + VideoFrame::NumPlanes(device_input_layout_->format())); + qbuf.m.planes[i].bytesused = base::checked_cast<__u32>( + VideoFrame::PlaneSize(frame->format(), i, + device_input_layout_->coded_size()) + .GetArea()); + } + + const auto& fds = frame->DmabufFds(); + const auto& planes = frame->layout().planes(); + DCHECK_EQ(device_input_layout_->num_buffers(), planes.size()); + qbuf.m.planes[i].m.fd = (i < fds.size()) ? fds[i].get() : fds.back().get(); + qbuf.m.planes[i].data_offset = planes[i].offset; + qbuf.m.planes[i].bytesused += qbuf.m.planes[i].data_offset; + qbuf.m.planes[i].length = + device_input_layout_->buffer_sizes()[i] + qbuf.m.planes[i].data_offset; + } + + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); + running_job_queue_.push(std::move(job_record)); + free_input_buffers_.pop_back(); + return true; +} + +bool V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::EnqueueOutputRecord() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + DCHECK(!free_output_buffers_.empty()); + + // Enqueue an output (VIDEO_CAPTURE) buffer. + const int index = free_output_buffers_.back(); + struct v4l2_buffer qbuf; + struct v4l2_plane planes[kMaxJpegPlane]; + memset(&qbuf, 0, sizeof(qbuf)); + memset(planes, 0, sizeof(planes)); + qbuf.index = index; + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_DMABUF; + qbuf.length = base::size(planes); + qbuf.m.planes = planes; + + auto& job_record = running_job_queue_.back(); + for (size_t i = 0; i < qbuf.length; i++) { + planes[i].m.fd = job_record->output_frame->DmabufFds()[i].get(); + } + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); + free_output_buffers_.pop_back(); + return true; +} + +size_t V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::FinalizeJpegImage( + scoped_refptr<VideoFrame> output_frame, + size_t buffer_size, + std::unique_ptr<UnalignedSharedMemory> exif_shm) { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + size_t idx = 0; + + auto output_gmb_handle = CreateGpuMemoryBufferHandle(output_frame.get()); + if (output_gmb_handle.is_null()) { + VLOGF(1) << "Failed to create GpuMemoryBufferHandle"; + return 0; + } + auto output_gmb_buffer = + gpu_memory_buffer_support_->CreateGpuMemoryBufferImplFromHandle( + std::move(output_gmb_handle), output_frame->coded_size(), + gfx::BufferFormat::R_8, gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, + base::DoNothing()); + + bool isMapped = output_gmb_buffer->Map(); + if (!isMapped) { + VLOGF(1) << "Failed to map gmb buffer"; + return 0; + } + uint8_t* dst_ptr = static_cast<uint8_t*>(output_gmb_buffer->memory(0)); + + // Fill SOI and EXIF markers. + static const uint8_t kJpegStart[] = {0xFF, JPEG_SOI}; + + if (exif_shm) { + uint8_t* exif_buffer = static_cast<uint8_t*>(exif_shm->memory()); + size_t exif_buffer_size = exif_shm->size(); + // Application Segment for Exif data. + uint16_t exif_segment_size = static_cast<uint16_t>(exif_buffer_size + 2); + const uint8_t kAppSegment[] = { + 0xFF, JPEG_APP1, static_cast<uint8_t>(exif_segment_size / 256), + static_cast<uint8_t>(exif_segment_size % 256)}; + + // Move compressed data first. + size_t compressed_data_offset = sizeof(kJpegStart) + sizeof(kAppSegment) + + exif_buffer_size + jpeg_markers_.size(); + memmove(dst_ptr + compressed_data_offset, dst_ptr, buffer_size); + + memcpy(dst_ptr, kJpegStart, sizeof(kJpegStart)); + idx += sizeof(kJpegStart); + memcpy(dst_ptr + idx, kAppSegment, sizeof(kAppSegment)); + idx += sizeof(kAppSegment); + memcpy(dst_ptr + idx, exif_buffer, exif_buffer_size); + idx += exif_buffer_size; + } else { + // Application Segment - JFIF standard 1.01. + static const uint8_t kAppSegment[] = { + 0xFF, JPEG_APP0, 0x00, + 0x10, // Segment length:16 (2-byte). + 0x4A, // J + 0x46, // F + 0x49, // I + 0x46, // F + 0x00, // 0 + 0x01, // Major version. + 0x01, // Minor version. + 0x01, // Density units 0:no units, 1:pixels per inch, + // 2: pixels per cm. + 0x00, + 0x48, // X density (2-byte). + 0x00, + 0x48, // Y density (2-byte). + 0x00, // Thumbnail width. + 0x00 // Thumbnail height. + }; + + // Move compressed data first. + size_t compressed_data_offset = + sizeof(kJpegStart) + sizeof(kAppSegment) + jpeg_markers_.size(); + memmove(dst_ptr + compressed_data_offset, dst_ptr, buffer_size); + + memcpy(dst_ptr, kJpegStart, sizeof(kJpegStart)); + idx += sizeof(kJpegStart); + + memcpy(dst_ptr + idx, kAppSegment, sizeof(kAppSegment)); + idx += sizeof(kAppSegment); + } + + switch (output_buffer_pixelformat_) { + case V4L2_PIX_FMT_JPEG_RAW: + // Fill the other jpeg markers for RAW JPEG. + memcpy(dst_ptr + idx, jpeg_markers_.data(), jpeg_markers_.size()); + idx += jpeg_markers_.size(); + // We already moved the compressed data. + idx += buffer_size; + // Fill EOI. Before Fill EOI we checked if the V4L2 device filled EOI + // first. + if (dst_ptr[idx - 2] != 0xFF && dst_ptr[idx - 1] != JPEG_EOI) { + dst_ptr[idx] = 0xFF; + dst_ptr[idx + 1] = JPEG_EOI; + idx += 2; + } + break; + + default: + NOTREACHED() << "Unsupported output pixel format"; + } + + output_gmb_buffer->Unmap(); + + return idx; +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::Dequeue() { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + // Dequeue completed input (VIDEO_OUTPUT) buffers, + // and recycle to the free list. + struct v4l2_buffer dqbuf; + struct v4l2_plane planes[kMaxNV12Plane]; + while (InputBufferQueuedCount() > 0) { + DCHECK(input_streamon_); + memset(&dqbuf, 0, sizeof(dqbuf)); + memset(planes, 0, sizeof(planes)); + dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + dqbuf.memory = V4L2_MEMORY_DMABUF; + dqbuf.length = base::size(planes); + dqbuf.m.planes = planes; + if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { + if (errno == EAGAIN) { + // EAGAIN if we're just out of buffers to dequeue. + break; + } + VPLOGF(1) << "ioctl() failed: input buffer VIDIOC_DQBUF failed."; + NotifyError(kInvalidBitstreamBufferId, PLATFORM_FAILURE); + return; + } + free_input_buffers_.push_back(dqbuf.index); + + if (dqbuf.flags & V4L2_BUF_FLAG_ERROR) { + VLOGF(1) << "Error in dequeued input buffer."; + NotifyError(kInvalidBitstreamBufferId, PARSE_IMAGE_FAILED); + running_job_queue_.pop(); + } + } + + // Dequeue completed output (VIDEO_CAPTURE) buffers, recycle to the free list. + // Return the finished buffer to the client via the job ready callback. + // If dequeued input buffer has an error, the error frame has removed from + // |running_job_queue_|. We only have to dequeue output buffer when we + // actually have pending frames in |running_job_queue_| and also enqueued + // output buffers. + while (!running_job_queue_.empty() && OutputBufferQueuedCount() > 0) { + DCHECK(output_streamon_); + memset(&dqbuf, 0, sizeof(dqbuf)); + memset(planes, 0, sizeof(planes)); + dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dqbuf.memory = V4L2_MEMORY_DMABUF; + dqbuf.length = base::size(planes); + dqbuf.m.planes = planes; + if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { + if (errno == EAGAIN) { + // EAGAIN if we're just out of buffers to dequeue. + break; + } + VPLOGF(1) << "ioctl() failed: output buffer VIDIOC_DQBUF failed."; + NotifyError(kInvalidBitstreamBufferId, PLATFORM_FAILURE); + return; + } + free_output_buffers_.push_back(dqbuf.index); + + // Jobs are always processed in FIFO order. + std::unique_ptr<JobRecord> job_record = + std::move(running_job_queue_.front()); + running_job_queue_.pop(); + + if (dqbuf.flags & V4L2_BUF_FLAG_ERROR) { + VLOGF(1) << "Error in dequeued output buffer."; + NotifyError(kInvalidBitstreamBufferId, PARSE_IMAGE_FAILED); + return; + } + + size_t jpeg_size = + FinalizeJpegImage(job_record->output_frame, planes[0].bytesused, + std::move(job_record->exif_shm)); + + if (!jpeg_size) { + NotifyError(job_record->task_id, PLATFORM_FAILURE); + return; + } + DVLOGF(4) << "Encoding finished, returning bitstream buffer, id=" + << job_record->task_id; + + parent_->VideoFrameReady(job_record->task_id, jpeg_size); + } +} + +void V4L2JpegEncodeAccelerator::EncodedInstanceDmaBuf::NotifyError( + int32_t task_id, + Status status) { + DCHECK(parent_->encoder_task_runner_->BelongsToCurrentThread()); + parent_->NotifyError(task_id, status); } V4L2JpegEncodeAccelerator::V4L2JpegEncodeAccelerator( @@ -938,31 +1721,36 @@ encoded_instances_.front()->DestroyTask(); encoded_instances_.pop(); } + + while (!encoded_instances_dma_buf_.empty()) { + encoded_instances_dma_buf_.front()->DestroyTask(); + encoded_instances_dma_buf_.pop(); + } } -void V4L2JpegEncodeAccelerator::VideoFrameReady(int32_t buffer_id, +void V4L2JpegEncodeAccelerator::VideoFrameReady(int32_t task_id, size_t encoded_picture_size) { if (!child_task_runner_->BelongsToCurrentThread()) { child_task_runner_->PostTask( FROM_HERE, base::BindOnce(&V4L2JpegEncodeAccelerator::VideoFrameReady, - weak_ptr_, buffer_id, encoded_picture_size)); + weak_ptr_, task_id, encoded_picture_size)); return; } - VLOGF(1) << "Encoding finished buffer id=" << buffer_id + VLOGF(1) << "Encoding finished task id=" << task_id << " Compressed size:" << encoded_picture_size; - client_->VideoFrameReady(buffer_id, encoded_picture_size); + client_->VideoFrameReady(task_id, encoded_picture_size); } -void V4L2JpegEncodeAccelerator::NotifyError(int32_t buffer_id, Status status) { +void V4L2JpegEncodeAccelerator::NotifyError(int32_t task_id, Status status) { if (!child_task_runner_->BelongsToCurrentThread()) { child_task_runner_->PostTask( FROM_HERE, base::BindOnce(&V4L2JpegEncodeAccelerator::NotifyError, - weak_ptr_, buffer_id, status)); + weak_ptr_, task_id, status)); return; } - VLOGF(1) << "Notifying of error " << status << " for buffer id " << buffer_id; - client_->NotifyError(buffer_id, status); + VLOGF(1) << "Notifying of error " << status << " for task id " << task_id; + client_->NotifyError(task_id, status); } chromeos_camera::JpegEncodeAccelerator::Status @@ -970,7 +1758,8 @@ chromeos_camera::JpegEncodeAccelerator::Client* client) { DCHECK(child_task_runner_->BelongsToCurrentThread()); - std::unique_ptr<EncodedInstance> encoded_device(new EncodedInstance(this)); + std::unique_ptr<EncodedInstanceDmaBuf> encoded_device( + new EncodedInstanceDmaBuf(this)); // We just check if we can initialize device here. if (!encoded_device->Initialize()) { @@ -1003,7 +1792,7 @@ BitstreamBuffer output_buffer) { DCHECK(io_task_runner_->BelongsToCurrentThread()); - DVLOGF(4) << "buffer_id=" << output_buffer.id() + DVLOGF(4) << "task_id=" << output_buffer.id() << ", size=" << output_buffer.size(); if (quality <= 0 || quality > 100) { @@ -1031,7 +1820,7 @@ encoder_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&V4L2JpegEncodeAccelerator::EncodeTask, + base::BindOnce(&V4L2JpegEncodeAccelerator::EncodeTaskLegacy, base::Unretained(this), base::Passed(&job_record))); } @@ -1041,57 +1830,85 @@ int quality, int32_t task_id, BitstreamBuffer* exif_buffer) { - NOTIMPLEMENTED(); + DCHECK(io_task_runner_->BelongsToCurrentThread()); + + if (quality <= 0 || quality > 100) { + VLOGF(1) << "quality is not in range. " << quality; + NotifyError(task_id, INVALID_ARGUMENT); + return; + } + + if (input_frame->format() != VideoPixelFormat::PIXEL_FORMAT_NV12) { + VLOGF(1) << "Format is not NV12"; + NotifyError(task_id, INVALID_ARGUMENT); + return; + } + + if (exif_buffer) { + VLOGF(4) << "EXIF size " << exif_buffer->size(); + if (exif_buffer->size() > kMaxMarkerSizeAllowed) { + NotifyError(task_id, INVALID_ARGUMENT); + return; + } + } + + std::unique_ptr<JobRecord> job_record( + new JobRecord(input_frame, output_frame, quality, task_id, exif_buffer)); + + encoder_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&V4L2JpegEncodeAccelerator::EncodeTask, + base::Unretained(this), base::Passed(&job_record))); } -void V4L2JpegEncodeAccelerator::EncodeTask( +void V4L2JpegEncodeAccelerator::EncodeTaskLegacy( std::unique_ptr<JobRecord> job_record) { DCHECK(encoder_task_runner_->BelongsToCurrentThread()); if (!job_record->output_shm.MapAt(job_record->output_offset, job_record->output_shm.size())) { VPLOGF(1) << "could not map I420 bitstream_buffer"; - NotifyError(job_record->buffer_id_, PLATFORM_FAILURE); + NotifyError(job_record->task_id, PLATFORM_FAILURE); return; } if (job_record->exif_shm && !job_record->exif_shm->MapAt(job_record->exif_offset, job_record->exif_shm->size())) { VPLOGF(1) << "could not map exif bitstream_buffer"; - NotifyError(job_record->buffer_id_, PLATFORM_FAILURE); + NotifyError(job_record->task_id, PLATFORM_FAILURE); return; } // Check if the parameters of input frame changes. // If it changes, we open a new device and put the job in it. // If it doesn't change, we use the same device as last used. - gfx::Size coded_size = job_record->input_frame_->coded_size(); - if (latest_input_buffer_coded_size_ != coded_size || - latest_quality_ != job_record->quality) { + gfx::Size coded_size = job_record->input_frame->coded_size(); + if (latest_input_buffer_coded_size_legacy_ != coded_size || + latest_quality_legacy_ != job_record->quality) { std::unique_ptr<EncodedInstance> encoded_device(new EncodedInstance(this)); VLOGF(1) << "Open Device for quality " << job_record->quality << ", width: " << coded_size.width() << ", height: " << coded_size.height(); if (!encoded_device->Initialize()) { VLOGF(1) << "Failed to initialize device"; - NotifyError(job_record->buffer_id_, PLATFORM_FAILURE); + NotifyError(job_record->task_id, PLATFORM_FAILURE); return; } if (!encoded_device->SetUpJpegParameters(job_record->quality, coded_size)) { VLOGF(1) << "SetUpJpegParameters failed"; - NotifyError(job_record->buffer_id_, PLATFORM_FAILURE); + NotifyError(job_record->task_id, PLATFORM_FAILURE); return; } if (!encoded_device->CreateBuffers(coded_size, job_record->output_shm.size())) { VLOGF(1) << "Create buffers failed."; - NotifyError(job_record->buffer_id_, PLATFORM_FAILURE); + NotifyError(job_record->task_id, PLATFORM_FAILURE); return; } - latest_input_buffer_coded_size_ = coded_size; - latest_quality_ = job_record->quality; + latest_input_buffer_coded_size_legacy_ = coded_size; + latest_quality_legacy_ = job_record->quality; encoded_instances_.push(std::move(encoded_device)); } @@ -1099,10 +1916,65 @@ // Always use latest opened device for new job. encoded_instances_.back()->input_job_queue_.push(std::move(job_record)); + ServiceDeviceTaskLegacy(); +} + +void V4L2JpegEncodeAccelerator::EncodeTask( + std::unique_ptr<JobRecord> job_record) { + DCHECK(encoder_task_runner_->BelongsToCurrentThread()); + if (job_record->exif_shm && + !job_record->exif_shm->MapAt(job_record->exif_offset, + job_record->exif_shm->size())) { + VPLOGF(1) << "could not map exif bitstream_buffer"; + NotifyError(job_record->task_id, PLATFORM_FAILURE); + return; + } + + // Check if the parameters of input frame changes. + // If it changes, we open a new device and put the job in it. + // If it doesn't change, we use the same device as last used. + gfx::Size coded_size = job_record->input_frame->coded_size(); + if (latest_input_buffer_coded_size_ != coded_size || + latest_quality_ != job_record->quality) { + std::unique_ptr<EncodedInstanceDmaBuf> encoded_device( + new EncodedInstanceDmaBuf(this)); + VLOGF(1) << "Open Device for quality " << job_record->quality + << ", width: " << coded_size.width() + << ", height: " << coded_size.height(); + if (!encoded_device->Initialize()) { + VLOGF(1) << "Failed to initialize device"; + NotifyError(job_record->task_id, PLATFORM_FAILURE); + return; + } + + if (!encoded_device->SetUpJpegParameters(job_record->quality, coded_size)) { + VLOGF(1) << "SetUpJpegParameters failed"; + NotifyError(job_record->task_id, PLATFORM_FAILURE); + return; + } + + if (!encoded_device->CreateBuffers( + coded_size, job_record->input_frame->layout(), + job_record->output_frame->coded_size().GetArea())) { + VLOGF(1) << "Create buffers failed."; + NotifyError(job_record->task_id, PLATFORM_FAILURE); + return; + } + + latest_input_buffer_coded_size_ = coded_size; + latest_quality_ = job_record->quality; + + encoded_instances_dma_buf_.push(std::move(encoded_device)); + } + + // Always use latest opened device for new job. + encoded_instances_dma_buf_.back()->input_job_queue_.push( + std::move(job_record)); + ServiceDeviceTask(); } -void V4L2JpegEncodeAccelerator::ServiceDeviceTask() { +void V4L2JpegEncodeAccelerator::ServiceDeviceTaskLegacy() { DCHECK(encoder_task_runner_->BelongsToCurrentThread()); // Always service the first device to keep the input order. @@ -1120,6 +1992,30 @@ if (!encoded_instances_.front()->running_job_queue_.empty() || !encoded_instances_.front()->input_job_queue_.empty()) { encoder_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&V4L2JpegEncodeAccelerator::ServiceDeviceTaskLegacy, + base::Unretained(this))); + } +} + +void V4L2JpegEncodeAccelerator::ServiceDeviceTask() { + DCHECK(encoder_task_runner_->BelongsToCurrentThread()); + + // Always service the first device to keep the input order. + encoded_instances_dma_buf_.front()->ServiceDevice(); + + // If we have more than 1 devices, we can remove the oldest one after all jobs + // finished. + if (encoded_instances_dma_buf_.size() > 1) { + if (encoded_instances_dma_buf_.front()->running_job_queue_.empty() && + encoded_instances_dma_buf_.front()->input_job_queue_.empty()) { + encoded_instances_dma_buf_.pop(); + } + } + + if (!encoded_instances_dma_buf_.front()->running_job_queue_.empty() || + !encoded_instances_dma_buf_.front()->input_job_queue_.empty()) { + encoder_task_runner_->PostTask( FROM_HERE, base::BindOnce(&V4L2JpegEncodeAccelerator::ServiceDeviceTask, base::Unretained(this))); }
diff --git a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h index 9ccc340..8fe97d7f 100644 --- a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h +++ b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h
@@ -18,17 +18,21 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" #include "components/chromeos_camera/jpeg_encode_accelerator.h" +#include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "media/base/bitstream_buffer.h" #include "media/base/unaligned_shared_memory.h" #include "media/base/video_frame.h" #include "media/gpu/media_gpu_export.h" #include "media/gpu/v4l2/v4l2_device.h" +#include "media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h" #include "media/parsers/jpeg_parser.h" namespace { // Input pixel format V4L2_PIX_FMT_YUV420M has 3 physical planes. constexpr size_t kMaxI420Plane = 3; +constexpr size_t kMaxNV12Plane = 2; + // Output pixel format V4L2_PIX_FMT_JPEG(_RAW) has only one physical plane. constexpr size_t kMaxJpegPlane = 1; @@ -98,19 +102,27 @@ // to submit input to the device). struct JobRecord { JobRecord(scoped_refptr<VideoFrame> input_frame, + scoped_refptr<VideoFrame> output_frame, + int32_t task_id, + int quality, + BitstreamBuffer* exif_buffer); + JobRecord(scoped_refptr<VideoFrame> input_frame, int quality, BitstreamBuffer* exif_buffer, BitstreamBuffer output_buffer); ~JobRecord(); // Input frame buffer. - scoped_refptr<VideoFrame> input_frame_; + scoped_refptr<VideoFrame> input_frame; + + // Output frame buffer. + scoped_refptr<VideoFrame> output_frame; // JPEG encode quality. int quality; - // Output image buffer ID. - int32_t buffer_id_; + // Encode task ID. + int32_t task_id; // Memory mapped from |output_buffer|. UnalignedSharedMemory output_shm; // Offset used for |output_shm|. @@ -124,6 +136,8 @@ off_t exif_offset; }; + // TODO(wtlee): To be deprecated. (crbug.com/944705) + // // Encode Instance. One EncodedInstance is used for a specific set of jpeg // parameters. The stored parameters are jpeg quality and resolutions of input // image. @@ -181,7 +195,7 @@ size_t InputBufferQueuedCount(); size_t OutputBufferQueuedCount(); - void NotifyError(int32_t buffer_id, Status status); + void NotifyError(int32_t task_id, Status status); // Fill the quantization table into |dst_table|. The value is scaled by // the |quality| and |basic_table|. @@ -240,14 +254,134 @@ std::vector<uint8_t> jpeg_markers_; }; - void VideoFrameReady(int32_t buffer_id, size_t encoded_picture_size); - void NotifyError(int32_t buffer_id, Status status); + // Encode Instance. One EncodedInstance is used for a specific set of jpeg + // parameters. The stored parameters are jpeg quality and resolutions of input + // image. + // We execute all EncodedInstance methods on |encoder_task_runner_| except + // Initialize(). + class EncodedInstanceDmaBuf { + public: + EncodedInstanceDmaBuf(V4L2JpegEncodeAccelerator* parent); + ~EncodedInstanceDmaBuf(); + + bool Initialize(); + + // Create V4L2 buffers for input and output. + bool CreateBuffers(gfx::Size input_coded_size, + const VideoFrameLayout& input_layout, + size_t output_buffer_size); + + // Set up JPEG related parameters in V4L2 device. + bool SetUpJpegParameters(int quality, gfx::Size coded_size); + + // Dequeue last frame and enqueue next frame. + void ServiceDevice(); + + // Destroy input and output buffers. + void DestroyTask(); + + base::queue<std::unique_ptr<JobRecord>> input_job_queue_; + base::queue<std::unique_ptr<JobRecord>> running_job_queue_; + + private: + // Prepare full JPEG markers except SOI and EXIF/APP0 markers in + // |jpeg_markers_|. + void PrepareJpegMarkers(gfx::Size coded_size); + + // Combined the encoded data from |output_frame| with the JFIF/EXIF data. + // Add JPEG Marks if needed. Add EXIF section by |exif_shm|. + size_t FinalizeJpegImage(scoped_refptr<VideoFrame> output_frame, + size_t buffer_size, + std::unique_ptr<UnalignedSharedMemory> exif_shm); + + bool SetInputBufferFormat(gfx::Size coded_size, + const VideoFrameLayout& input_layout); + bool SetOutputBufferFormat(gfx::Size coded_size, size_t buffer_size); + bool RequestInputBuffers(); + bool RequestOutputBuffers(); + + void EnqueueInput(); + void EnqueueOutput(); + void Dequeue(); + bool EnqueueInputRecord(); + bool EnqueueOutputRecord(); + + void DestroyInputBuffers(); + void DestroyOutputBuffers(); + + // Return the number of input/output buffers enqueued to the device. + size_t InputBufferQueuedCount(); + size_t OutputBufferQueuedCount(); + + void NotifyError(int32_t task_id, Status status); + + // Fill the quantization table into |dst_table|. The value is scaled by + // the |quality| and |basic_table|. + // We use the the Independent JPEG Group's formula to scale scale table. + // http://www.ijg.org/ + static void FillQuantizationTable(int quality, + const uint8_t* basic_table, + uint8_t* dst_table); + + // The number of input buffers and output buffers. + const size_t kBufferCount = 2; + + // Pointer back to the parent. + V4L2JpegEncodeAccelerator* parent_; + + // Layout that represents the input data. + base::Optional<VideoFrameLayout> device_input_layout_; + + // The V4L2Device this class is operating upon. + scoped_refptr<V4L2Device> device_; + + std::unique_ptr<gpu::GpuMemoryBufferSupport> gpu_memory_buffer_support_; + + // Input queue state. + bool input_streamon_; + // Indices of input buffers ready to use; LIFO since we don't care about + // ordering. + std::vector<int> free_input_buffers_; + + // Output queue state. + bool output_streamon_; + // Indices of output buffers ready to use; LIFO since we don't care about + // ordering. + std::vector<int> free_output_buffers_; + + // Pixel format of input buffer. + uint32_t input_buffer_pixelformat_; + + // Number of physical planes the input buffers have. + size_t input_buffer_num_planes_; + + // Pixel format of output buffer. + uint32_t output_buffer_pixelformat_; + + // Height of input buffer returned by driver. + uint32_t input_buffer_height_; + + // JPEG Quantization table for V4L2_PIX_FMT_JPEG_RAW. + JpegQuantizationTable quantization_table_[2]; + + // JPEG markers for V4L2_PIX_FMT_JPEG_RAW. + // We prepare markers in the EncodedInstance setup stage, and reuse it for + // every encoding. + std::vector<uint8_t> jpeg_markers_; + }; + + void VideoFrameReady(int32_t task_id, size_t encoded_picture_size); + void NotifyError(int32_t task_id, Status status); // Run on |encoder_thread_| to enqueue the incoming frame. void EncodeTask(std::unique_ptr<JobRecord> job_record); + // TODO(wtlee): To be deprecated. (crbug.com/944705) + void EncodeTaskLegacy(std::unique_ptr<JobRecord> job_record); // Run on |encoder_thread_| to trigger ServiceDevice of EncodedInstance class. void ServiceDeviceTask(); + // TODO(wtlee): To be deprecated. (crbug.com/944705) + void ServiceDeviceTaskLegacy(); // Run on |encoder_thread_| to destroy input and output buffers. void DestroyTask(); @@ -257,8 +391,13 @@ // Latest coded size of input buffer. gfx::Size latest_input_buffer_coded_size_; + // TODO(wtlee): To be deprecated. (crbug.com/944705) + gfx::Size latest_input_buffer_coded_size_legacy_; + // Latest encode quality. int latest_quality_; + // TODO(wtlee): To be deprecated. (crbug.com/944705) + int latest_quality_legacy_; // ChildThread's task runner. scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; @@ -280,6 +419,7 @@ // JEA may open multiple devices for different input parameters. // We handle the |encoded_instances_| by order for keeping user's input order. std::queue<std::unique_ptr<EncodedInstance>> encoded_instances_; + std::queue<std::unique_ptr<EncodedInstanceDmaBuf>> encoded_instances_dma_buf_; // Point to |this| for use in posting tasks from the encoder thread back to // the ChildThread.
diff --git a/media/gpu/v4l2/v4l2_slice_video_decoder.cc b/media/gpu/v4l2/v4l2_slice_video_decoder.cc index 54fc3e6..be9b71d 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decoder.cc
@@ -13,7 +13,7 @@ #include "base/task/post_task.h" #include "media/base/scopedfd_helper.h" #include "media/gpu/accelerated_video_decoder.h" -#include "media/gpu/linux/dmabuf_video_frame_pool.h" +#include "media/gpu/chromeos/dmabuf_video_frame_pool.h" #include "media/gpu/macros.h" #include "media/gpu/v4l2/v4l2_h264_accelerator.h" #include "media/gpu/v4l2/v4l2_vp8_accelerator.h"
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn index b7c8784..0fad908 100644 --- a/media/gpu/vaapi/BUILD.gn +++ b/media/gpu/vaapi/BUILD.gn
@@ -57,6 +57,8 @@ "vaapi_utils.h", "vaapi_video_decode_accelerator.cc", "vaapi_video_decode_accelerator.h", + "vaapi_video_decoder.cc", + "vaapi_video_decoder.h", "vaapi_video_encode_accelerator.cc", "vaapi_video_encode_accelerator.h", "vaapi_vp8_accelerator.cc", @@ -81,7 +83,7 @@ "//media", "//media/gpu:common", "//media/gpu:video_frame_mapper_common", - "//media/gpu/linux", + "//media/gpu/chromeos:common", "//media/parsers", "//mojo/public/cpp/bindings", "//third_party/libyuv", @@ -105,7 +107,6 @@ if (is_linux) { configs += [ "//build/config/linux/libva" ] - deps += [ "//media/gpu/linux:common" ] } if (use_x11) {
diff --git a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc index 2235b37..183ce457b 100644 --- a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc +++ b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc
@@ -15,9 +15,9 @@ #include "media/gpu/vaapi/vaapi_wrapper.h" #include "media/video/picture.h" -#if defined(OS_LINUX) -#include "media/gpu/linux/platform_video_frame_utils.h" -#endif +#if defined(OS_CHROMEOS) +#include "media/gpu/chromeos/platform_video_frame_utils.h" +#endif // defined(OS_CHROMEOS) namespace media { @@ -137,16 +137,21 @@ } gfx::GpuMemoryBufferHandle gmb_handle; -#if defined(OS_LINUX) +#if defined(OS_CHROMEOS) gmb_handle = CreateGpuMemoryBufferHandle(video_frame.get()); #endif if (gmb_handle.is_null()) { VLOGF(1) << "Failed to CreateGMBHandleFromVideoFrame."; return nullptr; } - if (!va_picture->ImportGpuMemoryBufferHandle( - VideoPixelFormatToGfxBufferFormat(video_frame->format()), - std::move(gmb_handle))) { + auto buffer_format = VideoPixelFormatToGfxBufferFormat(video_frame->format()); + if (!buffer_format) { + VLOGF(1) << "Unsupported format: " << video_frame->format(); + return nullptr; + } + + if (!va_picture->ImportGpuMemoryBufferHandle(*buffer_format, + std::move(gmb_handle))) { VLOGF(1) << "Failed in ImportGpuMemoryBufferHandle."; return nullptr; }
diff --git a/media/gpu/vaapi/vaapi_image_decoder.cc b/media/gpu/vaapi/vaapi_image_decoder.cc index 5bafbd6..d642f3f2 100644 --- a/media/gpu/vaapi/vaapi_image_decoder.cc +++ b/media/gpu/vaapi/vaapi_image_decoder.cc
@@ -4,38 +4,20 @@ #include "media/gpu/vaapi/vaapi_image_decoder.h" -#include <va/va.h> - -#include "base/logging.h" #include "media/gpu/vaapi/vaapi_wrapper.h" namespace media { -namespace { - -VAProfile ConvertToVAProfile(VaapiImageDecoder::Type type) { - switch (type) { - case VaapiImageDecoder::Type::kJpeg: - return VAProfileJPEGBaseline; - case VaapiImageDecoder::Type::kWebP: - return VAProfileVP8Version0_3; - default: - NOTREACHED() << "Undefined Type value"; - return VAProfileNone; - } -} - -} // namespace - -VaapiImageDecoder::VaapiImageDecoder() - : va_surface_id_(VA_INVALID_SURFACE), va_rt_format_(kInvalidVaRtFormat) {} +VaapiImageDecoder::VaapiImageDecoder(VAProfile va_profile) + : va_profile_(va_profile), + va_surface_id_(VA_INVALID_SURFACE), + va_rt_format_(kInvalidVaRtFormat) {} VaapiImageDecoder::~VaapiImageDecoder() = default; bool VaapiImageDecoder::Initialize(const base::RepeatingClosure& error_uma_cb) { - const VAProfile va_profile = ConvertToVAProfile(GetType()); vaapi_wrapper_ = - VaapiWrapper::Create(VaapiWrapper::kDecode, va_profile, error_uma_cb); + VaapiWrapper::Create(VaapiWrapper::kDecode, va_profile_, error_uma_cb); return !!vaapi_wrapper_; }
diff --git a/media/gpu/vaapi/vaapi_image_decoder.h b/media/gpu/vaapi/vaapi_image_decoder.h index 68eaf26..bc6ed92 100644 --- a/media/gpu/vaapi/vaapi_image_decoder.h +++ b/media/gpu/vaapi/vaapi_image_decoder.h
@@ -7,15 +7,14 @@ #include <stdint.h> +#include <va/va.h> + #include "base/callback_forward.h" #include "base/containers/span.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "ui/gfx/geometry/size.h" -// This data type is defined in va/va.h using typedef, reproduced here. -typedef unsigned int VASurfaceID; - namespace media { class VASurface; @@ -50,15 +49,9 @@ // more implementing classes are added (e.g. VaapiWebPDecoder). class VaapiImageDecoder { public: - // Type of image decoder. - enum class Type { - kJpeg, - kWebP, - }; - virtual ~VaapiImageDecoder(); - // Uses GetType() to initialize |vaapi_wrapper_| in kDecode mode with the + // Initializes |vaapi_wrapper_| in kDecode mode with the // appropriate VAAPI profile and |error_uma_cb| for error reporting. bool Initialize(const base::RepeatingClosure& error_uma_cb); @@ -72,14 +65,13 @@ base::span<const uint8_t> encoded_image, VaapiImageDecodeStatus* status) = 0; - // Returns the type of the current decoder. - virtual Type GetType() const = 0; - protected: - VaapiImageDecoder(); + VaapiImageDecoder(VAProfile va_profile); scoped_refptr<VaapiWrapper> vaapi_wrapper_; + // The VA profile used for the current image decoder. + const VAProfile va_profile_; // The current VA surface for decoding. VASurfaceID va_surface_id_; // The coded size associated with |va_surface_id_|.
diff --git a/media/gpu/vaapi/vaapi_jpeg_decoder.cc b/media/gpu/vaapi/vaapi_jpeg_decoder.cc index 53b26a8..34ef58e 100644 --- a/media/gpu/vaapi/vaapi_jpeg_decoder.cc +++ b/media/gpu/vaapi/vaapi_jpeg_decoder.cc
@@ -140,8 +140,8 @@ // whether a given parsed JPEG result is supported or not. static bool IsVaapiSupportedJpeg(const JpegParseResult& jpeg) { // Make sure the JPEG's chroma subsampling format is supported. - if (!VaapiWrapper::IsJpegDecodingSupportedForInternalFormat( - VaSurfaceFormatForJpeg(jpeg.frame_header))) { + if (!VaapiWrapper::IsDecodingSupportedForInternalFormat( + VAProfileJPEGBaseline, VaSurfaceFormatForJpeg(jpeg.frame_header))) { DLOG(ERROR) << "The JPEG's subsampling format is unsupported"; return false; } @@ -158,12 +158,14 @@ // Validate the coded size. gfx::Size min_jpeg_resolution; - if (!VaapiWrapper::GetJpegDecodeMinResolution(&min_jpeg_resolution)) { + if (!VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline, + &min_jpeg_resolution)) { DLOG(ERROR) << "Could not get the minimum resolution"; return false; } gfx::Size max_jpeg_resolution; - if (!VaapiWrapper::GetJpegDecodeMaxResolution(&max_jpeg_resolution)) { + if (!VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline, + &max_jpeg_resolution)) { DLOG(ERROR) << "Could not get the maximum resolution"; return false; } @@ -210,6 +212,9 @@ return kInvalidVaRtFormat; } +VaapiJpegDecoder::VaapiJpegDecoder() + : VaapiImageDecoder(VAProfileJPEGBaseline) {} + VaapiJpegDecoder::~VaapiJpegDecoder() { if (vaapi_wrapper_) { vaapi_wrapper_->DestroyContextAndSurfaces( @@ -332,10 +337,6 @@ base::DoNothing() /* release_cb */); } -VaapiImageDecoder::Type VaapiJpegDecoder::GetType() const { - return VaapiImageDecoder::Type::kJpeg; -} - std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::GetImage( uint32_t preferred_image_fourcc, VaapiImageDecodeStatus* status) {
diff --git a/media/gpu/vaapi/vaapi_jpeg_decoder.h b/media/gpu/vaapi/vaapi_jpeg_decoder.h index 270a748..b3325de 100644 --- a/media/gpu/vaapi/vaapi_jpeg_decoder.h +++ b/media/gpu/vaapi/vaapi_jpeg_decoder.h
@@ -26,13 +26,12 @@ // hardware-accelerated JPEG decodes. class VaapiJpegDecoder : public VaapiImageDecoder { public: - VaapiJpegDecoder() = default; + VaapiJpegDecoder(); ~VaapiJpegDecoder() override; // VaapiImageDecoder implementation. scoped_refptr<VASurface> Decode(base::span<const uint8_t> encoded_image, VaapiImageDecodeStatus* status) override; - Type GetType() const override; // Get the decoded data from the last Decode() call as a ScopedVAImage. The // VAImage's format will be either |preferred_image_fourcc| if the conversion
diff --git a/media/gpu/vaapi/vaapi_jpeg_decoder_unittest.cc b/media/gpu/vaapi/vaapi_jpeg_decoder_unittest.cc index 57b21568..84110a99 100644 --- a/media/gpu/vaapi/vaapi_jpeg_decoder_unittest.cc +++ b/media/gpu/vaapi/vaapi_jpeg_decoder_unittest.cc
@@ -417,7 +417,7 @@ // Skip the image if the VAAPI driver doesn't claim to support its chroma // subsampling format. However, we expect at least 4:2:0 and 4:2:2 support. const VaapiWrapper::InternalFormats supported_internal_formats = - VaapiWrapper::GetJpegDecodeSupportedInternalFormats(); + VaapiWrapper::GetDecodeSupportedInternalFormats(VAProfileJPEGBaseline); ASSERT_TRUE(supported_internal_formats.yuv420); ASSERT_TRUE(supported_internal_formats.yuv422); JpegParseResult parse_result; @@ -426,8 +426,10 @@ const unsigned int rt_format = VaSurfaceFormatForJpeg(parse_result.frame_header); ASSERT_NE(kInvalidVaRtFormat, rt_format); - if (!VaapiWrapper::IsJpegDecodingSupportedForInternalFormat(rt_format)) + if (!VaapiWrapper::IsDecodingSupportedForInternalFormat(VAProfileJPEGBaseline, + rt_format)) { GTEST_SKIP(); + } // Note that this test together with // VaapiJpegDecoderTest.MinimalImageFormatSupport gives us two guarantees: @@ -478,9 +480,11 @@ // TODO(andrescj): for now, this assumes 4:2:0. Handle other formats. TEST_F(VaapiJpegDecoderTest, DecodeSucceedsForSupportedSizes) { gfx::Size min_supported_size; - ASSERT_TRUE(VaapiWrapper::GetJpegDecodeMinResolution(&min_supported_size)); + ASSERT_TRUE(VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline, + &min_supported_size)); gfx::Size max_supported_size; - ASSERT_TRUE(VaapiWrapper::GetJpegDecodeMaxResolution(&max_supported_size)); + ASSERT_TRUE(VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline, + &max_supported_size)); // Ensure the maximum supported size is reasonable. ASSERT_GE(max_supported_size.width(), min_supported_size.width()); @@ -522,9 +526,11 @@ // TODO(andrescj): for now, this assumes 4:2:0. Handle other formats. TEST_F(VaapiJpegDecoderTest, DecodeFailsForBelowMinSize) { gfx::Size min_supported_size; - ASSERT_TRUE(VaapiWrapper::GetJpegDecodeMinResolution(&min_supported_size)); + ASSERT_TRUE(VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline, + &min_supported_size)); gfx::Size max_supported_size; - ASSERT_TRUE(VaapiWrapper::GetJpegDecodeMaxResolution(&max_supported_size)); + ASSERT_TRUE(VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline, + &max_supported_size)); // Ensure the maximum supported size is reasonable. ASSERT_GE(max_supported_size.width(), min_supported_size.width()); @@ -573,9 +579,11 @@ // TODO(andrescj): for now, this assumes 4:2:0. Handle other formats. TEST_F(VaapiJpegDecoderTest, DecodeFailsForAboveMaxSize) { gfx::Size min_supported_size; - ASSERT_TRUE(VaapiWrapper::GetJpegDecodeMinResolution(&min_supported_size)); + ASSERT_TRUE(VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline, + &min_supported_size)); gfx::Size max_supported_size; - ASSERT_TRUE(VaapiWrapper::GetJpegDecodeMaxResolution(&max_supported_size)); + ASSERT_TRUE(VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline, + &max_supported_size)); // Ensure the maximum supported size is reasonable. ASSERT_GE(max_supported_size.width(), min_supported_size.width());
diff --git a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc index 03e3dcc..4ee6e5c 100644 --- a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
@@ -21,7 +21,7 @@ #include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "media/base/bind_to_current_loop.h" #include "media/base/video_frame.h" -#include "media/gpu/linux/platform_video_frame_utils.h" +#include "media/gpu/chromeos/platform_video_frame_utils.h" #include "media/gpu/macros.h" #include "media/gpu/vaapi/vaapi_jpeg_encoder.h" #include "media/parsers/jpeg_parser.h"
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc index 1149d3c8..69859ee 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -738,10 +738,16 @@ return; } + auto buffer_format = VideoPixelFormatToGfxBufferFormat(pixel_format); + if (!buffer_format) { + VLOGF(1) << "Unsupported format: " << pixel_format; + NotifyError(INVALID_ARGUMENT); + return; + } + VaapiPicture* picture = pictures_[picture_buffer_id].get(); if (!picture->ImportGpuMemoryBufferHandle( - VideoPixelFormatToGfxBufferFormat(pixel_format), - std::move(gpu_memory_buffer_handle))) { + *buffer_format, std::move(gpu_memory_buffer_handle))) { // ImportGpuMemoryBufferHandle will close the handles even on failure, so // we don't need to do this ourselves. VLOGF(1) << "Failed to import GpuMemoryBufferHandle";
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc new file mode 100644 index 0000000..3e830d11 --- /dev/null +++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -0,0 +1,627 @@ +// 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. + +#include "media/gpu/vaapi/vaapi_video_decoder.h" + +#include <limits> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "media/base/bind_to_current_loop.h" +#include "media/base/video_frame.h" +#include "media/gpu/chromeos/dmabuf_video_frame_pool.h" +#include "media/gpu/chromeos/platform_video_frame_utils.h" +#include "media/gpu/format_utils.h" +#include "media/gpu/macros.h" +#include "media/gpu/vaapi/va_surface.h" +#include "media/gpu/vaapi/vaapi_h264_accelerator.h" +#include "media/gpu/vaapi/vaapi_picture.h" +#include "media/gpu/vaapi/vaapi_picture_factory.h" +#include "media/gpu/vaapi/vaapi_vp8_accelerator.h" +#include "media/gpu/vaapi/vaapi_vp9_accelerator.h" +#include "media/gpu/vaapi/vaapi_wrapper.h" +#include "media/gpu/video_frame_converter.h" + +namespace media { + +namespace { + +// Maximum number of parallel decode requests. +constexpr int kMaxDecodeRequests = 4; + +// Returns the preferred VA_RT_FORMAT for the given |profile|. +unsigned int GetVaFormatForVideoCodecProfile(VideoCodecProfile profile) { + switch (profile) { + case VP9PROFILE_PROFILE2: + case VP9PROFILE_PROFILE3: + return VA_RT_FORMAT_YUV420_10BPP; + default: + return VA_RT_FORMAT_YUV420; + } +} + +} // namespace + +VaapiVideoDecoder::DecodeTask::DecodeTask(scoped_refptr<DecoderBuffer> buffer, + int32_t buffer_id, + DecodeCB decode_done_cb) + : buffer_(std::move(buffer)), + buffer_id_(buffer_id), + decode_done_cb_(std::move(decode_done_cb)) {} + +VaapiVideoDecoder::DecodeTask::~DecodeTask() = default; + +VaapiVideoDecoder::DecodeTask::DecodeTask(DecodeTask&&) = default; + +// static +std::unique_ptr<VideoDecoder> VaapiVideoDecoder::Create( + scoped_refptr<base::SequencedTaskRunner> client_task_runner, + std::unique_ptr<DmabufVideoFramePool> frame_pool, + std::unique_ptr<VideoFrameConverter> frame_converter) { + return base::WrapUnique<VideoDecoder>( + new VaapiVideoDecoder(std::move(client_task_runner), + std::move(frame_pool), std::move(frame_converter))); +} + +VaapiVideoDecoder::VaapiVideoDecoder( + scoped_refptr<base::SequencedTaskRunner> client_task_runner, + std::unique_ptr<DmabufVideoFramePool> frame_pool, + std::unique_ptr<VideoFrameConverter> frame_converter) + : frame_pool_(std::move(frame_pool)), + frame_converter_(std::move(frame_converter)), + vaapi_picture_factory_(new VaapiPictureFactory()), + client_task_runner_(std::move(client_task_runner)), + decoder_thread_("VaapiDecoderThread"), + weak_this_factory_(this) { + DETACH_FROM_SEQUENCE(decoder_sequence_checker_); + VLOGF(2); + + weak_this_ = weak_this_factory_.GetWeakPtr(); +} + +VaapiVideoDecoder::~VaapiVideoDecoder() {} + +std::string VaapiVideoDecoder::GetDisplayName() const { + return "VaapiVideoDecoder"; +} + +bool VaapiVideoDecoder::IsPlatformDecoder() const { + return true; +} + +bool VaapiVideoDecoder::NeedsBitstreamConversion() const { + return needs_bitstream_conversion_; +} + +bool VaapiVideoDecoder::CanReadWithoutStalling() const { + return frame_pool_ && !frame_pool_->IsExhausted(); +} + +int VaapiVideoDecoder::GetMaxDecodeRequests() const { + return kMaxDecodeRequests; +} + +// TODO(dstaessens): Handle re-initialization. +void VaapiVideoDecoder::Initialize(const VideoDecoderConfig& config, + bool low_delay, + CdmContext* cdm_context, + InitCB init_cb, + const OutputCB& output_cb, + const WaitingCB& /*waiting_cb*/) { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + VLOGF(2) << "config: " << config.AsHumanReadableString(); + + if (cdm_context) { + VLOGF(1) << "cdm_context is not supported."; + std::move(init_cb).Run(false); + return; + } + if (!config.IsValidConfig()) { + VLOGF(1) << "config is not valid"; + std::move(init_cb).Run(false); + return; + } + if (config.is_encrypted()) { + VLOGF(1) << "Encrypted streams are not supported for this VD"; + std::move(init_cb).Run(false); + return; + } + + if (!decoder_thread_.Start()) { + std::move(init_cb).Run(false); + return; + } + + decoder_thread_task_runner_ = decoder_thread_.task_runner(); + frame_pool_->set_parent_task_runner(decoder_thread_task_runner_); + frame_converter_->set_parent_task_runner(decoder_thread_task_runner_); + + decoder_thread_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VaapiVideoDecoder::InitializeTask, weak_this_, config, + std::move(init_cb), std::move(output_cb))); +} + +void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config, + InitCB init_cb, + OutputCB output_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(state_, State::kUninitialized); + DVLOGF(3); + + // Initialize VAAPI wrapper. + VideoCodecProfile profile = config.profile(); + vaapi_wrapper_ = VaapiWrapper::CreateForVideoCodec( + VaapiWrapper::kDecode, profile, base::DoNothing()); + if (!vaapi_wrapper_.get()) { + VLOGF(1) << "Failed initializing VAAPI for profile " + << GetProfileName(profile); + client_task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(init_cb), false)); + return; + } + + // Create AcceleratedVideoDecoder for the specified profile. + if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { + decoder_.reset(new H264Decoder( + std::make_unique<VaapiH264Accelerator>(this, vaapi_wrapper_), + config.color_space_info())); + } else if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) { + decoder_.reset(new VP8Decoder( + std::make_unique<VaapiVP8Accelerator>(this, vaapi_wrapper_))); + } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) { + decoder_.reset(new VP9Decoder( + std::make_unique<VaapiVP9Accelerator>(this, vaapi_wrapper_), + config.color_space_info())); + } else { + VLOGF(1) << "Unsupported profile " << GetProfileName(profile); + client_task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(init_cb), false)); + return; + } + needs_bitstream_conversion_ = (config.codec() == kCodecH264); + + visible_rect_ = config.visible_rect(); + natural_size_ = config.natural_size(); + profile_ = profile; + + output_cb_ = std::move(output_cb); + SetState(State::kWaitingForInput); + + // Notify client initialization was successful. + client_task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(init_cb), true)); +} + +void VaapiVideoDecoder::Destroy() { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + VLOGF(2); + + decoder_thread_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VaapiVideoDecoder::DestroyTask, weak_this_)); + decoder_thread_.Stop(); + + delete this; + VLOGF(2) << "Destroying VAAPI VD done"; +} + +void VaapiVideoDecoder::DestroyTask() { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DVLOGF(2); + + // Abort all currently scheduled decode tasks. + ClearDecodeTaskQueue(DecodeStatus::ABORTED); + + if (decoder_) { + decoder_->Reset(); + decoder_ = nullptr; + } + + // Drop all video frame references. This will cause the frames to be + // destroyed once the decoder's client is done using them. + frame_pool_ = nullptr; + frame_converter_ = nullptr; + + weak_this_factory_.InvalidateWeakPtrs(); +} + +void VaapiVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, + DecodeCB decode_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + + decoder_thread_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VaapiVideoDecoder::QueueDecodeTask, weak_this_, + std::move(buffer), std::move(decode_cb))); +} + +void VaapiVideoDecoder::QueueDecodeTask(scoped_refptr<DecoderBuffer> buffer, + DecodeCB decode_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DVLOGF(4) << "Queuing input buffer, id: " << next_buffer_id_ << ", size: " + << (buffer->end_of_stream() ? 0 : buffer->data_size()); + + // If we're in the error state, immediately fail the decode task. + if (state_ == State::kError) { + RunDecodeCB(std::move(decode_cb), DecodeStatus::DECODE_ERROR); + return; + } + + decode_task_queue_.emplace(std::move(buffer), next_buffer_id_, + std::move(decode_cb)); + + // Generate the next positive buffer id. + next_buffer_id_ = (next_buffer_id_ + 1) & 0x7fffffff; + + // If we were waiting for input buffers, start decoding again. + if (state_ == State::kWaitingForInput) { + DCHECK(!current_decode_task_); + SetState(State::kDecoding); + ScheduleNextDecodeTask(); + } +} + +void VaapiVideoDecoder::ScheduleNextDecodeTask() { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(state_, State::kDecoding); + DCHECK(!current_decode_task_); + DCHECK(!decode_task_queue_.empty()); + + // Dequeue the next decode task. + current_decode_task_ = std::move(decode_task_queue_.front()); + decode_task_queue_.pop(); + if (!current_decode_task_->buffer_->end_of_stream()) { + decoder_->SetStream(current_decode_task_->buffer_id_, + current_decode_task_->buffer_->data(), + current_decode_task_->buffer_->data_size()); + } + + decoder_thread_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_)); +} + +void VaapiVideoDecoder::HandleDecodeTask() { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DVLOGF(4); + + if (state_ == State::kError || state_ == State::kResetting) + return; + + DCHECK_EQ(state_, State::kDecoding); + DCHECK(current_decode_task_); + + // Check whether a flush was requested. + if (current_decode_task_->buffer_->end_of_stream()) { + FlushTask(); + return; + } + + AcceleratedVideoDecoder::DecodeResult decode_result = decoder_->Decode(); + switch (decode_result) { + case AcceleratedVideoDecoder::kRanOutOfStreamData: + // Decoding was successful, notify client and try to schedule the next + // task. Switch to the idle state if we ran out of buffers to decode. + RunDecodeCB(std::move(current_decode_task_->decode_done_cb_), + DecodeStatus::OK); + current_decode_task_ = base::nullopt; + if (!decode_task_queue_.empty()) { + ScheduleNextDecodeTask(); + } else { + SetState(State::kWaitingForInput); + } + break; + case AcceleratedVideoDecoder::kAllocateNewSurfaces: + // A new set of output buffers is requested. We either didn't have any + // output buffers yet or encountered a resolution change. + ChangeFrameResolutionTask(); + break; + case AcceleratedVideoDecoder::kRanOutOfSurfaces: + // No more surfaces to decode into available, wait until client returns + // video frames to the frame pool. + SetState(State::kWaitingForOutput); + break; + case AcceleratedVideoDecoder::kNeedContextUpdate: + DVLOGF(3) << "Context updates not supported"; + SetState(State::kError); + break; + case AcceleratedVideoDecoder::kDecodeError: + DVLOGF(3) << "Error decoding stream"; + SetState(State::kError); + break; + case AcceleratedVideoDecoder::kTryAgain: + DVLOGF(3) << "Encrypted streams not supported"; + SetState(State::kError); + break; + } +} + +void VaapiVideoDecoder::ClearDecodeTaskQueue(DecodeStatus status) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DVLOGF(4); + + if (current_decode_task_) { + RunDecodeCB(std::move(current_decode_task_->decode_done_cb_), status); + current_decode_task_ = base::nullopt; + } + + while (!decode_task_queue_.empty()) { + RunDecodeCB(std::move(decode_task_queue_.front().decode_done_cb_), status); + decode_task_queue_.pop(); + } +} + +scoped_refptr<VASurface> VaapiVideoDecoder::CreateSurface() { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(state_, State::kDecoding); + DCHECK(current_decode_task_); + DVLOGF(4); + + // Get a video frame from the video frame pool. + scoped_refptr<VideoFrame> frame = frame_pool_->GetFrame(); + if (!frame) + return nullptr; + + frame->set_timestamp(current_decode_task_->buffer_->timestamp()); + + // Create a VaapiPicture for the frame + std::unique_ptr<VaapiPicture> picture = vaapi_picture_factory_->Create( + vaapi_wrapper_, MakeGLContextCurrentCallback(), BindGLImageCallback(), + PictureBuffer(frame->unique_id(), frame->coded_size())); + + // Import the frame's memory handle into the VaapiPicture, this will create + // a VASurface using the handle. + gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle = + media::CreateGpuMemoryBufferHandle(frame.get()); + LOG_ASSERT(!gpu_memory_buffer_handle.is_null()) + << "Failed to create GPU memory handle"; + + auto buffer_format = + VideoPixelFormatToGfxBufferFormat(frame->layout().format()); + if (!buffer_format) { + VLOGF(1) << "Unexpected frame format"; + SetState(State::kError); + return nullptr; + } + + if (!picture->ImportGpuMemoryBufferHandle( + *buffer_format, std::move(gpu_memory_buffer_handle))) { + LOG(ERROR) << "Failed to import GpuMemoryBufferHandle"; + SetState(State::kError); + return nullptr; + } + + // Store the mapping between surface and video frame, so we know which video + // frame to output when the surface is ready. It's also important to keep a + // reference to the video frame during decoding, as the frame will be + // automatically returned to the pool when the last reference is dropped. + VASurfaceID surface_id = picture->va_surface_id(); + DCHECK_EQ(output_frames_.count(surface_id), 0u); + output_frames_[surface_id] = frame; + + // When the video frame is returned to the pool we need to be notified, so we + // can start decoding again if we are waiting for output buffers. + // TODO(dstaessens@): Don't make use of BindToCurrentLoop. + base::OnceClosure delete_frame_cb = BindToCurrentLoop( + base::BindOnce(&VaapiVideoDecoder::NotifyFrameAvailableTask, weak_this_)); + frame->AddDestructionObserver(std::move(delete_frame_cb)); + + // When the last reference to the VASurface is dropped ReleaseFrameTask() will + // be called. This means the decoder no longer needs the frame for output or + // reference, so we can safely remove it from |output_frames_| and destroy the + // associated VaapiPicture and surface. The frame will be returned to the + // pool once the client stops using it. + VASurface::ReleaseCB release_frame_cb = base::BindOnce( + &VaapiVideoDecoder::ReleaseFrameTask, weak_this_, std::move(picture)); + + return new VASurface(surface_id, frame->layout().coded_size(), + GetVaFormatForVideoCodecProfile(profile_), + std::move(release_frame_cb)); +} + +void VaapiVideoDecoder::SurfaceReady(const scoped_refptr<VASurface>& va_surface, + int32_t /*buffer_id*/, + const gfx::Rect& /*visible_rect*/, + const VideoColorSpace& /*color_space*/) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(state_, State::kDecoding); + DVLOGF(3); + + // Find the frame associated with the surface. We won't erase it from + // |output_frames_| yet, as the decoder might still be using it for reference. + DCHECK_EQ(output_frames_.count(va_surface->id()), 1u); + OutputFrameTask(output_frames_[va_surface->id()]); +} + +void VaapiVideoDecoder::OutputFrameTask(scoped_refptr<VideoFrame> video_frame) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(state_, State::kDecoding); + DCHECK(video_frame); + VLOGF(4); + + scoped_refptr<VideoFrame> converted_frame = + frame_converter_->ConvertFrame(video_frame); + if (!converted_frame) { + VLOGF(1) << "Failed to convert video frame"; + SetState(State::kError); + return; + } + + // TODO(dstaessens): MojoVideoDecoderService expects the |output_cb_| to be + // called on the client task runner, even though media::VideoDecoder states + // frames should be output without any thread jumping. + client_task_runner_->PostTask( + FROM_HERE, base::BindOnce(output_cb_, std::move(converted_frame))); +} + +void VaapiVideoDecoder::ChangeFrameResolutionTask() { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK(state_ == State::kDecoding); + DCHECK(output_frames_.empty()); + VLOGF(2); + + // TODO(hiroh): Handle profile changes. + // TODO(dstaessens): Update natural size after submitting crrev.com/c/1657871. + visible_rect_ = decoder_->GetVisibleRect(); + natural_size_ = visible_rect_.size(); + gfx::Size pic_size = decoder_->GetPicSize(); + const VideoPixelFormat format = GfxBufferFormatToVideoPixelFormat( + vaapi_picture_factory_->GetBufferFormat()); + auto frame_layout = VideoFrameLayout::Create(format, pic_size); + frame_pool_->SetFrameFormat(*frame_layout, visible_rect_, natural_size_); + frame_pool_->SetMaxNumFrames(decoder_->GetRequiredNumOfPictures()); + + // All pending decode operations will be completed before triggering a + // resolution change, so we can safely destroy the context here. + vaapi_wrapper_->DestroyContext(); + vaapi_wrapper_->CreateContext(GetVaFormatForVideoCodecProfile(profile_), + pic_size); + + // Retry the current decode task. + decoder_thread_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_)); +} + +void VaapiVideoDecoder::ReleaseFrameTask(std::unique_ptr<VaapiPicture> picture, + VASurfaceID surface_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(picture->va_surface_id(), surface_id); + DVLOGF(4); + + // The decoder has finished using the frame associated with |surface_id| for + // output or reference, so it's safe to drop our reference here. Once the + // client drops their reference NotifyFrameAvailableTask() will be called. + size_t num_erased = output_frames_.erase(surface_id); + DCHECK_EQ(num_erased, 1u); + + // Releasing the |picture| here will also destroy the associated VASurface. +} + +void VaapiVideoDecoder::NotifyFrameAvailableTask() { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + VLOGF(4); + + // If we were waiting for output buffers, retry the current decode task. + if (state_ == State::kWaitingForOutput) { + DCHECK(current_decode_task_); + SetState(State::kDecoding); + decoder_thread_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_)); + } +} + +void VaapiVideoDecoder::FlushTask() { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(state_, State::kDecoding); + DCHECK(current_decode_task_); + DCHECK(current_decode_task_->buffer_->end_of_stream()); + DCHECK(decode_task_queue_.empty()); + DVLOGF(2); + + // Flush will block until SurfaceReady() has been called for every frame + // currently decoding. + if (!decoder_->Flush()) { + VLOGF(1) << "Failed to flush the decoder"; + SetState(State::kError); + return; + } + + // Put the decoder in an idle state, ready to resume. + decoder_->Reset(); + + // Notify the client flushing is done. + RunDecodeCB(std::move(current_decode_task_->decode_done_cb_), + DecodeStatus::OK); + current_decode_task_ = base::nullopt; + + // Wait for new decodes, no decode tasks should be queued while flushing. + SetState(State::kWaitingForInput); +} + +void VaapiVideoDecoder::Reset(base::OnceClosure reset_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + DVLOGF(2); + + decoder_thread_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VaapiVideoDecoder::ResetTask, weak_this_, + std::move(reset_cb))); +} + +void VaapiVideoDecoder::ResetTask(base::OnceClosure reset_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DVLOGF(2); + + // If we encountered an error, skip reset and notify client. + if (state_ == State::kError) { + client_task_runner_->PostTask(FROM_HERE, std::move(reset_cb)); + return; + } + + decoder_->Reset(); + SetState(State::kResetting); + + // Wait until any pending decode task has been aborted. + decoder_thread_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VaapiVideoDecoder::ResetDoneTask, weak_this_, + std::move(reset_cb))); +} + +void VaapiVideoDecoder::ResetDoneTask(base::OnceClosure reset_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DCHECK_EQ(state_, State::kResetting); + DCHECK(!current_decode_task_); + DCHECK(decode_task_queue_.empty()); + DVLOGF(2); + + client_task_runner_->PostTask(FROM_HERE, std::move(reset_cb)); + SetState(State::kWaitingForInput); +} + +void VaapiVideoDecoder::RunDecodeCB(DecodeCB cb, DecodeStatus status) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + + client_task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(cb), status)); +} + +void VaapiVideoDecoder::SetState(State state) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); + DVLOGF(4) << static_cast<int>(state) + << ", current state: " << static_cast<int>(state_); + + // Check whether the state change is valid. + switch (state) { + case State::kDecoding: + DCHECK(state_ == State::kWaitingForInput || + state_ == State::kWaitingForOutput); + break; + case State::kWaitingForInput: + DCHECK(decode_task_queue_.empty()); + DCHECK(!current_decode_task_); + DCHECK(state_ == State::kUninitialized || state_ == State::kDecoding || + state_ == State::kResetting); + break; + case State::kWaitingForOutput: + DCHECK(current_decode_task_); + DCHECK_EQ(state_, State::kDecoding); + break; + case State::kResetting: + DCHECK(state_ == State::kWaitingForInput || + state_ == State::kWaitingForOutput || state_ == State::kDecoding); + ClearDecodeTaskQueue(DecodeStatus::ABORTED); + break; + case State::kError: + ClearDecodeTaskQueue(DecodeStatus::DECODE_ERROR); + break; + default: + NOTREACHED() << "Invalid state change"; + } + + state_ = state; +} + +} // namespace media
diff --git a/media/gpu/vaapi/vaapi_video_decoder.h b/media/gpu/vaapi/vaapi_video_decoder.h new file mode 100644 index 0000000..069e5f51 --- /dev/null +++ b/media/gpu/vaapi/vaapi_video_decoder.h
@@ -0,0 +1,205 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_H_ +#define MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_H_ + +#include <stdint.h> +#include <va/va.h> + +#include <map> +#include <memory> +#include <string> +#include <utility> + +#include "base/containers/queue.h" +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/threading/thread.h" +#include "media/base/video_codecs.h" +#include "media/base/video_decoder.h" +#include "media/gpu/decode_surface_handler.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +class AcceleratedVideoDecoder; +class DmabufVideoFramePool; +class VaapiPictureFactory; +class VaapiPicture; +class VaapiWrapper; +class VideoFrame; +class VideoFrameConverter; +class VASurface; + +class VaapiVideoDecoder : public media::VideoDecoder, + public DecodeSurfaceHandler<VASurface> { + public: + static std::unique_ptr<VideoDecoder> Create( + scoped_refptr<base::SequencedTaskRunner> client_task_runner, + std::unique_ptr<DmabufVideoFramePool> frame_pool, + std::unique_ptr<VideoFrameConverter> frame_converter); + + // media::VideoDecoder implementation. + std::string GetDisplayName() const override; + bool IsPlatformDecoder() const override; + bool NeedsBitstreamConversion() const override; + bool CanReadWithoutStalling() const override; + int GetMaxDecodeRequests() const override; + void Initialize(const VideoDecoderConfig& config, + bool low_delay, + CdmContext* cdm_context, + InitCB init_cb, + const OutputCB& output_cb, + const WaitingCB& waiting_cb) override; + void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override; + void Reset(base::OnceClosure reset_cb) override; + + // DecodeSurfaceHandler<VASurface> implementation. + scoped_refptr<VASurface> CreateSurface() override; + void SurfaceReady(const scoped_refptr<VASurface>& va_surface, + int32_t buffer_id, + const gfx::Rect& visible_rect, + const VideoColorSpace& color_space) override; + + private: + // Decode task holding single decode request. + struct DecodeTask { + DecodeTask(scoped_refptr<DecoderBuffer> buffer, + int32_t buffer_id, + DecodeCB decode_done_cb); + ~DecodeTask(); + DecodeTask(DecodeTask&&); + DecodeTask& operator=(DecodeTask&&) = default; + scoped_refptr<DecoderBuffer> buffer_; + int32_t buffer_id_ = -1; + DecodeCB decode_done_cb_; + DISALLOW_COPY_AND_ASSIGN(DecodeTask); + }; + + enum class State { + kUninitialized, // not initialized yet or initialization failed. + kWaitingForInput, // waiting for input buffers. + kWaitingForOutput, // waiting for output buffers. + kDecoding, // decoding buffers. + kResetting, // resetting decoder. + kError, // decoder encountered an error. + }; + + VaapiVideoDecoder(scoped_refptr<base::SequencedTaskRunner> client_task_runner, + std::unique_ptr<DmabufVideoFramePool> frame_pool, + std::unique_ptr<VideoFrameConverter> frame_converter); + ~VaapiVideoDecoder() override; + + // Destroy the VAAPIVideoDecoder, aborts pending decode requests and blocks + // until destroyed. + void Destroy() override; + + // Initialize the VAAPI video decoder on the decoder thread. + void InitializeTask(const VideoDecoderConfig& config, + InitCB init_cb, + OutputCB output_cb); + // Destroy the VAAPI video decoder on the decoder thread. + void DestroyTask(); + + // Queue a decode task on the decoder thread. If the decoder is currently + // waiting for input buffers decoding will be started. + void QueueDecodeTask(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb); + // Schedule the next decode task in the queue to be executed. + void ScheduleNextDecodeTask(); + // Try to decode a single input buffer on the decoder thread. + void HandleDecodeTask(); + // Clear the decode task queue on the decoder thread. This is done when + // resetting or destroying the decoder, or encountering an error. + void ClearDecodeTaskQueue(DecodeStatus status); + + // Output a single |video_frame| on the decoder thread. + void OutputFrameTask(scoped_refptr<VideoFrame> video_frame); + // Called when a different output frame resolution is requested on the decoder + // thread. This happens when either decoding just started or a resolution + // change occurred in the video stream. + void ChangeFrameResolutionTask(); + // Release the video frame associated with the specified |surface_id| on the + // decoder thread. This is called when the last reference to the associated + // VASurface has been released, which happens when the decoder outputted the + // video frame, or stopped using it as a reference frame. Note that this + // doesn't mean the frame can be reused immediately, as it might still be used + // by the client. + void ReleaseFrameTask(std::unique_ptr<VaapiPicture> picture, + VASurfaceID surface_id); + // Called when a video frame was returned to the video frame pool on the + // decoder thread. This will happen when both the client and decoder + // (in ReleaseFrameTask()) released their reference to the video frame. + void NotifyFrameAvailableTask(); + + // Flush the decoder on the decoder thread, blocks until all pending decode + // tasks have been executed and all frames have been output. + void FlushTask(); + + // Reset the decoder on the decoder thread. This will abort any pending decode + // task. The |reset_cb| will be passed to ResetDoneTask() and called when + // resetting has completed. + void ResetTask(base::OnceClosure reset_cb); + // Called on the decoder thread once resetting is done. Executes |reset_cb|. + void ResetDoneTask(base::OnceClosure reset_cb); + + // Called on decoder thread to schedule |decode_cb| on the client task runner. + void RunDecodeCB(DecodeCB decode_cb, DecodeStatus status); + // Change the current |state_| to the specified |state| on the decoder thread. + void SetState(State state); + + // The video decoder's state. + State state_ = State::kUninitialized; + + // Callback used to notify the client when a frame is available for output. + OutputCB output_cb_; + + // The video stream's profile. + VideoCodecProfile profile_ = VIDEO_CODEC_PROFILE_UNKNOWN; + // True if the decoder needs bitstream conversion before decoding. + bool needs_bitstream_conversion_ = false; + + // Output frame properties. + gfx::Rect visible_rect_; + gfx::Size natural_size_; + + // Video frame pool used to allocate and recycle video frames. + std::unique_ptr<DmabufVideoFramePool> frame_pool_; + // Video frame converter. + std::unique_ptr<VideoFrameConverter> frame_converter_; + + // Queue containing all requested decode tasks. + base::queue<DecodeTask> decode_task_queue_; + // The decode task we're currently trying to execute. + base::Optional<DecodeTask> current_decode_task_; + // The next input buffer id. + int32_t next_buffer_id_ = 0; + + // The list of frames currently used as output buffers or reference frames. + std::map<VASurfaceID, scoped_refptr<VideoFrame>> output_frames_; + + // Platform and codec specific video decoder. + std::unique_ptr<AcceleratedVideoDecoder> decoder_; + scoped_refptr<VaapiWrapper> vaapi_wrapper_; + std::unique_ptr<VaapiPictureFactory> vaapi_picture_factory_; + + const scoped_refptr<base::SequencedTaskRunner> client_task_runner_; + base::Thread decoder_thread_; + scoped_refptr<base::SingleThreadTaskRunner> decoder_thread_task_runner_; + + SEQUENCE_CHECKER(client_sequence_checker_); + SEQUENCE_CHECKER(decoder_sequence_checker_); + + base::WeakPtr<VaapiVideoDecoder> weak_this_; + base::WeakPtrFactory<VaapiVideoDecoder> weak_this_factory_; + + DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecoder); +}; + +} // namespace media + +#endif // MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_H_
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc index 0fca64e..d602f8f2 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -41,9 +41,9 @@ #include "media/gpu/vp8_reference_frame_vector.h" #include "media/gpu/vp9_reference_frame_vector.h" -#if defined(OS_LINUX) -#include "media/gpu/linux/platform_video_frame_utils.h" -#endif +#if defined(OS_CHROMEOS) +#include "media/gpu/chromeos/platform_video_frame_utils.h" +#endif // defined(OS_CHROMEOS) #define NOTIFY_ERROR(error, msg) \ do { \ @@ -558,7 +558,7 @@ vaapi_wrapper_, MakeGLContextCurrentCallback(), BindGLImageCallback(), PictureBuffer(kDummyPictureBufferId, frame->coded_size())); gfx::GpuMemoryBufferHandle gmb_handle; -#if defined(OS_LINUX) +#if defined(OS_CHROMEOS) gmb_handle = CreateGpuMemoryBufferHandle(frame.get()); #endif if (gmb_handle.is_null()) { @@ -566,9 +566,15 @@ "Failed to create GMB handle from video frame"); return nullptr; } - if (!va_picture->ImportGpuMemoryBufferHandle( - VideoPixelFormatToGfxBufferFormat(frame->format()), - std::move(gmb_handle))) { + + auto buffer_format = VideoPixelFormatToGfxBufferFormat(frame->format()); + if (!buffer_format) { + NOTIFY_ERROR(kInvalidArgumentError, + "Unsupported format: " << frame->format()); + return nullptr; + } + if (!va_picture->ImportGpuMemoryBufferHandle(*buffer_format, + std::move(gmb_handle))) { NOTIFY_ERROR(kPlatformFailureError, "Failed in ImportGpuMemoryBufferHandle"); return nullptr;
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index 97f89f9a..f080f1ec 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -1064,36 +1064,40 @@ } // static -VaapiWrapper::InternalFormats -VaapiWrapper::GetJpegDecodeSupportedInternalFormats() { +VaapiWrapper::InternalFormats VaapiWrapper::GetDecodeSupportedInternalFormats( + VAProfile va_profile) { VASupportedProfiles::ProfileInfo profile_info; - if (!VASupportedProfiles::Get().IsProfileSupported( - kDecode, VAProfileJPEGBaseline, &profile_info)) { + if (!VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile, + &profile_info)) { return InternalFormats{}; } return profile_info.supported_internal_formats; } // static -bool VaapiWrapper::IsJpegDecodingSupportedForInternalFormat( +bool VaapiWrapper::IsDecodingSupportedForInternalFormat( + VAProfile va_profile, unsigned int rt_format) { static const base::NoDestructor<VaapiWrapper::InternalFormats> supported_internal_formats( - VaapiWrapper::GetJpegDecodeSupportedInternalFormats()); - if (rt_format == VA_RT_FORMAT_YUV420) - return supported_internal_formats->yuv420; - else if (rt_format == VA_RT_FORMAT_YUV422) - return supported_internal_formats->yuv422; - else if (rt_format == VA_RT_FORMAT_YUV444) - return supported_internal_formats->yuv444; + VaapiWrapper::GetDecodeSupportedInternalFormats(va_profile)); + switch (rt_format) { + case VA_RT_FORMAT_YUV420: + return supported_internal_formats->yuv420; + case VA_RT_FORMAT_YUV422: + return supported_internal_formats->yuv422; + case VA_RT_FORMAT_YUV444: + return supported_internal_formats->yuv444; + } return false; } // static -bool VaapiWrapper::GetJpegDecodeMinResolution(gfx::Size* min_size) { +bool VaapiWrapper::GetDecodeMinResolution(VAProfile va_profile, + gfx::Size* min_size) { VASupportedProfiles::ProfileInfo profile_info; - if (!VASupportedProfiles::Get().IsProfileSupported( - kDecode, VAProfileJPEGBaseline, &profile_info)) { + if (!VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile, + &profile_info)) { return false; } *min_size = profile_info.min_resolution; @@ -1101,10 +1105,11 @@ } // static -bool VaapiWrapper::GetJpegDecodeMaxResolution(gfx::Size* max_size) { +bool VaapiWrapper::GetDecodeMaxResolution(VAProfile va_profile, + gfx::Size* max_size) { VASupportedProfiles::ProfileInfo profile_info; - if (!VASupportedProfiles::Get().IsProfileSupported( - kDecode, VAProfileJPEGBaseline, &profile_info)) { + if (!VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile, + &profile_info)) { return false; } *max_size = profile_info.max_resolution; @@ -1115,7 +1120,7 @@ bool VaapiWrapper::GetJpegDecodeSuitableImageFourCC(unsigned int rt_format, uint32_t preferred_fourcc, uint32_t* suitable_fourcc) { - if (!IsJpegDecodingSupportedForInternalFormat(rt_format)) + if (!IsDecodingSupportedForInternalFormat(VAProfileJPEGBaseline, rt_format)) return false; // Work around some driver-specific conversion issues. If you add a workaround
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h index 0c03759c..4643651b 100644 --- a/media/gpu/vaapi/vaapi_wrapper.h +++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -99,24 +99,26 @@ // Return true when JPEG decode is supported. static bool IsJpegDecodeSupported(); - // Returns the supported internal formats for JPEG decoding. If JPEG decoding - // is not supported, returns InternalFormats{}. - static InternalFormats GetJpegDecodeSupportedInternalFormats(); + // Returns the supported internal formats for decoding using |va_profile|. If + // decoding is not supported for that profile, returns InternalFormats{}. + static InternalFormats GetDecodeSupportedInternalFormats( + VAProfile va_profile); - // Returns true if |rt_format| is supported for JPEG decoding. If it's not or - // JPEG decoding is not supported, returns false. - static bool IsJpegDecodingSupportedForInternalFormat(unsigned int rt_format); + // Returns true if |rt_format| is supported for decoding using |va_profile|. + // Returns false if |rt_format| or |va_profile| is not supported for decoding. + static bool IsDecodingSupportedForInternalFormat(VAProfile va_profile, + unsigned int rt_format); - // Gets the minimum surface size allowed for JPEG decoding. Returns true if - // the size can be obtained, false otherwise. If a dimension is not reported - // by the driver, the dimension is returned as 0. - static bool GetJpegDecodeMinResolution(gfx::Size* min_size); + // Gets the minimum surface size allowed for decoding using |va_profile|. + // Returns true if the size can be obtained, false otherwise. If a dimension + // is not reported by the driver, the dimension is returned as 0. + static bool GetDecodeMinResolution(VAProfile va_profile, gfx::Size* min_size); - // Gets the maximum surface size allowed for JPEG decoding. Returns true if - // the size can be obtained, false otherwise. Because of the initialization in - // VASupportedProfiles::FillProfileInfo_Locked(), the size is guaranteed to - // not be empty (as long as this method returns true). - static bool GetJpegDecodeMaxResolution(gfx::Size* max_size); + // Gets the maximum surface size allowed for decoding using |va_profile|. + // Returns true if the size can be obtained, false otherwise. Because of the + // initialization in VASupportedProfiles::FillProfileInfo_Locked(), the size + // is guaranteed to not be empty (as long as this method returns true). + static bool GetDecodeMaxResolution(VAProfile va_profile, gfx::Size* max_size); // Obtains a suitable FOURCC that can be used in vaCreateImage() + // vaGetImage(). |rt_format| corresponds to the JPEG's subsampling format.
diff --git a/media/gpu/video_frame_mapper_factory.cc b/media/gpu/video_frame_mapper_factory.cc index 41f452b..af5d933 100644 --- a/media/gpu/video_frame_mapper_factory.cc +++ b/media/gpu/video_frame_mapper_factory.cc
@@ -7,9 +7,9 @@ #include "build/build_config.h" #include "media/gpu/buildflags.h" -#if defined(OS_LINUX) -#include "media/gpu/linux/generic_dmabuf_video_frame_mapper.h" -#endif // defined(OS_LINUX) +#if defined(OS_CHROMEOS) +#include "media/gpu/chromeos/generic_dmabuf_video_frame_mapper.h" +#endif // defined(OS_CHROMEOS) #if BUILDFLAG(USE_VAAPI) && defined(OS_LINUX) #include "media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.h" @@ -31,7 +31,7 @@ std::unique_ptr<VideoFrameMapper> VideoFrameMapperFactory::CreateMapper( VideoPixelFormat format, bool linear_buffer_mapper) { -#if defined(OS_LINUX) +#if defined(OS_CHROMEOS) if (linear_buffer_mapper) return GenericDmaBufVideoFrameMapper::Create(format); #endif // defined(OS_LINUX)
diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc index 913a7af3..a1c7bfb 100644 --- a/media/mojo/services/gpu_mojo_media_client.cc +++ b/media/mojo/services/gpu_mojo_media_client.cc
@@ -45,11 +45,11 @@ #include "ui/gl/gl_angle_util_win.h" #endif // defined(OS_WIN) -#if defined(OS_CHROMEOS) || defined(OS_LINUX) -#include "media/gpu/linux/linux_video_decoder_factory.h" -#include "media/gpu/linux/mailbox_video_frame_converter.h" -#include "media/gpu/linux/platform_video_frame_pool.h" -#endif // defined(OS_CHROMEOS) || defined(OS_LINUX) +#if defined(OS_CHROMEOS) +#include "media/gpu/chromeos/chromeos_video_decoder_factory.h" +#include "media/gpu/chromeos/mailbox_video_frame_converter.h" +#include "media/gpu/chromeos/platform_video_frame_pool.h" +#endif // defined(OS_CHROMEOS) #if defined(OS_ANDROID) #include "media/mojo/services/android_mojo_util.h" @@ -207,18 +207,18 @@ gpu_task_runner_, std::move(get_stub_cb), gpu_preferences_, MaybeRenderEarlyManager::Create(gpu_task_runner_))); -#elif defined(OS_CHROMEOS) || defined(OS_LINUX) - std::unique_ptr<VideoDecoder> linux_video_decoder; - if (base::FeatureList::IsEnabled(kLinuxVideoDecoder)) { - linux_video_decoder = LinuxVideoDecoderFactory::Create( +#elif defined(OS_CHROMEOS) + std::unique_ptr<VideoDecoder> cros_video_decoder; + if (base::FeatureList::IsEnabled(kChromeosVideoDecoder)) { + cros_video_decoder = ChromeosVideoDecoderFactory::Create( task_runner, gpu_task_runner_, base::BindOnce(&GetCommandBufferStub, media_gpu_channel_manager_, command_buffer_id->channel_token, command_buffer_id->route_id)); } - if (linux_video_decoder) { - video_decoder = std::move(linux_video_decoder); + if (cros_video_decoder) { + video_decoder = std::move(cros_video_decoder); } else { video_decoder = VdaVideoDecoder::Create( task_runner, gpu_task_runner_, media_log->Clone(), @@ -228,7 +228,7 @@ command_buffer_id->channel_token, command_buffer_id->route_id)); } -#elif defined(OS_MACOSX) || defined(OS_WIN) +#elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) video_decoder = VdaVideoDecoder::Create( task_runner, gpu_task_runner_, media_log->Clone(), target_color_space, gpu_preferences_, gpu_workarounds_,
diff --git a/media/test/data/switch_1080p_720p_240frames.h264.json b/media/test/data/switch_1080p_720p_240frames.h264.json index f80a1193..88a66a6 100644 --- a/media/test/data/switch_1080p_720p_240frames.h264.json +++ b/media/test/data/switch_1080p_720p_240frames.h264.json
@@ -6,30 +6,30 @@ "num_frames": 240, "num_fragments": 240, "md5_checksums": [ - "1ea74d81500947d6a3d34c04e9764ef0", - "7fcddae137a12f1db5fd757ba9eb4d5d", - "d2b19d292b17fa39cd2a8160bf23f95c", - "7334c16c5a19cc752ae7aa44d6a215af", - "c8bc383a8ca8d55facab7e3f1a22887a", - "e1fa116fad967f26bf7358d95fcb9053", - "7496c984d115a6ea03bff4b7f376abf5", - "71d34a7018c20f567db6d8d1ca24dbce", - "32ab770431449d3a9dffb363e07503bf", - "fd37201d4dba5aa7756dee66d720e3bd", - "feeb4764d4050552ab8c9859fad22f4d", - "750ffffd327c819671493a012f0a1d23", - "d56c0c58b4df674e45354403a259958c", - "9c5b69644c1b66319e313b5633645759", - "542d39a6a72d40765cd733b8361b7b6a", - "47353bd00d6bbaebf9e96733945fe1e5", - "2103fc9ac9daf0ddde16475044f00205", - "f7bfa94b6d64c73504bb861b344b7167", - "9a6d942b1b34a71e017f0a23e73dc17e", - "6553e4afdd0650c5b22027142a5fc433", - "e11a3c3d8b0cb55440acbe5c5e3c4862", - "1fd9fef4bd2d9d1e2a0988961b0437a9", - "d3515af1a62f13c72752d516f7116a86", - "08e9658119f10eae643df508aed35bd6", + "618e221ab37578eacdbd1c2385ceebf6", + "6bfdf9dd478ccdf5ebec6cfe922e90ed", + "07625040a9d2c8925a95a230b51310af", + "369f954bd778962cb3b1c43388da6c19", + "71bbfeb879e2cc4c7d3409636e5a63d0", + "6507508432c78d43f6bcfa979d0109bc", + "d573a59d98dc6421fad7e4ff781804dd", + "9e6b4637c18023600ea6445deacdb2bc", + "cd854ab68eaaa7e8dbf2a24a64ed3c31", + "1218212a929c93c4865d433daa17d1c7", + "198d2519fe543cacd699d065d4cc9842", + "8eb7c703385aaaf266588479189179b0", + "1a5c535ad9b0623fceae8cc4761f1b70", + "ba8ff4fdc4fe920e91e7b1ba7758cac0", + "cc790c9acb2c4454c162cc40c019622c", + "7522a2070fe1be5fcbed25fa52895e76", + "b579605af943996086cc7bafe634fa53", + "fbf115afff79f0f46be95a717053e97d", + "595b3bc3ebcdcb6397b08b81018605de", + "09576d5cc1edc6fb2be0363d9d7e70a6", + "54fd62b4ea7e2ffa4826e94c9d458dd4", + "5ab9fe5e2aa8239857a01c819d51df2a", + "676ad8ff3df480947df702278ac8a323", + "2abbc77986855f982add2afc0ed047cb", "9136ce7e1d12c88b156cff82e7d9e9ba", "026b98b25146f1c7cca3d471c04e74f5", "f83732b128173676a297af6952cd1172", @@ -54,30 +54,30 @@ "d2ed901723cc1e68c238768c0534e879", "101646cfc6763c5c1b717a1714de629e", "f18a8880cc2ba2546cc93e896bad9a87", - "c1720979103a5112b9202927839d3cde", - "87cfa6aad79afc17167ac5c095571ce5", - "54c3a2c2ebea12a31eb143c2939edfe5", - "fd869ed345eca5ec7093bd05dc30cffb", - "76d441e2f2bf3f98fa4fd7b07747afab", - "5bb8e69e1cab92119f5a7bda17c18c44", - "dfb5c7f0c85569aae61591fc8bcddd9c", - "b180fbbf8030375047372da857b75b3b", - "a7cc73956ea98e7b9362aa31a32c7e62", - "41132851eddd24c0642a106f53a15f67", - "e40b327432763928ed3493e5013576f3", - "0546b922e1230188a62df403a91d07c3", - "62568050892a31481bb97246e6ff536a", - "548e2c1efad55469487d327060df735b", - "6d562ba81b0d6a8778ec086676009f95", - "823197683e80c97db950c84e0f133efa", - "dd05cc003408d986202c62b33e2da8b5", - "c0a2757cae8897a9d373c2813bfaf477", - "724155cf93c0524fac084e870f52611f", - "282c1909a390ce744ed633448427bc0c", - "6d3915180b22d2f55ffa701da1732478", - "085571e021ab661fe0ec7e05e8d88283", - "bc83704520c594a9f961de659c75b201", - "787fd2478126bac4ae00d1682b283350", + "3ec1b35b9549ee7377a256fc0c38c0cc", + "5d9c7f70c5ca9858d80701baadd5ffd5", + "ab43faa51dfbf81b3721544c0b725200", + "59fcf6e498adc501fcb5d92cc4bff61c", + "3861a2d93d2f4cbcce11f0a82a0a3c24", + "9ff98dc74c41e1187d935288d5097cc0", + "1f83c088d895505b2255477eece59bbb", + "92a2874445b673ea9a1b4b992d2ce9f2", + "79daf9297b6d3fd8d9aac1bd50420d24", + "5e2f67997360df0834e10460e8c6180e", + "fb750e9d933076d8a1215a00177519d9", + "75036e9902bcb5a3c4a8622d172be711", + "facf86b08fb082b751dbe320ef506333", + "9a43ee6a4985f7c8cc659fcb99994a7c", + "52306bab7768c1d369865cd8f8e71194", + "e01cc284c4a9b9c80d2e9e3536535150", + "0f44ec980a2ce060a95220f6ead736f2", + "5f1b3a36e3561f86d08452eb361a741c", + "895ca73cf54ba4bd3756fa43f15773ec", + "d90b696587825cddeb979f99d89eae52", + "5273dc4f6321229d1104c511c54589e2", + "bd9cb487be1500e42900f1f24e737dd0", + "4f7d78c826ca2aa96b147a07a24bac50", + "ccf610ac059b7075d3ac5d07975b6fc5", "c18211c545cb62952ebf17b308967c19", "14007f63879604b3073a161670bfa530", "93fe30a376b43c40dea50e6c701591b1", @@ -102,30 +102,30 @@ "6ffb1fb866ae111ad81b9ff45befd97c", "5cbbac768099e6ff8c02c8ce944f9f9e", "6b3a1df6b9e5e39cd3374d2b7903c2e2", - "3cc5c9a06be37ece4c064c29838c2e32", - "e422c0c8e191db6fb7e1387eb3c8a6f0", - "27ab37f0dbde918d9f59b36e22749553", - "a5414e9f63f52ef9c8dcecccd86b5d51", - "af4862631058c73a463a27d7f85f306d", - "a4acf60a23dfc25c4406846afe62bf47", - "2607ed239c92702c770f77b1ee5addc4", - "a95ceb88b70f04021737d30d71c90e66", - "5c5a77161330a4f8549f97dbf8225277", - "a9e3f9f8642491d5177130ca033e3e36", - "19af17b48076d43fa2a7cc98767f813f", - "f1c6cedbabd77b38f2185889f2341dc5", - "311e3cbd6e2ecd3156d9139ba42c90d4", - "f2cbc62fe87d3cdaa1104ece8731de59", - "2c82fc598535895b595a753985433915", - "ecd7ae4acb76516e5340e408915cf52a", - "6f1c00a3e25fd6ca4a43656d7630a78b", - "50e2162ff8b76ac372d8de4198ed027a", - "a55cdd309a5c088fcd8bf5b76227a158", - "d3f7065996d3611949e22fc6e9dc0ca4", - "58276f282b293af00ade1f8c3e45deb9", - "e69587d5f16a3e377f4ae85ee79ade3e", - "74975fce79a524130f99093b2eceb99d", - "110a2e3463b69bc7a6dd91089eef190e", + "028fa697f6dad0e06e2a9d373333d9d1", + "dee4cc13f45ba82760bd9d456b529bb6", + "dcd9268b28ff8246840be504718b057a", + "99fd9019cddf3181b6b866c382fa791c", + "bf9688913c7218792fd08451e8fd93f0", + "4e56f5d7a45bc47484f21f0596e4dfbb", + "5dd74f5128782f15f499996993f604a9", + "e5f7fed27ffc7029e2f306aeaac7815a", + "6fdcb254f6afba556e4a3b43f96def63", + "f4cd9410961448d4f08a6bc4bea8338e", + "c170ba50b2a1a838e45ca5bf2ce0d59c", + "e90f7f67f33b0acc863d6bb02401843d", + "cc882829fc801291238bf9b3c4db1f79", + "b560132e0bc3116b7c4dc5e88493f151", + "4508e94a61f92f84cebb455d7985382f", + "75aa3e59665c1954d471ad686ec8059c", + "3813648085c0fe4ab8c3082465e4ab0d", + "e9c5e2c66f2aa3eb40406fe5b1c60c87", + "a97e4c9f788c7d91d46122d095e715b4", + "648da24888aac5e4a2fc054a808c4a7c", + "ea00c871e2672ed0c32780a791c06eaf", + "448aabb77ae3f0001798bacb314fe00d", + "6b9411e0414b88bc104c99e2a9967021", + "1a307af0df2e4802e9f85156dc761830", "1bc347c9ff00fcd0d681501468763f30", "4c44cf7c80135163797cda5c8702102d", "2945724c191f294f7f4d26449342a4f0", @@ -150,30 +150,30 @@ "8ae6fa040f5e8d7dea4df2bf8f53d896", "246b3a0a580a022cf04936c7a2aa257d", "1ec3ce1a95caba5547205b34b7a6bf3c", - "bd119589613bdca7c6ed3777e4368a20", - "c6511ad9e8cef12a194ef3e309b145af", - "a0cc142aa0fc825b9775193c4949dc8d", - "996962e0cf4f1661a331b18a31c910ec", - "0b5719ef2680487bbc7d00a842e069f3", - "ec2aeadaaff0657aa25ccb2a594afda5", - "7a674b663009dd1651d2f177100e957e", - "fde53d5287350443c6f1f24fef222224", - "c6835ce045708c2b4d0a5e827b9a7e5f", - "f7818cbe9ddc7626f36dfa760616f11c", - "c454b8c62220922ea5bd9244b5d9801e", - "92f4c8d462f2d99629fa02be6b3c369d", - "c15663a71ef3021ca40ef08eaa48c799", - "b7560d18ed11d267ce8d9e916c6bf40b", - "41864ff938c7597e5898d19c335c3e1f", - "9d02f5b094f44ac6b5b27ad49d0da0ae", - "f9ecd165566123204c55b708a59568e2", - "1a583e857a690c4f883f7744cf73db30", - "40c11af6f0cb8800051b483cc311a10e", - "4e79a4ecfbc576719b087f3833533e47", - "5cf862b4dd62d3088f30e5c9514df2f2", - "df5aaecfbcce7aa4e2ba1a29e5b11c78", - "15dfb9c388c96756be95e8ee951048a8", - "2360da0a3f8a085512edb5a740730c04", + "b9e4c05d2c0fe2e92ea2e95febf4c266", + "7fffd15d0b6dc79286dc9a3913a24506", + "754ad9a168485fe13283c240b46331c3", + "e976caca3192c69a249154f621363f65", + "964e8fe6b42fd682d0b951175b3c5331", + "b3603c2a8bc949acbe3d5ba215aa52a9", + "a05cb40fd106973e264e489bc8884e34", + "d4551aa2d5bc6bb8033b854d3736ffd1", + "9e537d15c9bf923937cd14558ba85abe", + "3b0a1fd53968c3a5fd76eac9b4210007", + "362a105c1d1493269e9ff657de1c2736", + "0a8e4a8c7246d0ca31ac1be8b6ce2ccb", + "d2062ff316e00cabcffb3555d98cd8fd", + "50522c238ea52c40702e53721f0bb2c7", + "676efe270a19e18ed083e5986d91ab88", + "c4cb6c657236c968120c1156161380d1", + "6e51be96f45d61c6a8e11b4977e61349", + "889e293be125a8de4ccfdf2f41143183", + "80cf01d36d3790c626ac9966bacdc63c", + "86eed119ddcdbadfa4641f0233df9dea", + "ba7abf35435af2c3d16949a9d4f693e4", + "16a5682c15ce3b98cea58ecb54f9215e", + "1aea29f680e86a0a0114185869b120c7", + "550d11713e9ea5d5047c4dbf3afac425", "fcbf68e25bc7b4dc5a16646816423632", "95d2094ba330f2760c99f9c34c2cbd91", "777e9bd9e2c840181fc08cbb89f1a870", @@ -198,30 +198,30 @@ "5c750eb19fcb11fea02d9c30eb9c32cd", "035b6337218ee99d3c350929376682cd", "04b755c100294daf0e81725483fe2d51", - "a493d4ef012ae27acbaa84335d404936", - "9d76553c6c7788672d0752d36485b67a", - "8f236a3d2783b86fb547dba251ca0d8a", - "b24937134659ab8e0e92764ee11d111f", - "93e8414e58b8942565ae6024d025d362", - "169e00122e16cedad574696822d43f8f", - "9d71b713284836310947f6509b380923", - "93600680f442e2a47bd4ee4331203139", - "41044e9898aa37a11cfc15f356a072fc", - "0e7d406fbf68723977822e99242d2257", - "19b4ae4e60124347d8e5d7f748819b95", - "faf875a73c78234e079b9605f7f81837", - "1a8e8b702e9aebdc40d3b77e06a604af", - "4aac35bbf8f82ebde5f5ee52f13e2e42", - "ec021d58e14960a83df6ce4a5dd680d3", - "21f511020c5387b6c4d5998def5a3229", - "6284c7a638d033cdea3968fd50f76d96", - "0f14d8949d741fd66e1d4f9474f3fd9f", - "8080e48d2f252c1954e08667d3fb455f", - "9c3e2539508ad5377a34425731e8b24c", - "3ee7a1f732f75d57925aee4fcbd89127", - "16c5e3cc4e9a5af1c21f75bffe5e4f4c", - "4a4e32c51d92bfd7afda79405d65a614", - "d301de4149929c28bd2445d8080f73a1", + "4b50cdcf008cf06a418ca7b8792e09ae", + "f34daf3f06a9ac022a42e489b885da5a", + "12338c7736822bfb953f715311b2344b", + "b805bc0f5eb42d2e9f2a6a111426ec4d", + "c55e960bd3e35c2d9a9430a62cfa2922", + "c974708957d80642c79f2bab439a40b4", + "536f7d380486eda20e23cac0ed886a85", + "35711b04131507ad13533de6bb59e561", + "ef1e7bfec24ddeec791f7afd90c4d8db", + "453ad3fa50c077920770674208aeef0e", + "25d9b5d596151d5815da7cea6d63a5c6", + "82626610edbe42e892776756c8c20112", + "1e9c01fce75d32d7c56298d487bfa379", + "00ea9eb0cc82148912b3e27c8cb4e0ad", + "79acc6ba6ca1f4f2e1d39e8b867244e5", + "c74bb7a82e75d8aafbd446bfe2d6fa12", + "850f45f93cce3550277d710281e6e87b", + "699a00180350c4a444a617568c730939", + "8af77702dfa7bc7ed45037f37eaea621", + "c5056f92e83468ff28bc8c433acb9238", + "be7910a5934ad79303015e6a3902fd45", + "931c9192cfe51655cd9d4fede1b0220e", + "6139cce29bcceb977e0d556b61ef9927", + "1a11888ed641fbd3b66413215684e09e", "05afe3fdd001130a1419a65643cf26a1", "20bcc937fa951e887494b7aca2741239", "3762c139192ef392a7a8502735846847",
diff --git a/net/BUILD.gn b/net/BUILD.gn index 7d2f4ef..a7216ca 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -86,6 +86,7 @@ "USE_KERBEROS=$use_kerberos", "DLOPEN_KERBEROS=$use_external_gssapi", "TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED=$trial_comparison_cert_verifier_supported", + "BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED=$builtin_cert_verifier_feature_supported", ] }
diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java index 9b8317b..35a5843d 100644 --- a/net/android/java/src/org/chromium/net/X509Util.java +++ b/net/android/java/src/org/chromium/net/X509Util.java
@@ -18,7 +18,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; -import org.chromium.base.metrics.RecordHistogram; import java.io.ByteArrayInputStream; import java.io.File; @@ -245,13 +244,6 @@ // Could not load AndroidCAStore. Continue anyway; isKnownRoot will always // return false. } - if (!sDisableNativeCodeForTest - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - // Only record the histogram for 4.2 and up. Before 4.2, the platform doesn't - // return the certificate chain anyway. - RecordHistogram.recordBooleanHistogram( - "Net.FoundSystemTrustRootsAndroid", sSystemKeyStore != null); - } sLoadedSystemKeyStore = true; } if (sSystemTrustAnchorCache == null) {
diff --git a/net/android/network_change_notifier_factory_android.cc b/net/android/network_change_notifier_factory_android.cc index 64b9ca2..71269a83 100644 --- a/net/android/network_change_notifier_factory_android.cc +++ b/net/android/network_change_notifier_factory_android.cc
@@ -4,6 +4,7 @@ #include "net/android/network_change_notifier_factory_android.h" +#include "base/memory/ptr_util.h" #include "net/android/network_change_notifier_android.h" #include "net/android/network_change_notifier_delegate_android.h" @@ -13,8 +14,9 @@ NetworkChangeNotifierFactoryAndroid::~NetworkChangeNotifierFactoryAndroid() {} -NetworkChangeNotifier* NetworkChangeNotifierFactoryAndroid::CreateInstance() { - return new NetworkChangeNotifierAndroid(&delegate_); +std::unique_ptr<NetworkChangeNotifier> +NetworkChangeNotifierFactoryAndroid::CreateInstance() { + return base::WrapUnique(new NetworkChangeNotifierAndroid(&delegate_)); } } // namespace net
diff --git a/net/android/network_change_notifier_factory_android.h b/net/android/network_change_notifier_factory_android.h index 17eb11b..db982e8 100644 --- a/net/android/network_change_notifier_factory_android.h +++ b/net/android/network_change_notifier_factory_android.h
@@ -29,7 +29,7 @@ ~NetworkChangeNotifierFactoryAndroid() override; // NetworkChangeNotifierFactory: - NetworkChangeNotifier* CreateInstance() override; + std::unique_ptr<NetworkChangeNotifier> CreateInstance() override; private: // Delegate passed to the instances created by this class.
diff --git a/net/base/features.cc b/net/base/features.cc index 2061f27..e96e696 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -46,5 +46,10 @@ const base::Feature kCookiesWithoutSameSiteMustBeSecure{ "CookiesWithoutSameSiteMustBeSecure", base::FEATURE_DISABLED_BY_DEFAULT}; +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) +const base::Feature kCertVerifierBuiltinFeature{ + "CertVerifierBuiltin", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + } // namespace features } // namespace net
diff --git a/net/base/features.h b/net/base/features.h index d2e39d71..ebd382b 100644 --- a/net/base/features.h +++ b/net/base/features.h
@@ -8,6 +8,7 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" #include "net/base/net_export.h" +#include "net/net_buildflags.h" namespace net { namespace features { @@ -68,6 +69,11 @@ // SameSiteByDefaultCookies is also enabled. NET_EXPORT extern const base::Feature kCookiesWithoutSameSiteMustBeSecure; +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) +// When enabled, use the builtin cert verifier instead of the platform verifier. +NET_EXPORT extern const base::Feature kCertVerifierBuiltinFeature; +#endif + } // namespace features } // namespace net
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc index 3a38594..6e311e2 100644 --- a/net/base/network_change_notifier.cc +++ b/net/base/network_change_notifier.cc
@@ -199,13 +199,13 @@ } // static -NetworkChangeNotifier* NetworkChangeNotifier::Create() { +std::unique_ptr<NetworkChangeNotifier> NetworkChangeNotifier::Create() { if (g_network_change_notifier_factory) return g_network_change_notifier_factory->CreateInstance(); #if defined(OS_WIN) - NetworkChangeNotifierWin* network_change_notifier = - new NetworkChangeNotifierWin(); + std::unique_ptr<NetworkChangeNotifierWin> network_change_notifier = + std::make_unique<NetworkChangeNotifierWin>(); network_change_notifier->WatchForAddressChange(); return network_change_notifier; #elif defined(OS_ANDROID) @@ -213,13 +213,16 @@ CHECK(false); return NULL; #elif defined(OS_CHROMEOS) - return new NetworkChangeNotifierPosix(CONNECTION_NONE, SUBTYPE_NONE); + return std::make_unique<NetworkChangeNotifierPosix>(CONNECTION_NONE, + SUBTYPE_NONE); #elif defined(OS_LINUX) - return new NetworkChangeNotifierLinux(std::unordered_set<std::string>()); + return std::make_unique<NetworkChangeNotifierLinux>( + std::unordered_set<std::string>()); #elif defined(OS_MACOSX) - return new NetworkChangeNotifierMac(); + return std::make_unique<NetworkChangeNotifierMac>(); #elif defined(OS_FUCHSIA) - return new NetworkChangeNotifierFuchsia(0 /* required_features */); + return std::make_unique<NetworkChangeNotifierFuchsia>( + 0 /* required_features */); #else NOTIMPLEMENTED(); return NULL; @@ -485,8 +488,8 @@ } // static -NetworkChangeNotifier* NetworkChangeNotifier::CreateMock() { - return new MockNetworkChangeNotifier(); +std::unique_ptr<NetworkChangeNotifier> NetworkChangeNotifier::CreateMock() { + return std::make_unique<MockNetworkChangeNotifier>(); } NetworkChangeNotifier::IPAddressObserver::IPAddressObserver() = default;
diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h index 327421f1..899ed75 100644 --- a/net/base/network_change_notifier.h +++ b/net/base/network_change_notifier.h
@@ -292,7 +292,7 @@ // monitored), but if you do create it, you must do so before any other // threads try to access the API below, and it must outlive all other threads // which might try to use it. - static NetworkChangeNotifier* Create(); + static std::unique_ptr<NetworkChangeNotifier> Create(); // Returns whether the process-wide, platform-specific NetworkChangeNotifier // has been created. @@ -401,7 +401,7 @@ // Like Create(), but for use in tests. The mock object doesn't monitor any // events, it merely rebroadcasts notifications when requested. - static NetworkChangeNotifier* CreateMock(); + static std::unique_ptr<NetworkChangeNotifier> CreateMock(); // Registers |observer| to receive notifications of network changes. The // thread on which this is called is the thread on which |observer| will be
diff --git a/net/base/network_change_notifier_factory.h b/net/base/network_change_notifier_factory.h index 88cc15ab..203e997 100644 --- a/net/base/network_change_notifier_factory.h +++ b/net/base/network_change_notifier_factory.h
@@ -5,6 +5,8 @@ #ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_FACTORY_H_ #define NET_BASE_NETWORK_CHANGE_NOTIFIER_FACTORY_H_ +#include <memory> + #include "net/base/net_export.h" namespace net { @@ -16,7 +18,7 @@ public: NetworkChangeNotifierFactory() {} virtual ~NetworkChangeNotifierFactory() {} - virtual NetworkChangeNotifier* CreateInstance() = 0; + virtual std::unique_ptr<NetworkChangeNotifier> CreateInstance() = 0; }; } // namespace net
diff --git a/net/base/network_change_notifier_linux.h b/net/base/network_change_notifier_linux.h index fa14f30..8c4c325 100644 --- a/net/base/network_change_notifier_linux.h +++ b/net/base/network_change_notifier_linux.h
@@ -33,10 +33,11 @@ explicit NetworkChangeNotifierLinux( const std::unordered_set<std::string>& ignored_interfaces); + ~NetworkChangeNotifierLinux() override; + private: class BlockingThreadObjects; - ~NetworkChangeNotifierLinux() override; static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsLinux(); // NetworkChangeNotifier:
diff --git a/net/base/network_change_notifier_win.h b/net/base/network_change_notifier_win.h index e7a00b9c..6647b8c 100644 --- a/net/base/network_change_notifier_win.h +++ b/net/base/network_change_notifier_win.h
@@ -37,6 +37,7 @@ public base::win::ObjectWatcher::Delegate { public: NetworkChangeNotifierWin(); + ~NetworkChangeNotifierWin() override; // Begins listening for a single subsequent address change. If it fails to // start watching, it retries on a timer. Must be called only once, on the @@ -48,7 +49,6 @@ void WatchForAddressChange(); protected: - ~NetworkChangeNotifierWin() override; // For unit tests only. bool is_watching() { return is_watching_; }
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc index d12a247c..29cd2b83 100644 --- a/net/cert/cert_verify_proc.cc +++ b/net/cert/cert_verify_proc.cc
@@ -19,6 +19,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "crypto/sha2.h" +#include "net/base/features.h" #include "net/base/net_errors.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/url_util.h" @@ -38,9 +39,14 @@ #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "net/der/encode_values.h" +#include "net/net_buildflags.h" #include "third_party/boringssl/src/include/openssl/pool.h" #include "url/url_canon.h" +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) +#include "net/cert/cert_verify_proc_builtin.h" +#endif + #if defined(USE_NSS_CERTS) #include "net/cert/cert_verify_proc_nss.h" #elif defined(OS_ANDROID) @@ -454,6 +460,10 @@ // static scoped_refptr<CertVerifyProc> CertVerifyProc::CreateDefault( scoped_refptr<CertNetFetcher> cert_net_fetcher) { +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) + if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature)) + return CreateCertVerifyProcBuiltin(std::move(cert_net_fetcher)); +#endif #if defined(USE_NSS_CERTS) return new CertVerifyProcNSS(); #elif defined(OS_ANDROID)
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index a1726f21..2f39a05 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -60,19 +60,19 @@ #include "third_party/boringssl/src/include/openssl/mem.h" #if defined(USE_NSS_CERTS) +#include "net/cert/cert_verify_proc_nss.h" #include "net/cert_net/nss_ocsp.h" -#endif - -#if defined(OS_ANDROID) +#elif defined(OS_ANDROID) #include "base/android/build_info.h" -#endif - -#if defined(OS_MACOSX) && !defined(OS_IOS) +#include "net/cert/cert_verify_proc_android.h" +#elif defined(OS_IOS) +#include "net/cert/cert_verify_proc_ios.h" +#elif defined(OS_MACOSX) #include "base/mac/mac_util.h" -#endif - -#if defined(OS_WIN) +#include "net/cert/cert_verify_proc_mac.h" +#elif defined(OS_WIN) #include "base/win/windows_version.h" +#include "net/cert/cert_verify_proc_win.h" #endif // TODO(crbug.com/649017): Add tests that only certificates with @@ -149,27 +149,6 @@ CERT_VERIFY_PROC_BUILTIN, }; -// Returns the CertVerifyProcType corresponding to what -// CertVerifyProc::CreateDefault() returns. This needs to be kept in sync with -// CreateDefault(). -CertVerifyProcType GetDefaultCertVerifyProcType() { -#if defined(USE_NSS_CERTS) - return CERT_VERIFY_PROC_NSS; -#elif defined(OS_ANDROID) - return CERT_VERIFY_PROC_ANDROID; -#elif defined(OS_IOS) - return CERT_VERIFY_PROC_IOS; -#elif defined(OS_MACOSX) - return CERT_VERIFY_PROC_MAC; -#elif defined(OS_WIN) - return CERT_VERIFY_PROC_WIN; -#elif defined(OS_FUCHSIA) - return CERT_VERIFY_PROC_BUILTIN; -#else -// Will fail to compile. -#endif -} - // Whether the test is running within the iphone simulator. const bool kTargetIsIphoneSimulator = #if TARGET_IPHONE_SIMULATOR @@ -210,19 +189,55 @@ return nullptr; } -// The set of all CertVerifyProcTypes that tests should be -// parameterized on. -const std::vector<CertVerifyProcType> kAllCertVerifiers = { - GetDefaultCertVerifyProcType() - -// TODO(crbug.com/649017): Enable this everywhere. Right now this is -// gated on having CertVerifyProcBuiltin understand the roots added -// via TestRootCerts. -#if defined(USE_NSS_CERTS) || (defined(OS_MACOSX) && !defined(OS_IOS)) - , - CERT_VERIFY_PROC_BUILTIN +scoped_refptr<CertVerifyProc> CreateCertVerifyProc( + CertVerifyProcType type, + scoped_refptr<CertNetFetcher> cert_net_fetcher) { + switch (type) { +#if defined(USE_NSS_CERTS) + case CERT_VERIFY_PROC_NSS: + return new CertVerifyProcNSS(); +#elif defined(OS_ANDROID) + case CERT_VERIFY_PROC_ANDROID: + return new CertVerifyProcAndroid(std::move(cert_net_fetcher)); +#elif defined(OS_IOS) + case CERT_VERIFY_PROC_IOS: + return new CertVerifyProcIOS(); +#elif defined(OS_MACOSX) + case CERT_VERIFY_PROC_MAC: + return new CertVerifyProcMac(); +#elif defined(OS_WIN) + case CERT_VERIFY_PROC_WIN: + return new CertVerifyProcWin(); #endif -}; + case CERT_VERIFY_PROC_BUILTIN: + return CreateCertVerifyProcBuiltin(std::move(cert_net_fetcher)); + default: + return nullptr; + } +} + +// The set of all CertVerifyProcTypes that tests should be parameterized on. +// This needs to be kept in sync with CertVerifyProc::CreateDefault(). +// TODO(crbug.com/649017): Enable CERT_VERIFY_PROC_BUILTIN everywhere. Right +// now this is gated on having CertVerifyProcBuiltin understand the roots added +// via TestRootCerts. +const std::vector<CertVerifyProcType> kAllCertVerifiers = { +#if defined(USE_NSS_CERTS) + CERT_VERIFY_PROC_NSS, CERT_VERIFY_PROC_BUILTIN +#elif defined(OS_ANDROID) + CERT_VERIFY_PROC_ANDROID +#elif defined(OS_IOS) + CERT_VERIFY_PROC_IOS +#elif defined(OS_MACOSX) + CERT_VERIFY_PROC_MAC, CERT_VERIFY_PROC_BUILTIN +#elif defined(OS_WIN) + CERT_VERIFY_PROC_WIN +#elif defined(OS_FUCHSIA) + CERT_VERIFY_PROC_BUILTIN +#else +#error Unsupported platform +#endif +}; // namespace // Returns true if a test root added through ScopedTestRoot can verify // successfully as a target certificate with chain of length 1 on the given @@ -809,13 +824,8 @@ // fetching by calling SetUpWithCertNetFetcher instead of SetUp. void SetUpWithCertNetFetcher(scoped_refptr<CertNetFetcher> cert_net_fetcher) { CertVerifyProcType type = verify_proc_type(); - if (type == CERT_VERIFY_PROC_BUILTIN) { - verify_proc_ = CreateCertVerifyProcBuiltin(std::move(cert_net_fetcher)); - } else if (type == GetDefaultCertVerifyProcType()) { - verify_proc_ = CertVerifyProc::CreateDefault(std::move(cert_net_fetcher)); - } else { - ADD_FAILURE() << "Unhandled CertVerifyProcType"; - } + verify_proc_ = CreateCertVerifyProc(type, std::move(cert_net_fetcher)); + ASSERT_TRUE(verify_proc_); } int Verify(X509Certificate* cert,
diff --git a/net/cert/cert_verify_proc_win.h b/net/cert/cert_verify_proc_win.h index e584906..b89f088 100644 --- a/net/cert/cert_verify_proc_win.h +++ b/net/cert/cert_verify_proc_win.h
@@ -11,7 +11,7 @@ // Performs certificate path construction and validation using Windows' // CryptoAPI. -class CertVerifyProcWin : public CertVerifyProc { +class NET_EXPORT_PRIVATE CertVerifyProcWin : public CertVerifyProc { public: CertVerifyProcWin();
diff --git a/net/cert/crl_set_fuzzer.cc b/net/cert/crl_set_fuzzer.cc index 97d029c..ef186183 100644 --- a/net/cert/crl_set_fuzzer.cc +++ b/net/cert/crl_set_fuzzer.cc
@@ -9,9 +9,24 @@ #include "net/cert/crl_set.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + if (size < 32 + 32 + 20) + return 0; + base::FuzzedDataProvider data_provider(data, size); - const std::string str = data_provider.ConsumeRandomLengthString(size); + std::string spki_hash = data_provider.ConsumeBytesAsString(32); + std::string issuer_hash = data_provider.ConsumeBytesAsString(32); + size_t serial_length = data_provider.ConsumeIntegralInRange(4, 19); + std::string serial = data_provider.ConsumeBytesAsString(serial_length); + std::string crlset_data = data_provider.ConsumeRemainingBytesAsString(); + scoped_refptr<net::CRLSet> out_crl_set; - net::CRLSet::Parse(str, &out_crl_set); + net::CRLSet::Parse(crlset_data, &out_crl_set); + + if (out_crl_set) { + out_crl_set->CheckSPKI(spki_hash); + out_crl_set->CheckSerial(serial, issuer_hash); + out_crl_set->IsExpired(); + } + return 0; }
diff --git a/net/features.gni b/net/features.gni index 86598e8..3cdaf70 100644 --- a/net/features.gni +++ b/net/features.gni
@@ -42,4 +42,10 @@ # Platforms where the cert verifier comparison trial is supported. # See https://crbug.com/649026. trial_comparison_cert_verifier_supported = is_desktop_linux || is_mac + + # Platforms where both the builtin cert verifier and a platform verifier are + # supported and may be switched between using the CertVerifierBuiltin feature + # flag. This does not include platforms where the builtin cert verifier is + # the only verifier supported. + builtin_cert_verifier_feature_supported = is_desktop_linux || is_mac }
diff --git a/net/test/net_test_suite.cc b/net/test/net_test_suite.cc index 6ef5f7c8..088a547 100644 --- a/net/test/net_test_suite.cc +++ b/net/test/net_test_suite.cc
@@ -35,7 +35,7 @@ } void NetTestSuite::InitializeTestThread() { - network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock()); + network_change_notifier_ = net::NetworkChangeNotifier::CreateMock(); InitializeTestThreadNoNetworkChangeNotifier(); }
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 8f9e182a..0392748 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -133,10 +133,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" -#if defined(OS_FUCHSIA) -#define USE_BUILTIN_CERT_VERIFIER -#endif - #if !BUILDFLAG(DISABLE_FILE_SUPPORT) #include "net/base/filename_util.h" #include "net/url_request/file_protocol_handler.h" @@ -11494,7 +11490,19 @@ std::unique_ptr<ScopedTestEVPolicy> ev_test_policy_; }; +static bool UsingBuiltinCertVerifier() { +#if defined(OS_FUCHSIA) + return true; +#elif BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) + if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature)) + return true; +#endif + return false; +} + static CertStatus ExpectedCertStatusForFailedOnlineRevocationCheck() { + if (UsingBuiltinCertVerifier()) + return 0; #if defined(OS_WIN) || defined(OS_MACOSX) // Windows can return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION but we don't // have that ability on other platforms. @@ -11514,8 +11522,9 @@ // If it does not, then tests which rely on 'hard fail' behaviour should be // skipped. static bool SystemSupportsHardFailRevocationChecking() { -#if defined(OS_WIN) || defined(USE_NSS_CERTS) || \ - defined(USE_BUILTIN_CERT_VERIFIER) + if (UsingBuiltinCertVerifier()) + return true; +#if defined(OS_WIN) || defined(USE_NSS_CERTS) return true; #else return false; @@ -11527,6 +11536,8 @@ // several tests are effected because our testing EV certificate won't be // recognised as EV. static bool SystemUsesChromiumEVMetadata() { + if (UsingBuiltinCertVerifier()) + return true; #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA) return true; #else @@ -11557,6 +11568,8 @@ } static bool SystemSupportsOCSPStapling() { + if (UsingBuiltinCertVerifier()) + return true; #if defined(OS_ANDROID) return false; #elif defined(OS_MACOSX) @@ -11623,17 +11636,17 @@ CertStatus cert_status; DoConnection(ssl_options, &cert_status); -#if defined(USE_BUILTIN_CERT_VERIFIER) - // TODO(649017): This test uses soft-fail revocation checking, but returns an - // invalid OCSP response (can't parse). CertVerifyProcBuiltin currently - // doesn't consider this a candidate for soft-fail (only considers - // network-level failures as skippable). - EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, - cert_status & CERT_STATUS_UNABLE_TO_CHECK_REVOCATION); -#else - EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), - cert_status & CERT_STATUS_ALL_ERRORS); -#endif + if (UsingBuiltinCertVerifier()) { + // TODO(649017): This test uses soft-fail revocation checking, but returns + // an invalid OCSP response (can't parse). CertVerifyProcBuiltin currently + // doesn't consider this a candidate for soft-fail (only considers + // network-level failures as skippable). + EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, + cert_status & CERT_STATUS_UNABLE_TO_CHECK_REVOCATION); + } else { + EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), + cert_status & CERT_STATUS_ALL_ERRORS); + } // Without a positive OCSP response, we shouldn't show the EV status. EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); @@ -11704,18 +11717,18 @@ CertStatus cert_status; DoConnection(ssl_options, &cert_status); -#if defined(USE_BUILTIN_CERT_VERIFIER) - // The builtin verifier enforces the baseline requirements for max age of an - // intermediate's OCSP response. - EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, - cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(0u, cert_status & CERT_STATUS_IS_EV); -#else - // The platform verifiers are more lenient. - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); -#endif + if (UsingBuiltinCertVerifier()) { + // The builtin verifier enforces the baseline requirements for max age of an + // intermediate's OCSP response. + EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, + cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(0u, cert_status & CERT_STATUS_IS_EV); + } else { + // The platform verifiers are more lenient. + EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(SystemUsesChromiumEVMetadata(), + static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); + } EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -12164,14 +12177,14 @@ CertStatus cert_status; DoConnection(ssl_options, &cert_status); -#if defined(USE_BUILTIN_CERT_VERIFIER) - // TODO(crbug.com/649017): Should we consider invalid response as - // affirmatively revoked? - EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, - cert_status & CERT_STATUS_UNABLE_TO_CHECK_REVOCATION); -#else - EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_REVOKED); -#endif + if (UsingBuiltinCertVerifier()) { + // TODO(crbug.com/649017): Should we consider invalid response as + // affirmatively revoked? + EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, + cert_status & CERT_STATUS_UNABLE_TO_CHECK_REVOCATION); + } else { + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_REVOKED); + } // Without a positive OCSP response, we shouldn't show the EV status. EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); @@ -12221,14 +12234,19 @@ CertStatus cert_status; DoConnection(ssl_options, &cert_status); -// Currently only works for Windows and OS X. When using NSS, it's not -// possible to determine whether the check failed because of actual -// revocation or because there was an OCSP failure. + // Currently only works for Windows and OS X. When using NSS, it's not + // possible to determine whether the check failed because of actual + // revocation or because there was an OCSP failure. + if (UsingBuiltinCertVerifier()) { + // TODO(https://crbug.com/410574): Handle this in builtin verifier too? + EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); + } else { #if defined(OS_WIN) || defined(OS_MACOSX) - EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); #else - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); #endif + } EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); EXPECT_EQ(SystemUsesChromiumEVMetadata(),
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc index d3fe375..e656652 100644 --- a/net/websockets/websocket_channel.cc +++ b/net/websockets/websocket_channel.cc
@@ -392,6 +392,12 @@ // |this| may have been deleted. } +// Overrides default quota resend threshold size for WebSocket. This flag will +// be used to investigate the performance issue of crbug.com/865001 and be +// deleted later on. +const char kWebSocketReceiveQuotaThreshold[] = + "websocket-renderer-receive-quota-max"; + ChannelState WebSocketChannel::AddReceiveFlowControlQuota(int64_t quota) { DCHECK(state_ == CONNECTING || state_ == CONNECTED || state_ == SEND_CLOSED || state_ == CLOSE_WAIT);
diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h index 613d4958..24cb76534 100644 --- a/net/websockets/websocket_channel.h +++ b/net/websockets/websocket_channel.h
@@ -153,6 +153,11 @@ void OnFinishOpeningHandshake( std::unique_ptr<WebSocketHandshakeResponseInfo> response); + // The renderer calls AddReceiveFlowControlQuota() to the browser per + // recerving this amount of data so that the browser can continue sending + // remaining data to the renderer. + static const uint64_t kReceiveQuotaThreshold = 1 << 15; + private: class PendingReceivedFrame; @@ -417,6 +422,8 @@ DISALLOW_COPY_AND_ASSIGN(WebSocketChannel); }; +NET_EXPORT extern const char kWebSocketReceiveQuotaThreshold[]; + } // namespace net #endif // NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_
diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc index b33d046..e1108bf 100644 --- a/ppapi/tests/test_url_loader.cc +++ b/ppapi/tests/test_url_loader.cc
@@ -692,7 +692,6 @@ ASSERT_EQ(PP_OK, OpenTrusted("GET", "Accept-Charset:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Accept-Encoding:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Connection:\n")); - ASSERT_EQ(PP_OK, OpenTrusted("GET", "Content-Length:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Cookie:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Cookie2:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Content-Transfer-Encoding:\n")); @@ -704,14 +703,9 @@ ASSERT_EQ(PP_OK, OpenTrusted("GET", "Keep-Alive:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Referer:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "TE:\n")); - ASSERT_EQ(PP_OK, OpenTrusted("GET", "Trailer:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Transfer-Encoding:\n")); - ASSERT_EQ(PP_OK, OpenTrusted("GET", "Upgrade:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "User-Agent:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Via:\n")); - ASSERT_EQ(PP_OK, - OpenTrusted("GET", - "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==:\n")); ASSERT_EQ(PP_OK, OpenTrusted("GET", "Sec-foo:\n")); } // Trusted requests with custom referrer should succeed.
diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index 525cdde4..df0d8a3 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc
@@ -65,7 +65,7 @@ ChromotingHostTest() = default; void SetUp() override { - network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); + network_change_notifier_ = net::NetworkChangeNotifier::Create(); task_runner_ = new AutoThreadTaskRunner(base::ThreadTaskRunnerHandle::Get(), base::DoNothing());
diff --git a/remoting/host/it2me/it2me_host_unittest.cc b/remoting/host/it2me/it2me_host_unittest.cc index 88f82de..103becf 100644 --- a/remoting/host/it2me/it2me_host_unittest.cc +++ b/remoting/host/it2me/it2me_host_unittest.cc
@@ -215,7 +215,7 @@ #endif run_loop_.reset(new base::RunLoop()); - network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); + network_change_notifier_ = net::NetworkChangeNotifier::Create(); host_context_ = ChromotingHostContext::Create(new AutoThreadTaskRunner( base::ThreadTaskRunnerHandle::Get(), run_loop_->QuitClosure()));
diff --git a/remoting/test/protocol_perftest.cc b/remoting/test/protocol_perftest.cc index 1491711..052afb31 100644 --- a/remoting/test/protocol_perftest.cc +++ b/remoting/test/protocol_perftest.cc
@@ -119,7 +119,7 @@ encode_thread_.Start(); decode_thread_.Start(); - network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); + network_change_notifier_ = net::NetworkChangeNotifier::Create(); desktop_environment_factory_.reset( new FakeDesktopEnvironmentFactory(capture_thread_.task_runner()));
diff --git a/services/data_decoder/BUILD.gn b/services/data_decoder/BUILD.gn index 16bfaa7..518e2103 100644 --- a/services/data_decoder/BUILD.gn +++ b/services/data_decoder/BUILD.gn
@@ -18,6 +18,13 @@ "xml_parser.h", ] + if (is_chromeos) { + sources += [ + "ble_scan_parser_impl.cc", + "ble_scan_parser_impl.h", + ] + } + configs += [ "//build/config/compiler:wexit_time_destructors" ] deps = [ @@ -47,6 +54,10 @@ "xml_parser_unittest.cc", ] + if (is_chromeos) { + sources += [ "ble_scan_parser_impl_unittest.cc" ] + } + deps = [ ":lib", "//base", @@ -83,3 +94,14 @@ dict = "//third_party/libxml/fuzz/xml.dict" seed_corpus = "//third_party/libxml/fuzz/seed_corpus" } + +if (is_chromeos) { + fuzzer_test("ble_scan_parser_fuzzer") { + sources = [ + "ble_scan_parser_impl_fuzzer.cc", + ] + deps = [ + ":lib", + ] + } +}
diff --git a/services/data_decoder/DEPS b/services/data_decoder/DEPS index c891c85..91ccb2b 100644 --- a/services/data_decoder/DEPS +++ b/services/data_decoder/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+device/bluetooth/public", "+gin", "+jni", "+skia",
diff --git a/chrome/services/ble_scan_parser/ble_scan_parser_impl.cc b/services/data_decoder/ble_scan_parser_impl.cc similarity index 97% rename from chrome/services/ble_scan_parser/ble_scan_parser_impl.cc rename to services/data_decoder/ble_scan_parser_impl.cc index fc7d649..9f56cc2 100644 --- a/chrome/services/ble_scan_parser/ble_scan_parser_impl.cc +++ b/services/data_decoder/ble_scan_parser_impl.cc
@@ -7,9 +7,9 @@ #include "base/containers/flat_map.h" #include "base/strings/string_number_conversions.h" -#include "chrome/services/ble_scan_parser/ble_scan_parser_impl.h" +#include "services/data_decoder/ble_scan_parser_impl.h" -namespace ble_scan_parser { +namespace data_decoder { // Definitions of the data type flags: // https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/ @@ -196,4 +196,4 @@ return true; } -} // namespace ble_scan_parser +} // namespace data_decoder
diff --git a/chrome/services/ble_scan_parser/ble_scan_parser_impl.h b/services/data_decoder/ble_scan_parser_impl.h similarity index 82% rename from chrome/services/ble_scan_parser/ble_scan_parser_impl.h rename to services/data_decoder/ble_scan_parser_impl.h index 95ee98d..3bc3362c 100644 --- a/chrome/services/ble_scan_parser/ble_scan_parser_impl.h +++ b/services/data_decoder/ble_scan_parser_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_SERVICES_BLE_SCAN_PARSER_BLE_SCAN_PARSER_IMPL_H_ -#define CHROME_SERVICES_BLE_SCAN_PARSER_BLE_SCAN_PARSER_IMPL_H_ +#ifndef SERVICES_DATA_DECODER_BLE_SCAN_PARSER_IMPL_H_ +#define SERVICES_DATA_DECODER_BLE_SCAN_PARSER_IMPL_H_ #include <memory> #include <string> @@ -11,11 +11,11 @@ #include "base/containers/span.h" #include "base/macros.h" -#include "chrome/services/ble_scan_parser/public/mojom/ble_scan_parser.mojom.h" #include "device/bluetooth/public/mojom/uuid.mojom.h" +#include "services/data_decoder/public/mojom/ble_scan_parser.mojom.h" #include "services/service_manager/public/cpp/service_context_ref.h" -namespace ble_scan_parser { +namespace data_decoder { enum class UuidFormat { // The UUID is the third and fourth bytes of a UUID with this pattern: @@ -56,6 +56,6 @@ DISALLOW_COPY_AND_ASSIGN(BleScanParserImpl); }; -} // namespace ble_scan_parser +} // namespace data_decoder -#endif // CHROME_SERVICES_BLE_SCAN_PARSER_BLE_SCAN_PARSER_IMPL_H_ +#endif // SERVICES_DATA_DECODER_BLE_SCAN_PARSER_IMPL_H_
diff --git a/chrome/services/ble_scan_parser/ble_scan_parser_impl_fuzzer.cc b/services/data_decoder/ble_scan_parser_impl_fuzzer.cc similarity index 66% rename from chrome/services/ble_scan_parser/ble_scan_parser_impl_fuzzer.cc rename to services/data_decoder/ble_scan_parser_impl_fuzzer.cc index 84f8dfa..dce884c 100644 --- a/chrome/services/ble_scan_parser/ble_scan_parser_impl_fuzzer.cc +++ b/services/data_decoder/ble_scan_parser_impl_fuzzer.cc
@@ -5,9 +5,9 @@ #include <stddef.h> #include <stdint.h> -#include "chrome/services/ble_scan_parser/ble_scan_parser_impl.h" +#include "services/data_decoder/ble_scan_parser_impl.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - ble_scan_parser::BleScanParserImpl::ParseBleScan(base::make_span(data, size)); + data_decoder::BleScanParserImpl::ParseBleScan(base::make_span(data, size)); return 0; }
diff --git a/chrome/services/ble_scan_parser/ble_scan_parser_impl_unittest.cc b/services/data_decoder/ble_scan_parser_impl_unittest.cc similarity index 97% rename from chrome/services/ble_scan_parser/ble_scan_parser_impl_unittest.cc rename to services/data_decoder/ble_scan_parser_impl_unittest.cc index 7768fa33..b5897b89 100644 --- a/chrome/services/ble_scan_parser/ble_scan_parser_impl_unittest.cc +++ b/services/data_decoder/ble_scan_parser_impl_unittest.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ble_scan_parser_impl.h" +#include "services/data_decoder/ble_scan_parser_impl.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ble_scan_parser { +namespace data_decoder { TEST(BleScanParserImplTest, ParseBadUuidLengthReturnsEmptyString) { std::vector<uint8_t> bad_uuid(0xab, 5); @@ -148,4 +148,4 @@ EXPECT_EQ(expected_manufacturer_data_map, actual->manufacturer_data_map); } -} // namespace ble_scan_parser +} // namespace data_decoder
diff --git a/services/data_decoder/data_decoder_service.cc b/services/data_decoder/data_decoder_service.cc index 6473993..7efa90e 100644 --- a/services/data_decoder/data_decoder_service.cc +++ b/services/data_decoder/data_decoder_service.cc
@@ -17,6 +17,10 @@ #include "services/data_decoder/public/mojom/image_decoder.mojom.h" #include "services/data_decoder/xml_parser.h" +#ifdef OS_CHROMEOS +#include "services/data_decoder/ble_scan_parser_impl.h" +#endif // OS_CHROMEOS + namespace data_decoder { namespace { @@ -35,6 +39,11 @@ base::Unretained(this))); registry_.AddInterface(base::BindRepeating( &DataDecoderService::BindBundledExchangesParser, base::Unretained(this))); + +#ifdef OS_CHROMEOS + registry_.AddInterface(base::BindRepeating( + &DataDecoderService::BindBleScanParser, base::Unretained(this))); +#endif // OS_CHROMEOS } DataDecoderService::DataDecoderService( @@ -57,6 +66,15 @@ registry_.BindInterface(interface_name, std::move(interface_pipe)); } +#ifdef OS_CHROMEOS +void DataDecoderService::BindBleScanParser( + mojom::BleScanParserRequest request) { + mojo::MakeStrongBinding( + std::make_unique<BleScanParserImpl>(keepalive_.CreateRef()), + std::move(request)); +} +#endif // OS_CHROMEOS + void DataDecoderService::BindImageDecoder(mojom::ImageDecoderRequest request) { mojo::MakeStrongBinding( std::make_unique<ImageDecoderImpl>(keepalive_.CreateRef()),
diff --git a/services/data_decoder/data_decoder_service.h b/services/data_decoder/data_decoder_service.h index 2c438cf..2876153 100644 --- a/services/data_decoder/data_decoder_service.h +++ b/services/data_decoder/data_decoder_service.h
@@ -18,6 +18,10 @@ #include "services/service_manager/public/cpp/service_keepalive.h" #include "services/service_manager/public/mojom/service.mojom.h" +#ifdef OS_CHROMEOS +#include "services/data_decoder/public/mojom/ble_scan_parser.mojom.h" +#endif // OS_CHROMEOS + namespace data_decoder { class DataDecoderService : public service_manager::Service { @@ -41,6 +45,10 @@ void BindJsonParser(mojom::JsonParserRequest request); void BindXmlParser(mojom::XmlParserRequest request); +#ifdef OS_CHROMEOS + void BindBleScanParser(mojom::BleScanParserRequest request); +#endif // OS_CHROMEOS + service_manager::ServiceBinding binding_{this}; service_manager::ServiceKeepalive keepalive_; service_manager::BinderRegistry registry_;
diff --git a/services/data_decoder/public/cpp/manifest.cc b/services/data_decoder/public/cpp/manifest.cc index b860e9e..77ea54c2 100644 --- a/services/data_decoder/public/cpp/manifest.cc +++ b/services/data_decoder/public/cpp/manifest.cc
@@ -12,10 +12,14 @@ #include "services/data_decoder/public/mojom/xml_parser.mojom.h" #include "services/service_manager/public/cpp/manifest_builder.h" +#ifdef OS_CHROMEOS +#include "services/data_decoder/public/mojom/ble_scan_parser.mojom.h" +#endif // OS_CHROMEOS + namespace data_decoder { const service_manager::Manifest& GetManifest() { - static base::NoDestructor<service_manager::Manifest> manifest{ + auto manifest_builder = service_manager::ManifestBuilder() .WithServiceName(mojom::kServiceName) .WithDisplayName("Data Decoder Service") @@ -38,8 +42,16 @@ service_manager::Manifest::InterfaceList<mojom::XmlParser>()) .ExposeCapability("bundled_exchanges_parser", service_manager::Manifest::InterfaceList< - mojom::BundledExchangesParser>()) - .Build()}; + mojom::BundledExchangesParser>()); + +#ifdef OS_CHROMEOS + manifest_builder.ExposeCapability( + "ble_scan_parser", + service_manager::Manifest::InterfaceList<mojom::BleScanParser>()); +#endif // OS_CHROMEOS + + static base::NoDestructor<service_manager::Manifest> manifest{ + manifest_builder.Build()}; return *manifest; }
diff --git a/services/data_decoder/public/mojom/BUILD.gn b/services/data_decoder/public/mojom/BUILD.gn index d3611a2..0f36f7b 100644 --- a/services/data_decoder/public/mojom/BUILD.gn +++ b/services/data_decoder/public/mojom/BUILD.gn
@@ -19,6 +19,11 @@ "//ui/gfx/geometry/mojo", "//url/mojom:url_mojom_gurl", ] + + if (is_chromeos) { + sources += [ "ble_scan_parser.mojom" ] + public_deps += [ "//device/bluetooth/public/mojom" ] + } } mojom("constants") {
diff --git a/chrome/services/ble_scan_parser/public/mojom/ble_scan_parser.mojom b/services/data_decoder/public/mojom/ble_scan_parser.mojom similarity index 96% rename from chrome/services/ble_scan_parser/public/mojom/ble_scan_parser.mojom rename to services/data_decoder/public/mojom/ble_scan_parser.mojom index 05f905f..7907c5d87 100644 --- a/chrome/services/ble_scan_parser/public/mojom/ble_scan_parser.mojom +++ b/services/data_decoder/public/mojom/ble_scan_parser.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module ble_scan_parser.mojom; +module data_decoder.mojom; import "device/bluetooth/public/mojom/uuid.mojom";
diff --git a/services/device/geolocation/geolocation_service_unittest.cc b/services/device/geolocation/geolocation_service_unittest.cc index 36f6ffe..d1cda12 100644 --- a/services/device/geolocation/geolocation_service_unittest.cc +++ b/services/device/geolocation/geolocation_service_unittest.cc
@@ -43,7 +43,7 @@ chromeos::shill_clients::InitializeFakes(); chromeos::NetworkHandler::Initialize(); #endif - network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock()); + network_change_notifier_ = net::NetworkChangeNotifier::CreateMock(); // We need to initialize the above *before* the base fixture instantiates // the device service. DeviceServiceTestBase::SetUp();
diff --git a/services/identity/public/cpp/BUILD.gn b/services/identity/public/cpp/BUILD.gn index 3c04bf4..049056e 100644 --- a/services/identity/public/cpp/BUILD.gn +++ b/services/identity/public/cpp/BUILD.gn
@@ -22,15 +22,10 @@ "primary_account_access_token_fetcher.cc", "primary_account_access_token_fetcher.h", "primary_account_mutator.h", + "primary_account_mutator_impl.cc", + "primary_account_mutator_impl.h", ] - if (!is_chromeos) { - sources += [ - "primary_account_mutator_impl.cc", - "primary_account_mutator_impl.h", - ] - } - if (!is_android && !is_ios) { sources += [ "accounts_mutator_impl.cc", @@ -101,7 +96,6 @@ "accounts_cookie_mutator_unittest.cc", "accounts_mutator_unittest.cc", "diagnostics_provider_unittest.cc", - "primary_account_mutator_unittest.cc", ] deps = [ @@ -115,6 +109,10 @@ "//testing/gmock", "//testing/gtest", ] + + if (!is_chromeos) { + sources += [ "primary_account_mutator_unittest.cc" ] + } } source_set("manifest") {
diff --git a/services/identity/public/cpp/DEPS b/services/identity/public/cpp/DEPS index ca08848..322304f 100644 --- a/services/identity/public/cpp/DEPS +++ b/services/identity/public/cpp/DEPS
@@ -21,6 +21,7 @@ "+google_apis/gaia/oauth2_access_token_consumer.h", "+google_apis/gaia/oauth2_token_service.h", "+google_apis/gaia/oauth2_token_service_delegate.h", + "+google_apis/gaia/oauth2_token_service_observer.h", "+services/network/public/cpp", ]
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index 6bf383f..d19f7e8 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -10,6 +10,7 @@ #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/ubertoken_fetcher_impl.h" #include "google_apis/gaia/gaia_auth_util.h" #include "services/identity/public/cpp/accounts_cookie_mutator.h" @@ -142,7 +143,7 @@ IdentityManager::CreateAccessTokenFetcherForAccount( const CoreAccountId& account_id, const std::string& oauth_consumer_name, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode) { return std::make_unique<AccessTokenFetcher>(account_id, oauth_consumer_name, @@ -155,7 +156,7 @@ const CoreAccountId& account_id, const std::string& oauth_consumer_name, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode) { return std::make_unique<AccessTokenFetcher>( @@ -169,7 +170,7 @@ const std::string& client_id, const std::string& client_secret, const std::string& oauth_consumer_name, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode) { return std::make_unique<AccessTokenFetcher>( @@ -179,7 +180,7 @@ void IdentityManager::RemoveAccessTokenFromCache( const CoreAccountId& account_id, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, const std::string& access_token) { token_service_->InvalidateAccessToken(account_id, scopes, access_token); } @@ -387,20 +388,6 @@ return diagnostics_provider_.get(); } -#if defined(OS_CHROMEOS) -void IdentityManager::LegacySetPrimaryAccount( - const std::string& gaia_id, - const std::string& email_address) { - // On ChromeOS the primary account is not guaranteed to be present in - // AccountTrackerService when it is set, but PrimaryAccountManager::SignIn() - // requires that it be so. - // TODO(https://crbug.com/967602): Eliminate the need to seed the account - // here. - account_tracker_service_->SeedAccountInfo(gaia_id, email_address); - primary_account_manager_->SignIn(email_address); -} -#endif - #if defined(OS_IOS) void IdentityManager::ForceTriggerOnCookieChange() { gaia_cookie_manager_service_->ForceOnCookieChangeProcessing();
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index 70d750b3..1a1a855 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -12,9 +12,9 @@ #include "build/build_config.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/primary_account_manager.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/browser/ubertoken_fetcher.h" +#include "google_apis/gaia/oauth2_token_service_observer.h" #include "services/identity/public/cpp/access_token_fetcher.h" #include "services/identity/public/cpp/accounts_in_cookie_jar_info.h" #include "services/identity/public/cpp/scope_set.h" @@ -35,6 +35,7 @@ class AccountFetcherService; class AccountTrackerService; class GaiaCookieManagerService; +class ProfileOAuth2TokenService; namespace identity { @@ -154,7 +155,7 @@ std::unique_ptr<AccessTokenFetcher> CreateAccessTokenFetcherForAccount( const CoreAccountId& account_id, const std::string& oauth_consumer_name, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode); @@ -164,7 +165,7 @@ const CoreAccountId& account_id, const std::string& oauth_consumer_name, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode); @@ -176,7 +177,7 @@ const std::string& client_id, const std::string& client_secret, const std::string& oauth_consumer_name, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode); @@ -185,7 +186,7 @@ // request for |account_id| and |scopes| will fetch a new token from the // network. Otherwise, is a no-op. void RemoveAccessTokenFromCache(const CoreAccountId& account_id, - const identity::ScopeSet& scopes, + const ScopeSet& scopes, const std::string& access_token); // Provides the information of all accounts that have refresh tokens. @@ -296,7 +297,7 @@ // Called when receiving request for access token. virtual void OnAccessTokenRequested(const std::string& account_id, const std::string& consumer_id, - const identity::ScopeSet& scopes) {} + const ScopeSet& scopes) {} // Called when an access token request is completed. Contains diagnostic // information about the access token request. @@ -391,13 +392,6 @@ // state of IdentityManager. DiagnosticsProvider* GetDiagnosticsProvider(); -#if defined(OS_CHROMEOS) - // Sets the primary account info with IdentityManager. - // TODO(https://crbug.com/814787): Eliminate this method. - void LegacySetPrimaryAccount(const std::string& gaia_id, - const std::string& email_address); -#endif - #if defined(OS_IOS) // Forces the processing of GaiaCookieManagerService::OnCookieChange. On // iOS, it's necessary to force-trigger the processing of cookie changes @@ -602,10 +596,9 @@ void OnGaiaCookieDeletedByUserAction(); // OAuth2TokenService::DiagnosticsObserver: - void OnAccessTokenRequested( - const CoreAccountId& account_id, - const std::string& consumer_id, - const OAuth2TokenService::ScopeSet& scopes) override; + void OnAccessTokenRequested(const CoreAccountId& account_id, + const std::string& consumer_id, + const ScopeSet& scopes) override; void OnFetchAccessTokenComplete(const CoreAccountId& account_id, const std::string& consumer_id, const ScopeSet& scopes,
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc index 5391f2d..801b254 100644 --- a/services/identity/public/cpp/identity_test_environment.cc +++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -30,6 +30,7 @@ #include "services/identity/public/cpp/diagnostics_provider_impl.h" #include "services/identity/public/cpp/identity_test_utils.h" #include "services/identity/public/cpp/primary_account_mutator.h" +#include "services/identity/public/cpp/primary_account_mutator_impl.h" #include "services/identity/public/cpp/test_identity_manager_observer.h" #if defined(OS_IOS) @@ -37,10 +38,6 @@ #include "components/signin/ios/browser/profile_oauth2_token_service_ios_provider.h" #endif -#if !defined(OS_CHROMEOS) -#include "services/identity/public/cpp/primary_account_mutator_impl.h" -#endif - #if !defined(OS_ANDROID) && !defined(OS_IOS) #include "services/identity/public/cpp/accounts_mutator_impl.h" #endif @@ -220,15 +217,12 @@ std::make_unique<GaiaCookieManagerService>(token_service.get(), signin_client); - std::unique_ptr<PrimaryAccountMutator> primary_account_mutator; + std::unique_ptr<PrimaryAccountMutator> primary_account_mutator = + std::make_unique<PrimaryAccountMutatorImpl>(account_tracker_service.get(), + primary_account_manager.get(), + pref_service); + std::unique_ptr<AccountsMutator> accounts_mutator; - -#if !defined(OS_CHROMEOS) - primary_account_mutator = std::make_unique<PrimaryAccountMutatorImpl>( - account_tracker_service.get(), primary_account_manager.get(), - pref_service); -#endif - #if !defined(OS_ANDROID) && !defined(OS_IOS) accounts_mutator = std::make_unique<AccountsMutatorImpl>( token_service.get(), account_tracker_service.get(),
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc index a76afa7..349dfcf 100644 --- a/services/identity/public/cpp/identity_test_utils.cc +++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -15,6 +15,7 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "google_apis/gaia/gaia_auth_util.h" #include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/primary_account_mutator.h" #include "services/identity/public/cpp/test_identity_manager_observer.h" #if defined(OS_ANDROID)
diff --git a/services/identity/public/cpp/primary_account_mutator.h b/services/identity/public/cpp/primary_account_mutator.h index 0674d7e..2094a8c9 100644 --- a/services/identity/public/cpp/primary_account_mutator.h +++ b/services/identity/public/cpp/primary_account_mutator.h
@@ -41,6 +41,7 @@ PrimaryAccountMutator const& operator=(const PrimaryAccountMutator& other) = delete; +#if !defined(OS_CHROMEOS) // Marks the account with |account_id| as the primary account, and returns // whether the operation succeeded or not. To succeed, this requires that: // - setting the primary account is allowed, @@ -56,6 +57,19 @@ ClearAccountsAction action, signin_metrics::ProfileSignout source_metric, signin_metrics::SignoutDelete delete_metric) = 0; +#else + // Updates the info of the account corresponding to (|gaia_id|, |email|), + // marks it as the primary account, and returns whether the operation + // succeeded or not. Currently, this method is guaranteed to succeed. + // NOTE: Unlike SetPrimaryAccount(), this method does not require that the + // account is known by IdentityManager. The reason is that on ChromeOS the + // primary account is in fact not guaranteed to be known by IdentityManager + // when it is set. TODO(https://crbug.com/967605): Port callers to + // SetPrimaryAccount() once https://crbug.com/867602 is fixed." + virtual bool SetPrimaryAccountAndUpdateAccountInfo( + const std::string& gaia_id, + const std::string& email) = 0; +#endif }; } // namespace identity
diff --git a/services/identity/public/cpp/primary_account_mutator_impl.cc b/services/identity/public/cpp/primary_account_mutator_impl.cc index e0ff567..c8f6917 100644 --- a/services/identity/public/cpp/primary_account_mutator_impl.cc +++ b/services/identity/public/cpp/primary_account_mutator_impl.cc
@@ -4,7 +4,7 @@ #include "services/identity/public/cpp/primary_account_mutator_impl.h" -#include <utility> +#include <string> #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_tracker_service.h" @@ -27,6 +27,7 @@ PrimaryAccountMutatorImpl::~PrimaryAccountMutatorImpl() {} +#if !defined(OS_CHROMEOS) bool PrimaryAccountMutatorImpl::SetPrimaryAccount( const std::string& account_id) { if (!pref_service_->GetBoolean(prefs::kSigninAllowed)) @@ -68,5 +69,14 @@ return true; } +#else +bool PrimaryAccountMutatorImpl::SetPrimaryAccountAndUpdateAccountInfo( + const std::string& gaia_id, + const std::string& email) { + account_tracker_->SeedAccountInfo(gaia_id, email); + primary_account_manager_->SignIn(email); + return true; +} +#endif } // namespace identity
diff --git a/services/identity/public/cpp/primary_account_mutator_impl.h b/services/identity/public/cpp/primary_account_mutator_impl.h index 99f6398..19a0a85 100644 --- a/services/identity/public/cpp/primary_account_mutator_impl.h +++ b/services/identity/public/cpp/primary_account_mutator_impl.h
@@ -7,6 +7,8 @@ #include "services/identity/public/cpp/primary_account_mutator.h" +#include <string> + class AccountTrackerService; class PrefService; class PrimaryAccountManager; @@ -14,7 +16,7 @@ namespace identity { // Concrete implementation of PrimaryAccountMutator that is based on the -// PrimaryAccountManager API. It is supported on all platform except Chrome OS. +// PrimaryAccountManager API. class PrimaryAccountMutatorImpl : public PrimaryAccountMutator { public: PrimaryAccountMutatorImpl(AccountTrackerService* account_tracker, @@ -23,11 +25,16 @@ ~PrimaryAccountMutatorImpl() override; // PrimaryAccountMutator implementation. +#if !defined(OS_CHROMEOS) bool SetPrimaryAccount(const std::string& account_id) override; bool ClearPrimaryAccount( ClearAccountsAction action, signin_metrics::ProfileSignout source_metric, signin_metrics::SignoutDelete delete_metric) override; +#else + bool SetPrimaryAccountAndUpdateAccountInfo(const std::string& gaia_id, + const std::string& email) override; +#endif private: // Pointers to the services used by the PrimaryAccountMutatorImpl. They
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index ba81fa45..1ee3127 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -303,6 +303,7 @@ "ignore_errors_cert_verifier_unittest.cc", "initiator_lock_compatibility_unittest.cc", "keepalive_statistics_recorder_unittest.cc", + "loader_util_unittest.cc", "mojo_host_resolver_impl_unittest.cc", "network_change_manager_unittest.cc", "network_context_unittest.cc",
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 01e606ed..5b172ca5 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -33,14 +33,13 @@ }; bool NeedsPreflight(const ResourceRequest& request) { - if (!IsCorsEnabledRequestMode(request.fetch_request_mode)) + if (!IsCorsEnabledRequestMode(request.mode)) return false; if (request.is_external_request) return true; - if (request.fetch_request_mode == - mojom::FetchRequestMode::kCorsWithForcedPreflight) { + if (request.mode == mojom::RequestMode::kCorsWithForcedPreflight) { return true; } @@ -118,8 +117,7 @@ } void CorsURLLoader::Start() { - if (fetch_cors_flag_ && - IsCorsEnabledRequestMode(request_.fetch_request_mode)) { + if (fetch_cors_flag_ && IsCorsEnabledRequestMode(request_.mode)) { // Username and password should be stripped in a CORS-enabled request. if (request_.url.has_username() || request_.url.has_password()) { GURL::Replacements replacements; @@ -151,7 +149,7 @@ // When the redirect mode is "error", the client is not expected to // call this function. Let's abort the request. - if (request_.fetch_redirect_mode == mojom::FetchRedirectMode::kError) { + if (request_.redirect_mode == mojom::RedirectMode::kError) { HandleComplete(URLLoaderCompletionStatus(net::ERR_FAILED)); return; } @@ -200,15 +198,15 @@ if ((fetch_cors_flag_ && NeedsPreflight(request_)) || (!original_fetch_cors_flag && fetch_cors_flag_) || (fetch_cors_flag_ && original_method != request_.method)) { - DCHECK_NE(request_.fetch_request_mode, mojom::FetchRequestMode::kNoCors); + DCHECK_NE(request_.mode, mojom::RequestMode::kNoCors); network_client_binding_.Unbind(); StartRequest(); return; } response_tainting_ = CalculateResponseTainting( - request_.url, request_.fetch_request_mode, request_.request_initiator, - fetch_cors_flag_, tainted_, origin_access_list_); + request_.url, request_.mode, request_.request_initiator, fetch_cors_flag_, + tainted_, origin_access_list_); network_loader_->FollowRedirect(removed_headers, modified_headers, new_url); } @@ -249,7 +247,7 @@ GetHeaderString(response_head, header_names::kAccessControlAllowOrigin), GetHeaderString(response_head, header_names::kAccessControlAllowCredentials), - request_.fetch_credentials_mode, + request_.credentials_mode, tainted_ ? url::Origin() : *request_.request_initiator); if (error_status) { HandleComplete(URLLoaderCompletionStatus(*error_status)); @@ -269,7 +267,7 @@ DCHECK(forwarding_client_); DCHECK(!deferred_redirect_url_); - if (request_.fetch_redirect_mode == mojom::FetchRedirectMode::kManual) { + if (request_.redirect_mode == mojom::RedirectMode::kManual) { deferred_redirect_url_ = std::make_unique<GURL>(redirect_info.new_url); forwarding_client_->OnReceiveRedirect(redirect_info, response_head); return; @@ -277,14 +275,13 @@ // If |CORS flag| is set and a CORS check for |request| and |response| returns // failure, then return a network error. - if (fetch_cors_flag_ && - IsCorsEnabledRequestMode(request_.fetch_request_mode)) { + if (fetch_cors_flag_ && IsCorsEnabledRequestMode(request_.mode)) { const auto error_status = CheckAccess( request_.url, response_head.headers->response_code(), GetHeaderString(response_head, header_names::kAccessControlAllowOrigin), GetHeaderString(response_head, header_names::kAccessControlAllowCredentials), - request_.fetch_credentials_mode, + request_.credentials_mode, tainted_ ? url::Origin() : *request_.request_initiator); if (error_status) { HandleComplete(URLLoaderCompletionStatus(*error_status)); @@ -305,8 +302,8 @@ } const auto error_status = CheckRedirectLocation( - redirect_info.new_url, request_.fetch_request_mode, - request_.request_initiator, fetch_cors_flag_, tainted_); + redirect_info.new_url, request_.mode, request_.request_initiator, + fetch_cors_flag_, tainted_); if (error_status) { HandleComplete(URLLoaderCompletionStatus(*error_status)); return; @@ -343,7 +340,7 @@ deferred_redirect_url_ = std::make_unique<GURL>(redirect_info.new_url); auto response_head_to_pass = response_head; - if (request_.fetch_redirect_mode == mojom::FetchRedirectMode::kManual) { + if (request_.redirect_mode == mojom::RedirectMode::kManual) { response_head_to_pass.response_type = mojom::FetchResponseType::kOpaqueRedirect; } else { @@ -414,7 +411,7 @@ // // We exclude navigation requests to keep the existing behavior. // TODO(yhirano): Reconsider this. - if (request_.fetch_request_mode != mojom::FetchRequestMode::kNavigate && + if (request_.mode != mojom::RequestMode::kNavigate && request_.request_initiator && (fetch_cors_flag_ || (request_.method != "GET" && request_.method != "HEAD"))) { @@ -433,8 +430,7 @@ } } - if (fetch_cors_flag_ && - request_.fetch_request_mode == mojom::FetchRequestMode::kSameOrigin) { + if (fetch_cors_flag_ && request_.mode == mojom::RequestMode::kSameOrigin) { DCHECK(request_.request_initiator); HandleComplete(URLLoaderCompletionStatus( CorsErrorStatus(mojom::CorsError::kDisallowedByMode))); @@ -442,10 +438,10 @@ } response_tainting_ = CalculateResponseTainting( - request_.url, request_.fetch_request_mode, request_.request_initiator, - fetch_cors_flag_, tainted_, origin_access_list_); + request_.url, request_.mode, request_.request_initiator, fetch_cors_flag_, + tainted_, origin_access_list_); - if (!CalculateCredentialsFlag(request_.fetch_credentials_mode, + if (!CalculateCredentialsFlag(request_.credentials_mode, response_tainting_)) { request_.allow_credentials = false; } @@ -508,7 +504,7 @@ return; if (!network::cors::ShouldCheckCors(request_.url, request_.request_initiator, - request_.fetch_request_mode)) { + request_.mode)) { return; } @@ -565,7 +561,7 @@ // static mojom::FetchResponseType CorsURLLoader::CalculateResponseTainting( const GURL& url, - mojom::FetchRequestMode request_mode, + mojom::RequestMode request_mode, const base::Optional<url::Origin>& origin, bool cors_flag, bool tainted_origin, @@ -584,7 +580,7 @@ return mojom::FetchResponseType::kBasic; } - if (request_mode == mojom::FetchRequestMode::kNoCors) { + if (request_mode == mojom::RequestMode::kNoCors) { if (tainted_origin || (!origin->IsSameOriginWith(url::Origin::Create(url)) && origin_access_list->CheckAccessState(*origin, url) !=
diff --git a/services/network/cors/cors_url_loader.h b/services/network/cors/cors_url_loader.h index 8748cb88..c83c4e6 100644 --- a/services/network/cors/cors_url_loader.h +++ b/services/network/cors/cors_url_loader.h
@@ -87,7 +87,7 @@ // https://fetch.spec.whatwg.org/#main-fetch. static network::mojom::FetchResponseType CalculateResponseTainting( const GURL& url, - mojom::FetchRequestMode request_mode, + mojom::RequestMode request_mode, const base::Optional<url::Origin>& origin, bool cors_flag, bool tainted_origin,
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 7c3f7c28..9757d46 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -133,9 +133,9 @@ // CORS needs a proper origin (including a unique opaque origin). If the // request doesn't have one, CORS cannot work. if (!request.request_initiator && - request.fetch_request_mode != mojom::FetchRequestMode::kNavigate && - request.fetch_request_mode != mojom::FetchRequestMode::kNoCors) { - LOG(WARNING) << "|fetch_request_mode| is " << request.fetch_request_mode + request.mode != mojom::RequestMode::kNavigate && + request.mode != mojom::RequestMode::kNoCors) { + LOG(WARNING) << "|mode| is " << request.mode << ", but |request_initiator| is not set."; mojo::ReportBadMessage("CorsURLLoaderFactory: cors without initiator"); return false; @@ -148,10 +148,10 @@ // Fetch mode is kOmit, then either |allow_credentials| must be false or // all three load flags must be set. https://crbug.com/799935 tracks // unifying |LOAD_DO_NOT_*| into |allow_credentials|. - if (request.fetch_credentials_mode == mojom::FetchCredentialsMode::kOmit && + if (request.credentials_mode == mojom::CredentialsMode::kOmit && request.allow_credentials && (request.load_flags & load_flags_pattern) != load_flags_pattern) { - LOG(WARNING) << "|fetch_credentials_mode| and |allow_credentials| or " + LOG(WARNING) << "|credentials_mode| and |allow_credentials| or " "|load_flags| contradict each " "other."; mojo::ReportBadMessage( @@ -161,8 +161,8 @@ // Ensure that renderer requests are covered either by CORS or CORB. if (process_id_ != mojom::kBrowserProcessId) { - switch (request.fetch_request_mode) { - case mojom::FetchRequestMode::kNavigate: + switch (request.mode) { + case mojom::RequestMode::kNavigate: // Only the browser process can initiate navigations. This helps ensure // that a malicious/compromised renderer cannot bypass CORB by issuing // kNavigate, rather than kNoCors requests. (CORB should apply only to @@ -172,13 +172,13 @@ "CorsURLLoaderFactory: navigate from non-browser-process"); return false; - case mojom::FetchRequestMode::kSameOrigin: - case mojom::FetchRequestMode::kCors: - case mojom::FetchRequestMode::kCorsWithForcedPreflight: + case mojom::RequestMode::kSameOrigin: + case mojom::RequestMode::kCors: + case mojom::RequestMode::kCorsWithForcedPreflight: // SOP enforced by CORS. break; - case mojom::FetchRequestMode::kNoCors: + case mojom::RequestMode::kNoCors: // SOP enforced by CORB. break; }
diff --git a/services/network/cors/cors_url_loader_factory_unittest.cc b/services/network/cors/cors_url_loader_factory_unittest.cc index aff3cc5f..2e05a0f 100644 --- a/services/network/cors/cors_url_loader_factory_unittest.cc +++ b/services/network/cors/cors_url_loader_factory_unittest.cc
@@ -118,8 +118,8 @@ TEST_F(CorsURLLoaderFactoryTest, DestructionOrder) { ResourceRequest request; GURL url("http://localhost"); - request.fetch_request_mode = mojom::FetchRequestMode::kNoCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kNoCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.allow_credentials = false; request.method = net::HttpRequestHeaders::kGetMethod; request.url = url;
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index 3e465cb4..c62c701 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -170,10 +170,10 @@ void CreateLoaderAndStart(const GURL& origin, const GURL& url, - mojom::FetchRequestMode fetch_request_mode) { + mojom::RequestMode mode) { ResourceRequest request; - request.fetch_request_mode = fetch_request_mode; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mode; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.allow_credentials = false; request.method = net::HttpRequestHeaders::kGetMethod; request.url = url; @@ -221,9 +221,11 @@ test_url_loader_factory_->NotifyClientOnComplete(error_code); } - void FollowRedirect(const std::vector<std::string>& removed_headers = {}) { + void FollowRedirect(const std::vector<std::string>& removed_headers = {}, + const net::HttpRequestHeaders& modified_headers = + net::HttpRequestHeaders()) { DCHECK(url_loader_); - url_loader_->FollowRedirect(removed_headers, {} /*modified_headers*/, + url_loader_->FollowRedirect(removed_headers, modified_headers, base::nullopt /*new_url*/); } @@ -409,8 +411,8 @@ TEST_F(CorsURLLoaderTest, SameOriginWithoutInitiator) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kSameOrigin; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kInclude; + request.mode = mojom::RequestMode::kSameOrigin; + request.credentials_mode = mojom::CredentialsMode::kInclude; request.url = GURL("http://example.com/"); request.request_initiator = base::nullopt; @@ -430,8 +432,8 @@ TEST_F(CorsURLLoaderTest, NoCorsWithoutInitiator) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kNoCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kInclude; + request.mode = mojom::RequestMode::kNoCors; + request.credentials_mode = mojom::CredentialsMode::kInclude; request.url = GURL("http://example.com/"); request.request_initiator = base::nullopt; @@ -449,8 +451,8 @@ TEST_F(CorsURLLoaderTest, CorsWithoutInitiator) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kInclude; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kInclude; request.url = GURL("http://example.com/"); request.request_initiator = base::nullopt; @@ -472,8 +474,8 @@ ResetFactory(base::nullopt /* initiator */, mojom::kBrowserProcessId); ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kNavigate; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kInclude; + request.mode = mojom::RequestMode::kNavigate; + request.credentials_mode = mojom::CredentialsMode::kInclude; request.url = GURL("http://example.com/"); request.request_initiator = base::nullopt; @@ -491,8 +493,8 @@ TEST_F(CorsURLLoaderTest, CredentialsModeAndLoadFlagsContradictEachOther1) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kNavigate; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kNavigate; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.load_flags = net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES; request.url = GURL("http://example.com/"); @@ -514,8 +516,8 @@ TEST_F(CorsURLLoaderTest, CredentialsModeAndLoadFlagsContradictEachOther2) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kNavigate; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kNavigate; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.load_flags = net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA; request.url = GURL("http://example.com/"); @@ -537,8 +539,8 @@ TEST_F(CorsURLLoaderTest, CredentialsModeAndLoadFlagsContradictEachOther3) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kNavigate; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kNavigate; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.load_flags = net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA; request.url = GURL("http://example.com/"); @@ -560,7 +562,7 @@ TEST_F(CorsURLLoaderTest, NavigationFromRenderer) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kNavigate; + request.mode = mojom::RequestMode::kNavigate; request.url = GURL("http://example.com/"); request.request_initiator = base::nullopt; @@ -580,8 +582,7 @@ TEST_F(CorsURLLoaderTest, SameOriginRequest) { const GURL url("http://example.com/foo.png"); - CreateLoaderAndStart(url.GetOrigin(), url, - mojom::FetchRequestMode::kSameOrigin); + CreateLoaderAndStart(url.GetOrigin(), url, mojom::RequestMode::kSameOrigin); NotifyLoaderClientOnReceiveResponse(); NotifyLoaderClientOnComplete(net::OK); @@ -598,7 +599,7 @@ TEST_F(CorsURLLoaderTest, CrossOriginRequestWithNoCorsMode) { const GURL origin("http://example.com"); const GURL url("http://other.com/foo.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kNoCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kNoCors); NotifyLoaderClientOnReceiveResponse(); NotifyLoaderClientOnComplete(net::OK); @@ -618,8 +619,8 @@ const GURL origin("http://example.com"); const GURL url("http://other.com/foo.png"); ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kNoCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kInclude; + request.mode = mojom::RequestMode::kNoCors; + request.credentials_mode = mojom::CredentialsMode::kInclude; request.method = "PATCH"; request.url = url; request.request_initiator = url::Origin::Create(origin); @@ -644,7 +645,7 @@ TEST_F(CorsURLLoaderTest, CrossOriginRequestFetchRequestModeSameOrigin) { const GURL origin("http://example.com"); const GURL url("http://other.com/foo.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kSameOrigin); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kSameOrigin); RunUntilComplete(); @@ -662,7 +663,7 @@ TEST_F(CorsURLLoaderTest, CrossOriginRequestWithCorsModeButMissingCorsHeader) { const GURL origin("http://example.com"); const GURL url("http://other.com/foo.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse(); NotifyLoaderClientOnComplete(net::OK); @@ -685,7 +686,7 @@ TEST_F(CorsURLLoaderTest, CrossOriginRequestWithCorsMode) { const GURL origin("http://example.com"); const GURL url("http://other.com/foo.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse( {"Access-Control-Allow-Origin: http://example.com"}); @@ -704,7 +705,7 @@ CrossOriginRequestFetchRequestWithCorsModeButMismatchedCorsHeader) { const GURL origin("http://example.com"); const GURL url("http://other.com/foo.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse( {"Access-Control-Allow-Origin: http://some-other-domain.com"}); @@ -725,7 +726,7 @@ const GURL origin("http://example.com"); const GURL url("http://foo:bar@other.com/foo.png"); std::string stripped_url = "http://other.com/foo.png"; - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse( {"Access-Control-Allow-Origin: http://example.com"}); @@ -746,7 +747,7 @@ const GURL url("https://other.example.com/foo.png"); const GURL new_url("https://other2.example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -768,7 +769,7 @@ const GURL url("https://other.example.com/foo.png"); const GURL new_url("https://other2.example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -792,7 +793,7 @@ const GURL url("https://other.example.com/foo.png"); const GURL new_url("https://other2.example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -818,7 +819,7 @@ const GURL url("https://example.com/foo.png"); const GURL new_url("https://example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -854,7 +855,7 @@ const GURL url("https://example.com/foo.png"); const GURL new_url("https://other.example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -893,7 +894,7 @@ const GURL url("https://other.example.com/foo.png"); const GURL new_url("https://other.example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -933,7 +934,7 @@ const GURL url("https://other.example.com/foo.png"); const GURL new_url("https://example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -977,7 +978,7 @@ const GURL url("https://other.example.com/foo.png"); const GURL new_url("https://other2.example.com/bar.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); EXPECT_EQ(1, num_created_loaders()); EXPECT_EQ(GetRequest().url, url); @@ -1019,8 +1020,8 @@ const GURL new_url("https://other2.example.com/bar.png"); ResourceRequest original_request; - original_request.fetch_request_mode = mojom::FetchRequestMode::kCors; - original_request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + original_request.mode = mojom::RequestMode::kCors; + original_request.credentials_mode = mojom::CredentialsMode::kOmit; original_request.allow_credentials = false; original_request.method = "PATCH"; original_request.url = url; @@ -1090,8 +1091,8 @@ const GURL new_url("https://other.example.com/foo.png"); ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.allow_credentials = false; request.method = "POST"; request.url = url; @@ -1140,7 +1141,7 @@ const GURL origin("https://example.com"); const GURL url("https://example.com/foo.png"); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); for (int i = 0; i < 20; ++i) { EXPECT_EQ(1, num_created_loaders()); @@ -1173,10 +1174,10 @@ const GURL new_url("https://example.com/bar.png"); ResourceRequest original_request; - original_request.fetch_request_mode = mojom::FetchRequestMode::kCors; - original_request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + original_request.mode = mojom::RequestMode::kCors; + original_request.credentials_mode = mojom::CredentialsMode::kOmit; original_request.allow_credentials = false; - original_request.fetch_redirect_mode = mojom::FetchRedirectMode::kError; + original_request.redirect_mode = mojom::RedirectMode::kError; original_request.method = "GET"; original_request.url = url; original_request.request_initiator = url::Origin::Create(origin); @@ -1202,7 +1203,7 @@ ResourceRequest request; request.url = GURL("https://example.com/foo.png"); request.request_initiator = url::Origin::Create(GURL("https://example.com")); - request.fetch_request_mode = mojom::FetchRequestMode::kCors; + request.mode = mojom::RequestMode::kCors; request.cors_exempt_headers.SetHeader(kTestCorsExemptHeader, "test-value"); CreateLoaderAndStart(request); EXPECT_EQ(1, num_created_loaders()); @@ -1240,7 +1241,7 @@ url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse(); NotifyLoaderClientOnComplete(net::OK); @@ -1268,7 +1269,7 @@ url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse(); @@ -1292,7 +1293,7 @@ url::Origin::Create(origin), url.scheme(), url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse(); NotifyLoaderClientOnComplete(net::OK); @@ -1320,7 +1321,7 @@ url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveResponse(); @@ -1344,7 +1345,7 @@ url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); - CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kNoCors); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kNoCors); NotifyLoaderClientOnReceiveResponse(); NotifyLoaderClientOnComplete(net::OK); @@ -1366,8 +1367,8 @@ const GURL new_url("https://other2.example.com/bar.png"); ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.allow_credentials = false; request.method = "GET"; request.url = url; @@ -1396,8 +1397,8 @@ const GURL new_url("https://other2.example.com/bar.png"); ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.allow_credentials = false; request.method = "GET"; request.url = url; @@ -1422,8 +1423,8 @@ const GURL new_url("https://other2.example.com/bar.png"); ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.allow_credentials = false; request.method = "GET"; request.url = url; @@ -1452,8 +1453,8 @@ const GURL new_url("https://other2.example.com/bar.png"); ResourceRequest original_request; - original_request.fetch_request_mode = mojom::FetchRequestMode::kCors; - original_request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + original_request.mode = mojom::RequestMode::kCors; + original_request.credentials_mode = mojom::CredentialsMode::kOmit; original_request.allow_credentials = false; original_request.method = "GET"; original_request.url = url; @@ -1498,8 +1499,8 @@ // Keep this in sync with the CalculateResponseTainting test in // Blink's cors_test.cc. TEST(CorsURLLoaderTaintingTest, CalculateResponseTainting) { - using mojom::FetchRequestMode; using mojom::FetchResponseType; + using mojom::RequestMode; const GURL same_origin_url("https://example.com/"); const GURL cross_origin_url("https://example2.com/"); @@ -1511,92 +1512,92 @@ // CORS flag is false, same-origin request EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kSameOrigin, origin, false, - false, &origin_access_list)); - EXPECT_EQ(FetchResponseType::kBasic, - CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kNoCors, origin, false, - false, &origin_access_list)); - EXPECT_EQ(FetchResponseType::kBasic, - CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kCors, origin, false, false, + same_origin_url, RequestMode::kSameOrigin, origin, false, false, &origin_access_list)); EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kCorsWithForcedPreflight, - origin, false, false, &origin_access_list)); + same_origin_url, RequestMode::kNoCors, origin, false, false, + &origin_access_list)); EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kNavigate, origin, false, - false, &origin_access_list)); + same_origin_url, RequestMode::kCors, origin, false, false, + &origin_access_list)); + EXPECT_EQ(FetchResponseType::kBasic, + CorsURLLoader::CalculateResponseTainting( + same_origin_url, RequestMode::kCorsWithForcedPreflight, origin, + false, false, &origin_access_list)); + EXPECT_EQ(FetchResponseType::kBasic, + CorsURLLoader::CalculateResponseTainting( + same_origin_url, RequestMode::kNavigate, origin, false, false, + &origin_access_list)); // CORS flag is false, cross-origin request EXPECT_EQ(FetchResponseType::kOpaque, CorsURLLoader::CalculateResponseTainting( - cross_origin_url, FetchRequestMode::kNoCors, origin, false, - false, &origin_access_list)); + cross_origin_url, RequestMode::kNoCors, origin, false, false, + &origin_access_list)); EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - cross_origin_url, FetchRequestMode::kNavigate, origin, false, - false, &origin_access_list)); + cross_origin_url, RequestMode::kNavigate, origin, false, false, + &origin_access_list)); // CORS flag is true, same-origin request EXPECT_EQ(FetchResponseType::kCors, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kCors, origin, true, false, + same_origin_url, RequestMode::kCors, origin, true, false, &origin_access_list)); EXPECT_EQ(FetchResponseType::kCors, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kCorsWithForcedPreflight, - origin, true, false, &origin_access_list)); + same_origin_url, RequestMode::kCorsWithForcedPreflight, origin, + true, false, &origin_access_list)); // CORS flag is true, cross-origin request EXPECT_EQ(FetchResponseType::kCors, CorsURLLoader::CalculateResponseTainting( - cross_origin_url, FetchRequestMode::kCors, origin, true, false, + cross_origin_url, RequestMode::kCors, origin, true, false, &origin_access_list)); EXPECT_EQ(FetchResponseType::kCors, CorsURLLoader::CalculateResponseTainting( - cross_origin_url, FetchRequestMode::kCorsWithForcedPreflight, - origin, true, false, &origin_access_list)); + cross_origin_url, RequestMode::kCorsWithForcedPreflight, origin, + true, false, &origin_access_list)); // Origin is not provided. EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kNoCors, no_origin, false, + same_origin_url, RequestMode::kNoCors, no_origin, false, false, + &origin_access_list)); + EXPECT_EQ(FetchResponseType::kBasic, + CorsURLLoader::CalculateResponseTainting( + same_origin_url, RequestMode::kNavigate, no_origin, false, false, &origin_access_list)); EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kNavigate, no_origin, false, - false, &origin_access_list)); + cross_origin_url, RequestMode::kNoCors, no_origin, false, false, + &origin_access_list)); EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - cross_origin_url, FetchRequestMode::kNoCors, no_origin, false, - false, &origin_access_list)); - EXPECT_EQ(FetchResponseType::kBasic, - CorsURLLoader::CalculateResponseTainting( - cross_origin_url, FetchRequestMode::kNavigate, no_origin, false, + cross_origin_url, RequestMode::kNavigate, no_origin, false, false, &origin_access_list)); // Tainted origin. EXPECT_EQ(FetchResponseType::kOpaque, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kNoCors, origin, false, true, + same_origin_url, RequestMode::kNoCors, origin, false, true, &origin_access_list)); EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kCorsWithForcedPreflight, - origin, false, true, &origin_access_list)); + same_origin_url, RequestMode::kCorsWithForcedPreflight, origin, + false, true, &origin_access_list)); EXPECT_EQ(FetchResponseType::kBasic, CorsURLLoader::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kNavigate, origin, false, - true, &origin_access_list)); + same_origin_url, RequestMode::kNavigate, origin, false, true, + &origin_access_list)); } TEST_F(CorsURLLoaderTest, RequestWithHostHeaderFails) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.allow_credentials = false; request.method = net::HttpRequestHeaders::kGetMethod; request.url = GURL("https://foo.test/path"); @@ -1611,9 +1612,28 @@ EXPECT_EQ(net::ERR_INVALID_ARGUMENT, client().completion_status().error_code); } +TEST_F(CorsURLLoaderTest, RequestWithProxyAuthorizationHeaderFails) { + ResourceRequest request; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; + request.allow_credentials = false; + request.method = net::HttpRequestHeaders::kGetMethod; + request.url = GURL("https://foo.test/path"); + request.request_initiator = url::Origin::Create(GURL("https://foo.test")); + request.headers.SetHeader(net::HttpRequestHeaders::kProxyAuthorization, + "Basic Zm9vOmJhcg=="); + CreateLoaderAndStart(request); + + RunUntilComplete(); + + EXPECT_FALSE(client().has_received_response()); + EXPECT_TRUE(client().has_received_completion()); + EXPECT_EQ(net::ERR_INVALID_ARGUMENT, client().completion_status().error_code); +} + TEST_F(CorsURLLoaderTest, SetHostHeaderOnRedirectFails) { CreateLoaderAndStart(GURL("http://foo.test/"), GURL("http://foo.test/path"), - mojom::FetchRequestMode::kCors); + mojom::RequestMode::kCors); NotifyLoaderClientOnReceiveRedirect( CreateRedirectInfo(301, "GET", GURL("https://redirect.test/"))); @@ -1626,7 +1646,37 @@ ClearHasReceivedRedirect(); // This should cause the request to fail. - AddHostHeaderAndFollowRedirect(); + net::HttpRequestHeaders modified_headers; + modified_headers.SetHeader(net::HttpRequestHeaders::kHost, "bar.test"); + FollowRedirect({} /* removed_headers */, modified_headers); + + RunUntilComplete(); + + EXPECT_FALSE(client().has_received_redirect()); + EXPECT_FALSE(client().has_received_response()); + EXPECT_TRUE(client().has_received_completion()); + EXPECT_EQ(net::ERR_INVALID_ARGUMENT, client().completion_status().error_code); +} + +TEST_F(CorsURLLoaderTest, SetProxyAuthorizationHeaderOnRedirectFails) { + CreateLoaderAndStart(GURL("http://foo.test/"), GURL("http://foo.test/path"), + mojom::RequestMode::kCors); + + NotifyLoaderClientOnReceiveRedirect( + CreateRedirectInfo(301, "GET", GURL("https://redirect.test/"))); + RunUntilRedirectReceived(); + + EXPECT_TRUE(IsNetworkLoaderStarted()); + EXPECT_TRUE(client().has_received_redirect()); + EXPECT_FALSE(client().has_received_response()); + EXPECT_FALSE(client().has_received_completion()); + + ClearHasReceivedRedirect(); + // This should cause the request to fail. + net::HttpRequestHeaders modified_headers; + modified_headers.SetHeader(net::HttpRequestHeaders::kProxyAuthorization, + "Basic Zm9vOmJhcg=="); + FollowRedirect({} /* removed_headers */, modified_headers); RunUntilComplete();
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index 0f92a05..19b2a19 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -84,8 +84,7 @@ preflight_request->referrer = request.referrer; preflight_request->referrer_policy = request.referrer_policy; - preflight_request->fetch_credentials_mode = - mojom::FetchCredentialsMode::kOmit; + preflight_request->credentials_mode = mojom::CredentialsMode::kOmit; preflight_request->allow_credentials = false; preflight_request->load_flags = RetrieveCacheFlags(request.load_flags); preflight_request->fetch_window_id = request.fetch_window_id; @@ -133,7 +132,7 @@ GetHeaderString(head.headers, header_names::kAccessControlAllowOrigin), GetHeaderString(head.headers, header_names::kAccessControlAllowCredentials), - original_request.fetch_credentials_mode, + original_request.credentials_mode, tainted ? url::Origin() : *original_request.request_initiator); if (*detected_error_status) return nullptr; @@ -153,7 +152,7 @@ } auto result = PreflightResult::Create( - original_request.fetch_credentials_mode, + original_request.credentials_mode, GetHeaderString(head.headers, header_names::kAccessControlAllowMethods), GetHeaderString(head.headers, header_names::kAccessControlAllowHeaders), GetHeaderString(head.headers, header_names::kAccessControlMaxAge), @@ -340,7 +339,7 @@ if (!RetrieveCacheFlags(request.load_flags) && !request.is_external_request && cache_.CheckIfRequestCanSkipPreflight( request.request_initiator->Serialize(), request.url, - request.fetch_credentials_mode, request.method, request.headers, + request.credentials_mode, request.method, request.headers, request.is_revalidating)) { std::move(callback).Run(net::OK, base::nullopt, base::nullopt); return;
diff --git a/services/network/cors/preflight_controller_unittest.cc b/services/network/cors/preflight_controller_unittest.cc index 9affeec..f13ad806 100644 --- a/services/network/cors/preflight_controller_unittest.cc +++ b/services/network/cors/preflight_controller_unittest.cc
@@ -33,8 +33,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, LexicographicalOrder) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader("Orange", "Orange"); request.headers.SetHeader("Apple", "Red"); @@ -58,8 +58,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, ExcludeSimpleHeaders) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader("Accept", "everything"); request.headers.SetHeader(net::HttpRequestHeaders::kAcceptLanguage, @@ -80,24 +80,23 @@ TEST(PreflightControllerCreatePreflightRequestTest, Credentials) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kInclude; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kInclude; request.request_initiator = url::Origin(); request.headers.SetHeader("Orange", "Orange"); std::unique_ptr<ResourceRequest> preflight = PreflightController::CreatePreflightRequestForTesting(request); - EXPECT_EQ(mojom::FetchCredentialsMode::kOmit, - preflight->fetch_credentials_mode); + EXPECT_EQ(mojom::CredentialsMode::kOmit, preflight->credentials_mode); EXPECT_FALSE(preflight->allow_credentials); } TEST(PreflightControllerCreatePreflightRequestTest, ExcludeSimpleContentTypeHeader) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader(net::HttpRequestHeaders::kContentType, "text/plain"); @@ -113,8 +112,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, IncludeNonSimpleHeader) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader("X-Custom-Header", "foobar"); @@ -130,8 +129,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, IncludeNonSimpleContentTypeHeader) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader(net::HttpRequestHeaders::kContentType, "application/octet-stream"); @@ -147,8 +146,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, ExcludeForbiddenHeaders) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader("referer", "https://www.google.com/"); @@ -162,8 +161,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, Tainted) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin::Create(GURL("https://example.com")); std::unique_ptr<ResourceRequest> preflight = @@ -177,8 +176,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, FetchWindowId) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader(net::HttpRequestHeaders::kContentType, "application/octet-stream"); @@ -192,8 +191,8 @@ TEST(PreflightControllerCreatePreflightRequestTest, RenderFrameId) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.request_initiator = url::Origin(); request.headers.SetHeader(net::HttpRequestHeaders::kContentType, "application/octet-stream"); @@ -314,8 +313,8 @@ TEST_F(PreflightControllerTest, CheckInvalidRequest) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.url = GetURL("/404"); request.request_initiator = url::Origin::Create(request.url); @@ -328,8 +327,8 @@ TEST_F(PreflightControllerTest, CheckValidRequest) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.url = GetURL("/allow"); request.request_initiator = url::Origin::Create(request.url); @@ -365,8 +364,8 @@ TEST_F(PreflightControllerTest, CheckTaintedRequest) { ResourceRequest request; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; - request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; request.url = GetURL("/tainted"); request.request_initiator = url::Origin::Create(request.url);
diff --git a/services/network/cross_origin_read_blocking.cc b/services/network/cross_origin_read_blocking.cc index 14dd79ec..7d0dcc9 100644 --- a/services/network/cross_origin_read_blocking.cc +++ b/services/network/cross_origin_read_blocking.cc
@@ -594,14 +594,14 @@ const base::Optional<url::Origin>& request_initiator, const ResourceResponseInfo& response, base::Optional<url::Origin> request_initiator_site_lock, - mojom::FetchRequestMode fetch_request_mode) { + mojom::RequestMode request_mode) { content_length_ = response.content_length; http_response_code_ = response.headers ? response.headers->response_code() : 0; request_initiator_site_lock_ = request_initiator_site_lock; should_block_based_on_headers_ = ShouldBlockBasedOnHeaders( - fetch_request_mode, request_url, request_initiator, response); + request_mode, request_url, request_initiator, response); if (should_block_based_on_headers_ == kNeedToSniffMore) CreateSniffers(); } @@ -610,7 +610,7 @@ CrossOriginReadBlocking::ResponseAnalyzer::BlockingDecision CrossOriginReadBlocking::ResponseAnalyzer::ShouldBlockBasedOnHeaders( - mojom::FetchRequestMode fetch_request_mode, + mojom::RequestMode request_mode, const GURL& request_url, const base::Optional<url::Origin>& request_initiator, const ResourceResponseInfo& response) { @@ -658,14 +658,14 @@ // Allow the response through if this is a CORS request and the response has // valid CORS headers. - switch (fetch_request_mode) { - case mojom::FetchRequestMode::kNavigate: - case mojom::FetchRequestMode::kNoCors: - case mojom::FetchRequestMode::kSameOrigin: + switch (request_mode) { + case mojom::RequestMode::kNavigate: + case mojom::RequestMode::kNoCors: + case mojom::RequestMode::kSameOrigin: break; - case mojom::FetchRequestMode::kCors: - case mojom::FetchRequestMode::kCorsWithForcedPreflight: + case mojom::RequestMode::kCors: + case mojom::RequestMode::kCorsWithForcedPreflight: std::string cors_header; response.headers->GetNormalizedHeader("access-control-allow-origin", &cors_header); @@ -750,11 +750,11 @@ // blocked before reaching the renderer process (even without CORB's help). // Of course this assumes that OOR-CORS will use trustworthy // |request_initiator| (i.e. vetted against |request_initiator|site_lock|). - constexpr mojom::FetchRequestMode kOverreachingFetchMode = - mojom::FetchRequestMode::kNoCors; + constexpr mojom::RequestMode kOverreachingRequestMode = + mojom::RequestMode::kNoCors; if (CrossOriginResourcePolicy::kBlock == CrossOriginResourcePolicy::Verify(request_url, request_initiator, - response, kOverreachingFetchMode, + response, kOverreachingRequestMode, request_initiator_site_lock_)) { // Ignore mime types and/or sniffing and have CORB block all responses with // COR*P* header.
diff --git a/services/network/cross_origin_read_blocking.h b/services/network/cross_origin_read_blocking.h index b51b6ff..cd2177d 100644 --- a/services/network/cross_origin_read_blocking.h +++ b/services/network/cross_origin_read_blocking.h
@@ -78,7 +78,7 @@ const base::Optional<url::Origin>& request_initiator, const ResourceResponseInfo& response, base::Optional<url::Origin> request_initiator_site_lock, - mojom::FetchRequestMode fetch_request_mode); + mojom::RequestMode request_mode); ~ResponseAnalyzer(); @@ -141,7 +141,7 @@ kNeedToSniffMore, }; BlockingDecision ShouldBlockBasedOnHeaders( - mojom::FetchRequestMode fetch_request_mode, + mojom::RequestMode request_mode, const GURL& request_url, const base::Optional<url::Origin>& request_initiator, const ResourceResponseInfo& response);
diff --git a/services/network/cross_origin_resource_policy.cc b/services/network/cross_origin_resource_policy.cc index 1f4450f..fc1befa 100644 --- a/services/network/cross_origin_resource_policy.cc +++ b/services/network/cross_origin_resource_policy.cc
@@ -99,11 +99,11 @@ const GURL& request_url, const base::Optional<url::Origin>& request_initiator, const ResourceResponseInfo& response, - mojom::FetchRequestMode fetch_mode, + mojom::RequestMode request_mode, base::Optional<url::Origin> request_initiator_site_lock) { // From https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header: // > 1. If request’s mode is not "no-cors", then return allowed. - if (fetch_mode != mojom::FetchRequestMode::kNoCors) + if (request_mode != mojom::RequestMode::kNoCors) return kAllow; // From https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header:
diff --git a/services/network/cross_origin_resource_policy.h b/services/network/cross_origin_resource_policy.h index 72cee992..fb3ae9e 100644 --- a/services/network/cross_origin_resource_policy.h +++ b/services/network/cross_origin_resource_policy.h
@@ -40,7 +40,7 @@ const GURL& request_url, const base::Optional<url::Origin>& request_initiator, const ResourceResponseInfo& response, - mojom::FetchRequestMode fetch_mode, + mojom::RequestMode request_mode, base::Optional<url::Origin> request_initiator_site_lock); // Parsing of the Cross-Origin-Resource-Policy http response header.
diff --git a/services/network/dns_config_change_manager_unittest.cc b/services/network/dns_config_change_manager_unittest.cc index 5925cc54..08945fa 100644 --- a/services/network/dns_config_change_manager_unittest.cc +++ b/services/network/dns_config_change_manager_unittest.cc
@@ -63,8 +63,8 @@ private: base::test::ScopedTaskEnvironment scoped_task_environment_; - std::unique_ptr<net::NetworkChangeNotifier> notifier_mock_{ - net::NetworkChangeNotifier::CreateMock()}; + std::unique_ptr<net::NetworkChangeNotifier> notifier_mock_ = + net::NetworkChangeNotifier::CreateMock(); DnsConfigChangeManager manager_; TestDnsConfigChangeManagerClient client_{&manager_};
diff --git a/services/network/loader_util.cc b/services/network/loader_util.cc index e1e104e..b329c4d 100644 --- a/services/network/loader_util.cc +++ b/services/network/loader_util.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "net/base/load_flags.h" #include "net/base/mime_sniffer.h" @@ -28,6 +29,44 @@ "image/apng,*/*;q=0.8"; const char kDefaultAcceptHeader[] = "*/*"; +// Headers that consumers are not trusted to set. All "Proxy-" prefixed messages +// are blocked inline. The"Authorization" auth header is deliberately not +// included, since OAuth requires websites be able to set it directly. +const char* kUnsafeHeaders[] = { + // This is determined by the upload body and set by net/. A consumer + // overriding that could allow for Bad Things. + net::HttpRequestHeaders::kContentLength, + + // Disallow setting the Host header because it can conflict with specified + // URL and logic related to isolating sites. + net::HttpRequestHeaders::kHost, + + // Trailers are not supported. + "Trailer", + + // Websockets use a different API. + "Upgrade", + + // TODO(mmenke): Gather stats on the following headers before adding them: + // Cookie, Cookie2, Referer, TE, Keep-Alive, Via. +}; + +// Headers that consumers are currently allowed to set, with the exception of +// certain values could cause problems. +// TODO(mmenke): Gather stats on these, and see if these headers can be banned +// outright instead. +const struct { + const char* name; + const char* value; +} kUnsafeHeaderValues[] = { + // Websockets use a different API. + {net::HttpRequestHeaders::kConnection, "Upgrade"}, + + // Telling a server a non-chunked upload is chunked has similar implications + // as sending the wrong Content-Length. + {net::HttpRequestHeaders::kTransferEncoding, "Chunked"}, +}; + bool ShouldSniffContent(net::URLRequest* url_request, ResourceResponse* response) { const std::string& mime_type = response->head.mime_type; @@ -110,12 +149,26 @@ } bool AreRequestHeadersSafe(const net::HttpRequestHeaders& request_headers) { - // Disallow setting the Host header because it can conflict with specified URL - // and logic related to isolating sites. - if (request_headers.HasHeader(net::HttpRequestHeaders::kHost)) { - LOG(WARNING) - << "Host header should not be set from outside the network service"; - return false; + net::HttpRequestHeaders::Iterator it(request_headers); + + while (it.GetNext()) { + for (const auto* header : kUnsafeHeaders) { + if (base::EqualsCaseInsensitiveASCII(header, it.name())) + return false; + } + + for (const auto& header : kUnsafeHeaderValues) { + if (base::EqualsCaseInsensitiveASCII(header.name, it.name()) && + base::EqualsCaseInsensitiveASCII(header.value, it.value())) { + return false; + } + } + + // Proxy headers are destined for the proxy, so shouldn't be set by callers. + if (base::StartsWith(it.name(), "Proxy-", + base::CompareCase::INSENSITIVE_ASCII)) { + return false; + } } return true; }
diff --git a/services/network/loader_util.h b/services/network/loader_util.h index d73f315..8c9b75a 100644 --- a/services/network/loader_util.h +++ b/services/network/loader_util.h
@@ -55,8 +55,8 @@ COMPONENT_EXPORT(NETWORK_SERVICE) std::string ComputeReferrer(const GURL& referrer); -// Any single headers in a set of request headers are not safe to send. When -// adding sets of headers together, it's safe to call this on each set +// Checks if any single header in a set of request headers is not safe to send. +// When adding sets of headers together, it's safe to call this on each set // individually. COMPONENT_EXPORT(NETWORK_SERVICE) bool AreRequestHeadersSafe(const net::HttpRequestHeaders& request_headers);
diff --git a/services/network/loader_util_unittest.cc b/services/network/loader_util_unittest.cc new file mode 100644 index 0000000..1e561fc --- /dev/null +++ b/services/network/loader_util_unittest.cc
@@ -0,0 +1,61 @@ +// 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. + +#include "services/network/loader_util.h" + +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "net/http/http_request_headers.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace network { + +TEST(LoaderUtilTest, AreRequestHeadersSafe) { + const struct HeaderKeyValuePair { + const char* key; + const char* value; + bool is_safe; + } kHeaders[] = { + {"foo", "bar", true}, + + {net::HttpRequestHeaders::kContentLength, "42", false}, + {net::HttpRequestHeaders::kHost, "foo.test", false}, + {"Trailer", "header-names", false}, + {"Upgrade", "websocket", false}, + {"Upgrade", "webbedsocket", false}, + {"hOsT", "foo.test", false}, + + {net::HttpRequestHeaders::kConnection, "Upgrade", false}, + {net::HttpRequestHeaders::kConnection, "Close", true}, + {net::HttpRequestHeaders::kTransferEncoding, "Chunked", false}, + {net::HttpRequestHeaders::kTransferEncoding, "Chunky", true}, + {"cOnNeCtIoN", "uPgRaDe", false}, + + {net::HttpRequestHeaders::kProxyAuthorization, + "Basic Zm9vOmJhcg==", false}, + {"Proxy-Foo", "bar", false}, + {"PrOxY-FoO", "bar", false}, + }; + + // Check each header in isolation, and all combinations of two header + // key/value pairs that have different keys. + for (const auto& header1 : kHeaders) { + net::HttpRequestHeaders request_headers1; + request_headers1.SetHeader(header1.key, header1.value); + EXPECT_EQ(header1.is_safe, AreRequestHeadersSafe(request_headers1)); + + for (const auto& header2 : kHeaders) { + if (base::EqualsCaseInsensitiveASCII(header1.key, header2.key)) + continue; + + net::HttpRequestHeaders request_headers2; + request_headers2.SetHeader(header1.key, header1.value); + request_headers2.SetHeader(header2.key, header2.value); + EXPECT_EQ(header1.is_safe && header2.is_safe, + AreRequestHeadersSafe(request_headers2)); + } + } +} + +} // namespace network
diff --git a/services/network/network_change_manager_unittest.cc b/services/network/network_change_manager_unittest.cc index efe0ba7..fca5f73 100644 --- a/services/network/network_change_manager_unittest.cc +++ b/services/network/network_change_manager_unittest.cc
@@ -92,7 +92,7 @@ public: NetworkChangeManagerTest() : network_change_manager_(new NetworkChangeManager( - base::WrapUnique(net::NetworkChangeNotifier::CreateMock()))) { + net::NetworkChangeNotifier::CreateMock())) { network_change_manager_client_ = std::make_unique<TestNetworkChangeManagerClient>( network_change_manager_.get());
diff --git a/services/network/network_service.cc b/services/network/network_service.cc index ed24210e..5ac1b0b 100644 --- a/services/network/network_service.cc +++ b/services/network/network_service.cc
@@ -102,7 +102,7 @@ NOTIMPLEMENTED(); return nullptr; #else - return base::WrapUnique(net::NetworkChangeNotifier::Create()); + return net::NetworkChangeNotifier::Create(); #endif } return nullptr;
diff --git a/services/network/public/cpp/cors/cors.cc b/services/network/public/cpp/cors/cors.cc index b7c573ef..e0345d0 100644 --- a/services/network/public/cpp/cors/cors.cc +++ b/services/network/public/cpp/cors/cors.cc
@@ -148,7 +148,7 @@ const int response_status_code, const base::Optional<std::string>& allow_origin_header, const base::Optional<std::string>& allow_credentials_header, - mojom::FetchCredentialsMode credentials_mode, + mojom::CredentialsMode credentials_mode, const url::Origin& origin) { // TODO(toyoshim): This response status code check should not be needed. We // have another status code check after a CheckAccess() call if it is needed. @@ -159,7 +159,7 @@ // A wildcard Access-Control-Allow-Origin can not be used if credentials are // to be sent, even with Access-Control-Allow-Credentials set to true. // See https://fetch.spec.whatwg.org/#cors-protocol-and-credentials. - if (credentials_mode != mojom::FetchCredentialsMode::kInclude) + if (credentials_mode != mojom::CredentialsMode::kInclude) return base::nullopt; // Since the credential is a concept for network schemes, we perform the @@ -212,7 +212,7 @@ *allow_origin_header); } - if (credentials_mode == mojom::FetchCredentialsMode::kInclude) { + if (credentials_mode == mojom::CredentialsMode::kInclude) { // https://fetch.spec.whatwg.org/#http-access-control-allow-credentials. // This check should be case sensitive. // See also https://fetch.spec.whatwg.org/#http-new-header-syntax. @@ -226,9 +226,9 @@ bool ShouldCheckCors(const GURL& request_url, const base::Optional<url::Origin>& request_initiator, - mojom::FetchRequestMode fetch_request_mode) { - if (fetch_request_mode == network::mojom::FetchRequestMode::kNavigate || - fetch_request_mode == network::mojom::FetchRequestMode::kNoCors) { + mojom::RequestMode request_mode) { + if (request_mode == network::mojom::RequestMode::kNavigate || + request_mode == network::mojom::RequestMode::kNoCors) { return false; } @@ -251,7 +251,7 @@ const int response_status_code, const base::Optional<std::string>& allow_origin_header, const base::Optional<std::string>& allow_credentials_header, - mojom::FetchCredentialsMode actual_credentials_mode, + mojom::CredentialsMode actual_credentials_mode, const url::Origin& origin) { const auto error_status = CheckAccess(response_url, response_status_code, allow_origin_header, @@ -293,7 +293,7 @@ base::Optional<CorsErrorStatus> CheckRedirectLocation( const GURL& url, - mojom::FetchRequestMode request_mode, + mojom::RequestMode request_mode, const base::Optional<url::Origin>& origin, bool cors_flag, bool tainted) { @@ -343,9 +343,9 @@ *allow_external); } -bool IsCorsEnabledRequestMode(mojom::FetchRequestMode mode) { - return mode == mojom::FetchRequestMode::kCors || - mode == mojom::FetchRequestMode::kCorsWithForcedPreflight; +bool IsCorsEnabledRequestMode(mojom::RequestMode mode) { + return mode == mojom::RequestMode::kCors || + mode == mojom::RequestMode::kCorsWithForcedPreflight; } bool IsCorsSafelistedMethod(const std::string& method) { @@ -601,7 +601,7 @@ } } -bool CalculateCredentialsFlag(mojom::FetchCredentialsMode credentials_mode, +bool CalculateCredentialsFlag(mojom::CredentialsMode credentials_mode, mojom::FetchResponseType response_tainting) { // Let |credentials flag| be set if one of // - |request|’s credentials mode is "include" @@ -609,11 +609,11 @@ // response tainting is "basic" // is true, and unset otherwise. switch (credentials_mode) { - case network::mojom::FetchCredentialsMode::kOmit: + case network::mojom::CredentialsMode::kOmit: return false; - case network::mojom::FetchCredentialsMode::kSameOrigin: + case network::mojom::CredentialsMode::kSameOrigin: return response_tainting == network::mojom::FetchResponseType::kBasic; - case network::mojom::FetchCredentialsMode::kInclude: + case network::mojom::CredentialsMode::kInclude: return true; } }
diff --git a/services/network/public/cpp/cors/cors.h b/services/network/public/cpp/cors/cors.h index 5de06af..ee9cf0b 100644 --- a/services/network/public/cpp/cors/cors.h +++ b/services/network/public/cpp/cors/cors.h
@@ -55,16 +55,16 @@ const int response_status_code, const base::Optional<std::string>& allow_origin_header, const base::Optional<std::string>& allow_credentials_header, - mojom::FetchCredentialsMode credentials_mode, + mojom::CredentialsMode credentials_mode, const url::Origin& origin); -// Returns true if |fetch_request_mode| is not kNavigate nor kNoCors, and the +// Returns true if |request_mode| is not kNavigate nor kNoCors, and the // origin of |request_url| is not a data URL, and |request_initiator| is not // same as the origin of |request_url|, COMPONENT_EXPORT(NETWORK_CPP) bool ShouldCheckCors(const GURL& request_url, const base::Optional<url::Origin>& request_initiator, - mojom::FetchRequestMode fetch_request_mode); + mojom::RequestMode request_mode); // Performs a CORS access check on the CORS-preflight response parameters. // According to the note at https://fetch.spec.whatwg.org/#cors-preflight-fetch @@ -76,7 +76,7 @@ const int response_status_code, const base::Optional<std::string>& allow_origin_header, const base::Optional<std::string>& allow_credentials_header, - mojom::FetchCredentialsMode actual_credentials_mode, + mojom::CredentialsMode actual_credentials_mode, const url::Origin& origin); // Given a redirected-to URL, checks if the location is allowed @@ -86,7 +86,7 @@ COMPONENT_EXPORT(NETWORK_CPP) base::Optional<CorsErrorStatus> CheckRedirectLocation( const GURL& url, - mojom::FetchRequestMode request_mode, + mojom::RequestMode request_mode, const base::Optional<url::Origin>& origin, bool cors_flag, bool tainted); @@ -105,7 +105,7 @@ const base::Optional<std::string>& allow_external); COMPONENT_EXPORT(NETWORK_CPP) -bool IsCorsEnabledRequestMode(mojom::FetchRequestMode mode); +bool IsCorsEnabledRequestMode(mojom::RequestMode mode); // Checks safelisted request parameters. COMPONENT_EXPORT(NETWORK_CPP) @@ -170,7 +170,7 @@ // Returns true if the credentials flag should be set for the given arguments // as in https://fetch.spec.whatwg.org/#http-network-or-cache-fetch. COMPONENT_EXPORT(NETWORK_CPP) -bool CalculateCredentialsFlag(mojom::FetchCredentialsMode credentials_mode, +bool CalculateCredentialsFlag(mojom::CredentialsMode credentials_mode, mojom::FetchResponseType response_tainting); } // namespace cors
diff --git a/services/network/public/cpp/cors/cors_unittest.cc b/services/network/public/cpp/cors/cors_unittest.cc index 2fdda5d2..ffcf50c 100644 --- a/services/network/public/cpp/cors/cors_unittest.cc +++ b/services/network/public/cpp/cors/cors_unittest.cc
@@ -21,7 +21,7 @@ CheckAccess(GURL(), 0 /* response_status_code */, base::nullopt /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, url::Origin()); + network::mojom::CredentialsMode::kOmit, url::Origin()); ASSERT_TRUE(error_status); EXPECT_EQ(mojom::CorsError::kInvalidResponse, error_status->cors_error); } @@ -38,7 +38,7 @@ CheckAccess(response_url, response_status_code, allow_all_header /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, origin); + network::mojom::CredentialsMode::kOmit, origin); EXPECT_FALSE(error1); // Access-Control-Allow-Origin '*' should not be allowed if credentials mode @@ -47,7 +47,7 @@ CheckAccess(response_url, response_status_code, allow_all_header /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kInclude, origin); + network::mojom::CredentialsMode::kInclude, origin); ASSERT_TRUE(error2); EXPECT_EQ(mojom::CorsError::kWildcardOriginNotAllowed, error2->cors_error); } @@ -63,7 +63,7 @@ CheckAccess(response_url, response_status_code, base::nullopt /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, origin); + network::mojom::CredentialsMode::kOmit, origin); ASSERT_TRUE(error); EXPECT_EQ(mojom::CorsError::kMissingAllowOriginHeader, error->cors_error); } @@ -81,7 +81,7 @@ CheckAccess(response_url, response_status_code, space_separated_multiple_origins /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, origin); + network::mojom::CredentialsMode::kOmit, origin); ASSERT_TRUE(error1); EXPECT_EQ(mojom::CorsError::kMultipleAllowOriginValues, error1->cors_error); @@ -91,7 +91,7 @@ CheckAccess(response_url, response_status_code, comma_separated_multiple_origins /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, origin); + network::mojom::CredentialsMode::kOmit, origin); ASSERT_TRUE(error2); EXPECT_EQ(mojom::CorsError::kMultipleAllowOriginValues, error2->cors_error); } @@ -106,7 +106,7 @@ CheckAccess(response_url, response_status_code, std::string("invalid.origin") /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, origin); + network::mojom::CredentialsMode::kOmit, origin); ASSERT_TRUE(error); EXPECT_EQ(mojom::CorsError::kInvalidAllowOriginValue, error->cors_error); EXPECT_EQ("invalid.origin", error->failed_parameter); @@ -122,14 +122,14 @@ CheckAccess(response_url, response_status_code, origin.Serialize() /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, origin); + network::mojom::CredentialsMode::kOmit, origin); ASSERT_FALSE(error1); base::Optional<CorsErrorStatus> error2 = CheckAccess( response_url, response_status_code, std::string("http://not.google.com") /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, origin); + network::mojom::CredentialsMode::kOmit, origin); ASSERT_TRUE(error2); EXPECT_EQ(mojom::CorsError::kAllowOriginMismatch, error2->cors_error); EXPECT_EQ("http://not.google.com", error2->failed_parameter); @@ -142,7 +142,7 @@ base::Optional<CorsErrorStatus> error3 = CheckAccess( response_url, response_status_code, null_string /* allow_origin_header */, base::nullopt /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kOmit, null_origin); + network::mojom::CredentialsMode::kOmit, null_origin); EXPECT_FALSE(error3); } @@ -156,14 +156,14 @@ CheckAccess(response_url, response_status_code, origin.Serialize() /* allow_origin_header */, std::string("true") /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kInclude, origin); + network::mojom::CredentialsMode::kInclude, origin); ASSERT_FALSE(error1); base::Optional<CorsErrorStatus> error2 = CheckAccess(response_url, response_status_code, origin.Serialize() /* allow_origin_header */, std::string("fuga") /* allow_credentials_header */, - network::mojom::FetchCredentialsMode::kInclude, origin); + network::mojom::CredentialsMode::kInclude, origin); ASSERT_TRUE(error2); EXPECT_EQ(mojom::CorsError::kInvalidAllowCredentials, error2->cors_error); EXPECT_EQ("fuga", error2->failed_parameter); @@ -174,16 +174,16 @@ TEST_F(CorsTest, CheckRedirectLocation) { struct TestCase { GURL url; - mojom::FetchRequestMode request_mode; + mojom::RequestMode request_mode; bool cors_flag; bool tainted; base::Optional<CorsErrorStatus> expectation; }; - const auto kCors = mojom::FetchRequestMode::kCors; + const auto kCors = mojom::RequestMode::kCors; const auto kCorsWithForcedPreflight = - mojom::FetchRequestMode::kCorsWithForcedPreflight; - const auto kNoCors = mojom::FetchRequestMode::kNoCors; + mojom::RequestMode::kCorsWithForcedPreflight; + const auto kNoCors = mojom::RequestMode::kNoCors; const url::Origin origin = url::Origin::Create(GURL("http://example.com/")); const GURL same_origin_url("http://example.com/");
diff --git a/services/network/public/cpp/cors/preflight_cache.cc b/services/network/public/cpp/cors/preflight_cache.cc index 1aa99bc..208c25f 100644 --- a/services/network/public/cpp/cors/preflight_cache.cc +++ b/services/network/public/cpp/cors/preflight_cache.cc
@@ -79,7 +79,7 @@ bool PreflightCache::CheckIfRequestCanSkipPreflight( const std::string& origin, const GURL& url, - mojom::FetchCredentialsMode credentials_mode, + mojom::CredentialsMode credentials_mode, const std::string& method, const net::HttpRequestHeaders& request_headers, bool is_revalidating) {
diff --git a/services/network/public/cpp/cors/preflight_cache.h b/services/network/public/cpp/cors/preflight_cache.h index 326d99a..29e1494a 100644 --- a/services/network/public/cpp/cors/preflight_cache.h +++ b/services/network/public/cpp/cors/preflight_cache.h
@@ -42,13 +42,12 @@ // Consults with cached results, and decides if we can skip CORS-preflight or // not. - bool CheckIfRequestCanSkipPreflight( - const std::string& origin, - const GURL& url, - mojom::FetchCredentialsMode credentials_mode, - const std::string& method, - const net::HttpRequestHeaders& headers, - bool is_revalidating); + bool CheckIfRequestCanSkipPreflight(const std::string& origin, + const GURL& url, + mojom::CredentialsMode credentials_mode, + const std::string& method, + const net::HttpRequestHeaders& headers, + bool is_revalidating); // Reports and gather CORS preflight cache size metric. Metrics ReportAndGatherSizeMetric();
diff --git a/services/network/public/cpp/cors/preflight_cache_unittest.cc b/services/network/public/cpp/cors/preflight_cache_unittest.cc index 36c68a80..6fc53d7 100644 --- a/services/network/public/cpp/cors/preflight_cache_unittest.cc +++ b/services/network/public/cpp/cors/preflight_cache_unittest.cc
@@ -29,7 +29,7 @@ PreflightCache* cache() { return &cache_; } std::unique_ptr<PreflightResult> CreateEntry() { - return PreflightResult::Create(mojom::FetchCredentialsMode::kInclude, + return PreflightResult::Create(mojom::CredentialsMode::kInclude, std::string("POST"), base::nullopt, std::string("5"), nullptr); } @@ -40,7 +40,7 @@ bool CheckEntryAndRefreshCache(const std::string& origin, const GURL& url) { return cache_.CheckIfRequestCanSkipPreflight( - origin, url, network::mojom::FetchCredentialsMode::kInclude, "POST", + origin, url, network::mojom::CredentialsMode::kInclude, "POST", net::HttpRequestHeaders(), false); }
diff --git a/services/network/public/cpp/cors/preflight_result.cc b/services/network/public/cpp/cors/preflight_result.cc index c3233987..22d7a67 100644 --- a/services/network/public/cpp/cors/preflight_result.cc +++ b/services/network/public/cpp/cors/preflight_result.cc
@@ -84,7 +84,7 @@ // static std::unique_ptr<PreflightResult> PreflightResult::Create( - const mojom::FetchCredentialsMode credentials_mode, + const mojom::CredentialsMode credentials_mode, const base::Optional<std::string>& allow_methods_header, const base::Optional<std::string>& allow_headers_header, const base::Optional<std::string>& max_age_header, @@ -101,9 +101,8 @@ return result; } -PreflightResult::PreflightResult( - const mojom::FetchCredentialsMode credentials_mode) - : credentials_(credentials_mode == mojom::FetchCredentialsMode::kInclude) {} +PreflightResult::PreflightResult(const mojom::CredentialsMode credentials_mode) + : credentials_(credentials_mode == mojom::CredentialsMode::kInclude) {} PreflightResult::~PreflightResult() = default; @@ -162,12 +161,11 @@ } bool PreflightResult::EnsureAllowedRequest( - mojom::FetchCredentialsMode credentials_mode, + mojom::CredentialsMode credentials_mode, const std::string& method, const net::HttpRequestHeaders& headers, bool is_revalidating) const { - if (!credentials_ && - credentials_mode == mojom::FetchCredentialsMode::kInclude) { + if (!credentials_ && credentials_mode == mojom::CredentialsMode::kInclude) { return false; }
diff --git a/services/network/public/cpp/cors/preflight_result.h b/services/network/public/cpp/cors/preflight_result.h index 43a18d2..b87f0e79 100644 --- a/services/network/public/cpp/cors/preflight_result.h +++ b/services/network/public/cpp/cors/preflight_result.h
@@ -38,7 +38,7 @@ // nullptr and |detected_error| is populated with the failed reason if the // passed parameters contain an invalid entry, and the pointer is valid. static std::unique_ptr<PreflightResult> Create( - const mojom::FetchCredentialsMode credentials_mode, + const mojom::CredentialsMode credentials_mode, const base::Optional<std::string>& allow_methods_header, const base::Optional<std::string>& allow_headers_header, const base::Optional<std::string>& max_age_header, @@ -66,7 +66,7 @@ // |headers| is allowed by the CORS-preflight response. // This also does not reject the forbidden headers as // EnsureAllowCrossOriginHeaders does not. - bool EnsureAllowedRequest(mojom::FetchCredentialsMode credentials_mode, + bool EnsureAllowedRequest(mojom::CredentialsMode credentials_mode, const std::string& method, const net::HttpRequestHeaders& headers, bool is_revalidating) const; @@ -78,7 +78,7 @@ base::TimeTicks absolute_expiry_time() const { return absolute_expiry_time_; } protected: - explicit PreflightResult(const mojom::FetchCredentialsMode credentials_mode); + explicit PreflightResult(const mojom::CredentialsMode credentials_mode); base::Optional<mojom::CorsError> Parse( const base::Optional<std::string>& allow_methods_header,
diff --git a/services/network/public/cpp/cors/preflight_result_unittest.cc b/services/network/public/cpp/cors/preflight_result_unittest.cc index cfc53a7..77ed184 100644 --- a/services/network/public/cpp/cors/preflight_result_unittest.cc +++ b/services/network/public/cpp/cors/preflight_result_unittest.cc
@@ -20,128 +20,128 @@ struct TestCase { const std::string allow_methods; const std::string allow_headers; - const mojom::FetchCredentialsMode cache_credentials_mode; + const mojom::CredentialsMode cache_credentials_mode; const std::string request_method; const std::string request_headers; - const mojom::FetchCredentialsMode request_credentials_mode; + const mojom::CredentialsMode request_credentials_mode; const base::Optional<CorsErrorStatus> expected_result; }; const TestCase method_cases[] = { // Found in the preflight response. - {"OPTIONS", "", mojom::FetchCredentialsMode::kOmit, "OPTIONS", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"GET", "", mojom::FetchCredentialsMode::kOmit, "GET", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"HEAD", "", mojom::FetchCredentialsMode::kOmit, "HEAD", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"POST", "", mojom::FetchCredentialsMode::kOmit, "POST", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"PUT", "", mojom::FetchCredentialsMode::kOmit, "PUT", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"DELETE", "", mojom::FetchCredentialsMode::kOmit, "DELETE", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"OPTIONS", "", mojom::CredentialsMode::kOmit, "OPTIONS", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"GET", "", mojom::CredentialsMode::kOmit, "GET", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"HEAD", "", mojom::CredentialsMode::kOmit, "HEAD", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"POST", "", mojom::CredentialsMode::kOmit, "POST", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"PUT", "", mojom::CredentialsMode::kOmit, "PUT", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"DELETE", "", mojom::CredentialsMode::kOmit, "DELETE", "", + mojom::CredentialsMode::kOmit, base::nullopt}, // Found in the safe list. - {"", "", mojom::FetchCredentialsMode::kOmit, "GET", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"", "", mojom::FetchCredentialsMode::kOmit, "HEAD", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"", "", mojom::FetchCredentialsMode::kOmit, "POST", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"", "", mojom::CredentialsMode::kOmit, "GET", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"", "", mojom::CredentialsMode::kOmit, "HEAD", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"", "", mojom::CredentialsMode::kOmit, "POST", "", + mojom::CredentialsMode::kOmit, base::nullopt}, // By '*'. - {"*", "", mojom::FetchCredentialsMode::kOmit, "OPTIONS", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"*", "", mojom::CredentialsMode::kOmit, "OPTIONS", "", + mojom::CredentialsMode::kOmit, base::nullopt}, // Cache allowing multiple methods. - {"GET, PUT, DELETE", "", mojom::FetchCredentialsMode::kOmit, "GET", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"GET, PUT, DELETE", "", mojom::FetchCredentialsMode::kOmit, "PUT", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"GET, PUT, DELETE", "", mojom::FetchCredentialsMode::kOmit, "DELETE", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"GET, PUT, DELETE", "", mojom::CredentialsMode::kOmit, "GET", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"GET, PUT, DELETE", "", mojom::CredentialsMode::kOmit, "PUT", "", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"GET, PUT, DELETE", "", mojom::CredentialsMode::kOmit, "DELETE", "", + mojom::CredentialsMode::kOmit, base::nullopt}, // Not found in the preflight response and the safe lit. - {"", "", mojom::FetchCredentialsMode::kOmit, "OPTIONS", "", - mojom::FetchCredentialsMode::kOmit, + {"", "", mojom::CredentialsMode::kOmit, "OPTIONS", "", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kMethodDisallowedByPreflightResponse, "OPTIONS")}, - {"", "", mojom::FetchCredentialsMode::kOmit, "PUT", "", - mojom::FetchCredentialsMode::kOmit, + {"", "", mojom::CredentialsMode::kOmit, "PUT", "", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kMethodDisallowedByPreflightResponse, "PUT")}, - {"", "", mojom::FetchCredentialsMode::kOmit, "DELETE", "", - mojom::FetchCredentialsMode::kOmit, + {"", "", mojom::CredentialsMode::kOmit, "DELETE", "", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kMethodDisallowedByPreflightResponse, "DELETE")}, - {"GET", "", mojom::FetchCredentialsMode::kOmit, "PUT", "", - mojom::FetchCredentialsMode::kOmit, + {"GET", "", mojom::CredentialsMode::kOmit, "PUT", "", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kMethodDisallowedByPreflightResponse, "PUT")}, - {"GET, POST, DELETE", "", mojom::FetchCredentialsMode::kOmit, "PUT", "", - mojom::FetchCredentialsMode::kOmit, + {"GET, POST, DELETE", "", mojom::CredentialsMode::kOmit, "PUT", "", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kMethodDisallowedByPreflightResponse, "PUT")}, // Request method is normalized to upper-case, but allowed methods is not. // Comparison is in case-sensitive, that means allowed methods should be in // upper case. - {"put", "", mojom::FetchCredentialsMode::kOmit, "PUT", "", - mojom::FetchCredentialsMode::kOmit, + {"put", "", mojom::CredentialsMode::kOmit, "PUT", "", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kMethodDisallowedByPreflightResponse, "PUT")}, - {"put", "", mojom::FetchCredentialsMode::kOmit, "put", "", - mojom::FetchCredentialsMode::kOmit, + {"put", "", mojom::CredentialsMode::kOmit, "put", "", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kMethodDisallowedByPreflightResponse, "put")}, - {"PUT", "", mojom::FetchCredentialsMode::kOmit, "put", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"PUT", "", mojom::CredentialsMode::kOmit, "put", "", + mojom::CredentialsMode::kOmit, base::nullopt}, // ... But, GET is always allowed by the safe list. - {"get", "", mojom::FetchCredentialsMode::kOmit, "GET", "", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"get", "", mojom::CredentialsMode::kOmit, "GET", "", + mojom::CredentialsMode::kOmit, base::nullopt}, }; const TestCase header_cases[] = { // Found in the preflight response. - {"GET", "X-MY-HEADER", mojom::FetchCredentialsMode::kOmit, "GET", - "X-MY-HEADER:t", mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"GET", "X-MY-HEADER, Y-MY-HEADER", mojom::FetchCredentialsMode::kOmit, - "GET", "X-MY-HEADER:t\r\nY-MY-HEADER:t", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"GET", "x-my-header, Y-MY-HEADER", mojom::FetchCredentialsMode::kOmit, - "GET", "X-MY-HEADER:t\r\ny-my-header:t", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"GET", "X-MY-HEADER", mojom::CredentialsMode::kOmit, "GET", + "X-MY-HEADER:t", mojom::CredentialsMode::kOmit, base::nullopt}, + {"GET", "X-MY-HEADER, Y-MY-HEADER", mojom::CredentialsMode::kOmit, "GET", + "X-MY-HEADER:t\r\nY-MY-HEADER:t", mojom::CredentialsMode::kOmit, + base::nullopt}, + {"GET", "x-my-header, Y-MY-HEADER", mojom::CredentialsMode::kOmit, "GET", + "X-MY-HEADER:t\r\ny-my-header:t", mojom::CredentialsMode::kOmit, + base::nullopt}, // Found in the safe list. - {"GET", "", mojom::FetchCredentialsMode::kOmit, "GET", "Accept:*/*", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"GET", "", mojom::CredentialsMode::kOmit, "GET", "Accept:*/*", + mojom::CredentialsMode::kOmit, base::nullopt}, // By '*'. - {"GET", "*", mojom::FetchCredentialsMode::kOmit, "GET", "xyzzy:t", - mojom::FetchCredentialsMode::kOmit, base::nullopt}, - {"GET", "*", mojom::FetchCredentialsMode::kInclude, "GET", "xyzzy:t", - mojom::FetchCredentialsMode::kOmit, + {"GET", "*", mojom::CredentialsMode::kOmit, "GET", "xyzzy:t", + mojom::CredentialsMode::kOmit, base::nullopt}, + {"GET", "*", mojom::CredentialsMode::kInclude, "GET", "xyzzy:t", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kHeaderDisallowedByPreflightResponse, "xyzzy")}, // Forbidden headers can pass. - {"GET", "", mojom::FetchCredentialsMode::kOmit, "GET", - "Host: www.google.com", mojom::FetchCredentialsMode::kOmit, base::nullopt}, + {"GET", "", mojom::CredentialsMode::kOmit, "GET", "Host: www.google.com", + mojom::CredentialsMode::kOmit, base::nullopt}, // Not found in the preflight response and the safe list. - {"GET", "", mojom::FetchCredentialsMode::kOmit, "GET", "X-MY-HEADER:t", - mojom::FetchCredentialsMode::kOmit, + {"GET", "", mojom::CredentialsMode::kOmit, "GET", "X-MY-HEADER:t", + mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kHeaderDisallowedByPreflightResponse, "x-my-header")}, - {"GET", "X-SOME-OTHER-HEADER", mojom::FetchCredentialsMode::kOmit, "GET", - "X-MY-HEADER:t", mojom::FetchCredentialsMode::kOmit, + {"GET", "X-SOME-OTHER-HEADER", mojom::CredentialsMode::kOmit, "GET", + "X-MY-HEADER:t", mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kHeaderDisallowedByPreflightResponse, "x-my-header")}, - {"GET", "X-MY-HEADER", mojom::FetchCredentialsMode::kOmit, "GET", - "X-MY-HEADER:t\r\nY-MY-HEADER:t", mojom::FetchCredentialsMode::kOmit, + {"GET", "X-MY-HEADER", mojom::CredentialsMode::kOmit, "GET", + "X-MY-HEADER:t\r\nY-MY-HEADER:t", mojom::CredentialsMode::kOmit, CorsErrorStatus(mojom::CorsError::kHeaderDisallowedByPreflightResponse, "y-my-header")}, }; @@ -152,7 +152,7 @@ PreflightResult::SetTickClockForTesting(tick_clock.get()); std::unique_ptr<PreflightResult> result1 = - PreflightResult::Create(mojom::FetchCredentialsMode::kOmit, base::nullopt, + PreflightResult::Create(mojom::CredentialsMode::kOmit, base::nullopt, base::nullopt, std::string("573"), nullptr); EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSeconds(573), result1->absolute_expiry_time()); @@ -161,7 +161,7 @@ // should not cache such results. PreflightResult expresses it as a result // with 'Access-Control-Max-Age: 0'. std::unique_ptr<PreflightResult> result2 = - PreflightResult::Create(mojom::FetchCredentialsMode::kOmit, base::nullopt, + PreflightResult::Create(mojom::CredentialsMode::kOmit, base::nullopt, base::nullopt, std::string("-765"), nullptr); EXPECT_EQ(base::TimeTicks(), result2->absolute_expiry_time()); @@ -222,21 +222,18 @@ } struct { - const mojom::FetchCredentialsMode cache_credentials_mode; - const mojom::FetchCredentialsMode request_credentials_mode; + const mojom::CredentialsMode cache_credentials_mode; + const mojom::CredentialsMode request_credentials_mode; const bool expected_result; } credentials_cases[] = { // Different credential modes. - {mojom::FetchCredentialsMode::kInclude, - mojom::FetchCredentialsMode::kOmit, true}, - {mojom::FetchCredentialsMode::kInclude, - mojom::FetchCredentialsMode::kInclude, true}, + {mojom::CredentialsMode::kInclude, mojom::CredentialsMode::kOmit, true}, + {mojom::CredentialsMode::kInclude, mojom::CredentialsMode::kInclude, + true}, // Credential mode mismatch. - {mojom::FetchCredentialsMode::kOmit, mojom::FetchCredentialsMode::kOmit, - true}, - {mojom::FetchCredentialsMode::kOmit, - mojom::FetchCredentialsMode::kInclude, false}, + {mojom::CredentialsMode::kOmit, mojom::CredentialsMode::kOmit, true}, + {mojom::CredentialsMode::kOmit, mojom::CredentialsMode::kInclude, false}, }; for (const auto& test : credentials_cases) {
diff --git a/services/network/public/cpp/network_ipc_param_traits.h b/services/network/public/cpp/network_ipc_param_traits.h index 274fbb0..237928e 100644 --- a/services/network/public/cpp/network_ipc_param_traits.h +++ b/services/network/public/cpp/network_ipc_param_traits.h
@@ -94,14 +94,14 @@ IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::CorsError, network::mojom::CorsError::kMaxValue) -IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchCredentialsMode, - network::mojom::FetchCredentialsMode::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::CredentialsMode, + network::mojom::CredentialsMode::kMaxValue) -IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchRedirectMode, - network::mojom::FetchRedirectMode::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::RedirectMode, + network::mojom::RedirectMode::kMaxValue) -IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchRequestMode, - network::mojom::FetchRequestMode::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::RequestMode, + network::mojom::RequestMode::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::CorsPreflightPolicy, network::mojom::CorsPreflightPolicy::kMaxValue)
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc index d1fe50a..738a7d0 100644 --- a/services/network/public/cpp/resource_request.cc +++ b/services/network/public/cpp/resource_request.cc
@@ -39,10 +39,9 @@ request.originated_from_service_worker && skip_service_worker == request.skip_service_worker && corb_detachable == request.corb_detachable && - corb_excluded == request.corb_excluded && - fetch_request_mode == request.fetch_request_mode && - fetch_credentials_mode == request.fetch_credentials_mode && - fetch_redirect_mode == request.fetch_redirect_mode && + corb_excluded == request.corb_excluded && mode == request.mode && + credentials_mode == request.credentials_mode && + redirect_mode == request.redirect_mode && fetch_integrity == request.fetch_integrity && fetch_request_context_type == request.fetch_request_context_type && request_body == request.request_body &&
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h index c2f7bf44..ffcdef9e2 100644 --- a/services/network/public/cpp/resource_request.h +++ b/services/network/public/cpp/resource_request.h
@@ -63,11 +63,9 @@ bool skip_service_worker = false; bool corb_detachable = false; bool corb_excluded = false; - mojom::FetchRequestMode fetch_request_mode = mojom::FetchRequestMode::kNoCors; - mojom::FetchCredentialsMode fetch_credentials_mode = - mojom::FetchCredentialsMode::kInclude; - mojom::FetchRedirectMode fetch_redirect_mode = - mojom::FetchRedirectMode::kFollow; + mojom::RequestMode mode = mojom::RequestMode::kNoCors; + mojom::CredentialsMode credentials_mode = mojom::CredentialsMode::kInclude; + mojom::RedirectMode redirect_mode = mojom::RedirectMode::kFollow; std::string fetch_integrity; int fetch_request_context_type = 0; scoped_refptr<ResourceRequestBody> request_body;
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc index 727c784..3e7a2c5 100644 --- a/services/network/public/cpp/url_request_mojom_traits.cc +++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -165,9 +165,9 @@ !data.ReadCorsExemptHeaders(&out->cors_exempt_headers) || !data.ReadPriority(&out->priority) || !data.ReadCorsPreflightPolicy(&out->cors_preflight_policy) || - !data.ReadFetchRequestMode(&out->fetch_request_mode) || - !data.ReadFetchCredentialsMode(&out->fetch_credentials_mode) || - !data.ReadFetchRedirectMode(&out->fetch_redirect_mode) || + !data.ReadMode(&out->mode) || + !data.ReadCredentialsMode(&out->credentials_mode) || + !data.ReadRedirectMode(&out->redirect_mode) || !data.ReadFetchIntegrity(&out->fetch_integrity) || !data.ReadRequestBody(&out->request_body) || !data.ReadThrottlingProfileId(&out->throttling_profile_id) ||
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h index ced5daa8..8247516 100644 --- a/services/network/public/cpp/url_request_mojom_traits.h +++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -132,17 +132,17 @@ static bool corb_excluded(const network::ResourceRequest& request) { return request.corb_excluded; } - static network::mojom::FetchRequestMode fetch_request_mode( + static network::mojom::RequestMode mode( const network::ResourceRequest& request) { - return request.fetch_request_mode; + return request.mode; } - static network::mojom::FetchCredentialsMode fetch_credentials_mode( + static network::mojom::CredentialsMode credentials_mode( const network::ResourceRequest& request) { - return request.fetch_credentials_mode; + return request.credentials_mode; } - static network::mojom::FetchRedirectMode fetch_redirect_mode( + static network::mojom::RedirectMode redirect_mode( const network::ResourceRequest& request) { - return request.fetch_redirect_mode; + return request.redirect_mode; } static const std::string& fetch_integrity( const network::ResourceRequest& request) {
diff --git a/services/network/public/cpp/url_request_mojom_traits_unittest.cc b/services/network/public/cpp/url_request_mojom_traits_unittest.cc index da9f850..26a8a8f 100644 --- a/services/network/public/cpp/url_request_mojom_traits_unittest.cc +++ b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
@@ -70,9 +70,9 @@ mojom::CorsPreflightPolicy::kConsiderPreflight; original.originated_from_service_worker = false; original.skip_service_worker = false; - original.fetch_request_mode = mojom::FetchRequestMode::kNoCors; - original.fetch_credentials_mode = mojom::FetchCredentialsMode::kInclude; - original.fetch_redirect_mode = mojom::FetchRedirectMode::kFollow; + original.mode = mojom::RequestMode::kNoCors; + original.credentials_mode = mojom::CredentialsMode::kInclude; + original.redirect_mode = mojom::RedirectMode::kFollow; original.fetch_integrity = "dummy_fetch_integrity"; original.fetch_request_context_type = 0; original.keepalive = true;
diff --git a/services/network/public/mojom/fetch_api.mojom b/services/network/public/mojom/fetch_api.mojom index 548d07a4..7d72e81 100644 --- a/services/network/public/mojom/fetch_api.mojom +++ b/services/network/public/mojom/fetch_api.mojom
@@ -8,8 +8,8 @@ // https://fetch.spec.whatwg.org/#concept-request-mode // // This enum is also used in histograms. Append-only. -// See the "FetchRequestMode" enum in enums.xml. -enum FetchRequestMode { +// See the "RequestMode" enum in enums.xml. +enum RequestMode { kSameOrigin, kNoCors, kCors, @@ -20,7 +20,7 @@ // Corresponds to Fetch request's "redirect mode": // https://fetch.spec.whatwg.org/#concept-request-redirect-mode -enum FetchRedirectMode { +enum RedirectMode { kFollow, kError, kManual, @@ -28,7 +28,7 @@ // Corresponds to Fetch request's "credentials mode": // https://fetch.spec.whatwg.org/#concept-request-credentials-mode -enum FetchCredentialsMode { +enum CredentialsMode { kOmit, kSameOrigin, kInclude,
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom index df9db84..9c5238d2d 100644 --- a/services/network/public/mojom/url_loader.mojom +++ b/services/network/public/mojom/url_loader.mojom
@@ -202,7 +202,7 @@ // TODO(lukasza): https://crbug.com/846339: Remove the field below and instead // make plugins use a separate URLoaderFactory. Note requests of this type are - // only excluded if fetch_request_mode is kNoCors. + // only excluded if mode is kNoCors. bool corb_excluded = false; // https://fetch.spec.whatwg.org/#concept-request-mode @@ -210,18 +210,18 @@ // CORS handling needs a proper origin (including a unique opaque origin). // Hence a request with kSameOrigin, kCors, or kCorsWithForcedPreflight should // have a non-null request_initiator. - FetchRequestMode fetch_request_mode; + RequestMode mode; // https://fetch.spec.whatwg.org/#concept-request-credentials-mode // Used mainly by CORS handling (out-of-blink CORS), Service Worker. // If this member is kOmit, then DO_NOT_SAVE_COOKIES, DO_NOT_SEND_COOKIES, // and DO_NOT_SEND_AUTH_DATA must be set on load_flags. - FetchCredentialsMode fetch_credentials_mode; + CredentialsMode credentials_mode; // https://fetch.spec.whatwg.org/#concept-request-redirect-mode // Used mainly by CORS handling (out-of-blink CORS), Service Worker. - // This member must be kFollow as long as |fetch_request_mode| is kNoCors. - FetchRedirectMode fetch_redirect_mode; + // This member must be kFollow as long as |mode| is kNoCors. + RedirectMode redirect_mode; // The integrity used in Fetch API. string fetch_integrity;
diff --git a/services/network/public/mojom/websocket.mojom b/services/network/public/mojom/websocket.mojom index a568244e..3ac27f7 100644 --- a/services/network/public/mojom/websocket.mojom +++ b/services/network/public/mojom/websocket.mojom
@@ -62,7 +62,13 @@ // Response to an AddChannelRequest. |selected_protocol| is the sub-protocol // the server selected, or empty if no sub-protocol was selected. // |extensions| is the list of extensions negotiated for the connection. - OnAddChannelResponse(string selected_protocol, string extensions); + // default threshold value + // |receive_quota_threshold| is the value that the renderer calls + // AddReceiveFlowControlQuota() to the browser per receiving this value + // so that the browser can continue sending remaining data to the renderer. + OnAddChannelResponse(string selected_protocol, + string extensions, + uint64 receive_quota_threshold); }; interface WebSocketClient {
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index a5822961..d8ede8d 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -409,11 +409,10 @@ std::make_unique<UnownedPointer>(this)); is_nocors_corb_excluded_request_ = - request.corb_excluded && - request.fetch_request_mode == mojom::FetchRequestMode::kNoCors && + request.corb_excluded && request.mode == mojom::RequestMode::kNoCors && CrossOriginReadBlocking::ShouldAllowForPlugin( factory_params_->process_id); - fetch_request_mode_ = request.fetch_request_mode; + request_mode_ = request.mode; throttling_token_ = network::ScopedThrottlingToken::MaybeCreate( url_request_->net_log().source().id, request.throttling_profile_id); @@ -751,7 +750,7 @@ if (CrossOriginResourcePolicy::kBlock == CrossOriginResourcePolicy::Verify( url_request_->url(), url_request_->initiator(), response->head, - fetch_request_mode_, factory_params_->request_initiator_site_lock)) { + request_mode_, factory_params_->request_initiator_site_lock)) { CompleteBlockedResponse(net::ERR_BLOCKED_BY_RESPONSE, false); DeleteSelf(); return; @@ -910,7 +909,7 @@ if (CrossOriginResourcePolicy::kBlock == CrossOriginResourcePolicy::Verify( url_request_->url(), url_request_->initiator(), response_->head, - fetch_request_mode_, factory_params_->request_initiator_site_lock)) { + request_mode_, factory_params_->request_initiator_site_lock)) { CompleteBlockedResponse(net::ERR_BLOCKED_BY_RESPONSE, false); DeleteSelf(); return; @@ -925,7 +924,7 @@ corb_analyzer_ = std::make_unique<CrossOriginReadBlocking::ResponseAnalyzer>( url_request_->url(), url_request_->initiator(), response_->head, - factory_params_->request_initiator_site_lock, fetch_request_mode_); + factory_params_->request_initiator_site_lock, request_mode_); is_more_corb_sniffing_needed_ = corb_analyzer_->needs_sniffing(); if (corb_analyzer_->ShouldBlock()) { DCHECK(!is_more_corb_sniffing_needed_);
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 3c8f97ec..1af2ea53 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -325,7 +325,7 @@ // CORB-excluded requests must be blocked if the CORS check fails. bool is_nocors_corb_excluded_request_ = false; - mojom::FetchRequestMode fetch_request_mode_; + mojom::RequestMode request_mode_; scoped_refptr<ResourceSchedulerClient> resource_scheduler_client_;
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index b342d64..0786f2e 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -1896,38 +1896,47 @@ EXPECT_EQ("Value3", request_headers2.find("Header3")->second); } -// Make sure requests are failed when the consumer tries to modify the host -// header. -TEST_F(URLLoaderTest, RedirectFailsOnModifyHostHeader) { - ResourceRequest request = CreateResourceRequest( - "GET", test_server()->GetURL("/redirect307-to-echo")); +TEST_F(URLLoaderTest, RedirectFailsOnModifyUnsafeHeader) { + const char* kUnsafeHeaders[] = { + net::HttpRequestHeaders::kContentLength, + net::HttpRequestHeaders::kHost, + net::HttpRequestHeaders::kProxyConnection, + net::HttpRequestHeaders::kProxyAuthorization, + "Proxy-Foo", + }; - base::RunLoop delete_run_loop; - mojom::URLLoaderPtr loader; - std::unique_ptr<URLLoader> url_loader; - mojom::URLLoaderFactoryParams params; - params.process_id = mojom::kBrowserProcessId; - params.is_corb_enabled = false; - url_loader = std::make_unique<URLLoader>( - context(), nullptr /* network_service_client */, - DeleteLoaderCallback(&delete_run_loop, &url_loader), - mojo::MakeRequest(&loader), mojom::kURLLoadOptionNone, request, - client()->CreateInterfacePtr(), TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, - 0 /* request_id */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */); + for (const auto* unsafe_header : kUnsafeHeaders) { + TestURLLoaderClient client; - client()->RunUntilRedirectReceived(); + ResourceRequest request = CreateResourceRequest( + "GET", test_server()->GetURL("/redirect307-to-echo")); - net::HttpRequestHeaders redirect_headers; - redirect_headers.SetHeader(net::HttpRequestHeaders::kHost, "foo.test"); - loader->FollowRedirect({}, redirect_headers, base::nullopt); + base::RunLoop delete_run_loop; + mojom::URLLoaderPtr loader; + std::unique_ptr<URLLoader> url_loader; + mojom::URLLoaderFactoryParams params; + params.process_id = mojom::kBrowserProcessId; + params.is_corb_enabled = false; + url_loader = std::make_unique<URLLoader>( + context(), nullptr /* network_service_client */, + DeleteLoaderCallback(&delete_run_loop, &url_loader), + mojo::MakeRequest(&loader), mojom::kURLLoadOptionNone, request, + client.CreateInterfacePtr(), TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, + 0 /* request_id */, resource_scheduler_client(), nullptr, + nullptr /* network_usage_accumulator */, nullptr /* header_client */); - client()->RunUntilComplete(); - delete_run_loop.Run(); + client.RunUntilRedirectReceived(); - EXPECT_TRUE(client()->has_received_completion()); - EXPECT_EQ(net::ERR_INVALID_ARGUMENT, - client()->completion_status().error_code); + net::HttpRequestHeaders redirect_headers; + redirect_headers.SetHeader(unsafe_header, "foo"); + loader->FollowRedirect({}, redirect_headers, base::nullopt); + + client.RunUntilComplete(); + delete_run_loop.Run(); + + EXPECT_TRUE(client.has_received_completion()); + EXPECT_EQ(net::ERR_INVALID_ARGUMENT, client.completion_status().error_code); + } } // Test the client can remove headers during a redirect. @@ -2784,7 +2793,7 @@ ResourceRequest request = CreateResourceRequest("GET", test_server()->GetURL("/hello.html")); request.resource_type = kResourceType; - request.fetch_request_mode = mojom::FetchRequestMode::kCors; + request.mode = mojom::RequestMode::kCors; request.request_initiator = url::Origin::Create(GURL("http://foo.com/")); request.corb_excluded = true; @@ -2820,7 +2829,7 @@ ResourceRequest request = CreateResourceRequest("GET", test_server()->GetURL("/hello.html")); request.resource_type = kResourceType; - request.fetch_request_mode = mojom::FetchRequestMode::kNoCors; + request.mode = mojom::RequestMode::kNoCors; request.request_initiator = url::Origin::Create(GURL("http://foo.com/")); request.corb_excluded = true; @@ -2860,7 +2869,7 @@ ResourceRequest request = CreateResourceRequest("GET", test_server()->GetURL("/hello.html")); request.resource_type = kResourceType; - request.fetch_request_mode = mojom::FetchRequestMode::kNoCors; + request.mode = mojom::RequestMode::kNoCors; request.request_initiator = url::Origin::Create(GURL("http://foo.com/")); request.corb_excluded = true;
diff --git a/services/network/websocket.cc b/services/network/websocket.cc index b863f9b..5b4c0ec 100644 --- a/services/network/websocket.cc +++ b/services/network/websocket.cc
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/single_thread_task_runner.h" #include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" @@ -27,6 +28,7 @@ #include "net/http/http_response_headers.h" #include "net/http/http_util.h" #include "net/ssl/ssl_info.h" +#include "net/websockets/websocket_basic_stream.h" #include "net/websockets/websocket_channel.h" #include "net/websockets/websocket_errors.h" #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode @@ -147,7 +149,20 @@ impl_->handshake_succeeded_ = true; impl_->pending_connection_tracker_.OnCompleteHandshake(); - impl_->handshake_client_->OnAddChannelResponse(selected_protocol, extensions); + base::CommandLine* const command_line = + base::CommandLine::ForCurrentProcess(); + DCHECK(command_line); + uint64_t receive_quota_threshold = + net::WebSocketChannel::kReceiveQuotaThreshold; + if (command_line->HasSwitch(net::kWebSocketReceiveQuotaThreshold)) { + std::string flag_string = + command_line->GetSwitchValueASCII(net::kWebSocketReceiveQuotaThreshold); + if (!base::StringToUint64(flag_string, &receive_quota_threshold)) + receive_quota_threshold = net::WebSocketChannel::kReceiveQuotaThreshold; + } + DVLOG(3) << "receive_quota_threshold is " << receive_quota_threshold; + impl_->handshake_client_->OnAddChannelResponse(selected_protocol, extensions, + receive_quota_threshold); } void WebSocket::WebSocketEventHandler::OnDataFrame(
diff --git a/storage/browser/quota/quota_manager_unittest.cc b/storage/browser/quota/quota_manager_unittest.cc index 27856ee..e40d4cb 100644 --- a/storage/browser/quota/quota_manager_unittest.cc +++ b/storage/browser/quota/quota_manager_unittest.cc
@@ -460,7 +460,6 @@ const blink::mojom::UsageBreakdown& usage_breakdown() const { return *usage_breakdown_; } - int64_t limited_usage() const { return limited_usage_; } int64_t unlimited_usage() const { return unlimited_usage_; } int64_t quota() const { return quota_; } int64_t total_space() const { return total_space_; } @@ -500,7 +499,6 @@ UsageInfoEntries usage_info_; int64_t usage_; blink::mojom::UsageBreakdownPtr usage_breakdown_; - int64_t limited_usage_; int64_t unlimited_usage_; int64_t quota_; int64_t total_space_;
diff --git a/styleguide/c++/c++11.html b/styleguide/c++/c++11.html index 17973a0..9fbb544f 100644 --- a/styleguide/c++/c++11.html +++ b/styleguide/c++/c++11.html
@@ -18,19 +18,21 @@ </head> <body> <div id="content"> -<h1>C++11 and C++14 use in Chromium</h1> +<h1>C++ use in Chromium</h1> <p><i>This document lives at src/styleguide/c++/c++11.html in a Chromium checkout and is part of the more general <a href="https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md"> -Chromium C++ style guide</a>.</i></p> +Chromium C++ style guide</a>. It summarizes the supported state of new and +updated language and library features in recent C++ standards. This guide +applies to both Chromium and its subprojects, though subprojects can choose to +be more restrictive if necessary for toolchain support.</i></p> -<p>This summarizes the new and updated features in C++11 and C++14 (for both -the language itself and the Standard Library) from the perspective of what's -allowed in Chromium. When applicable, it contains pointers to more detailed -information. This Guide applies to Chromium and its subprojects, though -subprojects can choose to be more restrictive if necessary for toolchain -support.</p> +<p>The C++ language has in recent years received an updated standard every three +years (C++11, C++14, C++17). For various reasons, Chromium does not immediately +allow new features on the publication of such a standard. Instead, once +toolchain support is sufficient, a standard is declared "initially supported", +with new language/library features banned pending discussion.</p> <p>You can propose changing the status of a feature by sending an email to <a href="https://groups.google.com/a/chromium.org/forum/#!forum/cxx"> @@ -39,22 +41,28 @@ previous discussion. If the list arrives at some consensus, send a codereview to change this file accordingly, linking to your discussion thread.</p> +<p>Two years after a standard is initially supported in Chromium, style arbiters +should make a final decision on any remaining TBD features to be banned, then +default-allow all non-banned portions of the standard. The current status of +existing standards is: +<ul><li><b>C++11:</b> <i>Default allowed; see banned features below</i></li> +<li><b>C++14:</b> <i>Initially supported August 15, 2017; see allowed/banned/TBD features below</i></li> +<li><b>C++17:</b> <i>Not yet supported in Chromium</i></li> +<li><b>C++20:</b> <i>Not yet standardized</i></li></ul></p> + <h2>Table of Contents</h2> <ol class="toc"> <li>Allowed Features<ol> <li>Language - <a href="#core-whitelist">C++11</a> <a href="#core-whitelist-14">C++14</a> </li> <li>Library - <a href="#library-whitelist">C++11</a> <a href="#library-whitelist-14">C++14</a> </li> </ol></li> <li>Banned Features<ol> <li>Language <a href="#core-blocklist">C++11</a> - <a href="#core-blocklist-14">C++14</a> </li> <li>Library <a href="#library-blocklist">C++11</a> @@ -63,321 +71,17 @@ </ol></li> <li>To Be Discussed<ol> <li>Language - <a href="#core-review">C++11</a> <a href="#core-review-14">C++14</a> </li> <li>Library - <a href="#library-review">C++11</a> <a href="#library-review-14">C++14</a> </li> </ol></li> </ol> -<h2 id="whitelist"><a name="core-whitelist"></a>C++11 Allowed Features</h2> +<h2 id="whitelist"><a name="core-whitelist-14"></a>C++14 Allowed Language Features</h2> -<p>The following features are currently allowed.</p> - -<table id="whitelist_lang_list" class="unlined striped"> -<tbody> - -<tr> -<th style='width:220px;'>Feature</th> -<th style='width:260px;'>Snippet</th> -<th style='width:240px;'>Description</th> -<th style='width:240px;'>Documentation Link</th> -<th style='width:240px;'>Notes and Discussion Thread</th> -</tr> - -<tr> -<td>__func__ Local Variable</td> -<td><code>__func__</code></td> -<td>Provides a local variable containing the name of the enclosing function</td> -<td><a href="http://en.cppreference.com/w/cpp/language/function#func">__func__</a></td> -<td>Use instead of the non-standard <code>__FUNCTION__</code>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/ojGfcgSDzHM">Discussion thread</a></td> -</tr> - -<tr> -<td>Alignment Features</td> -<td><code>alignas(alignof(T)) char[10];</code></td> -<td>Specifies or queries storage alignment.</td> -<td><a href="http://en.cppreference.com/w/chttp://en.cppreference.com/w/cpp/language/alignas">alignas</a>, <a href="http://en.cppreference.com/w/cpp/language/alignof">alignof</a></td> -<td><code>alignof()</code> can be used. <code>alignas()</code> must be used with care because it does not interact well with export and packing specifiers. If your declaration contains any other attributes, use <code>ALIGNAS()</code> from <code>base/compiler_specific.h</code> instead. <a href="https://codereview.chromium.org/2670873002/">Patch where this was discussed</a></td> -</tr> - -<tr> -<td>Angle Bracket Parsing in Templates</td> -<td><code>>></code> for <code>> ></code>, <code><::</code> for <code>< ::</code></td> -<td>More intuitive parsing of template parameters</td> -<td><a href="http://stackoverflow.com/questions/15785496/c-templates-angle-brackets-pitfall-what-is-the-c11-fix">C++ templates angle brackets pitfall</a></td> -<td>Recommended to increase readability. Approved without discussion.</td> -</tr> - -<tr> -<td>Arrays</td> -<td><code>std::array</code></td> -<td>A fixed-size replacement for built-in arrays, with STL support</td> -<td><a href="http://en.cppreference.com/w/cpp/container/array">std::array</a></td> -<td>Useful in performance-critical situations, with small, fixed-size arrays. In most cases, consider std::vector instead. std::vector is cheaper to std::move and is more widely used. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/pVRQCRWHEU8">Discussion thread</a></td> -</tr> - -<tr> -<td>Automatic Types</td> -<td><code>auto</code></td> -<td>Automatic type deduction</td> -<td><a href="http://en.cppreference.com/w/cpp/language/auto">auto specifier</a></td> -<td>General guidance in <a href="https://google.github.io/styleguide/cppguide.html#auto">Google Style Guide</a>. Additionally, do not use <code>auto</code> to deduce a raw pointer, use <code>auto*</code> instead. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/OQyYSfH9m2M">Discussion thread</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/5-Bt3BJzAo0">Another discussion thread</a></td> -</tr> - -<tr> -<td>Constant Expressions</td> -<td><code>constexpr</code></td> -<td>Compile-time constant expressions</td> -<td><a href="http://en.cppreference.com/w/cpp/language/constexpr">constexpr specifier</a></td> -<td>Prefer to <code>const</code> for variables where possible. Use cautiously on functions. Don't go out of the way to convert existing code. <a href="https://google.github.io/styleguide/cppguide.html#Use_of_constexpr">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/BE9xLUI-Vww">Discussion thread</a></td> -</tr> - -<tr> -<td>Declared Type Accessor</td> -<td><code>decltype(<i>expression</i>)</code></td> -<td>Provides a means to determine the type of an expression at compile-time, useful most often in templates.</td> -<td><a href="http://en.cppreference.com/w/cpp/language/decltype">decltype specifier</a></td> -<td>Usage should be rare. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/_zoNvZd_dSo">Discussion thread</a></td> -</tr> - -<tr> -<td>Default Function Creation</td> -<td><code><i>Function</i>(<i>arguments</i>) = default;</code></td> -<td>Instructs the compiler to generate a default version of the indicated function</td> -<td><a href="http://stackoverflow.com/questions/823935/whats-the-point-in-defaulting-functions-in-c11">What's the point in defaulting functions in C++11?</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/qgU4mh_MpGA">Discussion thread</a></td> -</tr> - -<tr> -<td>Default Function Template Arguments</td> -<td><code>template <typename T = <i>type</i>><br /> -<i>type</i> <i>Function</i>(T <i>var</i>) {}</code></td> -<td>Allow function templates, like classes, to have default arguments</td> -<td><a href="http://stackoverflow.com/questions/2447458/default-template-arguments-for-function-templates">Default Template Arguments for Function Templates</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/9KtaAsome-o">Discussion thread</a></td> -</tr> - -<tr> -<td>Delegated Constructors</td> -<td><code>Class() : Class(0) {}<br /> -Class(<i>type</i> <i>var</i>) : Class(<i>var</i>, 0) {}</code></td> -<td>Allow overloaded constructors to use common initialization code</td> -<td><a href="https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/introduction_to_the_c_11_feature_delegating_constructors?lang=en">Introduction to the C++11 feature: delegating constructors</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/0zVA8Ctx3Xo">Discussion thread</a></td> -</tr> - -<tr> -<td>Enumerated Type Classes and Enum Bases</td> -<td><code>enum class <i>classname</i><br /> -enum class <i>classname</i> : <i>base-type</i><br /> -enum <i>enumname</i> : <i>base-type</i></code></td> -<td>Provide enums as full classes, with no implicit conversion to booleans or integers. Provide an explicit underlying type for enum classes and regular enums.</td> -<td><a href="http://en.cppreference.com/w/cpp/language/enum">enumeration declaration</a></td> -<td>Enum classes are still enums and follow enum naming rules. <a href="https://google.github.io/styleguide/cppguide.html#Enumerator_Names">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/Q5WmkAImanc">Discussion thread</a></td> -</tr> - -<tr> -<td>Explicit Conversion Operators</td> -<td><code>explicit operator <i>type</i>() { ... }</code></td> -<td>Allows conversion operators that cannot be implicitly invoked</td> -<td><a href="http://en.cppreference.com/w/cpp/language/explicit">explicit specifier</a></td> -<td>Prefer to the "safe bool" idiom. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/zGF1SrQ-1HQ">Discussion thread</a></td> -</tr> - -<tr> -<td>Final Specifier</td> -<td><code>final</code></td> -<td> Indicates that a class or function is final and cannot be overridden</td> -<td><a href="http://en.cppreference.com/w/cpp/language/final">final specifier</a></td> -<td>Recommended for new code. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/VTNZzizN0zo">Discussion thread</a></td> -</tr> - -<tr> -<td>Function Suppression</td> -<td><code><i>Function</i>(<i>arguments</i>) = delete;</code></td> -<td>Suppresses the implementation of a function, especially a synthetic function such as a copy constructor</td> -<td><a href="http://en.cppreference.com/w/cpp/language/function#Deleted_functions">Deleted functions</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/i1o7-RNRnMs">Discussion thread</a></td> -</tr> - -<tr> -<td>Inherited Constructors</td> -<td><code>class Derived : Base {<br /> - using Base::Base;<br /> -};</code></td> -<td>Allows derived classes to inherit constructors from base classes</td> -<td><a href="http://en.cppreference.com/w/cpp/language/using_declaration#Inheriting_constructors">Inheriting constructors</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/BULzgIKZ-Ao">Discussion thread</a></td> -</tr> - -<tr> -<td>Lambda Expressions</td> -<td><code>[<i>captures</i>](<i>params</i>) -> <i>ret</i> { <i>body</i> }</code></td> -<td>Anonymous functions</td> -<td><a href="http://en.cppreference.com/w/cpp/language/lambda">Lambda functions</a></td> -<td>Lambdas are typically useful as a parameter to methods or functions that will use them immediately, such as those in <code><algorithm></code>. Be careful with default captures (<code>[=]</code>, <code>[&]</code>), and do not bind or store any capturing lambdas outside the lifetime of the stack frame they are defined in; use <code>base::Callback</code> for this instead, as it helps prevent object lifetime mistakes. (Captureless lambdas can be used with <code>base::Bind</code> as they do not have the same risks.) <a href="https://google.github.io/styleguide/cppguide.html#Lambda_expressions">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/D9UnnxBnciQ">Discussion thread</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/QxjsPELDYdQ">Another discussion thread</a> (about captureless lambdas and <code>base::Bind</code>).</td> -</tr> - -<tr> -<td>Local Types as Template Arguments</td> -<td><code>void func() {<br /> - class Pred {<br /> - public:<br /> - bool operator()(const T&) { ... }<br /> - };<br /> - std::remove_if(vec.begin(), vec.end(), Pred());</code></td> -<td>Allows local and unnamed types as template arguments</td> -<td><a href="http://stackoverflow.com/questions/742607/using-local-classes-with-stl-algorithms">Local types, types without linkage and unnamed types as template arguments</a></td> -<td>Usage should be rare. Approved without discussion.</td> -</tr> - -<tr> -<td>Noexcept Specifier</td> -<td><code>void f() noexcept</code></td> -<td>Specifies that a function will not throw exceptions</td> -<td><a href="http://en.cppreference.com/w/cpp/language/noexcept_spec">noexcept specifier</a></td> -<td>Chromium compiles without exception support, but there are still cases where explicitly marking a function as <code>noexcept</code> may be necessary to compile, or for performance reasons. Use noexcept for move constructors whenever possible (see "Notes" section on <a href="http://en.cppreference.com/w/cpp/language/move_constructor">move constructors</a>). Other usage should be rare. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8i4tMqNpHhg">Discussion thread</a></td> -</tr> - -<tr> -<td>Non-Static Class Member Initializers</td> -<td><code>class C {<br /> - <i>type</i> <i>var</i> = <i>value</i>;<br /> - C() // copy-initializes <i>var</i></code> -<td>Allows non-static class members to be initialized at their definitions (outside constructors)</td> -<td><a href="http://en.cppreference.com/w/cpp/language/data_members">Non-static data members</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/zqB-DySA4V0">Discussion thread</a></td> -</tr> - -<tr> -<td>Null Pointer Constant</td> -<td><code>nullptr</code></td> -<td>Declares a type-safe null pointer</td> -<td><a href="http://en.cppreference.com/w/cpp/language/nullptr">nullptr, the pointer literal</a></td> -<td>Prefer over <code>NULL</code> or <code>0</code>. <a href="https://google.github.io/styleguide/cppguide.html#0_and_nullptr/NULL">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/4mijeJHzxLg">Discussion thread</a></td> -</tr> - -<tr> -<td>Override Specifier</td> -<td><code>override</code></td> -<td>Indicates that a class or function overrides a base implementation</td> -<td><a href="http://en.cppreference.com/w/cpp/language/override">override specifier</a></td> -<td>Recommended for new code. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/VTNZzizN0zo">Discussion thread</a></td> -</tr> - -<tr> -<td>Range-Based For Loops</td> -<td><code>for (<i>type</i> <i>var</i> : <i>range</i>)</code></td> -<td>Facilitates a more concise syntax for iterating over the elements of a container (or a range of iterators) in a <code>for</code> loop</td> -<td><a href="http://en.cppreference.com/w/cpp/language/range-for">Range-based for loop</a></td> -<td>As a rule of thumb, use <code>for (const auto& ...)</code>, <code>for (auto& ...)</code>, or <code>for (<i>concrete type</i> ...)</code>. For pointers, use <code>for (auto* ...)</code> to make clear that the copy of the loop variable is intended, and only a pointer is copied. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/hpzz4EqbVmc">Discussion thread</a></td> -</tr> - -<tr> -<td>Raw String Literals</td> -<td><code>string <i>var</i>=R"(<i>raw_string</i>)";</code></td> -<td>Allows a string to be encoded without any escape sequences, easing parsing in regex expressions, for example</td> -<td><a href="http://en.cppreference.com/w/cpp/language/string_literal">string literal</a></td> -<td>Beware of passing these as macro arguments, which can trigger a <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824">lexer bug</a> on older GCC versions. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2kWQHbbuMHI">Discussion thread</a></td> -</tr> - -<tr> -<td>Ref-qualified Member Functions</td> -<td><code>class T {<br /> - void f() & {}<br /> - void f() && {}<br /> -};<br /> -t.f(); // first<br /> -T().f(); // second<br /> -std::move(t).f(); // second</code></td> -<td>Allows class member functions to only bind to |this| as an rvalue or lvalue.</td> -<td><a href="http://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions">const-, volatile-, and ref-qualified member functions</a></td> -<td>Use sparingly, since this feature may not be understood well by all developers. Consult with <code>styleguide/c++/OWNERS</code> when in doubt. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/gowclr2LPQA">Discussion Thread</a></td> -</tr> - -<tr> -<td>Rvalue References</td> -<td><code>T(T&& t)</code> and <code>T& operator=(T&& t)<br/><br/> -template <typename T><br/>void Function(T&& t) { ... }</code></td> -<td>Reference that only binds to a temporary object</td> -<td><a href="http://en.cppreference.com/w/cpp/language/reference#Rvalue_references">Rvalue references</a></td> -<td>Only use these to define move constructors and move assignment operators, and for perfect forwarding. Most classes should not be copyable, even if movable. Continue to use DISALLOW_COPY_AND_ASSIGN in most cases. <a href="https://google.github.io/styleguide/cppguide.html#Rvalue_references">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/UnRaORb4TSw">Discussion thread</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/Q526tkruXpM">Another discussion thread</a></td> -</tr> - -<tr> -<td>Standard Integers</td> -<td>Typedefs within <code><stdint.h></code> and <code><inttypes></code></td> -<td>Provides fixed-size integers independent of platforms</td> -<td><a href="http://en.cppreference.com/w/cpp/header/cstdint">Standard library header <cstdint></a></td> -<td>Approved without discussion. Required by the <a href="http://google.github.io/styleguide/cppguide.html#Integer_Types">Google Style Guide</a>.</td> -</tr> - -<tr> -<td>Static Assertions</td> -<td><code>static_assert(<i>bool</i>, <i>string</i>)</code></td> -<td>Tests compile-time conditions</td> -<td><a href="http://en.cppreference.com/w/cpp/language/static_assert">Static Assertion</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/POISBQEhGzU">Discussion thread</a></td> -</tr> - -<tr> -<td>Trailing Return Types</td> -<td><code>auto <i>function declaration</i> -> <i>return_type</i></code></td> -<td>Allows trailing function return value syntax</td> -<td><a href="http://en.cppreference.com/w/cpp/language/function">Declaring functions</a></td> -<td>Use only where it considerably improves readability. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/OQyYSfH9m2M">Discussion thread</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/Lkp0nubVd0Q">Another discussion thread</a></td> -</tr> - -<tr> -<td>Type Aliases ("using" instead of "typedef")</td> -<td><code>using <i>new_alias</i> = <i>typename</i></code></td> -<td>Allows parameterized typedefs</td> -<td><a href="http://en.cppreference.com/w/cpp/language/type_alias">Type alias, alias template</a></td> -<td>Use instead of typedef, unless the header needs to be compatible with C. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8dOAMzgR4ao">Discussion thread</a></td> -</tr> - -<tr> -<td>Uniform Initialization Syntax</td> -<td><code><i>type</i> <i>name</i> {[<i>value</i> ..., <i>value</i>]};</code></td> -<td>Allows any object of primitive, aggregate or class type to be initialized using brace syntax</td> -<td><a href="http://www.stroustrup.com/C++11FAQ.html#uniform-init">Uniform initialization syntax and semantics</a></td> -<td>See the <a href="https://www.chromium.org/developers/coding-style/cpp-dos-and-donts?pli=1#TOC-Variable-initialization">Chromium C++ Dos And Don'ts guidance</a> on when to use this. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/GF96FshwHLw">Discussion thread</a></td> -</tr> - -<tr> -<td>Union Class Members</td> -<td><code>union <i>name</i> {<i>class</i> <i>var</i>}</code></td> -<td>Allows class type members</td> -<td><a href="http://en.cppreference.com/w/cpp/language/union">Union declaration</a></td> -<td>Usage should be rare. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/3oK78s1ntgU">Discussion thread</a></td> -</tr> - -<tr> -<td>Variadic Macros</td> -<td><code>#define <i>MACRO</i>(...) <i>Impl</i>(<i>args</i>, __VA_ARGS__)</code></td> -<td>Allows macros that accept a variable number of arguments</td> -<td><a href="http://stackoverflow.com/questions/4786649/are-variadic-macros-nonstandard">Are Variadic macros nonstandard?</a></td> -<td>Usage should be rare. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/sRx9j3CQqyA">Discussion thread</a></td> -</tr> - -<tr> -<td>Variadic Templates</td> -<td><code>template <<i>typename</i> ... <i>arg</i>></code></td> -<td>Allows templates that accept a variable number of arguments</td> -<td><a href="http://en.cppreference.com/w/cpp/language/parameter_pack">Parameter pack</a></td> -<td>Usage should be rare. Use instead of .pump files. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/6ItymeMXpMc">Discussion thread</a></td> -</tr> - -</tbody> -</table> - -<h2 id="whitelist"><a name="core-whitelist-14"></a>C++14 Allowed Features</h2> - -<p>The following features are currently allowed.</p> +<p>The following C++14 language features are allowed in the Chromium codebase.</p> <table id="whitelist_lang_list_14" class="unlined striped"> <tbody> @@ -457,235 +161,9 @@ </tbody> </table> -<h2 id="whitelist"><a name="library-whitelist"></a>C++11 Allowed Library Features</h2> - -<p>The following library features are currently allowed.</p> - -<table id="whitelist_lib_list" class="unlined striped"> -<tbody> - -<tr> -<th style='width:240px;'>Feature or Library</th> -<th style='width:240px;'>Snippet</th> -<th style='width:240px;'>Description</th> -<th style='width:240px;'>Documentation Link</th> -<th style='width:240px;'>Notes and Discussion Thread</th> -</tr> - -<tr> -<td>Access to underlying <code>std::vector</code> data</td> -<td><code>v.data()</code></td> -<td>Returns a pointer to a <code>std::vector</code>'s underlying data, accounting for empty vectors.</td> -<td><a href="http://en.cppreference.com/w/cpp/container/vector/data">std::vector::data</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/16V7fmtbzok">Discussion thread</a></td> -</tr> - -<tr> -<td>Algorithms</td> -<td>All C++11 features in <code><algorithm></code>:<br/> -<code>all_of</code>, <code>any_of</code>, <code>none_of</code><br/> -<code>find_if_not</code><br/> -<code>copy_if</code>, <code>copy_n</code><br/> -<code>move</code>, <code>move_backward</code> (see note)<br/> -<code>shuffle</code><br/> -<code>is_partitioned</code>, <code>partition_copy</code>, <code>partition_point</code><br/> -<code>is_sorted</code>, <code>is_sorted_until</code><br/> -<code>is_heap</code>, <code>is_heap_until</code><br/> -<code>minmax</code>, <code>minmax_element</code><br/> -<code>is_permutation<br/></td> -<td>Safe and performant implementations of common algorithms</td> -<td><a href="http://en.cppreference.com/w/cpp/header/algorithm">Standard library header <algorithm></a></td> -<td>Note that <algorithm> contains a range-based <code>move</code> method. This is allowed, but because people may confuse it with the single-arg <code>std::move</code>, there is often a way to write code without it that is more readable. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/UJQk8S1IuHk">Discussion thread</a>. <a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/8WzmtYrZvQ8'>Another discussion thread</a></td> -</tr> - -<tr> -<td>Atomics</td> -<td><code><atomic></code></td> -<td>Fine-grained atomic types and operations</td> -<td><a href="http://en.cppreference.com/w/cpp/atomic">Atomic operations library</a></td> -<td>Direct use should be rare because the semantics are subtle. Prefer to use higher-level abstractions built on top of atomics or synchronization primitives.</td> -</tr> - -<tr> -<td>Begin and End Non-Member Functions</td> -<td><code>std::begin()</code>, <code>std::end()</code></td> -<td>Allows use of free functions on any container, including fixed-size arrays</td> -<td><a href="http://en.cppreference.com/w/cpp/iterator/begin">std::begin</a>, <a href="http://en.cppreference.com/w/cpp/iterator/end">std::end</a></td> -<td>Useful for fixed-size arrays. Note that non-member <code>cbegin()</code> and <code>cend()</code> are not available until C++14. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/5iFNE8P5qT4">Discussion thread</a></td> -</tr> - -<tr> -<td>Conditional Type Selection</td> -<td><code>std::enable_if</code>, <code>std::conditional</code></td> -<td>Enables compile-time conditional type selection</td> -<td><a href="http://en.cppreference.com/w/cpp/types/enable_if">std::enable_if</a>, <a href="http://en.cppreference.com/w/cpp/types/conditional">conditional</a></td> -<td>Usage should be rare. <a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/vCxo4tZNd_M'>Discussion thread</a></td> -</tr> - -<tr> -<td>Constant Iterator Methods on Containers</td> -<td>E.g. <code>std::vector::cbegin()</code>, <code>std::vector::cend()</code></td> -<td>Allows more widespread use of <code>const_iterator</code></td> -<td><a href="http://en.cppreference.com/w/cpp/container/vector/begin">std::vector::cbegin</a>, <a href="http://en.cppreference.com/w/cpp/container/vector/end">std::vector::cend<a></td> -<td>Applies to all containers, not just <code>vector</code>. Consider using <code>const_iterator</code> over <code>iterator</code> where possible for the same reason as using <code>const</code> variables and functions where possible; see Effective Modern C++ item 13. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/cS83F_buqLM">Discussion thread</a></td> -</tr> - -<tr> -<td>Container Compaction Functions</td> -<td><code>std::vector::shrink_to_fit()</code>, <code>std::deque::shrink_to_fit()</code>, <code>std::string::shrink_to_fit()</code></td> -<td>Requests the removal of unused space in the container</td> -<td><a href="http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit">std::vector::shrink_to_fit</a>, <a href="http://en.cppreference.com/w/cpp/container/deque/shrink_to_fit">std::deque::shrink_to_fit</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/shrink_to_fit">std::basic_string::shrink_to_fit</a></td> -<td></td> -</tr> - -<tr> -<td>Declared Type As Value</td> -<td><code>std::declval<<i>class</i>>()</code></td> -<td>Converts a type to a reference of the type to allow use of members of the type without constructing it in templates.</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/declval">std::declval</a></td> -<td>Usage should be rare. <a href="https://groups.google.com/a/chromium.org/d/topic/cxx/ku6lYjk0-OU/discussion">Discussion thread</a></td> -</tr> - -<tr> -<td>Emplacement methods for containers</td> -<td><code>emplace()</code>, <code>emplace_back()</code>, <code>emplace_front()</code>, <code>emplace_hint()</code></td> -<td>Constructs elements directly within a container without a copy or a move. Less verbose than <code>push_back()</code> due to not naming the type being constructed.</td> -<td>E.g. <a href="http://en.cppreference.com/w/cpp/container/vector/emplace_back">std::vector::emplace_back</a></td> -<td>When using emplacement for performance reasons, your type should probably be movable (since e.g. a vector of it might be resized); given a movable type, then, consider whether you really need to avoid the move done by <code>push_back()</code>. For readability concerns, treat like <code>auto</code>; sometimes the brevity over <code>push_back()</code> is a win, sometimes a loss. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/m3cblzEta7A">Discussion thread</a></td> -</tr> - -<tr> -<td>Forwarding references</td> -<td><code>std::forward()</code></td> -<td>Perfectly forwards arguments (including rvalues)</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/forward">std::forward</a></td> -<td>Allowed, though usage should be rare (primarily for forwarding constructor arguments, or in carefully reviewed library code). <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/-O7euklhSxs">Discussion thread</a> -</td> -</tr> - -<tr> -<td>Initializer Lists</td> -<td><code>std::initializer_list<T></code></td> -<td>Allows containers to be initialized with aggregate elements</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/initializer_list">std::initializer_list</a></td> -<td>Be cautious adding new constructors which take these, as they can hide non-initializer_list constructors in undesirable ways; see Effective Modern C++ Item 7. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/TQQ-L51_naM">Discussion thread</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/UpiCpuu9UNc">Another discussion thread</a></td> -</tr> - -<tr> -<td>Iterator Operators</td> -<td><code>std::next()</code>, <code>std::prev()</code></td> -<td>Copies an iterator and increments or decrements the copy by some value</td> -<td><a href="http://en.cppreference.com/w/cpp/iterator/next">std::next</a>, <a href="http://en.cppreference.com/w/cpp/iterator/prev">std::prev</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/KeHhLI-E2Ww">Discussion thread</a></td> -</tr> - -<tr> -<td>Math functions</td> -<td>All C++11 features in <code><cmath></code>, e.g.:<br/> -<code>INFINITY</code>, <code>NAN</code>, <code>FP_NAN</code><br/> -<code>float_t</code>, <code>double_t</code><br/> -<code>fmax</code>, <code>fmin</code>, <code>trunc</code>, <code>round</code><br/> -<code>isinf</code>, <code>isnan</code><br/></td> -<td>Useful for math-related code</td> -<td><a href="http://en.cppreference.com/w/cpp/header/cmath">Standard library header <cmath></a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/P-1bFBXMeUk">Discussion thread</a></td> -</tr> - -<tr> -<td>Move Iterator Adaptor</td> -<td><code>std::make_move_iterator()</code></td> -<td>Wraps an iterator so that it moves objects instead of copying them.</td> -<td><a href="http://en.cppreference.com/w/cpp/iterator/make_move_iterator">std::make_move_iterator</a></td> -<td>Useful to move objects between containers that contain move-only types like <code>std::unique_ptr</code>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/lccnUljOHQU">Discussion thread</a></td> -</tr> - -<tr> -<td>Move Semantics</td> -<td><code>std::move()</code></td> -<td>Facilitates efficient move operations</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/move">std::move</a></td> -<td><a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/x_dWFxJFdbM'>Discussion thread</a></td> -</tr> - -<tr> -<td>Null Pointer Type</td> -<td><code>std::nullptr_t</code></td> -<td>Allows referencing the type of <code>nullptr</code>, e.g. in templates</td> -<td><a href="http://en.cppreference.com/w/cpp/types/nullptr_t">std::nullptr_t</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/UNaXc8R7eJ0">Discussion thread</a></td> -</tr> - -<tr> -<td>Random Number Distributions</td> -<td>The random number distributions defined in <code><random></code> (see separate item for random number engines), e.g.:<br/> -<code>uniform_int_distribution</code>, <code>uniform_real_distribution</code><br/> -<code>poisson_distribution</code>, <code>gamma_distribution</code><br/> -<code>normal_distribution</code>, <code>chi_squared_distribution</code><br/> -</td> -<td>Utilities for producing random distributions given a random bit generator.</td> -<td><a href="http://en.cppreference.com/w/cpp/numeric/random">Pseudo-random number generation</a></td> -<td>Because the standard does not define precisely how the <code><i>xxx</i>_distribution</code> objects generate output, the same object may produce different output for the same seed across platforms, or even across different versions of the STL. Do not use these objects in any scenario where behavioral consistency is required. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/MLgK9vCE4BA">Discussion thread</a></td> -</tr> - -<tr> -<td>Reference Wrapper Classes</td> -<td><code>std::reference_wrapper</code> and <code>std::ref()</code>, <code>std::cref()</code></td> -<td>Allows you to wrap a reference within a standard object (and use those within containers)</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper">std::reference_wrapper</a>, <a href="http://en.cppreference.com/w/cpp/utility/functional/ref">std::ref, std::cref</a></td> -<td><a href="https://groups.google.com/a/chromium.org/d/msg/cxx/oVdPIhPji3E/sr4Dv0geAgAJ">Discussion thread</a></td> -</tr> - -<tr> -<td>String Direct Reference Functions</td> -<td><code>std::string::front()</code>, <code>std::string::back()</code></td> -<td>Returns a reference to the front or back of a string</td> -<td><a href="http://en.cppreference.com/w/cpp/string/basic_string/front">std::basic_string::front</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/back">std::basic_string::back</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/DRJuROAYCV4">Discussion thread</a></td> -</tr> - -<tr> -<td>Type Traits</td> -<td>All C++11 features in <code><type_traits></code> except for aligned storage (see separate item), e.g.:<br/> -<code>integral_constant</code><br/> -<code>is_floating_point</code>, <code>is_rvalue_reference</code>, <code>is_scalar</code><br/> -<code>is_const</code>, <code>is_pod</code>, <code>is_unsigned</code><br/> -<code>is_default_constructible</code>, <code>is_move_constructible</code>, <code>is_copy_assignable</code><br/> -<code>enable_if</code>, <code>conditional</code>, <code>result_of</code><br/></td> -<td>Allows compile-time inspection of the properties of types</td> -<td><a href="http://en.cppreference.com/w/cpp/header/type_traits">Standard library header <type_traits></a></td> -<td><a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/vCxo4tZNd_M'>Discussion thread</a></td> -</tr> - -<tr> -<td>Tuples</td> -<td>All C++11 features in <code><tuple></code>, e.g. <code>std::tie</code> and <code>std::tuple</code>.</td> -<td>A fixed-size ordered collection of values of mixed types</td> -<td><a href="http://en.cppreference.com/w/cpp/header/tuple">Standard library header <tuple></a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/0NnCRmMY1xY">Discussion thread</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/VA7Ej2IWS2w">Another discussion thread</a></td> -</tr> - -<tr> -<td>Unordered Associative Containers</td> -<td><code>std::unordered_set</code>, <code>std::unordered_map</code>, <code>std::unordered_multiset</code>, <code>std::unordered_multimap</code></td> -<td>Allows efficient containers of key/value pairs</td> -<td><a href="http://en.cppreference.com/w/cpp/container/unordered_map">std::unordered_map</a>, <a href="http://en.cppreference.com/w/cpp/container/unordered_set">std::unordered_set</a></td> -<td>Specify custom hashers instead of specializing <code>std::hash</code> for custom types. <a href="https://google.github.io/styleguide/cppguide.html#std_hash">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/nCdjQqnouO4">Discussion thread</a></td> -</tr> - -<tr> -<td>Unique Pointers</td> -<td><code>std::unique_ptr<<i>type</i>></code></td> -<td>A smart pointer with sole ownership of the owned object.</td> -<td><a href="http://en.cppreference.com/w/cpp/memory/unique_ptr">std::unique_ptr</a></td> -<td><a href="https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/aT2wsBLKvzI">Discussion thread</a></td> -</tr> - -</tbody> -</table> - <h2 id="whitelist"><a name="library-whitelist-14"></a>C++14 Allowed Library Features</h2> -<p>The following library features are currently allowed.</p> +<p>The following C++14 library features are allowed in the Chromium codebase.</p> <table id="whitelist_lib_list" class="unlined striped"> <tbody> @@ -727,7 +205,7 @@ <td><code>auto widget = std::make_unique<Widget>();</code></td> <td>Allocates objects on the heap and immediately constructs an <code>std::unique_ptr</code> to assume ownership.</td> <td><a href="http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique">std::make_unique</a></td> -<td>Should replace <code>base::MakeUnique</code> and <code>WTF::MakeUnique</code>. <a href="https://groups.google.com/a/chromium.org/d/msg/cxx/ow7hmdDm4yw/EDEvBRi_BQAJ">Discussion thread</a></td> +<td><a href="https://groups.google.com/a/chromium.org/d/msg/cxx/ow7hmdDm4yw/EDEvBRi_BQAJ">Discussion thread</a></td> </tr> <tr> @@ -757,13 +235,9 @@ </tbody> </table> -<h2 id="blocklist">C++11 and C++14 Disallowed Features</h2> +<h2 id="blocklist_banned"><a name="core-blocklist"></a>C++11 Banned Language Features</h2> -<p>This section lists features that are not allowed to be used yet. - -<h3 id="blocklist_banned"><a name="core-blocklist"></a>C++11 Banned Features</h3> - -<p>This section lists C++11 features that are not allowed in the Chromium codebase.</p> +<p>The following C++11 language features are not allowed in the Chromium codebase.</p> <table id="banned_list" class="unlined striped"> <tbody> @@ -789,7 +263,7 @@ <td><code>long long <i>var</i> = <i>value</i>;</code></td> <td>An integer of at least 64 bits</td> <td><a href="http://en.cppreference.com/w/cpp/language/types">Fundamental types</a></td> -<td>Use a stdint.h type if you need a 64bit number. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/RxugZ-pIDxk">Discussion thread</a></td> +<td>Use a stdint.h type if you need a 64-bit number. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/RxugZ-pIDxk">Discussion thread</a></td> </tr> <tr> @@ -805,34 +279,15 @@ <td><code>thread_local int foo = 1;</code></td> <td>Puts variables into thread local storage.</td> <td><a href="http://en.cppreference.com/w/cpp/language/storage_duration">Storage duration</a></td> -<td>Some surprising effects on Mac (<a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2msN8k3Xzgs">discussion</a>, <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/h7O5BdtWCZw">fork</a>). Use <a href="https://cs.chromium.org/chromium/src/base/threading/sequence_local_storage_slot.h">SequenceLocalStorageSlot</a> for sequence support, and <a href="https://cs.chromium.org/chromium/src/base/threading/thread_local.h">ThreadLocal</a>/<a href="https://cs.chromium.org/chromium/src/base/threading/thread_local_storage.h">ThreadLocalStorage</a> otherwise.</td> +<td>Some surprising effects on Mac (<a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2msN8k3Xzgs">discussion</a>, <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/h7O5BdtWCZw">fork</a>). Use <code>base::SequenceLocalStorageSlot</code> for sequence support, and <code>base::ThreadLocal</code>/<code>base::ThreadLocalStorage</code> otherwise.</td> </tr> </tbody> </table> -<h3 id="blocklist_banned"><a name="core-blocklist-14"></a>C++14 Banned Features</h3> +<h2 id="blocklist_stdlib"><a name="library-blocklist"></a>C++11 Banned Library Features</h2> -<p>This section lists C++14 features that are not allowed in the Chromium codebase.</p> - -<table id="banned_list" class="unlined striped"> -<tbody> - -<tr> -<th style='width:240px;'>Feature</th> -<th style='width:240px;'>Snippet</th> -<th style='width:240px;'>Description</th> -<th style='width:240px;'>Documentation Link</th> -<th style='width:240px;'>Notes and Discussion Thread</th> -</tr> - -<tr> -</tbody> -</table> - -<h3 id="blocklist_stdlib"><a name="library-blocklist"></a>C++11 Banned Library Features</h3> - -<p>This section lists C++11 library features that are not allowed in the Chromium codebase.</p> +<p>The following C++11 library features are not allowed in the Chromium codebase.</p> <table id="blocklist_lib_list" class="unlined striped"> <tbody> @@ -845,14 +300,6 @@ <th style='width:240px;'>Notes and Discussion Thread</th> </tr> -<tr> -<td>Aligned storage</td> -<td><code>std::aligned_storage<10, 128></code></td> -<td>Uninitialized storage for objects requiring specific alignment.</td> -<td><a href="http://en.cppreference.com/w/cpp/types/aligned_storage">std::aligned_storage</a></td> -<td>MSVC 2017's implementation does not align on boundaries greater than sizeof(double) = 8 bytes. Use <code>alignas(128) char foo[10];</code> instead. <a href="https://codereview.chromium.org/2932053002">Patch where this was discovered</a>.</td> -</tr> - <td>Bind Operations</td> <td><code>std::bind(<i>function</i>, <i>args</i>, ...)</code></td> <td>Declares a function object bound to certain arguments</td> @@ -881,7 +328,7 @@ <td><code><exception></code></td> <td>Enhancements to exception throwing and handling</td> <td><a href="http://en.cppreference.com/w/cpp/header/exception">Standard library header <exception></a></td> -<td>Exceptions are banned by the <a href="https://google.github.io/styleguide/cppguide.html#Exceptions">Google Style Guide</a> and disabled in Chromium compiles. Note that the <code>noexcept</code> specifier is explicitly allowed above. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8i4tMqNpHhg">Discussion thread</a></td> +<td>Exceptions are banned by the <a href="https://google.github.io/styleguide/cppguide.html#Exceptions">Google Style Guide</a> and disabled in Chromium compiles. However, the <code>noexcept</code> specifier is explicitly allowed. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8i4tMqNpHhg">Discussion thread</a></td> </tr> <tr> @@ -929,6 +376,14 @@ </tr> <tr> +<td>String-Number Conversion Functions</td> +<td><code>std::stoi()</code>, <code>std::stol()</code>, <code>std::stoul()</code>, <code>std::stoll</code>, <code>std::stoull()</code>, <code>std::stof()</code>, <code>std::stod()</code>, <code>std::stold()</code>, <code>std::to_string()</code></td> +<td>Converts strings to/from numbers</td> +<td><a href="http://en.cppreference.com/w/cpp/string/basic_string/stol">std::stoi, std::stol, std::stoll</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/stoul">std::stoul, std::stoull</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/stof">std::stof, std::stod, std::stold</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/to_string">std::to_string</a></td> +<td>The string-to-number conversions rely on exceptions to communicate failure, while the number-to-string conversions have performance concerns and depend on the locale. Use the routines in <code>base/strings/string_number_conversions.h</code> instead.</td> +</tr> + +<tr> <td>Thread Library</td> <td><code><thread></code> and related headers, including<br /> <code><future></code>, <code><mutex></code>, <code><condition_variable></code></td> @@ -937,12 +392,20 @@ <td>Overlaps with many classes in <code>base/</code>. Keep using the <code>base/</code> classes for now. <code>base::Thread</code> is tightly coupled to <code>MessageLoop</code> which would make it hard to replace. We should investigate using standard mutexes, or unique_lock, etc. to replace our locking/synchronization classes.</td> </tr> +<tr> +<td>Weak Pointers</td> +<td><code>std::weak_ptr</code></td> +<td>Allows a weak reference to a <code>std::shared_ptr</code></td> +<td><a href="http://en.cppreference.com/w/cpp/memory/weak_ptr">std::weak_ptr</a></td> +<td>Banned because <code>std::shared_ptr</code> is banned. Use <code>base::WeakPtr</code> instead.</td> +</tr> + </tbody> </table> -<h3 id="blocklist_stdlib"><a name="library-blocklist-14"></a>C++14 Banned Library Features</h3> +<h2 id="blocklist_stdlib"><a name="library-blocklist-14"></a>C++14 Banned Library Features</h2> -<p>This section lists C++14 library features that are not allowed in the Chromium codebase.</p> +<p>The following C++14 library features are not allowed in the Chromium codebase.</p> <table id="blocklist_lib_list" class="unlined striped"> <tbody> @@ -966,51 +429,9 @@ </tbody> </table> -<h3 id="blocklist_review"><a name="core-review"></a>C++11 Features To Be Discussed</h3> +<h2 id="blocklist_review"><a name="core-review-14"></a>C++14 TBD Language Features</h2> -<p>The following C++ language features are currently disallowed. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections.</p> - -<table id="blocklist_review_list" class="unlined striped"> -<tbody> - -<tr> -<th style='width:240px;'>Feature</th> -<th style='width:240px;'>Snippet</th> -<th style='width:240px;'>Description</th> -<th style='width:240px;'>Documentation Link</th> -<th style='width:240px;'>Notes and Discussion Thread</th> -</tr> - -<tr> -<td>Attributes</td> -<td><code>[[<i>attribute_name</i>]]</code></td> -<td>Attaches properties to declarations that specific compiler implementations may use.</td> -<td><a href="http://www.codesynthesis.com/~boris/blog/2012/04/18/cxx11-generalized-attributes/">C++11 generalized attributes</a></td> -<td></td> -</tr> - -<tr> -<td>UTF-8, UTF-16, UTF-32 String Literals</td> -<td><code>u8"<i>string</i>", u"<i>string</i>", U"<i>string</i>"</code></td> -<td>Enforces UTF-8, UTF-16, UTF-32 encoding on all string literals</td> -<td><a href="http://en.cppreference.com/w/cpp/language/string_literal">string literal</a></td> -<td>Reevaluate now that MSVS2015 is available. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/gcoUbcjfsII">Discussion thread</a></td> -</tr> - -<tr> -<td>UTF-16 and UTF-32 Support (16-Bit and 32-Bit Character Types)</td> -<td><code>char16_t</code> and <code>char32_t</code></td> -<td>Provides character types for handling 16-bit and 32-bit code units (useful for encoding UTF-16 and UTF-32 string data)</td> -<td><a href="http://en.cppreference.com/w/cpp/language/types">Fundamental types</a></td> -<td>Reevaluate now that MSVS2015 is available. Non-UTF-8 text is banned by the <a href="https://google.github.io/styleguide/cppguide.html#Non-ASCII_Characters">Google Style Guide</a>. However, may be useful for consuming non-ASCII data. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/ME2kL7_Kvyk">Discussion thread</a></td> -</tr> - -</tbody> -</table> - -<h3 id="blocklist_review"><a name="core-review-14"></a>C++14 Features To Be Discussed</h3> - -<p>The following C++14 language features are currently disallowed. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections.</p> +<p>The following C++14 language features are not allowed in the Chromium codebase. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections.</p> <table id="blocklist_review_list" class="unlined striped"> <tbody> @@ -1052,172 +473,9 @@ </tbody> </table> -<h3 id="blocklist_stdlib_review"><a name="library-review"></a>C++11 Standard Library Features To Be Discussed</h3> +<h2 id="blocklist_stdlib_review"><a name="library-review-14"></a>C++14 TBD Library Features</h2> -<p>The following C++ library features are currently disallowed. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections.</p> - -<table id="banned_stdlib" class="unlined striped"> - -<tbody> -<tr> -<th style='width:240px;'>Feature</th> -<th style='width:240px;'>Snippet</th> -<th style='width:240px;'>Description</th> -<th style='width:240px;'>Documentation Link</th> -<th style='width:240px;'>Notes</th> -</tr> - -<tr> -<td>Address Retrieval</td> -<td><code>std::addressof()</code></td> -<td>Obtains the address of an object even with overloaded <code>operator&</code></td> -<td><a href="http://en.cppreference.com/w/cpp/memory/addressof">std::addressof</a></td> -<td>Usage should be rare as <a href="https://google.github.io/styleguide/cppguide.html#Operator_Overloading">operator overloading</a> is rare and <code>&</code> should suffice in most cases. May be preferable over <code>&</code> for performing object identity checks.</td> -</tr> - -<tr> -<td>Aligned Storage</td> -<td><code>std::alignment_of<T></code>, <code>std::aligned_union<Size, ...Types></code> <code>std::max_align_t</code></td> -<td>Declare uninitialized storage having a specified alignment, or determine alignments.</td> -<td><a href="http://en.cppreference.com/w/cpp/types/aligned_union">std::aligned_union</a></td> -<td><code>std::aligned_union</code> is disallowed in google3 over concerns about compatibility with internal cross-compiling toolchains. <code>std::aligned_storage</code> is on the disallowed list due to compatibility concerns.</td> -</tr> - -<tr> -<td>Allocator Traits</td> -<td><code>std::allocator_traits</code></td> -<td>Provides an interface for accessing custom allocators</td> -<td><a href="http://en.cppreference.com/w/cpp/memory/allocator_traits">std::allocator_traits</a></td> -<td>Usage should be rare.</td> -</tr> - -<tr> -<td>Complex Inverse Trigonometric and Hyperbolic Functions</td> -<td>Functions within <code><complex></code></td> -<td>Adds inverse trigonomentric and hyperbolic non-member functions to the <code><complex></code> library.</td> -<td><a href="http://en.cppreference.com/w/cpp/numeric/complex">std::complex</a></td> -<td></td> -</tr> - -<tr> -<td>Date/Time String Formatting Specifiers</td> -<td><code>std::strftime()</code></td> -<td>Converts date and time information into a formatted string using new specifiers</td> -<td><a href="http://en.cppreference.com/w/cpp/chrono/c/strftime">std::strftime</a></td> -<td></td> -</tr> - -<tr> -<td>Function Return Type Extraction</td> -<td><code>std::result_of<<i>Functor(ArgTypes...)</i>></code></td> -<td>Extracts the return type from the type signature of a function call invocation at compile-time.</td> -<td><a href="http://en.cppreference.com/w/cpp/types/result_of">std::result_of</a></td> -<td><a href="http://stackoverflow.com/questions/15486951/why-does-stdresult-of-take-an-unrelated-function-type-as-a-type-argument">Why does std::result_of take an (unrelated) function type as a type argument?</a></td> -</tr> - -<tr> -<td>Forward Lists</td> -<td><code>std::forward_list</code></td> -<td>Provides an efficient singly linked list</td> -<td><a href="http://en.cppreference.com/w/cpp/container/forward_list">std::forward_list</a></td> -<td></td> -</tr> - -<tr> -<td>Gamma Natural Log</td> -<td><code>std::lgamma()</code></td> -<td>Computes the natural log of the gamma of a floating point value</td> -<td><a href="http://en.cppreference.com/w/cpp/numeric/math/lgamma">std::lgamma</a></td> -<td></td> -</tr> - -<tr> -<td>Garbage Collection Features</td> -<td><code>std::{un}declare_reachable()</code>, <code>std::{un}declare_no_pointers()</code></td> -<td>Enables garbage collection implementations</td> -<td><a href="http://en.cppreference.com/w/cpp/memory/gc/declare_reachable">std::declare_reachable</a>, <a href="http://en.cppreference.com/w/cpp/memory/gc/declare_no_pointers">std::declare_no_pointers</a></td> -<td></td> -</tr> - -<tr> -<td>Pointer Traits Class Template</td> -<td><code>std::pointer_traits</code></td> -<td>Provides a standard way to access properties of pointers and pointer-like types</td> -<td><a href="http://en.cppreference.com/w/cpp/memory/pointer_traits">std::pointer_traits</a></td> -<td>Useful for determining the element type pointed at by a (possibly smart) pointer.</td> -</tr> - -<tr> -<td>Soft Program Exits</td> -<td><code>std::at_quick_exit()</code>, <code>std::quick_exit()</code></td> -<td>Allows registration of functions to be called upon exit, allowing cleaner program exit than <code>abort()</code> or <code>exit</code></td> -<td><a href="http://en.cppreference.com/w/cpp/utility/program/quick_exit">std:quick_exit</a></td> -<td></td> -</tr> - -<tr> -<td>String-Number Conversion Functions</td> -<td><code>std::stoi()</code>, <code>std::stol()</code>, <code>std::stoul()</code>, <code>std::stoll</code>, <code>std::stoull()</code>, <code>std::stof()</code>, <code>std::stod()</code>, <code>std::stold()</code>, <code>std::to_string()</code></td> -<td>Converts strings to/from numbers</td> -<td><a href="http://en.cppreference.com/w/cpp/string/basic_string/stol">std::stoi, std::stol, std::stoll</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/stoul">std::stoul, std::stoull</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/stof">std::stof, std::stod, std::stold</a>, <a href="http://en.cppreference.com/w/cpp/string/basic_string/to_string">std::to_string</a></td> -<td>May be useful to <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=593512">replace dmg_fp</a>.</td> -</tr> - -<tr> -<td>System Errors</td> -<td><code><system_error></code></td> -<td>Provides a standard system error library</td> -<td><a href="http://en.cppreference.com/w/cpp/header/system_error">Standard library header <system_error></a></td> -<td></td> -</tr> - -<tr> -<td>Type-Generic Math Functions</td> -<td><code><ctgmath></code></td> -<td>Provides a means to call real or complex functions based on the type of arguments</td> -<td><a href="http://en.cppreference.com/w/cpp/header/ctgmath">Standard library header <ctgmath></a></td> -<td></td> -</tr> - -<tr> -<td>Type Info Enhancements</td> -<td><code>std::type_index</code>, <code>std::type_info::hash_code()</code></td> -<td>Allows type information (most often within containers) that can be copied, assigned, or hashed</td> -<td><a href="http://en.cppreference.com/w/cpp/types/type_index">std::type_index</a>, <a href="http://en.cppreference.com/w/cpp/types/type_info/hash_code">std::type_info::hash_code</a></td> -<td><code>std::type_index</code> is a thin wrapper for <code>std::type_info</code>, allowing you to use it directly within both associative and unordered containers.</td> -</tr> - -<tr> -<td>Variadic Copy Macro</td> -<td><code>va_copy(va_list <i>dest</i>, va_list <i>src</i>)</code></td> -<td>Makes a copy of the variadic function arguments</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/variadic/va_copy">va_copy</a></td> -<td></td> -</tr> - -<tr> -<td>Weak Pointers</td> -<td><code>std::weak_ptr</code></td> -<td>Allows a weak reference to a <code>std::shared_ptr</code></td> -<td><a href="http://en.cppreference.com/w/cpp/memory/weak_ptr">std::weak_ptr</a></td> -<td><a href="https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers">Ownership and Smart Pointers</a></td> -</tr> - -<tr> -<td>Wide String Support</td> -<td><code>std::wstring_convert</code>, <code>std::wbuffer_convert</code><br /> -<code>std::codecvt_utf8</code>, <code>std::codecvt_utf16</code>, <code>std::codecvt_utf8_utf16</code></td> -<td>Converts between string encodings</td> -<td><a href="http://en.cppreference.com/w/cpp/locale/wstring_convert">std::wstring_convert</a>, <a href="http://en.cppreference.com/w/cpp/locale/wbuffer_convert">std::wbuffer_convert</a>, <a href="http://en.cppreference.com/w/cpp/locale/codecvt_utf8">std::codecvt_utf8</a>, <a href="http://en.cppreference.com/w/cpp/locale/codecvt_utf16">std::codecvt_utf16</a>, <a href="http://en.cppreference.com/w/cpp/locale/codecvt_utf8_utf16">std::codecvt_utf8_utf16</a></td> -<td>Non-UTF-8 text is banned by the <a href="https://google.github.io/styleguide/cppguide.html#Non-ASCII_Characters">Google Style Guide</a>. However, may be useful for consuming non-ASCII data.</td> -</tr> - -</tbody> -</table> - -<h3 id="blocklist_stdlib_review"><a name="library-review-14"></a>C++14 Standard Library Features To Be Discussed</h3> - -<p>The following C++14 library features are currently disallowed. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections.</p> +<p>The following C++14 library features are not allowed in the Chromium codebase. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections.</p> <table id="banned_stdlib" class="unlined striped">
diff --git a/testing/buildbot/chromium.chrome.json b/testing/buildbot/chromium.chrome.json index 2ce91ee..eaf3669 100644 --- a/testing/buildbot/chromium.chrome.json +++ b/testing/buildbot/chromium.chrome.json
@@ -775,6 +775,9 @@ "test": "boringssl_ssl_tests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.browser_tests.filter" + ], "experiment_percentage": 100, "merge": { "args": [], @@ -794,7 +797,8 @@ }, { "args": [ - "--enable-features=VizDisplayCompositor" + "--enable-features=VizDisplayCompositor", + "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.browser_tests.filter" ], "experiment_percentage": 100, "merge": {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 7cfff9b..15de3bd 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -29,7 +29,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -46,7 +46,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -63,7 +63,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -84,7 +84,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -101,7 +101,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -118,7 +118,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -136,7 +136,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -153,7 +153,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -170,7 +170,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -187,7 +187,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -209,7 +209,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -226,7 +226,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -243,7 +243,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -260,7 +260,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -280,7 +280,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -297,7 +297,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -314,7 +314,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -341,7 +341,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -362,7 +362,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -379,7 +379,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -396,7 +396,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -413,7 +413,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -430,7 +430,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -447,7 +447,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -464,7 +464,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ] @@ -491,7 +491,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -517,7 +517,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -548,7 +548,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ],
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 9bc3356..ec6aad2 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -6040,7 +6040,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6060,7 +6060,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6092,7 +6092,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6183,7 +6183,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6203,7 +6203,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6223,7 +6223,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6247,7 +6247,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6267,7 +6267,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6287,7 +6287,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6308,7 +6308,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6328,7 +6328,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6348,7 +6348,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6368,7 +6368,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6388,7 +6388,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6408,7 +6408,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6428,7 +6428,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6451,7 +6451,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6471,7 +6471,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6491,7 +6491,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6521,7 +6521,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6545,7 +6545,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6565,7 +6565,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6585,7 +6585,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6605,7 +6605,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6625,7 +6625,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6645,7 +6645,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ], @@ -6665,7 +6665,7 @@ "dimension_sets": [ { "kvm": "1", - "os": "Ubuntu-14.04", + "os": "Ubuntu-16.04", "pool": "Chrome-CrOS-VM" } ],
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 0be4941..66bc9a2 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -36,6 +36,7 @@ source_set("chromeos_filters") { data = [ "//testing/buildbot/filters/chromeos.base_unittests.filter", + "//testing/buildbot/filters/chromeos.browser_tests.filter", "//testing/buildbot/filters/chromeos.media_unittests.filter", "//testing/buildbot/filters/chromeos.services_unittests.filter", "//testing/buildbot/filters/chromeos.unit_tests.filter",
diff --git a/testing/buildbot/filters/chromeos.browser_tests.filter b/testing/buildbot/filters/chromeos.browser_tests.filter new file mode 100644 index 0000000..70c8265 --- /dev/null +++ b/testing/buildbot/filters/chromeos.browser_tests.filter
@@ -0,0 +1,2 @@ +# TODO(crbug.com/976083): Enable this. +-MSE_Widevine/EncryptedMediaTest.*
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index cb20c9d..f6a57d8b 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -90,6 +90,9 @@ 'linux-chromeos-google-rel': { # TODO(https://crbug.com/932269): Promote out of experiment when the # tests are green. + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.browser_tests.filter', + ], 'experiment_percentage': 100, }, 'linux-chromeos-oobe-code-coverage': { @@ -1511,6 +1514,9 @@ 'linux-chromeos-google-rel': { # TODO(https://crbug.com/932269): Promote out of experiment when the # tests are green. + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.browser_tests.filter', + ], 'experiment_percentage': 100, }, 'linux-chromeos-oobe-code-coverage': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 92fbc1e7..c9b4253 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -650,7 +650,7 @@ 'dimension_sets': [ { 'kvm': '1', - 'os': 'Ubuntu-14.04', + 'os': 'Ubuntu-16.04', 'pool': 'Chrome-CrOS-VM', }, ], @@ -1607,7 +1607,7 @@ 'dimension_sets': [ { 'kvm': '1', - 'os': 'Ubuntu-14.04', + 'os': 'Ubuntu-16.04', 'pool': 'Chrome-CrOS-VM', }, ], @@ -1646,7 +1646,7 @@ 'dimension_sets': [ { 'kvm': '1', - 'os': 'Ubuntu-14.04', + 'os': 'Ubuntu-16.04', 'pool': 'Chrome-CrOS-VM', }, ],
diff --git a/testing/gtest_ios/unittest-Info.plist b/testing/gtest_ios/unittest-Info.plist index 9fd1593..e897266 100644 --- a/testing/gtest_ios/unittest-Info.plist +++ b/testing/gtest_ios/unittest-Info.plist
@@ -18,6 +18,8 @@ <string>${PRODUCT_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key>
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 62a7074..f37ba02ee 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2280,6 +2280,25 @@ ] } ], + "FontSrcLocalMatching": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FontSrcLocalMatching" + ] + } + ] + } + ], "ForbidSyncXHRInPageDismissal": [ { "platforms": [ @@ -2338,6 +2357,33 @@ ] } ], + "FreezeBackgroundTabOnNetworkIdle": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "enable_1min", + "params": { + "DelayForBackgroundAndNetworkIdleTabFreezingMills": "60000" + }, + "enable_features": [ + "freeze-background-tab-on-network-idle" + ] + }, + { + "name": "enable_3min", + "params": { + "DelayForBackgroundAndNetworkIdleTabFreezingMills": "180000" + }, + "enable_features": [ + "freeze-background-tab-on-network-idle" + ] + } + ] + } + ], "GamepadPollingInterval": [ { "platforms": [ @@ -3361,6 +3407,24 @@ ] } ], + "NewPrintPreviewLayout": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NewPrintPreviewLayout" + ] + } + ] + } + ], "NewTabInProductHelp": [ { "platforms": [
diff --git a/third_party/abseil-cpp/CMake/install_test_project/CMakeLists.txt b/third_party/abseil-cpp/CMake/install_test_project/CMakeLists.txt index b8e27dd..06b797e 100644 --- a/third_party/abseil-cpp/CMake/install_test_project/CMakeLists.txt +++ b/third_party/abseil-cpp/CMake/install_test_project/CMakeLists.txt
@@ -16,7 +16,7 @@ # A simple CMakeLists.txt for testing cmake installation cmake_minimum_required(VERSION 3.5) -project(absl_cmake_testing) +project(absl_cmake_testing CXX) set(CMAKE_CXX_STANDARD 11)
diff --git a/third_party/abseil-cpp/CMakeLists.txt b/third_party/abseil-cpp/CMakeLists.txt index e7587f7..86f5634 100644 --- a/third_party/abseil-cpp/CMakeLists.txt +++ b/third_party/abseil-cpp/CMakeLists.txt
@@ -30,7 +30,7 @@ # Project version variables are the empty std::string if version is unspecified cmake_policy(SET CMP0048 NEW) -project(absl) +project(absl CXX) # when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp)) # in the source tree of a project that uses it, install rules are disabled.
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index 2edc12f..c37fd3b5 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@ License: Apache 2.0 License File: LICENSE Version: 0 -Revision: 27c30ec671cb7b5ba84c4e79feff7fd0b0ac6338 +Revision: 8f11724067248acc330b4d1f12f0c76d03f2cfb1 Security Critical: yes Description:
diff --git a/third_party/abseil-cpp/absl/base/BUILD.bazel b/third_party/abseil-cpp/absl/base/BUILD.bazel index c6f0e4d..5b7b295 100644 --- a/third_party/abseil-cpp/absl/base/BUILD.bazel +++ b/third_party/abseil-cpp/absl/base/BUILD.bazel
@@ -69,6 +69,9 @@ cc_library( name = "core_headers", + srcs = [ + "internal/thread_annotations.h", + ], hdrs = [ "attributes.h", "const_init.h", @@ -385,7 +388,6 @@ srcs = ["internal/endian_test.cc"], copts = ABSL_TEST_COPTS, deps = [ - ":base", ":config", ":endian", "@com_google_googletest//:gtest_main",
diff --git a/third_party/abseil-cpp/absl/base/CMakeLists.txt b/third_party/abseil-cpp/absl/base/CMakeLists.txt index b9f35bc..34bfba27 100644 --- a/third_party/abseil-cpp/absl/base/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/base/CMakeLists.txt
@@ -67,6 +67,7 @@ "optimization.h" "port.h" "thread_annotations.h" + "internal/thread_annotations.h" COPTS ${ABSL_DEFAULT_COPTS} DEPS
diff --git a/third_party/abseil-cpp/absl/base/config.h b/third_party/abseil-cpp/absl/base/config.h index 2a14fe7..f12f84fd 100644 --- a/third_party/abseil-cpp/absl/base/config.h +++ b/third_party/abseil-cpp/absl/base/config.h
@@ -181,6 +181,13 @@ #endif #endif // defined(__ANDROID__) && defined(__clang__) +// Emscripten doesn't yet support `thread_local` or `__thread`. +// https://github.com/emscripten-core/emscripten/issues/3502 +#if defined(__EMSCRIPTEN__) +#undef ABSL_HAVE_TLS +#undef ABSL_HAVE_THREAD_LOCAL +#endif // defined(__EMSCRIPTEN__) + // ABSL_HAVE_INTRINSIC_INT128 // // Checks whether the __int128 compiler extension for a 128-bit integral type is
diff --git a/third_party/abseil-cpp/absl/base/thread_annotations.h b/third_party/abseil-cpp/absl/base/thread_annotations.h index 341f7c28..9321c3f8 100644 --- a/third_party/abseil-cpp/absl/base/thread_annotations.h +++ b/third_party/abseil-cpp/absl/base/thread_annotations.h
@@ -35,9 +35,9 @@ #define ABSL_BASE_THREAD_ANNOTATIONS_H_ #if defined(__clang__) -#define ABSL_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) +#define ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x)) #else -#define ABSL_THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op +#define ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) // no-op #endif // ABSL_GUARDED_BY() @@ -57,7 +57,8 @@ // int p1_ ABSL_GUARDED_BY(mu_); // ... // }; -#define ABSL_GUARDED_BY(x) ABSL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) +#define ABSL_GUARDED_BY(x) \ + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(guarded_by(x)) // ABSL_PT_GUARDED_BY() // @@ -79,7 +80,8 @@ // // `q_`, guarded by `mu1_`, points to a shared memory location that is // // guarded by `mu2_`: // int *q_ ABSL_GUARDED_BY(mu1_) ABSL_PT_GUARDED_BY(mu2_); -#define ABSL_PT_GUARDED_BY(x) ABSL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) +#define ABSL_PT_GUARDED_BY(x) \ + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x)) // ABSL_ACQUIRED_AFTER() / ABSL_ACQUIRED_BEFORE() // @@ -97,10 +99,10 @@ // Mutex m1_; // Mutex m2_ ABSL_ACQUIRED_AFTER(m1_); #define ABSL_ACQUIRED_AFTER(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__)) #define ABSL_ACQUIRED_BEFORE(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__)) // ABSL_EXCLUSIVE_LOCKS_REQUIRED() / ABSL_SHARED_LOCKS_REQUIRED() // @@ -125,11 +127,12 @@ // // void foo() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } // void bar() const ABSL_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } -#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__)) +#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \ + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ + exclusive_locks_required(__VA_ARGS__)) #define ABSL_SHARED_LOCKS_REQUIRED(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_locks_required(__VA_ARGS__)) // ABSL_LOCKS_EXCLUDED() // @@ -137,7 +140,7 @@ // cannot be held when calling this function (as Abseil's `Mutex` locks are // non-reentrant). #define ABSL_LOCKS_EXCLUDED(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__)) // ABSL_LOCK_RETURNED() // @@ -145,13 +148,12 @@ // a public getter method that returns a pointer to a private mutex should // be annotated with ABSL_LOCK_RETURNED. #define ABSL_LOCK_RETURNED(x) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x)) // ABSL_LOCKABLE // // Documents if a class/type is a lockable type (such as the `Mutex` class). -#define ABSL_LOCKABLE \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(lockable) +#define ABSL_LOCKABLE ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lockable) // ABSL_SCOPED_LOCKABLE // @@ -161,28 +163,29 @@ // arguments; the analysis will assume that the destructor unlocks whatever the // constructor locked. #define ABSL_SCOPED_LOCKABLE \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable) // ABSL_EXCLUSIVE_LOCK_FUNCTION() // // Documents functions that acquire a lock in the body of a function, and do // not release it. -#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__)) +#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \ + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ + exclusive_lock_function(__VA_ARGS__)) // ABSL_SHARED_LOCK_FUNCTION() // // Documents functions that acquire a shared (reader) lock in the body of a // function, and do not release it. #define ABSL_SHARED_LOCK_FUNCTION(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_lock_function(__VA_ARGS__)) // ABSL_UNLOCK_FUNCTION() // // Documents functions that expect a lock to be held on entry to the function, // and release it in the body of the function. #define ABSL_UNLOCK_FUNCTION(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(unlock_function(__VA_ARGS__)) // ABSL_EXCLUSIVE_TRYLOCK_FUNCTION() / ABSL_SHARED_TRYLOCK_FUNCTION() // @@ -193,20 +196,22 @@ // argument specifies the mutex that is locked on success. If unspecified, this // mutex is assumed to be `this`. #define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ + exclusive_trylock_function(__VA_ARGS__)) -#define ABSL_SHARED_TRYLOCK_FUNCTION(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__)) +#define ABSL_SHARED_TRYLOCK_FUNCTION(...) \ + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ + shared_trylock_function(__VA_ARGS__)) // ABSL_ASSERT_EXCLUSIVE_LOCK() / ABSL_ASSERT_SHARED_LOCK() // // Documents functions that dynamically check to see if a lock is held, and fail // if it is not held. #define ABSL_ASSERT_EXCLUSIVE_LOCK(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_exclusive_lock(__VA_ARGS__)) #define ABSL_ASSERT_SHARED_LOCK(...) \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__)) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_lock(__VA_ARGS__)) // ABSL_NO_THREAD_SAFETY_ANALYSIS // @@ -214,7 +219,7 @@ // This annotation is used to mark functions that are known to be correct, but // the locking behavior is more complicated than the analyzer can handle. #define ABSL_NO_THREAD_SAFETY_ANALYSIS \ - ABSL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) + ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(no_thread_safety_analysis) //------------------------------------------------------------------------------ // Tool-Supplied Annotations @@ -230,28 +235,29 @@ // The annotation should either be fixed, or changed to ABSL_TS_UNCHECKED. #define ABSL_TS_FIXME(x) "" -// Like ABSL_NO_THREAD_SAFETY_ANALYSIS, this turns off checking within the body of -// a particular function. However, this attribute is used to mark functions +// Like ABSL_NO_THREAD_SAFETY_ANALYSIS, this turns off checking within the body +// of a particular function. However, this attribute is used to mark functions // that are incorrect and need to be fixed. It is used by automated tools to // avoid breaking the build when the analysis is updated. // Code owners are expected to eventually fix the routine. -#define ABSL_NO_THREAD_SAFETY_ANALYSIS_FIXME ABSL_NO_THREAD_SAFETY_ANALYSIS +#define ABSL_NO_THREAD_SAFETY_ANALYSIS_FIXME ABSL_NO_THREAD_SAFETY_ANALYSIS -// Similar to ABSL_NO_THREAD_SAFETY_ANALYSIS_FIXME, this macro marks a ABSL_GUARDED_BY -// annotation that needs to be fixed, because it is producing thread safety -// warning. It disables the ABSL_GUARDED_BY. +// Similar to ABSL_NO_THREAD_SAFETY_ANALYSIS_FIXME, this macro marks a +// ABSL_GUARDED_BY annotation that needs to be fixed, because it is producing +// thread safety warning. It disables the ABSL_GUARDED_BY. #define ABSL_GUARDED_BY_FIXME(x) // Disables warnings for a single read operation. This can be used to avoid // warnings when it is known that the read is not actually involved in a race, // but the compiler cannot confirm that. -#define ABSL_TS_UNCHECKED_READ(x) thread_safety_analysis::absl_ts_unchecked_read(x) +#define ABSL_TS_UNCHECKED_READ(x) absl::base_internal::absl_ts_unchecked_read(x) - -namespace thread_safety_analysis { +namespace absl { +namespace base_internal { // Takes a reference to a guarded data member, and returns an unguarded // reference. +// Do not used this function directly, use ABSL_TS_UNCHECKED_READ instead. template <typename T> inline const T& absl_ts_unchecked_read(const T& v) ABSL_NO_THREAD_SAFETY_ANALYSIS { return v; @@ -262,6 +268,7 @@ return v; } -} // namespace thread_safety_analysis +} // namespace base_internal +} // namespace absl #endif // ABSL_BASE_THREAD_ANNOTATIONS_H_
diff --git a/third_party/abseil-cpp/absl/container/BUILD.bazel b/third_party/abseil-cpp/absl/container/BUILD.bazel index 99a7248..331030a 100644 --- a/third_party/abseil-cpp/absl/container/BUILD.bazel +++ b/third_party/abseil-cpp/absl/container/BUILD.bazel
@@ -124,6 +124,7 @@ linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":compressed_tuple", + "//absl/memory", "//absl/meta:type_traits", ], )
diff --git a/third_party/abseil-cpp/absl/container/BUILD.gn b/third_party/abseil-cpp/absl/container/BUILD.gn index 3466fda..5ae19c407 100644 --- a/third_party/abseil-cpp/absl/container/BUILD.gn +++ b/third_party/abseil-cpp/absl/container/BUILD.gn
@@ -63,6 +63,7 @@ deps = [ ":compressed_tuple", "../meta:type_traits", + "../memory", ] }
diff --git a/third_party/abseil-cpp/absl/container/CMakeLists.txt b/third_party/abseil-cpp/absl/container/CMakeLists.txt index 526e37a..c75b0a2 100644 --- a/third_party/abseil-cpp/absl/container/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/container/CMakeLists.txt
@@ -124,6 +124,7 @@ ${ABSL_DEFAULT_COPTS} DEPS absl::compressed_tuple + absl::memory absl::type_traits PUBLIC )
diff --git a/third_party/abseil-cpp/absl/container/inlined_vector.h b/third_party/abseil-cpp/absl/container/inlined_vector.h index 564c953..046182d 100644 --- a/third_party/abseil-cpp/absl/container/inlined_vector.h +++ b/third_party/abseil-cpp/absl/container/inlined_vector.h
@@ -100,9 +100,8 @@ // InlinedVector Constructors and Destructor // --------------------------------------------------------------------------- - // Creates an empty inlined vector with a default initialized allocator. - InlinedVector() noexcept(noexcept(allocator_type())) - : storage_(allocator_type()) {} + // Creates an empty inlined vector with a value-initialized allocator. + InlinedVector() noexcept(noexcept(allocator_type())) : storage_() {} // Creates an empty inlined vector with a specified allocator. explicit InlinedVector(const allocator_type& alloc) noexcept @@ -112,22 +111,40 @@ explicit InlinedVector(size_type n, const allocator_type& alloc = allocator_type()) : storage_(alloc) { - InitAssign(n); + if (n > static_cast<size_type>(N)) { + pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n); + storage_.SetAllocatedData(new_data, n); + UninitializedFill(storage_.GetAllocatedData(), + storage_.GetAllocatedData() + n); + storage_.SetAllocatedSize(n); + } else { + UninitializedFill(storage_.GetInlinedData(), + storage_.GetInlinedData() + n); + storage_.SetInlinedSize(n); + } } // Creates an inlined vector with `n` copies of `v`. InlinedVector(size_type n, const_reference v, const allocator_type& alloc = allocator_type()) : storage_(alloc) { - InitAssign(n, v); + if (n > static_cast<size_type>(N)) { + pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n); + storage_.SetAllocatedData(new_data, n); + UninitializedFill(storage_.GetAllocatedData(), + storage_.GetAllocatedData() + n, v); + storage_.SetAllocatedSize(n); + } else { + UninitializedFill(storage_.GetInlinedData(), + storage_.GetInlinedData() + n, v); + storage_.SetInlinedSize(n); + } } // Creates an inlined vector of copies of the values in `list`. InlinedVector(std::initializer_list<value_type> list, const allocator_type& alloc = allocator_type()) - : storage_(alloc) { - AppendForwardRange(list.begin(), list.end()); - } + : InlinedVector(list.begin(), list.end(), alloc) {} // Creates an inlined vector with elements constructed from the provided // forward iterator range [`first`, `last`). @@ -140,7 +157,15 @@ InlinedVector(ForwardIterator first, ForwardIterator last, const allocator_type& alloc = allocator_type()) : storage_(alloc) { - AppendForwardRange(first, last); + auto length = std::distance(first, last); + reserve(size() + length); + if (storage_.GetIsAllocated()) { + UninitializedCopy(first, last, storage_.GetAllocatedData() + size()); + storage_.SetAllocatedSize(size() + length); + } else { + UninitializedCopy(first, last, storage_.GetInlinedData() + size()); + storage_.SetInlinedSize(size() + length); + } } // Creates an inlined vector with elements constructed from the provided input @@ -193,8 +218,8 @@ if (other.storage_.GetIsAllocated()) { // We can just steal the underlying buffer from the source. // That leaves the source empty, so we clear its size. - storage_.SetAllocatedData(other.storage_.GetAllocatedData()); - storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity()); + storage_.SetAllocatedData(other.storage_.GetAllocatedData(), + other.storage_.GetAllocatedCapacity()); storage_.SetAllocatedSize(other.size()); other.storage_.SetInlinedSize(0); } else { @@ -227,8 +252,8 @@ if (*storage_.GetAllocPtr() == *other.storage_.GetAllocPtr()) { // We can just steal the allocation from the source. storage_.SetAllocatedSize(other.size()); - storage_.SetAllocatedData(other.storage_.GetAllocatedData()); - storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity()); + storage_.SetAllocatedData(other.storage_.GetAllocatedData(), + other.storage_.GetAllocatedCapacity()); other.storage_.SetInlinedSize(0); } else { // We need to use our own allocator @@ -248,7 +273,7 @@ } } - ~InlinedVector() { clear(); } + ~InlinedVector() {} // --------------------------------------------------------------------------- // InlinedVector Member Accessors @@ -473,8 +498,8 @@ if (other.storage_.GetIsAllocated()) { clear(); storage_.SetAllocatedSize(other.size()); - storage_.SetAllocatedData(other.storage_.GetAllocatedData()); - storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity()); + storage_.SetAllocatedData(other.storage_.GetAllocatedData(), + other.storage_.GetAllocatedCapacity()); other.storage_.SetInlinedSize(0); } else { if (storage_.GetIsAllocated()) clear(); @@ -793,16 +818,8 @@ // Destroys all elements in the inlined vector, sets the size of `0` and // deallocates the heap allocation if the inlined vector was allocated. void clear() noexcept { - const bool is_allocated = storage_.GetIsAllocated(); - pointer the_data = - is_allocated ? storage_.GetAllocatedData() : storage_.GetInlinedData(); - inlined_vector_internal::DestroyElements(storage_.GetAllocPtr(), the_data, - storage_.GetSize()); + storage_.DestroyAndDeallocate(); storage_.SetInlinedSize(0); - if (is_allocated) { - AllocatorTraits::deallocate(*storage_.GetAllocPtr(), the_data, - storage_.GetAllocatedCapacity()); - } } // `InlinedVector::reserve()` @@ -883,14 +900,13 @@ Destroy(storage_.GetInlinedData(), storage_.GetInlinedData() + size()); } - storage_.SetAllocatedData(new_data); - storage_.SetAllocatedCapacity(new_capacity); + storage_.SetAllocatedData(new_data, new_capacity); storage_.SetAllocatedSize(new_size); } template <typename... Args> reference Construct(pointer p, Args&&... args) { - std::allocator_traits<allocator_type>::construct( + absl::allocator_traits<allocator_type>::construct( *storage_.GetAllocPtr(), p, std::forward<Args>(args)...); return *p; } @@ -908,8 +924,8 @@ // Destroy [`from`, `to`) in place. void Destroy(pointer from, pointer to) { for (pointer cur = from; cur != to; ++cur) { - std::allocator_traits<allocator_type>::destroy(*storage_.GetAllocPtr(), - cur); + absl::allocator_traits<allocator_type>::destroy(*storage_.GetAllocPtr(), + cur); } #if !defined(NDEBUG) // Overwrite unused memory with `0xab` so we can catch uninitialized usage. @@ -1032,53 +1048,6 @@ return new_element; } - void InitAssign(size_type n) { - if (n > static_cast<size_type>(N)) { - pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n); - storage_.SetAllocatedData(new_data); - storage_.SetAllocatedCapacity(n); - UninitializedFill(storage_.GetAllocatedData(), - storage_.GetAllocatedData() + n); - storage_.SetAllocatedSize(n); - } else { - UninitializedFill(storage_.GetInlinedData(), - storage_.GetInlinedData() + n); - storage_.SetInlinedSize(n); - } - } - - void InitAssign(size_type n, const_reference v) { - if (n > static_cast<size_type>(N)) { - pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n); - storage_.SetAllocatedData(new_data); - storage_.SetAllocatedCapacity(n); - UninitializedFill(storage_.GetAllocatedData(), - storage_.GetAllocatedData() + n, v); - storage_.SetAllocatedSize(n); - } else { - UninitializedFill(storage_.GetInlinedData(), - storage_.GetInlinedData() + n, v); - storage_.SetInlinedSize(n); - } - } - - template <typename ForwardIt> - void AppendForwardRange(ForwardIt first, ForwardIt last) { - static_assert(absl::inlined_vector_internal::IsAtLeastForwardIterator< - ForwardIt>::value, - ""); - - auto length = std::distance(first, last); - reserve(size() + length); - if (storage_.GetIsAllocated()) { - UninitializedCopy(first, last, storage_.GetAllocatedData() + size()); - storage_.SetAllocatedSize(size() + length); - } else { - UninitializedCopy(first, last, storage_.GetInlinedData() + size()); - storage_.SetInlinedSize(size() + length); - } - } - iterator InsertWithCount(const_iterator position, size_type n, const_reference v) { assert(position >= begin() && position <= end()); @@ -1191,8 +1160,7 @@ a->Destroy(a->storage_.GetInlinedData(), a->storage_.GetInlinedData() + a_size); - a->storage_.SetAllocatedData(b_data); - a->storage_.SetAllocatedCapacity(b_capacity); + a->storage_.SetAllocatedData(b_data, b_capacity); if (*a->storage_.GetAllocPtr() != *b->storage_.GetAllocPtr()) { swap(*a->storage_.GetAllocPtr(), *b->storage_.GetAllocPtr());
diff --git a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc index d906997..a8368d4 100644 --- a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc +++ b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc
@@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <array> #include <string> #include <vector> @@ -373,71 +374,165 @@ } BENCHMARK(BM_StdVectorEmpty); -constexpr size_t kInlineElements = 4; -constexpr size_t kSmallSize = kInlineElements / 2; -constexpr size_t kLargeSize = kInlineElements * 2; +constexpr size_t kInlinedCapacity = 4; +constexpr size_t kLargeSize = kInlinedCapacity * 2; +constexpr size_t kSmallSize = kInlinedCapacity / 2; constexpr size_t kBatchSize = 100; +#define ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_FunctionTemplate, T) \ + BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kLargeSize); \ + BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kSmallSize) + +template <typename T> +using InlVec = absl::InlinedVector<T, kInlinedCapacity>; + struct TrivialType { size_t val; }; -using TrivialVec = absl::InlinedVector<TrivialType, kInlineElements>; - class NontrivialType { public: - ABSL_ATTRIBUTE_NOINLINE NontrivialType() : val_() {} + ABSL_ATTRIBUTE_NOINLINE NontrivialType() : val_() { + benchmark::DoNotOptimize(*this); + } ABSL_ATTRIBUTE_NOINLINE NontrivialType(const NontrivialType& other) - : val_(other.val_) {} + : val_(other.val_) { + benchmark::DoNotOptimize(*this); + } ABSL_ATTRIBUTE_NOINLINE NontrivialType& operator=( const NontrivialType& other) { val_ = other.val_; + benchmark::DoNotOptimize(*this); return *this; } - ABSL_ATTRIBUTE_NOINLINE ~NontrivialType() noexcept {} + ABSL_ATTRIBUTE_NOINLINE ~NontrivialType() noexcept { + benchmark::DoNotOptimize(*this); + } private: size_t val_; }; -using NontrivialVec = absl::InlinedVector<NontrivialType, kInlineElements>; - -template <typename VecT, typename PrepareVec, typename TestVec> -void BatchedBenchmark(benchmark::State& state, PrepareVec prepare_vec, - TestVec test_vec) { - VecT vectors[kBatchSize]; +template <typename T, typename PrepareVecFn, typename TestVecFn> +void BatchedBenchmark(benchmark::State& state, PrepareVecFn prepare_vec, + TestVecFn test_vec) { + std::array<InlVec<T>, kBatchSize> vector_batch{}; while (state.KeepRunningBatch(kBatchSize)) { // Prepare batch state.PauseTiming(); - for (auto& vec : vectors) { - prepare_vec(&vec); + for (size_t i = 0; i < kBatchSize; ++i) { + prepare_vec(vector_batch.data() + i, i); } - benchmark::DoNotOptimize(vectors); + benchmark::DoNotOptimize(vector_batch); state.ResumeTiming(); // Test batch - for (auto& vec : vectors) { - test_vec(&vec); + for (size_t i = 0; i < kBatchSize; ++i) { + test_vec(vector_batch.data() + i, i); } } } -template <typename VecT, size_t FromSize> -void BM_Clear(benchmark::State& state) { - BatchedBenchmark<VecT>( +template <typename T, size_t ToSize> +void BM_ConstructFromSize(benchmark::State& state) { + using VecT = InlVec<T>; + auto size = ToSize; + BatchedBenchmark<T>( state, - /* prepare_vec = */ [](VecT* vec) { vec->resize(FromSize); }, - /* test_vec = */ [](VecT* vec) { vec->clear(); }); + /* prepare_vec = */ [](InlVec<T>* vec, size_t) { vec->~VecT(); }, + /* test_vec = */ + [&](void* ptr, size_t) { + benchmark::DoNotOptimize(size); + ::new (ptr) VecT(size); + }); } +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromSize, TrivialType); +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromSize, NontrivialType); -BENCHMARK_TEMPLATE(BM_Clear, TrivialVec, kSmallSize); -BENCHMARK_TEMPLATE(BM_Clear, TrivialVec, kLargeSize); +template <typename T, size_t ToSize> +void BM_ConstructFromSizeRef(benchmark::State& state) { + using VecT = InlVec<T>; + auto size = ToSize; + auto ref = T(); + BatchedBenchmark<T>( + state, + /* prepare_vec = */ [](InlVec<T>* vec, size_t) { vec->~VecT(); }, + /* test_vec = */ + [&](void* ptr, size_t) { + benchmark::DoNotOptimize(size); + benchmark::DoNotOptimize(ref); + ::new (ptr) VecT(size, ref); + }); +} +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromSizeRef, TrivialType); +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromSizeRef, NontrivialType); -BENCHMARK_TEMPLATE(BM_Clear, NontrivialVec, kSmallSize); -BENCHMARK_TEMPLATE(BM_Clear, NontrivialVec, kLargeSize); +template <typename T, size_t ToSize> +void BM_ConstructFromRange(benchmark::State& state) { + using VecT = InlVec<T>; + std::array<T, ToSize> arr{}; + BatchedBenchmark<T>( + state, + /* prepare_vec = */ [](InlVec<T>* vec, size_t) { vec->~VecT(); }, + /* test_vec = */ + [&](void* ptr, size_t) { + benchmark::DoNotOptimize(arr); + ::new (ptr) VecT(arr.begin(), arr.end()); + }); +} +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromRange, TrivialType); +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromRange, NontrivialType); + +template <typename T, size_t ToSize> +void BM_ConstructFromCopy(benchmark::State& state) { + using VecT = InlVec<T>; + VecT other_vec(ToSize); + BatchedBenchmark<T>( + state, + /* prepare_vec = */ + [](InlVec<T>* vec, size_t) { vec->~VecT(); }, + /* test_vec = */ + [&](void* ptr, size_t) { + benchmark::DoNotOptimize(other_vec); + ::new (ptr) VecT(other_vec); + }); +} +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromCopy, TrivialType); +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromCopy, NontrivialType); + +template <typename T, size_t ToSize> +void BM_ConstructFromMove(benchmark::State& state) { + using VecT = InlVec<T>; + std::array<VecT, kBatchSize> vector_batch{}; + BatchedBenchmark<T>( + state, + /* prepare_vec = */ + [&](InlVec<T>* vec, size_t i) { + vector_batch[i].clear(); + vector_batch[i].resize(ToSize); + vec->~VecT(); + }, + /* test_vec = */ + [&](void* ptr, size_t i) { + benchmark::DoNotOptimize(vector_batch[i]); + ::new (ptr) VecT(std::move(vector_batch[i])); + }); +} +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromMove, TrivialType); +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromMove, NontrivialType); + +template <typename T, size_t FromSize> +void BM_Clear(benchmark::State& state) { + BatchedBenchmark<T>( + state, + /* prepare_vec = */ [](InlVec<T>* vec, size_t) { vec->resize(FromSize); }, + /* test_vec = */ [](InlVec<T>* vec, size_t) { vec->clear(); }); +} +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_Clear, TrivialType); +ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_Clear, NontrivialType); } // namespace
diff --git a/third_party/abseil-cpp/absl/container/inlined_vector_exception_safety_test.cc b/third_party/abseil-cpp/absl/container/inlined_vector_exception_safety_test.cc index 0af048b1..1aae0b0 100644 --- a/third_party/abseil-cpp/absl/container/inlined_vector_exception_safety_test.cc +++ b/third_party/abseil-cpp/absl/container/inlined_vector_exception_safety_test.cc
@@ -20,36 +20,85 @@ namespace { -constexpr size_t kInlined = 4; -constexpr size_t kSmallSize = kInlined / 2; -constexpr size_t kLargeSize = kInlined * 2; +constexpr size_t kInlinedCapacity = 4; +constexpr size_t kLargeSize = kInlinedCapacity * 2; +constexpr size_t kSmallSize = kInlinedCapacity / 2; using Thrower = testing::ThrowingValue<>; -using ThrowerAlloc = testing::ThrowingAllocator<Thrower>; +using MovableThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>; +using ThrowAlloc = testing::ThrowingAllocator<Thrower>; -template <typename Allocator = std::allocator<Thrower>> -using InlVec = absl::InlinedVector<Thrower, kInlined, Allocator>; +using ThrowerVec = absl::InlinedVector<Thrower, kInlinedCapacity>; +using MovableThrowerVec = absl::InlinedVector<MovableThrower, kInlinedCapacity>; -TEST(InlinedVector, DefaultConstructor) { - testing::TestThrowingCtor<InlVec<>>(); +using ThrowAllocThrowerVec = + absl::InlinedVector<Thrower, kInlinedCapacity, ThrowAlloc>; +using ThrowAllocMovableThrowerVec = + absl::InlinedVector<MovableThrower, kInlinedCapacity, ThrowAlloc>; - testing::TestThrowingCtor<InlVec<ThrowerAlloc>>(); +template <typename TheVecT, size_t... TheSizes> +class TestParams { + public: + using VecT = TheVecT; + constexpr static size_t GetSizeAt(size_t i) { return kSizes[1 + i]; } + + private: + constexpr static size_t kSizes[1 + sizeof...(TheSizes)] = {1, TheSizes...}; +}; + +using NoSizeTestParams = + ::testing::Types<TestParams<ThrowerVec>, TestParams<MovableThrowerVec>, + TestParams<ThrowAllocThrowerVec>, + TestParams<ThrowAllocMovableThrowerVec>>; + +using OneSizeTestParams = + ::testing::Types<TestParams<ThrowerVec, kLargeSize>, + TestParams<ThrowerVec, kSmallSize>, + TestParams<MovableThrowerVec, kLargeSize>, + TestParams<MovableThrowerVec, kSmallSize>, + TestParams<ThrowAllocThrowerVec, kLargeSize>, + TestParams<ThrowAllocThrowerVec, kSmallSize>, + TestParams<ThrowAllocMovableThrowerVec, kLargeSize>, + TestParams<ThrowAllocMovableThrowerVec, kSmallSize>>; + +template <typename> +struct NoSizeTest : ::testing::Test {}; +TYPED_TEST_SUITE(NoSizeTest, NoSizeTestParams); + +template <typename> +struct OneSizeTest : ::testing::Test {}; +TYPED_TEST_SUITE(OneSizeTest, OneSizeTestParams); + +// Function that always returns false is correct, but refactoring is required +// for clarity. It's needed to express that, as a contract, certain operations +// should not throw at all. Execution of this function means an exception was +// thrown and thus the test should fail. +// TODO(johnsoncj): Add `testing::NoThrowGuarantee` to the framework +template <typename VecT> +bool NoThrowGuarantee(VecT* /* vec */) { + return false; } -TEST(InlinedVector, AllocConstructor) { - auto alloc = std::allocator<Thrower>(); - testing::TestThrowingCtor<InlVec<>>(alloc); +TYPED_TEST(NoSizeTest, DefaultConstructor) { + using VecT = typename TypeParam::VecT; + using allocator_type = typename VecT::allocator_type; - auto throw_alloc = ThrowerAlloc(); - testing::TestThrowingCtor<InlVec<ThrowerAlloc>>(throw_alloc); + testing::TestThrowingCtor<VecT>(); + + testing::TestThrowingCtor<VecT>(allocator_type{}); } -TEST(InlinedVector, Clear) { - auto small_vec = InlVec<>(kSmallSize); - EXPECT_TRUE(testing::TestNothrowOp([&]() { small_vec.clear(); })); +TYPED_TEST(OneSizeTest, Clear) { + using VecT = typename TypeParam::VecT; + constexpr static auto size = TypeParam::GetSizeAt(0); - auto large_vec = InlVec<>(kLargeSize); - EXPECT_TRUE(testing::TestNothrowOp([&]() { large_vec.clear(); })); + auto tester = testing::MakeExceptionSafetyTester() + .WithInitialValue(VecT(size)) + .WithContracts(NoThrowGuarantee<VecT>); + + EXPECT_TRUE(tester.Test([](VecT* vec) { + vec->clear(); // + })); } } // namespace
diff --git a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc index d2435ed8..7f9e8dd 100644 --- a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc +++ b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
@@ -199,7 +199,7 @@ SetHashtablezSampleParameter(100); int64_t num_sampled = 0; int64_t total = 0; - double sample_rate; + double sample_rate = 0.0; for (int i = 0; i < 1000000; ++i) { HashtablezInfoHandle h = Sample(); ++total;
diff --git a/third_party/abseil-cpp/absl/container/internal/inlined_vector.h b/third_party/abseil-cpp/absl/container/internal/inlined_vector.h index a2b3d24d..f4eb92e 100644 --- a/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +++ b/third_party/abseil-cpp/absl/container/internal/inlined_vector.h
@@ -22,6 +22,7 @@ #include <utility> #include "absl/container/internal/compressed_tuple.h" +#include "absl/memory/memory.h" #include "absl/meta/type_traits.h" namespace absl { @@ -35,15 +36,7 @@ template <typename AllocatorType, typename ValueType, typename SizeType> void DestroyElements(AllocatorType* alloc_ptr, ValueType* destroy_first, SizeType destroy_size) { - using AllocatorTraits = std::allocator_traits<AllocatorType>; - - // Destroys `destroy_size` elements from `destroy_first`. - // - // Destroys the range - // [`destroy_first`, `destroy_first + destroy_size`). - // - // NOTE: We assume destructors do not throw and thus make no attempt to roll - // back. + using AllocatorTraits = absl::allocator_traits<AllocatorType>; for (SizeType i = 0; i < destroy_size; ++i) { AllocatorTraits::destroy(*alloc_ptr, destroy_first + i); } @@ -59,6 +52,16 @@ #endif // NDEBUG } +template <typename AllocatorType> +struct StorageView { + using pointer = typename AllocatorType::pointer; + using size_type = typename AllocatorType::size_type; + + pointer data; + size_type size; + size_type capacity; +}; + template <typename T, size_t N, typename A> class Storage { public: @@ -75,11 +78,17 @@ using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; - using AllocatorTraits = std::allocator_traits<allocator_type>; + using AllocatorTraits = absl::allocator_traits<allocator_type>; + + using StorageView = inlined_vector_internal::StorageView<allocator_type>; + + Storage() : metadata_() {} explicit Storage(const allocator_type& alloc) : metadata_(alloc, /* empty and inlined */ 0) {} + ~Storage() { DestroyAndDeallocate(); } + size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; } bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; } @@ -104,6 +113,13 @@ return data_.allocated.allocated_capacity; } + StorageView MakeStorageView() { + return GetIsAllocated() ? StorageView{GetAllocatedData(), GetSize(), + GetAllocatedCapacity()} + : StorageView{GetInlinedData(), GetSize(), + static_cast<size_type>(N)}; + } + allocator_type* GetAllocPtr() { return std::addressof(metadata_.template get<0>()); } @@ -120,9 +136,8 @@ void AddSize(size_type count) { GetSizeAndIsAllocated() += count << 1; } - void SetAllocatedData(pointer data) { data_.allocated.allocated_data = data; } - - void SetAllocatedCapacity(size_type capacity) { + void SetAllocatedData(pointer data, size_type capacity) { + data_.allocated.allocated_data = data; data_.allocated.allocated_capacity = capacity; } @@ -136,6 +151,8 @@ swap(data_.allocated, other->data_.allocated); } + void DestroyAndDeallocate(); + private: size_type& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } @@ -166,6 +183,20 @@ Data data_; }; +template <typename T, size_t N, typename A> +void Storage<T, N, A>::DestroyAndDeallocate() { + namespace ivi = inlined_vector_internal; + + StorageView storage_view = MakeStorageView(); + + ivi::DestroyElements(GetAllocPtr(), storage_view.data, storage_view.size); + + if (GetIsAllocated()) { + AllocatorTraits::deallocate(*GetAllocPtr(), storage_view.data, + storage_view.capacity); + } +} + } // namespace inlined_vector_internal } // namespace absl
diff --git a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h index 02030bd1..c4889cd4 100644 --- a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +++ b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
@@ -350,7 +350,7 @@ return BitMask<uint32_t, kWidth>( _mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))); #else - return Match(kEmpty); + return Match(static_cast<h2_t>(kEmpty)); #endif }
diff --git a/third_party/abseil-cpp/absl/debugging/BUILD.bazel b/third_party/abseil-cpp/absl/debugging/BUILD.bazel index e4aed5e..913cfaf 100644 --- a/third_party/abseil-cpp/absl/debugging/BUILD.bazel +++ b/third_party/abseil-cpp/absl/debugging/BUILD.bazel
@@ -61,6 +61,7 @@ ":demangle_internal", "//absl/base", "//absl/base:core_headers", + "//absl/base:dynamic_annotations", "//absl/base:malloc_internal", ], )
diff --git a/third_party/abseil-cpp/absl/debugging/CMakeLists.txt b/third_party/abseil-cpp/absl/debugging/CMakeLists.txt index d813fede..001e2727 100644 --- a/third_party/abseil-cpp/absl/debugging/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/debugging/CMakeLists.txt
@@ -50,6 +50,7 @@ absl::demangle_internal absl::base absl::core_headers + absl::dynamic_annotations absl::malloc_internal PUBLIC )
diff --git a/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h b/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h index 99b375800..d84200d 100644 --- a/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +++ b/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h
@@ -34,7 +34,7 @@ #define ABSL_HAVE_ELF_MEM_IMAGE 1 #endif -#if ABSL_HAVE_ELF_MEM_IMAGE +#ifdef ABSL_HAVE_ELF_MEM_IMAGE #include <link.h> // for ElfW
diff --git a/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc b/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc index 7ed3bd3..5a55f29d 100644 --- a/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +++ b/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc
@@ -23,7 +23,7 @@ #include <DbgHelp.h> #pragma warning(pop) -#pragma comment(lib, "DbgHelp") +#pragma comment(lib, "dbghelp.lib") #include <algorithm> #include <cstring>
diff --git a/third_party/abseil-cpp/absl/flags/internal/flag.h b/third_party/abseil-cpp/absl/flags/internal/flag.h index 6402866f..9b32f46 100644 --- a/third_party/abseil-cpp/absl/flags/internal/flag.h +++ b/third_party/abseil-cpp/absl/flags/internal/flag.h
@@ -56,7 +56,7 @@ // forward declared types. // auto IsCopyConstructible(const T& v) -> decltype(T(v)); // auto HasAbslParseFlag(absl::string_view in, T* dst, std::string* err) - // -> decltype(AbslParseFlag(in, dst, GlobalStringADLGuard(err))); + // -> decltype(AbslParseFlag(in, dst, err)); // auto HasAbslUnparseFlag(const T& v) -> decltype(AbslUnparseFlag(v)); };
diff --git a/third_party/abseil-cpp/absl/flags/marshalling.h b/third_party/abseil-cpp/absl/flags/marshalling.h index 669cf452..7eb75cd 100644 --- a/third_party/abseil-cpp/absl/flags/marshalling.h +++ b/third_party/abseil-cpp/absl/flags/marshalling.h
@@ -185,18 +185,11 @@ bool AbslParseFlag(absl::string_view, std::string*, std::string*); bool AbslParseFlag(absl::string_view, std::vector<std::string>*, std::string*); -struct GlobalStringADLGuard { - explicit GlobalStringADLGuard(std::string* p) : ptr(p) {} - operator std::string*() { return ptr; } // NOLINT - std::string* ptr; -}; - template <typename T> bool InvokeParseFlag(absl::string_view input, T* dst, std::string* err) { // Comment on next line provides a good compiler error message if T // does not have AbslParseFlag(absl::string_view, T*, std::string*). - return AbslParseFlag( // Is T missing AbslParseFlag? - input, dst, GlobalStringADLGuard(err)); + return AbslParseFlag(input, dst, err); // Is T missing AbslParseFlag? } // Strings and std:: containers do not have the same overload resolution
diff --git a/third_party/abseil-cpp/absl/hash/hash_test.cc b/third_party/abseil-cpp/absl/hash/hash_test.cc index 449e77b..bab560bd 100644 --- a/third_party/abseil-cpp/absl/hash/hash_test.cc +++ b/third_party/abseil-cpp/absl/hash/hash_test.cc
@@ -524,6 +524,7 @@ template <InvokeTag... Tags> struct CustomHashType { + explicit CustomHashType(size_t val) : value(val) {} size_t value; }; @@ -590,7 +591,7 @@ EXPECT_TRUE(is_hashable<const type&>()); const size_t offset = static_cast<int>(std::min({T::value...})); - EXPECT_EQ(SpyHash(type{7}), SpyHash(size_t{7 + offset})); + EXPECT_EQ(SpyHash(type(7)), SpyHash(size_t{7 + offset})); } void TestCustomHashType(InvokeTagConstant<InvokeTag::kNone>) {
diff --git a/third_party/abseil-cpp/absl/strings/str_cat.h b/third_party/abseil-cpp/absl/strings/str_cat.h index 559ee0aa..a99aac0 100644 --- a/third_party/abseil-cpp/absl/strings/str_cat.h +++ b/third_party/abseil-cpp/absl/strings/str_cat.h
@@ -37,7 +37,8 @@ // attempt to pass ':' instead of ":" might result in a 58 ending up in your // result. // -// Bools convert to "0" or "1". +// Bools convert to "0" or "1". Pointers to types other than `char *` are not +// valid inputs. No output is generated for null `char *` pointers. // // Floating point numbers are formatted with six-digit precision, which is // the default for "std::cout <<" or printf "%g" (the same as "%.6g").
diff --git a/third_party/abseil-cpp/absl/strings/str_format.h b/third_party/abseil-cpp/absl/strings/str_format.h index da3208e1..0b93c28 100644 --- a/third_party/abseil-cpp/absl/strings/str_format.h +++ b/third_party/abseil-cpp/absl/strings/str_format.h
@@ -20,7 +20,8 @@ // The `str_format` library is a typesafe replacement for the family of // `printf()` string formatting routines within the `<cstdio>` standard library // header. Like the `printf` family, the `str_format` uses a "format string" to -// perform argument substitutions based on types. +// perform argument substitutions based on types. See the `FormatSpec` section +// below for format string documentation. // // Example: // @@ -67,6 +68,7 @@ // In addition, the `str_format` library provides extension points for // augmenting formatting to new types. These extensions are fully documented // within the `str_format_extension.h` header file. + #ifndef ABSL_STRINGS_STR_FORMAT_H_ #define ABSL_STRINGS_STR_FORMAT_H_ @@ -211,6 +213,11 @@ // written to this point. The resulting value must be captured within an // `absl::FormatCountCapture` type. // +// Implementation-defined behavior: +// * A null pointer provided to "%s" or "%p" is output as "(nil)". +// * A non-null pointer provided to "%p" is output in hex as if by %#x or +// %#lx. +// // NOTE: `o`, `x\X` and `u` will convert signed values to their unsigned // counterpart before formatting. // @@ -226,7 +233,7 @@ // "%e", .01 -> "1.00000e-2" // "%a", -3.0 -> "-0x1.8p+1" // "%g", .01 -> "1e-2" -// "%p", *int -> "0x7ffdeb6ad2a4" +// "%p", (void*)&value -> "0x7ffdeb6ad2a4" // // int n = 0; // std::string s = absl::StrFormat(
diff --git a/third_party/abseil-cpp/absl/strings/str_format_test.cc b/third_party/abseil-cpp/absl/strings/str_format_test.cc index 80830b3..96c6234 100644 --- a/third_party/abseil-cpp/absl/strings/str_format_test.cc +++ b/third_party/abseil-cpp/absl/strings/str_format_test.cc
@@ -271,7 +271,7 @@ EXPECT_EQ(errno, EBADF); } -#if __GLIBC__ +#ifdef __GLIBC__ TEST_F(FormatEntryPointTest, FprintfTooLarge) { std::FILE* f = std::fopen("/dev/null", "w"); int width = 2000000000;
diff --git a/third_party/abseil-cpp/absl/strings/substitute.h b/third_party/abseil-cpp/absl/strings/substitute.h index 32dec30b..233e9dc 100644 --- a/third_party/abseil-cpp/absl/strings/substitute.h +++ b/third_party/abseil-cpp/absl/strings/substitute.h
@@ -35,10 +35,13 @@ // and single digit positional ids to indicate which substitution arguments to // use at that location within the format string. // +// A '$$' sequence in the format string causes a literal '$' character to be +// output. +// // Example 1: -// std::string s = Substitute("$1 purchased $0 $2. Thanks $1!", +// std::string s = Substitute("$1 purchased $0 $2 for $$10. Thanks $1!", // 5, "Bob", "Apples"); -// EXPECT_EQ("Bob purchased 5 Apples. Thanks Bob!", s); +// EXPECT_EQ("Bob purchased 5 Apples for $10. Thanks Bob!", s); // // Example 2: // std::string s = "Hi. ";
diff --git a/third_party/abseil-cpp/absl/time/civil_time.h b/third_party/abseil-cpp/absl/time/civil_time.h index 2dfcbd27..6bb7eec 100644 --- a/third_party/abseil-cpp/absl/time/civil_time.h +++ b/third_party/abseil-cpp/absl/time/civil_time.h
@@ -407,9 +407,9 @@ // // absl::CivilDay d = ... // // Gets the following Thursday if d is not already Thursday -// absl::CivilDay thurs1 = absl::PrevWeekday(d, absl::Weekday::thursday) + 7; +// absl::CivilDay thurs1 = absl::NextWeekday(d - 1, absl::Weekday::thursday); // // Gets the previous Thursday if d is not already Thursday -// absl::CivilDay thurs2 = absl::NextWeekday(d, absl::Weekday::thursday) - 7; +// absl::CivilDay thurs2 = absl::PrevWeekday(d + 1, absl::Weekday::thursday); // inline CivilDay NextWeekday(CivilDay cd, Weekday wd) { return CivilDay(time_internal::cctz::next_weekday(cd, wd));
diff --git a/third_party/abseil-cpp/absl/time/civil_time_test.cc b/third_party/abseil-cpp/absl/time/civil_time_test.cc index b8d5713..070f0d5 100644 --- a/third_party/abseil-cpp/absl/time/civil_time_test.cc +++ b/third_party/abseil-cpp/absl/time/civil_time_test.cc
@@ -1028,7 +1028,7 @@ TEST(CivilTime, FirstThursdayInMonth) { const absl::CivilDay nov1(2014, 11, 1); const absl::CivilDay thursday = - absl::PrevWeekday(nov1, absl::Weekday::thursday) + 7; + absl::NextWeekday(nov1 - 1, absl::Weekday::thursday); EXPECT_EQ("2014-11-06", absl::FormatCivilTime(thursday)); // Bonus: Date of Thanksgiving in the United States
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h b/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h index f844182..aa578ee 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h +++ b/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h
@@ -306,9 +306,9 @@ // // civil_day d = ... // // Gets the following Thursday if d is not already Thursday -// civil_day thurs1 = prev_weekday(d, weekday::thursday) + 7; +// civil_day thurs1 = next_weekday(d - 1, weekday::thursday); // // Gets the previous Thursday if d is not already Thursday -// civil_day thurs2 = next_weekday(d, weekday::thursday) - 7; +// civil_day thurs2 = prev_weekday(d + 1, weekday::thursday); // using detail::next_weekday; using detail::prev_weekday;
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc index dc7e5a1d..b1f46f1 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc
@@ -1035,7 +1035,7 @@ TEST(CivilTime, FirstThursdayInMonth) { const civil_day nov1(2014, 11, 1); - const civil_day thursday = prev_weekday(nov1, weekday::thursday) + 7; + const civil_day thursday = next_weekday(nov1 - 1, weekday::thursday); EXPECT_EQ("2014-11-06", Format(thursday)); // Bonus: Date of Thanksgiving in the United States
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc index 81ece72..b0d159a2 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc
@@ -27,7 +27,7 @@ namespace { // The prefix used for the internal names of fixed-offset zones. -const char kFixedOffsetPrefix[] = "Fixed/UTC"; +const char kFixedZonePrefix[] = "Fixed/UTC"; const char kDigits[] = "0123456789"; @@ -55,11 +55,11 @@ return true; } - const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1; - const char* const ep = kFixedOffsetPrefix + prefix_len; + const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; + const char* const ep = kFixedZonePrefix + prefix_len; if (name.size() != prefix_len + 9) // <prefix>+99:99:99 return false; - if (!std::equal(kFixedOffsetPrefix, ep, name.begin())) + if (!std::equal(kFixedZonePrefix, ep, name.begin())) return false; const char* np = name.data() + prefix_len; if (np[0] != '+' && np[0] != '-') @@ -102,9 +102,9 @@ } int hours = minutes / 60; minutes %= 60; - char buf[sizeof(kFixedOffsetPrefix) - 1 + sizeof("-24:00:00")]; - std::strcpy(buf, kFixedOffsetPrefix); - char* ep = buf + sizeof(kFixedOffsetPrefix) - 1; + const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; + char buf[prefix_len + sizeof("-24:00:00")]; + char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf); *ep++ = sign; ep = Format02d(ep, hours); *ep++ = ':'; @@ -118,7 +118,7 @@ std::string FixedOffsetToAbbr(const seconds& offset) { std::string abbr = FixedOffsetToName(offset); - const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1; + const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; if (abbr.size() == prefix_len + 9) { // <prefix>+99:99:99 abbr.erase(0, prefix_len); // +99:99:99 abbr.erase(6, 1); // +99:9999
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc index 50f7de54..184bd43 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc
@@ -682,7 +682,6 @@ // Use of the "file:" prefix is intended for testing purposes only. if (name.compare(0, 5, "file:") == 0) return Open(name.substr(5)); -#if defined(__ANDROID__) // See Android's libc/tzcode/bionic.cpp for additional information. for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", "/system/usr/share/zoneinfo/tzdata"}) { @@ -717,7 +716,7 @@ } } } -#endif // __ANDROID__ + return nullptr; }
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc index 3ab1623c..6095e764 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc
@@ -21,7 +21,6 @@ #include <chrono> #include <ctime> #include <limits> -#include <tuple> #include <utility> #include "absl/time/internal/cctz/include/cctz/civil_time.h" @@ -33,57 +32,75 @@ namespace { -// .first is seconds east of UTC; .second is the time-zone abbreviation. -using OffsetAbbr = std::pair<int, const char*>; - -// Defines a function that can be called as follows: -// -// std::tm tm = ...; -// OffsetAbbr off_abbr = get_offset_abbr(tm); -// #if defined(_WIN32) || defined(_WIN64) // Uses the globals: '_timezone', '_dstbias' and '_tzname'. -OffsetAbbr get_offset_abbr(const std::tm& tm) { +auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + _dstbias) { const bool is_dst = tm.tm_isdst > 0; - const int off = _timezone + (is_dst ? _dstbias : 0); - const char* abbr = _tzname[is_dst]; - return {off, abbr}; + return _timezone + (is_dst ? _dstbias : 0); +} +auto tm_zone(const std::tm& tm) -> decltype(_tzname[0]) { + const bool is_dst = tm.tm_isdst > 0; + return _tzname[is_dst]; } #elif defined(__sun) // Uses the globals: 'timezone', 'altzone' and 'tzname'. -OffsetAbbr get_offset_abbr(const std::tm& tm) { +auto tm_gmtoff(const std::tm& tm) -> decltype(timezone) { const bool is_dst = tm.tm_isdst > 0; - const int off = is_dst ? altzone : timezone; - const char* abbr = tzname[is_dst]; - return {off, abbr}; + return is_dst ? altzone : timezone; +} +auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) { + const bool is_dst = tm.tm_isdst > 0; + return tzname[is_dst]; } #elif defined(__native_client__) || defined(__myriad2__) || \ defined(__EMSCRIPTEN__) // Uses the globals: 'timezone' and 'tzname'. -OffsetAbbr get_offset_abbr(const std::tm& tm) { +auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) { const bool is_dst = tm.tm_isdst > 0; - const int off = _timezone + (is_dst ? 60 * 60 : 0); - const char* abbr = tzname[is_dst]; - return {off, abbr}; + return _timezone + (is_dst ? 60 * 60 : 0); +} +auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) { + const bool is_dst = tm.tm_isdst > 0; + return tzname[is_dst]; } #else -// -// Returns an OffsetAbbr using std::tm fields with various spellings. -// -#if !defined(tm_gmtoff) && !defined(tm_zone) -template <typename T> -OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::tm_gmtoff) = nullptr, - decltype(&T::tm_zone) = nullptr) { - return {tm.tm_gmtoff, tm.tm_zone}; +// Adapt to different spellings of the struct std::tm extension fields. +#if defined(tm_gmtoff) +auto tm_gmtoff(const std::tm& tm) -> decltype(tm.tm_gmtoff) { + return tm.tm_gmtoff; } -#endif // !defined(tm_gmtoff) && !defined(tm_zone) -#if !defined(__tm_gmtoff) && !defined(__tm_zone) -template <typename T> -OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::__tm_gmtoff) = nullptr, - decltype(&T::__tm_zone) = nullptr) { - return {tm.__tm_gmtoff, tm.__tm_zone}; +#elif defined(__tm_gmtoff) +auto tm_gmtoff(const std::tm& tm) -> decltype(tm.__tm_gmtoff) { + return tm.__tm_gmtoff; } -#endif // !defined(__tm_gmtoff) && !defined(__tm_zone) +#else +template <typename T> +auto tm_gmtoff(const T& tm) -> decltype(tm.tm_gmtoff) { + return tm.tm_gmtoff; +} +template <typename T> +auto tm_gmtoff(const T& tm) -> decltype(tm.__tm_gmtoff) { + return tm.__tm_gmtoff; +} +#endif // tm_gmtoff +#if defined(tm_zone) +auto tm_zone(const std::tm& tm) -> decltype(tm.tm_zone) { + return tm.tm_zone; +} +#elif defined(__tm_zone) +auto tm_zone(const std::tm& tm) -> decltype(tm.__tm_zone) { + return tm.__tm_zone; +} +#else +template <typename T> +auto tm_zone(const T& tm) -> decltype(tm.tm_zone) { + return tm.tm_zone; +} +template <typename T> +auto tm_zone(const T& tm) -> decltype(tm.__tm_zone) { + return tm.__tm_zone; +} +#endif // tm_zone #endif inline std::tm* gm_time(const std::time_t *timep, std::tm *result) { @@ -126,7 +143,7 @@ return false; } } - *off = get_offset_abbr(tm).first; + *off = static_cast<int>(tm_gmtoff(tm)); return true; } @@ -137,7 +154,7 @@ while (lo + 1 != hi) { const std::time_t mid = lo + (hi - lo) / 2; if (std::tm* tmp = local_time(&mid, &tm)) { - if (get_offset_abbr(*tmp).first == offset) { + if (tm_gmtoff(*tmp) == offset) { hi = mid; } else { lo = mid; @@ -147,7 +164,7 @@ // ignoring all failed conversions. Slow, but never really happens. while (++lo != hi) { if (std::tm* tmp = local_time(&lo, &tm)) { - if (get_offset_abbr(*tmp).first == offset) break; + if (tm_gmtoff(*tmp) == offset) break; } } return lo; @@ -193,8 +210,8 @@ const year_t year = tmp->tm_year + year_t{1900}; al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - std::tie(al.offset, al.abbr) = get_offset_abbr(*tmp); - if (!local_) al.abbr = "UTC"; // as expected by cctz + al.offset = static_cast<int>(tm_gmtoff(*tmp)); + al.abbr = local_ ? tm_zone(*tmp) : "UTC"; // as expected by cctz al.is_dst = tmp->tm_isdst > 0; return al; }
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc index 13248462..42f50c5 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc
@@ -46,7 +46,13 @@ // A "weak" definition for cctz_extension::zone_info_source_factory. // The user may override this with their own "strong" definition (see // zone_info_source.h). -#if defined(_MSC_VER) +#if !defined(__has_attribute) +#define __has_attribute(x) 0 +#endif +#if __has_attribute(weak) || defined(__GNUC__) +ZoneInfoSourceFactory zone_info_source_factory + __attribute__((weak)) = DefaultFactory; +#elif defined(_MSC_VER) && !defined(_LIBCPP_VERSION) extern ZoneInfoSourceFactory zone_info_source_factory; extern ZoneInfoSourceFactory default_factory; ZoneInfoSourceFactory default_factory = DefaultFactory; @@ -60,19 +66,11 @@ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA=?default_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA") #else #error Unsupported MSVC platform -#endif -#else // _MSC_VER -#if !defined(__has_attribute) -#define __has_attribute(x) 0 -#endif -#if __has_attribute(weak) || defined(__GNUC__) -ZoneInfoSourceFactory zone_info_source_factory - __attribute__((weak)) = DefaultFactory; +#endif // _M_<PLATFORM> #else // Make it a "strong" definition if we have no other choice. ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory; #endif -#endif // _MSC_VER } // namespace cctz_extension } // namespace time_internal
diff --git a/third_party/abseil-cpp/absl/types/BUILD.bazel b/third_party/abseil-cpp/absl/types/BUILD.bazel index 134f9f2..66ecb04 100644 --- a/third_party/abseil-cpp/absl/types/BUILD.bazel +++ b/third_party/abseil-cpp/absl/types/BUILD.bazel
@@ -18,9 +18,9 @@ "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_DEFAULT_LINKOPTS", - "ABSL_TEST_COPTS", "ABSL_EXCEPTIONS_FLAG", "ABSL_EXCEPTIONS_FLAG_LINKOPTS", + "ABSL_TEST_COPTS", ) package(default_visibility = ["//visibility:public"])
diff --git a/third_party/abseil-cpp/absl/types/internal/variant.h b/third_party/abseil-cpp/absl/types/internal/variant.h index 5ca66e2..85201b4a 100644 --- a/third_party/abseil-cpp/absl/types/internal/variant.h +++ b/third_party/abseil-cpp/absl/types/internal/variant.h
@@ -837,8 +837,8 @@ // NOTE: const& and && are used instead of by-value due to lack of guaranteed // move elision of C++17. This may have other minor differences, but tests // pass. - static SizeT<I> Run(const H&); - static SizeT<I> Run(H&&); + static SizeT<I> Run(const H&, SizeT<I>); + static SizeT<I> Run(H&&, SizeT<I>); }; // The following metafunctions are used in constructor and assignment @@ -860,7 +860,8 @@ template <class Variant, class T> struct ConversionIsPossibleImpl< - Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>> + Variant, T, + void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>(), {}))>> : std::true_type {}; template <class Variant, class T> @@ -868,8 +869,9 @@ template <class Variant, class T> struct IndexOfConstructedType< - Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>> - : decltype(ImaginaryFun<Variant>::Run(std::declval<T>())) {}; + Variant, T, + void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>(), {}))>> + : decltype(ImaginaryFun<Variant>::Run(std::declval<T>(), {})) {}; template <std::size_t... Is> struct ContainsVariantNPos
diff --git a/third_party/abseil-cpp/absl/types/variant_test.cc b/third_party/abseil-cpp/absl/types/variant_test.cc index b9c98118..d7024827 100644 --- a/third_party/abseil-cpp/absl/types/variant_test.cc +++ b/third_party/abseil-cpp/absl/types/variant_test.cc
@@ -460,6 +460,11 @@ EXPECT_EQ(value.value, mutable_valptr->value); } +TEST(VariantTest, AmbiguousValueConstructor) { + EXPECT_FALSE((std::is_convertible<int, absl::variant<int, int>>::value)); + EXPECT_FALSE((std::is_constructible<absl::variant<int, int>, int>::value)); +} + TEST(VariantTest, InPlaceType) { using Var = variant<int, std::string, NonCopyable, std::vector<int>>;
diff --git a/third_party/blink/common/manifest/manifest.cc b/third_party/blink/common/manifest/manifest.cc index dc5e625..e27e230 100644 --- a/third_party/blink/common/manifest/manifest.cc +++ b/third_party/blink/common/manifest/manifest.cc
@@ -44,8 +44,8 @@ orientation == blink::kWebScreenOrientationLockDefault && icons.empty() && !share_target.has_value() && related_applications.empty() && !prefer_related_applications && - !theme_color && !background_color && splash_screen_url.is_empty() && - gcm_sender_id.is_null() && scope.is_empty(); + !theme_color && !background_color && gcm_sender_id.is_null() && + scope.is_empty(); } } // namespace blink
diff --git a/third_party/blink/common/manifest/manifest_mojom_traits.cc b/third_party/blink/common/manifest/manifest_mojom_traits.cc index 8cf99a12..0f09a63 100644 --- a/third_party/blink/common/manifest/manifest_mojom_traits.cc +++ b/third_party/blink/common/manifest/manifest_mojom_traits.cc
@@ -84,9 +84,6 @@ if (data.has_background_color()) out->background_color = data.background_color(); - if (!data.ReadSplashScreenUrl(&out->splash_screen_url)) - return false; - if (!data.ReadDisplay(&out->display)) return false;
diff --git a/third_party/blink/perf_tests/websocket/receive-arraybuffer-1MBx100.html b/third_party/blink/perf_tests/websocket/receive-arraybuffer-1MBx100.html index 3641c5c..563cd327 100644 --- a/third_party/blink/perf_tests/websocket/receive-arraybuffer-1MBx100.html +++ b/third_party/blink/perf_tests/websocket/receive-arraybuffer-1MBx100.html
@@ -27,13 +27,15 @@ } }); const [openTime, closeTime] = await Promise.all([onOpen, onClose]); - PerfTestRunner.measureValueAsync(closeTime - openTime); + const executeTimeInSeconds = (closeTime - openTime) / 1000; + const downloadSpeedInMegaBytesPerSecond = 100 / executeTimeInSeconds; + PerfTestRunner.measureValueAsync(downloadSpeedInMegaBytesPerSecond); } let isDone = false; PerfTestRunner.startMeasureValuesAsync({ description: "Measure performance of receiving 1MB array 100 times.", - unit: 'ms', + unit: 'MB/s', done: function () { isDone = true; },
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 2b4e5ac..f02ba9a 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -379,6 +379,7 @@ "web/modules/mediastream/media_stream_video_track.h", "web/modules/mediastream/video_track_adapter_settings.h", "web/modules/mediastream/web_media_stream_utils.h", + "web/modules/mediastream/webaudio_media_stream_audio_sink.h", "web/modules/service_worker/web_service_worker_context_client.h", "web/modules/service_worker/web_service_worker_context_proxy.h", "web/web_active_fling_parameters.h",
diff --git a/third_party/blink/public/common/manifest/manifest.h b/third_party/blink/public/common/manifest/manifest.h index fdac3521..e53e85d 100644 --- a/third_party/blink/public/common/manifest/manifest.h +++ b/third_party/blink/public/common/manifest/manifest.h
@@ -190,10 +190,6 @@ // Null if field is not present or parsing failed. base::Optional<SkColor> background_color; - // A URL of the HTML splash screen. - // Empty if the parsing failed or the field was not present. - GURL splash_screen_url; - // This is a proprietary extension of the web Manifest, double-check that it // is okay to use this entry. // Null if parsing failed or the field was not present.
diff --git a/third_party/blink/public/common/manifest/manifest_mojom_traits.h b/third_party/blink/public/common/manifest/manifest_mojom_traits.h index 51d9108..eb53cc4 100644 --- a/third_party/blink/public/common/manifest/manifest_mojom_traits.h +++ b/third_party/blink/public/common/manifest/manifest_mojom_traits.h
@@ -92,10 +92,6 @@ return m.background_color.value_or(0); } - static const GURL& splash_screen_url(const ::blink::Manifest& manifest) { - return manifest.splash_screen_url; - } - static const std::vector<::blink::Manifest::ImageResource>& icons( const ::blink::Manifest& manifest) { return manifest.icons;
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom index cdaac79..44f7c7d 100644 --- a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom +++ b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
@@ -118,7 +118,7 @@ // Note: When updating this struct, also update // content/common/fetch/fetch_request_type_converters.cc. struct FetchAPIRequest { - network.mojom.FetchRequestMode mode = network.mojom.FetchRequestMode.kNoCors; + network.mojom.RequestMode mode = network.mojom.RequestMode.kNoCors; bool is_main_resource_load = false; RequestContextType request_context_type = RequestContextType.UNSPECIFIED; network.mojom.RequestContextFrameType frame_type = @@ -136,11 +136,11 @@ network.mojom.URLRequestBody? body; Referrer? referrer; - network.mojom.FetchCredentialsMode credentials_mode = - network.mojom.FetchCredentialsMode.kOmit; + network.mojom.CredentialsMode credentials_mode = + network.mojom.CredentialsMode.kOmit; FetchCacheMode cache_mode = FetchCacheMode.kDefault; - network.mojom.FetchRedirectMode redirect_mode = - network.mojom.FetchRedirectMode.kFollow; + network.mojom.RedirectMode redirect_mode = + network.mojom.RedirectMode.kFollow; string? integrity; network.mojom.RequestPriority priority = network.mojom.RequestPriority.kIdle;
diff --git a/third_party/blink/public/mojom/manifest/manifest.mojom b/third_party/blink/public/mojom/manifest/manifest.mojom index 5ba1207..d4da11e 100644 --- a/third_party/blink/public/mojom/manifest/manifest.mojom +++ b/third_party/blink/public/mojom/manifest/manifest.mojom
@@ -55,9 +55,6 @@ bool has_background_color; uint32 background_color; - // A URL of the HTML splash screen. - url.mojom.Url splash_screen_url; - mojo_base.mojom.String16? gcm_sender_id; url.mojom.Url scope;
diff --git a/third_party/blink/public/mojom/permissions/permission.mojom b/third_party/blink/public/mojom/permissions/permission.mojom index a2fb50c..dd220391 100644 --- a/third_party/blink/public/mojom/permissions/permission.mojom +++ b/third_party/blink/public/mojom/permissions/permission.mojom
@@ -23,6 +23,15 @@ BACKGROUND_FETCH, IDLE_DETECTION, PERIODIC_BACKGROUND_SYNC, + WAKE_LOCK, +}; + +// This is similar to WakeLockType in modules/wake_lock/wake_lock.idl. +// We also have device.mojom.WakeLockType, but it has more types than what we +// handle in the Wake Lock API. +enum WakeLockType { + kScreen, + kSystem, }; struct MidiPermissionDescriptor { @@ -33,10 +42,15 @@ bool allowWithoutGesture; }; +struct WakeLockPermissionDescriptor { + WakeLockType type; +}; + // Union of possible extensions to the base PermissionDescriptor type. union PermissionDescriptorExtension { MidiPermissionDescriptor midi; ClipboardPermissionDescriptor clipboard; + WakeLockPermissionDescriptor wake_lock; }; // This struct roughly corresponds to the PermissionDescriptor dictionary as
diff --git a/third_party/blink/public/mojom/worker/dedicated_worker_host_factory.mojom b/third_party/blink/public/mojom/worker/dedicated_worker_host_factory.mojom index baa807ae..067dd9f 100644 --- a/third_party/blink/public/mojom/worker/dedicated_worker_host_factory.mojom +++ b/third_party/blink/public/mojom/worker/dedicated_worker_host_factory.mojom
@@ -83,7 +83,7 @@ CreateWorkerHostAndStartScriptLoad( url.mojom.Url script_url, url.mojom.Origin origin, - network.mojom.FetchCredentialsMode credentials_mode, + network.mojom.CredentialsMode credentials_mode, blink.mojom.BlobURLToken? blob_url_token, DedicatedWorkerHostFactoryClient client); };
diff --git a/third_party/blink/public/platform/web_dedicated_worker_host_factory_client.h b/third_party/blink/public/platform/web_dedicated_worker_host_factory_client.h index 6baa3ebe..ed3b9302 100644 --- a/third_party/blink/public/platform/web_dedicated_worker_host_factory_client.h +++ b/third_party/blink/public/platform/web_dedicated_worker_host_factory_client.h
@@ -35,7 +35,7 @@ virtual void CreateWorkerHost( const blink::WebURL& script_url, const blink::WebSecurityOrigin& script_origin, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, mojo::ScopedMessagePipeHandle blob_url_token) = 0; // Clones the given WebWorkerFetchContext for nested workers.
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h index bdbfc0b..0461bac0 100644 --- a/third_party/blink/public/platform/web_url_request.h +++ b/third_party/blink/public/platform/web_url_request.h
@@ -43,9 +43,9 @@ namespace network { namespace mojom { enum class CorsPreflightPolicy : int32_t; -enum class FetchCredentialsMode : int32_t; -enum class FetchRedirectMode : int32_t; -enum class FetchRequestMode : int32_t; +enum class CredentialsMode : int32_t; +enum class RedirectMode : int32_t; +enum class RequestMode : int32_t; enum class RequestContextFrameType : int32_t; } // namespace mojom } // namespace network @@ -290,22 +290,18 @@ BLINK_PLATFORM_EXPORT void SetShouldResetAppCache(bool); // The request mode which will be passed to the ServiceWorker. - BLINK_PLATFORM_EXPORT network::mojom::FetchRequestMode GetFetchRequestMode() - const; - BLINK_PLATFORM_EXPORT void SetFetchRequestMode( - network::mojom::FetchRequestMode); + BLINK_PLATFORM_EXPORT network::mojom::RequestMode GetMode() const; + BLINK_PLATFORM_EXPORT void SetMode(network::mojom::RequestMode); // The credentials mode which will be passed to the ServiceWorker. - BLINK_PLATFORM_EXPORT network::mojom::FetchCredentialsMode - GetFetchCredentialsMode() const; - BLINK_PLATFORM_EXPORT void SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode); + BLINK_PLATFORM_EXPORT network::mojom::CredentialsMode GetCredentialsMode() + const; + BLINK_PLATFORM_EXPORT void SetCredentialsMode( + network::mojom::CredentialsMode); // The redirect mode which is used in Fetch API. - BLINK_PLATFORM_EXPORT network::mojom::FetchRedirectMode GetFetchRedirectMode() - const; - BLINK_PLATFORM_EXPORT void SetFetchRedirectMode( - network::mojom::FetchRedirectMode); + BLINK_PLATFORM_EXPORT network::mojom::RedirectMode GetRedirectMode() const; + BLINK_PLATFORM_EXPORT void SetRedirectMode(network::mojom::RedirectMode); // The integrity which is used in Fetch API. BLINK_PLATFORM_EXPORT WebString GetFetchIntegrity() const;
diff --git a/third_party/blink/public/web/modules/mediastream/DEPS b/third_party/blink/public/web/modules/mediastream/DEPS index 9ef7b3b..6e24a703 100644 --- a/third_party/blink/public/web/modules/mediastream/DEPS +++ b/third_party/blink/public/web/modules/mediastream/DEPS
@@ -8,7 +8,7 @@ "+base/gtest_prod_util.h", "+base/memory/weak_ptr.h", "+base/sequence_checker.h", - "+base/single_thread_task_runner.h", + "+base/synchronization/lock.h", "+base/threading/thread_checker.h", "+media/base", "+media/capture",
diff --git a/content/renderer/media/webrtc_local_audio_source_provider.h b/third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h similarity index 70% rename from content/renderer/media/webrtc_local_audio_source_provider.h rename to third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h index 930c02f..6ad584f 100644 --- a/content/renderer/media/webrtc_local_audio_source_provider.h +++ b/third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.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 CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_SOURCE_PROVIDER_H_ -#define CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_SOURCE_PROVIDER_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_ #include <stddef.h> @@ -12,13 +12,12 @@ #include "base/macros.h" #include "base/synchronization/lock.h" -#include "base/thread_annotations.h" #include "base/time/time.h" -#include "content/common/content_export.h" #include "media/base/audio_converter.h" #include "media/base/reentrancy_checker.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h" #include "third_party/blink/public/platform/web_audio_source_provider.h" +#include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/platform/web_vector.h" @@ -27,50 +26,45 @@ class AudioConverter; class AudioFifo; class AudioParameters; -} +} // namespace media namespace blink { + class WebAudioSourceProviderClient; -} -namespace content { - -// TODO(miu): This implementation should be renamed to WebAudioMediaStreamSink, -// as it should work as a provider for WebAudio from ANY MediaStreamAudioTrack. -// http://crbug.com/577874 +// WebAudioMediaStreamAudioSink provides a bridge between classes: +// MediaStreamAudioTrack ---> WebAudioSourceProvider // -// WebRtcLocalAudioSourceProvider provides a bridge between classes: -// MediaStreamAudioTrack ---> blink::WebAudioSourceProvider -// -// WebRtcLocalAudioSourceProvider works as a sink to the MediaStreamAudioTrack +// WebAudioMediaStreamAudioSink works as a sink to the MediaStreamAudioTrack // and stores the capture data to a FIFO. When the media stream is connected to // WebAudio MediaStreamAudioSourceNode as a source provider, // MediaStreamAudioSourceNode will periodically call provideInput() to get the // data from the FIFO. // // Most calls are protected by a lock. -class CONTENT_EXPORT WebRtcLocalAudioSourceProvider - : public blink::WebAudioSourceProvider, +// +// TODO(crbug.com/704136): Move this class out of the Blink exposed API +// when all users of it have been Onion souped. +class BLINK_MODULES_EXPORT WebAudioMediaStreamAudioSink + : public WebAudioSourceProvider, public media::AudioConverter::InputCallback, - public blink::WebMediaStreamAudioSink { + public WebMediaStreamAudioSink { public: static const size_t kWebAudioRenderBufferSize; - explicit WebRtcLocalAudioSourceProvider( - const blink::WebMediaStreamTrack& track, - int context_sample_rate); - ~WebRtcLocalAudioSourceProvider() override; + explicit WebAudioMediaStreamAudioSink(const WebMediaStreamTrack& track, + int context_sample_rate); + ~WebAudioMediaStreamAudioSink() override; - // blink::WebMediaStreamAudioSink implementation. + // WebMediaStreamAudioSink implementation. void OnData(const media::AudioBus& audio_bus, base::TimeTicks estimated_capture_time) override; void OnSetFormat(const media::AudioParameters& params) override; - void OnReadyStateChanged( - blink::WebMediaStreamSource::ReadyState state) override; + void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) override; - // blink::WebAudioSourceProvider implementation. - void SetClient(blink::WebAudioSourceProviderClient* client) override; - void ProvideInput(const blink::WebVector<float*>& audio_data, + // WebAudioSourceProvider implementation. + void SetClient(WebAudioSourceProviderClient* client) override; + void ProvideInput(const WebVector<float*>& audio_data, size_t number_of_frames) override; // Method to allow the unittests to inject its own sink parameters to avoid @@ -105,7 +99,7 @@ // The audio track that this source provider is connected to. // No lock protection needed since only accessed in constructor and // destructor. - blink::WebMediaStreamTrack track_; + WebMediaStreamTrack track_; // Flag to tell if the track has been stopped or not. // No lock protection needed since only accessed in constructor, destructor @@ -122,9 +116,9 @@ // Used to assert that OnReadyStateChanged() is not accessed concurrently. REENTRANCY_CHECKER(ready_state_reentrancy_checker_); - DISALLOW_COPY_AND_ASSIGN(WebRtcLocalAudioSourceProvider); + DISALLOW_COPY_AND_ASSIGN(WebAudioMediaStreamAudioSink); }; -} // namespace content +} // namespace blink -#endif // CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_SOURCE_PROVIDER_H_ +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_
diff --git a/third_party/blink/public/web/web_frame.h b/third_party/blink/public/web/web_frame.h index e5dd3db..12966c8 100644 --- a/third_party/blink/public/web/web_frame.h +++ b/third_party/blink/public/web/web_frame.h
@@ -110,7 +110,7 @@ WebInsecureRequestPolicy GetInsecureRequestPolicy() const; // The frame's upgrade insecure navigations set. - std::vector<unsigned> GetInsecureRequestToUpgrade() const; + WebVector<unsigned> GetInsecureRequestToUpgrade() const; // Updates this frame's FrameOwner properties, such as scrolling, margin, // or allowfullscreen. This is used when this frame's parent is in
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index cb6d5321c..c60758e 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -32,7 +32,6 @@ #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_LOCAL_FRAME_CLIENT_H_ #include <memory> -#include <vector> #include "base/unguessable_token.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" @@ -269,7 +268,7 @@ virtual void DidEnforceInsecureRequestPolicy(WebInsecureRequestPolicy) {} // This frame has set an upgrade insecure navigations set. - virtual void DidEnforceInsecureNavigationsSet(const std::vector<unsigned>&) {} + virtual void DidEnforceInsecureNavigationsSet(const WebVector<unsigned>&) {} // The sandbox flags or container policy have changed for a child frame of // this frame.
diff --git a/third_party/blink/public/web/web_remote_frame.h b/third_party/blink/public/web/web_remote_frame.h index 9659f676..344a5aa 100644 --- a/third_party/blink/public/web/web_remote_frame.h +++ b/third_party/blink/public/web/web_remote_frame.h
@@ -106,7 +106,7 @@ // process. virtual void SetReplicatedInsecureRequestPolicy(WebInsecureRequestPolicy) = 0; virtual void SetReplicatedInsecureNavigationsSet( - const std::vector<unsigned>&) = 0; + const WebVector<unsigned>&) = 0; // Reports resource timing info for a navigation in this frame. virtual void ForwardResourceTimingToParent(const WebResourceTimingInfo&) = 0;
diff --git a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc index ecc6988e..f4d42df 100644 --- a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc +++ b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
@@ -39,7 +39,7 @@ v8::Local<v8::Primitive> credentials_mode_value = host_defined_options->Get(isolate, kCredentialsMode); - auto credentials_mode = static_cast<network::mojom::FetchCredentialsMode>( + auto credentials_mode = static_cast<network::mojom::CredentialsMode>( credentials_mode_value->IntegerValue(context).ToChecked()); v8::Local<v8::Primitive> nonce_value =
diff --git a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h index f1209731..84ed3667 100644 --- a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h +++ b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
@@ -25,7 +25,7 @@ public: ReferrerScriptInfo() {} ReferrerScriptInfo(const KURL& base_url, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const String& nonce, ParserDisposition parser_state, network::mojom::ReferrerPolicy referrer_policy) @@ -47,7 +47,7 @@ v8::Local<v8::PrimitiveArray> ToV8HostDefinedOptions(v8::Isolate*) const; const KURL& BaseURL() const { return base_url_; } - network::mojom::FetchCredentialsMode CredentialsMode() const { + network::mojom::CredentialsMode CredentialsMode() const { return credentials_mode_; } const String& Nonce() const { return nonce_; } @@ -58,8 +58,7 @@ bool IsDefaultValue() const { return base_url_.IsNull() && - credentials_mode_ == - network::mojom::FetchCredentialsMode::kSameOrigin && + credentials_mode_ == network::mojom::CredentialsMode::kSameOrigin && nonce_.IsEmpty() && parser_state_ == kNotParserInserted; } @@ -75,8 +74,8 @@ // Spec: "referencing script's credentials mode" // The default value is "same-origin" per: // https://html.spec.whatwg.org/C/#default-classic-script-fetch-options - const network::mojom::FetchCredentialsMode credentials_mode_ = - network::mojom::FetchCredentialsMode::kSameOrigin; + const network::mojom::CredentialsMode credentials_mode_ = + network::mojom::CredentialsMode::kSameOrigin; // Spec: "referencing script's cryptographic nonce" const String nonce_;
diff --git a/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc b/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc index 76279d4..3387eb1 100644 --- a/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc
@@ -12,10 +12,10 @@ TEST(ReferrerScriptInfo, IsDefaultValue) { EXPECT_TRUE(ReferrerScriptInfo().IsDefaultValue()); - EXPECT_FALSE(ReferrerScriptInfo( - KURL("http://example.com"), - network::mojom::FetchCredentialsMode::kInclude, "", - kNotParserInserted, network::mojom::ReferrerPolicy::kDefault) + EXPECT_FALSE(ReferrerScriptInfo(KURL("http://example.com"), + network::mojom::CredentialsMode::kInclude, "", + kNotParserInserted, + network::mojom::ReferrerPolicy::kDefault) .IsDefaultValue()); } @@ -27,7 +27,7 @@ .ToV8HostDefinedOptions(scope.GetIsolate()) .IsEmpty()); - ReferrerScriptInfo info(url, network::mojom::FetchCredentialsMode::kInclude, + ReferrerScriptInfo info(url, network::mojom::CredentialsMode::kInclude, "foobar", kNotParserInserted, network::mojom::ReferrerPolicy::kOrigin); v8::Local<v8::PrimitiveArray> v8_info = @@ -36,7 +36,7 @@ ReferrerScriptInfo decoded = ReferrerScriptInfo::FromV8HostDefinedOptions(scope.GetContext(), v8_info); EXPECT_EQ(url, decoded.BaseURL()); - EXPECT_EQ(network::mojom::FetchCredentialsMode::kInclude, + EXPECT_EQ(network::mojom::CredentialsMode::kInclude, decoded.CredentialsMode()); EXPECT_EQ("foobar", decoded.Nonce()); EXPECT_EQ(kNotParserInserted, decoded.ParserState());
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index 1f3f5e2..9ed1767 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -469,13 +469,36 @@ v8::Local<v8::ScriptOrModule> v8_referrer, v8::Local<v8::String> v8_specifier) { ScriptState* script_state = ScriptState::From(context); - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); Modulator* modulator = Modulator::From(script_state); if (!modulator) { - resolver->Reject(); - return v8::Local<v8::Promise>::Cast(promise.V8Value()); + // Inactive browsing context (detached frames) doesn't have a modulator. + // We chose to return a rejected promise (which may never get to catch(), + // since MicrotaskQueue for a detached frame is never consumed). + // + // This is a hack to satisfy V8 API expectation, which are: + // - return non-empty v8::Promise value + // (can either be fulfilled/rejected), or + // - throw exception && return Empty value + // See crbug.com/972960 . + // + // We use the v8 promise API directly here. + // We can't use ScriptPromiseResolver here since it assumes a valid + // ScriptState. + v8::Local<v8::Promise::Resolver> resolver; + if (!v8::Promise::Resolver::New(script_state->GetContext()) + .ToLocal(&resolver)) { + // Note: V8 should have thrown an exception in this case, + // so we return Empty. + return v8::MaybeLocal<v8::Promise>(); + } + + v8::Local<v8::Promise> promise = resolver->GetPromise(); + v8::Local<v8::Value> error = V8ThrowException::CreateError( + script_state->GetIsolate(), + "Cannot import module from an inactive browsing context."); + resolver->Reject(script_state->GetContext(), error).ToChecked(); + return promise; } String specifier = ToCoreStringWithNullCheck(v8_specifier); @@ -488,9 +511,13 @@ if (!referrer_resource_url_str.IsEmpty()) referrer_resource_url = KURL(NullURL(), referrer_resource_url_str); } + ReferrerScriptInfo referrer_info = ReferrerScriptInfo::FromV8HostDefinedOptions( context, v8_referrer->GetHostDefinedOptions()); + + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); modulator->ResolveDynamically(specifier, referrer_resource_url, referrer_info, resolver); return v8::Local<v8::Promise>::Cast(promise.V8Value());
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index afecffc..a49f0d912 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/animation/document_timeline.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/scroll_timeline.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" @@ -115,24 +116,16 @@ AnimationTimeline* timeline, ExceptionState& exception_state) { DCHECK(timeline); - if (!timeline->IsDocumentTimeline()) { + if (!timeline->IsDocumentTimeline() && !timeline->IsScrollTimeline()) { exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, "Invalid timeline. Animation requires a " - "DocumentTimeline"); + "DocumentTimeline or ScrollTimeline"); return nullptr; } + DCHECK(timeline->IsDocumentTimeline() || timeline->IsScrollTimeline()); - DocumentTimeline* subtimeline = ToDocumentTimeline(timeline); - - Animation* animation = MakeGarbageCollected<Animation>( - subtimeline->GetDocument()->ContextDocument(), subtimeline, effect); - - if (subtimeline) { - subtimeline->AnimationAttached(*animation); - animation->AttachCompositorTimeline(); - } - - return animation; + return MakeGarbageCollected<Animation>( + timeline->GetDocument()->ContextDocument(), timeline, effect); } Animation* Animation::Create(ExecutionContext* execution_context, @@ -156,7 +149,7 @@ } Animation::Animation(ExecutionContext* execution_context, - DocumentTimeline* timeline, + AnimationTimeline* timeline, AnimationEffect* content) : ContextLifecycleObserver(execution_context), internal_play_state_(kIdle), @@ -190,6 +183,11 @@ document_ = timeline_ ? timeline_->GetDocument() : To<Document>(execution_context); DCHECK(document_); + + TickingTimeline().AnimationAttached(this); + if (timeline_ && timeline_->IsScrollTimeline()) + timeline_->AnimationAttached(this); + AttachCompositorTimeline(); probe::DidCreateAnimation(document_, sequence_number_); } @@ -199,6 +197,8 @@ } void Animation::Dispose() { + if (timeline_ && timeline_->IsScrollTimeline()) + timeline_->AnimationDetached(this); DestroyCompositorAnimation(); // If the DocumentTimeline and its Animation objects are // finalized by the same GC, we have to eagerly clear out @@ -215,9 +215,36 @@ (playback_rate_ > 0 && current_time >= EffectEnd()); } +Document* Animation::GetDocument() { + return document_; +} + +double Animation::TimelineTime() const { + if (timeline_) + return timeline_->CurrentTime().value_or(NullValue()); + return NullValue(); +} + +DocumentTimeline& Animation::TickingTimeline() { + // Active animations are tracked and ticked through the timeline attached to + // the animation's document. + // TODO(crbug.com/916117): Reconsider how animations are tracked and ticked. + return document_->Timeline(); +} + void Animation::setCurrentTime(double new_current_time, bool is_null, ExceptionState& exception_state) { + // TODO(crbug.com/916117): Implement setting current time for scroll-linked + // animations. + if (timeline_ && timeline_->IsScrollTimeline()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Scroll-linked WebAnimation currently does not support setting" + " current time."); + return; + } + PlayStateUpdateScope update_scope(*this, kTimingUpdateOnDemand); // Step 1. of the procedure to silently set the current time of an @@ -274,7 +301,7 @@ // Update timing to reflect updated animation clock due to tick void Animation::UpdateCurrentTimingState(TimingUpdateReason reason) { - if (internal_play_state_ == kIdle || !timeline_) + if (internal_play_state_ == kIdle || !timeline_ || !timeline_->IsActive()) return; if (hold_time_) { double new_current_time = hold_time_.value(); @@ -328,13 +355,21 @@ // * the associated timeline is inactive, or // * the animation’s start time is unresolved. // The current time is an unresolved time value. - if (!timeline_ || PlayStateInternal() == kIdle || !start_time_) + if (!timeline_ || !timeline_->IsActive() || PlayStateInternal() == kIdle || + !start_time_) { return NullValue(); + } // 3. Otherwise, // current time = (timeline time - start time) × playback rate + base::Optional<double> timeline_time = timeline_->CurrentTimeSeconds(); + // TODO(crbug.com/916117): Handle NaN values for scroll linked animations. + if (!timeline_time) { + DCHECK(timeline_->IsScrollTimeline()); + return 0; + } double current_time = - (timeline_->EffectiveTime() - start_time_.value()) * playback_rate_; + (timeline_time.value() - start_time_.value()) * playback_rate_; return ToMilliseconds(current_time); } @@ -521,20 +556,41 @@ double current_time) const { base::Optional<double> start_time; if (timeline_) { - start_time = timeline_->EffectiveTime() - current_time / playback_rate_; - DCHECK(!IsNull(start_time.value())); + base::Optional<double> timeline_time = timeline_->CurrentTimeSeconds(); + if (timeline_time) + start_time = timeline_time.value() - current_time / playback_rate_; + // TODO(crbug.com/916117): Handle NaN time for scroll-linked animations. + DCHECK(start_time || timeline_->IsScrollTimeline()); } return start_time; } double Animation::CalculateCurrentTime() const { - if (!start_time_ || !timeline_) + if (!start_time_ || !timeline_ || !timeline_->IsActive()) return NullValue(); - return (timeline_->EffectiveTime() - start_time_.value()) * playback_rate_; + base::Optional<double> timeline_time = timeline_->CurrentTimeSeconds(); + // TODO(crbug.com/916117): Handle NaN time for scroll-linked animations. + if (!timeline_time) { + DCHECK(timeline_->IsScrollTimeline()); + return NullValue(); + } + return (timeline_time.value() - start_time_.value()) * playback_rate_; } // https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation -void Animation::setStartTime(double start_time, bool is_null) { +void Animation::setStartTime(double start_time, + bool is_null, + ExceptionState& exception_state) { + // TODO(crbug.com/916117): Implement setting start time for scroll-linked + // animations. + if (timeline_ && timeline_->IsScrollTimeline()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Scroll-linked WebAnimation currently does not support setting start" + " time."); + return; + } + PlayStateUpdateScope update_scope(*this, kTimingUpdateOnDemand); base::Optional<double> new_start_time; @@ -556,7 +612,14 @@ void Animation::SetStartTimeInternal(base::Optional<double> new_start_time) { bool had_start_time = start_time_.has_value(); double previous_current_time = CurrentTimeInternal(); - start_time_ = new_start_time; + + // Scroll-linked animations are initialized with the start time of + // zero (i.e., scroll origin). + // Changing scroll-linked animation start_time initialization is under + // consideration here: https://github.com/w3c/csswg-drafts/issues/2075. + start_time_ = + (!timeline_ || timeline_->IsDocumentTimeline()) ? new_start_time : 0; + // When we don't have an active timeline it is only possible to set either the // start time or the current time. Resetting the hold time clears current // time. @@ -706,6 +769,13 @@ } void Animation::pause(ExceptionState& exception_state) { + // TODO(crbug.com/916117): Implement pause for scroll-linked animations. + if (timeline_ && timeline_->IsScrollTimeline()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Scroll-linked WebAnimation currently does not support pause."); + return; + } if (paused_) return; @@ -797,6 +867,13 @@ // https://drafts.csswg.org/web-animations/#reversing-an-animation-section void Animation::reverse(ExceptionState& exception_state) { + // TODO(crbug.com/916117): Implement reverse for scroll-linked animations. + if (timeline_ && timeline_->IsScrollTimeline()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Scroll-linked WebAnimation currently does not support reverse."); + return; + } if (!playback_rate_) { return; } @@ -852,7 +929,17 @@ } // https://drafts.csswg.org/web-animations/#setting-the-playback-rate-of-an-animation -void Animation::updatePlaybackRate(double playback_rate) { +void Animation::updatePlaybackRate(double playback_rate, + ExceptionState& exception_state) { + // TODO(crbug.com/916117): Implement updatePlaybackRate for scroll-linked + // animations. + if (timeline_ && timeline_->IsScrollTimeline()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Scroll-linked WebAnimation currently does not support" + " updatePlaybackRate."); + return; + } // The implementation differs from the spec; however, the end result is // consistent. Whereas Animation.playbackRate updates the playback rate // immediately, updatePlaybackRate is to take effect on the next async cycle. @@ -929,7 +1016,17 @@ return active_playback_rate_.value_or(playback_rate_); } -void Animation::setPlaybackRate(double playback_rate) { +void Animation::setPlaybackRate(double playback_rate, + ExceptionState& exception_state) { + // TODO(crbug.com/916117): Implement setting playback rate for scroll-linked + // animations. + if (timeline_ && timeline_->IsScrollTimeline()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Scroll-linked WebAnimation currently does not support setting" + " playback rate."); + return; + } active_playback_rate_.reset(); if (playback_rate == playback_rate_) return; @@ -971,7 +1068,7 @@ return; outdated_ = false; if (timeline_) - timeline_->ClearOutdatedAnimation(this); + TickingTimeline().ClearOutdatedAnimation(this); } void Animation::SetOutdated() { @@ -979,12 +1076,12 @@ return; outdated_ = true; if (timeline_) - timeline_->SetOutdatedAnimation(this); + TickingTimeline().SetOutdatedAnimation(this); } void Animation::ForceServiceOnNextFrame() { if (timeline_) - timeline_->Wake(); + TickingTimeline().Wake(); } CompositorAnimations::FailureReasons @@ -1025,7 +1122,8 @@ // reason to composite it. Additionally, mutating the timeline playback rate // is a debug feature available via devtools; we don't support this on the // compositor currently and there is no reason to do so. - if (!timeline_ || timeline_->PlaybackRate() != 1) + if (!timeline_ || (timeline_->IsDocumentTimeline() && + ToDocumentTimeline(timeline_)->PlaybackRate() != 1)) reasons |= CompositorAnimations::kInvalidAnimationOrEffect; // An Animation without an effect cannot produce a visual, so there is no @@ -1038,6 +1136,10 @@ if (!Playing()) reasons |= CompositorAnimations::kInvalidAnimationOrEffect; + // TODO(crbug.com/916117): Support accelerated scroll linked animations. + if (timeline_->IsScrollTimeline()) + reasons |= CompositorAnimations::kInvalidAnimationOrEffect; + return reasons; } @@ -1045,14 +1147,16 @@ const PaintArtifactCompositor* paint_artifact_compositor) { DCHECK_EQ(CheckCanStartAnimationOnCompositor(paint_artifact_compositor), CompositorAnimations::kNoFailure); + DCHECK(timeline_->IsDocumentTimeline()); bool reversed = playback_rate_ < 0; base::Optional<double> start_time = base::nullopt; double time_offset = 0; if (start_time_) { - start_time = TimelineInternal()->ZeroTime().since_origin().InSecondsF() + - start_time_.value(); + start_time = + ToDocumentTimeline(timeline_)->ZeroTime().since_origin().InSecondsF() + + start_time_.value(); if (reversed) start_time = start_time.value() - (EffectEnd() / fabs(playback_rate_)); } else { @@ -1153,9 +1257,8 @@ bool idle = PlayStateInternal() == kIdle; if (content_) { - double inherited_time = idle || IsNull(timeline_->CurrentTimeInternal()) - ? NullValue() - : CurrentTimeInternal(); + double inherited_time = + idle || !timeline_->CurrentTime() ? NullValue() : CurrentTimeInternal(); // Special case for end-exclusivity when playing backwards. if (inherited_time == 0 && playback_rate_ < 0) @@ -1177,6 +1280,8 @@ const AtomicString& event_type = event_type_names::kCancel; if (GetExecutionContext() && HasEventListeners(event_type)) { double event_current_time = NullValue(); + // TODO(crbug.com/916117): Handle NaN values for scroll-linked + // animations. pending_cancelled_event_ = MakeGarbageCollected<AnimationPlaybackEvent>( event_type, event_current_time, TimelineTime()); @@ -1198,6 +1303,7 @@ const AtomicString& event_type = event_type_names::kFinish; if (GetExecutionContext() && HasEventListeners(event_type)) { double event_current_time = CurrentTimeInternal() * 1000; + // TODO(crbug.com/916117): Handle NaN values for scroll-linked animations. pending_finished_event_ = MakeGarbageCollected<AnimationPlaybackEvent>( event_type, event_current_time, TimelineTime()); pending_finished_event_->SetTarget(this); @@ -1294,7 +1400,8 @@ void Animation::AttachCompositorTimeline() { if (compositor_animation_) { CompositorAnimationTimeline* timeline = - timeline_ ? timeline_->CompositorTimeline() : nullptr; + timeline_ ? ToDocumentTimeline(timeline_)->CompositorTimeline() + : nullptr; if (timeline) timeline->AnimationAttached(*this); } @@ -1303,7 +1410,8 @@ void Animation::DetachCompositorTimeline() { if (compositor_animation_) { CompositorAnimationTimeline* timeline = - timeline_ ? timeline_->CompositorTimeline() : nullptr; + timeline_ ? ToDocumentTimeline(timeline_)->CompositorTimeline() + : nullptr; if (timeline) timeline->AnimationDestroyed(*this); }
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h index e79245a5..8cbb198 100644 --- a/third_party/blink/renderer/core/animation/animation.h +++ b/third_party/blink/renderer/core/animation/animation.h
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" #include "third_party/blink/renderer/core/animation/animation_effect_owner.h" +#include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/compositor_animations.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" #include "third_party/blink/renderer/core/core_export.h" @@ -94,8 +95,7 @@ AnimationTimeline*, ExceptionState&); - Animation(ExecutionContext*, DocumentTimeline*, AnimationEffect*); - + Animation(ExecutionContext*, AnimationTimeline*, AnimationEffect*); ~Animation() override; void Dispose(); @@ -137,7 +137,8 @@ void play(ExceptionState& = ASSERT_NO_EXCEPTION); void reverse(ExceptionState& = ASSERT_NO_EXCEPTION); void finish(ExceptionState& = ASSERT_NO_EXCEPTION); - void updatePlaybackRate(double playback_rate); + void updatePlaybackRate(double playback_rate, + ExceptionState& = ASSERT_NO_EXCEPTION); ScriptPromise finished(ScriptState*); ScriptPromise ready(ScriptState*); @@ -158,20 +159,16 @@ void ContextDestroyed(ExecutionContext*) override; double playbackRate() const; - void setPlaybackRate(double); - AnimationTimeline* timeline() { - return static_cast<AnimationTimeline*>(timeline_); - } - const DocumentTimeline* TimelineInternal() const { return timeline_; } - DocumentTimeline* TimelineInternal() { return timeline_; } - double TimelineTime() const { - return timeline_ ? timeline_->currentTime() : NullValue(); - } + void setPlaybackRate(double, ExceptionState& = ASSERT_NO_EXCEPTION); + AnimationTimeline* timeline() { return timeline_; } + Document* GetDocument(); double startTime(bool& is_null) const; base::Optional<double> startTime() const; base::Optional<double> StartTimeInternal() const { return start_time_; } - void setStartTime(double, bool is_null); + void setStartTime(double, + bool is_null, + ExceptionState& = ASSERT_NO_EXCEPTION); const AnimationEffect* effect() const { return content_.Get(); } AnimationEffect* effect() { return content_.Get(); } @@ -299,6 +296,8 @@ void QueueFinishedEvent(); void ResetPendingTasks(); + double TimelineTime() const; + DocumentTimeline& TickingTimeline(); String id_; @@ -328,7 +327,7 @@ // Document refers to the timeline's document if there is a timeline. // Otherwise it refers to the document for the execution context. Member<Document> document_; - Member<DocumentTimeline> timeline_; + Member<AnimationTimeline> timeline_; // Reflects all pausing, including via pauseForTesting(). bool paused_;
diff --git a/third_party/blink/renderer/core/animation/animation.idl b/third_party/blink/renderer/core/animation/animation.idl index 351eda96..79acca95 100644 --- a/third_party/blink/renderer/core/animation/animation.idl +++ b/third_party/blink/renderer/core/animation/animation.idl
@@ -42,20 +42,20 @@ [Measure] attribute AnimationEffect? effect; // TODO(suzyh): Make timeline mutable. [RuntimeEnabled=WebAnimationsAPI] readonly attribute AnimationTimeline? timeline; - [Measure] attribute double? startTime; + [Measure, RaisesException=Setter] attribute double? startTime; [Measure, RaisesException=Setter] attribute double? currentTime; - [Measure] attribute double playbackRate; + [Measure, RaisesException=Setter] attribute double playbackRate; [Measure] readonly attribute AnimationPlayState playState; [Measure] readonly attribute boolean pending; [Measure, RaisesException] void finish(); [Measure, RaisesException] void play(); [Measure, RaisesException] void pause(); [Measure, RaisesException] void reverse(); - [Measure] void updatePlaybackRate(double playback_rate); + [Measure, RaisesException] void updatePlaybackRate(double playback_rate); [Measure] attribute DOMString id; [Measure] void cancel(); [Measure] attribute EventHandler onfinish; [Measure] attribute EventHandler oncancel; [RuntimeEnabled=WebAnimationsAPI, CallWith=ScriptState] readonly attribute Promise<Animation> finished; [RuntimeEnabled=WebAnimationsAPI, CallWith=ScriptState] readonly attribute Promise<Animation> ready; -}; +}; \ No newline at end of file
diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc index 88af1dd..032987b 100644 --- a/third_party/blink/renderer/core/animation/animation_test.cc +++ b/third_party/blink/renderer/core/animation/animation_test.cc
@@ -42,10 +42,12 @@ #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h" #include "third_party/blink/renderer/core/animation/pending_animations.h" +#include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" +#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -70,7 +72,7 @@ page_holder = std::make_unique<DummyPageHolder>(); document = &page_holder->GetDocument(); document->GetAnimationClock().ResetTimeForTesting(); - timeline = DocumentTimeline::Create(document.Get()); + timeline = document->Timeline(); timeline->ResetForTesting(); animation = timeline->Play(nullptr); animation->setStartTime(0, false); @@ -1134,4 +1136,61 @@ EXPECT_TRUE(animation->CompositorPendingForTesting()); } +// Verifies correctness of scroll linked animation current and start times in +// various animation states. +TEST_F(AnimationAnimationTest, ScrollLinkedAnimationCreation) { + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; width: 100px; height: 100px; } + #spacer { width: 200px; height: 200px; } + </style> + <div id='scroller'> + <div id ='spacer'></div> + </div> + )HTML"); + + LayoutBoxModelObject* scroller = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); + PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); + scrollable_area->SetScrollOffset(ScrollOffset(0, 20), kProgrammaticScroll); + ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); + DoubleOrScrollTimelineAutoKeyword time_range = + DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + options->setTimeRange(time_range); + options->setScrollSource(GetElementById("scroller")); + ScrollTimeline* scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + + NonThrowableExceptionState exception_state; + Animation* scroll_animation = + Animation::Create(MakeAnimation(), scroll_timeline, exception_state); + + // Verify start and current times in Idle state. + bool is_null; + scroll_animation->startTime(is_null); + EXPECT_TRUE(is_null); + scroll_animation->currentTime(is_null); + EXPECT_TRUE(is_null); + + scroll_animation->play(); + + // Verify start and current times in Pending state. + scroll_animation->startTime(is_null); + EXPECT_TRUE(is_null); + EXPECT_EQ(0, scroll_animation->currentTime(is_null)); + EXPECT_FALSE(is_null); + + UpdateAllLifecyclePhasesForTest(); + // Verify start and current times in Playing state. + EXPECT_EQ(0, scroll_animation->startTime(is_null)); + EXPECT_FALSE(is_null); + EXPECT_EQ(20, scroll_animation->currentTime(is_null)); + EXPECT_FALSE(is_null); + + // Verify current time after scroll. + scrollable_area->SetScrollOffset(ScrollOffset(0, 40), kProgrammaticScroll); + EXPECT_EQ(40, scroll_animation->currentTime(is_null)); + EXPECT_FALSE(is_null); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.h b/third_party/blink/renderer/core/animation/animation_timeline.h index 4d06d15..792d74d 100644 --- a/third_party/blink/renderer/core/animation/animation_timeline.h +++ b/third_party/blink/renderer/core/animation/animation_timeline.h
@@ -10,6 +10,9 @@ namespace blink { +class Animation; +class Document; + class CORE_EXPORT AnimationTimeline : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -18,9 +21,25 @@ virtual double currentTime(bool&) = 0; + base::Optional<double> CurrentTime() { + bool is_null; + double current_time_ms = currentTime(is_null); + return is_null ? base::nullopt : base::make_optional(current_time_ms); + } + + base::Optional<double> CurrentTimeSeconds() { + base::Optional<double> current_time_ms = CurrentTime(); + if (current_time_ms) + return current_time_ms.value() / 1000; + return current_time_ms; + } + virtual bool IsDocumentTimeline() const { return false; } virtual bool IsScrollTimeline() const { return false; } virtual bool IsActive() const = 0; + virtual Document* GetDocument() = 0; + virtual void AnimationAttached(Animation*) = 0; + virtual void AnimationDetached(Animation*) = 0; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc index 72aacdd..58bc43b8 100644 --- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc +++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -125,7 +125,7 @@ GetAnimationClock().ResetTimeForTesting(); - timeline_ = DocumentTimeline::Create(&GetDocument()); + timeline_ = GetDocument().Timeline(); timeline_->ResetForTesting(); // Using will-change ensures that this object will need paint properties.
diff --git a/third_party/blink/renderer/core/animation/document_timeline.cc b/third_party/blink/renderer/core/animation/document_timeline.cc index 920e8e8..85f67327 100644 --- a/third_party/blink/renderer/core/animation/document_timeline.cc +++ b/third_party/blink/renderer/core/animation/document_timeline.cc
@@ -97,10 +97,10 @@ return document_->GetPage(); } -void DocumentTimeline::AnimationAttached(Animation& animation) { - DCHECK_EQ(animation.TimelineInternal(), this); - DCHECK(!animations_.Contains(&animation)); - animations_.insert(&animation); +void DocumentTimeline::AnimationAttached(Animation* animation) { + DCHECK_EQ(&animation->GetDocument()->Timeline(), this); + DCHECK(!animations_.Contains(animation)); + animations_.insert(animation); } Animation* DocumentTimeline::Play(AnimationEffect* child) { @@ -218,6 +218,10 @@ last_current_time_internal_ = 0; } +void DocumentTimeline::SetTimingForTesting(PlatformTiming* timing) { + timing_ = timing; +} + double DocumentTimeline::currentTime(bool& is_null) { return CurrentTimeInternal(is_null) * 1000; }
diff --git a/third_party/blink/renderer/core/animation/document_timeline.h b/third_party/blink/renderer/core/animation/document_timeline.h index ce4350a..e566c60 100644 --- a/third_party/blink/renderer/core/animation/document_timeline.h +++ b/third_party/blink/renderer/core/animation/document_timeline.h
@@ -87,7 +87,10 @@ Animation* Play(AnimationEffect*); HeapVector<Member<Animation>> getAnimations(); - void AnimationAttached(Animation&); + void AnimationAttached(Animation*) override; + // animations_ is a map of weak members so there is no need to explicitly + // clean it up. + void AnimationDetached(Animation*) override {} bool IsActive() const override; bool HasPendingUpdates() const { @@ -118,9 +121,10 @@ return compositor_timeline_.get(); } - Document* GetDocument() { return document_.Get(); } + Document* GetDocument() override { return document_.Get(); } void Wake(); void ResetForTesting(); + void SetTimingForTesting(PlatformTiming* timing); bool HasAnimations() { return !animations_.IsEmpty(); } void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/animation/document_timeline_test.cc b/third_party/blink/renderer/core/animation/document_timeline_test.cc index 78feffb..32788fa 100644 --- a/third_party/blink/renderer/core/animation/document_timeline_test.cc +++ b/third_party/blink/renderer/core/animation/document_timeline_test.cc
@@ -70,8 +70,9 @@ GetAnimationClock().ResetTimeForTesting(); element = Element::Create(QualifiedName::Null(), document.Get()); platform_timing = MakeGarbageCollected<MockPlatformTiming>(); - timeline = - DocumentTimeline::Create(document.Get(), TimeDelta(), platform_timing); + timeline = document->Timeline(); + timeline->SetTimingForTesting(platform_timing); + timeline->ResetForTesting(); ASSERT_EQ(0, timeline->CurrentTimeInternal()); }
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 f662694..b63467b 100644 --- a/third_party/blink/renderer/core/animation/effect_stack_test.cc +++ b/third_party/blink/renderer/core/animation/effect_stack_test.cc
@@ -24,7 +24,7 @@ void SetUp() override { PageTestBase::SetUp(IntSize()); GetDocument().GetAnimationClock().ResetTimeForTesting(); - timeline = DocumentTimeline::Create(&GetDocument()); + timeline = GetDocument().Timeline(); element = GetDocument().CreateElementForBinding("foo"); }
diff --git a/third_party/blink/renderer/core/animation/pending_animations.cc b/third_party/blink/renderer/core/animation/pending_animations.cc index 2bbc247..dad04858 100644 --- a/third_party/blink/renderer/core/animation/pending_animations.cc +++ b/third_party/blink/renderer/core/animation/pending_animations.cc
@@ -44,7 +44,7 @@ DCHECK_EQ(pending_.Find(animation), kNotFound); pending_.push_back(animation); - Document* document = animation->TimelineInternal()->GetDocument(); + Document* document = animation->GetDocument(); if (document->View()) document->View()->ScheduleAnimation(); @@ -78,8 +78,7 @@ } if (animation->Playing() && !animation->startTime() && - animation->TimelineInternal() && - animation->TimelineInternal()->IsActive()) { + animation->timeline() && animation->timeline()->IsActive()) { waiting_for_start_time.push_back(animation.Get()); } } else { @@ -96,14 +95,18 @@ } else { for (auto& animation : waiting_for_start_time) { DCHECK(!animation->startTime()); + // TODO(crbug.com/916117): Handle start time of scroll-linked animations. animation->NotifyCompositorStartTime( - animation->TimelineInternal()->CurrentTimeInternal()); + animation->timeline()->CurrentTimeSeconds().value_or(0)); } } // FIXME: The postCommit should happen *after* the commit, not before. - for (auto& animation : animations) - animation->PostCommit(animation->TimelineInternal()->CurrentTimeInternal()); + for (auto& animation : animations) { + // TODO(crbug.com/916117): Handle NaN current time of scroll timeline. + animation->PostCommit( + animation->timeline()->CurrentTimeSeconds().value_or(0)); + } DCHECK(pending_.IsEmpty()); DCHECK(start_on_compositor || deferred.IsEmpty()); @@ -140,8 +143,7 @@ for (auto animation : animations) { if (animation->startTime() || animation->PlayStateInternal() != Animation::kPending || - !animation->TimelineInternal() || - !animation->TimelineInternal()->IsActive()) { + !animation->timeline() || !animation->timeline()->IsActive()) { // Already started or no longer relevant. continue; } @@ -150,9 +152,13 @@ waiting_for_compositor_animation_start_.push_back(animation); continue; } + DCHECK(animation->timeline()->IsDocumentTimeline()); animation->NotifyCompositorStartTime( monotonic_animation_start_time - - animation->TimelineInternal()->ZeroTime().since_origin().InSecondsF()); + ToDocumentTimeline(animation->timeline()) + ->ZeroTime() + .since_origin() + .InSecondsF()); } }
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc index 302d8b3..82566e7b 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -309,7 +309,7 @@ } } -void ScrollTimeline::AttachAnimation() { +void ScrollTimeline::AnimationAttached(Animation*) { if (!resolved_scroll_source_) return; @@ -327,7 +327,7 @@ object->SetNeedsPaintPropertyUpdate(); } -void ScrollTimeline::DetachAnimation() { +void ScrollTimeline::AnimationDetached(Animation*) { if (!resolved_scroll_source_) return;
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.h b/third_party/blink/renderer/core/animation/scroll_timeline.h index e71e10f..aa8d673 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.h +++ b/third_party/blink/renderer/core/animation/scroll_timeline.h
@@ -50,6 +50,7 @@ // AnimationTimeline implementation. double currentTime(bool& is_null) final; bool IsScrollTimeline() const override { return true; } + Document* GetDocument() override { return &scroll_source_->GetDocument(); } // ScrollTimeline is not active if scrollSource is null, does not currently // have a CSS layout box, or if its layout box is not a scroll container. // https://github.com/WICG/scroll-animations/issues/31 @@ -82,8 +83,8 @@ // Must be called when this ScrollTimeline is attached/detached from an // animation. - void AttachAnimation(); - void DetachAnimation(); + void AnimationAttached(Animation*) override; + void AnimationDetached(Animation*) override; void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.idl b/third_party/blink/renderer/core/animation/scroll_timeline.idl index 96520d2..bd0cd9c 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.idl +++ b/third_party/blink/renderer/core/animation/scroll_timeline.idl
@@ -9,7 +9,7 @@ ConstructorCallWith=Document, MeasureAs=ScrollTimelineConstructor, RaisesException=Constructor, - RuntimeEnabled=AnimationWorklet, + RuntimeEnabled=ScrollTimeline, Exposed=Window ] interface ScrollTimeline : AnimationTimeline { readonly attribute Element? scrollSource;
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc index 0ea38b9..03ea5af 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
@@ -47,13 +47,13 @@ EXPECT_EQ(kNotComposited, scroller->Layer()->GetCompositingState()); // Now attach an animation. This should require a compositing update. - scroll_timeline->AttachAnimation(); + scroll_timeline->AnimationAttached(nullptr); UpdateAllLifecyclePhasesForTest(); EXPECT_NE(scroller->Layer()->GetCompositingState(), kNotComposited); // Now detach an animation. This should again require a compositing update. - scroll_timeline->DetachAnimation(); + scroll_timeline->AnimationDetached(nullptr); UpdateAllLifecyclePhasesForTest(); EXPECT_EQ(scroller->Layer()->GetCompositingState(), kNotComposited); @@ -239,8 +239,8 @@ ASSERT_EQ(scroll_timeline->ResolvedScrollSource(), nullptr); // These calls should be no-ops in this mode, and shouldn't crash. - scroll_timeline->AttachAnimation(); - scroll_timeline->DetachAnimation(); + scroll_timeline->AnimationAttached(nullptr); + scroll_timeline->AnimationDetached(nullptr); } } // namespace blink
diff --git a/third_party/blink/renderer/core/clipboard/data_transfer_item.cc b/third_party/blink/renderer/core/clipboard/data_transfer_item.cc index 76e02205..ea4d935 100644 --- a/third_party/blink/renderer/core/clipboard/data_transfer_item.cc +++ b/third_party/blink/renderer/core/clipboard/data_transfer_item.cc
@@ -36,6 +36,7 @@ #include "third_party/blink/renderer/core/clipboard/data_object_item.h" #include "third_party/blink/renderer/core/clipboard/data_transfer.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -73,14 +74,15 @@ auto* v8persistent_callback = ToV8PersistentCallbackFunction(callback); ExecutionContext* context = ExecutionContext::From(script_state); + auto task_id = std::make_unique<probe::AsyncTaskId>(); probe::AsyncTaskScheduled(context, "DataTransferItem.getAsString", - v8persistent_callback); + task_id.get()); context->GetTaskRunner(TaskType::kUserInteraction) ->PostTask(FROM_HERE, WTF::Bind(&DataTransferItem::RunGetAsStringTask, WrapPersistent(this), WrapPersistent(context), WrapPersistent(v8persistent_callback), - item_->GetAsString())); + item_->GetAsString(), std::move(task_id))); } File* DataTransferItem::getAsFile() const { @@ -97,9 +99,10 @@ void DataTransferItem::RunGetAsStringTask( ExecutionContext* context, V8PersistentCallbackFunction<V8FunctionStringCallback>* callback, - const String& data) { + const String& data, + std::unique_ptr<probe::AsyncTaskId> task_id) { DCHECK(callback); - probe::AsyncTask async_task(context, callback); + probe::AsyncTask async_task(context, task_id.get()); if (context) callback->InvokeAndReportException(nullptr, data); }
diff --git a/third_party/blink/renderer/core/clipboard/data_transfer_item.h b/third_party/blink/renderer/core/clipboard/data_transfer_item.h index c930a457..faae65f 100644 --- a/third_party/blink/renderer/core/clipboard/data_transfer_item.h +++ b/third_party/blink/renderer/core/clipboard/data_transfer_item.h
@@ -46,6 +46,10 @@ class File; class ScriptState; +namespace probe { +class AsyncTaskId; +} + class CORE_EXPORT DataTransferItem final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -67,7 +71,8 @@ void RunGetAsStringTask( ExecutionContext*, V8PersistentCallbackFunction<V8FunctionStringCallback>*, - const String& data); + const String& data, + std::unique_ptr<probe::AsyncTaskId>); Member<DataTransfer> data_transfer_; Member<DataObjectItem> item_;
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 879154ef..9c6b4589 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -5355,6 +5355,14 @@ initial_color: "blink::Color", }, }, + { + name: "-internal-effective-zoom", + inherited: true, + field_template: "primitive", + type_name: "float", + default_value: "1.0f", + field_group: "*", + }, // Aliases; these map to the same CSSPropertyID {
diff --git a/third_party/blink/renderer/core/css/remote_font_face_source.cc b/third_party/blink/renderer/core/css/remote_font_face_source.cc index 871c76c..9ddc913 100644 --- a/third_party/blink/renderer/core/css/remote_font_face_source.cc +++ b/third_party/blink/renderer/core/css/remote_font_face_source.cc
@@ -117,6 +117,11 @@ ExecutionContext* execution_context = font_selector_->GetExecutionContext(); if (!execution_context) return; + // Prevent promise rejection while shutting down the document. + // See crbug.com/960290 + if (execution_context->IsDocument() && + To<Document>(execution_context)->IsDetached()) + return; FontResource* font = ToFontResource(resource); histograms_.RecordRemoteFont(font);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 9ee33d8..0359576f 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1589,6 +1589,24 @@ return getAttribute(QualifiedName(g_null_atom, local_name, namespace_uri)); } +std::pair<wtf_size_t, const QualifiedName> +Element::LookupAttributeQNameInternal(const AtomicString& local_name) const { + AtomicString case_adjusted_local_name = LowercaseIfNecessary(local_name); + if (!GetElementData()) { + return std::make_pair( + kNotFound, + QualifiedName(g_null_atom, case_adjusted_local_name, g_null_atom)); + } + + AttributeCollection attributes = GetElementData()->Attributes(); + wtf_size_t index = attributes.FindIndex(case_adjusted_local_name); + return std::make_pair( + index, + index != kNotFound + ? attributes[index].GetName() + : QualifiedName(g_null_atom, case_adjusted_local_name, g_null_atom)); +} + void Element::setAttribute(const AtomicString& local_name, const AtomicString& value, ExceptionState& exception_state) { @@ -1600,22 +1618,9 @@ } SynchronizeAttribute(local_name); - AtomicString case_adjusted_local_name = LowercaseIfNecessary(local_name); - - if (!GetElementData()) { - SetAttributeInternal( - kNotFound, - QualifiedName(g_null_atom, case_adjusted_local_name, g_null_atom), - value, kNotInSynchronizationOfLazyAttribute); - return; - } - - AttributeCollection attributes = GetElementData()->Attributes(); - wtf_size_t index = attributes.FindIndex(case_adjusted_local_name); - const QualifiedName& q_name = - index != kNotFound - ? attributes[index].GetName() - : QualifiedName(g_null_atom, case_adjusted_local_name, g_null_atom); + wtf_size_t index; + QualifiedName q_name = QualifiedName::Null(); + std::tie(index, q_name) = LookupAttributeQNameInternal(local_name); SetAttributeInternal(index, q_name, value, kNotInSynchronizationOfLazyAttribute); } @@ -1644,36 +1649,28 @@ } void Element::setAttribute( - const AtomicString& name, + const AtomicString& local_name, const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL& string_or_TT, ExceptionState& exception_state) { - // TODO(vogelheim): Check whether this applies to non-HTML documents, too. - AtomicString name_lowercase = LowercaseIfNecessary(name); - const AttrNameToTrustedType* attribute_types = &GetCheckedAttributeTypes(); - AttrNameToTrustedType::const_iterator it = - attribute_types->find(name_lowercase); - if (it != attribute_types->end()) { - String attr_value = GetStringFromSpecificTrustedType( - string_or_TT, it->value, &GetDocument(), exception_state); - if (!exception_state.HadException()) - setAttribute(name_lowercase, AtomicString(attr_value), exception_state); - return; - } else if (name_lowercase.StartsWith("on")) { - // TODO(jakubvrana): This requires TrustedScript in all attributes starting - // with "on", including e.g. "one". We use this pattern elsewhere (e.g. in - // IsEventHandlerAttribute) but it's not ideal. Consider using the event - // attribute of the resulting AttributeTriggers. - String attr_value = GetStringFromSpecificTrustedType( - string_or_TT, SpecificTrustedType::kTrustedScript, &GetDocument(), - exception_state); - if (!exception_state.HadException()) - setAttribute(name_lowercase, AtomicString(attr_value), exception_state); + if (!Document::IsValidName(local_name)) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidCharacterError, + "'" + local_name + "' is not a valid attribute name."); return; } - AtomicString value_string = - AtomicString(GetStringFromTrustedTypeWithoutCheck(string_or_TT)); - setAttribute(name_lowercase, value_string, exception_state); + + SynchronizeAttribute(local_name); + wtf_size_t index; + QualifiedName q_name = QualifiedName::Null(); + std::tie(index, q_name) = LookupAttributeQNameInternal(local_name); + String value = GetStringFromSpecificTrustedType( + string_or_TT, ExpectedTrustedTypeForAttribute(q_name), &GetDocument(), + exception_state); + if (exception_state.HadException()) + return; + SetAttributeInternal(index, q_name, AtomicString(value), + kNotInSynchronizationOfLazyAttribute); } const AttrNameToTrustedType& Element::GetCheckedAttributeTypes() const { @@ -1681,6 +1678,35 @@ return attribute_map; } +SpecificTrustedType Element::ExpectedTrustedTypeForAttribute( + const QualifiedName& q_name) const { + // There are only a handful of namespaced attributes we care about + // (xlink:href), and all of those have identical Trusted Types + // properties to their namespace-less counterpart. So we check whether this + // is one of SVG's 'known' attributes, and if so just check the local + // name part as usual. + if (!q_name.NamespaceURI().IsNull() && + !SVGAnimatedHref::IsKnownAttribute(q_name)) { + return SpecificTrustedType::kNone; + } + + const AttrNameToTrustedType* attribute_types = &GetCheckedAttributeTypes(); + AttrNameToTrustedType::const_iterator iter = + attribute_types->find(q_name.LocalName()); + if (iter != attribute_types->end()) + return iter->value; + + if (q_name.LocalName().StartsWith("on")) { + // TODO(jakubvrana): This requires TrustedScript in all attributes + // starting with "on", including e.g. "one". We use this pattern elsewhere + // (e.g. in IsEventHandlerAttribute) but it's not ideal. Consider using + // the event attribute of the resulting AttributeTriggers. + return SpecificTrustedType::kTrustedScript; + } + + return SpecificTrustedType::kNone; +} + void Element::setAttribute(const QualifiedName& name, const StringOrTrustedHTML& stringOrHTML, ExceptionState& exception_state) { @@ -3279,14 +3305,17 @@ const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL& string_or_TT, ExceptionState& exception_state) { - String value = - GetStringFromTrustedType(string_or_TT, &GetDocument(), exception_state); - if (exception_state.HadException()) - return; QualifiedName parsed_name = g_any_name; if (!ParseAttributeName(parsed_name, namespace_uri, qualified_name, exception_state)) return; + + String value = GetStringFromSpecificTrustedType( + string_or_TT, ExpectedTrustedTypeForAttribute(parsed_name), + &GetDocument(), exception_state); + if (exception_state.HadException()) + return; + setAttribute(parsed_name, AtomicString(value)); }
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 73d2c81..d14474df 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -1078,6 +1078,10 @@ SynchronizationOfLazyAttribute); void RemoveAttributeInternal(wtf_size_t index, SynchronizationOfLazyAttribute); + std::pair<wtf_size_t, const QualifiedName> LookupAttributeQNameInternal( + const AtomicString& local_name) const; + SpecificTrustedType ExpectedTrustedTypeForAttribute( + const QualifiedName&) const; void CancelFocusAppearanceUpdate();
diff --git a/third_party/blink/renderer/core/dom/element.idl b/third_party/blink/renderer/core/dom/element.idl index 354677a..84a5afb 100644 --- a/third_party/blink/renderer/core/dom/element.idl +++ b/third_party/blink/renderer/core/dom/element.idl
@@ -57,7 +57,7 @@ [CEReactions, CustomElementCallbacks] void removeAttributeNS(DOMString? namespaceURI, DOMString localName); [Affects=Nothing] boolean hasAttribute(DOMString name); [Affects=Nothing] boolean hasAttributeNS(DOMString? namespaceURI, DOMString localName); - [RaisesException] boolean toggleAttribute(DOMString qualifiedName, optional boolean force); + [RaisesException, CEReactions, CustomElementCallbacks] boolean toggleAttribute(DOMString qualifiedName, optional boolean force); Attr? getAttributeNode(DOMString name); Attr? getAttributeNodeNS(DOMString? namespaceURI, DOMString localName);
diff --git a/third_party/blink/renderer/core/dom/events/event.h b/third_party/blink/renderer/core/dom/events/event.h index caf97646..e9d27e5 100644 --- a/third_party/blink/renderer/core/dom/events/event.h +++ b/third_party/blink/renderer/core/dom/events/event.h
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/event_dispatch_result.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" @@ -304,6 +305,8 @@ virtual DispatchEventResult DispatchEvent(EventDispatcher&); + probe::AsyncTaskId* async_task_id() { return &async_task_id_; } + void Trace(Visitor*) override; protected: @@ -349,6 +352,8 @@ PassiveMode handling_passive_; uint8_t event_phase_; + probe::AsyncTaskId async_task_id_; + Member<EventTarget> current_target_; Member<EventTarget> target_; Member<Event> underlying_event_;
diff --git a/third_party/blink/renderer/core/dom/events/event_listener.h b/third_party/blink/renderer/core/dom/events/event_listener.h index 3d7eb513..0787c6f 100644 --- a/third_party/blink/renderer/core/dom/events/event_listener.h +++ b/third_party/blink/renderer/core/dom/events/event_listener.h
@@ -23,6 +23,7 @@ #include "base/macros.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -84,8 +85,11 @@ virtual bool IsJSBasedEventListener() const { return false; } virtual bool IsNativeEventListener() const { return false; } + probe::AsyncTaskId* async_task_id() { return &async_task_id_; } + private: EventListener() = default; + probe::AsyncTaskId async_task_id_; // Only these two classes are direct subclasses of EventListener. Other // subclasses must inherit from either of them.
diff --git a/third_party/blink/renderer/core/dom/events/event_queue.cc b/third_party/blink/renderer/core/dom/events/event_queue.cc index 89c80e0..a0a24e1 100644 --- a/third_party/blink/renderer/core/dom/events/event_queue.cc +++ b/third_party/blink/renderer/core/dom/events/event_queue.cc
@@ -57,7 +57,8 @@ DCHECK(event.target()); DCHECK(GetExecutionContext()); - probe::AsyncTaskScheduled(GetExecutionContext(), event.type(), &event); + probe::AsyncTaskScheduled(GetExecutionContext(), event.type(), + event.async_task_id()); bool was_added = queued_events_.insert(&event).is_new_entry; DCHECK(was_added); // It should not have already been in the list. @@ -96,7 +97,7 @@ DCHECK(GetExecutionContext()); - probe::AsyncTask async_task(GetExecutionContext(), event); + probe::AsyncTask async_task(GetExecutionContext(), event->async_task_id()); EventTarget* target = event->target(); if (LocalDOMWindow* window = target->ToLocalDOMWindow()) window->DispatchEvent(*event, nullptr); @@ -115,7 +116,7 @@ void EventQueue::DoCancelAllEvents(ExecutionContext* context) { for (const auto& queued_event : queued_events_) - probe::AsyncTaskCanceled(context, queued_event); + probe::AsyncTaskCanceled(context, queued_event->async_task_id()); queued_events_.clear(); }
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc index 3dbe4ae..9c8c0ade 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.cc +++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -472,7 +472,8 @@ AddedEventListener(event_type, registered_listener); if (IsA<JSBasedEventListener>(listener) && IsInstrumentedForAsyncStack(event_type)) { - probe::AsyncTaskScheduled(GetExecutionContext(), event_type, listener); + probe::AsyncTaskScheduled(GetExecutionContext(), event_type, + listener->async_task_id()); } } return added; @@ -621,7 +622,8 @@ if (registered_listener) { if (IsA<JSBasedEventListener>(listener) && IsInstrumentedForAsyncStack(event_type)) { - probe::AsyncTaskScheduled(GetExecutionContext(), event_type, listener); + probe::AsyncTaskScheduled(GetExecutionContext(), event_type, + listener->async_task_id()); } registered_listener->SetCallback(listener); return true; @@ -909,7 +911,7 @@ bool passive_forced = registered_listener.PassiveForcedForDocumentTarget(); probe::UserCallback probe(context, nullptr, event.type(), false, this); - probe::AsyncTask async_task(context, listener, "event", + probe::AsyncTask async_task(context, listener->async_task_id(), "event", IsInstrumentedForAsyncStack(event.type())); // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling @@ -987,7 +989,7 @@ ExecutionContext* context = GetExecutionContext(); if (!context) return; - probe::AsyncTaskScheduled(context, event.type(), &event); + probe::AsyncTaskScheduled(context, event.type(), event.async_task_id()); context->GetTaskRunner(task_type)->PostTask( FROM_HERE, WTF::Bind(&EventTarget::DispatchEnqueuedEvent, WrapPersistent(this), @@ -997,10 +999,10 @@ void EventTarget::DispatchEnqueuedEvent(Event* event, ExecutionContext* context) { if (!GetExecutionContext()) { - probe::AsyncTaskCanceled(context, event); + probe::AsyncTaskCanceled(context, event->async_task_id()); return; } - probe::AsyncTask async_task(context, event); + probe::AsyncTask async_task(context, event->async_task_id()); DispatchEvent(*event); }
diff --git a/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc b/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc index 37faa19..3a42dde 100644 --- a/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc +++ b/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc
@@ -25,7 +25,7 @@ TRACE_EVENT_SCOPE_THREAD, "data", inspector_animation_frame_event::Data(context_, id)); probe::AsyncTaskScheduledBreakable(context_, "requestAnimationFrame", - callback); + callback->async_task_id()); return id; } @@ -45,7 +45,7 @@ for (wtf_size_t i = 0; i < frame_callbacks_.size(); ++i) { if (frame_callbacks_[i]->Id() == id) { probe::AsyncTaskCanceledBreakable(context_, probe_name, - frame_callbacks_[i]); + frame_callbacks_[i]->async_task_id()); frame_callbacks_.EraseAt(i); TRACE_EVENT_INSTANT1("devtools.timeline", trace_event_name, TRACE_EVENT_SCOPE_THREAD, "data", @@ -55,8 +55,8 @@ } for (wtf_size_t i = 0; i < post_frame_callbacks_.size(); ++i) { if (post_frame_callbacks_[i]->Id() == id) { - probe::AsyncTaskCanceledBreakable(context_, probe_name, - post_frame_callbacks_[i]); + probe::AsyncTaskCanceledBreakable( + context_, probe_name, post_frame_callbacks_[i]->async_task_id()); post_frame_callbacks_.EraseAt(i); TRACE_EVENT_INSTANT1("devtools.timeline", trace_event_name, TRACE_EVENT_SCOPE_THREAD, "data", @@ -66,7 +66,8 @@ } for (const auto& callback : callbacks_to_invoke_) { if (callback->Id() == id) { - probe::AsyncTaskCanceledBreakable(context_, probe_name, callback); + probe::AsyncTaskCanceledBreakable(context_, probe_name, + callback->async_task_id()); TRACE_EVENT_INSTANT1("devtools.timeline", trace_event_name, TRACE_EVENT_SCOPE_THREAD, "data", inspector_animation_frame_event::Data(context_, id)); @@ -122,7 +123,7 @@ TRACE_EVENT1( "devtools.timeline", trace_event_name, "data", inspector_animation_frame_event::Data(context_, callback->Id())); - probe::AsyncTask async_task(context_, callback); + probe::AsyncTask async_task(context_, callback->async_task_id()); probe::UserCallback probe(context_, probe_name, AtomicString(), true); if (callback->GetUseLegacyTimeBase()) callback->Invoke(high_res_now_ms_legacy); @@ -145,7 +146,7 @@ TRACE_EVENT_SCOPE_THREAD, "data", inspector_animation_frame_event::Data(context_, id)); probe::AsyncTaskScheduledBreakable(context_, "requestPostAnimationFrame", - callback); + callback->async_task_id()); return id; }
diff --git a/third_party/blink/renderer/core/dom/frame_request_callback_collection.h b/third_party/blink/renderer/core/dom/frame_request_callback_collection.h index deafb2cf..daf9d35 100644 --- a/third_party/blink/renderer/core/dom/frame_request_callback_collection.h +++ b/third_party/blink/renderer/core/dom/frame_request_callback_collection.h
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_frame_request_callback.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -44,6 +45,8 @@ use_legacy_time_base_ = use_legacy_time_base; } + probe::AsyncTaskId* async_task_id() { return &async_task_id_; } + protected: FrameCallback() = default; @@ -51,6 +54,7 @@ int id_ = 0; bool is_cancelled_ = false; bool use_legacy_time_base_ = false; + probe::AsyncTaskId async_task_id_; }; // |V8FrameCallback| is an adapter class for the conversion from
diff --git a/third_party/blink/renderer/core/dom/mutation_observer.cc b/third_party/blink/renderer/core/dom/mutation_observer.cc index 3a6ad3f..58f5bc86 100644 --- a/third_party/blink/renderer/core/dom/mutation_observer.cc +++ b/third_party/blink/renderer/core/dom/mutation_observer.cc
@@ -240,7 +240,7 @@ records_.push_back(mutation); Activate(); probe::AsyncTaskScheduled(delegate_->GetExecutionContext(), mutation->type(), - mutation); + mutation->async_task_id()); } void MutationObserver::SetHasTransientRegistration() { @@ -261,8 +261,10 @@ } void MutationObserver::CancelInspectorAsyncTasks() { - for (auto& record : records_) - probe::AsyncTaskCanceled(delegate_->GetExecutionContext(), record); + for (auto& record : records_) { + probe::AsyncTaskCanceled(delegate_->GetExecutionContext(), + record->async_task_id()); + } } void MutationObserver::Deliver() { @@ -287,7 +289,7 @@ // Report the first (earliest) stack as the async cause. probe::AsyncTask async_task(delegate_->GetExecutionContext(), - records.front()); + records.front()->async_task_id()); delegate_->Deliver(records, *this); }
diff --git a/third_party/blink/renderer/core/dom/mutation_record.h b/third_party/blink/renderer/core/dom/mutation_record.h index bc69247..c8e5cce 100644 --- a/third_party/blink/renderer/core/dom/mutation_record.h +++ b/third_party/blink/renderer/core/dom/mutation_record.h
@@ -32,6 +32,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_MUTATION_RECORD_H_ #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -76,6 +77,11 @@ virtual const AtomicString& attributeNamespace() { return g_null_atom; } virtual String oldValue() { return String(); } + + probe::AsyncTaskId* async_task_id() { return &async_task_id_; } + + private: + probe::AsyncTaskId async_task_id_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc index 0f3dcb29..d718532 100644 --- a/third_party/blink/renderer/core/dom/processing_instruction.cc +++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -163,8 +163,8 @@ loading_ = true; if (is_xsl_) { DCHECK(RuntimeEnabledFeatures::XSLTEnabled()); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); XSLStyleSheetResource::Fetch(params, GetDocument().Fetcher(), this); } else { params.SetCharset(charset.IsEmpty() ? GetDocument().Encoding()
diff --git a/third_party/blink/renderer/core/dom/scripted_animation_controller.cc b/third_party/blink/renderer/core/dom/scripted_animation_controller.cc index 0f37c2b..35e7dc298 100644 --- a/third_party/blink/renderer/core/dom/scripted_animation_controller.cc +++ b/third_party/blink/renderer/core/dom/scripted_animation_controller.cc
@@ -132,7 +132,8 @@ // avoid special casting window. // FIXME: We should not fire events for nodes that are no longer in the // tree. - probe::AsyncTask async_task(event_target->GetExecutionContext(), event); + probe::AsyncTask async_task(event_target->GetExecutionContext(), + event->async_task_id()); if (LocalDOMWindow* window = event_target->ToLocalDOMWindow()) window->DispatchEvent(*event, nullptr); else @@ -210,7 +211,7 @@ void ScriptedAnimationController::EnqueueEvent(Event* event) { probe::AsyncTaskScheduled(event->target()->GetExecutionContext(), - event->type(), event); + event->type(), event->async_task_id()); event_queue_.push_back(event); ScheduleAnimationIfNeeded(); }
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc index 4d47f46..a9812c8 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc
@@ -128,7 +128,7 @@ idle_task, queue_timestamp, timeout_millis)); probe::AsyncTaskScheduled(GetExecutionContext(), "requestIdleCallback", - idle_task); + idle_task->async_task_id()); scoped_refptr<internal::IdleRequestCallbackWrapper> callback_wrapper = internal::IdleRequestCallbackWrapper::Create(id, this); @@ -208,7 +208,8 @@ TimeTicks now = CurrentTimeTicks(); TimeDelta allotted_time = std::max(deadline - now, TimeDelta()); - probe::AsyncTask async_task(GetExecutionContext(), idle_task); + probe::AsyncTask async_task(GetExecutionContext(), + idle_task->async_task_id()); probe::UserCallback probe(GetExecutionContext(), "requestIdleCallback", AtomicString(), true);
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h index b5803ff..80a68ee 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_callback.h" #include "third_party/blink/renderer/core/dom/idle_deadline.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/timer.h" @@ -55,6 +56,10 @@ const char* NameInHeapSnapshot() const override { return "IdleTask"; } virtual ~IdleTask() = default; virtual void invoke(IdleDeadline*) = 0; + probe::AsyncTaskId* async_task_id() { return &async_task_id_; } + + private: + probe::AsyncTaskId async_task_id_; }; // |V8IdleTask| is the adapter class for the conversion from
diff --git a/third_party/blink/renderer/core/execution_context/security_context.cc b/third_party/blink/renderer/core/execution_context/security_context.cc index afee13a1..55504fc2 100644 --- a/third_party/blink/renderer/core/execution_context/security_context.cc +++ b/third_party/blink/renderer/core/execution_context/security_context.cc
@@ -68,14 +68,14 @@ } // namespace // static -std::vector<unsigned> SecurityContext::SerializeInsecureNavigationSet( +WebVector<unsigned> SecurityContext::SerializeInsecureNavigationSet( const InsecureNavigationsSet& set) { // The set is serialized as a sorted array. Sorting it makes it easy to know // if two serialized sets are equal. - std::vector<unsigned> serialized; + WebVector<unsigned> serialized; serialized.reserve(set.size()); for (unsigned host : set) - serialized.push_back(host); + serialized.emplace_back(host); std::sort(serialized.begin(), serialized.end()); return serialized;
diff --git a/third_party/blink/renderer/core/execution_context/security_context.h b/third_party/blink/renderer/core/execution_context/security_context.h index 3249b2a..ae66bb0 100644 --- a/third_party/blink/renderer/core/execution_context/security_context.h +++ b/third_party/blink/renderer/core/execution_context/security_context.h
@@ -31,6 +31,7 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" +#include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/sandbox_flags.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -72,7 +73,7 @@ void Trace(blink::Visitor*) override; using InsecureNavigationsSet = HashSet<unsigned, WTF::AlreadyHashed>; - static std::vector<unsigned> SerializeInsecureNavigationSet( + static WebVector<unsigned> SerializeInsecureNavigationSet( const InsecureNavigationsSet&); const SecurityOrigin* GetSecurityOrigin() const { @@ -103,7 +104,7 @@ void SetRequireTrustedTypesForTesting(); // Skips sanity checks. // https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-insecure-navigations-set - void SetInsecureNavigationsSet(const std::vector<unsigned>& set) { + void SetInsecureNavigationsSet(const WebVector<unsigned>& set) { insecure_navigations_to_upgrade_.clear(); for (unsigned hash : set) insecure_navigations_to_upgrade_.insert(hash);
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index d5f21f5..8eba8e1 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -944,7 +944,7 @@ } void LocalFrameClientImpl::DidEnforceInsecureNavigationsSet( - const std::vector<unsigned>& set) { + const WebVector<unsigned>& set) { if (!web_frame_->Client()) return; web_frame_->Client()->DidEnforceInsecureNavigationsSet(set);
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index 1495ed10..754f3ee 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -207,7 +207,7 @@ void FrameFocused() const override; void DidChangeName(const String&) override; void DidEnforceInsecureRequestPolicy(WebInsecureRequestPolicy) override; - void DidEnforceInsecureNavigationsSet(const std::vector<unsigned>&) override; + void DidEnforceInsecureNavigationsSet(const WebVector<unsigned>&) override; void DidChangeFramePolicy(Frame* child_frame, const FramePolicy&) override; void DidSetFramePolicyHeaders( WebSandboxFlags,
diff --git a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc index 7fbe62a..9c2a348 100644 --- a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc +++ b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc
@@ -102,8 +102,8 @@ ClientAdapter(WebAssociatedURLLoaderImpl*, WebAssociatedURLLoaderClient*, const WebAssociatedURLLoaderOptions&, - network::mojom::FetchRequestMode, - network::mojom::FetchCredentialsMode, + network::mojom::RequestMode, + network::mojom::CredentialsMode, scoped_refptr<base::SingleThreadTaskRunner>); // ThreadableLoaderClient @@ -145,8 +145,8 @@ WebAssociatedURLLoaderImpl* loader_; WebAssociatedURLLoaderClient* client_; WebAssociatedURLLoaderOptions options_; - network::mojom::FetchRequestMode fetch_request_mode_; - network::mojom::FetchCredentialsMode credentials_mode_; + network::mojom::RequestMode request_mode_; + network::mojom::CredentialsMode credentials_mode_; base::Optional<WebURLError> error_; TaskRunnerTimer<ClientAdapter> error_timer_; @@ -160,13 +160,13 @@ WebAssociatedURLLoaderImpl* loader, WebAssociatedURLLoaderClient* client, const WebAssociatedURLLoaderOptions& options, - network::mojom::FetchRequestMode fetch_request_mode, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : loader_(loader), client_(client), options_(options), - fetch_request_mode_(fetch_request_mode), + request_mode_(request_mode), credentials_mode_(credentials_mode), error_timer_(std::move(task_runner), this, &ClientAdapter::NotifyError), enable_error_notifications_(false), @@ -203,9 +203,9 @@ return; if (options_.expose_all_response_headers || - (fetch_request_mode_ != network::mojom::FetchRequestMode::kCors && - fetch_request_mode_ != - network::mojom::FetchRequestMode::kCorsWithForcedPreflight)) { + (request_mode_ != network::mojom::RequestMode::kCors && + request_mode_ != + network::mojom::RequestMode::kCorsWithForcedPreflight)) { // Use the original ResourceResponse. client_->DidReceiveResponse(WrappedResourceResponse(response)); return; @@ -383,17 +383,17 @@ } client_ = client; client_adapter_ = MakeGarbageCollected<ClientAdapter>( - this, client, options_, request.GetFetchRequestMode(), - request.GetFetchCredentialsMode(), std::move(task_runner)); + this, client, options_, request.GetMode(), request.GetCredentialsMode(), + std::move(task_runner)); if (allow_load) { ResourceLoaderOptions resource_loader_options; resource_loader_options.data_buffering_policy = kDoNotBufferData; if (options_.grant_universal_access) { - const auto mode = new_request.GetFetchRequestMode(); - DCHECK(mode == network::mojom::FetchRequestMode::kNoCors || - mode == network::mojom::FetchRequestMode::kNavigate); + const auto request_mode = new_request.GetMode(); + DCHECK(request_mode == network::mojom::RequestMode::kNoCors || + request_mode == network::mojom::RequestMode::kNavigate); // Some callers, notablly flash, with |grant_universal_access| want to // have an origin matching with referrer. KURL referrer(request.HttpHeaderField(http_names::kReferer));
diff --git a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc index 3ba267b..1b7b430 100644 --- a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc +++ b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
@@ -164,9 +164,8 @@ void CheckMethodFails(const char* unsafe_method) { WebURLRequest request(ToKURL("http://www.test.com/success.html")); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kSameOrigin); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); request.SetHttpMethod(WebString::FromUTF8(unsafe_method)); WebAssociatedURLLoaderOptions options; options.untrusted_http = true; @@ -179,9 +178,8 @@ void CheckHeaderFails(const char* header_field, const char* header_value) { WebURLRequest request(ToKURL("http://www.test.com/success.html")); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kSameOrigin); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); if (EqualIgnoringASCIICase(WebString::FromUTF8(header_field), "referer")) { request.SetHttpReferrer(WebString::FromUTF8(header_value), network::mojom::ReferrerPolicy::kDefault); @@ -219,9 +217,8 @@ KURL url = ToKURL(id); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); WebString header_name_string(WebString::FromUTF8(header_name)); expected_response_ = WebURLResponse(); @@ -275,8 +272,8 @@ TEST_F(WebAssociatedURLLoaderTest, SameOriginSuccess) { KURL url = ToKURL("http://www.test.com/SameOriginSuccess.html"); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kSameOrigin); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/html"); @@ -298,8 +295,8 @@ // This is cross-origin since the frame was loaded from www.test.com. KURL url = ToKURL("http://www.other.com/SameOriginRestriction.html"); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kSameOrigin); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); CheckFails(request); } @@ -311,7 +308,7 @@ // No-CORS requests (CrossOriginRequestPolicyAllow) aren't allowed for the // default context. So we set the context as Script here. request.SetRequestContext(mojom::RequestContextType::SCRIPT); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/html"); @@ -335,8 +332,8 @@ KURL url = ToKURL("http://www.other.com/CrossOriginWithAccessControlSuccess.html"); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/html"); @@ -364,7 +361,7 @@ // credentials can't be sent to a server which returns the header // "access-control-allow-origin" with "*" as its value. WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); + request.SetMode(network::mojom::RequestMode::kCors); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/html"); @@ -393,8 +390,8 @@ KURL url = ToKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html"); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/html"); @@ -423,8 +420,8 @@ KURL redirect_url = ToKURL(redirect); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kSameOrigin); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_redirect_response_ = WebURLResponse(); expected_redirect_response_.SetMimeType("text/html"); @@ -459,8 +456,8 @@ KURL redirect_url = ToKURL(redirect); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kSameOrigin); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_redirect_response_ = WebURLResponse(); expected_redirect_response_.SetMimeType("text/html"); @@ -499,8 +496,8 @@ KURL redirect_url = ToKURL(redirect); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_redirect_response_ = WebURLResponse(); expected_redirect_response_.SetMimeType("text/html"); @@ -542,8 +539,8 @@ KURL redirect_url = ToKURL(redirect); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); // Add a CORS simple header. request.SetHttpHeaderField("accept", "application/json"); @@ -663,8 +660,8 @@ KURL url = ToKURL("http://www.other.com/CrossOriginHeaderAllowResponseHeaders.html"); WebURLRequest request(url); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); WebString header_name_string(WebString::FromUTF8("non-safelisted")); expected_response_ = WebURLResponse(); @@ -694,8 +691,8 @@ WebURLRequest request(url); request.SetRequestContext(mojom::RequestContextType::PLUGIN); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNoCors); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kNoCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/plain"); @@ -721,8 +718,8 @@ WebURLRequest request(url); request.SetRequestContext(mojom::RequestContextType::PLUGIN); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNoCors); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(network::mojom::RequestMode::kNoCors); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/plain");
diff --git a/third_party/blink/renderer/core/exported/web_frame.cc b/third_party/blink/renderer/core/exported/web_frame.cc index a151099..97cc4d48 100644 --- a/third_party/blink/renderer/core/exported/web_frame.cc +++ b/third_party/blink/renderer/core/exported/web_frame.cc
@@ -169,7 +169,7 @@ return ToCoreFrame(*this)->GetSecurityContext()->GetInsecureRequestPolicy(); } -std::vector<unsigned> WebFrame::GetInsecureRequestToUpgrade() const { +WebVector<unsigned> WebFrame::GetInsecureRequestToUpgrade() const { const SecurityContext::InsecureNavigationsSet& set = ToCoreFrame(*this)->GetSecurityContext()->InsecureNavigationsToUpgrade(); return SecurityContext::SerializeInsecureNavigationSet(set);
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc index 96e89a24..117d29c 100644 --- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc +++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -306,7 +306,7 @@ } void WebRemoteFrameImpl::SetReplicatedInsecureNavigationsSet( - const std::vector<unsigned>& set) { + const WebVector<unsigned>& set) { DCHECK(GetFrame()); GetFrame()->GetSecurityContext()->SetInsecureNavigationsSet(set); }
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h index 87ef4329d..2b59175 100644 --- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h +++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
@@ -79,8 +79,7 @@ WebContentSecurityPolicySource) override; void ResetReplicatedContentSecurityPolicy() override; void SetReplicatedInsecureRequestPolicy(WebInsecureRequestPolicy) override; - void SetReplicatedInsecureNavigationsSet( - const std::vector<unsigned>&) override; + void SetReplicatedInsecureNavigationsSet(const WebVector<unsigned>&) override; void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override; void DispatchLoadEventForFrameOwner() override; void SetNeedsOcclusionTracking(bool) override;
diff --git a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc index fba57aa9..b820697e 100644 --- a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc +++ b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
@@ -147,8 +147,8 @@ main_script_loader_->LoadTopLevelScriptAsynchronously( *shadow_page_->GetDocument(), shadow_page_->GetDocument()->Fetcher(), script_request_url_, mojom::RequestContextType::SHARED_WORKER, - network::mojom::FetchRequestMode::kSameOrigin, - network::mojom::FetchCredentialsMode::kSameOrigin, + network::mojom::RequestMode::kSameOrigin, + network::mojom::CredentialsMode::kSameOrigin, Bind(&WebSharedWorkerImpl::DidReceiveScriptLoaderResponse, WTF::Unretained(this)), Bind(&WebSharedWorkerImpl::OnScriptLoaderFinished,
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc index ea4e59e..d4ae6f19 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
@@ -295,9 +295,7 @@ } bool BodyStreamBuffer::HasPendingActivity() const { - if (loader_) - return true; - return UnderlyingSourceBase::HasPendingActivity(); + return loader_; } void BodyStreamBuffer::ContextDestroyed(ExecutionContext* destroyed_context) {
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc index 70deeea4..bb46eba 100644 --- a/third_party/blink/renderer/core/fetch/fetch_manager.cc +++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -61,9 +61,9 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" -using network::mojom::FetchRedirectMode; -using network::mojom::FetchRequestMode; using network::mojom::FetchResponseType; +using network::mojom::RedirectMode; +using network::mojom::RequestMode; namespace blink { @@ -278,13 +278,13 @@ const KURL& url, const ResourceResponse& response) { const auto redirect_mode = fetch_request_data_->Redirect(); - if (redirect_mode == network::mojom::FetchRedirectMode::kError) { + if (redirect_mode == network::mojom::RedirectMode::kError) { DidFailRedirectCheck(); Dispose(); return false; } - if (redirect_mode == network::mojom::FetchRedirectMode::kManual) { + if (redirect_mode == network::mojom::RedirectMode::kManual) { const uint64_t unused = 0; // There is no need to read the body of redirect response because there is // no way to read the body of opaque-redirect filtered response's internal @@ -302,7 +302,7 @@ return false; } - DCHECK_EQ(redirect_mode, network::mojom::FetchRedirectMode::kFollow); + DCHECK_EQ(redirect_mode, network::mojom::RedirectMode::kFollow); url_list_.push_back(url); return true; } @@ -330,13 +330,13 @@ // TODO(hiroshige): currently redirects to data URLs in no-cors // mode is also rejected by Chromium side. switch (fetch_request_data_->Mode()) { - case FetchRequestMode::kNoCors: + case RequestMode::kNoCors: tainting = FetchRequestData::kOpaqueTainting; break; - case FetchRequestMode::kSameOrigin: - case FetchRequestMode::kCors: - case FetchRequestMode::kCorsWithForcedPreflight: - case FetchRequestMode::kNavigate: + case RequestMode::kSameOrigin: + case RequestMode::kCors: + case RequestMode::kCorsWithForcedPreflight: + case RequestMode::kNavigate: PerformNetworkError("Fetch API cannot load " + fetch_request_data_->Url().GetString() + ". Redirects to data: URL are allowed only when " @@ -349,17 +349,17 @@ // Recompute the tainting if the request was redirected to a different // origin. switch (fetch_request_data_->Mode()) { - case FetchRequestMode::kSameOrigin: + case RequestMode::kSameOrigin: NOTREACHED(); break; - case FetchRequestMode::kNoCors: + case RequestMode::kNoCors: tainting = FetchRequestData::kOpaqueTainting; break; - case FetchRequestMode::kCors: - case FetchRequestMode::kCorsWithForcedPreflight: + case RequestMode::kCors: + case RequestMode::kCorsWithForcedPreflight: tainting = FetchRequestData::kCorsTainting; break; - case FetchRequestMode::kNavigate: + case RequestMode::kNavigate: LOG(FATAL); break; } @@ -432,10 +432,10 @@ DCHECK(!(network_utils::IsRedirectResponseCode(response_http_status_code_) && HasNonEmptyLocationHeader(response_data->HeaderList()) && - fetch_request_data_->Redirect() != FetchRedirectMode::kManual)); + fetch_request_data_->Redirect() != RedirectMode::kManual)); if (network_utils::IsRedirectResponseCode(response_http_status_code_) && - fetch_request_data_->Redirect() == FetchRedirectMode::kManual) { + fetch_request_data_->Redirect() == RedirectMode::kManual) { tainted_response = response_data->CreateOpaqueRedirectFilteredResponse(); } else { switch (tainting) { @@ -563,14 +563,14 @@ ->IsSameSchemeHostPort(fetch_request_data_->Origin().get())) || (fetch_request_data_->Url().ProtocolIsData() && fetch_request_data_->SameOriginDataURLFlag()) || - (fetch_request_data_->Mode() == FetchRequestMode::kNavigate)) { + (fetch_request_data_->Mode() == RequestMode::kNavigate)) { // "The result of performing a scheme fetch using request." PerformSchemeFetch(exception_state); return; } // "- |request|'s mode is |same-origin|" - if (fetch_request_data_->Mode() == FetchRequestMode::kSameOrigin) { + if (fetch_request_data_->Mode() == RequestMode::kSameOrigin) { // "A network error." PerformNetworkError("Fetch API cannot load " + fetch_request_data_->Url().GetString() + @@ -581,10 +581,10 @@ } // "- |request|'s mode is |no CORS|" - if (fetch_request_data_->Mode() == FetchRequestMode::kNoCors) { + if (fetch_request_data_->Mode() == RequestMode::kNoCors) { // "If |request|'s redirect mode is not |follow|, then return a network // error. - if (fetch_request_data_->Redirect() != FetchRedirectMode::kFollow) { + if (fetch_request_data_->Redirect() != RedirectMode::kFollow) { PerformNetworkError("Fetch API cannot load " + fetch_request_data_->Url().GetString() + ". Request mode is \"no-cors\" but the redirect mode " @@ -690,22 +690,22 @@ fetch_request_data_->ShouldAlsoUseFactoryBoundOriginForCors()); switch (fetch_request_data_->Mode()) { - case FetchRequestMode::kSameOrigin: - case FetchRequestMode::kNoCors: - case FetchRequestMode::kCors: - case FetchRequestMode::kCorsWithForcedPreflight: - request.SetFetchRequestMode(fetch_request_data_->Mode()); + case RequestMode::kSameOrigin: + case RequestMode::kNoCors: + case RequestMode::kCors: + case RequestMode::kCorsWithForcedPreflight: + request.SetMode(fetch_request_data_->Mode()); break; - case FetchRequestMode::kNavigate: + case RequestMode::kNavigate: // NetworkService (i.e. CorsURLLoaderFactory::IsSane) rejects kNavigate // requests coming from renderers, so using kSameOrigin here. // TODO(lukasza): Tweak CorsURLLoaderFactory::IsSane to accept kNavigate // if request_initiator and the target are same-origin. - request.SetFetchRequestMode(FetchRequestMode::kSameOrigin); + request.SetMode(RequestMode::kSameOrigin); break; } - request.SetFetchCredentialsMode(fetch_request_data_->Credentials()); + request.SetCredentialsMode(fetch_request_data_->Credentials()); for (const auto& header : fetch_request_data_->HeaderList()->List()) { // Since |fetch_request_data_|'s headers are populated with either of the // "request" guard or "request-no-cors" guard, we can assume that none of @@ -726,7 +726,7 @@ } } request.SetCacheMode(fetch_request_data_->CacheMode()); - request.SetFetchRedirectMode(fetch_request_data_->Redirect()); + request.SetRedirectMode(fetch_request_data_->Redirect()); request.SetFetchImportanceMode(fetch_request_data_->Importance()); request.SetPriority(fetch_request_data_->Priority()); request.SetUseStreamOnResponse(true); @@ -793,8 +793,8 @@ request.SetRequestContext(fetch_request_data_->Context()); request.SetUseStreamOnResponse(true); request.SetHttpMethod(fetch_request_data_->Method()); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); - request.SetFetchRedirectMode(FetchRedirectMode::kError); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); + request.SetRedirectMode(RedirectMode::kError); request.SetFetchImportanceMode(fetch_request_data_->Importance()); request.SetPriority(fetch_request_data_->Priority()); // We intentionally skip 'setExternalRequestStateFromRequestorAddressSpace',
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/third_party/blink/renderer/core/fetch/fetch_request_data.cc index 645bf4f..baabcbb 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.cc +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -198,10 +198,10 @@ same_origin_data_url_flag_(false), referrer_string_(Referrer::ClientReferrerString()), referrer_policy_(network::mojom::ReferrerPolicy::kDefault), - mode_(network::mojom::FetchRequestMode::kNoCors), - credentials_(network::mojom::FetchCredentialsMode::kOmit), + mode_(network::mojom::RequestMode::kNoCors), + credentials_(network::mojom::CredentialsMode::kOmit), cache_mode_(mojom::FetchCacheMode::kDefault), - redirect_(network::mojom::FetchRedirectMode::kFollow), + redirect_(network::mojom::RedirectMode::kFollow), importance_(mojom::FetchImportanceMode::kImportanceAuto), response_tainting_(kBasicTainting), priority_(ResourceLoadPriority::kUnresolved),
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.h b/third_party/blink/renderer/core/fetch/fetch_request_data.h index ad00a00..86b6f85 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.h +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -67,22 +67,20 @@ void SetReferrerPolicy(network::mojom::ReferrerPolicy p) { referrer_policy_ = p; } - void SetMode(network::mojom::FetchRequestMode mode) { mode_ = mode; } - network::mojom::FetchRequestMode Mode() const { return mode_; } - void SetCredentials(network::mojom::FetchCredentialsMode credentials) { + void SetMode(network::mojom::RequestMode mode) { mode_ = mode; } + network::mojom::RequestMode Mode() const { return mode_; } + void SetCredentials(network::mojom::CredentialsMode credentials) { credentials_ = credentials; } - network::mojom::FetchCredentialsMode Credentials() const { - return credentials_; - } + network::mojom::CredentialsMode Credentials() const { return credentials_; } void SetCacheMode(mojom::FetchCacheMode cache_mode) { cache_mode_ = cache_mode; } mojom::FetchCacheMode CacheMode() const { return cache_mode_; } - void SetRedirect(network::mojom::FetchRedirectMode redirect) { + void SetRedirect(network::mojom::RedirectMode redirect) { redirect_ = redirect; } - network::mojom::FetchRedirectMode Redirect() const { return redirect_; } + network::mojom::RedirectMode Redirect() const { return redirect_; } void SetImportance(mojom::FetchImportanceMode importance) { importance_ = importance; } @@ -138,13 +136,13 @@ network::mojom::ReferrerPolicy referrer_policy_; // FIXME: Support m_authenticationFlag; // FIXME: Support m_synchronousFlag; - network::mojom::FetchRequestMode mode_; - network::mojom::FetchCredentialsMode credentials_; + network::mojom::RequestMode mode_; + network::mojom::CredentialsMode credentials_; // TODO(yiyix): |cache_mode_| is exposed but does not yet affect fetch // behavior. We must transfer the mode to the network layer and service // worker. mojom::FetchCacheMode cache_mode_; - network::mojom::FetchRedirectMode redirect_; + network::mojom::RedirectMode redirect_; mojom::FetchImportanceMode importance_; // FIXME: Support m_useURLCredentialsFlag; // FIXME: Support m_redirectCount;
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc index f7ff972..379ca2c 100644 --- a/third_party/blink/renderer/core/fetch/request.cc +++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -279,8 +279,8 @@ // "If any of |init|'s members are present, then:" if (AreAnyMembersPresent(init)) { // "If |request|'s |mode| is "navigate", then set it to "same-origin". - if (request->Mode() == network::mojom::FetchRequestMode::kNavigate) - request->SetMode(network::mojom::FetchRequestMode::kSameOrigin); + if (request->Mode() == network::mojom::RequestMode::kNavigate) + request->SetMode(network::mojom::RequestMode::kSameOrigin); // TODO(yhirano): Implement the following substep: // "Unset |request|'s reload-navigation flag." @@ -368,16 +368,16 @@ return nullptr; } if (init->mode() == "same-origin") { - request->SetMode(network::mojom::FetchRequestMode::kSameOrigin); + request->SetMode(network::mojom::RequestMode::kSameOrigin); } else if (init->mode() == "no-cors") { - request->SetMode(network::mojom::FetchRequestMode::kNoCors); + request->SetMode(network::mojom::RequestMode::kNoCors); } else if (init->mode() == "cors") { - request->SetMode(network::mojom::FetchRequestMode::kCors); + request->SetMode(network::mojom::RequestMode::kCors); } else { // |inputRequest| is directly checked here instead of setting and // checking |fallbackMode| as specified in the spec. if (!input_request) - request->SetMode(network::mojom::FetchRequestMode::kCors); + request->SetMode(network::mojom::RequestMode::kCors); } // This is not yet standardized, but we can assume the following: @@ -400,11 +400,11 @@ // "If |credentials| is non-null, set |request|'s credentials mode to // |credentials|." - network::mojom::FetchCredentialsMode credentials_mode; + network::mojom::CredentialsMode credentials_mode; if (ParseCredentialsMode(init->credentials(), &credentials_mode)) { request->SetCredentials(credentials_mode); } else if (!input_request) { - request->SetCredentials(network::mojom::FetchCredentialsMode::kSameOrigin); + request->SetCredentials(network::mojom::CredentialsMode::kSameOrigin); } // "If |init|'s cache member is present, set |request|'s cache mode to it." @@ -425,7 +425,7 @@ // If |request|’s cache mode is "only-if-cached" and |request|’s mode is not // "same-origin", then throw a TypeError. if (request->CacheMode() == mojom::FetchCacheMode::kOnlyIfCached && - request->Mode() != network::mojom::FetchRequestMode::kSameOrigin) { + request->Mode() != network::mojom::RequestMode::kSameOrigin) { exception_state.ThrowTypeError( "'only-if-cached' can be set only with 'same-origin' mode"); return nullptr; @@ -434,11 +434,11 @@ // "If |init|'s redirect member is present, set |request|'s redirect mode // to it." if (init->redirect() == "follow") { - request->SetRedirect(network::mojom::FetchRedirectMode::kFollow); + request->SetRedirect(network::mojom::RedirectMode::kFollow); } else if (init->redirect() == "error") { - request->SetRedirect(network::mojom::FetchRedirectMode::kError); + request->SetRedirect(network::mojom::RedirectMode::kError); } else if (init->redirect() == "manual") { - request->SetRedirect(network::mojom::FetchRedirectMode::kManual); + request->SetRedirect(network::mojom::RedirectMode::kManual); } // "If |init|'s integrity member is present, set |request|'s @@ -492,7 +492,7 @@ // "Empty |r|'s request's header list." r->request_->HeaderList()->ClearList(); // "If |r|'s request's mode is "no-cors", run these substeps: - if (r->GetRequest()->Mode() == network::mojom::FetchRequestMode::kNoCors) { + if (r->GetRequest()->Mode() == network::mojom::RequestMode::kNoCors) { // "If |r|'s request's method is not a CORS-safelisted method, throw a // TypeError." if (!cors::IsCorsSafelistedMethod(r->GetRequest()->Method())) { @@ -634,19 +634,18 @@ return MakeGarbageCollected<Request>(script_state, data); } -bool Request::ParseCredentialsMode( - const String& credentials_mode, - network::mojom::FetchCredentialsMode* result) { +bool Request::ParseCredentialsMode(const String& credentials_mode, + network::mojom::CredentialsMode* result) { if (credentials_mode == "omit") { - *result = network::mojom::FetchCredentialsMode::kOmit; + *result = network::mojom::CredentialsMode::kOmit; return true; } if (credentials_mode == "same-origin") { - *result = network::mojom::FetchCredentialsMode::kSameOrigin; + *result = network::mojom::CredentialsMode::kSameOrigin; return true; } if (credentials_mode == "include") { - *result = network::mojom::FetchCredentialsMode::kInclude; + *result = network::mojom::CredentialsMode::kInclude; return true; } return false; @@ -724,14 +723,14 @@ // "The mode attribute's getter must return the value corresponding to the // first matching statement, switching on request's mode:" switch (request_->Mode()) { - case network::mojom::FetchRequestMode::kSameOrigin: + case network::mojom::RequestMode::kSameOrigin: return "same-origin"; - case network::mojom::FetchRequestMode::kNoCors: + case network::mojom::RequestMode::kNoCors: return "no-cors"; - case network::mojom::FetchRequestMode::kCors: - case network::mojom::FetchRequestMode::kCorsWithForcedPreflight: + case network::mojom::RequestMode::kCors: + case network::mojom::RequestMode::kCorsWithForcedPreflight: return "cors"; - case network::mojom::FetchRequestMode::kNavigate: + case network::mojom::RequestMode::kNavigate: return "navigate"; } NOTREACHED(); @@ -743,11 +742,11 @@ // to the first matching statement, switching on request's credentials // mode:" switch (request_->Credentials()) { - case network::mojom::FetchCredentialsMode::kOmit: + case network::mojom::CredentialsMode::kOmit: return "omit"; - case network::mojom::FetchCredentialsMode::kSameOrigin: + case network::mojom::CredentialsMode::kSameOrigin: return "same-origin"; - case network::mojom::FetchCredentialsMode::kInclude: + case network::mojom::CredentialsMode::kInclude: return "include"; } NOTREACHED(); @@ -781,11 +780,11 @@ String Request::redirect() const { // "The redirect attribute's getter must return request's redirect mode." switch (request_->Redirect()) { - case network::mojom::FetchRedirectMode::kFollow: + case network::mojom::RedirectMode::kFollow: return "follow"; - case network::mojom::FetchRedirectMode::kError: + case network::mojom::RedirectMode::kError: return "error"; - case network::mojom::FetchRedirectMode::kManual: + case network::mojom::RedirectMode::kManual: return "manual"; } NOTREACHED();
diff --git a/third_party/blink/renderer/core/fetch/request.h b/third_party/blink/renderer/core/fetch/request.h index 7031724..0f1cf26 100644 --- a/third_party/blink/renderer/core/fetch/request.h +++ b/third_party/blink/renderer/core/fetch/request.h
@@ -64,7 +64,7 @@ // Returns false if |credentials_mode| doesn't represent a valid credentials // mode. static bool ParseCredentialsMode(const String& credentials_mode, - network::mojom::FetchCredentialsMode*); + network::mojom::CredentialsMode*); // From Request.idl: String method() const;
diff --git a/third_party/blink/renderer/core/fetch/request_test.cc b/third_party/blink/renderer/core/fetch/request_test.cc index 1e216e0..59cd95d 100644 --- a/third_party/blink/renderer/core/fetch/request_test.cc +++ b/third_party/blink/renderer/core/fetch/request_test.cc
@@ -59,13 +59,13 @@ const network::mojom::ReferrerPolicy kReferrerPolicy = network::mojom::ReferrerPolicy::kAlways; const mojom::RequestContextType kContext = mojom::RequestContextType::AUDIO; - const network::mojom::FetchRequestMode kMode = - network::mojom::FetchRequestMode::kNavigate; - const network::mojom::FetchCredentialsMode kCredentialsMode = - network::mojom::FetchCredentialsMode::kInclude; + const network::mojom::RequestMode kMode = + network::mojom::RequestMode::kNavigate; + const network::mojom::CredentialsMode kCredentialsMode = + network::mojom::CredentialsMode::kInclude; const auto kCacheMode = mojom::FetchCacheMode::kValidateCache; - const network::mojom::FetchRedirectMode kRedirectMode = - network::mojom::FetchRedirectMode::kError; + const network::mojom::RedirectMode kRedirectMode = + network::mojom::RedirectMode::kError; fetch_api_request->url = url; fetch_api_request->method = method;
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.cc b/third_party/blink/renderer/core/fileapi/file_reader.cc index 5aeef60..034b7063 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader.cc
@@ -95,7 +95,7 @@ if (!controller) return; - probe::AsyncTaskScheduled(context, "FileReader", reader); + probe::AsyncTaskScheduled(context, "FileReader", reader->async_task_id()); controller->PushReader(reader); } @@ -116,7 +116,7 @@ return; controller->FinishReader(reader, next_step); - probe::AsyncTaskCanceled(context, reader); + probe::AsyncTaskCanceled(context, reader->async_task_id()); } explicit ThrottlingController(ExecutionContext& context) @@ -459,7 +459,7 @@ } void FileReader::FireEvent(const AtomicString& type) { - probe::AsyncTask async_task(GetExecutionContext(), this, "event"); + probe::AsyncTask async_task(GetExecutionContext(), async_task_id(), "event"); if (!loader_) { DispatchEvent(*ProgressEvent::Create(type, false, 0, 0)); return;
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.h b/third_party/blink/renderer/core/fileapi/file_reader.h index 17ed1a4..335c94957 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader.h +++ b/third_party/blink/renderer/core/fileapi/file_reader.h
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/fileapi/file_reader_loader.h" #include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -74,6 +75,7 @@ ReadyState getReadyState() const { return state_; } DOMException* error() { return error_; } void result(ScriptState*, StringOrArrayBuffer& result_attribute) const; + probe::AsyncTaskId* async_task_id() { return &async_task_id_; } // ContextLifecycleObserver void ContextDestroyed(ExecutionContext*) override; @@ -128,6 +130,7 @@ scoped_refptr<BlobDataHandle> blob_data_handle_; FileReaderLoader::ReadType read_type_; String encoding_; + probe::AsyncTaskId async_task_id_; std::unique_ptr<FileReaderLoader> loader_; Member<DOMException> error_;
diff --git a/third_party/blink/renderer/core/frame/ad_tracker.cc b/third_party/blink/renderer/core/frame/ad_tracker.cc index 64ccaefa..8970096 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker.cc +++ b/third_party/blink/renderer/core/frame/ad_tracker.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/feature_list.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/core_probe_sink.h" @@ -32,7 +33,31 @@ } // namespace -AdTracker::AdTracker(LocalFrame* local_root) : local_root_(local_root) { +namespace features { +// Controls whether the AdTracker will look across async stacks to determine if +// the currently running stack is ad related. +const base::Feature kAsyncStackAdTagging{"AsyncStackAdTagging", + base::FEATURE_DISABLED_BY_DEFAULT}; +} // namespace features + +// static +AdTracker* AdTracker::FromExecutionContext( + ExecutionContext* execution_context) { + if (!execution_context) + return nullptr; + if (auto* document = DynamicTo<Document>(execution_context)) { + LocalFrame* frame = document->GetFrame(); + if (frame) { + return frame->GetAdTracker(); + } + } + return nullptr; +} + +AdTracker::AdTracker(LocalFrame* local_root) + : local_root_(local_root), + async_stack_enabled_( + base::FeatureList::IsEnabled(features::kAsyncStackAdTagging)) { local_root_->GetProbeSink()->AddAdTracker(this); } @@ -132,8 +157,35 @@ return known_ad; } +void AdTracker::DidCreateAsyncTask(probe::AsyncTaskId* task) { + DCHECK(task); + if (!async_stack_enabled_) + return; + + if (IsAdScriptInStack()) + task->SetAdTask(); +} + +void AdTracker::DidStartAsyncTask(probe::AsyncTaskId* task) { + DCHECK(task); + if (!async_stack_enabled_) + return; + + if (task->IsAdTask()) + running_ad_async_tasks_ += 1; +} + +void AdTracker::DidFinishAsyncTask(probe::AsyncTaskId* task) { + DCHECK(task); + if (!async_stack_enabled_) + return; + + if (task->IsAdTask()) + running_ad_async_tasks_ -= 1; +} + bool AdTracker::IsAdScriptInStack() { - if (num_ads_in_stack_ > 0) + if (num_ads_in_stack_ > 0 || running_ad_async_tasks_ > 0) return true; ExecutionContext* execution_context = GetCurrentExecutionContext();
diff --git a/third_party/blink/renderer/core/frame/ad_tracker.h b/third_party/blink/renderer/core/frame/ad_tracker.h index b88ff12..001981e 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker.h +++ b/third_party/blink/renderer/core/frame/ad_tracker.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" @@ -24,10 +25,17 @@ class ExecuteScript; } // namespace probe +namespace features { +CORE_EXPORT extern const base::Feature kAsyncStackAdTagging; +} + // Tracker for tagging resources as ads based on the call stack scripts. // The tracker is maintained per local root. class CORE_EXPORT AdTracker : public GarbageCollectedFinalized<AdTracker> { public: + // Finds an AdTracker for a given ExecutionContext. + static AdTracker* FromExecutionContext(ExecutionContext*); + // Instrumenting methods. // Called when a script module or script gets executed from native code. void Will(const probe::ExecuteScript&); @@ -48,6 +56,16 @@ ResourceType resource_type, bool known_ad); + // Called when an async task is created. Check at this point for ad script on + // the stack and annotate the task if so. + void DidCreateAsyncTask(probe::AsyncTaskId* task); + + // Called when an async task is eventually run. + void DidStartAsyncTask(probe::AsyncTaskId* task); + + // Called when the task has finished running. + void DidFinishAsyncTask(probe::AsyncTaskId* task); + // Returns true if any script in the pseudo call stack has previously been // identified as an ad resource. bool IsAdScriptInStack(); @@ -84,6 +102,11 @@ // The set of ad scripts detected outside of ad-frame contexts. HeapHashMap<WeakMember<ExecutionContext>, HashSet<String>> known_ad_scripts_; + // The number of ad-related async tasks currently running in the stack. + uint32_t running_ad_async_tasks_ = 0; + + const bool async_stack_enabled_; + DISALLOW_COPY_AND_ASSIGN(AdTracker); };
diff --git a/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/third_party/blink/renderer/core/frame/ad_tracker_test.cc index 2a88349..b5f92e2 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker_test.cc +++ b/third_party/blink/renderer/core/frame/ad_tracker_test.cc
@@ -6,8 +6,11 @@ #include <memory> +#include "base/test/scoped_feature_list.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" @@ -88,6 +91,13 @@ return page_holder_->GetDocument().GetFrame(); } + void CreateAdTracker() { + if (ad_tracker_) + ad_tracker_->Shutdown(); + ad_tracker_ = MakeGarbageCollected<TestAdTracker>(GetFrame()); + ad_tracker_->SetExecutionContext(&page_holder_->GetDocument()); + } + void WillExecuteScript(const String& script_url) { ad_tracker_->WillExecuteScript(&page_holder_->GetDocument(), String(script_url)); @@ -110,8 +120,7 @@ void AdTrackerTest::SetUp() { page_holder_ = std::make_unique<DummyPageHolder>(IntSize(800, 600)); page_holder_->GetDocument().SetURL(KURL("https://example.com/foo")); - ad_tracker_ = MakeGarbageCollected<TestAdTracker>(GetFrame()); - ad_tracker_->SetExecutionContext(&page_holder_->GetDocument()); + CreateAdTracker(); } void AdTrackerTest::TearDown() { @@ -195,6 +204,49 @@ EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); } +TEST_F(AdTrackerTest, AsyncTagging) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kAsyncStackAdTagging); + CreateAdTracker(); + + // Put an ad script on the stack. + AppendToKnownAdScripts("https://example.com/ad.js"); + WillExecuteScript("https://example.com/ad.js"); + EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); + + // Create a fake task void*. + probe::AsyncTaskId async_task; + + // Create an async task while ad script is running. + ad_tracker_->DidCreateAsyncTask(&async_task); + + // Finish executing the ad script. + DidExecuteScript(); + EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResource()); + + // Start and stop the async task created by the ad script. + ad_tracker_->DidStartAsyncTask(&async_task); + EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); + ad_tracker_->DidFinishAsyncTask(&async_task); + EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResource()); + + // Do it again. + ad_tracker_->DidStartAsyncTask(&async_task); + EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); + ad_tracker_->DidFinishAsyncTask(&async_task); + EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResource()); + + // Call the task recursively. + ad_tracker_->DidStartAsyncTask(&async_task); + EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); + ad_tracker_->DidStartAsyncTask(&async_task); + EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); + ad_tracker_->DidFinishAsyncTask(&async_task); + EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); + ad_tracker_->DidFinishAsyncTask(&async_task); + EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResource()); +} + class AdTrackerSimTest : public SimTest { protected: void SetUp() override { @@ -372,7 +424,15 @@ } // Image loaded by ad script is tagged as ad. -TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScript) { +TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScriptAsyncEnabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kAsyncStackAdTagging); + + // Reset the AdTracker so that it gets the latest base::Feature value on + // construction. + ad_tracker_ = MakeGarbageCollected<TestAdTracker>(GetDocument().GetFrame()); + GetDocument().GetFrame()->SetAdTrackerForTesting(ad_tracker_); + const char kAdUrl[] = "https://example.com/ad_script.js"; const char kVanillaUrl[] = "https://example.com/vanilla_image.jpg"; SimSubresourceRequest ad_resource(kAdUrl, "text/javascript"); @@ -395,7 +455,47 @@ EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl)); EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl)); - // TODO(crbug.com/848916): Should be true. + + // Image loading is async, so we should catch this when async stacks are + // monitored. + EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl)); +} + +// Image loaded by ad script is tagged as ad. +TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScriptAsyncDisabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(features::kAsyncStackAdTagging); + + // Reset the AdTracker so that it gets the latest base::Feature value on + // construction. + ad_tracker_ = MakeGarbageCollected<TestAdTracker>(GetDocument().GetFrame()); + GetDocument().GetFrame()->SetAdTrackerForTesting(ad_tracker_); + + const char kAdUrl[] = "https://example.com/ad_script.js"; + const char kVanillaUrl[] = "https://example.com/vanilla_image.jpg"; + SimSubresourceRequest ad_resource(kAdUrl, "text/javascript"); + SimSubresourceRequest vanilla_image(kVanillaUrl, "image/jpeg"); + + ad_tracker_->SetAdSuffix("ad_script.js"); + + main_resource_->Complete("<body></body><script src=ad_script.js></script>"); + + ad_resource.Complete(R"SCRIPT( + image = document.createElement("img"); + image.src = "vanilla_image.jpg"; + document.body.appendChild(image); + )SCRIPT"); + + // Wait for script to run. + base::RunLoop().RunUntilIdle(); + + vanilla_image.Complete(""); + + EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl)); + EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl)); + + // Image loading is async, so we won't catch this when async stacks aren't + // monitored. EXPECT_FALSE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl)); }
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc index a5fe12b..8ecf36b1 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -185,10 +185,11 @@ void ContentSecurityPolicy::ApplyPolicySideEffectsToDelegate() { DCHECK(delegate_); - const SecurityOrigin* security_origin = delegate_->GetSecurityOrigin(); - DCHECK(security_origin); + const SecurityOrigin* self_origin = + delegate_->GetSecurityOrigin()->GetOriginOrPrecursorOriginIfOpaque(); + DCHECK(self_origin); - SetupSelf(*security_origin); + SetupSelf(*self_origin); // Set mixed content checking and sandbox flags, then dump all the parsing // error messages, then poke at histograms. @@ -1615,13 +1616,10 @@ WebContentSecurityPolicyList ContentSecurityPolicy::ExposeForNavigationalChecks() const { - std::vector<WebContentSecurityPolicy> policies; - for (const auto& policy : policies_) { - policies.push_back(policy->ExposeForNavigationalChecks()); - } - WebContentSecurityPolicyList list; - list.policies = policies; + for (const auto& policy : policies_) { + list.policies.emplace_back(policy->ExposeForNavigationalChecks()); + } if (self_source_) list.self_source = self_source_->ExposeForNavigationalChecks();
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index c912fdb..6919bd0 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -1601,4 +1601,23 @@ csp->HasPolicyFromSource(kContentSecurityPolicyHeaderSourceHTTP)); } +TEST_F(ContentSecurityPolicyTest, OpaqueOriginBeforeBind) { + const KURL url("https://example.test"); + + // Security Origin of execution context might change when sandbox flags + // are applied. This shouldn't change the application of the 'self' + // determination. + secure_origin = secure_origin->DeriveNewOpaqueOrigin(); + execution_context = CreateExecutionContext(); + csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); + csp->DidReceiveHeader("default-src 'self';", + kContentSecurityPolicyHeaderTypeEnforce, + kContentSecurityPolicyHeaderSourceMeta); + EXPECT_TRUE( + csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, url, String(), + IntegrityMetadataSet(), kParserInserted, + ResourceRequest::RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index e861ed8f..5da19f6d 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -1575,31 +1575,26 @@ policy.disposition = static_cast<mojom::ContentSecurityPolicyType>(header_type_); policy.source = static_cast<WebContentSecurityPolicySource>(header_source_); - std::vector<WebContentSecurityPolicyDirective> directives; for (const auto& directive : {child_src_, default_src_, form_action_, frame_src_, navigate_to_}) { if (directive) { - directives.push_back(WebContentSecurityPolicyDirective{ + policy.directives.emplace_back(WebContentSecurityPolicyDirective{ directive->DirectiveName(), directive->ExposeForNavigationalChecks()}); } } if (upgrade_insecure_requests_) { - directives.push_back(WebContentSecurityPolicyDirective{ + policy.directives.emplace_back(WebContentSecurityPolicyDirective{ blink::WebString("upgrade-insecure-requests"), WebContentSecurityPolicySourceList()}); } - policy.directives = directives; - std::vector<WebString> report_endpoints; for (const auto& report_endpoint : ReportEndpoints()) { - report_endpoints.push_back(report_endpoint); + policy.report_endpoints.emplace_back(report_endpoint); } policy.use_reporting_api = use_reporting_api_; - policy.report_endpoints = report_endpoints; - policy.header = Header(); return policy;
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc index 019d3ce3..c9d1525 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -6,7 +6,6 @@ #include <list> #include <string> -#include <vector> #include "base/test/scoped_feature_list.h" #include "services/network/public/cpp/features.h" @@ -665,7 +664,7 @@ kContentSecurityPolicyHeaderTypeEnforce); struct TestCase { - const std::vector<const char*> policies; + const Vector<const char*> policies; bool expected; bool expected_first_policy_opposite; } cases[] = { @@ -743,7 +742,7 @@ TEST_F(CSPDirectiveListTest, SubsumesIfNoneIsPresent) { struct TestCase { const char* policy_a; - const std::vector<const char*> policies_b; + const Vector<const char*> policies_b; bool expected; } cases[] = { // `policyA` subsumes any vector of policies. @@ -844,7 +843,7 @@ TEST_F(CSPDirectiveListTest, SubsumesPluginTypes) { struct TestCase { const char* policy_a; - const std::vector<const char*> policies_b; + const Vector<const char*> policies_b; bool expected; } cases[] = { // `policyA` subsumes `policiesB`. @@ -926,7 +925,7 @@ TEST_F(CSPDirectiveListTest, OperativeDirectiveGivenType) { struct TestCase { ContentSecurityPolicy::DirectiveType directive; - std::vector<ContentSecurityPolicy::DirectiveType> fallback_list; + Vector<ContentSecurityPolicy::DirectiveType> fallback_list; } cases[] = { // Directives with default directive. {ContentSecurityPolicy::DirectiveType::kChildSrc, @@ -986,12 +985,12 @@ EXPECT_FALSE(empty->OperativeDirective(test.directive)); // Add the directive itself as it should be the first one to be returned. - test.fallback_list.insert(test.fallback_list.begin(), test.directive); + test.fallback_list.push_front(test.directive); // Start the tests with all directives present. directive_string = all_directives.str(); - while (!test.fallback_list.empty()) { + while (!test.fallback_list.IsEmpty()) { directive_list = CreateList(directive_string.c_str(), kContentSecurityPolicyHeaderTypeEnforce); @@ -1032,7 +1031,7 @@ } TEST_F(CSPDirectiveListTest, GetSourceVector) { - const std::vector<const char*> policies = { + const Vector<const char*> policies = { // Policy 1 "default-src https://default-src.com", // Policy 2
diff --git a/third_party/blink/renderer/core/frame/csp/media_list_directive_test.cc b/third_party/blink/renderer/core/frame/csp/media_list_directive_test.cc index 1176f045c..3436ce31 100644 --- a/third_party/blink/renderer/core/frame/csp/media_list_directive_test.cc +++ b/third_party/blink/renderer/core/frame/csp/media_list_directive_test.cc
@@ -6,6 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -26,12 +27,12 @@ struct TestCase { const char* policy_b; - const std::vector<const char*> expected; + const Vector<const char*> expected; } cases[] = { - {"", std::vector<const char*>()}, - {"text/", std::vector<const char*>()}, - {"text/*", std::vector<const char*>()}, - {"*/plain", std::vector<const char*>()}, + {"", Vector<const char*>()}, + {"text/", Vector<const char*>()}, + {"text/*", Vector<const char*>()}, + {"*/plain", Vector<const char*>()}, {"text/plain */plain", {"text/plain"}}, {"text/plain application/*", {"text/plain"}}, {"text/plain", {"text/plain"}}, @@ -73,7 +74,7 @@ csp.Get()); struct TestCase { - const std::vector<const char*> policies_b; + const Vector<const char*> policies_b; bool subsumed; bool subsumed_by_empty_a; } cases[] = { @@ -119,7 +120,7 @@ true, true}, // `A` does not subsumes `policiesB`. - {std::vector<const char*>(), false, false}, + {Vector<const char*>(), false, false}, {{"application/x-blink-test-plugin"}, false, false}, {{"application/x-shockwave-flash text/plain " "application/x-blink-test-plugin"},
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc b/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc index 7f7b237..099801e 100644 --- a/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc +++ b/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
@@ -353,7 +353,7 @@ SourceListDirective required("script-src", required_sources, csp.Get()); struct TestCase { - std::vector<String> sources_vector; + Vector<String> sources_vector; bool expected; } cases[] = { // Non-intersecting source lists give an effective policy of 'none', which @@ -436,7 +436,7 @@ csp.Get()); struct TestCase { - std::vector<const char*> sources_b; + Vector<const char*> sources_b; const char* origin_b; bool expected; } cases[] = { @@ -607,7 +607,7 @@ struct TestCase { bool is_script_src; String sources_a; - std::vector<String> sources_b; + Vector<String> sources_b; bool expected; } cases[] = { // `sourcesA` allows all inline behavior. @@ -716,7 +716,7 @@ struct TestCase { bool is_script_src; String sources_a; - std::vector<String> sources_b; + Vector<String> sources_b; bool expected; } cases[] = { // A or policiesB contain `unsafe-eval`. @@ -920,7 +920,7 @@ struct TestCase { bool is_script_src; String sources_a; - std::vector<String> sources_b; + Vector<String> sources_b; bool expected; } cases[] = { // Check nonces. @@ -1068,7 +1068,7 @@ struct TestCase { bool is_script_src; String sources_a; - std::vector<String> sources_b; + Vector<String> sources_b; bool expected; } cases[] = { // Neither A nor effective policy of list B has `strict-dynamic`. @@ -1243,7 +1243,7 @@ TEST_F(SourceListDirectiveTest, SubsumesListWildcard) { struct TestCase { const char* sources_a; - std::vector<const char*> sources_b; + Vector<const char*> sources_b; bool expected; } cases[] = { // `A` subsumes `policiesB`.. @@ -1274,7 +1274,7 @@ {"*", "http://a.com ws://b.com ftp://c.com"}, true}, // `A` does not subsume `policiesB`.. - {"*", std::vector<const char*>(), false}, + {"*", Vector<const char*>(), false}, {"", {"*"}, false}, {"'none'", {"*"}, false}, {"*", {"data:"}, false},
diff --git a/third_party/blink/renderer/core/frame/dom_timer.cc b/third_party/blink/renderer/core/frame/dom_timer.cc index 419c2da..32ef55a 100644 --- a/third_party/blink/renderer/core/frame/dom_timer.cc +++ b/third_party/blink/renderer/core/frame/dom_timer.cc
@@ -108,7 +108,7 @@ inspector_timer_install_event::Data( context, timeout_id, interval, single_shot)); probe::AsyncTaskScheduledBreakable( - context, single_shot ? "setTimeout" : "setInterval", this); + context, single_shot ? "setTimeout" : "setInterval", &async_task_id_); } DOMTimer::~DOMTimer() { @@ -120,7 +120,7 @@ const bool is_interval = !RepeatInterval().is_zero(); probe::AsyncTaskCanceledBreakable( GetExecutionContext(), is_interval ? "clearInterval" : "clearTimeout", - this); + &async_task_id_); user_gesture_token_ = nullptr; // Need to release JS objects potentially protected by ScheduledAction @@ -150,7 +150,8 @@ const bool is_interval = !RepeatInterval().is_zero(); probe::UserCallback probe(context, is_interval ? "setInterval" : "setTimeout", g_null_atom, true); - probe::AsyncTask async_task(context, this, is_interval ? "fired" : nullptr); + probe::AsyncTask async_task(context, &async_task_id_, + is_interval ? "fired" : nullptr); // Simple case for non-one-shot timers. if (IsActive()) {
diff --git a/third_party/blink/renderer/core/frame/dom_timer.h b/third_party/blink/renderer/core/frame/dom_timer.h index 58da7f4..517ebb9d 100644 --- a/third_party/blink/renderer/core/frame/dom_timer.h +++ b/third_party/blink/renderer/core/frame/dom_timer.h
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/timer.h" @@ -84,6 +85,7 @@ int timeout_id_; int nesting_level_; + probe::AsyncTaskId async_task_id_; Member<ScheduledAction> action_; scoped_refptr<UserGestureToken> user_gesture_token_; };
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index ae0a6c2f..45af36ae 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -556,7 +556,7 @@ WrapPersistent(this), WrapPersistent(event), WrapRefCounted(UserGestureIndicator::CurrentToken()), std::move(target), std::move(location))); - probe::AsyncTaskScheduled(document(), "postMessage", event); + probe::AsyncTaskScheduled(document(), "postMessage", event->async_task_id()); } void LocalDOMWindow::DispatchPostMessage( @@ -564,7 +564,7 @@ scoped_refptr<UserGestureToken> token, scoped_refptr<const SecurityOrigin> intended_target_origin, std::unique_ptr<SourceLocation> location) { - probe::AsyncTask async_task(document(), event); + probe::AsyncTask async_task(document(), event->async_task_id()); if (!IsCurrentlyDisplayedInFrame()) return;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index 21cf8f4..a240c7b 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -348,7 +348,7 @@ virtual void DidChangeName(const String&) {} virtual void DidEnforceInsecureRequestPolicy(WebInsecureRequestPolicy) {} - virtual void DidEnforceInsecureNavigationsSet(const std::vector<unsigned>&) {} + virtual void DidEnforceInsecureNavigationsSet(const WebVector<unsigned>&) {} virtual void DidChangeFramePolicy(Frame* child_frame, const FramePolicy&) {}
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 bea964f1..5d2dae44 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1221,6 +1221,9 @@ frame_->GetDocument()->Lifecycle().LifecyclePostponed()) return; + if (frame_->IsMainFrame()) + jank_tracker_->NotifyViewportSizeChanged(); + auto* layout_view = GetLayoutView(); if (layout_view) { // If this is the main frame, we might have got here by hiding/showing the
diff --git a/third_party/blink/renderer/core/frame/use_counter_helper.cc b/third_party/blink/renderer/core/frame/use_counter_helper.cc index cd959476..c92d3b8 100644 --- a/third_party/blink/renderer/core/frame/use_counter_helper.cc +++ b/third_party/blink/renderer/core/frame/use_counter_helper.cc
@@ -1250,6 +1250,7 @@ // value. // 3. Run the update_use_counter_css.py script in // chromium/src/tools/metrics/histograms to update the UMA histogram names. + case CSSPropertyID::kInternalEffectiveZoom: case CSSPropertyID::kInternalVisitedBackgroundColor: case CSSPropertyID::kInternalVisitedBorderBlockEndColor: case CSSPropertyID::kInternalVisitedBorderBlockStartColor:
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc index c768811..a309639 100644 --- a/third_party/blink/renderer/core/html/html_plugin_element.cc +++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -294,10 +294,8 @@ } void HTMLPlugInElement::IntrinsicSizingInfoChanged() { - if (auto* layout_object = GetLayoutObject()) { - layout_object->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( - layout_invalidation_reason::kUnknown); - } + if (auto* embedded_object = GetLayoutEmbeddedObject()) + embedded_object->IntrinsicSizeChanged(); } void HTMLPlugInElement::UpdatePlugin() { @@ -602,11 +600,9 @@ } LayoutEmbeddedObject* HTMLPlugInElement::GetLayoutEmbeddedObject() const { - // HTMLObjectElement and HTMLEmbedElement may return arbitrary layoutObjects + // HTMLObjectElement and HTMLEmbedElement may return arbitrary LayoutObjects // when using fallback content. - if (!GetLayoutObject() || !GetLayoutObject()->IsEmbeddedObject()) - return nullptr; - return ToLayoutEmbeddedObject(GetLayoutObject()); + return ToLayoutEmbeddedObjectOrNull(GetLayoutObject()); } // We don't use url_, as it may not be the final URL that the object loads,
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index fbcf1a2..b443048e 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -58,8 +58,8 @@ struct CorsTestCase { const char* base_url; const char* input_html; - network::mojom::FetchRequestMode request_mode; - network::mojom::FetchCredentialsMode credentials_mode; + network::mojom::RequestMode request_mode; + network::mojom::CredentialsMode credentials_mode; }; struct CSPTestCase { @@ -159,15 +159,14 @@ void CorsRequestVerification( Document* document, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode) { ASSERT_TRUE(preload_request_.get()); Resource* resource = preload_request_->Start(document); ASSERT_TRUE(resource); - EXPECT_EQ(request_mode, - resource->GetResourceRequest().GetFetchRequestMode()); + EXPECT_EQ(request_mode, resource->GetResourceRequest().GetMode()); EXPECT_EQ(credentials_mode, - resource->GetResourceRequest().GetFetchCredentialsMode()); + resource->GetResourceRequest().GetCredentialsMode()); } void NonceRequestVerification(const char* nonce) { @@ -910,27 +909,27 @@ TEST_F(HTMLPreloadScannerTest, testCors) { CorsTestCase test_cases[] = { {"http://example.test", "<script src='/script'></script>", - network::mojom::FetchRequestMode::kNoCors, - network::mojom::FetchCredentialsMode::kInclude}, + network::mojom::RequestMode::kNoCors, + network::mojom::CredentialsMode::kInclude}, {"http://example.test", "<script crossorigin src='/script'></script>", - network::mojom::FetchRequestMode::kCors, - network::mojom::FetchCredentialsMode::kSameOrigin}, + network::mojom::RequestMode::kCors, + network::mojom::CredentialsMode::kSameOrigin}, {"http://example.test", "<script crossorigin=use-credentials src='/script'></script>", - network::mojom::FetchRequestMode::kCors, - network::mojom::FetchCredentialsMode::kInclude}, + network::mojom::RequestMode::kCors, + network::mojom::CredentialsMode::kInclude}, {"http://example.test", "<script type='module' src='/script'></script>", - network::mojom::FetchRequestMode::kCors, - network::mojom::FetchCredentialsMode::kSameOrigin}, + network::mojom::RequestMode::kCors, + network::mojom::CredentialsMode::kSameOrigin}, {"http://example.test", "<script type='module' crossorigin='anonymous' src='/script'></script>", - network::mojom::FetchRequestMode::kCors, - network::mojom::FetchCredentialsMode::kSameOrigin}, + network::mojom::RequestMode::kCors, + network::mojom::CredentialsMode::kSameOrigin}, {"http://example.test", "<script type='module' crossorigin='use-credentials' " "src='/script'></script>", - network::mojom::FetchRequestMode::kCors, - network::mojom::FetchCredentialsMode::kInclude}, + network::mojom::RequestMode::kCors, + network::mojom::CredentialsMode::kInclude}, }; for (const auto& test_case : test_cases) {
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl index 7a020824..70b2efbc 100644 --- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl +++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -585,6 +585,8 @@ sensors videoCapture idleDetection + wakeLockScreen + wakeLockSystem # Grant specific permissions to the given origin and reject all others. experimental command grantPermissions
diff --git a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc index 979936d..b388c705b 100644 --- a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
@@ -222,12 +222,16 @@ if (id_to_animation_clone_.at(id)) animation = id_to_animation_clone_.at(id); - if (animation->Paused()) { + if (animation->Paused() || !animation->timeline()->IsActive()) { *current_time = animation->currentTime(); } else { // Use startTime where possible since currentTime is limited. - *current_time = animation->TimelineInternal()->currentTime() - - animation->startTime().value_or(NullValue()); + base::Optional<double> timeline_time = animation->timeline()->CurrentTime(); + // TODO(crbug.com/916117): Handle NaN values for scroll linked animations. + *current_time = timeline_time + ? timeline_time.value() - + animation->startTime().value_or(NullValue()) + : NullValue(); } return Response::OK(); } @@ -246,8 +250,17 @@ return Response::Error("Failed to clone detached animation"); if (paused && !clone->Paused()) { // Ensure we restore a current time if the animation is limited. - double current_time = clone->TimelineInternal()->currentTime() - - clone->startTime().value_or(NullValue()); + double current_time = 0; + if (!clone->timeline()->IsActive()) { + current_time = clone->currentTime(); + } else { + base::Optional<double> timeline_time = clone->timeline()->CurrentTime(); + // TODO(crbug.com/916117): Handle NaN values. + current_time = timeline_time + ? timeline_time.value() - + clone->startTime().value_or(NullValue()) + : NullValue(); + } clone->pause(); clone->setCurrentTime(current_time, false); } else if (!paused && clone->Paused()) { @@ -497,14 +510,16 @@ double InspectorAnimationAgent::NormalizedStartTime( blink::Animation& animation) { double time_ms = animation.startTime().value_or(NullValue()); - if (ReferenceTimeline().PlaybackRate() == 0) { - time_ms += ReferenceTimeline().currentTime() - - animation.TimelineInternal()->currentTime(); - } else { - time_ms += (animation.TimelineInternal()->ZeroTime() - - ReferenceTimeline().ZeroTime()) - .InMillisecondsF() * - ReferenceTimeline().PlaybackRate(); + if (animation.timeline()->IsDocumentTimeline()) { + if (ReferenceTimeline().PlaybackRate() == 0) { + time_ms += ReferenceTimeline().currentTime() - + ToDocumentTimeline(animation.timeline())->currentTime(); + } else { + time_ms += (ToDocumentTimeline(animation.timeline())->ZeroTime() - + ReferenceTimeline().ZeroTime()) + .InMillisecondsF() * + ReferenceTimeline().PlaybackRate(); + } } // Round to the closest microsecond. return std::round(time_ms * 1000) / 1000;
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc index da68df4..46561b3 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -51,11 +51,6 @@ namespace { -void* AsyncId(uint64_t identifier) { - // This value should be odd to avoid collisions with regular pointers. - return reinterpret_cast<void*>((identifier << 1) | 1); -} - std::unique_ptr<TracedValue> InspectorParseHtmlBeginData(Document* document, unsigned start_line) { auto value = std::make_unique<TracedValue>(); @@ -150,8 +145,6 @@ TRACE_EVENT_SCOPE_THREAD, "data", inspector_receive_data_event::Data( loader, identifier, frame, encoded_data_length)); - probe::AsyncTask async_task(frame ? frame->GetDocument() : nullptr, - AsyncId(identifier), "data"); } void InspectorTraceEvents::DidFinishLoading(uint64_t identifier, @@ -160,14 +153,11 @@ int64_t encoded_data_length, int64_t decoded_body_length, bool should_report_corb_blocking) { - LocalFrame* frame = loader ? loader->GetFrame() : nullptr; TRACE_EVENT_INSTANT1( "devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", inspector_resource_finish_event::Data(loader, identifier, finish_time, false, encoded_data_length, decoded_body_length)); - probe::AsyncTask async_task(frame ? frame->GetDocument() : nullptr, - AsyncId(identifier)); } void InspectorTraceEvents::DidFailLoading(uint64_t identifier,
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc index 10868d99..7dd44d87 100644 --- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc +++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc
@@ -60,7 +60,7 @@ void LayoutWorkletGlobalScopeProxy::FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h index 6e9c6be..ed8e228f0 100644 --- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h +++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h
@@ -34,7 +34,7 @@ // Implements WorkletGlobalScopeProxy. void FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/core/layout/jank_tracker.cc b/third_party/blink/renderer/core/layout/jank_tracker.cc index bda98ab..ce87508 100644 --- a/third_party/blink/renderer/core/layout/jank_tracker.cc +++ b/third_party/blink/renderer/core/layout/jank_tracker.cc
@@ -231,12 +231,6 @@ if (!layout_object.FirstFragment().HasLocalBorderBoxProperties()) return; - // Convert to the local transform space, whose origin is the layer's previous - // location because the property trees haven't been updated yet. - FloatPoint transform_parent_offset = -old_layer_rect.Location(); - old_layer_rect.MoveBy(transform_parent_offset); - new_layer_rect.MoveBy(transform_parent_offset); - AccumulateJank(layout_object, PropertyTreeStateFor(layout_object), old_layer_rect, new_layer_rect); } @@ -389,6 +383,11 @@ observed_input_or_scroll_ = true; } +void JankTracker::NotifyViewportSizeChanged() { + // This cancels any previously scheduled task from the same timer. + timer_.StartOneShot(kTimerDelay, FROM_HERE); +} + bool JankTracker::IsActive() { // This eliminates noise from the private Page object created by // SVGImage::DataChanged.
diff --git a/third_party/blink/renderer/core/layout/jank_tracker.h b/third_party/blink/renderer/core/layout/jank_tracker.h index 385698b..678f0a6 100644 --- a/third_party/blink/renderer/core/layout/jank_tracker.h +++ b/third_party/blink/renderer/core/layout/jank_tracker.h
@@ -33,12 +33,14 @@ const PropertyTreeState& property_tree_state, const IntRect& old_visual_rect, const IntRect& new_visual_rect); + // Layer rects are relative to old layer position. void NotifyCompositedLayerMoved(const LayoutObject& object, FloatRect old_layer_rect, FloatRect new_layer_rect); void NotifyPrePaintFinished(); void NotifyInput(const WebInputEvent&); void NotifyScroll(ScrollType); + void NotifyViewportSizeChanged(); bool IsActive(); double Score() const { return score_; } double ScoreWithMoveDistance() const { return score_with_move_distance_; }
diff --git a/third_party/blink/renderer/core/layout/jank_tracker_test.cc b/third_party/blink/renderer/core/layout/jank_tracker_test.cc index b31c65c..a43e243 100644 --- a/third_party/blink/renderer/core/layout/jank_tracker_test.cc +++ b/third_party/blink/renderer/core/layout/jank_tracker_test.cc
@@ -447,6 +447,41 @@ EXPECT_FLOAT_EQ(0.15, jank_tracker.WeightedScore()); } +TEST_F(JankTrackerSimTest, ViewportSizeChange) { + WebView().MainFrameWidget()->Resize(WebSize(800, 600)); + + SimRequest main_resource("https://example.com/", "text/html"); + LoadURL("https://example.com/"); + main_resource.Complete(R"HTML( + <style> + body { margin: 0; } + .square { + display: inline-block; + position: relative; + width: 300px; + height: 300px; + background:yellow; + } + </style> + <div class='square'></div> + <div class='square'></div> + )HTML"); + + Compositor().BeginFrame(); + test::RunPendingTasks(); + + // Resize the viewport, making it 400px wide. This should cause the second div + // to change position during block layout flow. Since it was the result of a + // viewport size change, this position change should not affect the score. + WebView().MainFrameWidget()->Resize(WebSize(400, 600)); + + Compositor().BeginFrame(); + test::RunPendingTasks(); + + JankTracker& jank_tracker = MainFrame().GetFrameView()->GetJankTracker(); + EXPECT_FLOAT_EQ(0.0, jank_tracker.Score()); +} + TEST_F(JankTrackerTest, StableCompositingChanges) { SetBodyInnerHTML(R"HTML( <style> @@ -498,4 +533,67 @@ EXPECT_FLOAT_EQ(0, GetJankTracker().Score()); } +TEST_F(JankTrackerTest, CompositedOverflowExpansion) { + SetBodyInnerHTML(R"HTML( + <style> + + html { will-change: transform; } + body { height: 2000px; margin: 0; } + #drop { + position: absolute; + width: 1px; + height: 1px; + left: -10000px; + top: -1000px; + } + .pl { + position: relative; + background: #ddd; + z-index: 0; + width: 290px; + height: 170px; + left: 25px; + top: 25px; + } + #comp { + position: relative; + width: 240px; + height: 120px; + background: #efe; + will-change: transform; + z-index: 0; + left: 25px; + top: 25px; + } + .sh { + top: 515px !important; + } + + </style> + <div class="pl"> + <div id="comp"></div> + </div> + <div id="drop" style="display: none"></div> + )HTML"); + + Element* drop = GetDocument().getElementById("drop"); + drop->removeAttribute(html_names::kStyleAttr); + UpdateAllLifecyclePhases(); + + drop->setAttribute(html_names::kStyleAttr, AtomicString("display: none")); + UpdateAllLifecyclePhases(); + + EXPECT_FLOAT_EQ(0, GetJankTracker().Score()); + + Element* comp = GetDocument().getElementById("comp"); + comp->setAttribute(html_names::kClassAttr, AtomicString("sh")); + drop->removeAttribute(html_names::kStyleAttr); + UpdateAllLifecyclePhases(); + + // old rect (240 * 120) / (800 * 600) = 0.06 + // new rect, 50% clipped by viewport (240 * 60) / (800 * 600) = 0.03 + // final score 0.06 + 0.03 = 0.09 + EXPECT_FLOAT_EQ(0.09, GetJankTracker().Score()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.h b/third_party/blink/renderer/core/layout/layout_replaced.h index 979a86e0c..a945fcf3 100644 --- a/third_party/blink/renderer/core/layout/layout_replaced.h +++ b/third_party/blink/renderer/core/layout/layout_replaced.h
@@ -99,6 +99,13 @@ // intrinsic size in LayoutNG. virtual void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const; + // This callback is invoked whenever the intrinsic size changed. + // + // The intrinsic size can change due to the network (from the default + // intrinsic size [see above] to the actual intrinsic size) or to some + // CSS properties like 'zoom' or 'image-orientation'. + virtual void IntrinsicSizeChanged(); + protected: void WillBeDestroyed() override; @@ -132,13 +139,6 @@ intrinsic_size_ = intrinsic_size; } - // This callback is invoked whenever the intrinsic size changed. - // - // The intrinsic size can change due to the network (from the default - // intrinsic size [see above] to the actual intrinsic size) or to some - // CSS properties like 'zoom' or 'image-orientation'. - virtual void IntrinsicSizeChanged(); - PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override; bool IsOfType(LayoutObjectType type) const override {
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h index 39252729..142c04c 100644 --- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h +++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
@@ -107,9 +107,7 @@ if (!other.derived_geometry_) return; - track_shape_exclusions_ = other.track_shape_exclusions_; - derived_geometry_ = std::move(other.derived_geometry_); - other.derived_geometry_ = nullptr; + MoveDerivedGeometry(other); // Iterate through all the exclusions which were added by the layout, and // update the DerivedGeometry. @@ -128,6 +126,16 @@ } } + // See |NGExclusionSpace::MoveDerivedGeometry|. + void MoveDerivedGeometry(const NGExclusionSpaceInternal& other) { + if (!other.derived_geometry_) + return; + + track_shape_exclusions_ = other.track_shape_exclusions_; + derived_geometry_ = std::move(other.derived_geometry_); + other.derived_geometry_ = nullptr; + } + // See |NGExclusionSpace::MergeExclusionSpaces|. void MergeExclusionSpaces(const NGBfcDelta& offset_delta, const NGExclusionSpaceInternal& previous_output, @@ -479,7 +487,7 @@ exclusion_space_->PreInitialize(*other.exclusion_space_); } - // Shifts the DerivedGeometry data-structure to this exclusion space, and + // Shifts the |DerivedGeometry| data-structure to this exclusion space, and // adds any new exclusions. void MoveAndUpdateDerivedGeometry(const NGExclusionSpace& other) const { if (!exclusion_space_ || !other.exclusion_space_) @@ -488,6 +496,15 @@ exclusion_space_->MoveAndUpdateDerivedGeometry(*other.exclusion_space_); } + // Shifts the |DerivedGeometry| data-structure to this exclusion space. + void MoveDerivedGeometry(const NGExclusionSpace& other) const { + DCHECK(*this == other); + if (!exclusion_space_ || !other.exclusion_space_) + return; + + exclusion_space_->MoveDerivedGeometry(*other.exclusion_space_); + } + // This produces a new exclusion space for a |NGLayoutResult| which is being // re-used for caching purposes. //
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc index 13d2b5d6..2756019 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
@@ -19,6 +19,7 @@ child_break_tokens_.Shrink(0); inline_break_tokens_.Shrink(0); oof_positioned_candidates_.Shrink(0); + unpositioned_list_marker_ = NGUnpositionedListMarker(); size_.inline_size = LayoutUnit(); metrics_ = NGLineHeightMetrics();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc index 184634a4..cd48916 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -131,22 +131,24 @@ return builder.ToTextFragment(); } -bool IsStickyImage(const NGInlineItem& candidate, - const NGInlineItemResults& item_results, - NGLineBreaker::WhitespaceState trailing_whitespace, - const String& text) { - if (!IsImage(candidate)) - return false; +void PreventBreakBeforeStickyImage( + NGLineBreaker::WhitespaceState trailing_whitespace, + const String& text, + NGLineInfo* line_info) { if (trailing_whitespace != NGLineBreaker::WhitespaceState::kNone && trailing_whitespace != NGLineBreaker::WhitespaceState::kUnknown) - return false; + return; - if (item_results.size() >= 1) { - // If this image follows a <wbr> the image isn't sticky. - const auto& last = item_results[item_results.size() - 1]; - return text[last.start_offset] != kZeroWidthSpaceCharacter; - } - return true; + NGInlineItemResults* results = line_info->MutableResults(); + if (results->IsEmpty()) + return; + + // If this image follows a <wbr> the image isn't sticky. + NGInlineItemResult* last = &results->back(); + if (text[last->start_offset] == kZeroWidthSpaceCharacter) + return; + + last->can_break_after = false; } inline void ClearNeedsLayout(const NGInlineItem& item) { @@ -405,6 +407,13 @@ #endif continue; } + if (item.Type() == NGInlineItem::kAtomicInline) { + if (HandleAtomicInline(item, percentage_resolution_block_size_for_min_max, + line_info)) { + continue; + } + return; + } if (item.Type() == NGInlineItem::kCloseTag) { HandleCloseTag(item, line_info); continue; @@ -426,24 +435,11 @@ // opportunity if we're trailing. if (state_ == LineBreakState::kTrailing && CanBreakAfterLast(item_results)) { - // If the sticky images quirk is enabled, and this is an image that - // follows text that doesn't end with something breakable, we cannot break - // between the two items. - if (sticky_images_quirk_ && - IsStickyImage(item, item_results, trailing_whitespace_, Text())) { - HandleAtomicInline(item, percentage_resolution_block_size_for_min_max, - line_info); - continue; - } - line_info->SetIsLastLine(false); return; } - if (item.Type() == NGInlineItem::kAtomicInline) { - HandleAtomicInline(item, percentage_resolution_block_size_for_min_max, - line_info); - } else if (item.Type() == NGInlineItem::kOpenTag) { + if (item.Type() == NGInlineItem::kOpenTag) { HandleOpenTag(item, line_info); } else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) { AddItem(item, line_info); @@ -1089,10 +1085,12 @@ // Ignore carriage return and form feed. // https://drafts.csswg.org/css-text-3/#white-space-processing // https://github.com/w3c/csswg-drafts/issues/855 - break; + HandleEmptyText(item, line_info); + return; default: NOTREACHED(); - break; + HandleEmptyText(item, line_info); + return; } MoveToNextOf(item); } @@ -1131,13 +1129,30 @@ MoveToNextOf(item); } -void NGLineBreaker::HandleAtomicInline( +bool NGLineBreaker::HandleAtomicInline( const NGInlineItem& item, LayoutUnit percentage_resolution_block_size_for_min_max, NGLineInfo* line_info) { DCHECK_EQ(item.Type(), NGInlineItem::kAtomicInline); DCHECK(item.Style()); const ComputedStyle& style = *item.Style(); + const NGInlineItemResults& item_results = line_info->Results(); + + // If the sticky images quirk is enabled, and this is an image that + // follows text that doesn't end with something breakable, we cannot break + // between the two items. + bool is_sticky_image = sticky_images_quirk_ && IsImage(item); + if (UNLIKELY(is_sticky_image)) { + PreventBreakBeforeStickyImage(trailing_whitespace_, Text(), line_info); + } + + // Atomic inline is handled as if it is trailable, because it can prevent + // break-before. Check if the line should break before this item, after the + // last item's |can_break_after| is finalized for the quirk above. + if (state_ == LineBreakState::kTrailing && CanBreakAfterLast(item_results)) { + line_info->SetIsLastLine(false); + return false; + } NGInlineItemResult* item_result = AddItem(item, line_info); item_result->should_create_line_box = true; @@ -1187,7 +1202,7 @@ position_ += item_result->inline_size; ComputeCanBreakAfter(item_result, auto_wrap_, break_iterator_); - if (sticky_images_quirk_ && IsImage(item)) { + if (UNLIKELY(is_sticky_image)) { const auto& items = Items(); if (item_index_ + 1 < items.size()) { DCHECK_EQ(&item, &items[item_index_]); @@ -1200,6 +1215,7 @@ } } MoveToNextOf(item); + return true; } // Performs layout and positions a float.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h index 33715a5f..9cfae3f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -156,7 +156,7 @@ void HandleControlItem(const NGInlineItem&, NGLineInfo*); void HandleBidiControlItem(const NGInlineItem&, NGLineInfo*); - void HandleAtomicInline( + bool HandleAtomicInline( const NGInlineItem&, LayoutUnit percentage_resolution_block_size_for_min_max, NGLineInfo*);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc index 778bb89..df93ec37 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -22,8 +22,8 @@ NGInlineNode CreateInlineNode(const String& html_content) { SetBodyInnerHTML(html_content); - LayoutNGBlockFlow* block_flow = - ToLayoutNGBlockFlow(GetLayoutObjectByElementId("container")); + LayoutBlockFlow* block_flow = + To<LayoutBlockFlow>(GetLayoutObjectByElementId("container")); return NGInlineNode(block_flow); } @@ -523,6 +523,29 @@ EXPECT_EQ(size.max_size, LayoutUnit(110)); } +TEST_F(NGLineBreakerTest, TableCellWidthCalculationQuirkOutOfFlow) { + NGInlineNode node = CreateInlineNode(R"HTML( + <style> + table { + font-size: 10px; + width: 5ch; + } + </style> + <table><tr><td id=container> + 1234567 + <img style="position: absolute"> + </td></tr></table> + )HTML"); + // |SetBodyInnerHTML| doesn't set compatibility mode. + GetDocument().SetCompatibilityMode(Document::kQuirksMode); + EXPECT_TRUE(node.GetDocument().InQuirksMode()); + + node.ComputeMinMaxSize( + WritingMode::kHorizontalTb, + MinMaxSizeInput(/* percentage_resolution_block_size */ LayoutUnit())); + // Pass if |ComputeMinMaxSize| doesn't hit DCHECK failures. +} + #undef MAYBE_OverflowAtomicInline } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index 3a7bc24c..9fd60d2 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -2358,32 +2358,33 @@ LayoutUnit NGBlockLayoutAlgorithm::CalculateMinimumBlockSize( const NGMarginStrut& end_margin_strut) { - if (!Node().GetDocument().InQuirksMode()) + if (!Node().IsQuirkyAndFillsViewport()) return kIndefiniteSize; - if (Node().IsDocumentElement() && Node().Style().LogicalHeight().IsAuto()) { - return ConstraintSpace().AvailableSize().block_size - - ComputeMarginsForSelf(ConstraintSpace(), Style()).BlockSum(); - } - if (Node().IsBody() && Node().Style().LogicalHeight().IsAuto()) { - LayoutUnit body_block_end_margin = - ComputeMarginsForSelf(ConstraintSpace(), Style()).block_end; - LayoutUnit margin_sum; + if (!Style().LogicalHeight().IsAuto()) + return kIndefiniteSize; + + NGBoxStrut margins = ComputeMarginsForSelf(ConstraintSpace(), Style()); + LayoutUnit margin_sum; + if (Node().CreatesNewFormattingContext()) { + margin_sum = margins.BlockSum(); + } else { + DCHECK(Node().IsBody()); if (container_builder_.BfcBlockOffset()) { NGMarginStrut body_strut = end_margin_strut; - body_strut.Append(body_block_end_margin, /* is_quirky */ false); + body_strut.Append(margins.block_end, Style().HasMarginAfterQuirk()); margin_sum = *container_builder_.BfcBlockOffset() - ConstraintSpace().BfcOffset().block_offset + body_strut.Sum(); } else { - // end_margin_strut is top margin when we have no BfcOffset. - margin_sum = end_margin_strut.Sum() + body_block_end_margin; + // The |end_margin_strut| is the block-start margin if the body doesn't + // have a BFC block-offset. + margin_sum = end_margin_strut.Sum() + margins.block_end; } - LayoutUnit minimum_block_size = - ConstraintSpace().AvailableSize().block_size - margin_sum; - return minimum_block_size.ClampNegativeToZero(); } - return kIndefiniteSize; + + return (ConstraintSpace().AvailableSize().block_size - margin_sum) + .ClampNegativeToZero(); } void NGBlockLayoutAlgorithm::PositionOrPropagateListMarker(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index 4f39574b..9e015da 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -1039,11 +1039,10 @@ constraint_space.PercentageResolutionSize() != old_space.PercentageResolutionSize(); if (needs_cached_result_update) { - scoped_refptr<const NGLayoutResult> new_result = - base::AdoptRef(new NGLayoutResult(*layout_result, constraint_space, - layout_result->BfcLineOffset(), - layout_result->BfcBlockOffset())); - box_->SetCachedLayoutResult(*new_result, /* break_token */ nullptr); + layout_result = base::AdoptRef(new NGLayoutResult( + *layout_result, constraint_space, layout_result->BfcLineOffset(), + layout_result->BfcBlockOffset())); + box_->SetCachedLayoutResult(*layout_result, /* break_token */ nullptr); } }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/third_party/blink/renderer/core/layout/ng/ng_block_node.h index 89b39fa7..06999d98 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -92,6 +92,23 @@ bool IsInlineLevel() const; bool IsAtomicInlineLevel() const; + // Returns true if this node should fill the viewport. + // This occurs when we are in quirks-mode and we are *not* OOF-positioned, + // floating, or inline-level. + // + // https://quirks.spec.whatwg.org/#the-body-element-fills-the-html-element-quirk + bool IsQuirkyAndFillsViewport() const { + if (!GetDocument().InQuirksMode()) + return false; + if (IsOutOfFlowPositioned()) + return false; + if (IsFloating()) + return false; + if (IsAtomicInlineLevel()) + return false; + return (IsDocumentElement() || IsBody()); + } + // CSS defines certain cases to synthesize inline block baselines from box. // See comments in UseLogicalBottomMarginEdgeForInlineBlockBaseline(). bool UseLogicalBottomMarginEdgeForInlineBlockBaseline() const;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc index c3c57444..ad673637 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc
@@ -30,6 +30,7 @@ LogicalSize percentage_resolution_size) { #if DCHECK_IS_ON() DCHECK(is_available_size_set_); + is_percentage_resolution_size_set_ = true; #endif if (LIKELY(is_in_parallel_flow_)) { space_.bitfields_.percentage_inline_storage = @@ -76,6 +77,7 @@ LogicalSize replaced_percentage_resolution_size) { #if DCHECK_IS_ON() DCHECK(is_available_size_set_); + DCHECK(is_percentage_resolution_size_set_); #endif if (LIKELY(is_in_parallel_flow_)) { // We don't store the replaced percentage resolution inline size, so we need @@ -92,20 +94,21 @@ replaced_percentage_resolution_size.block_size; } } else { - AdjustInlineSizeIfNeeded(&replaced_percentage_resolution_size.block_size); - - // We don't store the replaced percentage resolution inline size, so we need - // it to be the same as the regular percentage resolution inline size. - DCHECK_EQ(replaced_percentage_resolution_size.block_size, - space_.PercentageResolutionInlineSize()); + // There should be no need to handle quirky percentage block-size resolution + // if this is an orthogonal writing mode root. The quirky percentage + // block-size resolution size that may have been calculated on an ancestor + // will be used to resolve inline-sizes of the child, and will therefore now + // be lost (since we don't store the quirky replaced percentage resolution + // *inline* size, only the *block* size). Just copy whatever was set as a + // regular percentage resolution block-size. + LayoutUnit block_size = space_.PercentageResolutionBlockSize(); space_.bitfields_.replaced_percentage_block_storage = - GetPercentageStorage(replaced_percentage_resolution_size.inline_size, - space_.available_size_.block_size); + GetPercentageStorage(block_size, space_.available_size_.block_size); if (space_.bitfields_.replaced_percentage_block_storage == kRareDataPercentage) { space_.EnsureRareData()->replaced_percentage_resolution_block_size = - replaced_percentage_resolution_size.inline_size; + block_size; } }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h index 43e24f4..314ead57 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h
@@ -83,9 +83,22 @@ return *this; } + // Set percentage resolution size. Prior to calling this method, + // SetAvailableSize() must have been called, since we'll compare the input + // against the available size set, because if they are equal in either + // dimension, we won't have to store the values separately. NGConstraintSpaceBuilder& SetPercentageResolutionSize( LogicalSize percentage_resolution_size); + // Set percentage resolution size for replaced content (a special quirk inside + // tables). Only honored if the writing modes (container vs. child) are + // parallel. In orthogonal writing modes, we'll use whatever regular + // percentage resolution size is already set. Prior to calling this method, + // SetAvailableSize() must have been called, since we'll compare the input + // against the available size set, because if they are equal in either + // dimension, we won't have to store the values separately. Additionally, + // SetPercentageResolutionSize() must have been called, since we'll override + // with that value on orthogonal writing mode roots. NGConstraintSpaceBuilder& SetReplacedPercentageResolutionSize( LogicalSize replaced_percentage_resolution_size); @@ -313,6 +326,7 @@ #if DCHECK_IS_ON() bool is_available_size_set_ = false; + bool is_percentage_resolution_size_set_ = false; bool is_fragmentainer_block_size_set_ = false; bool is_fragmentainer_space_at_bfc_start_set_ = false; bool is_block_direction_fragmentation_type_set_ = false;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h index 0c1c0d4..51400846 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -132,14 +132,6 @@ (box_->IsBody() || box_->IsTableCell()); } - // In quirks mode, in-flow positioned BODY and root elements must completely - // fill the viewport. Return true if this is such a node. - bool IsQuirkyAndFillsViewport() const { - if (!GetDocument().InQuirksMode()) - return false; - return (IsDocumentElement() || IsBody()) && !Style().HasOutOfFlowPosition(); - } - bool CreatesNewFormattingContext() const { return IsBlock() && box_->CreatesNewFormattingContext(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc index f2d5ddb..2049c34 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
@@ -15,19 +15,41 @@ namespace blink { +namespace { + +struct SameSizeAsNGLayoutResult : public RefCounted<SameSizeAsNGLayoutResult> { + const NGConstraintSpace space; + void* physical_fragment; + union { + NGBfcOffset bfc_offset; + LogicalOffset oof_positioned_offset; + void* rare_data; + }; + LayoutUnit intrinsic_block_size; + unsigned bitfields[1]; +}; + +static_assert(sizeof(NGLayoutResult) == sizeof(SameSizeAsNGLayoutResult), + "NGLayoutResult should stay small."); + +} // namespace + NGLayoutResult::NGLayoutResult( scoped_refptr<const NGPhysicalContainerFragment> physical_fragment, NGBoxFragmentBuilder* builder) : NGLayoutResult(std::move(physical_fragment), builder, /* cache_space */ true) { - is_initial_block_size_indefinite_ = + bitfields_.is_initial_block_size_indefinite = builder->is_initial_block_size_indefinite_; intrinsic_block_size_ = builder->intrinsic_block_size_; - minimal_space_shortage_ = builder->minimal_space_shortage_; - initial_break_before_ = builder->initial_break_before_; - final_break_after_ = builder->previous_break_after_; - has_forced_break_ = builder->has_forced_break_; + if (builder->minimal_space_shortage_ != LayoutUnit::Max()) + EnsureRareData()->minimal_space_shortage = builder->minimal_space_shortage_; + bitfields_.initial_break_before = + static_cast<unsigned>(builder->initial_break_before_); + bitfields_.final_break_after = + static_cast<unsigned>(builder->previous_break_after_); + bitfields_.has_forced_break = builder->has_forced_break_; } NGLayoutResult::NGLayoutResult( @@ -42,9 +64,7 @@ : NGLayoutResult(/* physical_fragment */ nullptr, builder, /* cache_space */ false) { - adjoining_floats_ = kFloatTypeNone; - has_descendant_that_depends_on_percentage_block_size_ = false; - status_ = status; + bitfields_.status = status; DCHECK_NE(status, kSuccess) << "Use the other constructor for successful layout"; } @@ -55,53 +75,50 @@ base::Optional<LayoutUnit> bfc_block_offset) : space_(new_space), physical_fragment_(other.physical_fragment_), - unpositioned_list_marker_(other.unpositioned_list_marker_), - exclusion_space_(MergeExclusionSpaces(other, - space_.ExclusionSpace(), - bfc_line_offset, - bfc_block_offset)), - bfc_line_offset_(bfc_line_offset), - bfc_block_offset_(bfc_block_offset), - end_margin_strut_(other.end_margin_strut_), intrinsic_block_size_(other.intrinsic_block_size_), - minimal_space_shortage_(other.minimal_space_shortage_), - initial_break_before_(other.initial_break_before_), - final_break_after_(other.final_break_after_), - has_valid_space_(other.has_valid_space_), - has_forced_break_(other.has_forced_break_), - is_self_collapsing_(other.is_self_collapsing_), - is_pushed_by_floats_(other.is_pushed_by_floats_), - adjoining_floats_(other.adjoining_floats_), - is_initial_block_size_indefinite_( - other.is_initial_block_size_indefinite_), - has_descendant_that_depends_on_percentage_block_size_( - other.has_descendant_that_depends_on_percentage_block_size_), - status_(other.status_) {} + bitfields_(other.bitfields_) { + if (HasRareData()) { + rare_data_ = new RareData(*other.rare_data_); + rare_data_->bfc_line_offset = bfc_line_offset; + rare_data_->bfc_block_offset = bfc_block_offset; + } else if (!bitfields_.has_oof_positioned_offset) { + bfc_offset_.line_offset = bfc_line_offset; + bfc_offset_.block_offset = bfc_block_offset.value_or(LayoutUnit()); + bitfields_.is_bfc_block_offset_nullopt = !bfc_block_offset.has_value(); + } else { + DCHECK(physical_fragment_->IsOutOfFlowPositioned()); + DCHECK_EQ(bfc_line_offset, LayoutUnit()); + DCHECK(bfc_block_offset && bfc_block_offset.value() == LayoutUnit()); + oof_positioned_offset_ = LogicalOffset(); + } + + NGExclusionSpace new_exclusion_space = MergeExclusionSpaces( + other, space_.ExclusionSpace(), bfc_line_offset, bfc_block_offset); + + if (new_exclusion_space != space_.ExclusionSpace()) { + bitfields_.has_rare_data_exclusion_space = true; + EnsureRareData()->exclusion_space = std::move(new_exclusion_space); + } else { + space_.ExclusionSpace().MoveDerivedGeometry(new_exclusion_space); + } +} NGLayoutResult::NGLayoutResult( scoped_refptr<const NGPhysicalContainerFragment> physical_fragment, NGContainerFragmentBuilder* builder, bool cache_space) - : space_(cache_space && builder->space_ - ? NGConstraintSpace(*builder->space_) - : NGConstraintSpace()), + : space_(builder->space_ ? NGConstraintSpace(*builder->space_) + : NGConstraintSpace()), physical_fragment_(std::move(physical_fragment)), - unpositioned_list_marker_(builder->unpositioned_list_marker_), - exclusion_space_(std::move(builder->exclusion_space_)), - bfc_line_offset_(builder->bfc_line_offset_), - bfc_block_offset_(builder->bfc_block_offset_), - end_margin_strut_(builder->end_margin_strut_), - has_valid_space_(cache_space && builder->space_), - has_forced_break_(false), - is_self_collapsing_(builder->is_self_collapsing_), - is_pushed_by_floats_(builder->is_pushed_by_floats_), - adjoining_floats_(builder->adjoining_floats_), - is_initial_block_size_indefinite_(false), - has_descendant_that_depends_on_percentage_block_size_( - builder->has_descendant_that_depends_on_percentage_block_size_), - status_(kSuccess) { + bitfields_( + /* has_valid_space */ cache_space && builder->space_, + /* is_self_collapsing */ builder->is_self_collapsing_, + /* is_pushed_by_floats */ builder->is_pushed_by_floats_, + /* adjoining_floats */ builder->adjoining_floats_, + /* has_descendant_that_depends_on_percentage_block_size */ + builder->has_descendant_that_depends_on_percentage_block_size_) { #if DCHECK_IS_ON() - if (is_self_collapsing_ && physical_fragment_) { + if (bitfields_.is_self_collapsing && physical_fragment_) { // A new formatting-context shouldn't be self-collapsing. DCHECK(!physical_fragment_->IsBlockFormattingContextRoot()); @@ -111,11 +128,36 @@ DCHECK_EQ(LayoutUnit(), fragment.BlockSize()); } #endif + + if (builder->end_margin_strut_ != NGMarginStrut()) + EnsureRareData()->end_margin_strut = builder->end_margin_strut_; + if (builder->unpositioned_list_marker_) { + EnsureRareData()->unpositioned_list_marker = + builder->unpositioned_list_marker_; + } + if (builder->exclusion_space_ != space_.ExclusionSpace()) { + bitfields_.has_rare_data_exclusion_space = true; + EnsureRareData()->exclusion_space = std::move(builder->exclusion_space_); + } else { + space_.ExclusionSpace().MoveDerivedGeometry(builder->exclusion_space_); + } + + if (HasRareData()) { + rare_data_->bfc_line_offset = builder->bfc_line_offset_; + rare_data_->bfc_block_offset = builder->bfc_block_offset_; + } else { + bfc_offset_.line_offset = builder->bfc_line_offset_; + bfc_offset_.block_offset = + builder->bfc_block_offset_.value_or(LayoutUnit()); + bitfields_.is_bfc_block_offset_nullopt = + !builder->bfc_block_offset_.has_value(); + } } -// Define the destructor here, so that we can forward-declare more in the -// header. -NGLayoutResult::~NGLayoutResult() = default; +NGLayoutResult::~NGLayoutResult() { + if (HasRareData()) + delete rare_data_; +} NGExclusionSpace NGLayoutResult::MergeExclusionSpaces( const NGLayoutResult& other, @@ -127,19 +169,31 @@ // value, and the result which we are copying doesn't (or visa versa). // This would imply the result has switched its "empty" state for margin // collapsing, which would mean it isn't possible to reuse the result. - DCHECK_EQ(bfc_block_offset.has_value(), other.bfc_block_offset_.has_value()); + DCHECK_EQ(bfc_block_offset.has_value(), other.BfcBlockOffset().has_value()); - NGBfcDelta offset_delta = {bfc_line_offset - other.bfc_line_offset_, - bfc_block_offset && other.bfc_block_offset_ - ? *bfc_block_offset - *other.bfc_block_offset_ + NGBfcDelta offset_delta = {bfc_line_offset - other.BfcLineOffset(), + bfc_block_offset && other.BfcBlockOffset() + ? *bfc_block_offset - *other.BfcBlockOffset() : LayoutUnit()}; return NGExclusionSpace::MergeExclusionSpaces( - /* old_output */ other.exclusion_space_, + /* old_output */ other.ExclusionSpace(), /* old_input */ other.space_.ExclusionSpace(), /* new_input */ new_input_exclusion_space, offset_delta); } +NGLayoutResult::RareData* NGLayoutResult::EnsureRareData() { + if (!HasRareData()) { + base::Optional<LayoutUnit> bfc_block_offset; + if (!bitfields_.is_bfc_block_offset_nullopt) + bfc_block_offset = bfc_offset_.block_offset; + rare_data_ = new RareData(bfc_offset_.line_offset, bfc_block_offset); + bitfields_.has_rare_data = true; + } + + return rare_data_; +} + #if DCHECK_IS_ON() void NGLayoutResult::CheckSameForSimplifiedLayout( const NGLayoutResult& other, @@ -149,34 +203,37 @@ To<NGPhysicalBoxFragment>(*other.physical_fragment_), check_same_block_size); - DCHECK(unpositioned_list_marker_ == other.unpositioned_list_marker_); - exclusion_space_.CheckSameForSimplifiedLayout(other.exclusion_space_); + DCHECK(UnpositionedListMarker() == other.UnpositionedListMarker()); + ExclusionSpace().CheckSameForSimplifiedLayout(other.ExclusionSpace()); - // We ignore bfc_block_offset_, and bfc_line_offset_ as "simplified" layout + // We ignore |BfcBlockOffset|, and |BfcLineOffset| as "simplified" layout // will move the layout result if required. - // We ignore the intrinsic_block_size_ as if a scrollbar gets added/removed + // We ignore the |intrinsic_block_size_| as if a scrollbar gets added/removed // this may change (even if the size of the fragment remains the same). - DCHECK(end_margin_strut_ == other.end_margin_strut_); - DCHECK_EQ(minimal_space_shortage_, other.minimal_space_shortage_); + DCHECK(EndMarginStrut() == other.EndMarginStrut()); + DCHECK_EQ(MinimalSpaceShortage(), other.MinimalSpaceShortage()); - DCHECK_EQ(initial_break_before_, other.initial_break_before_); - DCHECK_EQ(final_break_after_, other.final_break_after_); + DCHECK_EQ(bitfields_.has_valid_space, other.bitfields_.has_valid_space); + DCHECK_EQ(bitfields_.has_forced_break, other.bitfields_.has_forced_break); + DCHECK_EQ(bitfields_.is_self_collapsing, other.bitfields_.is_self_collapsing); + DCHECK_EQ(bitfields_.is_pushed_by_floats, + other.bitfields_.is_pushed_by_floats); + DCHECK_EQ(bitfields_.adjoining_floats, other.bitfields_.adjoining_floats); - DCHECK_EQ(has_valid_space_, other.has_valid_space_); - DCHECK_EQ(has_forced_break_, other.has_forced_break_); - DCHECK_EQ(is_self_collapsing_, other.is_self_collapsing_); - DCHECK_EQ(is_pushed_by_floats_, other.is_pushed_by_floats_); - DCHECK_EQ(adjoining_floats_, other.adjoining_floats_); + DCHECK_EQ(bitfields_.initial_break_before, + other.bitfields_.initial_break_before); + DCHECK_EQ(bitfields_.final_break_after, other.bitfields_.final_break_after); if (check_same_block_size) { - DCHECK_EQ(is_initial_block_size_indefinite_, - other.is_initial_block_size_indefinite_); + DCHECK_EQ(bitfields_.is_initial_block_size_indefinite, + other.bitfields_.is_initial_block_size_indefinite); } - DCHECK_EQ(has_descendant_that_depends_on_percentage_block_size_, - other.has_descendant_that_depends_on_percentage_block_size_); - DCHECK_EQ(status_, other.status_); + DCHECK_EQ( + bitfields_.has_descendant_that_depends_on_percentage_block_size, + other.bitfields_.has_descendant_that_depends_on_percentage_block_size); + DCHECK_EQ(bitfields_.status, other.bitfields_.status); } #endif
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h index 20e8aa7..9416d55f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
@@ -36,8 +36,8 @@ enum NGLayoutResultStatus { kSuccess = 0, kBfcBlockOffsetResolved = 1, - // When adding new values, make sure the bit size of |status_| is large - // enough to store. + // When adding new values, make sure the bit size of |Bitfields::status| is + // large enough to store. }; // Create a copy of NGLayoutResult with |BfcBlockOffset| replaced by the given @@ -56,25 +56,59 @@ } LogicalOffset OutOfFlowPositionedOffset() const { - return oof_positioned_offset_; + DCHECK(bitfields_.has_oof_positioned_offset); + return HasRareData() ? rare_data_->oof_positioned_offset + : oof_positioned_offset_; } - const NGUnpositionedListMarker& UnpositionedListMarker() const { - return unpositioned_list_marker_; + const NGUnpositionedListMarker UnpositionedListMarker() const { + return HasRareData() ? rare_data_->unpositioned_list_marker + : NGUnpositionedListMarker(); } - const NGExclusionSpace& ExclusionSpace() const { return exclusion_space_; } + const NGExclusionSpace& ExclusionSpace() const { + if (bitfields_.has_rare_data_exclusion_space) { + DCHECK(HasRareData()); + return rare_data_->exclusion_space; + } + + return space_.ExclusionSpace(); + } NGLayoutResultStatus Status() const { - return static_cast<NGLayoutResultStatus>(status_); + return static_cast<NGLayoutResultStatus>(bitfields_.status); } - LayoutUnit BfcLineOffset() const { return bfc_line_offset_; } - const base::Optional<LayoutUnit>& BfcBlockOffset() const { - return bfc_block_offset_; + LayoutUnit BfcLineOffset() const { + if (HasRareData()) + return rare_data_->bfc_line_offset; + + if (bitfields_.has_oof_positioned_offset) { + DCHECK(physical_fragment_->IsOutOfFlowPositioned()); + return LayoutUnit(); + } + + return bfc_offset_.line_offset; } - const NGMarginStrut EndMarginStrut() const { return end_margin_strut_; } + const base::Optional<LayoutUnit> BfcBlockOffset() const { + if (HasRareData()) + return rare_data_->bfc_block_offset; + + if (bitfields_.has_oof_positioned_offset) { + DCHECK(physical_fragment_->IsOutOfFlowPositioned()); + return LayoutUnit(); + } + + if (bitfields_.is_bfc_block_offset_nullopt) + return base::nullopt; + + return bfc_offset_.block_offset; + } + + const NGMarginStrut EndMarginStrut() const { + return HasRareData() ? rare_data_->end_margin_strut : NGMarginStrut(); + } const LayoutUnit IntrinsicBlockSize() const { DCHECK(physical_fragment_->Type() == NGPhysicalFragment::kFragmentBox || @@ -83,26 +117,33 @@ return intrinsic_block_size_; } - LayoutUnit MinimalSpaceShortage() const { return minimal_space_shortage_; } + LayoutUnit MinimalSpaceShortage() const { + return HasRareData() ? rare_data_->minimal_space_shortage + : LayoutUnit::Max(); + } // The break-before value on the first child needs to be propagated to the // container, in search of a valid class A break point. - EBreakBetween InitialBreakBefore() const { return initial_break_before_; } + EBreakBetween InitialBreakBefore() const { + return static_cast<EBreakBetween>(bitfields_.initial_break_before); + } // The break-after value on the last child needs to be propagated to the // container, in search of a valid class A break point. - EBreakBetween FinalBreakAfter() const { return final_break_after_; } + EBreakBetween FinalBreakAfter() const { + return static_cast<EBreakBetween>(bitfields_.final_break_after); + } // Return true if the fragment broke because a forced break before a child. - bool HasForcedBreak() const { return has_forced_break_; } + bool HasForcedBreak() const { return bitfields_.has_forced_break; } // Returns true if the fragment should be considered empty for margin // collapsing purposes (e.g. margins "collapse through"). - bool IsSelfCollapsing() const { return is_self_collapsing_; } + bool IsSelfCollapsing() const { return bitfields_.is_self_collapsing; } // Return true if this fragment got its block offset increased by the presence // of floats. - bool IsPushedByFloats() const { return is_pushed_by_floats_; } + bool IsPushedByFloats() const { return bitfields_.is_pushed_by_floats; } // Return the types (none, left, right, both) of preceding adjoining // floats. These are floats that are added while the in-flow BFC block offset @@ -112,12 +153,14 @@ // block-start margin (in such cases we will know up front that the block will // need clearance, since, if it doesn't, the float will be pulled along with // the block, and the block will fail to clear). - NGFloatTypes AdjoiningFloatTypes() const { return adjoining_floats_; } + NGFloatTypes AdjoiningFloatTypes() const { + return bitfields_.adjoining_floats; + } // Returns true if the initial (pre-layout) block-size of this fragment was // indefinite. (e.g. it has "height: auto"). bool IsInitialBlockSizeIndefinite() const { - return is_initial_block_size_indefinite_; + return bitfields_.is_initial_block_size_indefinite; } // Returns true if there is a descendant that depends on percentage @@ -126,15 +169,17 @@ // percentage sizing behaviour (typically when their parent layout forces a // block-size on them). bool HasDescendantThatDependsOnPercentageBlockSize() const { - return has_descendant_that_depends_on_percentage_block_size_; + return bitfields_.has_descendant_that_depends_on_percentage_block_size; } // Returns true if the space stored with this layout result, is valid. - bool HasValidConstraintSpaceForCaching() const { return has_valid_space_; } + bool HasValidConstraintSpaceForCaching() const { + return bitfields_.has_valid_space; + } // Returns the space which generated this object for caching purposes. const NGConstraintSpace& GetConstraintSpaceForCaching() const { - DCHECK(has_valid_space_); + DCHECK(bitfields_.has_valid_space); return space_; } @@ -147,7 +192,17 @@ friend class NGOutOfFlowLayoutPart; void SetOutOfFlowPositionedOffset(const LogicalOffset& offset) { - layout_result_->oof_positioned_offset_ = offset; + // OOF-positioned nodes *must* always have an initial BFC-offset. + DCHECK(layout_result_->physical_fragment_->IsOutOfFlowPositioned()); + DCHECK_EQ(layout_result_->BfcLineOffset(), LayoutUnit()); + DCHECK_EQ(layout_result_->BfcBlockOffset().value_or(LayoutUnit()), + LayoutUnit()); + + layout_result_->bitfields_.has_oof_positioned_offset = true; + if (layout_result_->HasRareData()) + layout_result_->rare_data_->oof_positioned_offset = offset; + else + layout_result_->oof_positioned_offset_ = offset; } private: @@ -183,9 +238,18 @@ // This constructor is for a non-success status. NGLayoutResult(NGLayoutResultStatus, NGBoxFragmentBuilder*); - // We don't need copy constructor today. Delete this to clarify that the - // default copy constructor will not work because RefCounted can't be copied. + // We don't need the copy constructor, move constructor, copy + // assigmnment-operator, or move assignment-operator today. + // Delete these to clarify that they will not work because a |RefCounted| + // object can't be copied directly. + // + // If at some point we do need these constructors particular care will need + // to be taken with the |rare_data_| field which is manually memory managed. NGLayoutResult(const NGLayoutResult&) = delete; + NGLayoutResult(NGLayoutResult&&) = delete; + NGLayoutResult& operator=(const NGLayoutResult& other) = delete; + NGLayoutResult& operator=(NGLayoutResult&& other) = delete; + NGLayoutResult() = delete; // Delegate constructor that sets up what it can, based on the builder. NGLayoutResult( @@ -199,40 +263,108 @@ LayoutUnit bfc_line_offset, base::Optional<LayoutUnit> bfc_block_offset); + struct RareData { + USING_FAST_MALLOC(RareData); + + public: + RareData(LayoutUnit bfc_line_offset, + base::Optional<LayoutUnit> bfc_block_offset) + : bfc_line_offset(bfc_line_offset), + bfc_block_offset(bfc_block_offset) {} + + LayoutUnit bfc_line_offset; + base::Optional<LayoutUnit> bfc_block_offset; + + LogicalOffset oof_positioned_offset; + NGMarginStrut end_margin_strut; + NGUnpositionedListMarker unpositioned_list_marker; + LayoutUnit minimal_space_shortage = LayoutUnit::Max(); + NGExclusionSpace exclusion_space; + }; + + bool HasRareData() const { return bitfields_.has_rare_data; } + RareData* EnsureRareData(); + + struct Bitfields { + DISALLOW_NEW(); + + public: + // We define the default constructor so that the |has_rare_data| bit is + // never uninitialized (potentially allowing a dangling pointer). + Bitfields() + : Bitfields(/* has_valid_space */ false, + /* is_self_collapsing */ false, + /* is_pushed_by_floats */ false, + /* adjoining_floats */ NGFloatTypeValue::kFloatTypeNone, + /* has_descendant_that_depends_on_percentage_block_size */ + false) {} + Bitfields(bool has_valid_space, + bool is_self_collapsing, + bool is_pushed_by_floats, + NGFloatTypes adjoining_floats, + bool has_descendant_that_depends_on_percentage_block_size) + : has_rare_data(false), + has_rare_data_exclusion_space(false), + has_oof_positioned_offset(false), + is_bfc_block_offset_nullopt(false), + has_valid_space(has_valid_space), + has_forced_break(false), + is_self_collapsing(is_self_collapsing), + is_pushed_by_floats(is_pushed_by_floats), + adjoining_floats(static_cast<unsigned>(adjoining_floats)), + is_initial_block_size_indefinite(false), + has_descendant_that_depends_on_percentage_block_size( + has_descendant_that_depends_on_percentage_block_size), + initial_break_before(static_cast<unsigned>(EBreakBetween::kAuto)), + final_break_after(static_cast<unsigned>(EBreakBetween::kAuto)), + status(static_cast<unsigned>(kSuccess)) {} + + unsigned has_rare_data : 1; + unsigned has_rare_data_exclusion_space : 1; + unsigned has_oof_positioned_offset : 1; + unsigned is_bfc_block_offset_nullopt : 1; + + unsigned has_valid_space : 1; + unsigned has_forced_break : 1; + + unsigned is_self_collapsing : 1; + unsigned is_pushed_by_floats : 1; + unsigned adjoining_floats : 2; // NGFloatTypes + + unsigned is_initial_block_size_indefinite : 1; + unsigned has_descendant_that_depends_on_percentage_block_size : 1; + + unsigned initial_break_before : 4; // EBreakBetween + unsigned final_break_after : 4; // EBreakBetween + + unsigned status : 1; // NGLayoutResultStatus + }; + // The constraint space which generated this layout result, may not be valid - // as indicated by |has_valid_space_|. + // as indicated by |Bitfields::has_valid_space|. const NGConstraintSpace space_; scoped_refptr<const NGPhysicalContainerFragment> physical_fragment_; - // This is the final position of an OOF-positioned object in its parent's - // writing-mode. This is set by the |NGOutOfFlowLayoutPart| while generating - // this layout result. - // This field is unused for other objects. - LogicalOffset oof_positioned_offset_; - NGUnpositionedListMarker unpositioned_list_marker_; + // To save space, we union these fields. + // - |rare_data_| is valid if the |Bitfields::has_rare_data| bit is set. + // |bfc_offset_| and |oof_positioned_offset_| are stored within the + // |RareData| object for this case. + // - |oof_positioned_offset_| is valid if the + // |Bitfields::has_oof_positioned_offset| bit is set. As the node is + // OOF-positioned the |bfc_offset_| is *always* the initial value. + // - Otherwise |bfc_offset_| is valid. + union { + NGBfcOffset bfc_offset_; + // This is the final position of an OOF-positioned object in its parent's + // writing-mode. This is set by the |NGOutOfFlowLayoutPart| while + // generating this layout result. + LogicalOffset oof_positioned_offset_; + RareData* rare_data_; + }; - const NGExclusionSpace exclusion_space_; - const LayoutUnit bfc_line_offset_; - const base::Optional<LayoutUnit> bfc_block_offset_; - const NGMarginStrut end_margin_strut_; LayoutUnit intrinsic_block_size_; - LayoutUnit minimal_space_shortage_ = LayoutUnit::Max(); - - EBreakBetween initial_break_before_ = EBreakBetween::kAuto; - EBreakBetween final_break_after_ = EBreakBetween::kAuto; - - unsigned has_valid_space_ : 1; - unsigned has_forced_break_ : 1; - - unsigned is_self_collapsing_ : 1; - unsigned is_pushed_by_floats_ : 1; - unsigned adjoining_floats_ : 2; // NGFloatTypes - - unsigned is_initial_block_size_indefinite_ : 1; - unsigned has_descendant_that_depends_on_percentage_block_size_ : 1; - - unsigned status_ : 1; + Bitfields bitfields_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc index 9890603..cb6babb 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
@@ -141,16 +141,18 @@ const NGPhysicalContainerFragment& fragment = result->PhysicalFragment(); AddChildFragment(*it, fragment); - const ComputedStyle& child_style = child.Style(); - - // Calculate the static block-offset for any OOF-positioned children. - NGMarginStrut margin_strut = result->EndMarginStrut(); - NGBoxStrut child_margins = ComputeMarginsFor( - child_style, child_available_inline_size_, writing_mode_, direction_); - margin_strut.Append(child_margins.block_end, - child_style.HasMarginBeforeQuirk()); - - static_block_offset_ += margin_strut.Sum(); + // Update the static block-offset for any OOF-positioned children. + // Only consider inflow children (floats don't contribute to the intrinsic + // block-size). + if (!child.IsFloating()) { + const ComputedStyle& child_style = child.Style(); + NGMarginStrut margin_strut = result->EndMarginStrut(); + NGBoxStrut child_margins = ComputeMarginsFor( + child_style, child_available_inline_size_, writing_mode_, direction_); + margin_strut.Append(child_margins.block_end, + child_style.HasMarginBeforeQuirk()); + static_block_offset_ += margin_strut.Sum(); + } // Only take exclusion spaces from children which don't establish their own // formatting context. @@ -207,7 +209,10 @@ container_builder_.AddChild(new_fragment, child_offset); // Update the static block-offset for any OOF-positioned children. - static_block_offset_ = child_offset.block_offset + child_size.block_size; + // Only consider inflow children (floats don't contribute to the intrinsic + // block-size). + if (!new_fragment.IsFloating()) + static_block_offset_ = child_offset.block_offset + child_size.block_size; } } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.cc b/third_party/blink/renderer/core/loader/base_fetch_context.cc index fe107dc..7917b62f 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -132,12 +132,12 @@ scoped_refptr<const SecurityOrigin> origin = resource_request.RequestorOrigin(); - const auto request_mode = resource_request.GetFetchRequestMode(); + const auto request_mode = resource_request.GetMode(); // On navigation cases, Context().GetSecurityOrigin() may return nullptr, so // the request's origin may be nullptr. // TODO(yhirano): Figure out if it's actually fine. - DCHECK(request_mode == network::mojom::FetchRequestMode::kNavigate || origin); - if (request_mode != network::mojom::FetchRequestMode::kNavigate && + DCHECK(request_mode == network::mojom::RequestMode::kNavigate || origin); + if (request_mode != network::mojom::RequestMode::kNavigate && !origin->CanDisplay(url)) { if (reporting_policy == SecurityViolationReportingPolicy::kReport) { AddConsoleMessage(ConsoleMessage::Create( @@ -150,7 +150,7 @@ return ResourceRequestBlockedReason::kOther; } - if (request_mode == network::mojom::FetchRequestMode::kSameOrigin && + if (request_mode == network::mojom::RequestMode::kSameOrigin && cors::CalculateCorsFlag(url, origin.get(), request_mode)) { PrintAccessDeniedMessage(url); return ResourceRequestBlockedReason::kOrigin;
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.cc b/third_party/blink/renderer/core/loader/frame_load_request.cc index dd5fb507..1b788678 100644 --- a/third_party/blink/renderer/core/loader/frame_load_request.cc +++ b/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -48,12 +48,10 @@ resource_request_(resource_request), should_send_referrer_(kMaybeSendReferrer) { // These flags are passed to a service worker which controls the page. - resource_request_.SetFetchRequestMode( - network::mojom::FetchRequestMode::kNavigate); - resource_request_.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kInclude); - resource_request_.SetFetchRedirectMode( - network::mojom::FetchRedirectMode::kManual); + resource_request_.SetMode(network::mojom::RequestMode::kNavigate); + resource_request_.SetCredentialsMode( + network::mojom::CredentialsMode::kInclude); + resource_request_.SetRedirectMode(network::mojom::RedirectMode::kManual); if (const WebInputEvent* input_event = CurrentInputEvent::Get()) SetInputStartTime(input_event->TimeStamp());
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index e95416eb..a01337cf 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -51,6 +51,7 @@ #include "third_party/blink/renderer/core/layout/layout_video.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h" #include "third_party/blink/renderer/core/loader/importance_attribute.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -194,7 +195,7 @@ request_url_(request_url), weak_factory_(this) { ExecutionContext& context = loader_->GetElement()->GetDocument(); - probe::AsyncTaskScheduled(&context, "Image", this); + probe::AsyncTaskScheduled(&context, "Image", &async_task_id_); v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate(); v8::HandleScope scope(isolate); // If we're invoked from C++ without a V8 context on the stack, we should @@ -212,7 +213,7 @@ if (!loader_) return; ExecutionContext& context = loader_->GetElement()->GetDocument(); - probe::AsyncTask async_task(&context, this); + probe::AsyncTask async_task(&context, &async_task_id_); if (script_state_ && script_state_->ContextIsValid()) { ScriptState::Scope scope(script_state_); loader_->DoUpdateFromElement(should_bypass_main_world_csp_, @@ -240,6 +241,7 @@ WeakPersistent<ScriptState> script_state_; network::mojom::ReferrerPolicy referrer_policy_; KURL request_url_; + probe::AsyncTaskId async_task_id_; base::WeakPtrFactory<Task> weak_factory_; }; @@ -713,8 +715,7 @@ // ImageResource to be populated later. if (loading_image_document_) { ResourceRequest request(url); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); ImageResource* image_resource = ImageResource::Create(request); image_resource->NotifyStartLoad(); SetImageForImageDocument(image_resource);
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc index d71dee2..e6cd611 100644 --- a/third_party/blink/renderer/core/loader/link_loader_test.cc +++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -468,25 +468,25 @@ CrossOriginAttributeValue cross_origin; network::mojom::ReferrerPolicy referrer_policy; bool expecting_load; - network::mojom::FetchCredentialsMode expected_credentials_mode; + network::mojom::CredentialsMode expected_credentials_mode; }; constexpr ModulePreloadTestParams kModulePreloadTestParams[] = { {"", nullptr, nullptr, kCrossOriginAttributeNotSet, network::mojom::ReferrerPolicy::kDefault, false, - network::mojom::FetchCredentialsMode::kSameOrigin}, + network::mojom::CredentialsMode::kSameOrigin}, {"http://example.test/cat.js", nullptr, nullptr, kCrossOriginAttributeNotSet, network::mojom::ReferrerPolicy::kDefault, - true, network::mojom::FetchCredentialsMode::kSameOrigin}, + true, network::mojom::CredentialsMode::kSameOrigin}, {"http://example.test/cat.js", nullptr, nullptr, kCrossOriginAttributeAnonymous, network::mojom::ReferrerPolicy::kDefault, - true, network::mojom::FetchCredentialsMode::kSameOrigin}, + true, network::mojom::CredentialsMode::kSameOrigin}, {"http://example.test/cat.js", "nonce", nullptr, kCrossOriginAttributeNotSet, network::mojom::ReferrerPolicy::kNever, true, - network::mojom::FetchCredentialsMode::kSameOrigin}, + network::mojom::CredentialsMode::kSameOrigin}, {"http://example.test/cat.js", nullptr, "sha384-abc", kCrossOriginAttributeNotSet, network::mojom::ReferrerPolicy::kDefault, - true, network::mojom::FetchCredentialsMode::kSameOrigin}}; + true, network::mojom::CredentialsMode::kSameOrigin}}; class LinkLoaderModulePreloadTest : public testing::TestWithParam<ModulePreloadTestParams> {};
diff --git a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc index 708df92..e55c7ac 100644 --- a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc +++ b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
@@ -43,7 +43,7 @@ ModuleScriptCreationParams params( script_resource->GetResponse().CurrentRequestUrl(), script_resource->SourceText(), script_resource->CacheHandler(), - script_resource->GetResourceRequest().GetFetchCredentialsMode()); + script_resource->GetResourceRequest().GetCredentialsMode()); client_->NotifyFetchFinished(params, error_messages); } @@ -80,7 +80,7 @@ ModuleScriptCreationParams params( layered_api_url, ParkableString(source_text.ReleaseImpl()), nullptr /* cache_handler */, - fetch_params.GetResourceRequest().GetFetchCredentialsMode()); + fetch_params.GetResourceRequest().GetCredentialsMode()); client_->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>()); return true; }
diff --git a/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc index 2292755..33f366d 100644 --- a/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc +++ b/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
@@ -72,7 +72,7 @@ ModuleScriptCreationParams params( fetch_params.Url(), ParkableString(script_data->TakeSourceText().Impl()), nullptr /* cache_handler */, - fetch_params.GetResourceRequest().GetFetchCredentialsMode()); + fetch_params.GetResourceRequest().GetCredentialsMode()); client->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>()); }
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h b/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h index ac3727a..a2e943e 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h +++ b/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
@@ -21,17 +21,16 @@ DISALLOW_NEW(); public: - ModuleScriptCreationParams( - const KURL& response_url, - const ParkableString& source_text, - SingleCachedMetadataHandler* cache_handler, - network::mojom::FetchCredentialsMode fetch_credentials_mode) + ModuleScriptCreationParams(const KURL& response_url, + const ParkableString& source_text, + SingleCachedMetadataHandler* cache_handler, + network::mojom::CredentialsMode credentials_mode) : response_url_(response_url), is_isolated_(false), source_text_(source_text), isolated_source_text_(), cache_handler_(cache_handler), - fetch_credentials_mode_(fetch_credentials_mode) {} + credentials_mode_(credentials_mode) {} ~ModuleScriptCreationParams() = default; @@ -54,8 +53,8 @@ return source_text_; } SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; } - network::mojom::FetchCredentialsMode GetFetchCredentialsMode() const { - return fetch_credentials_mode_; + network::mojom::CredentialsMode GetFetchCredentialsMode() const { + return credentials_mode_; } bool IsSafeToSendToAnotherThread() const { @@ -64,15 +63,14 @@ private: // Creates an isolated copy. - ModuleScriptCreationParams( - const KURL& response_url, - const String& isolated_source_text, - network::mojom::FetchCredentialsMode fetch_credentials_mode) + ModuleScriptCreationParams(const KURL& response_url, + const String& isolated_source_text, + network::mojom::CredentialsMode credentials_mode) : response_url_(response_url), is_isolated_(true), source_text_(), isolated_source_text_(isolated_source_text), - fetch_credentials_mode_(fetch_credentials_mode) {} + credentials_mode_(credentials_mode) {} const KURL response_url_; @@ -85,7 +83,7 @@ // |cache_handler_| is cleared when crossing thread boundaries. Persistent<SingleCachedMetadataHandler> cache_handler_; - const network::mojom::FetchCredentialsMode fetch_credentials_mode_; + const network::mojom::CredentialsMode credentials_mode_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc index d8419c6..7e2b9e6 100644 --- a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc +++ b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
@@ -128,7 +128,7 @@ ModuleScriptCreationParams params( script_resource->GetResponse().CurrentRequestUrl(), script_resource->SourceText(), script_resource->CacheHandler(), - script_resource->GetResourceRequest().GetFetchCredentialsMode()); + script_resource->GetResourceRequest().GetCredentialsMode()); // Step 12.7. "Asynchronously complete the perform the fetch steps with // response." [spec text]
diff --git a/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc index 514dedd..425b99a 100644 --- a/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc +++ b/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc
@@ -46,10 +46,10 @@ ScriptResource* script_resource = ToScriptResource(resource); HeapVector<Member<ConsoleMessage>> error_messages; if (WasModuleLoadSuccessful(script_resource, &error_messages)) { - params.emplace( - script_resource->GetResponse().CurrentRequestUrl(), - script_resource->SourceText(), script_resource->CacheHandler(), - script_resource->GetResourceRequest().GetFetchCredentialsMode()); + params.emplace(script_resource->GetResponse().CurrentRequestUrl(), + script_resource->SourceText(), + script_resource->CacheHandler(), + script_resource->GetResourceRequest().GetCredentialsMode()); } // This will eventually notify |client| passed to
diff --git a/third_party/blink/renderer/core/loader/ping_loader.cc b/third_party/blink/renderer/core/loader/ping_loader.cc index 3ca8a1c..4c1cd9a 100644 --- a/third_party/blink/renderer/core/loader/ping_loader.cc +++ b/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -255,11 +255,10 @@ } request.SetKeepalive(true); request.SetHttpBody(std::move(report)); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kSameOrigin); + request.SetCredentialsMode(network::mojom::CredentialsMode::kSameOrigin); request.SetRequestContext(mojom::RequestContextType::CSP_REPORT); request.SetRequestorOrigin(frame->GetDocument()->GetSecurityOrigin()); - request.SetFetchRedirectMode(network::mojom::FetchRedirectMode::kError); + request.SetRedirectMode(network::mojom::RedirectMode::kError); FetchParameters params(request); params.MutableOptions().initiator_info.name = fetch_initiator_type_names::kViolationreport;
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc index 711a98f5..fe6abc8 100644 --- a/third_party/blink/renderer/core/loader/preload_helper.cc +++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -387,7 +387,7 @@ // Step 6. "Let credentials mode be the module script credentials mode for the // crossorigin attribute." [spec text] - network::mojom::FetchCredentialsMode credentials_mode = + network::mojom::CredentialsMode credentials_mode = ScriptLoader::ModuleScriptCredentialsMode(params.cross_origin); // Step 7. "Let cryptographic nonce be the value of the nonce attribute, if it
diff --git a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc index 0e88473..070f330 100644 --- a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc +++ b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
@@ -55,7 +55,7 @@ const KURL& url, const WTF::TextEncoding& encoding) { ResourceRequest request(url); - request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); ResourceLoaderOptions options; TextResourceDecoderOptions decoder_options( TextResourceDecoderOptions::kCSSContent, encoding);
diff --git a/third_party/blink/renderer/core/loader/resource/document_resource.cc b/third_party/blink/renderer/core/loader/resource/document_resource.cc index 018321d..1ad946d 100644 --- a/third_party/blink/renderer/core/loader/resource/document_resource.cc +++ b/third_party/blink/renderer/core/loader/resource/document_resource.cc
@@ -36,8 +36,8 @@ DocumentResource* DocumentResource::FetchSVGDocument(FetchParameters& params, ResourceFetcher* fetcher, ResourceClient* client) { - DCHECK_EQ(params.GetResourceRequest().GetFetchRequestMode(), - network::mojom::FetchRequestMode::kSameOrigin); + DCHECK_EQ(params.GetResourceRequest().GetMode(), + network::mojom::RequestMode::kSameOrigin); params.SetRequestContext(mojom::RequestContextType::IMAGE); return ToDocumentResource( fetcher->RequestResource(params, SVGDocumentResourceFactory(), client));
diff --git a/third_party/blink/renderer/core/loader/resource/script_resource.h b/third_party/blink/renderer/core/loader/resource/script_resource.h index 1aa8e72..ba2a14fe 100644 --- a/third_party/blink/renderer/core/loader/resource/script_resource.h +++ b/third_party/blink/renderer/core/loader/resource/script_resource.h
@@ -79,8 +79,7 @@ static ScriptResource* CreateForTest(const KURL& url, const WTF::TextEncoding& encoding) { ResourceRequest request(url); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); ResourceLoaderOptions options; TextResourceDecoderOptions decoder_options( TextResourceDecoderOptions::kPlainTextContent, encoding);
diff --git a/third_party/blink/renderer/core/loader/text_track_loader.cc b/third_party/blink/renderer/core/loader/text_track_loader.cc index eaaaaf27..95e6fb9 100644 --- a/third_party/blink/renderer/core/loader/text_track_loader.cc +++ b/third_party/blink/renderer/core/loader/text_track_loader.cc
@@ -115,8 +115,8 @@ FetchParameters cue_fetch_params(ResourceRequest(url), options); if (cross_origin == kCrossOriginAttributeNotSet) { - cue_fetch_params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + cue_fetch_params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); } else { cue_fetch_params.SetCrossOriginAccessControl( GetDocument().GetSecurityOrigin(), cross_origin);
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc index 24596cc..b736daf 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -167,8 +167,7 @@ request.HttpMethod()); preflight_request->SetPriority(request.Priority()); preflight_request->SetRequestContext(request.GetRequestContext()); - preflight_request->SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + preflight_request->SetCredentialsMode(network::mojom::CredentialsMode::kOmit); preflight_request->SetSkipServiceWorker(true); preflight_request->SetReferrerString(request.ReferrerString()); preflight_request->SetReferrerPolicy(request.GetReferrerPolicy()); @@ -211,13 +210,13 @@ async_(resource_loader_options.synchronous_policy == kRequestAsynchronously), request_context_(mojom::RequestContextType::UNSPECIFIED), - fetch_request_mode_(network::mojom::FetchRequestMode::kSameOrigin), - fetch_credentials_mode_(network::mojom::FetchCredentialsMode::kOmit), + request_mode_(network::mojom::RequestMode::kSameOrigin), + credentials_mode_(network::mojom::CredentialsMode::kOmit), timeout_timer_(execution_context_->GetTaskRunner(TaskType::kNetworking), this, &ThreadableLoader::DidTimeout), redirect_limit_(kMaxRedirects), - redirect_mode_(network::mojom::FetchRedirectMode::kFollow), + redirect_mode_(network::mojom::RedirectMode::kFollow), override_referrer_(false) { DCHECK(client); if (!resource_fetcher_) { @@ -232,8 +231,7 @@ // Setting an outgoing referer is only supported in the async code path. DCHECK(async_ || request.HttpReferrer().IsEmpty()); - bool cors_enabled = - cors::IsCorsEnabledRequestMode(request.GetFetchRequestMode()); + bool cors_enabled = cors::IsCorsEnabledRequestMode(request.GetMode()); // kPreventPreflight can be used only when the CORS is enabled. DCHECK(request.CorsPreflightPolicy() == @@ -243,21 +241,20 @@ initial_request_url_ = request.Url(); last_request_url_ = initial_request_url_; request_context_ = request.GetRequestContext(); - fetch_request_mode_ = request.GetFetchRequestMode(); - fetch_credentials_mode_ = request.GetFetchCredentialsMode(); - redirect_mode_ = request.GetFetchRedirectMode(); + request_mode_ = request.GetMode(); + credentials_mode_ = request.GetCredentialsMode(); + redirect_mode_ = request.GetRedirectMode(); - if (request.GetFetchRequestMode() == - network::mojom::FetchRequestMode::kNoCors) { + if (request.GetMode() == network::mojom::RequestMode::kNoCors) { SECURITY_CHECK(cors::IsNoCorsAllowedContext(request_context_)); } cors_flag_ = cors::CalculateCorsFlag(request.Url(), GetSecurityOrigin(), - request.GetFetchRequestMode()); + request.GetMode()); // The CORS flag variable is not yet used at the step in the spec that // corresponds to this line, but divert |cors_flag_| here for convenience. - if (cors_flag_ && request.GetFetchRequestMode() == - network::mojom::FetchRequestMode::kSameOrigin) { + if (cors_flag_ && + request.GetMode() == network::mojom::RequestMode::kSameOrigin) { ThreadableLoaderClient* client = client_; Clear(); client->DidFail(ResourceError( @@ -315,7 +312,7 @@ return; } - if (cors::IsCorsEnabledRequestMode(request.GetFetchRequestMode())) { + if (cors::IsCorsEnabledRequestMode(request.GetMode())) { // Save the request to fallback_request_for_service_worker to use when the // service worker doesn't handle (call respondWith()) a CORS enabled // request. @@ -333,7 +330,7 @@ return; } - DCHECK(cors::IsCorsEnabledRequestMode(request.GetFetchRequestMode()) || + DCHECK(cors::IsCorsEnabledRequestMode(request.GetMode()) || request.IsExternalRequest()); MakeCrossOriginAccessRequest(request); @@ -373,7 +370,7 @@ void ThreadableLoader::MakeCrossOriginAccessRequest( const ResourceRequest& request) { - DCHECK(cors::IsCorsEnabledRequestMode(request.GetFetchRequestMode()) || + DCHECK(cors::IsCorsEnabledRequestMode(request.GetMode()) || request.IsExternalRequest()); DCHECK(client_); DCHECK(!GetResource()); @@ -417,8 +414,8 @@ return; } - if (request.GetFetchRequestMode() != - network::mojom::FetchRequestMode::kCorsWithForcedPreflight) { + if (request.GetMode() != + network::mojom::RequestMode::kCorsWithForcedPreflight) { if (request.CorsPreflightPolicy() == network::mojom::CorsPreflightPolicy::kPreventPreflight) { PrepareCrossOriginRequest(cross_origin_request); @@ -454,7 +451,7 @@ if (should_ignore_preflight_cache || !cors::CheckIfRequestCanSkipPreflight( GetSecurityOrigin()->ToString(), cross_origin_request.Url(), - cross_origin_request.GetFetchCredentialsMode(), + cross_origin_request.GetCredentialsMode(), cross_origin_request.HttpMethod(), cross_origin_request.HttpHeaderFields())) { LoadPreflightRequest(cross_origin_request, cross_origin_options); @@ -571,19 +568,19 @@ if (const auto error_status = cors::CheckAccess( original_url, redirect_response.HttpStatusCode(), redirect_response.HttpHeaderFields(), - new_request.GetFetchCredentialsMode(), *GetSecurityOrigin())) { + new_request.GetCredentialsMode(), *GetSecurityOrigin())) { DispatchDidFail(ResourceError(original_url, *error_status)); return false; } } - if (redirect_mode_ == network::mojom::FetchRedirectMode::kError) { + if (redirect_mode_ == network::mojom::RedirectMode::kError) { bool follow = client_->WillFollowRedirect(new_url, redirect_response); DCHECK(!follow); return false; } - if (redirect_mode_ == network::mojom::FetchRedirectMode::kManual) { + if (redirect_mode_ == network::mojom::RedirectMode::kManual) { auto redirect_response_to_pass = redirect_response; redirect_response_to_pass.SetType( network::mojom::FetchResponseType::kOpaqueRedirect); @@ -593,7 +590,7 @@ return false; } - DCHECK_EQ(redirect_mode_, network::mojom::FetchRedirectMode::kFollow); + DCHECK_EQ(redirect_mode_, network::mojom::RedirectMode::kFollow); if (redirect_limit_ <= 0) { ThreadableLoaderClient* client = client_; @@ -614,14 +611,12 @@ // Allow same origin requests to continue after allowing clients to audit // the redirect. - if (!(cors_flag_ || - cors::CalculateCorsFlag(new_url, GetSecurityOrigin(), - new_request.GetFetchRequestMode()))) { + if (!(cors_flag_ || cors::CalculateCorsFlag(new_url, GetSecurityOrigin(), + new_request.GetMode()))) { bool follow = client_->WillFollowRedirect(new_url, redirect_response_to_pass); response_tainting_ = cors::CalculateResponseTainting( - new_url, new_request.GetFetchRequestMode(), GetSecurityOrigin(), - CorsFlag::Unset); + new_url, new_request.GetMode(), GetSecurityOrigin(), CorsFlag::Unset); return follow; } @@ -633,7 +628,7 @@ redirect_response_to_pass, resource); if (auto error_status = cors::CheckRedirectLocation( - new_url, fetch_request_mode_, GetSecurityOrigin(), + new_url, request_mode_, GetSecurityOrigin(), cors_flag_ ? CorsFlag::Set : CorsFlag::Unset)) { DispatchDidFail(ResourceError(original_url, *error_status)); return false; @@ -751,8 +746,8 @@ base::Optional<network::CorsErrorStatus> cors_error_status = cors::CheckPreflightAccess( response.CurrentRequestUrl(), response.HttpStatusCode(), - response.HttpHeaderFields(), - actual_request_.GetFetchCredentialsMode(), *GetSecurityOrigin()); + response.HttpHeaderFields(), actual_request_.GetCredentialsMode(), + *GetSecurityOrigin()); if (cors_error_status) { HandlePreflightFailure(response.CurrentRequestUrl(), *cors_error_status); return; @@ -779,8 +774,7 @@ error_status = cors::EnsurePreflightResultAndCacheOnSuccess( response.HttpHeaderFields(), GetSecurityOrigin()->ToString(), actual_request_.Url(), actual_request_.HttpMethod(), - actual_request_.HttpHeaderFields(), - actual_request_.GetFetchCredentialsMode()); + actual_request_.HttpHeaderFields(), actual_request_.GetCredentialsMode()); if (error_status) HandlePreflightFailure(response.CurrentRequestUrl(), *error_status); } @@ -840,7 +834,7 @@ // We dispatch a CORS failure for the case. // TODO(yhirano): This is probably not spec conformant. Fix it after // https://github.com/w3c/preload/issues/100 is addressed. - if (fetch_request_mode_ != network::mojom::FetchRequestMode::kNoCors && + if (request_mode_ != network::mojom::RequestMode::kNoCors && response.GetType() == network::mojom::FetchResponseType::kOpaque) { DispatchDidFail( ResourceError(response.CurrentRequestUrl(), @@ -869,8 +863,7 @@ if (cors_flag_) { base::Optional<network::CorsErrorStatus> access_error = cors::CheckAccess( response.CurrentRequestUrl(), response.HttpStatusCode(), - response.HttpHeaderFields(), fetch_credentials_mode_, - *GetSecurityOrigin()); + response.HttpHeaderFields(), credentials_mode_, *GetSecurityOrigin()); if (access_error) { ReportResponseReceived(resource->InspectorId(), response); DispatchDidFail( @@ -1020,18 +1013,18 @@ kDisableCorsHandlingByResourceFetcher; if (out_of_blink_cors_) { - if (request.GetFetchCredentialsMode() == - network::mojom::FetchCredentialsMode::kOmit) { - // See comments at network::ResourceRequest::fetch_credentials_mode. + if (request.GetCredentialsMode() == + network::mojom::CredentialsMode::kOmit) { + // See comments at network::ResourceRequest::credentials_mode. request.SetAllowStoredCredentials(false); } } else { if (actual_request_.IsNull()) { response_tainting_ = cors::CalculateResponseTainting( - request.Url(), request.GetFetchRequestMode(), GetSecurityOrigin(), + request.Url(), request.GetMode(), GetSecurityOrigin(), cors_flag_ ? CorsFlag::Set : CorsFlag::Unset); request.SetAllowStoredCredentials(cors::CalculateCredentialsFlag( - request.GetFetchCredentialsMode(), response_tainting_)); + request.GetCredentialsMode(), response_tainting_)); } else { request.SetAllowStoredCredentials(false); }
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.h b/third_party/blink/renderer/core/loader/threadable_loader.h index 0a6a954d..6c639a60 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader.h +++ b/third_party/blink/renderer/core/loader/threadable_loader.h
@@ -235,8 +235,8 @@ // Saved so that we can use the original value for the modes in // ResponseReceived() where |resource| might be a reused one (e.g. preloaded // resource) which can have different modes. - network::mojom::FetchRequestMode fetch_request_mode_; - network::mojom::FetchCredentialsMode fetch_credentials_mode_; + network::mojom::RequestMode request_mode_; + network::mojom::CredentialsMode credentials_mode_; // Holds the original request for fallback in case the Service Worker // does not respond. @@ -261,7 +261,7 @@ // Max number of times that this ThreadableLoader can follow. int redirect_limit_; - network::mojom::FetchRedirectMode redirect_mode_; + network::mojom::RedirectMode redirect_mode_; // Holds the referrer after a redirect response was received. This referrer is // used to populate the HTTP Referer header when following the redirect.
diff --git a/third_party/blink/renderer/core/loader/threadable_loader_test.cc b/third_party/blink/renderer/core/loader/threadable_loader_test.cc index 6136d879..5d8fe7e 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader_test.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader_test.cc
@@ -210,13 +210,12 @@ : helper_(std::make_unique<ThreadableLoaderTestHelper>()) {} void StartLoader(const KURL& url, - network::mojom::FetchRequestMode fetch_request_mode = - network::mojom::FetchRequestMode::kNoCors) { + network::mojom::RequestMode request_mode = + network::mojom::RequestMode::kNoCors) { ResourceRequest request(url); request.SetRequestContext(mojom::RequestContextType::OBJECT); - request.SetFetchRequestMode(fetch_request_mode); - request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kOmit); + request.SetMode(request_mode); + request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit); helper_->StartLoader(request); } @@ -466,7 +465,7 @@ network::mojom::CorsError::kDisallowedByMode)))); EXPECT_CALL(GetCheckpoint(), Call(2)); - StartLoader(ErrorURL(), network::mojom::FetchRequestMode::kSameOrigin); + StartLoader(ErrorURL(), network::mojom::RequestMode::kSameOrigin); CallCheckpoint(2); ServeRequests(); } @@ -481,7 +480,7 @@ .WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::CancelLoader)); EXPECT_CALL(GetCheckpoint(), Call(2)); - StartLoader(ErrorURL(), network::mojom::FetchRequestMode::kSameOrigin); + StartLoader(ErrorURL(), network::mojom::RequestMode::kSameOrigin); CallCheckpoint(2); ServeRequests(); } @@ -496,7 +495,7 @@ .WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::ClearLoader)); EXPECT_CALL(GetCheckpoint(), Call(2)); - StartLoader(ErrorURL(), network::mojom::FetchRequestMode::kSameOrigin); + StartLoader(ErrorURL(), network::mojom::RequestMode::kSameOrigin); CallCheckpoint(2); ServeRequests(); } @@ -514,7 +513,7 @@ network::CorsErrorStatus( network::mojom::CorsError::kMissingAllowOriginHeader)))); - StartLoader(SuccessURL(), network::mojom::FetchRequestMode::kCors); + StartLoader(SuccessURL(), network::mojom::RequestMode::kCors); CallCheckpoint(2); ServeRequests(); } @@ -581,7 +580,7 @@ EXPECT_CALL(GetCheckpoint(), Call(2)); EXPECT_CALL(*Client(), DidFailRedirectCheck()); - StartLoader(RedirectLoopURL(), network::mojom::FetchRequestMode::kCors); + StartLoader(RedirectLoopURL(), network::mojom::RequestMode::kCors); CallCheckpoint(2); ServeRequests(); } @@ -596,7 +595,7 @@ EXPECT_CALL(*Client(), DidFailRedirectCheck()) .WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::CancelLoader)); - StartLoader(RedirectLoopURL(), network::mojom::FetchRequestMode::kCors); + StartLoader(RedirectLoopURL(), network::mojom::RequestMode::kCors); CallCheckpoint(2); ServeRequests(); } @@ -611,7 +610,7 @@ EXPECT_CALL(*Client(), DidFailRedirectCheck()) .WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::ClearLoader)); - StartLoader(RedirectLoopURL(), network::mojom::FetchRequestMode::kCors); + StartLoader(RedirectLoopURL(), network::mojom::RequestMode::kCors); CallCheckpoint(2); ServeRequests(); } @@ -631,7 +630,7 @@ // test is not saying that didFailAccessControlCheck should be dispatched // synchronously, but is saying that even when a response is served // synchronously it should not lead to a crash. - StartLoader(KURL("about:blank"), network::mojom::FetchRequestMode::kCors); + StartLoader(KURL("about:blank"), network::mojom::RequestMode::kCors); CallCheckpoint(2); }
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc index f00e13e..afdd44fd 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -563,7 +563,7 @@ } bool SpatialNavigationController::UpdateCanExitFocus(Element* element) { - bool can_exit_focus = IsFocused(element); + bool can_exit_focus = IsFocused(element) && !IsHTMLBodyElement(element); if (can_exit_focus == spatial_navigation_state_->can_exit_focus) return false; spatial_navigation_state_->can_exit_focus = can_exit_focus;
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 0efccaf..fbbc2eb 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -1154,7 +1154,8 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry( const PaintLayer* compositing_container, const PaintLayer* compositing_stacking_context, - Vector<PaintLayer*>& layers_needing_paint_invalidation) { + Vector<PaintLayer*>& layers_needing_paint_invalidation, + GraphicsLayerUpdater::UpdateContext& update_context) { DCHECK_EQ(owning_layer_.Compositor()->Lifecycle().GetState(), DocumentLifecycle::kInCompositingUpdate); @@ -1198,9 +1199,9 @@ IntSize contents_size(relative_compositing_bounds.Size()); - UpdateMainGraphicsLayerGeometry(relative_compositing_bounds, - local_compositing_bounds, - graphics_layer_parent_location); + UpdateMainGraphicsLayerGeometry( + relative_compositing_bounds, local_compositing_bounds, + graphics_layer_parent_location, update_context); UpdateOverflowControlsHostLayerGeometry(compositing_stacking_context, compositing_container, graphics_layer_parent_location); @@ -1300,28 +1301,42 @@ void CompositedLayerMapping::UpdateMainGraphicsLayerGeometry( const IntRect& relative_compositing_bounds, const IntRect& local_compositing_bounds, - const IntPoint& graphics_layer_parent_location) { + const IntPoint& graphics_layer_parent_location, + GraphicsLayerUpdater::UpdateContext& update_context) { FloatPoint old_position(graphics_layer_->GetPosition()); IntSize old_size(graphics_layer_->Size()); + // Previous offset of the LayoutObject relative to the main GraphicsLayer. + IntSize old_object_offset = -graphics_layer_->OffsetFromLayoutObject(); + FloatPoint new_position = FloatPoint(relative_compositing_bounds.Location() - graphics_layer_parent_location); IntSize new_size = relative_compositing_bounds.Size(); + IntSize new_object_offset = -ToIntSize(local_compositing_bounds.Location()); const LayoutObject& layout_object = GetLayoutObject(); // An iframe's main GraphicsLayer is positioned by the CLM for the <iframe> // element in the parent frame's DOM. bool is_iframe_doc = layout_object.IsLayoutView() && !layout_object.GetFrame()->IsLocalRoot(); - if (new_position != old_position && !is_iframe_doc) { + if (new_position != old_position && !is_iframe_doc) graphics_layer_->SetPosition(new_position); + graphics_layer_->SetOffsetFromLayoutObject(-new_object_offset); + IntSize obj_offset_delta = new_object_offset - old_object_offset; + IntSize position_delta = RoundedIntSize(new_position - old_position); + // Did our LayoutObject move in relation to the parent CLM's LayoutObject + // (accounting for their respective offsets from the main GraphicsLayers)? + IntSize layout_object_delta = position_delta + obj_offset_delta - + update_context.parent_object_offset_delta; + if (!layout_object_delta.IsZero()) { LocalFrameView* frame_view = layout_object.View()->GetFrameView(); frame_view->GetJankTracker().NotifyCompositedLayerMoved( - layout_object, FloatRect(old_position, FloatSize(old_size)), - FloatRect(new_position, FloatSize(new_size))); + layout_object, + FloatRect(FloatPoint(), FloatSize(old_size - old_object_offset)), + FloatRect(FloatPoint(layout_object_delta), + FloatSize(new_size - new_object_offset))); } - graphics_layer_->SetOffsetFromLayoutObject( - ToIntSize(local_compositing_bounds.Location())); + update_context.object_offset_delta = obj_offset_delta; if (old_size != new_size) graphics_layer_->SetSize(gfx::Size(new_size));
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h index 0b5fe83..2b52b22 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -99,7 +99,8 @@ void UpdateGraphicsLayerGeometry( const PaintLayer* compositing_container, const PaintLayer* compositing_stacking_context, - Vector<PaintLayer*>& layers_needing_paint_invalidation); + Vector<PaintLayer*>& layers_needing_paint_invalidation, + GraphicsLayerUpdater::UpdateContext& update_context); // Update whether background paints onto scrolling contents layer. // Returns (through the reference params) what invalidations are needed. @@ -359,7 +360,8 @@ void UpdateMainGraphicsLayerGeometry( const IntRect& relative_compositing_bounds, const IntRect& local_compositing_bounds, - const IntPoint& graphics_layer_parent_location); + const IntPoint& graphics_layer_parent_location, + GraphicsLayerUpdater::UpdateContext& update_context); void UpdateAncestorClippingLayerGeometry( const PaintLayer* compositing_container, const IntPoint& snapped_offset_from_composited_ancestor,
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc index cc3c6d1..2537338f 100644 --- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc +++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
@@ -37,72 +37,71 @@ namespace blink { -class GraphicsLayerUpdater::UpdateContext { - public: - UpdateContext() - : compositing_stacking_context_(nullptr), - compositing_ancestor_(nullptr), - use_slow_path_(false) {} +GraphicsLayerUpdater::UpdateContext::UpdateContext() + : compositing_stacking_context_(nullptr), + compositing_ancestor_(nullptr), + use_slow_path_(false) {} - UpdateContext(const UpdateContext& other, const PaintLayer& layer) - : compositing_stacking_context_(other.compositing_stacking_context_), - compositing_ancestor_(other.CompositingContainer(layer)), - use_slow_path_(other.use_slow_path_) { - CompositingState compositing_state = layer.GetCompositingState(); - if (compositing_state != kNotComposited && - compositing_state != kPaintsIntoGroupedBacking) { - compositing_ancestor_ = &layer; - if (layer.GetLayoutObject().StyleRef().IsStackingContext()) - compositing_stacking_context_ = &layer; +GraphicsLayerUpdater::UpdateContext::UpdateContext(const UpdateContext& other, + const PaintLayer& layer) + : compositing_stacking_context_(other.compositing_stacking_context_), + compositing_ancestor_(other.CompositingContainer(layer)), + use_slow_path_(other.use_slow_path_) { + CompositingState compositing_state = layer.GetCompositingState(); + if (compositing_state != kNotComposited && + compositing_state != kPaintsIntoGroupedBacking) { + compositing_ancestor_ = &layer; + if (layer.GetLayoutObject().StyleRef().IsStackingContext()) + compositing_stacking_context_ = &layer; + } + // Any composited content under SVG must be a descendant of (but not + // equal to, see PaintLayerCompositor::CanBeComposited) + // a <foreignObject> element. The rules for compositing ancestors are + // complicated for this situation, due to <foreignObject> being a replaced + // nornmal-flow stacking element + // (see PaintLayer::IsReplacedNormalFlowStacking). Use a slow path + // for these situations, to simplify the logic. + if (layer.GetLayoutObject().IsSVGRoot() || + layer.IsReplacedNormalFlowStacking()) + use_slow_path_ = true; - } - // Any composited content under SVG must be a descendant of (but not - // equal to, see PaintLayerCompositor::CanBeComposited) - // a <foreignObject> element. The rules for compositing ancestors are - // complicated for this situation, due to <foreignObject> being a replaced - // nornmal-flow stacking element - // (see PaintLayer::IsReplacedNormalFlowStacking). Use a slow path - // for these situations, to simplify the logic. - if (layer.GetLayoutObject().IsSVGRoot() || - layer.IsReplacedNormalFlowStacking()) - use_slow_path_ = true; + parent_object_offset_delta = + compositing_ancestor_ == other.compositing_ancestor_ + ? other.parent_object_offset_delta + : other.object_offset_delta; +} + +const PaintLayer* GraphicsLayerUpdater::UpdateContext::CompositingContainer( + const PaintLayer& layer) const { + if (use_slow_path_) + return layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf); + + const PaintLayer* compositing_container; + if (layer.GetLayoutObject().StyleRef().IsStacked() && + !layer.IsReplacedNormalFlowStacking()) { + compositing_container = compositing_stacking_context_; + } else if ((layer.Parent() && + !layer.Parent()->GetLayoutObject().IsLayoutBlock()) || + layer.GetLayoutObject().IsColumnSpanAll()) { + // In these cases, compositingContainer may escape the normal layer + // hierarchy. Use the slow path to ensure correct result. + // See PaintLayer::containingLayer() for details. + compositing_container = + layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf); + } else { + compositing_container = compositing_ancestor_; } - const PaintLayer* CompositingContainer(const PaintLayer& layer) const { - if (use_slow_path_) - return layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf); + // We should always get the same result as the slow path. + DCHECK_EQ(compositing_container, + layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf)); + return compositing_container; +} - const PaintLayer* compositing_container; - if (layer.GetLayoutObject().StyleRef().IsStacked() && - !layer.IsReplacedNormalFlowStacking()) { - compositing_container = compositing_stacking_context_; - } else if ((layer.Parent() && - !layer.Parent()->GetLayoutObject().IsLayoutBlock()) || - layer.GetLayoutObject().IsColumnSpanAll()) { - // In these cases, compositingContainer may escape the normal layer - // hierarchy. Use the slow path to ensure correct result. - // See PaintLayer::containingLayer() for details. - compositing_container = - layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf); - } else { - compositing_container = compositing_ancestor_; - } - - // We should always get the same result as the slow path. - DCHECK_EQ(compositing_container, - layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf)); - return compositing_container; - } - - const PaintLayer* CompositingStackingContext() const { - return compositing_stacking_context_; - } - - private: - const PaintLayer* compositing_stacking_context_; - const PaintLayer* compositing_ancestor_; - bool use_slow_path_; -}; +const PaintLayer* +GraphicsLayerUpdater::UpdateContext::CompositingStackingContext() const { + return compositing_stacking_context_; +} GraphicsLayerUpdater::GraphicsLayerUpdater() : needs_rebuild_tree_(false) {} @@ -112,14 +111,15 @@ PaintLayer& layer, Vector<PaintLayer*>& layers_needing_paint_invalidation) { TRACE_EVENT0("blink", "GraphicsLayerUpdater::update"); - UpdateRecursive(layer, kDoNotForceUpdate, UpdateContext(), + UpdateContext update_context; + UpdateRecursive(layer, kDoNotForceUpdate, update_context, layers_needing_paint_invalidation); } void GraphicsLayerUpdater::UpdateRecursive( PaintLayer& layer, UpdateType update_type, - const UpdateContext& context, + UpdateContext& context, Vector<PaintLayer*>& layers_needing_paint_invalidation) { if (layer.HasCompositedLayerMapping()) { CompositedLayerMapping* mapping = layer.GetCompositedLayerMapping(); @@ -134,9 +134,9 @@ if (had_scrolling_layer != !!mapping->ScrollingLayer()) layers_needing_paint_invalidation.push_back(&layer); } - mapping->UpdateGraphicsLayerGeometry(compositing_container, - context.CompositingStackingContext(), - layers_needing_paint_invalidation); + mapping->UpdateGraphicsLayerGeometry( + compositing_container, context.CompositingStackingContext(), + layers_needing_paint_invalidation, context); if (PaintLayerScrollableArea* scrollable_area = layer.GetScrollableArea()) scrollable_area->PositionOverflowControls(); update_type = mapping->UpdateTypeForChildren(update_type);
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h index 4df558a..9a98a93 100644 --- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h +++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
@@ -55,12 +55,30 @@ static void AssertNeedsToUpdateGraphicsLayerBitsCleared(PaintLayer&); #endif - private: - class UpdateContext; + class UpdateContext { + public: + UpdateContext(); + UpdateContext(const UpdateContext& other, const PaintLayer& layer); + const PaintLayer* CompositingContainer(const PaintLayer& layer) const; + const PaintLayer* CompositingStackingContext() const; + // Offset of this PaintLayer's LayoutObject relative to the position of its + // main GraphicsLayer. + IntSize object_offset_delta; + + // The object_offset_delta of the compositing ancestor. + IntSize parent_object_offset_delta; + + private: + const PaintLayer* compositing_stacking_context_; + const PaintLayer* compositing_ancestor_; + bool use_slow_path_; + }; + + private: void UpdateRecursive(PaintLayer&, UpdateType, - const UpdateContext&, + UpdateContext&, Vector<PaintLayer*>& layers_needing_paint_invalidation); bool needs_rebuild_tree_;
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index 0f5ee2a..884717d0 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -286,7 +286,6 @@ context.paint_invalidator_context.NeedsVisualRectUpdate(object); } -#if DCHECK_IS_ON() void PrePaintTreeWalk::CheckTreeBuilderContextState( const LayoutObject& object, const PrePaintTreeWalkContext& parent_context) { @@ -296,21 +295,20 @@ return; } - DCHECK(!object.NeedsPaintPropertyUpdate()); - DCHECK(!object.DescendantNeedsPaintPropertyUpdate()); - DCHECK(!object.DescendantNeedsPaintOffsetAndVisualRectUpdate()); + CHECK(!object.NeedsPaintPropertyUpdate()); + CHECK(!object.DescendantNeedsPaintPropertyUpdate()); + CHECK(!object.DescendantNeedsPaintOffsetAndVisualRectUpdate()); if (parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object)) { // Note that if paint_invalidator_context's NeedsVisualRectUpdate(object) is - // true, we definitely want to DCHECK. However, we would also like to know + // true, we definitely want to CHECK. However, we would also like to know // the value of object.NeedsPaintOffsetAndVisualRectUpdate(), hence one of - // the two DCHECKs below will definitely trigger, and depending on which one + // the two CHECKs below will definitely trigger, and depending on which one // does we will know the value. - DCHECK(object.NeedsPaintOffsetAndVisualRectUpdate()); - DCHECK(!object.NeedsPaintOffsetAndVisualRectUpdate()); + CHECK(object.NeedsPaintOffsetAndVisualRectUpdate()); + CHECK(!object.NeedsPaintOffsetAndVisualRectUpdate()); } - NOTREACHED(); + CHECK(false) << "Unknown reason."; } -#endif void PrePaintTreeWalk::WalkInternal(const LayoutObject& object, PrePaintTreeWalkContext& context) { @@ -425,9 +423,8 @@ return; } -#if DCHECK_IS_ON() + // The following is for debugging crbug.com/974639. CheckTreeBuilderContextState(object, parent_context()); -#endif // Early out from the tree walk if possible. if (!needs_tree_builder_context_update && !ObjectRequiresPrePaint(object) &&
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h index 7798e35..fa95f4b 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
@@ -86,10 +86,8 @@ static bool ContextRequiresTreeBuilderContext(const PrePaintTreeWalkContext&, const LayoutObject&); -#if DCHECK_IS_ON() void CheckTreeBuilderContextState(const LayoutObject&, const PrePaintTreeWalkContext&); -#endif const PrePaintTreeWalkContext& ContextAt(wtf_size_t index) { DCHECK_LT(index, context_storage_.size());
diff --git a/third_party/blink/renderer/core/probe/BUILD.gn b/third_party/blink/renderer/core/probe/BUILD.gn index c439b5d9..93ef592 100644 --- a/third_party/blink/renderer/core/probe/BUILD.gn +++ b/third_party/blink/renderer/core/probe/BUILD.gn
@@ -39,6 +39,7 @@ # Compiles the sources generated above. blink_core_sources("probe") { sources = [ + "async_task_id.h", "core_probes.cc", "core_probes.h", ]
diff --git a/third_party/blink/renderer/core/probe/async_task_id.h b/third_party/blink/renderer/core/probe/async_task_id.h new file mode 100644 index 0000000..eeba800 --- /dev/null +++ b/third_party/blink/renderer/core/probe/async_task_id.h
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PROBE_ASYNC_TASK_ID_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_PROBE_ASYNC_TASK_ID_H_ + +#include "third_party/blink/renderer/core/core_export.h" + +namespace blink { + +namespace probe { + +// The core probes use this class as an identifier for an async task. +class CORE_EXPORT AsyncTaskId { + public: + void SetAdTask() { ad_task_ = true; } + bool IsAdTask() const { return ad_task_; } + + private: + bool ad_task_ = false; +}; + +} // namespace probe + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PROBE_ASYNC_TASK_ID_H_
diff --git a/third_party/blink/renderer/core/probe/core_probes.cc b/third_party/blink/renderer/core/probe/core_probes.cc index f0277aa..a2a779c 100644 --- a/third_party/blink/renderer/core/probe/core_probes.cc +++ b/third_party/blink/renderer/core/probe/core_probes.cc
@@ -31,20 +31,30 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/core/core_probes_inl.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/inspector/thread_debugger.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" namespace blink { namespace probe { namespace { -void* AsyncId(void* task) { +void* AsyncId(AsyncTaskId* task) { // Blink uses odd ids for network requests and even ids for everything else. // We should make all of them even before reporting to V8 to avoid collisions // with internal V8 async events. return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(task) << 1); } + +void AsyncTaskCanceled(v8::Isolate* isolate, AsyncTaskId* task) { + if (ThreadDebugger* debugger = ThreadDebugger::From(isolate)) + debugger->AsyncTaskCanceled(AsyncId(task)); + TRACE_EVENT_FLOW_END0("devtools.timeline.async", "AsyncTask", + TRACE_ID_LOCAL(reinterpret_cast<uintptr_t>(task))); +} + } // namespace TimeTicks ProbeBase::CaptureStartTime() const { @@ -65,13 +75,14 @@ } AsyncTask::AsyncTask(ExecutionContext* context, - void* task, + AsyncTaskId* task, const char* step, bool enabled) : debugger_(enabled && context ? ThreadDebugger::From(context->GetIsolate()) : nullptr), - task_(AsyncId(task)), - recurring_(step) { + task_(task), + recurring_(step), + ad_tracker_(AdTracker::FromExecutionContext(context)) { if (recurring_) { TRACE_EVENT_FLOW_STEP0("devtools.timeline.async", "AsyncTask", TRACE_ID_LOCAL(reinterpret_cast<uintptr_t>(task)), @@ -81,50 +92,54 @@ TRACE_ID_LOCAL(reinterpret_cast<uintptr_t>(task))); } if (debugger_) - debugger_->AsyncTaskStarted(task_); + debugger_->AsyncTaskStarted(AsyncId(task_)); + + if (ad_tracker_) + ad_tracker_->DidStartAsyncTask(task_); } AsyncTask::~AsyncTask() { if (debugger_) { - debugger_->AsyncTaskFinished(task_); + debugger_->AsyncTaskFinished(AsyncId(task_)); if (!recurring_) - debugger_->AsyncTaskCanceled(task_); + debugger_->AsyncTaskCanceled(AsyncId(task_)); } + + if (ad_tracker_) + ad_tracker_->DidFinishAsyncTask(task_); } void AsyncTaskScheduled(ExecutionContext* context, const StringView& name, - void* task) { + AsyncTaskId* task) { TRACE_EVENT_FLOW_BEGIN1("devtools.timeline.async", "AsyncTask", TRACE_ID_LOCAL(reinterpret_cast<uintptr_t>(task)), "data", inspector_async_task::Data(name)); - if (context) { - if (ThreadDebugger* debugger = ThreadDebugger::From(context->GetIsolate())) - debugger->AsyncTaskScheduled(name, AsyncId(task), true); - } + if (!context) + return; + + if (ThreadDebugger* debugger = ThreadDebugger::From(context->GetIsolate())) + debugger->AsyncTaskScheduled(name, AsyncId(task), true); + + blink::AdTracker* ad_tracker = AdTracker::FromExecutionContext(context); + if (ad_tracker) + ad_tracker->DidCreateAsyncTask(task); } void AsyncTaskScheduledBreakable(ExecutionContext* context, const char* name, - void* task) { + AsyncTaskId* task) { AsyncTaskScheduled(context, name, task); BreakableLocation(context, name); } -void AsyncTaskCanceled(ExecutionContext* context, void* task) { +void AsyncTaskCanceled(ExecutionContext* context, AsyncTaskId* task) { AsyncTaskCanceled(context ? context->GetIsolate() : nullptr, task); } -void AsyncTaskCanceled(v8::Isolate* isolate, void* task) { - if (ThreadDebugger* debugger = ThreadDebugger::From(isolate)) - debugger->AsyncTaskCanceled(AsyncId(task)); - TRACE_EVENT_FLOW_END0("devtools.timeline.async", "AsyncTask", - TRACE_ID_LOCAL(reinterpret_cast<uintptr_t>(task))); -} - void AsyncTaskCanceledBreakable(ExecutionContext* context, const char* name, - void* task) { + AsyncTaskId* task) { AsyncTaskCanceled(context, task); BreakableLocation(context, name); }
diff --git a/third_party/blink/renderer/core/probe/core_probes.h b/third_party/blink/renderer/core/probe/core_probes.h index fd04373..71c77ef0 100644 --- a/third_party/blink/renderer/core/probe/core_probes.h +++ b/third_party/blink/renderer/core/probe/core_probes.h
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/ad_tracker.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h" @@ -52,6 +53,8 @@ namespace probe { +class AsyncTaskId; + class CORE_EXPORT ProbeBase { STACK_ALLOCATED(); @@ -70,15 +73,18 @@ public: AsyncTask(ExecutionContext*, - void* task, + AsyncTaskId* task, const char* step = nullptr, bool enabled = true); ~AsyncTask(); private: ThreadDebugger* debugger_; - void* task_; + AsyncTaskId* task_; bool recurring_; + + // This persistent is safe since the class is STACK_ALLOCATED. + Persistent<AdTracker> ad_tracker_; }; // Called from generated instrumentation code. @@ -113,15 +119,14 @@ CORE_EXPORT void AsyncTaskScheduled(ExecutionContext*, const StringView& name, - void*); + AsyncTaskId*); CORE_EXPORT void AsyncTaskScheduledBreakable(ExecutionContext*, const char* name, - void*); -CORE_EXPORT void AsyncTaskCanceled(ExecutionContext*, void*); -CORE_EXPORT void AsyncTaskCanceled(v8::Isolate*, void*); + AsyncTaskId*); +CORE_EXPORT void AsyncTaskCanceled(ExecutionContext*, AsyncTaskId*); CORE_EXPORT void AsyncTaskCanceledBreakable(ExecutionContext*, const char* name, - void*); + AsyncTaskId*); CORE_EXPORT void AllAsyncTasksCanceled(ExecutionContext*); } // namespace probe
diff --git a/third_party/blink/renderer/core/script/module_map_test.cc b/third_party/blink/renderer/core/script/module_map_test.cc index c69dd86..34a17d8 100644 --- a/third_party/blink/renderer/core/script/module_map_test.cc +++ b/third_party/blink/renderer/core/script/module_map_test.cc
@@ -117,7 +117,7 @@ TestRequest* test_request = MakeGarbageCollected<TestRequest>( ModuleScriptCreationParams( request.Url(), ParkableString(String("").ReleaseImpl()), nullptr, - request.GetResourceRequest().GetFetchCredentialsMode()), + request.GetResourceRequest().GetCredentialsMode()), client); modulator_->test_requests_.push_back(test_request); }
diff --git a/third_party/blink/renderer/core/script/script_loader.cc b/third_party/blink/renderer/core/script/script_loader.cc index 331448d..43cc578 100644 --- a/third_party/blink/renderer/core/script/script_loader.cc +++ b/third_party/blink/renderer/core/script/script_loader.cc
@@ -279,17 +279,17 @@ // https://html.spec.whatwg.org/C/#prepare-a-script // - Step 6 of obtaining a preloaded module script // https://html.spec.whatwg.org/C/#link-type-modulepreload. -network::mojom::FetchCredentialsMode ScriptLoader::ModuleScriptCredentialsMode( +network::mojom::CredentialsMode ScriptLoader::ModuleScriptCredentialsMode( CrossOriginAttributeValue cross_origin) { switch (cross_origin) { case kCrossOriginAttributeNotSet: case kCrossOriginAttributeAnonymous: - return network::mojom::FetchCredentialsMode::kSameOrigin; + return network::mojom::CredentialsMode::kSameOrigin; case kCrossOriginAttributeUseCredentials: - return network::mojom::FetchCredentialsMode::kInclude; + return network::mojom::CredentialsMode::kInclude; } NOTREACHED(); - return network::mojom::FetchCredentialsMode::kOmit; + return network::mojom::CredentialsMode::kOmit; } // https://github.com/WICG/feature-policy/issues/135 @@ -449,7 +449,7 @@ // <spec step="17">Let module script credentials mode be the module script // credentials mode for the element's crossorigin content attribute.</spec> - network::mojom::FetchCredentialsMode credentials_mode = + network::mojom::CredentialsMode credentials_mode = ModuleScriptCredentialsMode(cross_origin); // <spec step="18">Let cryptographic nonce be the element's @@ -880,23 +880,6 @@ EnumerationHistogram, scheduling_type_histogram, ("Blink.Script.SchedulingType", kLastScriptSchedulingType + 1)); scheduling_type_histogram.Count(static_cast<int>(scheduling_type)); - - switch (scheduling_type) { - case ScriptSchedulingType::kAsync: - case ScriptSchedulingType::kInOrder: - // As ClassicPendingScript keeps a reference to ScriptResource, - // the ScriptResource is anyway kept alive until evaluation, - // and can be garbage-collected after that (together with - // ClassicPendingScript). - resource_keep_alive_ = nullptr; - break; - - default: - // ScriptResource is kept alive by resource_keep_alive_ - // until ScriptLoader is garbage collected. - break; - } - PendingScript* pending_script = prepared_pending_script_; prepared_pending_script_ = nullptr; pending_script->SetSchedulingType(scheduling_type); @@ -908,6 +891,19 @@ DCHECK_EQ(pending_script_, pending_script); DCHECK_EQ(pending_script_->GetScriptType(), GetScriptType()); DCHECK(pending_script->IsControlledByScriptRunner()); + DCHECK(pending_script_->GetSchedulingType() == ScriptSchedulingType::kAsync || + pending_script_->GetSchedulingType() == + ScriptSchedulingType::kInOrder); + // Historically we clear |resource_keep_alive_| when the scheduling type is + // kAsync or kInOrder (crbug.com/778799). But if the script resource was + // served via signed exchange, the script may not be in the HTTPCache, + // therefore will need to be refetched over network if it's evicted from the + // memory cache not be in the HTTPCache. So we keep |resource_keep_alive_| to + // keep the resource in the memory cache. + if (resource_keep_alive_ && + !resource_keep_alive_->GetResponse().IsSignedExchangeInnerResponse()) { + resource_keep_alive_ = nullptr; + } Document* context_document = element_->GetDocument().ContextDocument(); if (!context_document) {
diff --git a/third_party/blink/renderer/core/script/script_loader.h b/third_party/blink/renderer/core/script/script_loader.h index 1cf0b0f5..0f0dcafa 100644 --- a/third_party/blink/renderer/core/script/script_loader.h +++ b/third_party/blink/renderer/core/script/script_loader.h
@@ -78,7 +78,7 @@ static bool BlockForNoModule(mojom::ScriptType, bool nomodule); - static network::mojom::FetchCredentialsMode ModuleScriptCredentialsMode( + static network::mojom::CredentialsMode ModuleScriptCredentialsMode( CrossOriginAttributeValue); // https://html.spec.whatwg.org/C/#prepare-a-script
diff --git a/third_party/blink/renderer/core/streams/ReadableStream.js b/third_party/blink/renderer/core/streams/ReadableStream.js index 797fe38d..b34ad33 100644 --- a/third_party/blink/renderer/core/streams/ReadableStream.js +++ b/third_party/blink/renderer/core/streams/ReadableStream.js
@@ -38,7 +38,6 @@ const internalReadableStreamSymbol = v8.createPrivateSymbol( 'internal ReadableStream in exposed ReadableStream interface'); // Remove this once C++ code has been updated to use CreateReadableStream. - const _lockNotifyTarget = v8.createPrivateSymbol('[[lockNotifyTarget]]'); const _strategySizeAlgorithm = v8.createPrivateSymbol( '[[strategySizeAlgorithm]]'); const _pullAlgorithm = v8.createPrivateSymbol('[[pullAlgorithm]]'); @@ -47,9 +46,6 @@ const CLOSE_REQUESTED = 0b10; const PULLING = 0b100; const PULL_AGAIN = 0b1000; - // TODO(ricea): Remove this once blink::UnderlyingSourceBase no longer needs - // it. - const BLINK_LOCK_NOTIFICATIONS = 0b10000; const ObjectCreate = global.Object.create; @@ -127,10 +123,10 @@ // CreateReadableStream. constructor(underlyingSource = {}, strategy = {}, internalArgument = undefined) { - const enableBlinkLockNotifications = + const createdByUA = internalArgument === createWithExternalControllerSentinel; - if (!useCounted && !enableBlinkLockNotifications) { + if (!useCounted && !createdByUA) { binding.countUse('ReadableStreamConstructor'); useCounted = true; } @@ -157,8 +153,7 @@ highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark); SetUpReadableStreamDefaultControllerFromUnderlyingSource( - this, underlyingSource, highWaterMark, sizeAlgorithm, - enableBlinkLockNotifications); + this, underlyingSource, highWaterMark, sizeAlgorithm); } } @@ -381,11 +376,8 @@ return new ReadableStreamDefaultReader(stream); } - // The non-standard boolean |enableBlinkLockNotifications| argument indicates - // whether the stream is being created from C++. function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, - highWaterMark, sizeAlgorithm, - enableBlinkLockNotifications) { + highWaterMark, sizeAlgorithm) { if (highWaterMark === undefined) { highWaterMark = 1; } @@ -399,7 +391,7 @@ const controller = ObjectCreate(ReadableStreamDefaultController_prototype); SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, - highWaterMark, sizeAlgorithm, enableBlinkLockNotifications); + highWaterMark, sizeAlgorithm); return stream; } @@ -490,11 +482,9 @@ const startAlgorithm = () => undefined; const branch1Stream = CreateReadableStream( - startAlgorithm, pullAlgorithm, cancel1Algorithm, undefined, undefined, - false); + startAlgorithm, pullAlgorithm, cancel1Algorithm); const branch2Stream = CreateReadableStream( - startAlgorithm, pullAlgorithm, cancel2Algorithm, undefined, undefined, - false); + startAlgorithm, pullAlgorithm, cancel2Algorithm); const branch1controller = branch1Stream[_controller]; const branch2controller = branch2Stream[_controller]; @@ -695,17 +685,6 @@ } function ReadableStreamReaderGenericInitialize(reader, stream) { - // TODO(yhirano): Remove this when we don't need hasPendingActivity in - // blink::UnderlyingSourceBase. - const controller = stream[_controller]; - if (controller[_readableStreamDefaultControllerBits] & - BLINK_LOCK_NOTIFICATIONS) { - // The stream is created with an external controller (i.e. made in - // Blink). - const lockNotifyTarget = controller[_lockNotifyTarget]; - callFunction(lockNotifyTarget.notifyLockAcquired, lockNotifyTarget); - } - reader[_ownerReadableStream] = stream; stream[_reader] = reader; @@ -724,17 +703,6 @@ } function ReadableStreamReaderGenericRelease(reader) { - // TODO(yhirano): Remove this when we don't need hasPendingActivity in - // blink::UnderlyingSourceBase. - const controller = reader[_ownerReadableStream][_controller]; - if (controller[_readableStreamDefaultControllerBits] & - BLINK_LOCK_NOTIFICATIONS) { - // The stream is created with an external controller (i.e. made in - // Blink). - const lockNotifyTarget = controller[_lockNotifyTarget]; - callFunction(lockNotifyTarget.notifyLockReleased, lockNotifyTarget); - } - if (ReadableStreamGetState(reader[_ownerReadableStream]) === STATE_READABLE) { rejectPromise( @@ -1000,12 +968,10 @@ function SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, - highWaterMark, sizeAlgorithm, enableBlinkLockNotifications) { + highWaterMark, sizeAlgorithm) { controller[_controlledReadableStream] = stream; controller[_queue] = new binding.SimpleQueue(); controller[_queueTotalSize] = 0; - controller[_readableStreamDefaultControllerBits] = - enableBlinkLockNotifications ? BLINK_LOCK_NOTIFICATIONS : 0b0; controller[_strategySizeAlgorithm] = sizeAlgorithm; controller[_strategyHWM] = highWaterMark; controller[_pullAlgorithm] = pullAlgorithm; @@ -1019,8 +985,7 @@ } function SetUpReadableStreamDefaultControllerFromUnderlyingSource( - stream, underlyingSource, highWaterMark, sizeAlgorithm, - enableBlinkLockNotifications) { + stream, underlyingSource, highWaterMark, sizeAlgorithm) { const controller = ObjectCreate(ReadableStreamDefaultController_prototype); const startAlgorithm = () => CallOrNoop1(underlyingSource, 'start', controller, @@ -1029,13 +994,9 @@ underlyingSource, 'pull', 0, controller, 'underlyingSource.pull'); const cancelAlgorithm = CreateAlgorithmFromUnderlyingMethod( underlyingSource, 'cancel', 1, 'underlyingSource.cancel'); - // TODO(ricea): Remove this once C++ API has been updated. - if (enableBlinkLockNotifications) { - controller[_lockNotifyTarget] = underlyingSource; - } SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, - highWaterMark, sizeAlgorithm, enableBlinkLockNotifications); + highWaterMark, sizeAlgorithm); } //
diff --git a/third_party/blink/renderer/core/streams/TransformStream.js b/third_party/blink/renderer/core/streams/TransformStream.js index 4b74495..639be9b 100644 --- a/third_party/blink/renderer/core/streams/TransformStream.js +++ b/third_party/blink/renderer/core/streams/TransformStream.js
@@ -193,7 +193,7 @@ }; stream[_readable] = binding.CreateReadableStream( startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, - readableSizeAlgorithm, false); + readableSizeAlgorithm); stream[_backpressure] = undefined; stream[_backpressureChangePromise] = undefined; TransformStreamSetBackpressure(stream, true);
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc b/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc index b5fca42..653cab0 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
@@ -271,7 +271,6 @@ visitor->Trace(pull_algorithm_); visitor->Trace(queue_); visitor->Trace(strategy_size_algorithm_); - visitor->Trace(lock_notify_target_); ScriptWrappable::Trace(visitor); } @@ -494,7 +493,6 @@ StreamAlgorithm* cancel_algorithm, double high_water_mark, StrategySizeAlgorithm* size_algorithm, - bool enable_blink_lock_notifications, ExceptionState& exception_state) { // https://streams.spec.whatwg.org/#set-up-readable-stream-default-controller // 1. Assert: stream.[[readableStreamController]] is undefined. @@ -510,10 +508,6 @@ DCHECK(controller->queue_->IsEmpty()); DCHECK_EQ(controller->queue_->TotalSize(), 0); - // Not part of the standard. - controller->enable_blink_lock_notifications_ = - enable_blink_lock_notifications; - // 5. Set controller.[[strategySizeAlgorithm]] to sizeAlgorithm and // controller.[[strategyHWM]] to highWaterMark. controller->strategy_size_algorithm_ = size_algorithm; @@ -610,7 +604,6 @@ v8::Local<v8::Object> underlying_source, double high_water_mark, StrategySizeAlgorithm* size_algorithm, - bool enable_blink_lock_notifications, ExceptionState& exception_state) { // https://streams.spec.whatwg.org/#set-up-readable-stream-default-controller-from-underlying-source // 2. Let controller be ObjectCreate(the original value of @@ -646,18 +639,11 @@ return; } - // TODO(ricea): Remove this once C++ API has been updated. - if (enable_blink_lock_notifications) { - controller->lock_notify_target_.Set(script_state->GetIsolate(), - underlying_source); - } - // 6. Perform ? SetUpReadableStreamDefaultController(stream, controller, // startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, // sizeAlgorithm). SetUp(script_state, stream, controller, start_algorithm, pull_algorithm, - cancel_algorithm, high_water_mark, size_algorithm, - enable_blink_lock_notifications, exception_state); + cancel_algorithm, high_water_mark, size_algorithm, exception_state); } } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller.h b/third_party/blink/renderer/core/streams/readable_stream_default_controller.h index 14e8bec..0a14d94 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_controller.h +++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
@@ -100,7 +100,6 @@ StreamAlgorithm* cancel_algorithm, double high_water_mark, StrategySizeAlgorithm* size_algorithm, - bool enable_blink_lock_notifications, ExceptionState&); // https://streams.spec.whatwg.org/#set-up-readable-stream-default-controller-from-underlying-source @@ -109,7 +108,6 @@ v8::Local<v8::Object> underlying_source, double high_water_mark, StrategySizeAlgorithm* size_algorithm, - bool enable_blink_lock_notifications, ExceptionState&); // Boolean flags are grouped together to reduce object size. Verbs have been @@ -118,14 +116,12 @@ bool will_pull_again_ = false; bool is_pulling_ = false; bool is_started_ = false; - bool enable_blink_lock_notifications_ = false; Member<StreamAlgorithm> cancel_algorithm_; Member<ReadableStreamNative> controlled_readable_stream_; Member<StreamAlgorithm> pull_algorithm_; Member<QueueWithSizes> queue_; double strategy_high_water_mark_ = 0.0; Member<StrategySizeAlgorithm> strategy_size_algorithm_; - TraceWrapperV8Reference<v8::Object> lock_notify_target_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.cc b/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.cc index 6abdeda..91fe704 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.cc
@@ -31,8 +31,6 @@ // (close/desiredSize/enqueue/error will become no-ops afterward.) void NoteHasBeenCanceled() override { js_controller_.Clear(); } - bool IsActive() const override { return !js_controller_.IsEmpty(); } - void Close() override { ScriptState* script_state = script_state_; // This will assert that the context is valid; do not call this method when @@ -129,8 +127,6 @@ void NoteHasBeenCanceled() override { controller_ = nullptr; } - bool IsActive() const override { return controller_; } - void Close() override { if (!controller_) return; @@ -138,6 +134,7 @@ ScriptState::Scope scope(script_state_); ReadableStreamDefaultController::Close(script_state_, controller_); + controller_ = nullptr; } double DesiredSize() const override { @@ -173,6 +170,7 @@ ReadableStreamDefaultController::Error(script_state_, controller_, js_error); + controller_ = nullptr; } void Trace(Visitor* visitor) override {
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.h b/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.h index bfdb804..7d859463 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.h +++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.h
@@ -33,7 +33,6 @@ // (Close/DesiredSize/Enqueue/Error will become no-ops afterward.) virtual void NoteHasBeenCanceled() = 0; - virtual bool IsActive() const = 0; virtual void Close() = 0; virtual double DesiredSize() const = 0; virtual void Enqueue(v8::Local<v8::Value> js_chunk) const = 0;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_native.cc b/third_party/blink/renderer/core/streams/readable_stream_native.cc index 1828317..632ea367 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_native.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_native.cc
@@ -1047,8 +1047,7 @@ // sizeAlgorithm). ReadableStreamDefaultController::SetUp( script_state, stream, controller, start_algorithm, pull_algorithm, - cancel_algorithm, high_water_mark, size_algorithm, false, - exception_state); + cancel_algorithm, high_water_mark, size_algorithm, exception_state); if (exception_state.HadException()) { return nullptr; } @@ -1059,14 +1058,12 @@ ReadableStreamNative::ReadableStreamNative() = default; -// TODO(ricea): Remove |enable_blink_lock_notifications| once -// blink::ReadableStreamOperations has been updated to use CreateReadableStream. ReadableStreamNative::ReadableStreamNative(ScriptState* script_state, ScriptValue raw_underlying_source, ScriptValue raw_strategy, - bool enable_blink_lock_notifications, + bool created_by_ua, ExceptionState& exception_state) { - if (!enable_blink_lock_notifications) { + if (!created_by_ua) { // TODO(ricea): Move this to IDL once blink::ReadableStreamOperations is // no longer using the public constructor. UseCounter::Count(ExecutionContext::From(script_state), @@ -1151,7 +1148,7 @@ // (this, underlyingSource, highWaterMark, sizeAlgorithm). ReadableStreamDefaultController::SetUpFromUnderlyingSource( script_state, this, underlying_source, high_water_mark, size_algorithm, - enable_blink_lock_notifications, exception_state); + exception_state); } ReadableStreamNative::~ReadableStreamNative() = default;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_native.h b/third_party/blink/renderer/core/streams/readable_stream_native.h index 9cd1fea..ee1b87d9d 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_native.h +++ b/third_party/blink/renderer/core/streams/readable_stream_native.h
@@ -67,14 +67,11 @@ ReadableStreamNative(); - // TODO(ricea): Remove |enable_blink_lock_notifications| once - // blink::ReadableStreamOperations has been updated to use - // CreateReadableStream. // https://streams.spec.whatwg.org/#rs-constructor ReadableStreamNative(ScriptState*, ScriptValue raw_underlying_source, ScriptValue raw_strategy, - bool enable_blink_lock_notifications, + bool created_by_ua, ExceptionState&); ~ReadableStreamNative() override;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc b/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc index 195292d..cca17f36 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc
@@ -368,46 +368,6 @@ EXPECT_TRUE(it3->IsDone()); } -TEST(ReadableStreamOperationsTest, - UnderlyingSourceShouldHavePendingActivityWhenLockedAndControllerIsActive) { - V8TestingScope scope; - TryCatchScope try_catch_scope(scope.GetIsolate()); - auto* underlying_source = - MakeGarbageCollected<TestUnderlyingSource>(scope.GetScriptState()); - - ScriptValue strategy = ReadableStreamOperations::CreateCountQueuingStrategy( - scope.GetScriptState(), 10); - ASSERT_FALSE(strategy.IsEmpty()); - - ScriptValue internal_stream = ReadableStreamOperations::CreateReadableStream( - scope.GetScriptState(), underlying_source, strategy); - ASSERT_FALSE(internal_stream.IsEmpty()); - - CHECK(!RuntimeEnabledFeatures::StreamsNativeEnabled()); - auto* stream = ReadableStreamWrapper::CreateFromInternalStream( - scope.GetScriptState(), internal_stream, ASSERT_NO_EXCEPTION); - ASSERT_TRUE(stream); - - v8::Local<v8::Object> global = scope.GetScriptState()->GetContext()->Global(); - ASSERT_TRUE(global - ->Set(scope.GetContext(), - V8String(scope.GetIsolate(), "stream"), - ToV8(stream, scope.GetScriptState())) - .IsJust()); - - EXPECT_FALSE(underlying_source->HasPendingActivity()); - EvalWithPrintingError(&scope, "let reader = stream.getReader();"); - EXPECT_TRUE(underlying_source->HasPendingActivity()); - EvalWithPrintingError(&scope, "reader.releaseLock();"); - EXPECT_FALSE(underlying_source->HasPendingActivity()); - EvalWithPrintingError(&scope, "reader = stream.getReader();"); - EXPECT_TRUE(underlying_source->HasPendingActivity()); - underlying_source->Enqueue( - ScriptValue(scope.GetScriptState(), v8::Undefined(scope.GetIsolate()))); - underlying_source->Close(); - EXPECT_FALSE(underlying_source->HasPendingActivity()); -} - TEST(ReadableStreamOperationsTest, IsReadable) { V8TestingScope scope; TryCatchScope try_catch_scope(scope.GetIsolate());
diff --git a/third_party/blink/renderer/core/streams/readable_stream_reader.cc b/third_party/blink/renderer/core/streams/readable_stream_reader.cc index 7396853..66b5a1a 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_reader.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_reader.cc
@@ -170,16 +170,6 @@ DCHECK_EQ(reader->owner_readable_stream_->reader_, reader); auto* isolate = script_state->GetIsolate(); - // TODO(yhirano): Remove this when we don"t need hasPendingActivity in - // blink::UnderlyingSourceBase. - ReadableStreamDefaultController* controller = - reader->owner_readable_stream_->readable_stream_controller_; - if (controller->enable_blink_lock_notifications_) { - // The stream is created with an external controller (i.e. made in - // Blink). - auto lock_notify_target = controller->lock_notify_target_.NewLocal(isolate); - CallNullaryMethod(script_state, lock_notify_target, "notifyLockReleased"); - } // 3. If reader.[[ownerReadableStream]].[[state]] is "readable", reject // reader.[[closedPromise]] with a TypeError exception. @@ -237,17 +227,6 @@ ReadableStreamReader* reader, ReadableStreamNative* stream) { auto* isolate = script_state->GetIsolate(); - // TODO(yhirano): Remove this when we don't need hasPendingActivity in - // blink::UnderlyingSourceBase. - ReadableStreamDefaultController* controller = - stream->readable_stream_controller_; - if (controller->enable_blink_lock_notifications_) { - // The stream is created with an external controller (i.e. made in - // Blink). - v8::Local<v8::Object> lock_notify_target = - controller->lock_notify_target_.NewLocal(isolate); - CallNullaryMethod(script_state, lock_notify_target, "notifyLockAcquired"); - } // https://streams.spec.whatwg.org/#readable-stream-reader-generic-initialize // 1. Set reader.[[forAuthorCode]] to true. @@ -290,32 +269,4 @@ } } -void ReadableStreamReader::CallNullaryMethod(ScriptState* script_state, - v8::Local<v8::Object> object, - const char* method_name) { - auto* isolate = script_state->GetIsolate(); - auto context = script_state->GetContext(); - v8::TryCatch try_catch(isolate); - v8::Local<v8::Value> method; - if (!object->Get(context, V8AtomicString(isolate, method_name)) - .ToLocal(&method)) { - DLOG(WARNING) << "Ignored failed lookup of '" << method_name - << "' in CallNullaryMethod"; - return; - } - - if (!method->IsFunction()) { - DLOG(WARNING) << "Didn't call '" << method_name - << "' in CallNullaryMethod because it was the wrong type"; - return; - } - - v8::MaybeLocal<v8::Value> result = - method.As<v8::Function>()->Call(context, object, 0, nullptr); - if (result.IsEmpty()) { - DLOG(WARNING) << "Ignored failure of '" << method_name - << "' in CallNullaryMethod"; - } -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_reader.h b/third_party/blink/renderer/core/streams/readable_stream_reader.h index 6099dca..ba10bef 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_reader.h +++ b/third_party/blink/renderer/core/streams/readable_stream_reader.h
@@ -82,12 +82,6 @@ ReadableStreamReader*, ReadableStreamNative*); - // Calls method |method_name| on |object|, passing no arguments, and ignoring - // errors. Used for Blink lock notifications. - static void CallNullaryMethod(ScriptState*, - v8::Local<v8::Object> object, - const char* method_name); - Member<StreamPromiseResolver> closed_promise_; bool for_author_code_ = true; Member<ReadableStreamNative> owner_readable_stream_;
diff --git a/third_party/blink/renderer/core/streams/underlying_source_base.cc b/third_party/blink/renderer/core/streams/underlying_source_base.cc index 6e4ccc9..9efc0fe 100644 --- a/third_party/blink/renderer/core/streams/underlying_source_base.cc +++ b/third_party/blink/renderer/core/streams/underlying_source_base.cc
@@ -47,22 +47,6 @@ return ScriptValue(script_state, v8::Undefined(script_state->GetIsolate())); } -void UnderlyingSourceBase::notifyLockAcquired() { - is_stream_locked_ = true; -} - -void UnderlyingSourceBase::notifyLockReleased() { - is_stream_locked_ = false; -} - -bool UnderlyingSourceBase::HasPendingActivity() const { - // This will return false within a finite time period _assuming_ that - // consumers use the controller to close or error the stream. - // Browser-created readable streams should always close or error within a - // finite time period, due to timeouts etc. - return controller_ && controller_->IsActive() && is_stream_locked_; -} - void UnderlyingSourceBase::ContextDestroyed(ExecutionContext*) { if (controller_) { controller_->NoteHasBeenCanceled();
diff --git a/third_party/blink/renderer/core/streams/underlying_source_base.h b/third_party/blink/renderer/core/streams/underlying_source_base.h index 55abd8e..664f30e8 100644 --- a/third_party/blink/renderer/core/streams/underlying_source_base.h +++ b/third_party/blink/renderer/core/streams/underlying_source_base.h
@@ -22,7 +22,6 @@ class CORE_EXPORT UnderlyingSourceBase : public ScriptWrappable, - public ActiveScriptWrappable<UnderlyingSourceBase>, public ContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(UnderlyingSourceBase); @@ -41,13 +40,8 @@ ScriptValue type(ScriptState*) const; - void notifyLockAcquired(); - void notifyLockReleased(); - - // ScriptWrappable - bool HasPendingActivity() const override; - // ContextLifecycleObserver + // TODO(ricea): Is this still useful? void ContextDestroyed(ExecutionContext*) override; protected: @@ -60,7 +54,6 @@ private: Member<ReadableStreamDefaultControllerInterface> controller_; - bool is_stream_locked_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/underlying_source_base.idl b/third_party/blink/renderer/core/streams/underlying_source_base.idl index d943658b..bdf1131 100644 --- a/third_party/blink/renderer/core/streams/underlying_source_base.idl +++ b/third_party/blink/renderer/core/streams/underlying_source_base.idl
@@ -8,7 +8,6 @@ // automatically for use in initializing a ReadableStream. [ - ActiveScriptWrappable, NoInterfaceObject ] interface UnderlyingSourceBase { @@ -18,7 +17,4 @@ // This only exists to prevent Object.prototype.type being accessed. [CallWith=ScriptState] readonly attribute any type; - - void notifyLockAcquired(); - void notifyLockReleased(); };
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 11a41817..cec12c8b6 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -871,6 +871,7 @@ } bool SetEffectiveZoom(float); + float EffectiveZoom() const; // -webkit-clip-path bool ClipPathDataEquivalent(const ComputedStyle& other) const { @@ -2722,10 +2723,14 @@ float clamped_effective_zoom = clampTo<float>(f, 1e-6, 1e6); if (EffectiveZoom() == clamped_effective_zoom) return false; - SetEffectiveZoomInternal(clamped_effective_zoom); + SetInternalEffectiveZoom(clamped_effective_zoom); return true; } +inline float ComputedStyle::EffectiveZoom() const { + return InternalEffectiveZoom(); +} + inline bool ComputedStyle::HasAnyPublicPseudoStyles() const { return PseudoBitsInternal() != kPseudoIdNone; }
diff --git a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 index 42896ae..36e484b 100644 --- a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 +++ b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -84,7 +84,7 @@ "-webkit-margin-before-collapse", "-webkit-margin-after-collapse", "-webkit-line-clamp", "text-overflow", "shape-margin", "order", "-webkit-highlight", - "text-indent", "text-align-last", "TextIndentLine", "EffectiveZoom", + "text-indent", "text-align-last", "TextIndentLine", "-internal-effective-zoom", "word-break", "overflow-wrap", "-webkit-line-break", "-webkit-text-security", "hyphens", "HyphenationLimitBefore", "HyphenationLimitAfter", "-webkit-hyphenate-character",
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 index 09fcdce..e9af136 100644 --- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 +++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -297,15 +297,6 @@ computed_style_custom_functions: ["getter", "setter"], }, { - name: "EffectiveZoom", - inherited: true, - field_template: "primitive", - type_name: "float", - default_value: "1.0f", - field_group: "*", - computed_style_custom_functions: ["setter"], - }, - { name: "TextStrokeColorIsCurrentColor", inherited: true, field_template: "primitive",
diff --git a/third_party/blink/renderer/core/svg/svg_a_element.h b/third_party/blink/renderer/core/svg/svg_a_element.h index 0302bca..19cfd753 100644 --- a/third_party/blink/renderer/core/svg/svg_a_element.h +++ b/third_party/blink/renderer/core/svg/svg_a_element.h
@@ -38,6 +38,10 @@ explicit SVGAElement(Document&); + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private:
diff --git a/third_party/blink/renderer/core/svg/svg_fe_image_element.h b/third_party/blink/renderer/core/svg/svg_fe_image_element.h index af5dcd70..a21fb8e 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_image_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_image_element.h
@@ -46,6 +46,10 @@ return preserve_aspect_ratio_.Get(); } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + // Promptly remove as a ImageResource client. EAGERLY_FINALIZE(); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/svg/svg_filter_element.h b/third_party/blink/renderer/core/svg/svg_filter_element.h index 02c1c25..46c123b 100644 --- a/third_party/blink/renderer/core/svg/svg_filter_element.h +++ b/third_party/blink/renderer/core/svg/svg_filter_element.h
@@ -68,6 +68,10 @@ // Get the associated SVGResource object, if any. LocalSVGResource* AssociatedResource() const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + private: void SvgAttributeChanged(const QualifiedName&) override; void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/blink/renderer/core/svg/svg_gradient_element.h b/third_party/blink/renderer/core/svg/svg_gradient_element.h index 0376e5d..4fac3d3 100644 --- a/third_party/blink/renderer/core/svg/svg_gradient_element.h +++ b/third_party/blink/renderer/core/svg/svg_gradient_element.h
@@ -64,6 +64,10 @@ const SVGGradientElement* ReferencedElement() const; void CollectCommonAttributes(GradientAttributes&) const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; protected:
diff --git a/third_party/blink/renderer/core/svg/svg_image_element.h b/third_party/blink/renderer/core/svg/svg_image_element.h index 7c7c3ee0..b5e3a36 100644 --- a/third_party/blink/renderer/core/svg/svg_image_element.h +++ b/third_party/blink/renderer/core/svg/svg_image_element.h
@@ -78,6 +78,10 @@ GetImageLoader().SetImageForTest(content); } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + private: bool IsStructurallyExternal() const override { return !HrefString().IsNull();
diff --git a/third_party/blink/renderer/core/svg/svg_mpath_element.h b/third_party/blink/renderer/core/svg/svg_mpath_element.h index ee6fa88..59e2871 100644 --- a/third_party/blink/renderer/core/svg/svg_mpath_element.h +++ b/third_party/blink/renderer/core/svg/svg_mpath_element.h
@@ -39,6 +39,10 @@ void TargetPathChanged(); + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private:
diff --git a/third_party/blink/renderer/core/svg/svg_pattern_element.h b/third_party/blink/renderer/core/svg/svg_pattern_element.h index 45b7af1..1a4e2cbf 100644 --- a/third_party/blink/renderer/core/svg/svg_pattern_element.h +++ b/third_party/blink/renderer/core/svg/svg_pattern_element.h
@@ -80,6 +80,10 @@ const SVGPatternElement* ReferencedElement() const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private:
diff --git a/third_party/blink/renderer/core/svg/svg_resource.cc b/third_party/blink/renderer/core/svg/svg_resource.cc index d767e45..9421f73 100644 --- a/third_party/blink/renderer/core/svg/svg_resource.cc +++ b/third_party/blink/renderer/core/svg/svg_resource.cc
@@ -128,8 +128,8 @@ ResourceLoaderOptions options; options.initiator_info.name = fetch_initiator_type_names::kCSS; FetchParameters params(ResourceRequest(url_), options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); resource_document_ = DocumentResource::FetchSVGDocument(params, document.Fetcher(), this); target_ = ResolveTarget();
diff --git a/third_party/blink/renderer/core/svg/svg_script_element.cc b/third_party/blink/renderer/core/svg/svg_script_element.cc index 5d3ac543..0147e9df 100644 --- a/third_party/blink/renderer/core/svg/svg_script_element.cc +++ b/third_party/blink/renderer/core/svg/svg_script_element.cc
@@ -173,6 +173,16 @@ } #endif +const AttrNameToTrustedType& SVGScriptElement::GetCheckedAttributeTypes() + const { + DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map, + ({ + {svg_names::kHrefAttr.LocalName(), + SpecificTrustedType::kTrustedScriptURL}, + })); + return attribute_map; +} + void SVGScriptElement::Trace(blink::Visitor* visitor) { visitor->Trace(loader_); SVGElement::Trace(visitor);
diff --git a/third_party/blink/renderer/core/svg/svg_script_element.h b/third_party/blink/renderer/core/svg/svg_script_element.h index c1222ee2..cb4b1763 100644 --- a/third_party/blink/renderer/core/svg/svg_script_element.h +++ b/third_party/blink/renderer/core/svg/svg_script_element.h
@@ -49,6 +49,8 @@ bool IsScriptElement() const override { return true; } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override; + void Trace(blink::Visitor*) override; private:
diff --git a/third_party/blink/renderer/core/svg/svg_text_path_element.h b/third_party/blink/renderer/core/svg/svg_text_path_element.h index 0576602..17c7f3c8 100644 --- a/third_party/blink/renderer/core/svg/svg_text_path_element.h +++ b/third_party/blink/renderer/core/svg/svg_text_path_element.h
@@ -66,6 +66,10 @@ return spacing_.Get(); } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private:
diff --git a/third_party/blink/renderer/core/svg/svg_uri_reference.cc b/third_party/blink/renderer/core/svg/svg_uri_reference.cc index 99471e10..3153f223 100644 --- a/third_party/blink/renderer/core/svg/svg_uri_reference.cc +++ b/third_party/blink/renderer/core/svg/svg_uri_reference.cc
@@ -151,4 +151,13 @@ observer = nullptr; } +const AttrNameToTrustedType& SVGURIReference::GetCheckedAttributeTypes() const { + DEFINE_STATIC_LOCAL( + AttrNameToTrustedType, attribute_map, + ({ + {svg_names::kHrefAttr.LocalName(), SpecificTrustedType::kTrustedURL}, + })); + return attribute_map; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_uri_reference.h b/third_party/blink/renderer/core/svg/svg_uri_reference.h index 9b0d505..b15cb9d5 100644 --- a/third_party/blink/renderer/core/svg/svg_uri_reference.h +++ b/third_party/blink/renderer/core/svg/svg_uri_reference.h
@@ -24,6 +24,7 @@ #include <memory> #include "base/callback.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/svg/svg_animated_href.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -31,7 +32,6 @@ namespace blink { class Document; -class Element; class IdTargetObserver; class SVGElement; class TreeScope; @@ -81,6 +81,8 @@ // JS API SVGAnimatedHref* href() const { return href_.Get(); } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const; + void Trace(blink::Visitor*) override; protected:
diff --git a/third_party/blink/renderer/core/svg/svg_use_element.cc b/third_party/blink/renderer/core/svg/svg_use_element.cc index cdfdda9..86b6df14 100644 --- a/third_party/blink/renderer/core/svg/svg_use_element.cc +++ b/third_party/blink/renderer/core/svg/svg_use_element.cc
@@ -204,8 +204,8 @@ ResourceLoaderOptions options; options.initiator_info.name = localName(); FetchParameters params(ResourceRequest(element_url_), options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); DocumentResource::FetchSVGDocument(params, GetDocument().Fetcher(), this); }
diff --git a/third_party/blink/renderer/core/svg/svg_use_element.h b/third_party/blink/renderer/core/svg/svg_use_element.h index 7c40606..b1ce459 100644 --- a/third_party/blink/renderer/core/svg/svg_use_element.h +++ b/third_party/blink/renderer/core/svg/svg_use_element.h
@@ -59,6 +59,10 @@ void DispatchPendingEvent(); Path ToClipPath() const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private:
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc index ea8ed8d0..695d0dd2 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc +++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
@@ -171,6 +171,8 @@ const ExecutionContext* execution_context, ExceptionState& exception_state) { switch (specific_trusted_type) { + case SpecificTrustedType::kNone: + return GetStringFromTrustedTypeWithoutCheck(string_or_trusted_type); case SpecificTrustedType::kTrustedHTML: { StringOrTrustedHTML string_or_trusted_html = string_or_trusted_type.IsTrustedHTML()
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h index 4dac44bb..31c9f6ce 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h +++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
@@ -21,6 +21,7 @@ class USVStringOrTrustedURL; enum class SpecificTrustedType { + kNone, kTrustedHTML, kTrustedScript, kTrustedScriptURL,
diff --git a/third_party/blink/renderer/core/url/dom_url_utils.cc b/third_party/blink/renderer/core/url/dom_url_utils.cc index 6e05c1b..50dcb710 100644 --- a/third_party/blink/renderer/core/url/dom_url_utils.cc +++ b/third_party/blink/renderer/core/url/dom_url_utils.cc
@@ -97,8 +97,10 @@ KURL kurl = Url(); if (!kurl.CanSetHostOrPort()) return; - - kurl.SetPort(value); + if (!value.IsEmpty()) + kurl.SetPort(value); + else + kurl.RemovePort(); SetURL(kurl); }
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc index 5738e86..8c51ceb1 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -217,7 +217,7 @@ // For module script, respect the credentials mode specified by // WorkerOptions. // https://html.spec.whatwg.org/C/#workeroptions - auto credentials_mode = network::mojom::FetchCredentialsMode::kSameOrigin; + auto credentials_mode = network::mojom::CredentialsMode::kSameOrigin; if (options_->type() == "module") { bool result = Request::ParseCredentialsMode(options_->credentials(), &credentials_mode); @@ -261,8 +261,8 @@ classic_script_loader_->LoadTopLevelScriptAsynchronously( *GetExecutionContext(), GetExecutionContext()->Fetcher(), script_request_url_, mojom::RequestContextType::WORKER, - network::mojom::FetchRequestMode::kSameOrigin, - network::mojom::FetchCredentialsMode::kSameOrigin, + network::mojom::RequestMode::kSameOrigin, + network::mojom::CredentialsMode::kSameOrigin, WTF::Bind(&DedicatedWorker::OnResponse, WrapPersistent(this)), WTF::Bind(&DedicatedWorker::OnFinished, WrapPersistent(this))); return;
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc index faa4b04..8e875339 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -172,8 +172,8 @@ *this, CreateOutsideSettingsFetcher(outside_settings_object, outside_resource_timing_notifier), - script_url, destination, network::mojom::FetchRequestMode::kSameOrigin, - network::mojom::FetchCredentialsMode::kSameOrigin, + script_url, destination, network::mojom::RequestMode::kSameOrigin, + network::mojom::CredentialsMode::kSameOrigin, WTF::Bind(&DedicatedWorkerGlobalScope::DidReceiveResponseForClassicScript, WrapWeakPersistent(this), WrapPersistent(classic_script_loader)), @@ -187,7 +187,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { // Step 12: "Let destination be "sharedworker" if is shared is true, and // "worker" otherwise." mojom::RequestContextType destination = mojom::RequestContextType::WORKER;
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h index 36bcb564..a2942ee5 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -90,7 +90,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode) override; + network::mojom::CredentialsMode) override; // Called by the bindings (dedicated_worker_global_scope.idl). const String name() const;
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc index d3be111..03063be 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
@@ -86,7 +86,7 @@ // "module: Fetch a module worker script graph given url, outside settings, // destination, the value of the credentials member of options, and inside // settings." - network::mojom::FetchCredentialsMode credentials_mode; + network::mojom::CredentialsMode credentials_mode; bool result = Request::ParseCredentialsMode(options->credentials(), &credentials_mode); DCHECK(result);
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc index ef0dd36..50c9c904 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
@@ -162,8 +162,8 @@ *this, CreateOutsideSettingsFetcher(outside_settings_object, outside_resource_timing_notifier), - script_url, destination, network::mojom::FetchRequestMode::kSameOrigin, - network::mojom::FetchCredentialsMode::kSameOrigin, + script_url, destination, network::mojom::RequestMode::kSameOrigin, + network::mojom::CredentialsMode::kSameOrigin, WTF::Bind(&SharedWorkerGlobalScope::DidReceiveResponseForClassicScript, WrapWeakPersistent(this), WrapPersistent(classic_script_loader)), @@ -177,7 +177,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { // Step 12: "Let destination be "sharedworker" if is shared is true, and // "worker" otherwise."
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h index fbb2dcb..7e6f70f 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
@@ -82,7 +82,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode) override; + network::mojom::CredentialsMode) override; // shared_worker_global_scope.idl const String name() const;
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc index 2ee386c6..dc29d2a 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
@@ -88,7 +88,7 @@ void ThreadedWorkletMessagingProxy::FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h index 1ca2d5a..6fb7f94 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h +++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
@@ -25,7 +25,7 @@ // WorkletGlobalScopeProxy implementation. void FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc index 6cea20dd..74dad39 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc
@@ -27,7 +27,7 @@ void ThreadedWorkletObjectProxy::FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, std::unique_ptr<CrossThreadFetchClientSettingsObjectData> outside_settings_object, WorkerResourceTimingNotifier* outside_resource_timing_notifier,
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h index e5b6091..ee717bd 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h +++ b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h
@@ -37,7 +37,7 @@ void FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, std::unique_ptr<CrossThreadFetchClientSettingsObjectData> outside_settings_object, WorkerResourceTimingNotifier* outside_resource_timing_notifier,
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc index c51ae114..873bf34 100644 --- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc +++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
@@ -134,8 +134,8 @@ ResourceFetcher* fetch_client_settings_object_fetcher, const KURL& url, mojom::RequestContextType request_context, - network::mojom::FetchRequestMode fetch_request_mode, - network::mojom::FetchCredentialsMode fetch_credentials_mode, + network::mojom::RequestMode request_mode, + network::mojom::CredentialsMode credentials_mode, base::OnceClosure response_callback, base::OnceClosure finished_callback) { DCHECK(fetch_client_settings_object_fetcher); @@ -153,8 +153,8 @@ .GetFetchClientSettingsObject() .GetAddressSpace()); request.SetRequestContext(request_context); - request.SetFetchRequestMode(fetch_request_mode); - request.SetFetchCredentialsMode(fetch_credentials_mode); + request.SetMode(request_mode); + request.SetCredentialsMode(credentials_mode); need_to_cancel_ = true; threadable_loader_ = MakeGarbageCollected<ThreadableLoader>(
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.h b/third_party/blink/renderer/core/workers/worker_classic_script_loader.h index 93e2689eb..ed7040f3 100644 --- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.h +++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.h
@@ -76,8 +76,8 @@ ResourceFetcher* fetch_client_settings_object_fetcher, const KURL&, mojom::RequestContextType, - network::mojom::FetchRequestMode, - network::mojom::FetchCredentialsMode, + network::mojom::RequestMode, + network::mojom::CredentialsMode, base::OnceClosure response_callback, base::OnceClosure finished_callback);
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h index 274d8cdd..4a8ad69 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -183,7 +183,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode) = 0; + network::mojom::CredentialsMode) = 0; void ReceiveMessage(BlinkTransferableMessage); base::TimeTicks TimeOrigin() const { return time_origin_; }
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc index 0dfa5b3..2c0c166 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -429,7 +429,7 @@ const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, WorkerResourceTimingNotifier& resource_timing_notifier, mojom::RequestContextType destination, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, ModuleScriptCustomFetchType custom_fetch_type, ModuleTreeClient* client) { // Step 2: "Let options be a script fetch options whose cryptographic nonce is
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h index 892e2d45..2184df6 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -156,7 +156,7 @@ const FetchClientSettingsObjectSnapshot&, WorkerResourceTimingNotifier&, mojom::RequestContextType destination, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, ModuleScriptCustomFetchType, ModuleTreeClient*);
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc index d20c373..6bbe756c 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.cc +++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -212,7 +212,7 @@ const KURL& script_url, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_); PostCrossThreadTask( *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE, @@ -611,7 +611,7 @@ std::unique_ptr<CrossThreadFetchClientSettingsObjectData> outside_settings_object, WorkerResourceTimingNotifier* outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { DCHECK(outside_resource_timing_notifier); // Worklets have a different code path to import module scripts. // TODO(nhiroki): Consider excluding this code path from WorkerThread like
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h index 7eacc127..9b41af3 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.h +++ b/third_party/blink/renderer/core/workers/worker_thread.h
@@ -129,7 +129,7 @@ const KURL& script_url, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode); + network::mojom::CredentialsMode); // Posts a task to the worker thread to close the global scope and terminate // the underlying thread. This task may be blocked by JavaScript execution on @@ -336,7 +336,7 @@ std::unique_ptr<CrossThreadFetchClientSettingsObjectData> outside_settings_object, WorkerResourceTimingNotifier* outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode); + network::mojom::CredentialsMode); // These are called in this order during worker thread termination. void PrepareForShutdownOnWorkerThread() LOCKS_EXCLUDED(mutex_);
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h index 68a2dd21..8eb7877 100644 --- a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h +++ b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
@@ -92,7 +92,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode) override { + network::mojom::CredentialsMode) override { NOTREACHED(); }
diff --git a/third_party/blink/renderer/core/workers/worklet.cc b/third_party/blink/renderer/core/workers/worklet.cc index 1f8d7df..7dde393 100644 --- a/third_party/blink/renderer/core/workers/worklet.cc +++ b/third_party/blink/renderer/core/workers/worklet.cc
@@ -122,7 +122,7 @@ return; // Step 6: "Let credentialOptions be the credentials member of options." - network::mojom::FetchCredentialsMode credentials_mode; + network::mojom::CredentialsMode credentials_mode; bool result = Request::ParseCredentialsMode(credentials, &credentials_mode); DCHECK(result);
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc index f0b6827..0418a301 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -206,7 +206,7 @@ // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script void WorkletGlobalScope::FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.h b/third_party/blink/renderer/core/workers/worklet_global_scope.h index 4420c21c..3d267c4 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.h
@@ -98,7 +98,7 @@ // parent frame's task runner). void FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h b/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h index a08c026d..173b26bf 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h +++ b/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h
@@ -28,7 +28,7 @@ // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script virtual void FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index 6e16c58..0ce0e92e 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -606,8 +606,8 @@ ResourceLoaderOptions options; options.initiator_info.name = fetch_initiator_type_names::kXml; FetchParameters params(ResourceRequest(url), options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); Resource* resource = RawResource::FetchSynchronously(params, document->Fetcher()); if (!resource->ErrorOccurred()) {
diff --git a/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc b/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc index 4219352..f92ccdd 100644 --- a/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc +++ b/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc
@@ -226,8 +226,8 @@ fetch_options.initiator_info.name = fetch_initiator_type_names::kXml; FetchParameters params( ResourceRequest(OwnerDocument()->CompleteURL(url_string)), fetch_options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); XSLStyleSheetResource* resource = XSLStyleSheetResource::FetchSynchronously( params, OwnerDocument()->Fetcher()); if (!resource->Sheet())
diff --git a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc index abeb923..357492e 100644 --- a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc +++ b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
@@ -108,8 +108,8 @@ ResourceLoaderOptions fetch_options; fetch_options.initiator_info.name = fetch_initiator_type_names::kXml; FetchParameters params(ResourceRequest(url), fetch_options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); Resource* resource = RawResource::FetchSynchronously(params, g_global_resource_fetcher); if (!g_global_processor)
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc index aba83d8..384cfa5 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -1027,7 +1027,8 @@ // Also, only async requests support upload progress events. bool upload_events = false; if (async_) { - probe::AsyncTaskScheduled(&execution_context, "XMLHttpRequest.send", this); + probe::AsyncTaskScheduled(&execution_context, "XMLHttpRequest.send", + &async_task_id_); DispatchProgressEvent(event_type_names::kLoadstart, 0, 0); // Event handler could have invalidated this send operation, // (re)setting the send flag and/or initiating another send @@ -1055,12 +1056,12 @@ request.SetRequestorOrigin(GetSecurityOrigin()); request.SetHttpMethod(method_); request.SetRequestContext(mojom::RequestContextType::XML_HTTP_REQUEST); - request.SetFetchRequestMode( - upload_events ? network::mojom::FetchRequestMode::kCorsWithForcedPreflight - : network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode( - with_credentials_ ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kSameOrigin); + request.SetMode(upload_events + ? network::mojom::RequestMode::kCorsWithForcedPreflight + : network::mojom::RequestMode::kCors); + request.SetCredentialsMode( + with_credentials_ ? network::mojom::CredentialsMode::kInclude + : network::mojom::CredentialsMode::kSameOrigin); request.SetSkipServiceWorker(is_isolated_world_); request.SetExternalRequestStateFromRequestorAddressSpace( execution_context.GetSecurityContext().AddressSpace()); @@ -1306,8 +1307,8 @@ ExecutionContext* context = GetExecutionContext(); probe::AsyncTask async_task( - context, this, type == event_type_names::kLoadend ? nullptr : "progress", - async_); + context, &async_task_id_, + type == event_type_names::kLoadend ? nullptr : "progress", async_); progress_event_throttle_->DispatchProgressEvent(type, length_computable, loaded, total); } @@ -1468,8 +1469,8 @@ WebHTTPHeaderSet access_control_expose_header_set = cors::ExtractCorsExposedHeaderNamesList( - with_credentials_ ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kSameOrigin, + with_credentials_ ? network::mojom::CredentialsMode::kInclude + : network::mojom::CredentialsMode::kSameOrigin, response_); HTTPHeaderMap::const_iterator end = response_.HttpHeaderFields().end(); @@ -1517,8 +1518,8 @@ WebHTTPHeaderSet access_control_expose_header_set = cors::ExtractCorsExposedHeaderNamesList( - with_credentials_ ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kSameOrigin, + with_credentials_ ? network::mojom::CredentialsMode::kInclude + : network::mojom::CredentialsMode::kSameOrigin, response_); if (response_.GetType() == network::mojom::FetchResponseType::kCors &&
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h index a77bc7a..ae2af2ce 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/dom/document_parser_client.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/loader/threadable_loader_client.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.h" #include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" @@ -163,6 +164,8 @@ XMLHttpRequestUpload* upload(); bool IsAsync() { return async_; } + probe::AsyncTaskId* async_task_id() { return &async_task_id_; } + DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange) void Trace(blink::Visitor*) override; @@ -374,6 +377,8 @@ bool response_text_overflow_ = false; bool send_flag_ = false; bool response_array_buffer_failure_ = false; + + probe::AsyncTaskId async_task_id_; }; std::ostream& operator<<(std::ostream&, const XMLHttpRequest*);
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc index 1dbea17..0cec76a 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc
@@ -131,8 +131,9 @@ // the previously dispatched event changes the readyState (e.g. when // the event handler calls xhr.abort()). In such cases a // readystatechange should have been already dispatched if necessary. - probe::AsyncTask async_task(target_->GetExecutionContext(), target_, - "progress", target_->IsAsync()); + probe::AsyncTask async_task(target_->GetExecutionContext(), + target_->async_task_id(), "progress", + target_->IsAsync()); target_->DispatchEvent(*event); } } @@ -145,8 +146,9 @@ TRACE_EVENT1("devtools.timeline", "XHRReadyStateChange", "data", inspector_xhr_ready_state_change_event::Data( target_->GetExecutionContext(), target_)); - probe::AsyncTask async_task(target_->GetExecutionContext(), target_, - "progress", target_->IsAsync()); + probe::AsyncTask async_task(target_->GetExecutionContext(), + target_->async_task_id(), "progress", + target_->IsAsync()); target_->DispatchEvent(*Event::Create(event_type_names::kReadystatechange)); } @@ -154,8 +156,9 @@ return; has_dispatched_progress_progress_event_ = true; - probe::AsyncTask async_task(target_->GetExecutionContext(), target_, - "progress", target_->IsAsync()); + probe::AsyncTask async_task(target_->GetExecutionContext(), + target_->async_task_id(), "progress", + target_->IsAsync()); target_->DispatchEvent(*progress_event); }
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc index 099554a..1ee0eb4 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc
@@ -51,8 +51,9 @@ uint64_t total_bytes_to_be_sent) { last_bytes_sent_ = bytes_sent; last_total_bytes_to_be_sent_ = total_bytes_to_be_sent; - probe::AsyncTask async_task(GetExecutionContext(), xml_http_request_, - "progress", xml_http_request_->IsAsync()); + probe::AsyncTask async_task(GetExecutionContext(), + xml_http_request_->async_task_id(), "progress", + xml_http_request_->IsAsync()); DispatchEvent(*ProgressEvent::Create(event_type_names::kProgress, true, bytes_sent, total_bytes_to_be_sent)); } @@ -64,7 +65,8 @@ DCHECK(type == event_type_names::kLoad || type == event_type_names::kAbort || type == event_type_names::kError || type == event_type_names::kTimeout); - probe::AsyncTask async_task(GetExecutionContext(), xml_http_request_, "event", + probe::AsyncTask async_task(GetExecutionContext(), + xml_http_request_->async_task_id(), "event", xml_http_request_->IsAsync()); DispatchEvent( *ProgressEvent::Create(type, length_computable, bytes_sent, total)); @@ -75,7 +77,8 @@ void XMLHttpRequestUpload::HandleRequestError(const AtomicString& type) { bool length_computable = last_total_bytes_to_be_sent_ > 0 && last_bytes_sent_ <= last_total_bytes_to_be_sent_; - probe::AsyncTask async_task(GetExecutionContext(), xml_http_request_, "error", + probe::AsyncTask async_task(GetExecutionContext(), + xml_http_request_->async_task_id(), "error", xml_http_request_->IsAsync()); DispatchEventAndLoadEnd(type, length_computable, last_bytes_sent_, last_total_bytes_to_be_sent_);
diff --git a/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js b/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js index dcfb44c6..c099b59 100644 --- a/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js +++ b/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js
@@ -121,11 +121,13 @@ } /** - * @param {string} name + * @param {?string} name * @param {boolean=} isPrivate * @return {!Element} */ static createNameElement(name, isPrivate) { + if (name === null) + return UI.html`<span class="name"></span>`; if (/^\s|\s$|^$|\n/.test(name)) return UI.html`<span class="name">"${name.replace(/\n/g, '\u21B5')}"</span>`; if (isPrivate) {
diff --git a/third_party/blink/renderer/devtools/front_end/sources/WatchExpressionsSidebarPane.js b/third_party/blink/renderer/devtools/front_end/sources/WatchExpressionsSidebarPane.js index 2224871..f709857 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/WatchExpressionsSidebarPane.js +++ b/third_party/blink/renderer/devtools/front_end/sources/WatchExpressionsSidebarPane.js
@@ -371,7 +371,7 @@ headerElement.appendChild(deleteButton); const titleElement = headerElement.createChild('div', 'watch-expression-title'); - this._nameElement = ObjectUI.ObjectPropertiesSection.createNameElement(/** @type {string} */ (this._expression)); + this._nameElement = ObjectUI.ObjectPropertiesSection.createNameElement(this._expression); if (!!exceptionDetails || !result) { this._valueElement = createElementWithClass('span', 'watch-expression-error value'); titleElement.classList.add('dimmed');
diff --git a/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css b/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css index 788959f..5b4a749 100644 --- a/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css +++ b/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
@@ -612,7 +612,7 @@ .CodeMirror-foldgutter-folded::before { background-color: #727272; -webkit-user-select: none; - -webkit-mask-image: url(Images/treeoutlineTriangles.png); + -webkit-mask-image: url(Images/treeoutlineTriangles.svg); -webkit-mask-size: 32px 24px; content: ""; display:block;
diff --git a/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css b/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css index 2076594..953e55c4 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css +++ b/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css
@@ -240,7 +240,7 @@ outline: none; padding-right: 20px; padding-left: 6px; - background-image: url(Images/chromeSelect.svg); + background-image: -webkit-image-set(url(Images/chromeSelect.png) 1x, url(Images/chromeSelect_2x.png) 2x); background-color: hsl(0, 0%, 98%); background-position: right center; background-repeat: no-repeat;
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 33b89513..c1cc5f9 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -338,6 +338,7 @@ "mediastream/mock_mojo_media_stream_dispatcher_host.cc", "mediastream/mock_mojo_media_stream_dispatcher_host.h", "mediastream/video_track_adapter_unittest.cc", + "mediastream/webaudio_media_stream_audio_sink_test.cc", "nfc/nfc_proxy_test.cc", "notifications/notification_data_test.cc", "notifications/notification_image_loader_test.cc",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index a1743d2..1088a23 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -909,8 +909,7 @@ cached_is_descendant_of_disabled_node_ = !!DisabledAncestor(); cached_has_inherited_presentational_role_ = !!InheritsPresentationalRoleFrom(); - IgnoredReasons ignored_reasons; - cached_is_ignored_ = ComputeAccessibilityIsIgnored(&ignored_reasons); + cached_is_ignored_ = ComputeAccessibilityIsIgnored(); cached_is_editable_root_ = ComputeIsEditableRoot(); // Compute live region root, which can be from any ARIA live value, including // "off", or from an automatic ARIA live value, e.g. from role="status".
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc index b6fc927..7395b42a 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -262,7 +262,7 @@ effect_timings_ = std::make_unique<WorkletAnimationEffectTimings>(timings); if (timeline_->IsScrollTimeline()) - ToScrollTimeline(timeline_)->AttachAnimation(); + timeline_->AnimationAttached(nullptr); } String WorkletAnimation::playState() { @@ -839,7 +839,7 @@ void WorkletAnimation::Dispose() { DCHECK(IsMainThread()); if (timeline_->IsScrollTimeline()) - ToScrollTimeline(timeline_)->DetachAnimation(); + timeline_->AnimationDetached(nullptr); DestroyCompositorAnimation(); }
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc index fbcdcfb..3e84444 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
@@ -96,10 +96,9 @@ resource_request.SetRequestContext(mojom::RequestContextType::IMAGE); resource_request.SetPriority(ResourceLoadPriority::kMedium); resource_request.SetKeepalive(true); - resource_request.SetFetchRequestMode( - network::mojom::FetchRequestMode::kNoCors); - resource_request.SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode::kInclude); + resource_request.SetMode(network::mojom::RequestMode::kNoCors); + resource_request.SetCredentialsMode( + network::mojom::CredentialsMode::kInclude); resource_request.SetSkipServiceWorker(true); threadable_loader_ = MakeGarbageCollected<ThreadableLoader>(
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc index ad1b86b8..93539192 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -207,7 +207,7 @@ // https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-fetch // ""If |internalRequest|’s mode is "no-cors", then return a promise // rejected with a TypeError."" - if (request->mode == network::mojom::FetchRequestMode::kNoCors) { + if (request->mode == network::mojom::RequestMode::kNoCors) { return RejectWithTypeError(script_state, request_url, "the request mode must not be no-cors"); }
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth.idl index 3e2272c9..857368e 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
@@ -5,6 +5,7 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetooth [ + Exposed=Window, RuntimeEnabled=WebBluetooth, SecureContext ] interface Bluetooth : EventTarget { @@ -15,4 +16,4 @@ Promise<BluetoothLEScan> requestLEScan (optional BluetoothLEScanOptions options); [RuntimeEnabled=WebBluetoothScanning] attribute EventHandler onadvertisementreceived; -}; +};
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl index 1cd2994..6a92e10 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl
@@ -5,6 +5,7 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent [ + Exposed=Window, RuntimeEnabled=WebBluetoothScanning, SecureContext ] interface BluetoothAdvertisingEvent : Event {
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_characteristic_properties.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_characteristic_properties.idl index 93af7ba..bc0e144 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_characteristic_properties.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_characteristic_properties.idl
@@ -4,9 +4,8 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothcharacteristicproperties -// Implement BluetoothCharacteristicProperties interface: http://crbug.com/483345 - [ + Exposed=Window, RuntimeEnabled=WebBluetooth, SecureContext ] interface BluetoothCharacteristicProperties {
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl index c1f8b5f..99c3c3f 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl
@@ -4,19 +4,16 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice -// Implement BluetoothDevice interface: http://crbug.com/421668 - [ + Exposed=Window, RuntimeEnabled=WebBluetooth, SecureContext -] interface BluetoothDevice : EventTarget -// Implement ServiceEventHandlers interface: http://crbug.com/421670 -// : ServiceEventHandlers -{ -// Implement BluetoothDevice interface: http://crbug.com/421668 +] interface BluetoothDevice : EventTarget { readonly attribute DOMString id; readonly attribute DOMString? name; readonly attribute BluetoothRemoteGATTServer gatt; attribute EventHandler ongattserverdisconnected; }; + +// TODO: Include ServiceEventHandlers mixin (https://crbug.com/421670)
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl index 78aaa1c..e326e8c 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl
@@ -4,7 +4,10 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent -[RuntimeEnabled=WebBluetoothScanning, SecureContext] -interface BluetoothManufacturerDataMap { +[ + Exposed=Window, + RuntimeEnabled=WebBluetoothScanning, + SecureContext +] interface BluetoothManufacturerDataMap { readonly maplike<unsigned short, DataView>; };
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl index a099782..3b8eb13 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl
@@ -4,13 +4,12 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattcharacteristic -// Implement BluetoothRemoteGATTCharacteristic interface: https://crbug.com/483344 - [ + Exposed=Window, ActiveScriptWrappable, RuntimeEnabled=WebBluetooth, SecureContext -] interface BluetoothRemoteGATTCharacteristic : EventTarget {//: CharacteristicEventHandlers { +] interface BluetoothRemoteGATTCharacteristic : EventTarget { [SameObject] readonly attribute BluetoothRemoteGATTService service; readonly attribute UUID uuid; readonly attribute BluetoothCharacteristicProperties properties;
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.idl index 8b6957b..62de0fa 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.idl
@@ -4,17 +4,14 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice -// Implement BluetoothRemoteGATTService interface: https://crbug.com/483342 - [ + Exposed=Window, RuntimeEnabled=WebBluetooth, SecureContext -] interface BluetoothRemoteGATTService { // : ServiceEventHandlers { +] interface BluetoothRemoteGATTService { [SameObject] readonly attribute BluetoothDevice device; readonly attribute UUID uuid; readonly attribute boolean isPrimary; [RaisesException, CallWith=ScriptState, MeasureAs=WebBluetoothRemoteServiceGetCharacteristic] Promise<BluetoothRemoteGATTCharacteristic> getCharacteristic(BluetoothCharacteristicUUID characteristic); [RaisesException, CallWith=ScriptState, MeasureAs=WebBluetoothRemoteServiceGetCharacteristics] Promise<sequence<BluetoothRemoteGATTCharacteristic>> getCharacteristics(optional BluetoothCharacteristicUUID characteristic); - // Promise<BluetoothRemoteGATTService> getIncludedService(BluetoothServiceUUID service); - // Promise<sequence<BluetoothRemoteGATTService>> getIncludedServices(optional BluetoothServiceUUID service); };
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl index 6be9244..dec1452 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl
@@ -4,7 +4,10 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent -[RuntimeEnabled=WebBluetoothScanning, SecureContext] -interface BluetoothServiceDataMap { +[ + Exposed=Window, + RuntimeEnabled=WebBluetoothScanning, + SecureContext +] interface BluetoothServiceDataMap { readonly maplike<UUID, DataView>; }; \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.idl index 09a09d4..2b1564d 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.idl
@@ -5,6 +5,7 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothuuid [ + Exposed=Window, RuntimeEnabled=WebBluetooth ] interface BluetoothUUID { [RaisesException] static UUID getService((DOMString or unsigned long) name);
diff --git a/third_party/blink/renderer/modules/csspaint/document_paint_definition.cc b/third_party/blink/renderer/modules/csspaint/document_paint_definition.cc index a6030820..3f1adef 100644 --- a/third_party/blink/renderer/modules/csspaint/document_paint_definition.cc +++ b/third_party/blink/renderer/modules/csspaint/document_paint_definition.cc
@@ -21,10 +21,25 @@ bool DocumentPaintDefinition::RegisterAdditionalPaintDefinition( const CSSPaintDefinition& other) { - if (alpha() != other.GetPaintRenderingContext2DSettings()->alpha() || - NativeInvalidationProperties() != other.NativeInvalidationProperties() || - CustomInvalidationProperties() != other.CustomInvalidationProperties() || - InputArgumentTypes() != other.InputArgumentTypes()) + if (other.NativeInvalidationProperties() != NativeInvalidationProperties() || + other.CustomInvalidationProperties() != CustomInvalidationProperties() || + other.InputArgumentTypes() != InputArgumentTypes() || + other.GetPaintRenderingContext2DSettings()->alpha() != alpha()) + return false; + registered_definitions_count_++; + return true; +} + +bool DocumentPaintDefinition::RegisterAdditionalPaintDefinition( + const Vector<CSSPropertyID>& native_properties, + const Vector<String>& custom_properties, + const Vector<CSSSyntaxDescriptor>& input_argument_types, + bool alpha) { + if (native_properties != NativeInvalidationProperties() || + !std::equal(custom_properties.begin(), custom_properties.end(), + CustomInvalidationProperties().begin(), + CustomInvalidationProperties().end()) || + input_argument_types != InputArgumentTypes() || alpha != this->alpha()) return false; registered_definitions_count_++; return true;
diff --git a/third_party/blink/renderer/modules/csspaint/document_paint_definition.h b/third_party/blink/renderer/modules/csspaint/document_paint_definition.h index eb634bcf..406db1c 100644 --- a/third_party/blink/renderer/modules/csspaint/document_paint_definition.h +++ b/third_party/blink/renderer/modules/csspaint/document_paint_definition.h
@@ -43,6 +43,10 @@ bool alpha() const { return alpha_; } bool RegisterAdditionalPaintDefinition(const CSSPaintDefinition&); + bool RegisterAdditionalPaintDefinition(const Vector<CSSPropertyID>&, + const Vector<String>&, + const Vector<CSSSyntaxDescriptor>&, + bool alpha); unsigned GetRegisteredDefinitionCount() const { return registered_definitions_count_;
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc index 9d619d7..ef16513 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
@@ -164,8 +164,15 @@ // Notify the generator ready only when register paint is called the // second time with the same |name| (i.e. there is already a document // definition associated with |name| + // + // We are looking for kNumGlobalScopesPerThread number of definitions + // regiserered from RegisterCSSPaintDefinition and one extra definition from + // RegisterMainThreadDocumentPaintDefinition if OffMainThreadCSSPaintEnabled + // is true. if (existing_document_definition->GetRegisteredDefinitionCount() == - PaintWorklet::kNumGlobalScopesPerThread) + RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled() + ? kNumGlobalScopesPerThread + 1 + : kNumGlobalScopesPerThread) pending_generator_registry_->NotifyGeneratorReady(name); } else { auto document_definition = std::make_unique<DocumentPaintDefinition>( @@ -183,18 +190,38 @@ Vector<String> custom_properties, Vector<CSSSyntaxDescriptor> input_argument_types, double alpha) { - // Because this method is called cross-thread, |custom_properties| cannot be - // an AtomicString. Instead, convert to AtomicString now that we are on the - // main thread. - Vector<AtomicString> new_custom_properties; - new_custom_properties.ReserveInitialCapacity(custom_properties.size()); - for (const String& property : custom_properties) - new_custom_properties.push_back(AtomicString(property)); - auto definition = std::make_unique<DocumentPaintDefinition>( - std::move(native_properties), std::move(new_custom_properties), - std::move(input_argument_types), alpha); - document_definition_map_.insert(name, std::move(definition)); - pending_generator_registry_->NotifyGeneratorReady(name); + if (document_definition_map_.Contains(name)) { + DocumentPaintDefinition* document_definition = + document_definition_map_.at(name); + if (!document_definition) + return; + if (!document_definition->RegisterAdditionalPaintDefinition( + native_properties, custom_properties, input_argument_types, + alpha)) { + document_definition_map_.Set(name, nullptr); + return; + } + } else { + // Because this method is called cross-thread, |custom_properties| cannot be + // an AtomicString. Instead, convert to AtomicString now that we are on the + // main thread. + Vector<AtomicString> new_custom_properties; + new_custom_properties.ReserveInitialCapacity(custom_properties.size()); + for (const String& property : custom_properties) + new_custom_properties.push_back(AtomicString(property)); + auto document_definition = std::make_unique<DocumentPaintDefinition>( + std::move(native_properties), std::move(new_custom_properties), + std::move(input_argument_types), alpha); + document_definition_map_.insert(name, std::move(document_definition)); + } + DocumentPaintDefinition* document_definition = + document_definition_map_.at(name); + // We are looking for kNumGlobalScopesPerThread number of definitions + // registered from RegisterCSSPaintDefinition and one extra definition from + // RegisterMainThreadDocumentPaintDefinition + if (document_definition->GetRegisteredDefinitionCount() == + kNumGlobalScopesPerThread + 1) + pending_generator_registry_->NotifyGeneratorReady(name); } bool PaintWorklet::NeedsToCreateGlobalScope() {
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc index 857eaee..61c4813 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
@@ -58,7 +58,7 @@ void PaintWorkletGlobalScopeProxy::FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h index 813ab341..b7dcf27 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h
@@ -35,7 +35,7 @@ // Implements WorkletGlobalScopeProxy. void FetchAndInvokeScript( const KURL& module_url_record, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner,
diff --git a/third_party/blink/renderer/modules/eventsource/event_source.cc b/third_party/blink/renderer/modules/eventsource/event_source.cc index ce08a98..a7fe56a 100644 --- a/third_party/blink/renderer/modules/eventsource/event_source.cc +++ b/third_party/blink/renderer/modules/eventsource/event_source.cc
@@ -128,10 +128,10 @@ request.SetHttpHeaderField(http_names::kAccept, "text/event-stream"); request.SetHttpHeaderField(http_names::kCacheControl, "no-cache"); request.SetRequestContext(mojom::RequestContextType::EVENT_SOURCE); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - request.SetFetchCredentialsMode( - with_credentials_ ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kSameOrigin); + request.SetMode(network::mojom::RequestMode::kCors); + request.SetCredentialsMode( + with_credentials_ ? network::mojom::CredentialsMode::kInclude + : network::mojom::CredentialsMode::kSameOrigin); request.SetCacheMode(blink::mojom::FetchCacheMode::kNoStore); request.SetExternalRequestStateFromRequestorAddressSpace( execution_context.GetSecurityContext().AddressSpace());
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc index f4f4905a..9b20712d 100644 --- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc +++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -319,8 +319,8 @@ main_script_loader_->LoadTopLevelScriptAsynchronously( *shadow_page_->GetDocument(), shadow_page_->GetDocument()->Fetcher(), worker_start_data_.script_url, mojom::RequestContextType::SERVICE_WORKER, - network::mojom::FetchRequestMode::kSameOrigin, - network::mojom::FetchCredentialsMode::kSameOrigin, base::OnceClosure(), + network::mojom::RequestMode::kSameOrigin, + network::mojom::CredentialsMode::kSameOrigin, base::OnceClosure(), Bind(&WebEmbeddedWorkerImpl::OnScriptLoaderFinished, WTF::Unretained(this))); // Do nothing here since OnScriptLoaderFinished() might have been already @@ -502,7 +502,7 @@ case mojom::ScriptType::kModule: worker_thread_->RunInstalledModuleScript( worker_start_data_.script_url, *CreateFetchClientSettingsObject(), - network::mojom::FetchCredentialsMode::kOmit); + network::mojom::CredentialsMode::kOmit); return; } NOTREACHED(); @@ -551,8 +551,7 @@ case mojom::ScriptType::kModule: worker_thread_->FetchAndRunModuleScript( worker_start_data_.script_url, *fetch_client_setting_object, - *resource_timing_notifier, - network::mojom::FetchCredentialsMode::kOmit); + *resource_timing_notifier, network::mojom::CredentialsMode::kOmit); return; } NOTREACHED();
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system.cc index 10156fe..54ff95f6 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
@@ -34,6 +34,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_security_origin.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/filesystem/directory_entry.h" #include "third_party/blink/renderer/modules/filesystem/dom_file_path.h" @@ -52,7 +53,7 @@ void RunCallback(ExecutionContext* execution_context, base::OnceClosure task, - std::unique_ptr<int> identifier) { + std::unique_ptr<probe::AsyncTaskId> identifier) { if (!execution_context) return; DCHECK(execution_context->IsContextThread()); @@ -166,7 +167,8 @@ DCHECK(execution_context->IsContextThread()); - std::unique_ptr<int> identifier = std::make_unique<int>(0); + std::unique_ptr<probe::AsyncTaskId> identifier = + std::make_unique<probe::AsyncTaskId>(); probe::AsyncTaskScheduled(execution_context, TaskNameForInstrumentation(), identifier.get()); execution_context->GetTaskRunner(TaskType::kFileReading)
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer.cc b/third_party/blink/renderer/modules/filesystem/file_writer.cc index c91f83f..0d0259e6 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer.cc +++ b/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -255,7 +255,8 @@ } void FileWriter::DoOperation(Operation operation) { - probe::AsyncTaskScheduled(GetExecutionContext(), "FileWriter", this); + probe::AsyncTaskScheduled(GetExecutionContext(), "FileWriter", + &async_task_id_); switch (operation) { case kOperationWrite: DCHECK_EQ(kOperationNone, operation_in_progress_); @@ -305,11 +306,11 @@ } FireEvent(event_type_names::kWriteend); - probe::AsyncTaskCanceled(GetExecutionContext(), this); + probe::AsyncTaskCanceled(GetExecutionContext(), &async_task_id_); } void FileWriter::FireEvent(const AtomicString& type) { - probe::AsyncTask async_task(GetExecutionContext(), this); + probe::AsyncTask async_task(GetExecutionContext(), &async_task_id_); ++recursion_depth_; DispatchEvent( *ProgressEvent::Create(type, true, bytes_written_, bytes_to_write_));
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer.h b/third_party/blink/renderer/modules/filesystem/file_writer.h index adb3dbc..89f6b8b 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer.h +++ b/third_party/blink/renderer/modules/filesystem/file_writer.h
@@ -34,6 +34,7 @@ #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/filesystem/file_writer_base.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -130,6 +131,7 @@ double last_progress_notification_time_ms_; Member<Blob> blob_being_written_; int request_id_; + probe::AsyncTaskId async_task_id_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc index 0608709..b4b93bcb 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database.h" @@ -73,13 +74,14 @@ : promise_resolver_(promise_resolver) { probe::AsyncTaskScheduled( ExecutionContext::From(promise_resolver_->GetScriptState()), - indexed_db_names::kIndexedDB, this); + indexed_db_names::kIndexedDB, &async_task_id_); } ~WebIDBGetDBNamesCallbacksImpl() override { if (promise_resolver_) { probe::AsyncTaskCanceled( - ExecutionContext::From(promise_resolver_->GetScriptState()), this); + ExecutionContext::From(promise_resolver_->GetScriptState()), + &async_task_id_); promise_resolver_->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kUnknownError, "An unexpected shutdown occured before the " @@ -95,8 +97,8 @@ return; probe::AsyncTask async_task( - ExecutionContext::From(promise_resolver_->GetScriptState()), this, - "error"); + ExecutionContext::From(promise_resolver_->GetScriptState()), + &async_task_id_, "error"); promise_resolver_->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kUnknownError, "The databases() promise was rejected.")); @@ -121,8 +123,8 @@ } probe::AsyncTask async_task( - ExecutionContext::From(promise_resolver_->GetScriptState()), this, - "success"); + ExecutionContext::From(promise_resolver_->GetScriptState()), + &async_task_id_, "success"); promise_resolver_->Resolve(name_and_version_list); promise_resolver_.Clear(); } @@ -183,6 +185,7 @@ void DetachRequestFromCallback() override { NOTREACHED(); } private: + probe::AsyncTaskId async_task_id_; Persistent<ScriptPromiseResolver> promise_resolver_; };
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc index ee2025c8..642ade68 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc
@@ -72,7 +72,7 @@ task_runner_ = request_->GetExecutionContext()->GetTaskRunner(TaskType::kDatabaseAccess); probe::AsyncTaskScheduled(request_->GetExecutionContext(), - indexed_db_names::kIndexedDB, this); + indexed_db_names::kIndexedDB, &async_task_id_); } WebIDBCallbacksImpl::~WebIDBCallbacksImpl() { @@ -86,7 +86,7 @@ void WebIDBCallbacksImpl::DetachCallbackFromRequest() { if (request_) { - probe::AsyncTaskCanceled(request_->GetExecutionContext(), this); + probe::AsyncTaskCanceled(request_->GetExecutionContext(), &async_task_id_); #if DCHECK_IS_ON() DCHECK_EQ(static_cast<WebIDBCallbacks*>(this), request_->WebCallbacks()); #endif // DCHECK_IS_ON() @@ -117,7 +117,8 @@ return; } - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "error"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "error"); IDBRequest* request = request_.Get(); Detach(); request->HandleResponse(MakeGarbageCollected<DOMException>( @@ -134,7 +135,8 @@ if (!request_) return; - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); #if DCHECK_IS_ON() DCHECK(!request_->TransactionHasQueuedResults()); #endif // DCHECK_IS_ON() @@ -162,7 +164,8 @@ } DCHECK(value); - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); value->SetIsolate(request_->GetIsolate()); IDBRequest* request = request_.Get(); Detach(); @@ -191,8 +194,8 @@ task_runner_); } if (request_) { - probe::AsyncTask async_task(request_->GetExecutionContext(), this, - "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), + &async_task_id_, "success"); #if DCHECK_IS_ON() DCHECK(!request_->TransactionHasQueuedResults()); #endif // DCHECK_IS_ON() @@ -208,7 +211,8 @@ if (!request_) return; - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); IDBRequest* request = request_.Get(); Detach(); request->HandleResponse(std::move(key)); @@ -220,7 +224,8 @@ return; std::unique_ptr<IDBValue> value = ConvertReturnValue(return_value); - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); value->SetIsolate(request_->GetIsolate()); IDBRequest* request = request_.Get(); Detach(); @@ -232,7 +237,8 @@ if (!request_) return; - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); Vector<std::unique_ptr<IDBValue>> idb_values; idb_values.ReserveInitialCapacity(values.size()); for (const mojom::blink::IDBReturnValuePtr& value : values) { @@ -249,7 +255,8 @@ if (!request_) return; - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); IDBRequest* request = request_.Get(); Detach(); request->HandleResponse(value); @@ -259,7 +266,8 @@ if (!request_) return; - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); IDBRequest* request = request_.Get(); Detach(); request->HandleResponse(); @@ -272,7 +280,8 @@ if (!request_) return; - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "success"); std::unique_ptr<IDBValue> value; if (optional_value.has_value()) { value = std::move(optional_value.value()); @@ -292,7 +301,8 @@ if (!request_) return; - probe::AsyncTask async_task(request_->GetExecutionContext(), this, "blocked"); + probe::AsyncTask async_task(request_->GetExecutionContext(), &async_task_id_, + "blocked"); #if DCHECK_IS_ON() DCHECK(!request_->TransactionHasQueuedResults()); #endif // DCHECK_IS_ON() @@ -314,8 +324,8 @@ task_runner_); } if (request_) { - probe::AsyncTask async_task(request_->GetExecutionContext(), this, - "upgradeNeeded"); + probe::AsyncTask async_task(request_->GetExecutionContext(), + &async_task_id_, "upgradeNeeded"); #if DCHECK_IS_ON() DCHECK(!request_->TransactionHasQueuedResults()); #endif // DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h index b189a947..ddae52a6a 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h
@@ -33,6 +33,7 @@ #include "base/memory/weak_ptr.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -99,6 +100,7 @@ Persistent<IDBRequest> request_; base::WeakPtr<WebIDBCursorImpl> cursor_; int64_t transaction_id_; + probe::AsyncTaskId async_task_id_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; };
diff --git a/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc b/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc index 298c3a66..44b1e8a 100644 --- a/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc +++ b/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
@@ -22,12 +22,12 @@ ResourceRequest request(url_); request.SetRequestContext(mojom::RequestContextType::MANIFEST); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); + request.SetMode(network::mojom::RequestMode::kCors); // See https://w3c.github.io/manifest/. Use "include" when use_credentials is // true, and "omit" otherwise. - request.SetFetchCredentialsMode( - use_credentials ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kOmit); + request.SetCredentialsMode(use_credentials + ? network::mojom::CredentialsMode::kInclude + : network::mojom::CredentialsMode::kOmit); ResourceLoaderOptions resource_loader_options; resource_loader_options.data_buffering_policy = kDoNotBufferData;
diff --git a/third_party/blink/renderer/modules/manifest/manifest_parser.cc b/third_party/blink/renderer/modules/manifest/manifest_parser.cc index 5977ddd..ef29349 100644 --- a/third_party/blink/renderer/modules/manifest/manifest_parser.cc +++ b/third_party/blink/renderer/modules/manifest/manifest_parser.cc
@@ -100,7 +100,6 @@ if (manifest_->has_background_color) manifest_->background_color = *background_color; - manifest_->splash_screen_url = ParseSplashScreenURL(root_object.get()); manifest_->gcm_sender_id = ParseGCMSenderID(root_object.get()); ManifestUmaUtil::ParseSucceeded(manifest_); @@ -734,11 +733,6 @@ return ParseColor(object, "background_color"); } -KURL ManifestParser::ParseSplashScreenURL(const JSONObject* object) { - return ParseURL(object, "splash_screen_url", manifest_url_, - ParseURLOriginRestrictions::kSameOriginOnly); -} - String ManifestParser::ParseGCMSenderID(const JSONObject* object) { base::Optional<String> gcm_sender_id = ParseString(object, "gcm_sender_id", Trim);
diff --git a/third_party/blink/renderer/modules/manifest/manifest_parser.h b/third_party/blink/renderer/modules/manifest/manifest_parser.h index 07f619f..0c0cdcc 100644 --- a/third_party/blink/renderer/modules/manifest/manifest_parser.h +++ b/third_party/blink/renderer/modules/manifest/manifest_parser.h
@@ -243,10 +243,6 @@ // Returns the parsed background color if any, or a null optional otherwise. base::Optional<RGBA32> ParseBackgroundColor(const JSONObject* object); - // Parses the 'splash_screen_url' field of the manifest. - // Returns the parsed KURL if any, an empty KURL if the parsing failed. - KURL ParseSplashScreenURL(const JSONObject* object); - // Parses the 'gcm_sender_id' field of the manifest. // This is a proprietary extension of the Web Manifest specification. // Returns the parsed string if any, a null string if the parsing failed.
diff --git a/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc b/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc index b65e0e0..1ee1ec1 100644 --- a/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc +++ b/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc
@@ -103,7 +103,6 @@ ASSERT_EQ(manifest->orientation, kWebScreenOrientationLockDefault); ASSERT_FALSE(manifest->has_theme_color); ASSERT_FALSE(manifest->has_background_color); - ASSERT_TRUE(manifest->splash_screen_url.IsEmpty()); ASSERT_TRUE(manifest->gcm_sender_id.IsNull()); ASSERT_EQ(DefaultDocumentUrl().BaseAsString(), manifest->scope.GetString()); } @@ -2670,91 +2669,6 @@ } } -TEST_F(ManifestParserTest, SplashScreenUrlParseRules) { - // Smoke test. - { - auto& manifest = - ParseManifest("{ \"splash_screen_url\": \"splash.html\" }"); - ASSERT_EQ(manifest->splash_screen_url, - KURL(DefaultDocumentUrl(), "splash.html")); - ASSERT_FALSE(IsManifestEmpty(manifest)); - EXPECT_EQ(0u, GetErrorCount()); - } - - // Whitespaces. - { - auto& manifest = - ParseManifest("{ \"splash_screen_url\": \" splash.html\" }"); - ASSERT_EQ(manifest->splash_screen_url, - KURL(DefaultDocumentUrl(), "splash.html").GetString()); - EXPECT_EQ(0u, GetErrorCount()); - } - - // Don't parse if property isn't a string. - { - auto& manifest = ParseManifest("{ \"splash_screen_url\": {} }"); - ASSERT_TRUE(manifest->splash_screen_url.IsEmpty()); - EXPECT_EQ(1u, GetErrorCount()); - EXPECT_EQ("property 'splash_screen_url' ignored, type string expected.", - errors()[0]); - } - - // Don't parse if property isn't a string. - { - auto& manifest = ParseManifest("{ \"splash_screen_url\": 42 }"); - ASSERT_TRUE(manifest->splash_screen_url.IsEmpty()); - EXPECT_EQ(1u, GetErrorCount()); - EXPECT_EQ("property 'splash_screen_url' ignored, type string expected.", - errors()[0]); - } - - // Don't parse if property isn't a valid URL. - { - auto& manifest = - ParseManifest("{ \"splash_screen_url\": \"http://www.google.ca:a\" }"); - ASSERT_TRUE(manifest->splash_screen_url.IsEmpty()); - EXPECT_EQ(1u, GetErrorCount()); - EXPECT_EQ("property 'splash_screen_url' ignored, URL is invalid.", - errors()[0]); - } - - // Absolute splash_screen_url, same origin with document. - { - auto& manifest = ParseManifestWithURLs( - "{ \"splash_screen_url\": \"http://foo.com/splash.html\" }", - KURL("http://foo.com/manifest.json"), - KURL("http://foo.com/index.html")); - ASSERT_EQ(manifest->splash_screen_url.GetString(), - "http://foo.com/splash.html"); - EXPECT_EQ(0u, GetErrorCount()); - } - - // Absolute splash_screen_url, cross origin with document. - { - auto& manifest = ParseManifestWithURLs( - "{ \"splash_screen_url\": \"http://bar.com/splash.html\" }", - KURL("http://foo.com/manifest.json"), - KURL("http://foo.com/index.html")); - ASSERT_TRUE(manifest->splash_screen_url.IsEmpty()); - EXPECT_EQ(1u, GetErrorCount()); - EXPECT_EQ( - "property 'splash_screen_url' ignored, should " - "be same origin as document.", - errors()[0]); - } - - // Resolving has to happen based on the manifest_url. - { - auto& manifest = - ParseManifestWithURLs("{ \"splash_screen_url\": \"splash.html\" }", - KURL("http://foo.com/splashy/manifest.json"), - KURL("http://foo.com/index.html")); - ASSERT_EQ(manifest->splash_screen_url.GetString(), - "http://foo.com/splashy/splash.html"); - EXPECT_EQ(0u, GetErrorCount()); - } -} - TEST_F(ManifestParserTest, GCMSenderIDParseRules) { // Smoke test. {
diff --git a/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc b/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc index 63f33440..a07f4771 100644 --- a/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc +++ b/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc
@@ -66,9 +66,6 @@ if (input->has_background_color) output.background_color = input->background_color; - if (!input->splash_screen_url.IsEmpty()) - output.splash_screen_url = input->splash_screen_url; - if (!input->gcm_sender_id.IsEmpty()) { output.gcm_sender_id = base::NullableString16(blink::WebString(input->gcm_sender_id).Utf16());
diff --git a/third_party/blink/renderer/modules/mediastream/BUILD.gn b/third_party/blink/renderer/modules/mediastream/BUILD.gn index 0b0f64f..dfe8c79 100644 --- a/third_party/blink/renderer/modules/mediastream/BUILD.gn +++ b/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -54,6 +54,7 @@ "video_track_adapter.h", "video_track_adapter_settings.cc", "web_media_stream_utils.cc", + "webaudio_media_stream_audio_sink.cc", ] }
diff --git a/content/renderer/media/webrtc_local_audio_source_provider.cc b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc similarity index 69% rename from content/renderer/media/webrtc_local_audio_source_provider.cc rename to third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc index 21412ec..d38a444 100644 --- a/content/renderer/media/webrtc_local_audio_source_provider.cc +++ b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc
@@ -2,61 +2,55 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/media/webrtc_local_audio_source_provider.h" +#include "third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h" #include <string> #include "base/logging.h" -#include "content/public/renderer/render_frame.h" -#include "content/renderer/media/audio/audio_device_factory.h" #include "media/base/audio_fifo.h" #include "media/base/audio_parameters.h" #include "third_party/blink/public/platform/web_audio_source_provider_client.h" #include "third_party/blink/public/web/web_local_frame.h" -using blink::WebVector; - namespace { static const size_t kMaxNumberOfAudioFifoBuffers = 10; } -namespace content { +namespace blink { // Size of the buffer that WebAudio processes each time, it is the same value // as AudioNode::ProcessingSizeInFrames in WebKit. // static -const size_t WebRtcLocalAudioSourceProvider::kWebAudioRenderBufferSize = 128; +const size_t WebAudioMediaStreamAudioSink::kWebAudioRenderBufferSize = 128; -WebRtcLocalAudioSourceProvider::WebRtcLocalAudioSourceProvider( - const blink::WebMediaStreamTrack& track, +WebAudioMediaStreamAudioSink::WebAudioMediaStreamAudioSink( + const WebMediaStreamTrack& track, int context_sample_rate) : is_enabled_(false), track_(track), track_stopped_(false) { // Get the native audio output hardware sample-rate for the sink. // We need to check if there is a valid frame since the unittests // do not have one and they will inject their own |sink_params_| for testing. - blink::WebLocalFrame* const web_frame = - blink::WebLocalFrame::FrameForCurrentContext(); - RenderFrame* const render_frame = RenderFrame::FromWebFrame(web_frame); - if (render_frame) { + WebLocalFrame* const web_frame = WebLocalFrame::FrameForCurrentContext(); + if (web_frame) { sink_params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_STEREO, context_sample_rate, kWebAudioRenderBufferSize); } // Connect the source provider to the track as a sink. - blink::WebMediaStreamAudioSink::AddToAudioTrack(this, track_); + WebMediaStreamAudioSink::AddToAudioTrack(this, track_); } -WebRtcLocalAudioSourceProvider::~WebRtcLocalAudioSourceProvider() { +WebAudioMediaStreamAudioSink::~WebAudioMediaStreamAudioSink() { if (audio_converter_.get()) audio_converter_->RemoveInput(this); // If the track is still active, it is necessary to notify the track before // the source provider goes away. if (!track_stopped_) - blink::WebMediaStreamAudioSink::RemoveFromAudioTrack(this, track_); + WebMediaStreamAudioSink::RemoveFromAudioTrack(this, track_); } -void WebRtcLocalAudioSourceProvider::OnSetFormat( +void WebAudioMediaStreamAudioSink::OnSetFormat( const media::AudioParameters& params) { DCHECK(params.IsValid()); @@ -76,14 +70,14 @@ kMaxNumberOfAudioFifoBuffers * params.frames_per_buffer())); } -void WebRtcLocalAudioSourceProvider::OnReadyStateChanged( - blink::WebMediaStreamSource::ReadyState state) { +void WebAudioMediaStreamAudioSink::OnReadyStateChanged( + WebMediaStreamSource::ReadyState state) { NON_REENTRANT_SCOPE(ready_state_reentrancy_checker_); - if (state == blink::WebMediaStreamSource::kReadyStateEnded) + if (state == WebMediaStreamSource::kReadyStateEnded) track_stopped_ = true; } -void WebRtcLocalAudioSourceProvider::OnData( +void WebAudioMediaStreamAudioSink::OnData( const media::AudioBus& audio_bus, base::TimeTicks estimated_capture_time) { NON_REENTRANT_SCOPE(capture_reentrancy_checker_); @@ -106,12 +100,12 @@ } } -void WebRtcLocalAudioSourceProvider::SetClient( - blink::WebAudioSourceProviderClient* client) { +void WebAudioMediaStreamAudioSink::SetClient( + WebAudioSourceProviderClient* client) { NOTREACHED(); } -void WebRtcLocalAudioSourceProvider::ProvideInput( +void WebAudioMediaStreamAudioSink::ProvideInput( const WebVector<float*>& audio_data, size_t number_of_frames) { NON_REENTRANT_SCOPE(provide_input_reentrancy_checker_); @@ -119,12 +113,13 @@ if (!output_wrapper_ || static_cast<size_t>(output_wrapper_->channels()) != audio_data.size()) { - output_wrapper_ = media::AudioBus::CreateWrapper(audio_data.size()); + output_wrapper_ = + media::AudioBus::CreateWrapper(static_cast<int>(audio_data.size())); } - output_wrapper_->set_frames(number_of_frames); + output_wrapper_->set_frames(static_cast<int>(number_of_frames)); for (size_t i = 0; i < audio_data.size(); ++i) - output_wrapper_->SetChannelData(i, audio_data[i]); + output_wrapper_->SetChannelData(static_cast<int>(i), audio_data[i]); base::AutoLock auto_lock(lock_); if (!audio_converter_) @@ -138,8 +133,8 @@ // AudioConverter which in turn is called by the above ProvideInput() function. // Thus thread safety analysis is disabled here and |lock_| acquire manually // asserted. -double WebRtcLocalAudioSourceProvider::ProvideInput(media::AudioBus* audio_bus, - uint32_t frames_delayed) +double WebAudioMediaStreamAudioSink::ProvideInput(media::AudioBus* audio_bus, + uint32_t frames_delayed) NO_THREAD_SAFETY_ANALYSIS { lock_.AssertAcquired(); if (fifo_->frames() >= audio_bus->frames()) { @@ -147,17 +142,16 @@ } else { audio_bus->Zero(); DVLOG(1) << "WARNING: Underrun, FIFO has data " << fifo_->frames() - << " samples but " << audio_bus->frames() - << " samples are needed"; + << " samples but " << audio_bus->frames() << " samples are needed"; } return 1.0; } -void WebRtcLocalAudioSourceProvider::SetSinkParamsForTesting( +void WebAudioMediaStreamAudioSink::SetSinkParamsForTesting( const media::AudioParameters& sink_params) { base::AutoLock auto_lock(lock_); sink_params_ = sink_params; } -} // namespace content +} // namespace blink
diff --git a/content/renderer/media/webrtc_local_audio_source_provider_unittest.cc b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc similarity index 70% rename from content/renderer/media/webrtc_local_audio_source_provider_unittest.cc rename to third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc index e833984..c212c57 100644 --- a/content/renderer/media/webrtc_local_audio_source_provider_unittest.cc +++ b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h" + #include <stddef.h> #include "base/logging.h" -#include "content/renderer/media/webrtc_local_audio_source_provider.h" #include "media/base/audio_bus.h" #include "media/base/audio_parameters.h" #include "testing/gtest/include/gtest/gtest.h" @@ -14,30 +15,28 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_heap.h" -namespace content { +namespace blink { -class WebRtcLocalAudioSourceProviderTest : public testing::Test { +class WebAudioMediaStreamAudioSinkTest : public testing::Test { protected: void SetUp() override { source_params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, 48000, 480); const int context_sample_rate = 44100; - sink_params_.Reset( - media::AudioParameters::AUDIO_PCM_LOW_LATENCY, - media::CHANNEL_LAYOUT_STEREO, context_sample_rate, - WebRtcLocalAudioSourceProvider::kWebAudioRenderBufferSize); + sink_params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::CHANNEL_LAYOUT_STEREO, context_sample_rate, + WebAudioMediaStreamAudioSink::kWebAudioRenderBufferSize); sink_bus_ = media::AudioBus::Create(sink_params_); - blink::WebMediaStreamSource audio_source; - audio_source.Initialize(blink::WebString::FromUTF8("dummy_source_id"), - blink::WebMediaStreamSource::kTypeAudio, - blink::WebString::FromUTF8("dummy_source_name"), + WebMediaStreamSource audio_source; + audio_source.Initialize(WebString::FromUTF8("dummy_source_id"), + WebMediaStreamSource::kTypeAudio, + WebString::FromUTF8("dummy_source_name"), false /* remote */); - blink_track_.Initialize(blink::WebString::FromUTF8("audio_track"), - audio_source); + blink_track_.Initialize(WebString::FromUTF8("audio_track"), audio_source); blink_track_.SetPlatformTrack( - std::make_unique<blink::MediaStreamAudioTrack>(true)); + std::make_unique<MediaStreamAudioTrack>(true)); source_provider_.reset( - new WebRtcLocalAudioSourceProvider(blink_track_, context_sample_rate)); + new WebAudioMediaStreamAudioSink(blink_track_, context_sample_rate)); source_provider_->SetSinkParamsForTesting(sink_params_); source_provider_->OnSetFormat(source_params_); } @@ -45,24 +44,23 @@ void TearDown() override { source_provider_.reset(); blink_track_.Reset(); - blink::WebHeap::CollectAllGarbageForTesting(); + WebHeap::CollectAllGarbageForTesting(); } media::AudioParameters source_params_; media::AudioParameters sink_params_; std::unique_ptr<media::AudioBus> sink_bus_; - blink::WebMediaStreamTrack blink_track_; - std::unique_ptr<WebRtcLocalAudioSourceProvider> source_provider_; + WebMediaStreamTrack blink_track_; + std::unique_ptr<WebAudioMediaStreamAudioSink> source_provider_; }; -TEST_F(WebRtcLocalAudioSourceProviderTest, VerifyDataFlow) { +TEST_F(WebAudioMediaStreamAudioSinkTest, VerifyDataFlow) { // TODO(miu): This test should be re-worked so that the audio data and format // is feed into a MediaStreamAudioSource and, through the // MediaStreamAudioTrack, ultimately delivered to the |source_provider_|. // Point the WebVector into memory owned by |sink_bus_|. - blink::WebVector<float*> audio_data( - static_cast<size_t>(sink_bus_->channels())); + WebVector<float*> audio_data(static_cast<size_t>(sink_bus_->channels())); for (size_t i = 0; i < audio_data.size(); ++i) audio_data[i] = sink_bus_->channel(i); @@ -76,8 +74,7 @@ const std::unique_ptr<media::AudioBus> source_bus = media::AudioBus::Create(source_params_); std::fill(source_bus->channel(0), - source_bus->channel(0) + source_bus->frames(), - 0.5f); + source_bus->channel(0) + source_bus->frames(), 0.5f); // Deliver data to |source_provider_|. base::TimeTicks estimated_capture_time = base::TimeTicks::Now(); @@ -98,9 +95,9 @@ } // Make a second data delivery. - estimated_capture_time += - source_bus->frames() * base::TimeDelta::FromSeconds(1) / - source_params_.sample_rate(); + estimated_capture_time += source_bus->frames() * + base::TimeDelta::FromSeconds(1) / + source_params_.sample_rate(); source_provider_->OnData(*source_bus, estimated_capture_time); // Verify that non-zero data samples are present in the results of the @@ -116,21 +113,21 @@ } } -TEST_F(WebRtcLocalAudioSourceProviderTest, +TEST_F(WebAudioMediaStreamAudioSinkTest, DeleteSourceProviderBeforeStoppingTrack) { source_provider_.reset(); // Stop the audio track. - blink::MediaStreamAudioTrack::From(blink_track_)->Stop(); + MediaStreamAudioTrack::From(blink_track_)->Stop(); } -TEST_F(WebRtcLocalAudioSourceProviderTest, +TEST_F(WebAudioMediaStreamAudioSinkTest, StopTrackBeforeDeletingSourceProvider) { // Stop the audio track. - blink::MediaStreamAudioTrack::From(blink_track_)->Stop(); + MediaStreamAudioTrack::From(blink_track_)->Stop(); // Delete the source provider. source_provider_.reset(); } -} // namespace content +} // namespace blink
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index 4e8ac7d2..78b68ddb 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -735,6 +735,7 @@ "permissions/midi_permission_descriptor.idl", "permissions/permission_descriptor.idl", "permissions/push_permission_descriptor.idl", + "permissions/wake_lock_permission_descriptor.idl", "picture_in_picture/enter_picture_in_picture_event_init.idl", "picture_in_picture/picture_in_picture_options.idl", "presentation/presentation_connection_available_event_init.idl",
diff --git a/third_party/blink/renderer/modules/permissions/permission_descriptor.idl b/third_party/blink/renderer/modules/permissions/permission_descriptor.idl index b7f23ad4..2368ac298 100644 --- a/third_party/blink/renderer/modules/permissions/permission_descriptor.idl +++ b/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
@@ -21,6 +21,7 @@ "gyroscope", "magnetometer", // "clipboard", + "wake-lock", // Non-standard: "accessibility-events",
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.cc b/third_party/blink/renderer/modules/permissions/permission_utils.cc index 4fd6403..f14b0be 100644 --- a/third_party/blink/renderer/modules/permissions/permission_utils.cc +++ b/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -69,4 +69,15 @@ return descriptor; } +PermissionDescriptorPtr CreateWakeLockPermissionDescriptor( + mojom::blink::WakeLockType type) { + auto descriptor = + CreatePermissionDescriptor(mojom::blink::PermissionName::WAKE_LOCK); + auto wake_lock_extension = + mojom::blink::WakeLockPermissionDescriptor::New(type); + descriptor->extension = mojom::blink::PermissionDescriptorExtension::New(); + descriptor->extension->set_wake_lock(std::move(wake_lock_extension)); + return descriptor; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.h b/third_party/blink/renderer/modules/permissions/permission_utils.h index a199659..688e2de 100644 --- a/third_party/blink/renderer/modules/permissions/permission_utils.h +++ b/third_party/blink/renderer/modules/permissions/permission_utils.h
@@ -27,6 +27,9 @@ mojom::blink::PermissionName, bool allow_without_gesture); +mojom::blink::PermissionDescriptorPtr CreateWakeLockPermissionDescriptor( + mojom::blink::WakeLockType type); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSION_UTILS_H_
diff --git a/third_party/blink/renderer/modules/permissions/permissions.cc b/third_party/blink/renderer/modules/permissions/permissions.cc index 443a59a..d200c02 100644 --- a/third_party/blink/renderer/modules/permissions/permissions.cc +++ b/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_midi_permission_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_permission_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_push_permission_descriptor.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_permission_descriptor.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -152,6 +153,26 @@ } return CreatePermissionDescriptor(PermissionName::PERIODIC_BACKGROUND_SYNC); } + if (name == "wake-lock") { + if (!RuntimeEnabledFeatures::WakeLockEnabled()) { + exception_state.ThrowTypeError("Wake Lock is not enabled."); + return nullptr; + } + WakeLockPermissionDescriptor* wake_lock_permission = + NativeValueTraits<WakeLockPermissionDescriptor>::NativeValue( + script_state->GetIsolate(), raw_permission.V8Value(), + exception_state); + const String& type = wake_lock_permission->type(); + if (type == "screen") { + return CreateWakeLockPermissionDescriptor( + mojom::blink::WakeLockType::kScreen); + } else if (type == "system") { + return CreateWakeLockPermissionDescriptor( + mojom::blink::WakeLockType::kSystem); + } else { + NOTREACHED(); + } + } return nullptr; }
diff --git a/third_party/blink/renderer/modules/permissions/wake_lock_permission_descriptor.idl b/third_party/blink/renderer/modules/permissions/wake_lock_permission_descriptor.idl new file mode 100644 index 0000000..9aee7dc --- /dev/null +++ b/third_party/blink/renderer/modules/permissions/wake_lock_permission_descriptor.idl
@@ -0,0 +1,8 @@ +// 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. + +// https://w3c.github.io/wake-lock/#the-wakelockpermissiondescriptor-dictionary +dictionary WakeLockPermissionDescriptor : PermissionDescriptor { + WakeLockType type; +};
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc index 8d9f136..0be2bf7 100644 --- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc +++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -17,6 +17,7 @@ #include "third_party/blink/renderer/core/html/media/html_video_element.h" #include "third_party/blink/renderer/core/html/media/remote_playback_observer.h" #include "third_party/blink/renderer/core/html_names.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/presentation/presentation_availability_state.h" @@ -50,7 +51,7 @@ void RunRemotePlaybackTask(ExecutionContext* context, base::OnceClosure task, - std::unique_ptr<int> task_id) { + std::unique_ptr<probe::AsyncTaskId> task_id) { probe::AsyncTask async_task(context, task_id.get()); std::move(task).Run(); } @@ -260,7 +261,9 @@ // task id. base::OnceClosure task = WTF::Bind(&RemotePlayback::PromptCancelled, WrapPersistent(this)); - std::unique_ptr<int> task_id = std::make_unique<int>(0); + + std::unique_ptr<probe::AsyncTaskId> task_id = + std::make_unique<probe::AsyncTaskId>(); probe::AsyncTaskScheduled(GetExecutionContext(), "promptCancelled", task_id.get()); GetExecutionContext() @@ -290,7 +293,8 @@ // We can remove the wrapper if InspectorInstrumentation returns a task id. base::OnceClosure task = WTF::Bind(&RemotePlayback::NotifyInitialAvailability, WrapPersistent(this), id); - std::unique_ptr<int> task_id = std::make_unique<int>(0); + std::unique_ptr<probe::AsyncTaskId> task_id = + std::make_unique<probe::AsyncTaskId>(); probe::AsyncTaskScheduled(GetExecutionContext(), "watchAvailabilityCallback", task_id.get()); GetExecutionContext()
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc index be196b3f..d91687c 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc +++ b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
@@ -187,8 +187,8 @@ ExecutionContext* context, int fetch_event_id, const KURL& request_url, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchRedirectMode redirect_mode, + network::mojom::RequestMode request_mode, + network::mojom::RedirectMode redirect_mode, network::mojom::RequestContextFrameType frame_type, mojom::RequestContextType request_context, WaitUntilObserver* observer) { @@ -243,13 +243,13 @@ return; } if (response_type == network::mojom::FetchResponseType::kCors && - request_mode_ == network::mojom::FetchRequestMode::kSameOrigin) { + request_mode_ == network::mojom::RequestMode::kSameOrigin) { OnResponseRejected( ServiceWorkerResponseError::kResponseTypeCorsForRequestModeSameOrigin); return; } if (response_type == network::mojom::FetchResponseType::kOpaque) { - if (request_mode_ != network::mojom::FetchRequestMode::kNoCors) { + if (request_mode_ != network::mojom::RequestMode::kNoCors) { OnResponseRejected(ServiceWorkerResponseError::kResponseTypeOpaque); return; } @@ -265,12 +265,12 @@ return; } } - if (redirect_mode_ != network::mojom::FetchRedirectMode::kManual && + if (redirect_mode_ != network::mojom::RedirectMode::kManual && response_type == network::mojom::FetchResponseType::kOpaqueRedirect) { OnResponseRejected(ServiceWorkerResponseError::kResponseTypeOpaqueRedirect); return; } - if (redirect_mode_ != network::mojom::FetchRedirectMode::kFollow && + if (redirect_mode_ != network::mojom::RedirectMode::kFollow && response->redirected()) { OnResponseRejected( ServiceWorkerResponseError::kRedirectedResponseForNotFollowRequest); @@ -366,8 +366,8 @@ ExecutionContext* context, int fetch_event_id, const KURL& request_url, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchRedirectMode redirect_mode, + network::mojom::RequestMode request_mode, + network::mojom::RedirectMode redirect_mode, network::mojom::RequestContextFrameType frame_type, mojom::RequestContextType request_context, WaitUntilObserver* observer)
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h index 631ed37..d21e51a 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h +++ b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h
@@ -25,8 +25,8 @@ FetchRespondWithObserver(ExecutionContext*, int fetch_event_id, const KURL& request_url, - network::mojom::FetchRequestMode, - network::mojom::FetchRedirectMode, + network::mojom::RequestMode, + network::mojom::RedirectMode, network::mojom::RequestContextFrameType, mojom::RequestContextType, WaitUntilObserver*); @@ -36,8 +36,8 @@ ExecutionContext*, int fetch_event_id, const KURL& request_url, - network::mojom::FetchRequestMode, - network::mojom::FetchRedirectMode, + network::mojom::RequestMode, + network::mojom::RedirectMode, network::mojom::RequestContextFrameType, mojom::RequestContextType, WaitUntilObserver*); @@ -53,8 +53,8 @@ private: const KURL request_url_; - const network::mojom::FetchRequestMode request_mode_; - const network::mojom::FetchRedirectMode redirect_mode_; + const network::mojom::RequestMode request_mode_; + const network::mojom::RedirectMode redirect_mode_; const network::mojom::RequestContextFrameType frame_type_; const mojom::RequestContextType request_context_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index 7d7b48e5..1e600aac 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -288,8 +288,8 @@ *this, CreateOutsideSettingsFetcher(outside_settings_object, outside_resource_timing_notifier), - script_url, destination, network::mojom::FetchRequestMode::kSameOrigin, - network::mojom::FetchCredentialsMode::kSameOrigin, + script_url, destination, network::mojom::RequestMode::kSameOrigin, + network::mojom::CredentialsMode::kSameOrigin, WTF::Bind(&ServiceWorkerGlobalScope::DidReceiveResponseForClassicScript, WrapWeakPersistent(this), WrapPersistent(classic_script_loader)), @@ -302,7 +302,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { DCHECK(IsContextThread()); FetchModuleScript(module_url_record, outside_settings_object, outside_resource_timing_notifier, @@ -358,7 +358,7 @@ void ServiceWorkerGlobalScope::RunInstalledModuleScript( const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { DCHECK(IsContextThread()); // Currently we don't plumb performance timing for toplevel service worker // script fetch. https://crbug.com/954005
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index da42cdb4..9f92e64 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -110,7 +110,7 @@ const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, - network::mojom::FetchCredentialsMode) override; + network::mojom::CredentialsMode) override; void Dispose() override; // Runs the installed top-level classic worker script for the 'installed' @@ -123,7 +123,7 @@ void RunInstalledModuleScript( const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, - network::mojom::FetchCredentialsMode); + network::mojom::CredentialsMode); // Counts an evaluated script and its size. Called for the main worker script. void CountWorkerScript(size_t script_size, size_t cached_metadata_size);
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc b/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc index 9c735f6..42b9051 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
@@ -89,7 +89,7 @@ void ServiceWorkerThread::RunInstalledModuleScript( const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { PostCrossThreadTask( *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE, CrossThreadBindOnce( @@ -110,7 +110,7 @@ const KURL& module_url_record, std::unique_ptr<CrossThreadFetchClientSettingsObjectData> outside_settings_object, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { DCHECK(IsCurrentThread()); To<ServiceWorkerGlobalScope>(GlobalScope()) ->RunInstalledModuleScript(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_thread.h b/third_party/blink/renderer/modules/service_worker/service_worker_thread.h index 2cf6ecf7..269e84bd 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_thread.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_thread.h
@@ -64,7 +64,7 @@ void RunInstalledModuleScript( const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, - network::mojom::FetchCredentialsMode); + network::mojom::CredentialsMode); private: WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope( @@ -81,7 +81,7 @@ const KURL& module_url_record, std::unique_ptr<CrossThreadFetchClientSettingsObjectData> outside_settings_object, - network::mojom::FetchCredentialsMode); + network::mojom::CredentialsMode); Persistent<ServiceWorkerGlobalScopeProxy> global_scope_proxy_; std::unique_ptr<WorkerBackingThread> worker_backing_thread_;
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc index 36002e77..af419ba 100644 --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -362,6 +362,11 @@ V8PersistentCallbackFunction<V8DecodeErrorCallback>* error_callback) { DCHECK(IsMainThread()); + if (!GetExecutionContext()) { + // Nothing to do if the execution context is gone. + return; + } + if (audio_buffer) { // Resolve promise successfully and run the success callback resolver->Resolve(audio_buffer);
diff --git a/third_party/blink/renderer/modules/webdatabase/database.cc b/third_party/blink/renderer/modules/webdatabase/database.cc index c413db01..d0e9ecee 100644 --- a/third_party/blink/renderer/modules/webdatabase/database.cc +++ b/third_party/blink/renderer/modules/webdatabase/database.cc
@@ -35,6 +35,7 @@ #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/webdatabase/change_version_data.h" #include "third_party/blink/renderer/modules/webdatabase/change_version_wrapper.h" @@ -294,14 +295,15 @@ << "Scheduling DatabaseCreationCallbackTask for database " << this; auto* v8persistent_callback = ToV8PersistentCallbackFunction(creation_callback); + auto task_id = std::make_unique<probe::AsyncTaskId>(); probe::AsyncTaskScheduled(GetExecutionContext(), "openDatabase", - v8persistent_callback); + task_id.get()); GetExecutionContext() ->GetTaskRunner(TaskType::kDatabaseAccess) - ->PostTask( - FROM_HERE, - WTF::Bind(&Database::RunCreationCallback, WrapPersistent(this), - WrapPersistent(v8persistent_callback))); + ->PostTask(FROM_HERE, WTF::Bind(&Database::RunCreationCallback, + WrapPersistent(this), + WrapPersistent(v8persistent_callback), + std::move(task_id))); } } @@ -309,8 +311,9 @@ } void Database::RunCreationCallback( - V8PersistentCallbackFunction<V8DatabaseCallback>* creation_callback) { - probe::AsyncTask async_task(GetExecutionContext(), creation_callback); + V8PersistentCallbackFunction<V8DatabaseCallback>* creation_callback, + std::unique_ptr<probe::AsyncTaskId> task_id) { + probe::AsyncTask async_task(GetExecutionContext(), task_id.get()); creation_callback->InvokeAndReportException(nullptr, this); }
diff --git a/third_party/blink/renderer/modules/webdatabase/database.h b/third_party/blink/renderer/modules/webdatabase/database.h index d8c509f..9399bb56 100644 --- a/third_party/blink/renderer/modules/webdatabase/database.h +++ b/third_party/blink/renderer/modules/webdatabase/database.h
@@ -138,7 +138,8 @@ DatabaseError&, String& error_message); void RunCreationCallback( - V8PersistentCallbackFunction<V8DatabaseCallback>* creation_callback); + V8PersistentCallbackFunction<V8DatabaseCallback>* creation_callback, + std::unique_ptr<probe::AsyncTaskId> task_id); void ScheduleTransaction();
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_statement.cc b/third_party/blink/renderer/modules/webdatabase/sql_statement.cc index 5daf639..c5a0fce 100644 --- a/third_party/blink/renderer/modules/webdatabase/sql_statement.cc +++ b/third_party/blink/renderer/modules/webdatabase/sql_statement.cc
@@ -90,7 +90,7 @@ if (HasCallback() || HasErrorCallback()) { probe::AsyncTaskScheduled(database->GetExecutionContext(), "SQLStatement", - this); + &async_task_id_); } } @@ -123,7 +123,7 @@ SQLErrorData* error = backend_->SqlError(); probe::AsyncTask async_task(transaction->GetDatabase()->GetExecutionContext(), - this); + &async_task_id_); // Call the appropriate statement callback and track if it resulted in an // error, because then we need to jump to the transaction error callback.
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_statement.h b/third_party/blink/renderer/modules/webdatabase/sql_statement.h index 7fd086c4..a41a970b 100644 --- a/third_party/blink/renderer/modules/webdatabase/sql_statement.h +++ b/third_party/blink/renderer/modules/webdatabase/sql_statement.h
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_sql_statement_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_sql_statement_error_callback.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/modules/webdatabase/sql_result_set.h" #include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -120,6 +121,8 @@ Member<OnSuccessCallback> success_callback_; Member<OnErrorCallback> error_callback_; + + probe::AsyncTaskId async_task_id_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc index ca901e6..d8d85d1 100644 --- a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc +++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
@@ -103,7 +103,8 @@ read_only_(read_only) { DCHECK(IsMainThread()); DCHECK(database_); - probe::AsyncTaskScheduled(db->GetExecutionContext(), "SQLTransaction", this); + probe::AsyncTaskScheduled(db->GetExecutionContext(), "SQLTransaction", + &async_task_id_); } SQLTransaction::~SQLTransaction() = default; @@ -184,7 +185,7 @@ SQLTransactionState SQLTransaction::DeliverTransactionCallback() { bool should_deliver_error_callback = false; - probe::AsyncTask async_task(database_->GetExecutionContext(), this, + probe::AsyncTask async_task(database_->GetExecutionContext(), &async_task_id_, "transaction"); // Spec 4.3.2 4: Invoke the transaction callback with the new SQLTransaction @@ -208,7 +209,8 @@ } SQLTransactionState SQLTransaction::DeliverTransactionErrorCallback() { - probe::AsyncTask async_task(database_->GetExecutionContext(), this); + probe::AsyncTask async_task(database_->GetExecutionContext(), + &async_task_id_); // Spec 4.3.2.10: If exists, invoke error callback with the last // error to have occurred in this transaction. @@ -272,7 +274,8 @@ SQLTransactionState SQLTransaction::DeliverSuccessCallback() { DCHECK(IsMainThread()); - probe::AsyncTask async_task(database_->GetExecutionContext(), this); + probe::AsyncTask async_task(database_->GetExecutionContext(), + &async_task_id_); // Spec 4.3.2.8: Deliver success callback. if (OnSuccessCallback* success_callback = success_callback_.Release())
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction.h b/third_party/blink/renderer/modules/webdatabase/sql_transaction.h index 7ba7863..f2ecb13 100644 --- a/third_party/blink/renderer/modules/webdatabase/sql_transaction.h +++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction.h
@@ -36,6 +36,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_sql_transaction_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_sql_transaction_error_callback.h" +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/modules/webdatabase/sql_statement.h" #include "third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -205,6 +206,7 @@ bool execute_sql_allowed_; std::unique_ptr<SQLErrorData> transaction_error_; + probe::AsyncTaskId async_task_id_; bool read_only_; };
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc index ebfc60d..3a5597ff 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
@@ -61,6 +61,13 @@ ContextGL()->DispatchCompute(numGroupsX, numGroupsY, numGroupsZ); } +void WebGL2ComputeRenderingContextBase::dispatchComputeIndirect( + int64_t offset) { + if (!ValidateValueFitNonNegInt32("dispatchComputeIndirect", "offset", offset)) + return; + ContextGL()->DispatchComputeIndirect(static_cast<GLintptr>(offset)); +} + ScriptValue WebGL2ComputeRenderingContextBase::getProgramInterfaceParameter( ScriptState* script_state, WebGLProgram* program,
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h index 2d39ac9..28b4954 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
@@ -19,6 +19,7 @@ /* Launch one or more compute work groups */ void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); + void dispatchComputeIndirect(int64_t offset); /* Program interface query */ ScriptValue getProgramInterfaceParameter(ScriptState*,
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl index 625d5a6..30e42ab 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl
@@ -92,6 +92,7 @@ const GLenum UNSIGNED_INT_ATOMIC_COUNTER = 0x92DB; void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); + void dispatchComputeIndirect(GLintptr offset); /* Program interface query */ [CallWith=ScriptState] any getProgramInterfaceParameter(WebGLProgram program, GLenum programInterface, GLenum pname);
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc index ade68bc..c76da3fa 100644 --- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc +++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -679,7 +679,9 @@ NETWORK_DVLOG(1) << "WebSocket " << this << " contextDestroyed()"; event_queue_->ContextDestroyed(); if (channel_) { - channel_->Close(WebSocketChannel::kCloseEventCodeGoingAway, String()); + if (state_ == kOpen) { + channel_->Close(WebSocketChannel::kCloseEventCodeGoingAway, String()); + } ReleaseChannel(); } if (state_ != kClosed)
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index a28dc458..ca2d2d0 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -521,8 +521,9 @@ } void WebSocketChannelImpl::AddReceiveFlowControlIfNecessary() { - if (!handle_ || received_data_size_for_flow_control_ < - kReceivedDataSizeForFlowControlHighWaterMark) { + DCHECK(receive_quota_threshold_.has_value()); + if (!handle_ || + received_data_size_for_flow_control_ < receive_quota_threshold_.value()) { return; } handle_->AddReceiveFlowControlQuota(received_data_size_for_flow_control_); @@ -530,10 +531,10 @@ } void WebSocketChannelImpl::InitialReceiveFlowControl() { + DCHECK(receive_quota_threshold_.has_value()); DCHECK_EQ(received_data_size_for_flow_control_, 0u); DCHECK(handle_); - handle_->AddReceiveFlowControlQuota( - kReceivedDataSizeForFlowControlHighWaterMark * 2); + handle_->AddReceiveFlowControlQuota(receive_quota_threshold_.value() * 2); } void WebSocketChannelImpl::AbortAsyncOperations() { @@ -548,6 +549,7 @@ const String& reason) { handshake_throttle_.reset(); handle_.reset(); + receive_quota_threshold_.reset(); AbortAsyncOperations(); if (!client_) { return; @@ -562,15 +564,18 @@ void WebSocketChannelImpl::DidConnect(WebSocketHandle* handle, const String& selected_protocol, - const String& extensions) { + const String& extensions, + uint64_t receive_quota_threshold) { NETWORK_DVLOG(1) << this << " DidConnect(" << handle << ", " << String(selected_protocol) << ", " << String(extensions) - << ")"; + << ", " << receive_quota_threshold << ")"; DCHECK(handle_); DCHECK_EQ(handle, handle_.get()); DCHECK(client_); + receive_quota_threshold_ = receive_quota_threshold; + if (!throttle_passed_) { connect_info_ = std::make_unique<ConnectInfo>(selected_protocol, extensions);
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h index 47bac2f..d96d12e 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -156,7 +156,8 @@ // WebSocketHandleClient functions. void DidConnect(WebSocketHandle*, const String& selected_protocol, - const String& extensions) override; + const String& extensions, + uint64_t receive_quota_threshold) override; void DidStartOpeningHandshake( WebSocketHandle*, network::mojom::blink::WebSocketHandshakeRequestPtr) override; @@ -219,7 +220,7 @@ scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_; - static const uint64_t kReceivedDataSizeForFlowControlHighWaterMark = 1 << 15; + base::Optional<uint64_t> receive_quota_threshold_; }; std::ostream& operator<<(std::ostream&, const WebSocketChannelImpl*);
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc index 007cee33..de03ade 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
@@ -166,7 +166,8 @@ EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b"))); } EXPECT_TRUE(Channel()->Connect(KURL("ws://localhost/"), "x")); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); testing::Mock::VerifyAndClearExpectations(this); } @@ -176,6 +177,8 @@ MockWebSocketHandshakeThrottle* handshake_throttle_; Persistent<WebSocketChannelImpl> channel_; uint64_t sum_of_consumed_buffered_amount_; + + static const uint64_t kDefaultReceiveQuotaThreshold = 1 << 15; }; MATCHER_P2(MemEq, @@ -221,7 +224,8 @@ EXPECT_EQ("x", protocols[0]); checkpoint.Call(1); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); } TEST_F(WebSocketChannelImplTest, sendText) { @@ -834,7 +838,8 @@ checkpoint.Call(1); ChannelImpl()->OnCompletion(base::nullopt); checkpoint.Call(2); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); } TEST_F(WebSocketChannelImplHandshakeThrottleTest, HandshakeSucceedsFirst) { @@ -850,7 +855,8 @@ } Channel()->Connect(url(), ""); checkpoint.Call(1); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); checkpoint.Call(2); ChannelImpl()->OnCompletion(base::nullopt); } @@ -887,7 +893,8 @@ EXPECT_CALL(checkpoint, Call(1)); } Channel()->Connect(url(), ""); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); Channel()->Fail("close during handshake", mojom::ConsoleMessageLevel::kWarning, std::make_unique<SourceLocation>(String(), 0, 0, nullptr)); @@ -920,7 +927,8 @@ EXPECT_CALL(checkpoint, Call(1)); } Channel()->Connect(url(), ""); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); Channel()->Close(WebSocketChannelImpl::kCloseEventCodeGoingAway, ""); checkpoint.Call(1); } @@ -948,7 +956,8 @@ EXPECT_CALL(checkpoint, Call(1)); } Channel()->Connect(url(), ""); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); Channel()->Disconnect(); checkpoint.Call(1); } @@ -976,7 +985,8 @@ EXPECT_CALL(*ChannelClient(), DidClose(_, _, _)); } Channel()->Connect(url(), ""); - HandleClient()->DidConnect(Handle(), String("a"), String("b")); + HandleClient()->DidConnect(Handle(), String("a"), String("b"), + kDefaultReceiveQuotaThreshold); ChannelImpl()->OnCompletion("Connection blocked by throttle"); }
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle_client.h b/third_party/blink/renderer/modules/websockets/websocket_handle_client.h index b353160..86e230b 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_handle_client.h +++ b/third_party/blink/renderer/modules/websockets/websocket_handle_client.h
@@ -42,7 +42,8 @@ // Called when the handle is opened. virtual void DidConnect(WebSocketHandle*, const String& selected_protocol, - const String& extensions) = 0; + const String& extensions, + uint64_t receive_quota_threshold) = 0; // Called when the browser starts the opening handshake. // This notification can be omitted when the inspector is not active.
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc index 7b5a0df7..f4f0eab 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
@@ -164,15 +164,17 @@ client_->DidFinishOpeningHandshake(this, std::move(response)); } -void WebSocketHandleImpl::OnAddChannelResponse(const String& protocol, - const String& extensions) { +void WebSocketHandleImpl::OnAddChannelResponse( + const String& protocol, + const String& extensions, + uint64_t receive_quota_threshold) { NETWORK_DVLOG(1) << this << " OnAddChannelResponse(" << protocol << ", " - << extensions << ")"; + << extensions << ", " << receive_quota_threshold << ")"; if (!client_) return; - client_->DidConnect(this, protocol, extensions); + client_->DidConnect(this, protocol, extensions, receive_quota_threshold); // |this| can be deleted here. }
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h index 482d51d..0f6a0cf 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h +++ b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h
@@ -68,7 +68,8 @@ void OnFinishOpeningHandshake( network::mojom::blink::WebSocketHandshakeResponsePtr) override; void OnAddChannelResponse(const String& selected_protocol, - const String& extensions) override; + const String& extensions, + uint64_t receive_quota_threshold) override; // network::mojom::blink::WebSocketClient methods: void OnDataFrame(bool fin, network::mojom::blink::WebSocketMessageType,
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc index 8f799cd..613701c 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc
@@ -12,6 +12,15 @@ namespace blink { +XRFrameRequestCallbackCollection::CallbackAndTask::CallbackAndTask( + V8XRFrameRequestCallback* callback) + : callback(callback) {} + +void XRFrameRequestCallbackCollection::CallbackAndTask::Trace( + blink::Visitor* visitor) { + visitor->Trace(callback); +} + XRFrameRequestCallbackCollection::XRFrameRequestCallbackCollection( ExecutionContext* context) : context_(context) {} @@ -20,10 +29,12 @@ XRFrameRequestCallbackCollection::RegisterCallback( V8XRFrameRequestCallback* callback) { CallbackId id = ++next_callback_id_; - callbacks_.Set(id, callback); + auto* callback_and_task = MakeGarbageCollected<CallbackAndTask>(callback); + callbacks_.Set(id, callback_and_task); pending_callbacks_.push_back(id); - probe::AsyncTaskScheduledBreakable(context_, "XRRequestFrame", callback); + probe::AsyncTaskScheduledBreakable(context_, "XRRequestFrame", + &callback_and_task->task_id); return id; } @@ -58,9 +69,9 @@ if (it == current_callbacks_.end()) continue; - probe::AsyncTask async_task(context_, it->value); + probe::AsyncTask async_task(context_, &it->value->task_id); probe::UserCallback probe(context_, "XRRequestFrame", AtomicString(), true); - it->value->InvokeAndReportException(session, timestamp, frame); + it->value->callback->InvokeAndReportException(session, timestamp, frame); } current_callbacks_.clear();
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h index f61136f5..6de9aa1 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h +++ b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_FRAME_REQUEST_CALLBACK_COLLECTION_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_FRAME_REQUEST_CALLBACK_COLLECTION_H_ +#include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -40,7 +41,15 @@ !WTF::IsHashTraitsEmptyValue<Traits, CallbackId>(id); } - using CallbackMap = HeapHashMap<CallbackId, Member<V8XRFrameRequestCallback>>; + struct CallbackAndTask : public GarbageCollectedFinalized { + explicit CallbackAndTask(V8XRFrameRequestCallback* callback); + void Trace(blink::Visitor* visitor); + + Member<V8XRFrameRequestCallback> callback; + probe::AsyncTaskId task_id; + }; + + using CallbackMap = HeapHashMap<CallbackId, Member<CallbackAndTask>>; CallbackMap callbacks_; Vector<CallbackId> pending_callbacks_;
diff --git a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc index 1b339b18..dd81d4b 100644 --- a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc +++ b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
@@ -72,7 +72,7 @@ return FloatPoint(target.x(), target.y()); } -void CompositorScrollOffsetAnimationCurve::UpdateTarget(TimeDelta time, +void CompositorScrollOffsetAnimationCurve::UpdateTarget(base::TimeDelta time, FloatPoint new_target) { curve_->UpdateTarget(time, gfx::ScrollOffset(new_target.X(), new_target.Y())); }
diff --git a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h index 4ed3a5a..4a640f9d 100644 --- a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h +++ b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
@@ -40,7 +40,7 @@ double Duration() const; FloatPoint TargetValue() const; void ApplyAdjustment(IntSize); - void UpdateTarget(TimeDelta time, FloatPoint new_target); + void UpdateTarget(base::TimeDelta time, FloatPoint new_target); // CompositorAnimationCurve implementation. std::unique_ptr<cc::AnimationCurve> CloneToAnimationCurve() const override;
diff --git a/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc b/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc index e9a1443..ee15599 100644 --- a/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc +++ b/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
@@ -67,7 +67,7 @@ *client_thread_->GetTaskRunner(), FROM_HERE, CrossThreadBindOnce(&FIFOClient::RunTaskOnOwnThread, CrossThreadUnretained(this)), - TimeDelta::FromMillisecondsD(interval_with_jitter)); + base::TimeDelta::FromMillisecondsD(interval_with_jitter)); } else { Stop(counter_); done_event_->Signal();
diff --git a/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc b/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc index 69883bb..acfa964 100644 --- a/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc +++ b/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc
@@ -37,16 +37,16 @@ DCHECK(!IsRunning()); counter_ = counter; parent_ = parent; - start_ticks_ = TimeTicks(clock_->NowTicks()); + start_ticks_ = base::TimeTicks(clock_->NowTicks()); if (parent_) parent_->Pause(start_ticks_); } RuntimeCallTimer* RuntimeCallTimer::Stop() { DCHECK(IsRunning()); - TimeTicks now = TimeTicks(clock_->NowTicks()); + base::TimeTicks now = base::TimeTicks(clock_->NowTicks()); elapsed_time_ += (now - start_ticks_); - start_ticks_ = TimeTicks(); + start_ticks_ = base::TimeTicks(); counter_->IncrementAndAddTime(elapsed_time_); if (parent_) parent_->Resume(now);
diff --git a/third_party/blink/renderer/platform/bindings/runtime_call_stats.h b/third_party/blink/renderer/platform/bindings/runtime_call_stats.h index 845865c..20542c2 100644 --- a/third_party/blink/renderer/platform/bindings/runtime_call_stats.h +++ b/third_party/blink/renderer/platform/bindings/runtime_call_stats.h
@@ -38,17 +38,17 @@ public: explicit RuntimeCallCounter(const char* name) : count_(0), name_(name) {} - void IncrementAndAddTime(TimeDelta time) { + void IncrementAndAddTime(base::TimeDelta time) { count_++; time_ += time; } uint64_t GetCount() const { return count_; } - TimeDelta GetTime() const { return time_; } + base::TimeDelta GetTime() const { return time_; } const char* GetName() const { return name_; } void Reset() { - time_ = TimeDelta(); + time_ = base::TimeDelta(); count_ = 0; } @@ -58,7 +58,7 @@ RuntimeCallCounter() = default; uint64_t count_; - TimeDelta time_; + base::TimeDelta time_; const char* name_; friend class RuntimeCallStats; @@ -84,28 +84,28 @@ // Resets the timer. Call this before reusing a timer. void Reset() { - start_ticks_ = TimeTicks(); - elapsed_time_ = TimeDelta(); + start_ticks_ = base::TimeTicks(); + elapsed_time_ = base::TimeDelta(); } private: - void Pause(TimeTicks now) { + void Pause(base::TimeTicks now) { DCHECK(IsRunning()); elapsed_time_ += (now - start_ticks_); - start_ticks_ = TimeTicks(); + start_ticks_ = base::TimeTicks(); } - void Resume(TimeTicks now) { + void Resume(base::TimeTicks now) { DCHECK(!IsRunning()); start_ticks_ = now; } - bool IsRunning() { return start_ticks_ != TimeTicks(); } + bool IsRunning() { return start_ticks_ != base::TimeTicks(); } RuntimeCallCounter* counter_; RuntimeCallTimer* parent_; - TimeTicks start_ticks_; - TimeDelta elapsed_time_; + base::TimeTicks start_ticks_; + base::TimeDelta elapsed_time_; const base::TickClock* clock_ = nullptr; };
diff --git a/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc b/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc index 7d4061b1..3b776a5 100644 --- a/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc +++ b/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc
@@ -24,8 +24,9 @@ public: void SetUp() override { // Add one millisecond because RuntimeCallTimer uses |start_ticks_| = - // TimeTicks() to represent that the timer is not running. - clock_.SetNowTicks(base::TimeTicks() + TimeDelta::FromMilliseconds(1)); + // base::TimeTicks() to represent that the timer is not running. + clock_.SetNowTicks(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(1)); } void TearDown() override { @@ -33,7 +34,7 @@ } void AdvanceClock(int milliseconds) { - clock_.Advance(TimeDelta::FromMilliseconds(milliseconds)); + clock_.Advance(base::TimeDelta::FromMilliseconds(milliseconds)); } const base::TickClock* clock() { return &clock_; }
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc b/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc index 1ff6f56e..f0ad17e8 100644 --- a/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc +++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
@@ -145,14 +145,14 @@ uint64_t file_offset) { base::FilePath path; base::CreateTemporaryFile(&path); - base::Optional<WTF::Time> received_modified; + base::Optional<base::Time> received_modified; test_provider_->RequestAsFile( source_offset, source_length, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), file_offset, base::BindOnce( - [](base::Optional<WTF::Time>* received_modified, - base::Optional<WTF::Time> modified) { + [](base::Optional<base::Time>* received_modified, + base::Optional<base::Time> modified) { *received_modified = modified; }, &received_modified)); @@ -227,7 +227,7 @@ test_provider_->RequestAsFile( test.offset, test.size, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), - file_offset, base::BindOnce([](base::Optional<WTF::Time> last_modified) { + file_offset, base::BindOnce([](base::Optional<base::Time> last_modified) { EXPECT_TRUE(last_modified); })); @@ -274,7 +274,7 @@ provider->RequestAsFile( i, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), combined_bytes_.size() - i - 16, - base::BindOnce([](base::Optional<WTF::Time> last_modified) { + base::BindOnce([](base::Optional<base::Time> last_modified) { EXPECT_TRUE(last_modified); })); expected_data.insert(0, combined_bytes_.data() + i, 16); @@ -298,7 +298,7 @@ provider->RequestAsFile( 0, 16, base::File(), 0, - base::BindOnce([](base::Optional<WTF::Time> last_modified) { + base::BindOnce([](base::Optional<base::Time> last_modified) { EXPECT_FALSE(last_modified); })); } @@ -310,7 +310,7 @@ base::CreateTemporaryFile(&path); provider->RequestAsFile( 0, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ), 0, - base::BindOnce([](base::Optional<WTF::Time> last_modified) { + base::BindOnce([](base::Optional<base::Time> last_modified) { EXPECT_FALSE(last_modified); }));
diff --git a/third_party/blink/renderer/platform/blob/blob_data.cc b/third_party/blink/renderer/platform/blob/blob_data.cc index 55756232..195e5e4 100644 --- a/third_party/blink/renderer/platform/blob/blob_data.cc +++ b/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -120,7 +120,7 @@ std::unique_ptr<BlobData> data = base::WrapUnique( new BlobData(FileCompositionStatus::SINGLE_UNKNOWN_SIZE_FILE)); data->elements_.push_back(DataElement::NewFile(DataElementFile::New( - WebStringToFilePath(path), 0, BlobData::kToEndOfFile, WTF::Time()))); + WebStringToFilePath(path), 0, BlobData::kToEndOfFile, base::Time()))); return data; } @@ -131,7 +131,7 @@ new BlobData(FileCompositionStatus::SINGLE_UNKNOWN_SIZE_FILE)); data->elements_.push_back(DataElement::NewFile(DataElementFile::New( WebStringToFilePath(path), 0, BlobData::kToEndOfFile, - WTF::Time::FromDoubleT(expected_modification_time)))); + base::Time::FromDoubleT(expected_modification_time)))); return data; } @@ -143,7 +143,7 @@ data->elements_.push_back( DataElement::NewFileFilesystem(DataElementFilesystemURL::New( file_system_url, 0, BlobData::kToEndOfFile, - WTF::Time::FromDoubleT(expected_modification_time)))); + base::Time::FromDoubleT(expected_modification_time)))); return data; } @@ -184,7 +184,7 @@ return; elements_.push_back(DataElement::NewFile(DataElementFile::New( WebStringToFilePath(path), offset, length, - WTF::Time::FromDoubleT(expected_modification_time)))); + base::Time::FromDoubleT(expected_modification_time)))); } void BlobData::AppendBlob(scoped_refptr<BlobDataHandle> data_handle, @@ -213,7 +213,7 @@ elements_.push_back( DataElement::NewFileFilesystem(DataElementFilesystemURL::New( url, offset, length, - WTF::Time::FromDoubleT(expected_modification_time)))); + base::Time::FromDoubleT(expected_modification_time)))); } void BlobData::AppendText(const String& text,
diff --git a/third_party/blink/renderer/platform/blob/blob_data_test.cc b/third_party/blink/renderer/platform/blob/blob_data_test.cc index 2657150..6d733071 100644 --- a/third_party/blink/renderer/platform/blob/blob_data_test.cc +++ b/third_party/blink/renderer/platform/blob/blob_data_test.cc
@@ -59,7 +59,7 @@ static ExpectedElement File(const String& path, uint64_t offset, uint64_t length, - WTF::Time time) { + base::Time time) { return ExpectedElement{DataElement::NewFile( DataElementFile::New(WebStringToFilePath(path), offset, length, time))}; } @@ -67,7 +67,7 @@ static ExpectedElement FileFilesystem(const KURL& url, uint64_t offset, uint64_t length, - WTF::Time time) { + base::Time time) { return ExpectedElement{DataElement::NewFileFilesystem( DataElementFilesystemURL::New(url, offset, length, time))}; } @@ -368,10 +368,10 @@ data->AppendFileSystemURL(url, 15, 876, timestamp2); Vector<ExpectedElement> expected_elements; - expected_elements.push_back( - ExpectedElement::File("path", 4, 32, WTF::Time::FromDoubleT(timestamp1))); + expected_elements.push_back(ExpectedElement::File( + "path", 4, 32, base::Time::FromDoubleT(timestamp1))); expected_elements.push_back(ExpectedElement::FileFilesystem( - url, 15, 876, WTF::Time::FromDoubleT(timestamp2))); + url, 15, 876, base::Time::FromDoubleT(timestamp2))); TestCreateBlob(std::move(data), std::move(expected_elements)); } @@ -379,7 +379,7 @@ TEST_F(BlobDataHandleTest, CreateFromFileWithUnknownSize) { Vector<ExpectedElement> expected_elements; expected_elements.push_back( - ExpectedElement::File("path", 0, uint64_t(-1), WTF::Time())); + ExpectedElement::File("path", 0, uint64_t(-1), base::Time())); TestCreateBlob(BlobData::CreateForFileWithUnknownSize("path"), std::move(expected_elements)); @@ -390,7 +390,7 @@ KURL url(NullURL(), "http://example.com/"); Vector<ExpectedElement> expected_elements; expected_elements.push_back(ExpectedElement::FileFilesystem( - url, 0, uint64_t(-1), WTF::Time::FromDoubleT(timestamp))); + url, 0, uint64_t(-1), base::Time::FromDoubleT(timestamp))); TestCreateBlob( BlobData::CreateForFileSystemURLWithUnknownSize(url, timestamp),
diff --git a/third_party/blink/renderer/platform/exported/mediastream/webaudio_media_stream_source.cc b/third_party/blink/renderer/platform/exported/mediastream/webaudio_media_stream_source.cc index 8d4398d..7e66eb77 100644 --- a/third_party/blink/renderer/platform/exported/mediastream/webaudio_media_stream_source.cc +++ b/third_party/blink/renderer/platform/exported/mediastream/webaudio_media_stream_source.cc
@@ -86,8 +86,8 @@ const WebVector<const float*>& audio_data, size_t number_of_frames) { // TODO(miu): Plumbing is needed to determine the actual capture timestamp - // of the audio, instead of just snapshotting TimeTicks::Now(), for proper - // audio/video sync. https://crbug.com/335335 + // of the audio, instead of just snapshotting base::TimeTicks::Now(), for + // proper audio/video sync. https://crbug.com/335335 current_reference_time_ = base::TimeTicks::Now(); wrapper_bus_->set_frames(number_of_frames);
diff --git a/third_party/blink/renderer/platform/exported/web_network_state_notifier.cc b/third_party/blink/renderer/platform/exported/web_network_state_notifier.cc index a293ff5..e571d4b 100644 --- a/third_party/blink/renderer/platform/exported/web_network_state_notifier.cc +++ b/third_party/blink/renderer/platform/exported/web_network_state_notifier.cc
@@ -44,8 +44,8 @@ } void WebNetworkStateNotifier::SetNetworkQuality(WebEffectiveConnectionType type, - TimeDelta http_rtt, - TimeDelta transport_rtt, + base::TimeDelta http_rtt, + base::TimeDelta transport_rtt, int downlink_throughput_kbps) { GetNetworkStateNotifier().SetNetworkQuality(type, http_rtt, transport_rtt, downlink_throughput_kbps);
diff --git a/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc b/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc index 9acf361..e2aad2d 100644 --- a/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc +++ b/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc
@@ -114,7 +114,7 @@ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> platform; - base::TimeTicks pseudo_time = TimeTicks::Now(); + base::TimeTicks pseudo_time = base::TimeTicks::Now(); WebResourceTimingInfo info = CreateWebResourceTimingInfo(pseudo_time); std::unique_ptr<Thread> thread = Platform::Current()->CreateThread(
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index d9516d8..aceed95 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -300,31 +300,28 @@ resource_request_->SetShouldResetAppCache(set_should_reset_app_cache); } -network::mojom::FetchRequestMode WebURLRequest::GetFetchRequestMode() const { - return resource_request_->GetFetchRequestMode(); +network::mojom::RequestMode WebURLRequest::GetMode() const { + return resource_request_->GetMode(); } -void WebURLRequest::SetFetchRequestMode(network::mojom::FetchRequestMode mode) { - return resource_request_->SetFetchRequestMode(mode); +void WebURLRequest::SetMode(network::mojom::RequestMode mode) { + return resource_request_->SetMode(mode); } -network::mojom::FetchCredentialsMode WebURLRequest::GetFetchCredentialsMode() - const { - return resource_request_->GetFetchCredentialsMode(); +network::mojom::CredentialsMode WebURLRequest::GetCredentialsMode() const { + return resource_request_->GetCredentialsMode(); } -void WebURLRequest::SetFetchCredentialsMode( - network::mojom::FetchCredentialsMode mode) { - return resource_request_->SetFetchCredentialsMode(mode); +void WebURLRequest::SetCredentialsMode(network::mojom::CredentialsMode mode) { + return resource_request_->SetCredentialsMode(mode); } -network::mojom::FetchRedirectMode WebURLRequest::GetFetchRedirectMode() const { - return resource_request_->GetFetchRedirectMode(); +network::mojom::RedirectMode WebURLRequest::GetRedirectMode() const { + return resource_request_->GetRedirectMode(); } -void WebURLRequest::SetFetchRedirectMode( - network::mojom::FetchRedirectMode redirect) { - return resource_request_->SetFetchRedirectMode(redirect); +void WebURLRequest::SetRedirectMode(network::mojom::RedirectMode redirect) { + return resource_request_->SetRedirectMode(redirect); } WebString WebURLRequest::GetFetchIntegrity() const {
diff --git a/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc b/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc index 16680772..85d9c44 100644 --- a/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc +++ b/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
@@ -620,10 +620,10 @@ } size_t FrameCount() override { return frame_count_; } int RepetitionCount() const override { return repetition_count_; } - TimeDelta FrameDuration() const override { return duration_; } + base::TimeDelta FrameDuration() const override { return duration_; } protected: - TimeDelta duration_; + base::TimeDelta duration_; int repetition_count_; size_t frame_count_; bool last_frame_complete_; @@ -652,7 +652,7 @@ } // Now the load is finished. - duration_ = TimeDelta::FromSeconds(1); + duration_ = base::TimeDelta::FromSeconds(1); repetition_count_ = kAnimationLoopInfinite; frame_count_ = 6u; last_frame_complete_ = true;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc index 5126e0a..1331784 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -166,7 +166,7 @@ } static void HibernateWrapper(base::WeakPtr<Canvas2DLayerBridge> bridge, - TimeTicks /*idleDeadline*/) { + base::TimeTicks /*idleDeadline*/) { if (bridge) { bridge->Hibernate(); } else { @@ -179,7 +179,7 @@ static void HibernateWrapperForTesting( base::WeakPtr<Canvas2DLayerBridge> bridge) { - HibernateWrapper(std::move(bridge), TimeTicks()); + HibernateWrapper(std::move(bridge), base::TimeTicks()); } void Canvas2DLayerBridge::Hibernate() {
diff --git a/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc b/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc index 80f2ba8a8..99066f1 100644 --- a/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc +++ b/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc
@@ -124,7 +124,7 @@ : orientation_(kDefaultImageOrientation), is_received_(false) {} ImageOrientation orientation_; - TimeDelta duration_; + base::TimeDelta duration_; bool is_received_; private: @@ -339,8 +339,8 @@ return false; } -TimeDelta DeferredImageDecoder::FrameDurationAtIndex(size_t index) const { - TimeDelta duration; +base::TimeDelta DeferredImageDecoder::FrameDurationAtIndex(size_t index) const { + base::TimeDelta duration; if (metadata_decoder_) duration = metadata_decoder_->FrameDurationAtIndex(index); if (index < frame_data_.size()) @@ -350,8 +350,8 @@ // possible. We follow Firefox's behavior and use a duration of 100 ms for any // frames that specify a duration of <= 10 ms. See <rdar://problem/7689300> // and <http://webkit.org/b/36082> for more information. - if (duration <= TimeDelta::FromMilliseconds(10)) - duration = TimeDelta::FromMilliseconds(100); + if (duration <= base::TimeDelta::FromMilliseconds(10)) + duration = base::TimeDelta::FromMilliseconds(100); return duration; }
diff --git a/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h b/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h index 9d69ad29..a76dd5b 100644 --- a/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h +++ b/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h
@@ -77,7 +77,7 @@ int RepetitionCount() const; bool FrameHasAlphaAtIndex(size_t index) const; bool FrameIsReceivedAtIndex(size_t index) const; - TimeDelta FrameDurationAtIndex(size_t index) const; + base::TimeDelta FrameDurationAtIndex(size_t index) const; ImageOrientation OrientationAtIndex(size_t index) const; bool HotSpot(IntPoint&) const;
diff --git a/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc b/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc index b821938d..f5a96073 100644 --- a/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
@@ -95,7 +95,7 @@ decode_request_count_ = 0; repetition_count_ = kAnimationNone; status_ = ImageFrame::kFrameComplete; - frame_duration_ = TimeDelta(); + frame_duration_ = base::TimeDelta(); decoded_size_ = actual_decoder_->Size(); } @@ -111,7 +111,7 @@ ImageFrame::Status GetStatus(size_t index) override { return status_; } - TimeDelta FrameDuration() const override { return frame_duration_; } + base::TimeDelta FrameDuration() const override { return frame_duration_; } IntSize DecodedSize() const override { return decoded_size_; } @@ -153,7 +153,7 @@ size_t frame_count_; int repetition_count_; ImageFrame::Status status_; - TimeDelta frame_duration_; + base::TimeDelta frame_duration_; IntSize decoded_size_; }; @@ -301,7 +301,7 @@ TEST_F(DeferredImageDecoderTest, multiFrameImageLoading) { repetition_count_ = 10; frame_count_ = 1; - frame_duration_ = TimeDelta::FromMilliseconds(10); + frame_duration_ = base::TimeDelta::FromMilliseconds(10); status_ = ImageFrame::kFramePartial; lazy_decoder_->SetData(data_, false /* all_data_received */); @@ -309,11 +309,11 @@ ASSERT_TRUE(image); EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0)); // Anything <= 10ms is clamped to 100ms. See the implementaiton for details. - EXPECT_EQ(TimeDelta::FromMilliseconds(100), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(100), lazy_decoder_->FrameDurationAtIndex(0)); frame_count_ = 2; - frame_duration_ = TimeDelta::FromMilliseconds(20); + frame_duration_ = base::TimeDelta::FromMilliseconds(20); status_ = ImageFrame::kFrameComplete; data_->Append(" ", 1u); lazy_decoder_->SetData(data_, false /* all_data_received */); @@ -322,23 +322,23 @@ ASSERT_TRUE(image); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0)); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(1)); - EXPECT_EQ(TimeDelta::FromMilliseconds(20), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), lazy_decoder_->FrameDurationAtIndex(1)); EXPECT_TRUE(actual_decoder_); frame_count_ = 3; - frame_duration_ = TimeDelta::FromMilliseconds(30); + frame_duration_ = base::TimeDelta::FromMilliseconds(30); status_ = ImageFrame::kFrameComplete; lazy_decoder_->SetData(data_, true /* all_data_received */); EXPECT_FALSE(actual_decoder_); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0)); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(1)); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(2)); - EXPECT_EQ(TimeDelta::FromMilliseconds(100), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(100), lazy_decoder_->FrameDurationAtIndex(0)); - EXPECT_EQ(TimeDelta::FromMilliseconds(20), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), lazy_decoder_->FrameDurationAtIndex(1)); - EXPECT_EQ(TimeDelta::FromMilliseconds(30), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(30), lazy_decoder_->FrameDurationAtIndex(2)); EXPECT_EQ(10, lazy_decoder_->RepetitionCount()); } @@ -438,7 +438,7 @@ TEST_F(MultiFrameDeferredImageDecoderTest, PaintImage) { frame_count_ = 2; - frame_duration_ = TimeDelta::FromMilliseconds(20); + frame_duration_ = base::TimeDelta::FromMilliseconds(20); last_complete_frame_ = 0u; lazy_decoder_->SetData(data_, false /* all_data_received */); @@ -490,7 +490,7 @@ TEST_F(MultiFrameDeferredImageDecoderTest, FrameDurationOverride) { frame_count_ = 2; - frame_duration_ = TimeDelta::FromMilliseconds(5); + frame_duration_ = base::TimeDelta::FromMilliseconds(5); last_complete_frame_ = 1u; lazy_decoder_->SetData(data_, true /* all_data_received */);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc index 158ee960..d7be56d 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
@@ -57,7 +57,7 @@ } void XRFrameTransport::FramePreImage(gpu::gles2::GLES2Interface* gl) { - frame_wait_time_ = WTF::TimeDelta(); + frame_wait_time_ = base::TimeDelta(); // If we're expecting a fence for the previous frame and it hasn't arrived // yet, wait for it to be received. @@ -238,9 +238,9 @@ waiting_for_previous_frame_render_ = false; } -WTF::TimeDelta XRFrameTransport::WaitForPreviousRenderToFinish() { +base::TimeDelta XRFrameTransport::WaitForPreviousRenderToFinish() { TRACE_EVENT0("gpu", "waitForPreviousRenderToFinish"); - WTF::TimeTicks start = WTF::CurrentTimeTicks(); + base::TimeTicks start = WTF::CurrentTimeTicks(); while (waiting_for_previous_frame_render_) { if (!submit_frame_client_binding_.WaitForIncomingMethodCall()) { DLOG(ERROR) << __FUNCTION__ << ": Failed to receive response"; @@ -257,9 +257,9 @@ previous_frame_fence_ = std::make_unique<gfx::GpuFence>(handle); } -WTF::TimeDelta XRFrameTransport::WaitForGpuFenceReceived() { +base::TimeDelta XRFrameTransport::WaitForGpuFenceReceived() { TRACE_EVENT0("gpu", "WaitForGpuFenceReceived"); - WTF::TimeTicks start = WTF::CurrentTimeTicks(); + base::TimeTicks start = WTF::CurrentTimeTicks(); while (waiting_for_previous_frame_fence_) { if (!submit_frame_client_binding_.WaitForIncomingMethodCall()) { DLOG(ERROR) << __FUNCTION__ << ": Failed to receive response";
diff --git a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h index 57dc839..8200bd6 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h +++ b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
@@ -64,8 +64,8 @@ private: void WaitForPreviousTransfer(); - WTF::TimeDelta WaitForPreviousRenderToFinish(); - WTF::TimeDelta WaitForGpuFenceReceived(); + base::TimeDelta WaitForPreviousRenderToFinish(); + base::TimeDelta WaitForGpuFenceReceived(); void CallPreviousFrameCallback(); // XRPresentationClient @@ -83,7 +83,7 @@ bool waiting_for_previous_frame_transfer_ = false; bool last_transfer_succeeded_ = false; - WTF::TimeDelta frame_wait_time_; + base::TimeDelta frame_wait_time_; bool waiting_for_previous_frame_render_ = false; // If using GpuFence to separate frames, need to wait for the previous // frame's fence, but not if this is the first frame. Separately track
diff --git a/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc b/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc index 37aba75e..bd064bbc 100644 --- a/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc +++ b/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc
@@ -58,7 +58,7 @@ size_t FrameCount() override { return 1; } int RepetitionCount() const override { return kAnimationNone; } - TimeDelta FrameDuration() const override { return TimeDelta(); } + base::TimeDelta FrameDuration() const override { return base::TimeDelta(); } protected: void EvictOneCache() {
diff --git a/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc b/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc index d1e5cd68..03a2df5 100644 --- a/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc +++ b/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
@@ -96,7 +96,7 @@ int RepetitionCount() const override { return frame_count_ == 1 ? kAnimationNone : kAnimationLoopOnce; } - TimeDelta FrameDuration() const override { return TimeDelta(); } + base::TimeDelta FrameDuration() const override { return base::TimeDelta(); } protected: void UseMockImageDecoderFactory() {
diff --git a/third_party/blink/renderer/platform/graphics/picture_snapshot.cc b/third_party/blink/renderer/platform/graphics/picture_snapshot.cc index 802a292d..1525e097 100644 --- a/third_party/blink/renderer/platform/graphics/picture_snapshot.cc +++ b/third_party/blink/renderer/platform/graphics/picture_snapshot.cc
@@ -131,11 +131,11 @@ return base64_data; } -Vector<Vector<TimeDelta>> PictureSnapshot::Profile( +Vector<Vector<base::TimeDelta>> PictureSnapshot::Profile( unsigned min_repeat_count, - TimeDelta min_duration, + base::TimeDelta min_duration, const FloatRect* clip_rect) const { - Vector<Vector<TimeDelta>> timings; + Vector<Vector<base::TimeDelta>> timings; timings.ReserveInitialCapacity(min_repeat_count); const SkIRect bounds = picture_->cullRect().roundOut(); SkBitmap bitmap; @@ -143,10 +143,10 @@ SkImageInfo::MakeN32Premul(bounds.width(), bounds.height())); bitmap.eraseARGB(0, 0, 0, 0); - TimeTicks now = WTF::CurrentTimeTicks(); - TimeTicks stop_time = now + min_duration; + base::TimeTicks now = WTF::CurrentTimeTicks(); + base::TimeTicks stop_time = now + min_duration; for (unsigned step = 0; step < min_repeat_count || now < stop_time; ++step) { - Vector<TimeDelta> current_timings; + Vector<base::TimeDelta> current_timings; if (!timings.IsEmpty()) current_timings.ReserveInitialCapacity(timings.front().size()); ProfilingCanvas canvas(bitmap);
diff --git a/third_party/blink/renderer/platform/graphics/picture_snapshot.h b/third_party/blink/renderer/platform/graphics/picture_snapshot.h index 6b9d554c..574c8da1 100644 --- a/third_party/blink/renderer/platform/graphics/picture_snapshot.h +++ b/third_party/blink/renderer/platform/graphics/picture_snapshot.h
@@ -65,9 +65,9 @@ Vector<char> Replay(unsigned from_step = 0, unsigned to_step = 0, double scale = 1.0) const; - Vector<Vector<TimeDelta>> Profile(unsigned min_iterations, - TimeDelta min_duration, - const FloatRect* clip_rect) const; + Vector<Vector<base::TimeDelta>> Profile(unsigned min_iterations, + base::TimeDelta min_duration, + const FloatRect* clip_rect) const; std::unique_ptr<JSONArray> SnapshotCommandLog() const; bool IsEmpty() const;
diff --git a/third_party/blink/renderer/platform/graphics/profiling_canvas.cc b/third_party/blink/renderer/platform/graphics/profiling_canvas.cc index e41220824..24cecaa 100644 --- a/third_party/blink/renderer/platform/graphics/profiling_canvas.cc +++ b/third_party/blink/renderer/platform/graphics/profiling_canvas.cc
@@ -41,7 +41,7 @@ CanvasInterceptor<ProfilingCanvas>::~CanvasInterceptor() { if (!TopLevelCall()) return; - TimeDelta delta = WTF::CurrentTimeTicks() - start_time_; + base::TimeDelta delta = WTF::CurrentTimeTicks() - start_time_; if (auto* timings = Canvas()->timings_) { DCHECK_EQ(timings->size(), Canvas()->CallCount()); timings->push_back(delta); @@ -51,7 +51,7 @@ ProfilingCanvas::ProfilingCanvas(SkBitmap bitmap) : InterceptingCanvas(bitmap), timings_(nullptr) {} -void ProfilingCanvas::SetTimings(Vector<TimeDelta>* timings) { +void ProfilingCanvas::SetTimings(Vector<base::TimeDelta>* timings) { timings_ = timings; }
diff --git a/third_party/blink/renderer/platform/graphics/profiling_canvas.h b/third_party/blink/renderer/platform/graphics/profiling_canvas.h index 0099134..df5142417 100644 --- a/third_party/blink/renderer/platform/graphics/profiling_canvas.h +++ b/third_party/blink/renderer/platform/graphics/profiling_canvas.h
@@ -47,18 +47,18 @@ ~CanvasInterceptor(); private: - TimeTicks start_time_; + base::TimeTicks start_time_; }; class ProfilingCanvas : public InterceptingCanvas<ProfilingCanvas> { public: explicit ProfilingCanvas(SkBitmap); - void SetTimings(Vector<TimeDelta>*); + void SetTimings(Vector<base::TimeDelta>*); private: friend class CanvasInterceptor<ProfilingCanvas>; - Vector<TimeDelta>* timings_; + Vector<base::TimeDelta>* timings_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/test/mock_image_decoder.h b/third_party/blink/renderer/platform/graphics/test/mock_image_decoder.h index 3ee7693..084d243 100644 --- a/third_party/blink/renderer/platform/graphics/test/mock_image_decoder.h +++ b/third_party/blink/renderer/platform/graphics/test/mock_image_decoder.h
@@ -43,7 +43,7 @@ virtual ImageFrame::Status GetStatus(size_t index) = 0; virtual size_t FrameCount() = 0; virtual int RepetitionCount() const = 0; - virtual TimeDelta FrameDuration() const = 0; + virtual base::TimeDelta FrameDuration() const = 0; virtual void ClearCacheExceptFrameRequested(size_t) {} virtual void MemoryAllocatorSet() {} @@ -88,7 +88,7 @@ return client_->GetStatus(index) == ImageFrame::kFrameComplete; } - TimeDelta FrameDurationAtIndex(size_t) const override { + base::TimeDelta FrameDurationAtIndex(size_t) const override { return client_->FrameDuration(); }
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index 4b7dc7d..3f00ddb 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -263,7 +263,7 @@ namespace { template <typename Worklist, typename Callback> -bool DrainWorklistWithDeadline(TimeTicks deadline, +bool DrainWorklistWithDeadline(base::TimeTicks deadline, Worklist* worklist, Callback callback) { const size_t kDeadlineCheckInterval = 2500; @@ -285,7 +285,8 @@ } // namespace -bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor, TimeTicks deadline) { +bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor, + base::TimeTicks deadline) { bool finished; // Ephemeron fixed point loop. do { @@ -597,13 +598,13 @@ ->AddOwnershipEdge(classes_dump->guid(), heaps_dump->guid()); } -bool ThreadHeap::AdvanceLazySweep(TimeTicks deadline) { +bool ThreadHeap::AdvanceLazySweep(base::TimeTicks deadline) { for (int i = 0; i < BlinkGC::kNumberOfArenas; i++) { // lazySweepWithDeadline() won't check the deadline until it sweeps // 10 pages. So we give a small slack for safety. - TimeDelta slack = TimeDelta::FromSecondsD(0.001); - TimeDelta remaining_budget = deadline - slack - CurrentTimeTicks(); - if (remaining_budget <= TimeDelta() || + base::TimeDelta slack = base::TimeDelta::FromSecondsD(0.001); + base::TimeDelta remaining_budget = deadline - slack - CurrentTimeTicks(); + if (remaining_budget <= base::TimeDelta() || !arenas_[i]->LazySweepWithDeadline(deadline)) { return false; }
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index bc0282b..8da19b2 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -267,7 +267,7 @@ // Marks not fully constructed objects. void MarkNotFullyConstructedObjects(MarkingVisitor*); // Marks the transitive closure including ephemerons. - bool AdvanceMarking(MarkingVisitor*, TimeTicks deadline); + bool AdvanceMarking(MarkingVisitor*, base::TimeTicks deadline); void VerifyMarking(); // Conservatively checks whether an address is a pointer in any of the @@ -360,7 +360,7 @@ void Compact(); - bool AdvanceLazySweep(TimeTicks deadline); + bool AdvanceLazySweep(base::TimeTicks deadline); void PrepareForSweep(); void RemoveAllPages();
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.cc b/third_party/blink/renderer/platform/heap/heap_compact.cc index 04eb4812..b56d29090 100644 --- a/third_party/blink/renderer/platform/heap/heap_compact.cc +++ b/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -255,6 +255,35 @@ } #endif + void VerifySlots() { + // TODO(918064): Remove this after investigation. + constexpr size_t kMaxNameLen = 256; + char slot_container_name[kMaxNameLen]; + base::debug::Alias(slot_container_name); + + for (auto it : fixups_) { + MovableReference object = it.first; + MovableReference* slot = it.second; + // Record name on stack. + const char* name = fixup_names_.find(slot)->second; + size_t len = strlen(name); + if (len > kMaxNameLen) + len = kMaxNameLen; + strncpy(slot_container_name, name, len); + slot_container_name[len - 1] = 0; + // Verify that slot either + // - points to the original object + // - points to null + // - points to a cleared hashtable entry + // - or points to a newly allocated object that will not be compacted. + MovableReference object_in_slot = *slot; + CHECK(object_in_slot == object || !object_in_slot || + object_in_slot == reinterpret_cast<MovableReference>(-1) || + !relocatable_pages_.Contains(heap_->LookupPageForAddress( + reinterpret_cast<Address>(object_in_slot)))); + } + } + private: void VerifyUpdatedSlot(MovableReference* slot); @@ -449,6 +478,13 @@ Fixups().Relocate(from, to); } +void HeapCompact::VerifySlots() { + if (!do_compact_) + return; + + Fixups().VerifySlots(); +} + void HeapCompact::FilterNonLiveSlots() { if (!do_compact_) return;
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.h b/third_party/blink/renderer/platform/heap/heap_compact.h index 125fe85..baf8800 100644 --- a/third_party/blink/renderer/platform/heap/heap_compact.h +++ b/third_party/blink/renderer/platform/heap/heap_compact.h
@@ -77,6 +77,10 @@ // die before being reached by the marker. void FilterNonLiveSlots(); + // Verifies that all recorded slots are in consistent state, i.e., either + // point to valid objects that can be compacted or are cleared. + void VerifySlots(); + // Finishes compaction and clears internal state. void Finish();
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc index f9fc5604..63c84cd 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.cc +++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -301,7 +301,7 @@ return is_empty; } -bool BaseArena::LazySweepWithDeadline(TimeTicks deadline) { +bool BaseArena::LazySweepWithDeadline(base::TimeTicks deadline) { // It might be heavy to call // Platform::current()->monotonicallyIncreasingTimeSeconds() per page (i.e., // 128 KB sweep or one LargeObject sweep), so we check the deadline per 10
diff --git a/third_party/blink/renderer/platform/heap/heap_page.h b/third_party/blink/renderer/platform/heap/heap_page.h index 5f0e1a2..8fb72ee 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.h +++ b/third_party/blink/renderer/platform/heap/heap_page.h
@@ -823,7 +823,7 @@ bool SweepUnsweptPageOnConcurrentThread(BasePage*); // Returns true if we have swept all pages within the deadline. Returns false // otherwise. - bool LazySweepWithDeadline(TimeTicks deadline); + bool LazySweepWithDeadline(base::TimeTicks deadline); void CompleteSweep(); void SweepOnConcurrentThread();
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc index d8a8251..be961cb3 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -140,7 +140,7 @@ static_assert(!std::is_polymorphic<Event>::value, "Event should not be polymorphic"); memset(¤t_, 0, sizeof(current_)); - gc_nested_in_v8_ = TimeDelta(); + gc_nested_in_v8_ = base::TimeDelta(); } void ThreadHeapStatsCollector::UpdateReason(BlinkGC::GCReason reason) { @@ -166,8 +166,8 @@ : kInitialMarkingTimeInSeconds; } -TimeDelta ThreadHeapStatsCollector::estimated_marking_time() const { - return TimeDelta::FromSecondsD(estimated_marking_time_in_seconds()); +base::TimeDelta ThreadHeapStatsCollector::estimated_marking_time() const { + return base::TimeDelta::FromSecondsD(estimated_marking_time_in_seconds()); } double ThreadHeapStatsCollector::Event::marking_time_in_ms() const { @@ -183,7 +183,7 @@ return marked_bytes ? marking_time_in_ms() / 1000 / marked_bytes : 0.0; } -TimeDelta ThreadHeapStatsCollector::Event::sweeping_time() const { +base::TimeDelta ThreadHeapStatsCollector::Event::sweeping_time() const { return scope_data[kCompleteSweep] + scope_data[kEagerSweep] + scope_data[kLazySweepInIdle] + scope_data[kLazySweepOnAllocation]; }
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h index d439791..4cf93cd8 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -187,7 +187,7 @@ void StopTrace(Id id) { TRACE_EVENT_END0(TraceCategory(), ToString(id)); } ThreadHeapStatsCollector* const tracer_; - const TimeTicks start_time_; + const base::TimeTicks start_time_; const Id id_; }; @@ -211,7 +211,7 @@ private: ThreadHeapStatsCollector* const tracer_; - const TimeTicks start_time_; + const base::TimeTicks start_time_; }; // POD to hold interesting data accumulated during a garbage collection cycle. @@ -221,20 +221,20 @@ struct PLATFORM_EXPORT Event { double marking_time_in_ms() const; double marking_time_in_bytes_per_second() const; - TimeDelta sweeping_time() const; + base::TimeDelta sweeping_time() const; // Marked bytes collected during sweeping. size_t marked_bytes = 0; size_t compaction_freed_bytes = 0; size_t compaction_freed_pages = 0; - TimeDelta scope_data[kNumScopeIds]; + base::TimeDelta scope_data[kNumScopeIds]; BlinkGC::GCReason reason; size_t object_size_in_bytes_before_sweeping = 0; size_t allocated_space_in_bytes_before_sweeping = 0; size_t partition_alloc_bytes_before_sweeping = 0; double live_object_rate = 0; size_t wrapper_count_before_sweeping = 0; - TimeDelta gc_nested_in_v8_; + base::TimeDelta gc_nested_in_v8_; }; // Indicates a new garbage collection cycle. @@ -248,7 +248,7 @@ // is finished at this point. void NotifySweepingCompleted(); - void IncreaseScopeTime(Id id, TimeDelta time) { + void IncreaseScopeTime(Id id, base::TimeDelta time) { DCHECK(is_started_); current_.scope_data[id] += time; } @@ -278,7 +278,7 @@ // the previous cycle assuming that the collection rate of the current cycle // is similar to the rate of the last GC. double estimated_marking_time_in_seconds() const; - TimeDelta estimated_marking_time() const; + base::TimeDelta estimated_marking_time() const; size_t marked_bytes() const; int64_t allocated_bytes_since_prev_gc() const; @@ -293,8 +293,8 @@ // Statistics for the previously running garbage collection. const Event& previous() const { return previous_; } - TimeDelta marking_time_so_far() const { - return TimeDelta::FromMilliseconds(current_.marking_time_in_ms()); + base::TimeDelta marking_time_so_far() const { + return base::TimeDelta::FromMilliseconds(current_.marking_time_in_ms()); } void RegisterObserver(ThreadHeapStatsObserver* observer); @@ -335,9 +335,9 @@ bool is_started_ = false; - // TimeDelta for RawScope. These don't need to be nested within a garbage - // collection cycle to make them easier to use. - TimeDelta gc_nested_in_v8_; + // base::TimeDelta for RawScope. These don't need to be nested within a + // garbage collection cycle to make them easier to use. + base::TimeDelta gc_nested_in_v8_; Vector<ThreadHeapStatsObserver*> observers_;
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc index 554d4b9..d965886 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc
@@ -23,7 +23,7 @@ ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); for (int i = 0; i < ThreadHeapStatsCollector::kNumScopeIds; i++) { - EXPECT_EQ(TimeDelta(), stats_collector.current().scope_data[i]); + EXPECT_EQ(base::TimeDelta(), stats_collector.current().scope_data[i]); } stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); @@ -34,8 +34,8 @@ stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, - TimeDelta::FromMilliseconds(1)); - EXPECT_EQ(TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMilliseconds(1)); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), stats_collector.current() .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); @@ -47,10 +47,10 @@ stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, - TimeDelta::FromMilliseconds(1)); + base::TimeDelta::FromMilliseconds(1)); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); - EXPECT_EQ(TimeDelta::FromMilliseconds(1), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), stats_collector.previous() .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]); } @@ -60,10 +60,10 @@ stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, - TimeDelta::FromMilliseconds(1)); + base::TimeDelta::FromMilliseconds(1)); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); - EXPECT_EQ(TimeDelta(), + EXPECT_EQ(base::TimeDelta(), stats_collector.current() .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]); } @@ -151,7 +151,8 @@ ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( - ThreadHeapStatsCollector::kAtomicPhaseMarking, TimeDelta::FromSeconds(1)); + ThreadHeapStatsCollector::kAtomicPhaseMarking, + base::TimeDelta::FromSeconds(1)); stats_collector.NotifyMarkingCompleted(1024); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); @@ -164,7 +165,8 @@ ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( - ThreadHeapStatsCollector::kAtomicPhaseMarking, TimeDelta::FromSeconds(1)); + ThreadHeapStatsCollector::kAtomicPhaseMarking, + base::TimeDelta::FromSeconds(1)); stats_collector.NotifyMarkingCompleted(1024); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); @@ -215,17 +217,17 @@ stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStartMarking, - TimeDelta::FromMilliseconds(7)); + base::TimeDelta::FromMilliseconds(7)); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, - TimeDelta::FromMilliseconds(2)); + base::TimeDelta::FromMilliseconds(2)); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingFinalizeMarking, - TimeDelta::FromMilliseconds(1)); + base::TimeDelta::FromMilliseconds(1)); // Ignore the full finalization. stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingFinalize, - TimeDelta::FromMilliseconds(3)); + base::TimeDelta::FromMilliseconds(3)); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(10.0, stats_collector.previous().marking_time_in_ms()); @@ -236,7 +238,7 @@ stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kAtomicPhaseMarking, - TimeDelta::FromMilliseconds(11)); + base::TimeDelta::FromMilliseconds(11)); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(11.0, stats_collector.previous().marking_time_in_ms()); @@ -246,7 +248,8 @@ ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime( - ThreadHeapStatsCollector::kAtomicPhaseMarking, TimeDelta::FromSeconds(1)); + ThreadHeapStatsCollector::kAtomicPhaseMarking, + base::TimeDelta::FromSeconds(1)); stats_collector.NotifyMarkingCompleted(1000); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ( @@ -257,19 +260,19 @@ ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle, - TimeDelta::FromMilliseconds(1)); + base::TimeDelta::FromMilliseconds(1)); stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle, - TimeDelta::FromMilliseconds(2)); + base::TimeDelta::FromMilliseconds(2)); stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle, - TimeDelta::FromMilliseconds(3)); + base::TimeDelta::FromMilliseconds(3)); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kLazySweepOnAllocation, - TimeDelta::FromMilliseconds(4)); + base::TimeDelta::FromMilliseconds(4)); stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kCompleteSweep, - TimeDelta::FromMilliseconds(5)); + base::TimeDelta::FromMilliseconds(5)); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); - EXPECT_EQ(TimeDelta::FromMilliseconds(15), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(15), stats_collector.previous().sweeping_time()); }
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index e8f535d..bca3dad 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -94,8 +94,8 @@ // Duration of one incremental marking step. Should be short enough that it // doesn't cause jank even though it is scheduled as a normal task. -constexpr TimeDelta kDefaultIncrementalMarkingStepDuration = - TimeDelta::FromMilliseconds(2); +constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration = + base::TimeDelta::FromMilliseconds(2); constexpr size_t kMaxTerminationGCLoops = 20; @@ -556,7 +556,7 @@ return page->Arena()->GetThreadState(); } -void ThreadState::PerformIdleLazySweep(TimeTicks deadline) { +void ThreadState::PerformIdleLazySweep(base::TimeTicks deadline) { DCHECK(CheckThread()); // If we are not in a sweeping phase, there is nothing to do here. @@ -804,6 +804,13 @@ EagerSweep(); + { + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), + ThreadHeapStatsCollector::kAtomicPhaseCompaction); + Heap().Compaction()->VerifySlots(); + } + // Any sweep compaction must happen after pre-finalizers and eager // sweeping, as it will finalize dead objects in compactable arenas // (e.g., backing stores for container objects.) @@ -940,7 +947,7 @@ UMA_HISTOGRAM_ENUMERATION("BlinkGC.GCReason", event.reason); // Blink GC cycle time. - const WTF::TimeDelta cycle_duration = + const base::TimeDelta cycle_duration = event.scope_data [ThreadHeapStatsCollector::kIncrementalMarkingStartMarking] + event.scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep] + @@ -950,14 +957,14 @@ event.scope_data[ThreadHeapStatsCollector::kLazySweepOnAllocation]; UMA_HISTOGRAM_TIMES("BlinkGC.TimeForGCCycle", cycle_duration); - const WTF::TimeDelta incremental_marking_duration = + const base::TimeDelta incremental_marking_duration = event.scope_data [ThreadHeapStatsCollector::kIncrementalMarkingStartMarking] + event.scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]; UMA_HISTOGRAM_TIMES("BlinkGC.TimeForIncrementalMarking", incremental_marking_duration); - const WTF::TimeDelta marking_duration = + const base::TimeDelta marking_duration = event.scope_data [ThreadHeapStatsCollector::kIncrementalMarkingStartMarking] + event.scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep] + @@ -965,14 +972,14 @@ UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarking", marking_duration); constexpr size_t kMinObjectSizeForReportingThroughput = 1024 * 1024; - if (WTF::TimeTicks::IsHighResolution() && + if (base::TimeTicks::IsHighResolution() && (event.object_size_in_bytes_before_sweeping > kMinObjectSizeForReportingThroughput) && !marking_duration.is_zero()) { DCHECK_GT(marking_duration.InMillisecondsF(), 0.0); // For marking throughput computation all marking steps, independent of // whether they are triggered from V8 or Blink, are relevant. - const WTF::TimeDelta blink_marking_duration = + const base::TimeDelta blink_marking_duration = marking_duration + event.scope_data [ThreadHeapStatsCollector::kUnifiedMarkingAtomicPrologue] + @@ -1281,7 +1288,7 @@ AtomicPauseScope atomic_pause_scope(this); next_incremental_marking_step_duration_ = kDefaultIncrementalMarkingStepDuration; - previous_incremental_marking_time_left_ = TimeDelta::Max(); + previous_incremental_marking_time_left_ = base::TimeDelta::Max(); MarkPhasePrologue(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kIncrementalMarking, reason); MarkPhaseVisitRoots(); @@ -1378,7 +1385,7 @@ if (SweepForbidden()) return; - TimeTicks start_total_collect_garbage_time = WTF::CurrentTimeTicks(); + base::TimeTicks start_total_collect_garbage_time = WTF::CurrentTimeTicks(); RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS( GetIsolate(), RuntimeCallStats::CounterId::kCollectGarbage); @@ -1400,7 +1407,7 @@ RunAtomicPause(stack_state, marking_type, sweeping_type, reason); } - const TimeDelta total_collect_garbage_time = + const base::TimeDelta total_collect_garbage_time = WTF::CurrentTimeTicks() - start_total_collect_garbage_time; UMA_HISTOGRAM_TIMES("BlinkGC.TimeForTotalCollectGarbage", total_collect_garbage_time); @@ -1442,7 +1449,7 @@ } void ThreadState::AtomicPauseMarkTransitiveClosure() { - CHECK(MarkPhaseAdvanceMarking(TimeTicks::Max())); + CHECK(MarkPhaseAdvanceMarking(base::TimeTicks::Max())); } void ThreadState::AtomicPauseMarkEpilogue(BlinkGC::MarkingType marking_type) { @@ -1601,7 +1608,7 @@ } } -bool ThreadState::MarkPhaseAdvanceMarking(TimeTicks deadline) { +bool ThreadState::MarkPhaseAdvanceMarking(base::TimeTicks deadline) { return Heap().AdvanceMarking( reinterpret_cast<MarkingVisitor*>(current_gc_data_.visitor.get()), deadline); @@ -1684,8 +1691,9 @@ void ThreadState::UpdateIncrementalMarkingStepDuration() { if (!IsIncrementalMarking()) return; - TimeDelta time_left = Heap().stats_collector()->estimated_marking_time() - - Heap().stats_collector()->marking_time_so_far(); + base::TimeDelta time_left = + Heap().stats_collector()->estimated_marking_time() - + Heap().stats_collector()->marking_time_so_far(); // Increase step size if estimated time left is increasing. if (previous_incremental_marking_time_left_ < time_left) { constexpr double ratio = 2.0;
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index f8d2c90..68137405 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -217,7 +217,7 @@ // in the dangling pointer situation. void RunTerminationGC(); - void PerformIdleLazySweep(TimeTicks deadline); + void PerformIdleLazySweep(base::TimeTicks deadline); void ScheduleIdleLazySweep(); void SchedulePreciseGC(); @@ -472,7 +472,7 @@ void MarkPhaseEpilogue(BlinkGC::MarkingType); void MarkPhaseVisitRoots(); void MarkPhaseVisitNotFullyConstructedObjects(); - bool MarkPhaseAdvanceMarking(TimeTicks deadline); + bool MarkPhaseAdvanceMarking(base::TimeTicks deadline); void VerifyMarking(BlinkGC::MarkingType); bool ShouldVerifyMarking() const; @@ -544,8 +544,8 @@ size_t no_allocation_count_ = 0; size_t gc_forbidden_count_ = 0; - TimeDelta next_incremental_marking_step_duration_; - TimeDelta previous_incremental_marking_time_left_; + base::TimeDelta next_incremental_marking_step_duration_; + base::TimeDelta previous_incremental_marking_time_left_; GCState gc_state_; GCPhase gc_phase_;
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_controller.cc b/third_party/blink/renderer/platform/heap/unified_heap_controller.cc index c0cffa6..b791793 100644 --- a/third_party/blink/renderer/platform/heap/unified_heap_controller.cc +++ b/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
@@ -139,8 +139,8 @@ // V8 calls into embedder tracing from its own marking to ensure // progress. Oilpan will additionally schedule marking steps. ThreadState::AtomicPauseScope atomic_pause_scope(thread_state_); - TimeTicks deadline = - TimeTicks() + TimeDelta::FromMillisecondsD(deadline_in_ms); + base::TimeTicks deadline = + base::TimeTicks() + base::TimeDelta::FromMillisecondsD(deadline_in_ms); is_tracing_done_ = thread_state_->MarkPhaseAdvanceMarking(deadline); return is_tracing_done_; }
diff --git a/third_party/blink/renderer/platform/histogram.h b/third_party/blink/renderer/platform/histogram.h index 69a3d465d..cd9ca56 100644 --- a/third_party/blink/renderer/platform/histogram.h +++ b/third_party/blink/renderer/platform/histogram.h
@@ -91,7 +91,7 @@ private: const base::TickClock& clock_; - TimeTicks start_time_; + base::TimeTicks start_time_; CustomCountHistogram& counter_; }; @@ -106,7 +106,7 @@ : public ScopedUsHistogramTimerBase<ScopedHighResUsHistogramTimer> { public: using ScopedUsHistogramTimerBase::ScopedUsHistogramTimerBase; - static bool ShouldRecord() { return TimeTicks::IsHighResolution(); } + static bool ShouldRecord() { return base::TimeTicks::IsHighResolution(); } }; #define SCOPED_BLINK_UMA_HISTOGRAM_TIMER_IMPL(name, allow_cross_thread) \
diff --git a/third_party/blink/renderer/platform/histogram_test.cc b/third_party/blink/renderer/platform/histogram_test.cc index 1a67831..32e5ebb 100644 --- a/third_party/blink/renderer/platform/histogram_test.cc +++ b/third_party/blink/renderer/platform/histogram_test.cc
@@ -37,7 +37,7 @@ { ScopedUsHistogramTimer timer(scoped_us_counter, test_task_runner_->GetMockTickClock()); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(500)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(500)); } // 500ms == 500000us EXPECT_EQ(500000, scoped_us_counter.Histogram()->SnapshotSamples()->sum()); @@ -49,9 +49,9 @@ { ScopedHighResUsHistogramTimer timer(scoped_us_counter, test_task_runner_->GetMockTickClock()); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(500)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(500)); } - int64_t expected = TimeTicks::IsHighResolution() ? 500000 : 0; + int64_t expected = base::TimeTicks::IsHighResolution() ? 500000 : 0; EXPECT_EQ(expected, scoped_us_counter.Histogram()->SnapshotSamples()->sum()); }
diff --git a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc index 2a8640b..f200a1661 100644 --- a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.cc
@@ -146,10 +146,10 @@ return frame_info.fFullyReceived; } -TimeDelta GIFImageDecoder::FrameDurationAtIndex(size_t index) const { +base::TimeDelta GIFImageDecoder::FrameDurationAtIndex(size_t index) const { if (index < frame_buffer_cache_.size()) return frame_buffer_cache_[index].Duration(); - return TimeDelta(); + return base::TimeDelta(); } bool GIFImageDecoder::SetFailed() { @@ -200,7 +200,7 @@ SkCodec::FrameInfo frame_info; bool frame_info_received = codec_->getFrameInfo(index, &frame_info); DCHECK(frame_info_received); - frame.SetDuration(TimeDelta::FromMilliseconds(frame_info.fDuration)); + frame.SetDuration(base::TimeDelta::FromMilliseconds(frame_info.fDuration)); size_t required_previous_frame_index; if (frame_info.fRequiredFrame == SkCodec::kNoFrame) { required_previous_frame_index = kNotFound;
diff --git a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h index 52ece599..ea5c2e68 100644 --- a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h +++ b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h
@@ -48,7 +48,7 @@ void OnSetData(SegmentReader* data) override; int RepetitionCount() const override; bool FrameIsReceivedAtIndex(size_t) const override; - TimeDelta FrameDurationAtIndex(size_t) const override; + base::TimeDelta FrameDurationAtIndex(size_t) const override; // CAUTION: SetFailed() deletes |codec_|. Be careful to avoid // accessing deleted memory. bool SetFailed() override;
diff --git a/third_party/blink/renderer/platform/image-decoders/image_decoder.h b/third_party/blink/renderer/platform/image-decoders/image_decoder.h index 4085c2bb..d962313 100644 --- a/third_party/blink/renderer/platform/image-decoders/image_decoder.h +++ b/third_party/blink/renderer/platform/image-decoders/image_decoder.h
@@ -278,7 +278,9 @@ // Duration for displaying a frame. This method is only used by animated // images. - virtual TimeDelta FrameDurationAtIndex(size_t) const { return TimeDelta(); } + virtual base::TimeDelta FrameDurationAtIndex(size_t) const { + return base::TimeDelta(); + } // Number of bytes in the decoded frame. Returns 0 if the decoder doesn't // have this frame cached (either because it hasn't been decoded, or because
diff --git a/third_party/blink/renderer/platform/image-decoders/image_frame.h b/third_party/blink/renderer/platform/image-decoders/image_frame.h index bbadfed..b70e0a7 100644 --- a/third_party/blink/renderer/platform/image-decoders/image_frame.h +++ b/third_party/blink/renderer/platform/image-decoders/image_frame.h
@@ -132,7 +132,7 @@ PixelFormat GetPixelFormat() const { return pixel_format_; } const IntRect& OriginalFrameRect() const { return original_frame_rect_; } Status GetStatus() const { return status_; } - TimeDelta Duration() const { return duration_; } + base::TimeDelta Duration() const { return duration_; } DisposalMethod GetDisposalMethod() const { return disposal_method_; } AlphaBlendSource GetAlphaBlendSource() const { return alpha_blend_source_; } bool PremultiplyAlpha() const { return premultiply_alpha_; } @@ -156,7 +156,7 @@ void SetPixelFormat(PixelFormat format) { pixel_format_ = format; } void SetOriginalFrameRect(const IntRect& r) { original_frame_rect_ = r; } void SetStatus(Status); - void SetDuration(TimeDelta duration) { duration_ = duration; } + void SetDuration(base::TimeDelta duration) { duration_ = duration; } void SetDisposalMethod(DisposalMethod disposal_method) { disposal_method_ = disposal_method; } @@ -313,7 +313,7 @@ // frames whose original rect was smaller than the overall image size. IntRect original_frame_rect_; Status status_; - TimeDelta duration_; + base::TimeDelta duration_; DisposalMethod disposal_method_; AlphaBlendSource alpha_blend_source_; bool premultiply_alpha_;
diff --git a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc index 14025593..509fe3a 100644 --- a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
@@ -150,7 +150,7 @@ DCHECK(IntRect(IntPoint(), Size()).Contains(frame_info.frame_rect)); buffer.SetOriginalFrameRect(frame_info.frame_rect); - buffer.SetDuration(TimeDelta::FromMilliseconds(frame_info.duration)); + buffer.SetDuration(base::TimeDelta::FromMilliseconds(frame_info.duration)); buffer.SetDisposalMethod(frame_info.disposal_method); buffer.SetAlphaBlendSource(frame_info.alpha_blend); @@ -787,10 +787,10 @@ return reader_->FrameIsReceivedAtIndex(index); } -TimeDelta PNGImageDecoder::FrameDurationAtIndex(size_t index) const { +base::TimeDelta PNGImageDecoder::FrameDurationAtIndex(size_t index) const { if (index < frame_buffer_cache_.size()) return frame_buffer_cache_[index].Duration(); - return TimeDelta(); + return base::TimeDelta(); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h index 245050b..55c6a5ae 100644 --- a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h +++ b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h
@@ -49,7 +49,7 @@ int RepetitionCount() const override; bool ImageIsHighBitDepth() override; bool FrameIsReceivedAtIndex(size_t) const override; - TimeDelta FrameDurationAtIndex(size_t) const override; + base::TimeDelta FrameDurationAtIndex(size_t) const override; bool SetFailed() override; // Callbacks from libpng
diff --git a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc index 54210639..48d910e 100644 --- a/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc
@@ -111,7 +111,7 @@ } struct PublicFrameInfo { - TimeDelta duration; + base::TimeDelta duration; IntRect frame_rect; ImageFrame::AlphaBlendSource alpha_blend; ImageFrame::DisposalMethod disposal_method; @@ -120,19 +120,19 @@ // This is the frame data for the following PNG image: // web_tests/images/resources/png-animated-idat-part-of-animation.png static PublicFrameInfo g_png_animated_frame_info[] = { - {TimeDelta::FromMilliseconds(500), + {base::TimeDelta::FromMilliseconds(500), {IntPoint(0, 0), IntSize(5, 5)}, ImageFrame::kBlendAtopBgcolor, ImageFrame::kDisposeKeep}, - {TimeDelta::FromMilliseconds(900), + {base::TimeDelta::FromMilliseconds(900), {IntPoint(1, 1), IntSize(3, 1)}, ImageFrame::kBlendAtopBgcolor, ImageFrame::kDisposeOverwriteBgcolor}, - {TimeDelta::FromMilliseconds(2000), + {base::TimeDelta::FromMilliseconds(2000), {IntPoint(1, 2), IntSize(3, 2)}, ImageFrame::kBlendAtopPreviousFrame, ImageFrame::kDisposeKeep}, - {TimeDelta::FromMilliseconds(1500), + {base::TimeDelta::FromMilliseconds(1500), {IntPoint(1, 2), IntSize(3, 1)}, ImageFrame::kBlendAtopBgcolor, ImageFrame::kDisposeKeep}, @@ -1016,7 +1016,7 @@ TEST(StaticPNGTests, MetaDataTest) { const size_t kExpectedFrameCount = 1; - const TimeDelta kExpectedDuration; + const base::TimeDelta kExpectedDuration; auto decoder = CreatePNGDecoderWithPngData("/images/resources/png-simple.png"); EXPECT_EQ(kExpectedFrameCount, decoder->FrameCount());
diff --git a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc index f38b64be..2342dda 100644 --- a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
@@ -266,10 +266,10 @@ return frame_is_received_at_index; } -TimeDelta WEBPImageDecoder::FrameDurationAtIndex(size_t index) const { +base::TimeDelta WEBPImageDecoder::FrameDurationAtIndex(size_t index) const { return index < frame_buffer_cache_.size() ? frame_buffer_cache_[index].Duration() - : TimeDelta(); + : base::TimeDelta(); } bool WEBPImageDecoder::UpdateDemuxer() { @@ -593,7 +593,8 @@ animated_frame.width, animated_frame.height); buffer->SetOriginalFrameRect( Intersection(frame_rect, IntRect(IntPoint(), Size()))); - buffer->SetDuration(TimeDelta::FromMilliseconds(animated_frame.duration)); + buffer->SetDuration( + base::TimeDelta::FromMilliseconds(animated_frame.duration)); buffer->SetDisposalMethod(animated_frame.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ? ImageFrame::kDisposeOverwriteBgcolor
diff --git a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h index 30db849..e9f082a 100644 --- a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h +++ b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h
@@ -51,7 +51,7 @@ void OnSetData(SegmentReader* data) override; int RepetitionCount() const override; bool FrameIsReceivedAtIndex(size_t) const override; - TimeDelta FrameDurationAtIndex(size_t) const override; + base::TimeDelta FrameDurationAtIndex(size_t) const override; private: // ImageDecoder:
diff --git a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc index 7c402fb..435a9446 100644 --- a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc
@@ -50,7 +50,7 @@ int x_offset, y_offset, width, height; ImageFrame::DisposalMethod disposal_method; ImageFrame::AlphaBlendSource alpha_blend_source; - TimeDelta duration; + base::TimeDelta duration; bool has_alpha; }; @@ -119,14 +119,14 @@ const int kCanvasHeight = 29; const AnimParam kFrameParameters[] = { {0, 0, 11, 29, ImageFrame::kDisposeKeep, - ImageFrame::kBlendAtopPreviousFrame, TimeDelta::FromMilliseconds(1000), - true}, + ImageFrame::kBlendAtopPreviousFrame, + base::TimeDelta::FromMilliseconds(1000), true}, {2, 10, 7, 17, ImageFrame::kDisposeKeep, - ImageFrame::kBlendAtopPreviousFrame, TimeDelta::FromMilliseconds(500), - true}, + ImageFrame::kBlendAtopPreviousFrame, + base::TimeDelta::FromMilliseconds(500), true}, {2, 2, 7, 16, ImageFrame::kDisposeKeep, - ImageFrame::kBlendAtopPreviousFrame, TimeDelta::FromMilliseconds(1000), - true}, + ImageFrame::kBlendAtopPreviousFrame, + base::TimeDelta::FromMilliseconds(1000), true}, }; for (size_t i = 0; i < base::size(kFrameParameters); ++i) { @@ -163,17 +163,17 @@ const int kCanvasHeight = 87; const AnimParam kFrameParameters[] = { {4, 10, 33, 32, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopPreviousFrame, TimeDelta::FromMilliseconds(1000), - true}, + ImageFrame::kBlendAtopPreviousFrame, + base::TimeDelta::FromMilliseconds(1000), true}, {34, 30, 33, 32, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopPreviousFrame, TimeDelta::FromMilliseconds(1000), - true}, + ImageFrame::kBlendAtopPreviousFrame, + base::TimeDelta::FromMilliseconds(1000), true}, {62, 50, 32, 32, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopPreviousFrame, TimeDelta::FromMilliseconds(1000), - true}, + ImageFrame::kBlendAtopPreviousFrame, + base::TimeDelta::FromMilliseconds(1000), true}, {10, 54, 32, 33, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopPreviousFrame, TimeDelta::FromMilliseconds(1000), - true}, + ImageFrame::kBlendAtopPreviousFrame, + base::TimeDelta::FromMilliseconds(1000), true}, }; for (size_t i = 0; i < base::size(kFrameParameters); ++i) { @@ -209,13 +209,17 @@ const int kCanvasHeight = 87; const AnimParam kFrameParameters[] = { {4, 10, 33, 32, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopBgcolor, TimeDelta::FromMilliseconds(1000), true}, + ImageFrame::kBlendAtopBgcolor, base::TimeDelta::FromMilliseconds(1000), + true}, {34, 30, 33, 32, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopBgcolor, TimeDelta::FromMilliseconds(1000), true}, + ImageFrame::kBlendAtopBgcolor, base::TimeDelta::FromMilliseconds(1000), + true}, {62, 50, 32, 32, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopBgcolor, TimeDelta::FromMilliseconds(1000), true}, + ImageFrame::kBlendAtopBgcolor, base::TimeDelta::FromMilliseconds(1000), + true}, {10, 54, 32, 33, ImageFrame::kDisposeOverwriteBgcolor, - ImageFrame::kBlendAtopBgcolor, TimeDelta::FromMilliseconds(1000), true}, + ImageFrame::kBlendAtopBgcolor, base::TimeDelta::FromMilliseconds(1000), + true}, }; for (size_t i = 0; i < base::size(kFrameParameters); ++i) { @@ -349,20 +353,22 @@ EXPECT_EQ(2u, decoder->FrameCount()); EXPECT_FALSE(decoder->Failed()); EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); - EXPECT_EQ(TimeDelta::FromMilliseconds(1000), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), decoder->FrameDurationAtIndex(0)); EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(1)); - EXPECT_EQ(TimeDelta::FromMilliseconds(500), decoder->FrameDurationAtIndex(1)); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), + decoder->FrameDurationAtIndex(1)); decoder->SetData(data_buffer.get(), true); EXPECT_EQ(3u, decoder->FrameCount()); EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); - EXPECT_EQ(TimeDelta::FromMilliseconds(1000), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), decoder->FrameDurationAtIndex(0)); EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(1)); - EXPECT_EQ(TimeDelta::FromMilliseconds(500), decoder->FrameDurationAtIndex(1)); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), + decoder->FrameDurationAtIndex(1)); EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(2)); - EXPECT_EQ(TimeDelta::FromMilliseconds(1000), + EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), decoder->FrameDurationAtIndex(2)); }
diff --git a/third_party/blink/renderer/platform/loader/cors/cors.cc b/third_party/blink/renderer/platform/loader/cors/cors.cc index 44e3aec0..285209f 100644 --- a/third_party/blink/renderer/platform/loader/cors/cors.cc +++ b/third_party/blink/renderer/platform/loader/cors/cors.cc
@@ -160,7 +160,7 @@ const KURL& response_url, const int response_status_code, const HTTPHeaderMap& response_header, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const SecurityOrigin& origin) { return network::cors::CheckAccess( response_url, response_status_code, @@ -174,7 +174,7 @@ const KURL& response_url, const int response_status_code, const HTTPHeaderMap& response_header, - network::mojom::FetchCredentialsMode actual_credentials_mode, + network::mojom::CredentialsMode actual_credentials_mode, const SecurityOrigin& origin) { return network::cors::CheckPreflightAccess( response_url, response_status_code, @@ -186,7 +186,7 @@ base::Optional<network::CorsErrorStatus> CheckRedirectLocation( const KURL& url, - network::mojom::FetchRequestMode request_mode, + network::mojom::RequestMode request_mode, const SecurityOrigin* origin, CorsFlag cors_flag) { base::Optional<url::Origin> origin_to_pass; @@ -210,7 +210,7 @@ GetHeaderValue(response_header, http_names::kAccessControlAllowExternal)); } -bool IsCorsEnabledRequestMode(network::mojom::FetchRequestMode request_mode) { +bool IsCorsEnabledRequestMode(network::mojom::RequestMode request_mode) { return network::cors::IsCorsEnabledRequestMode(request_mode); } @@ -220,7 +220,7 @@ const KURL& request_url, const String& request_method, const HTTPHeaderMap& request_header_map, - network::mojom::FetchCredentialsMode request_credentials_mode) { + network::mojom::CredentialsMode request_credentials_mode) { DCHECK(!origin.IsNull()); DCHECK(!request_method.IsNull()); @@ -259,7 +259,7 @@ bool CheckIfRequestCanSkipPreflight( const String& origin, const KURL& url, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const String& method, const HTTPHeaderMap& request_header_map) { DCHECK(!origin.IsNull()); @@ -284,7 +284,7 @@ // mutate the origin instead of using such a flag. network::mojom::FetchResponseType CalculateResponseTainting( const KURL& url, - network::mojom::FetchRequestMode request_mode, + network::mojom::RequestMode request_mode, const SecurityOrigin* origin, CorsFlag cors_flag) { if (url.ProtocolIsData()) @@ -301,7 +301,7 @@ return network::mojom::FetchResponseType::kBasic; } - if (request_mode == network::mojom::FetchRequestMode::kNoCors && + if (request_mode == network::mojom::RequestMode::kNoCors && !origin->CanRequest(url)) { return network::mojom::FetchResponseType::kOpaque; } @@ -309,7 +309,7 @@ } bool CalculateCredentialsFlag( - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, network::mojom::FetchResponseType response_tainting) { return network::cors::CalculateCredentialsFlag(credentials_mode, response_tainting); @@ -384,9 +384,9 @@ bool CalculateCorsFlag(const KURL& url, const SecurityOrigin* origin, - network::mojom::FetchRequestMode request_mode) { - if (request_mode == network::mojom::FetchRequestMode::kNavigate || - request_mode == network::mojom::FetchRequestMode::kNoCors) { + network::mojom::RequestMode request_mode) { + if (request_mode == network::mojom::RequestMode::kNavigate || + request_mode == network::mojom::RequestMode::kNoCors) { return false; } // CORS needs a proper origin (including a unique opaque origin). If the @@ -396,7 +396,7 @@ } WebHTTPHeaderSet ExtractCorsExposedHeaderNamesList( - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, const ResourceResponse& response) { // If a response was fetched via a service worker, it will always have // CorsExposedHeaderNames set from the Access-Control-Expose-Headers header. @@ -414,7 +414,7 @@ response.HttpHeaderField(http_names::kAccessControlExposeHeaders)); parser.Parse(header_set); - if (credentials_mode != network::mojom::FetchCredentialsMode::kInclude && + if (credentials_mode != network::mojom::CredentialsMode::kInclude && header_set.find("*") != header_set.end()) { header_set.clear(); for (const auto& header : response.HttpHeaderFields())
diff --git a/third_party/blink/renderer/platform/loader/cors/cors.h b/third_party/blink/renderer/platform/loader/cors/cors.h index 8f5c0738..6544bf1 100644 --- a/third_party/blink/renderer/platform/loader/cors/cors.h +++ b/third_party/blink/renderer/platform/loader/cors/cors.h
@@ -37,19 +37,19 @@ const KURL&, const int response_status_code, const HTTPHeaderMap&, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const SecurityOrigin&); PLATFORM_EXPORT base::Optional<network::CorsErrorStatus> CheckPreflightAccess( const KURL&, const int response_status_code, const HTTPHeaderMap&, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const SecurityOrigin&); PLATFORM_EXPORT base::Optional<network::CorsErrorStatus> CheckRedirectLocation( const KURL&, - network::mojom::FetchRequestMode, + network::mojom::RequestMode, const SecurityOrigin*, CorsFlag); @@ -59,7 +59,7 @@ PLATFORM_EXPORT base::Optional<network::CorsErrorStatus> CheckExternalPreflight( const HTTPHeaderMap&); -PLATFORM_EXPORT bool IsCorsEnabledRequestMode(network::mojom::FetchRequestMode); +PLATFORM_EXPORT bool IsCorsEnabledRequestMode(network::mojom::RequestMode); PLATFORM_EXPORT base::Optional<network::CorsErrorStatus> EnsurePreflightResultAndCacheOnSuccess( @@ -68,12 +68,12 @@ const KURL& request_url, const String& request_method, const HTTPHeaderMap& request_header_map, - network::mojom::FetchCredentialsMode request_credentials_mode); + network::mojom::CredentialsMode request_credentials_mode); PLATFORM_EXPORT bool CheckIfRequestCanSkipPreflight( const String& origin, const KURL&, - network::mojom::FetchCredentialsMode, + network::mojom::CredentialsMode, const String& method, const HTTPHeaderMap& request_header_map); @@ -83,12 +83,12 @@ // https://fetch.spec.whatwg.org/#main-fetch. PLATFORM_EXPORT network::mojom::FetchResponseType CalculateResponseTainting( const KURL& url, - network::mojom::FetchRequestMode request_mode, + network::mojom::RequestMode request_mode, const SecurityOrigin* origin, CorsFlag cors_flag); PLATFORM_EXPORT bool CalculateCredentialsFlag( - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, network::mojom::FetchResponseType response_tainting); // Thin wrapper functions that will not be removed even after out-of-renderer @@ -120,10 +120,10 @@ PLATFORM_EXPORT bool CalculateCorsFlag( const KURL& url, const SecurityOrigin* origin, - network::mojom::FetchRequestMode request_mode); + network::mojom::RequestMode request_mode); PLATFORM_EXPORT WebHTTPHeaderSet -ExtractCorsExposedHeaderNamesList(network::mojom::FetchCredentialsMode, +ExtractCorsExposedHeaderNamesList(network::mojom::CredentialsMode, const ResourceResponse&); PLATFORM_EXPORT bool IsCorsSafelistedResponseHeader(const String&);
diff --git a/third_party/blink/renderer/platform/loader/cors/cors_test.cc b/third_party/blink/renderer/platform/loader/cors/cors_test.cc index 5365a937..60a7ba4 100644 --- a/third_party/blink/renderer/platform/loader/cors/cors_test.cc +++ b/third_party/blink/renderer/platform/loader/cors/cors_test.cc
@@ -14,7 +14,7 @@ class CorsExposedHeadersTest : public testing::Test { public: - using CredentialsMode = network::mojom::FetchCredentialsMode; + using CredentialsMode = network::mojom::CredentialsMode; WebHTTPHeaderSet Parse(CredentialsMode credentials_mode, const AtomicString& header) const { @@ -104,8 +104,8 @@ // Keep this in sync with the CalculateResponseTainting test in // services/network/cors/cors_url_loader_unittest.cc. TEST(CorsTest, CalculateResponseTainting) { - using network::mojom::FetchRequestMode; using network::mojom::FetchResponseType; + using network::mojom::RequestMode; const KURL same_origin_url("https://example.com/"); const KURL cross_origin_url("https://example2.com/"); @@ -115,74 +115,71 @@ const SecurityOrigin* no_origin = nullptr; // CORS flag is false, same-origin request - EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting(same_origin_url, - FetchRequestMode::kSameOrigin, - origin, CorsFlag::Unset)); EXPECT_EQ( FetchResponseType::kBasic, - cors::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kNoCors, origin, CorsFlag::Unset)); + cors::CalculateResponseTainting(same_origin_url, RequestMode::kSameOrigin, + origin, CorsFlag::Unset)); EXPECT_EQ( FetchResponseType::kBasic, - cors::CalculateResponseTainting(same_origin_url, FetchRequestMode::kCors, + cors::CalculateResponseTainting(same_origin_url, RequestMode::kNoCors, origin, CorsFlag::Unset)); EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kCorsWithForcedPreflight, - origin, CorsFlag::Unset)); + cors::CalculateResponseTainting(same_origin_url, RequestMode::kCors, + origin, CorsFlag::Unset)); EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting(same_origin_url, - FetchRequestMode::kNavigate, origin, - CorsFlag::Unset)); + cors::CalculateResponseTainting( + same_origin_url, RequestMode::kCorsWithForcedPreflight, origin, + CorsFlag::Unset)); + EXPECT_EQ( + FetchResponseType::kBasic, + cors::CalculateResponseTainting(same_origin_url, RequestMode::kNavigate, + origin, CorsFlag::Unset)); // CORS flag is false, cross-origin request - EXPECT_EQ(FetchResponseType::kOpaque, - cors::CalculateResponseTainting(cross_origin_url, - FetchRequestMode::kNoCors, origin, - CorsFlag::Unset)); - EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting(cross_origin_url, - FetchRequestMode::kNavigate, origin, - CorsFlag::Unset)); + EXPECT_EQ( + FetchResponseType::kOpaque, + cors::CalculateResponseTainting(cross_origin_url, RequestMode::kNoCors, + origin, CorsFlag::Unset)); + EXPECT_EQ( + FetchResponseType::kBasic, + cors::CalculateResponseTainting(cross_origin_url, RequestMode::kNavigate, + origin, CorsFlag::Unset)); // CORS flag is true, same-origin request - EXPECT_EQ( - FetchResponseType::kCors, - cors::CalculateResponseTainting(same_origin_url, FetchRequestMode::kCors, - origin, CorsFlag::Set)); + EXPECT_EQ(FetchResponseType::kCors, + cors::CalculateResponseTainting(same_origin_url, RequestMode::kCors, + origin, CorsFlag::Set)); EXPECT_EQ(FetchResponseType::kCors, cors::CalculateResponseTainting( - same_origin_url, FetchRequestMode::kCorsWithForcedPreflight, - origin, CorsFlag::Set)); + same_origin_url, RequestMode::kCorsWithForcedPreflight, origin, + CorsFlag::Set)); // CORS flag is true, cross-origin request - EXPECT_EQ( - FetchResponseType::kCors, - cors::CalculateResponseTainting(cross_origin_url, FetchRequestMode::kCors, - origin, CorsFlag::Set)); EXPECT_EQ(FetchResponseType::kCors, cors::CalculateResponseTainting( - cross_origin_url, FetchRequestMode::kCorsWithForcedPreflight, - origin, CorsFlag::Set)); + cross_origin_url, RequestMode::kCors, origin, CorsFlag::Set)); + EXPECT_EQ(FetchResponseType::kCors, + cors::CalculateResponseTainting( + cross_origin_url, RequestMode::kCorsWithForcedPreflight, origin, + CorsFlag::Set)); // Origin is not provided. - EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting(same_origin_url, - FetchRequestMode::kNoCors, - no_origin, CorsFlag::Unset)); - EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting(same_origin_url, - FetchRequestMode::kNavigate, - no_origin, CorsFlag::Unset)); - EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting(cross_origin_url, - FetchRequestMode::kNoCors, - no_origin, CorsFlag::Unset)); - EXPECT_EQ(FetchResponseType::kBasic, - cors::CalculateResponseTainting(cross_origin_url, - FetchRequestMode::kNavigate, - no_origin, CorsFlag::Unset)); + EXPECT_EQ( + FetchResponseType::kBasic, + cors::CalculateResponseTainting(same_origin_url, RequestMode::kNoCors, + no_origin, CorsFlag::Unset)); + EXPECT_EQ( + FetchResponseType::kBasic, + cors::CalculateResponseTainting(same_origin_url, RequestMode::kNavigate, + no_origin, CorsFlag::Unset)); + EXPECT_EQ( + FetchResponseType::kBasic, + cors::CalculateResponseTainting(cross_origin_url, RequestMode::kNoCors, + no_origin, CorsFlag::Unset)); + EXPECT_EQ( + FetchResponseType::kBasic, + cors::CalculateResponseTainting(cross_origin_url, RequestMode::kNavigate, + no_origin, CorsFlag::Unset)); } } // namespace
diff --git a/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.cc b/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.cc index a2367811..a491ca7 100644 --- a/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.cc +++ b/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.cc
@@ -23,7 +23,7 @@ private: const KURL response_url_; - const Time response_time_; + const base::Time response_time_; const blink::mojom::CodeCacheType code_cache_type_; }; @@ -69,7 +69,7 @@ private: const KURL response_url_; - const Time response_time_; + const base::Time response_time_; const String cache_storage_cache_name_; scoped_refptr<const SecurityOrigin> security_origin_; };
diff --git a/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc b/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc index b05491fe..3af7c49 100644 --- a/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc +++ b/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc
@@ -135,7 +135,7 @@ if (!conversion_ok || persist_duration_seconds <= 0) return; - persist_duration_ = TimeDelta::FromSeconds(persist_duration_seconds); + persist_duration_ = base::TimeDelta::FromSeconds(persist_duration_seconds); if (context) context->CountPersistentClientHintHeaders(); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc b/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc index fcf6551..63c62fe 100644 --- a/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc
@@ -254,7 +254,7 @@ EXPECT_FALSE( enabled_types.IsEnabled(mojom::WebClientHintsType::kUAPlatform)); EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kUAModel)); - TimeDelta persist_duration = preferences.GetPersistDuration(); + base::TimeDelta persist_duration = preferences.GetPersistDuration(); EXPECT_EQ(base::TimeDelta(), persist_duration); const KURL kurl(String::FromUTF8("https://www.google.com/"));
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc index daa93db2..74b2d62 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
@@ -59,24 +59,23 @@ NOTREACHED(); break; case kCrossOriginAttributeAnonymous: - SetCrossOriginAccessControl( - origin, network::mojom::FetchCredentialsMode::kSameOrigin); + SetCrossOriginAccessControl(origin, + network::mojom::CredentialsMode::kSameOrigin); break; case kCrossOriginAttributeUseCredentials: - SetCrossOriginAccessControl( - origin, network::mojom::FetchCredentialsMode::kInclude); + SetCrossOriginAccessControl(origin, + network::mojom::CredentialsMode::kInclude); break; } } void FetchParameters::SetCrossOriginAccessControl( const SecurityOrigin* origin, - network::mojom::FetchCredentialsMode credentials_mode) { + network::mojom::CredentialsMode credentials_mode) { // Currently FetchParametersMode is only used when the request goes to // Service Worker. - resource_request_.SetFetchRequestMode( - network::mojom::FetchRequestMode::kCors); - resource_request_.SetFetchCredentialsMode(credentials_mode); + resource_request_.SetMode(network::mojom::RequestMode::kCors); + resource_request_.SetCredentialsMode(credentials_mode); resource_request_.SetRequestorOrigin(origin);
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h index b8a7bb1..5fcbe87 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
@@ -147,7 +147,7 @@ // Configures the request to use the "cors" mode and the specified // credentials mode. void SetCrossOriginAccessControl(const SecurityOrigin*, - network::mojom::FetchCredentialsMode); + network::mojom::CredentialsMode); const IntegrityMetadataSet IntegrityMetadata() const { return options_.integrity_metadata; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc index 78b141b..3c1f7c2 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -347,7 +347,7 @@ } } -void Resource::Finish(TimeTicks load_response_end, +void Resource::Finish(base::TimeTicks load_response_end, base::SingleThreadTaskRunner* task_runner) { DCHECK(!is_revalidating_); load_response_end_ = load_response_end; @@ -743,8 +743,7 @@ // TODO(yhirano): Remove this. if (GetResponse().WasFetchedViaServiceWorker() && GetResponse().GetType() == network::mojom::FetchResponseType::kOpaque && - new_request.GetFetchRequestMode() != - network::mojom::FetchRequestMode::kNoCors) { + new_request.GetMode() != network::mojom::RequestMode::kNoCors) { return MatchStatus::kUnknownFailure; } @@ -818,25 +817,25 @@ // securityOrigin has more complicated checks which callers are responsible // for. - if (new_request.GetFetchCredentialsMode() != - resource_request_.GetFetchCredentialsMode()) { + if (new_request.GetCredentialsMode() != + resource_request_.GetCredentialsMode()) { return MatchStatus::kRequestCredentialsModeDoesNotMatch; } - const auto new_mode = new_request.GetFetchRequestMode(); - const auto existing_mode = resource_request_.GetFetchRequestMode(); + const auto new_mode = new_request.GetMode(); + const auto existing_mode = resource_request_.GetMode(); if (new_mode != existing_mode) return MatchStatus::kRequestModeDoesNotMatch; switch (new_mode) { - case network::mojom::FetchRequestMode::kNoCors: - case network::mojom::FetchRequestMode::kNavigate: + case network::mojom::RequestMode::kNoCors: + case network::mojom::RequestMode::kNavigate: break; - case network::mojom::FetchRequestMode::kCors: - case network::mojom::FetchRequestMode::kSameOrigin: - case network::mojom::FetchRequestMode::kCorsWithForcedPreflight: + case network::mojom::RequestMode::kCors: + case network::mojom::RequestMode::kSameOrigin: + case network::mojom::RequestMode::kCorsWithForcedPreflight: // We have two separate CORS handling logics in ThreadableLoader // and ResourceLoader and sharing resources is difficult when they are // handled differently. @@ -1213,10 +1212,6 @@ return ToCodeCacheType(resource_type); } -bool Resource::ShouldBlockLoadEvent() const { - return !link_preload_ && IsLoadEventBlockingResourceType(); -} - bool Resource::IsLoadEventBlockingResourceType() const { switch (type_) { case ResourceType::kImage:
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h index 0a461a4..d82f35b 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -247,13 +247,13 @@ void SetLoader(ResourceLoader*); ResourceLoader* Loader() const { return loader_.Get(); } - bool ShouldBlockLoadEvent() const; bool IsLoadEventBlockingResourceType() const; // Computes the status of an object after loading. Updates the expire date on // the cache entry file - virtual void Finish(TimeTicks finish_time, base::SingleThreadTaskRunner*); - void FinishForTest() { Finish(TimeTicks(), nullptr); } + virtual void Finish(base::TimeTicks finish_time, + base::SingleThreadTaskRunner*); + void FinishForTest() { Finish(base::TimeTicks(), nullptr); } virtual scoped_refptr<const SharedBuffer> ResourceBuffer() const { return data_; @@ -350,7 +350,7 @@ virtual void DidDownloadData(uint64_t) {} virtual void DidDownloadToBlob(scoped_refptr<BlobDataHandle>) {} - TimeTicks LoadResponseEnd() const { return load_response_end_; } + base::TimeTicks LoadResponseEnd() const { return load_response_end_; } void SetEncodedDataLength(int64_t value) { response_.SetEncodedDataLength(value); @@ -537,7 +537,7 @@ base::Optional<ResourceError> error_; - TimeTicks load_response_end_; + base::TimeTicks load_response_end_; size_t encoded_size_; size_t encoded_size_memory_usage_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index eb6761a..d83017c 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -292,18 +292,18 @@ } } -// This maps the network::mojom::FetchRequestMode to a string that can be used +// This maps the network::mojom::RequestMode to a string that can be used // in a `Sec-Fetch-Mode` header. -const char* FetchRequestModeToString(network::mojom::FetchRequestMode mode) { +const char* RequestModeToString(network::mojom::RequestMode mode) { switch (mode) { - case network::mojom::FetchRequestMode::kSameOrigin: + case network::mojom::RequestMode::kSameOrigin: return "same-origin"; - case network::mojom::FetchRequestMode::kNoCors: + case network::mojom::RequestMode::kNoCors: return "no-cors"; - case network::mojom::FetchRequestMode::kCors: - case network::mojom::FetchRequestMode::kCorsWithForcedPreflight: + case network::mojom::RequestMode::kCors: + case network::mojom::RequestMode::kCorsWithForcedPreflight: return "cors"; - case network::mojom::FetchRequestMode::kNavigate: + case network::mojom::RequestMode::kNavigate: return "navigate"; } NOTREACHED(); @@ -332,9 +332,8 @@ request.SetHttpHeaderField("Sec-Fetch-Dest", destination_value); } - request.SetHttpHeaderField( - "Sec-Fetch-Mode", - FetchRequestModeToString(request.GetFetchRequestMode())); + request.SetHttpHeaderField("Sec-Fetch-Mode", + RequestModeToString(request.GetMode())); // Note that the `Sec-Fetch-User` header is always false (and therefore // omitted) for subresource requests. Likewise, note that we rely on @@ -619,8 +618,9 @@ } resource_load_observer_->DidFinishLoading( - identifier, TimeTicks(), 0, resource->GetResponse().DecodedBodyLength(), - false, ResourceLoadObserver::ResponseSource::kFromMemoryCache); + identifier, base::TimeTicks(), 0, + resource->GetResponse().DecodedBodyLength(), false, + ResourceLoadObserver::ResponseSource::kFromMemoryCache); if (!is_static_data) { // Resources loaded from memory cache should be reported the first time @@ -639,7 +639,7 @@ info->SetLoadResponseEnd(info->InitialTime()); scheduled_resource_timing_reports_.push_back(std::move(info)); if (!resource_timing_report_timer_.IsActive()) - resource_timing_report_timer_.StartOneShot(TimeDelta(), FROM_HERE); + resource_timing_report_timer_.StartOneShot(base::TimeDelta(), FROM_HERE); } } @@ -700,7 +700,7 @@ if (data->size()) resource->SetResourceBuffer(data); resource->SetCacheIdentifier(cache_identifier); - resource->Finish(TimeTicks(), task_runner_.get()); + resource->Finish(base::TimeTicks(), task_runner_.get()); AddToMemoryCacheIfNeeded(params, resource); return resource; @@ -885,20 +885,20 @@ resource_request.RequestorOrigin(); DCHECK(!options.cors_flag); params.MutableOptions().cors_flag = cors::CalculateCorsFlag( - params.Url(), origin.get(), resource_request.GetFetchRequestMode()); + params.Url(), origin.get(), resource_request.GetMode()); // TODO(yhirano): Reject requests for non CORS-enabled schemes. // See https://crrev.com/c/1298828. resource_request.SetAllowStoredCredentials(cors::CalculateCredentialsFlag( - resource_request.GetFetchCredentialsMode(), + resource_request.GetCredentialsMode(), cors::CalculateResponseTainting( - params.Url(), resource_request.GetFetchRequestMode(), origin.get(), + params.Url(), resource_request.GetMode(), origin.get(), params.Options().cors_flag ? CorsFlag::Set : CorsFlag::Unset))); } if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() && - resource_request.GetFetchCredentialsMode() == - network::mojom::FetchCredentialsMode::kOmit) { - // See comments at network::ResourceRequest::fetch_credentials_mode. + resource_request.GetCredentialsMode() == + network::mojom::CredentialsMode::kOmit) { + // See comments at network::ResourceRequest::credentials_mode. resource_request.SetAllowStoredCredentials(false); } @@ -1028,8 +1028,6 @@ ScheduleStaleRevalidate(resource); } - if (resource->IsLinkPreload() && !params.IsLinkPreload()) - resource->SetLinkPreload(false); break; } DCHECK(resource); @@ -1720,7 +1718,7 @@ void ResourceFetcher::HandleLoaderFinish( Resource* resource, - TimeTicks response_end, + base::TimeTicks response_end, LoaderFinishType type, uint32_t inflight_keepalive_bytes, bool should_report_corb_blocking, @@ -1910,10 +1908,17 @@ loader = MakeGarbageCollected<ResourceLoader>(this, scheduler_, resource, size); - if (resource->ShouldBlockLoadEvent()) + // Preload requests should not block the load event. IsLinkPreload() + // actually continues to return true for Resources matched from the preload + // cache that must block the load event, but that is OK because this method + // is not responsible for promoting matched preloads to load-blocking. This + // is handled by MakePreloadedResourceBlockOnloadIfNeeded(). + if (!resource->IsLinkPreload() && + resource->IsLoadEventBlockingResourceType()) { loaders_.insert(loader); - else + } else { non_blocking_loaders_.insert(loader); + } StorePerformanceTimingInitiatorInformation(resource); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h index c2e1829..8379c23 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -203,7 +203,7 @@ enum LoaderFinishType { kDidFinishLoading, kDidFinishFirstPartInMultipart }; void HandleLoaderFinish(Resource*, - TimeTicks finish_time, + base::TimeTicks finish_time, LoaderFinishType, uint32_t inflight_keepalive_bytes, bool should_report_corb_blocking,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc index 20db51d..59f9ef0 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -140,7 +140,7 @@ int transfer_size_diff) override {} void DidDownloadToBlob(uint64_t identifier, BlobDataHandle*) override {} void DidFinishLoading(uint64_t identifier, - TimeTicks finish_time, + base::TimeTicks finish_time, int64_t encoded_data_length, int64_t decoded_body_length, bool should_report_corb_blocking, @@ -661,7 +661,7 @@ Resource* preload_scanner_resource = MockResource::Fetch(fetch_params_preload_scanner, fetcher, nullptr); EXPECT_EQ(resource, preload_scanner_resource); - EXPECT_FALSE(resource->IsLinkPreload()); + EXPECT_TRUE(resource->IsLinkPreload()); // Resource created by parser FetchParameters fetch_params{ResourceRequest(url)}; @@ -669,7 +669,7 @@ MakeGarbageCollected<MockResourceClient>(); Resource* new_resource = MockResource::Fetch(fetch_params, fetcher, client); EXPECT_EQ(resource, new_resource); - EXPECT_FALSE(resource->IsLinkPreload()); + EXPECT_TRUE(resource->IsLinkPreload()); // DCL reached fetcher->ClearPreloads(ResourceFetcher::kClearSpeculativeMarkupPreloads); @@ -696,7 +696,7 @@ Resource* second_resource = MockResource::Fetch(fetch_params_second, fetcher, nullptr); EXPECT_EQ(resource, second_resource); - EXPECT_FALSE(resource->IsLinkPreload()); + EXPECT_TRUE(resource->IsLinkPreload()); } TEST_F(ResourceFetcherTest, CrossFramePreloadMatchIsNotAllowed) { @@ -789,7 +789,7 @@ EXPECT_FALSE(resource1->IsUnusedPreload()); } -TEST_F(ResourceFetcherTest, SpeculativePreloadShouldBePromotedToLinkePreload) { +TEST_F(ResourceFetcherTest, SpeculativePreloadShouldBePromotedToLinkPreload) { auto* fetcher = CreateFetcher(); KURL url("http://127.0.0.1:8000/foo.png"); @@ -824,7 +824,7 @@ EXPECT_EQ(resource1, resource3); EXPECT_FALSE(fetcher->ContainsAsPreload(resource1)); EXPECT_FALSE(resource1->IsUnusedPreload()); - EXPECT_FALSE(resource1->IsLinkPreload()); + EXPECT_TRUE(resource1->IsLinkPreload()); } TEST_F(ResourceFetcherTest, Revalidate304) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h index 7c7e4e4..9447676 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h
@@ -82,7 +82,7 @@ // Called when a request finishes successfully. virtual void DidFinishLoading(uint64_t identifier, - TimeTicks finish_time, + base::TimeTicks finish_time, int64_t encoded_data_length, int64_t decoded_body_length, bool should_report_corb_blocking,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc index 150a026b..838094ab 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc
@@ -55,78 +55,80 @@ return !(*this == other); } -void ResourceLoadTiming::SetDnsStart(TimeTicks dns_start) { +void ResourceLoadTiming::SetDnsStart(base::TimeTicks dns_start) { dns_start_ = dns_start; } -void ResourceLoadTiming::SetRequestTime(TimeTicks request_time) { +void ResourceLoadTiming::SetRequestTime(base::TimeTicks request_time) { request_time_ = request_time; } -void ResourceLoadTiming::SetProxyStart(TimeTicks proxy_start) { +void ResourceLoadTiming::SetProxyStart(base::TimeTicks proxy_start) { proxy_start_ = proxy_start; } -void ResourceLoadTiming::SetProxyEnd(TimeTicks proxy_end) { +void ResourceLoadTiming::SetProxyEnd(base::TimeTicks proxy_end) { proxy_end_ = proxy_end; } -void ResourceLoadTiming::SetDnsEnd(TimeTicks dns_end) { +void ResourceLoadTiming::SetDnsEnd(base::TimeTicks dns_end) { dns_end_ = dns_end; } -void ResourceLoadTiming::SetConnectStart(TimeTicks connect_start) { +void ResourceLoadTiming::SetConnectStart(base::TimeTicks connect_start) { connect_start_ = connect_start; } -void ResourceLoadTiming::SetConnectEnd(TimeTicks connect_end) { +void ResourceLoadTiming::SetConnectEnd(base::TimeTicks connect_end) { connect_end_ = connect_end; } -void ResourceLoadTiming::SetWorkerStart(TimeTicks worker_start) { +void ResourceLoadTiming::SetWorkerStart(base::TimeTicks worker_start) { worker_start_ = worker_start; } -void ResourceLoadTiming::SetWorkerReady(TimeTicks worker_ready) { +void ResourceLoadTiming::SetWorkerReady(base::TimeTicks worker_ready) { worker_ready_ = worker_ready; } -void ResourceLoadTiming::SetSendStart(TimeTicks send_start) { +void ResourceLoadTiming::SetSendStart(base::TimeTicks send_start) { TRACE_EVENT_MARK_WITH_TIMESTAMP0("blink.user_timing", "requestStart", send_start); send_start_ = send_start; } -void ResourceLoadTiming::SetSendEnd(TimeTicks send_end) { +void ResourceLoadTiming::SetSendEnd(base::TimeTicks send_end) { send_end_ = send_end; } void ResourceLoadTiming::SetReceiveHeadersStart( - TimeTicks receive_headers_start) { + base::TimeTicks receive_headers_start) { receive_headers_start_ = receive_headers_start; } -void ResourceLoadTiming::SetReceiveHeadersEnd(TimeTicks receive_headers_end) { +void ResourceLoadTiming::SetReceiveHeadersEnd( + base::TimeTicks receive_headers_end) { receive_headers_end_ = receive_headers_end; } -void ResourceLoadTiming::SetSslStart(TimeTicks ssl_start) { +void ResourceLoadTiming::SetSslStart(base::TimeTicks ssl_start) { ssl_start_ = ssl_start; } -void ResourceLoadTiming::SetSslEnd(TimeTicks ssl_end) { +void ResourceLoadTiming::SetSslEnd(base::TimeTicks ssl_end) { ssl_end_ = ssl_end; } -void ResourceLoadTiming::SetPushStart(TimeTicks push_start) { +void ResourceLoadTiming::SetPushStart(base::TimeTicks push_start) { push_start_ = push_start; } -void ResourceLoadTiming::SetPushEnd(TimeTicks push_end) { +void ResourceLoadTiming::SetPushEnd(base::TimeTicks push_end) { push_end_ = push_end; } -double ResourceLoadTiming::CalculateMillisecondDelta(TimeTicks time) const { +double ResourceLoadTiming::CalculateMillisecondDelta( + base::TimeTicks time) const { return time.is_null() ? -1 : (time - request_time_).InMillisecondsF(); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h index 9c978eb..079ce18 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h
@@ -42,43 +42,43 @@ bool operator==(const ResourceLoadTiming&) const; bool operator!=(const ResourceLoadTiming&) const; - void SetDnsStart(TimeTicks); - void SetRequestTime(TimeTicks); - void SetProxyStart(TimeTicks); - void SetProxyEnd(TimeTicks); - void SetDnsEnd(TimeTicks); - void SetConnectStart(TimeTicks); - void SetConnectEnd(TimeTicks); - void SetWorkerStart(TimeTicks); - void SetWorkerReady(TimeTicks); - void SetSendStart(TimeTicks); - void SetSendEnd(TimeTicks); - void SetReceiveHeadersStart(TimeTicks); - void SetReceiveHeadersEnd(TimeTicks); - void SetSslStart(TimeTicks); - void SetSslEnd(TimeTicks); - void SetPushStart(TimeTicks); - void SetPushEnd(TimeTicks); + void SetDnsStart(base::TimeTicks); + void SetRequestTime(base::TimeTicks); + void SetProxyStart(base::TimeTicks); + void SetProxyEnd(base::TimeTicks); + void SetDnsEnd(base::TimeTicks); + void SetConnectStart(base::TimeTicks); + void SetConnectEnd(base::TimeTicks); + void SetWorkerStart(base::TimeTicks); + void SetWorkerReady(base::TimeTicks); + void SetSendStart(base::TimeTicks); + void SetSendEnd(base::TimeTicks); + void SetReceiveHeadersStart(base::TimeTicks); + void SetReceiveHeadersEnd(base::TimeTicks); + void SetSslStart(base::TimeTicks); + void SetSslEnd(base::TimeTicks); + void SetPushStart(base::TimeTicks); + void SetPushEnd(base::TimeTicks); - TimeTicks DnsStart() const { return dns_start_; } - TimeTicks RequestTime() const { return request_time_; } - TimeTicks ProxyStart() const { return proxy_start_; } - TimeTicks ProxyEnd() const { return proxy_end_; } - TimeTicks DnsEnd() const { return dns_end_; } - TimeTicks ConnectStart() const { return connect_start_; } - TimeTicks ConnectEnd() const { return connect_end_; } - TimeTicks WorkerStart() const { return worker_start_; } - TimeTicks WorkerReady() const { return worker_ready_; } - TimeTicks SendStart() const { return send_start_; } - TimeTicks SendEnd() const { return send_end_; } - TimeTicks ReceiveHeadersStart() const { return receive_headers_start_; } - TimeTicks ReceiveHeadersEnd() const { return receive_headers_end_; } - TimeTicks SslStart() const { return ssl_start_; } - TimeTicks SslEnd() const { return ssl_end_; } - TimeTicks PushStart() const { return push_start_; } - TimeTicks PushEnd() const { return push_end_; } + base::TimeTicks DnsStart() const { return dns_start_; } + base::TimeTicks RequestTime() const { return request_time_; } + base::TimeTicks ProxyStart() const { return proxy_start_; } + base::TimeTicks ProxyEnd() const { return proxy_end_; } + base::TimeTicks DnsEnd() const { return dns_end_; } + base::TimeTicks ConnectStart() const { return connect_start_; } + base::TimeTicks ConnectEnd() const { return connect_end_; } + base::TimeTicks WorkerStart() const { return worker_start_; } + base::TimeTicks WorkerReady() const { return worker_ready_; } + base::TimeTicks SendStart() const { return send_start_; } + base::TimeTicks SendEnd() const { return send_end_; } + base::TimeTicks ReceiveHeadersStart() const { return receive_headers_start_; } + base::TimeTicks ReceiveHeadersEnd() const { return receive_headers_end_; } + base::TimeTicks SslStart() const { return ssl_start_; } + base::TimeTicks SslEnd() const { return ssl_end_; } + base::TimeTicks PushStart() const { return push_start_; } + base::TimeTicks PushEnd() const { return push_end_; } - double CalculateMillisecondDelta(TimeTicks) const; + double CalculateMillisecondDelta(base::TimeTicks) const; private: ResourceLoadTiming(); @@ -93,24 +93,24 @@ // pseudo time = document wall reference + // (m_requestTime - document monotonic reference). - // All values from monotonicallyIncreasingTime(), in WTF::TimeTicks. - TimeTicks request_time_; - TimeTicks proxy_start_; - TimeTicks proxy_end_; - TimeTicks dns_start_; - TimeTicks dns_end_; - TimeTicks connect_start_; - TimeTicks connect_end_; - TimeTicks worker_start_; - TimeTicks worker_ready_; - TimeTicks send_start_; - TimeTicks send_end_; - TimeTicks receive_headers_start_; - TimeTicks receive_headers_end_; - TimeTicks ssl_start_; - TimeTicks ssl_end_; - TimeTicks push_start_; - TimeTicks push_end_; + // All values from monotonicallyIncreasingTime(), in base::TimeTicks. + base::TimeTicks request_time_; + base::TimeTicks proxy_start_; + base::TimeTicks proxy_end_; + base::TimeTicks dns_start_; + base::TimeTicks dns_end_; + base::TimeTicks connect_start_; + base::TimeTicks connect_end_; + base::TimeTicks worker_start_; + base::TimeTicks worker_ready_; + base::TimeTicks send_start_; + base::TimeTicks send_end_; + base::TimeTicks receive_headers_start_; + base::TimeTicks receive_headers_end_; + base::TimeTicks ssl_start_; + base::TimeTicks ssl_end_; + base::TimeTicks push_start_; + base::TimeTicks push_end_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 0b52edaa..862c35ff 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -438,7 +438,7 @@ if (ShouldCheckCorsInResourceLoader()) { const auto origin = resource_->GetOrigin(); response_tainting_ = cors::CalculateResponseTainting( - request.Url(), request.GetFetchRequestMode(), origin.get(), + request.Url(), request.GetMode(), origin.get(), GetCorsFlag() ? CorsFlag::Set : CorsFlag::Unset); } @@ -614,7 +614,7 @@ void ResourceLoader::ScheduleCancel() { if (!cancel_timer_.IsActive()) - cancel_timer_.StartOneShot(TimeDelta(), FROM_HERE); + cancel_timer_.StartOneShot(base::TimeDelta(), FROM_HERE); } void ResourceLoader::CancelTimerFired(TimerBase*) { @@ -643,8 +643,7 @@ } static bool IsManualRedirectFetchRequest(const ResourceRequest& request) { - return request.GetFetchRedirectMode() == - network::mojom::FetchRedirectMode::kManual && + return request.GetRedirectMode() == network::mojom::RedirectMode::kManual && request.GetRequestContext() == mojom::RequestContextType::FETCH; } @@ -683,10 +682,9 @@ // The following parameters never change during the lifetime of a request. mojom::RequestContextType request_context = initial_request.GetRequestContext(); - network::mojom::FetchRequestMode fetch_request_mode = - initial_request.GetFetchRequestMode(); - network::mojom::FetchCredentialsMode fetch_credentials_mode = - initial_request.GetFetchCredentialsMode(); + network::mojom::RequestMode request_mode = initial_request.GetMode(); + network::mojom::CredentialsMode credentials_mode = + initial_request.GetCredentialsMode(); const ResourceLoaderOptions& options = resource_->Options(); @@ -724,13 +722,12 @@ scoped_refptr<const SecurityOrigin> origin = resource_->GetOrigin(); base::Optional<network::CorsErrorStatus> cors_error = cors::CheckRedirectLocation( - new_url, fetch_request_mode, origin.get(), + new_url, request_mode, origin.get(), GetCorsFlag() ? CorsFlag::Set : CorsFlag::Unset); if (!cors_error && GetCorsFlag()) { - cors_error = - cors::CheckAccess(new_url, redirect_response.HttpStatusCode(), - redirect_response.HttpHeaderFields(), - fetch_credentials_mode, *origin); + cors_error = cors::CheckAccess( + new_url, redirect_response.HttpStatusCode(), + redirect_response.HttpHeaderFields(), credentials_mode, *origin); } if (cors_error) { HandleError( @@ -762,12 +759,12 @@ base::Optional<ResourceResponse> redirect_response_with_type; if (ShouldCheckCorsInResourceLoader()) { - new_request->SetAllowStoredCredentials(cors::CalculateCredentialsFlag( - fetch_credentials_mode, response_tainting_)); + new_request->SetAllowStoredCredentials( + cors::CalculateCredentialsFlag(credentials_mode, response_tainting_)); if (!redirect_response.WasFetchedViaServiceWorker()) { auto response_type = response_tainting_; - if (initial_request.GetFetchRedirectMode() == - network::mojom::FetchRedirectMode::kManual) { + if (initial_request.GetRedirectMode() == + network::mojom::RedirectMode::kManual) { response_type = network::mojom::FetchResponseType::kOpaqueRedirect; } if (response_type != redirect_response.GetType()) { @@ -806,8 +803,8 @@ // The following parameters never change during the lifetime of a request. DCHECK_EQ(new_request->GetRequestContext(), request_context); - DCHECK_EQ(new_request->GetFetchRequestMode(), fetch_request_mode); - DCHECK_EQ(new_request->GetFetchCredentialsMode(), fetch_credentials_mode); + DCHECK_EQ(new_request->GetMode(), request_mode); + DCHECK_EQ(new_request->GetCredentialsMode(), credentials_mode); if (new_request->Url() != KURL(new_url)) { CancelForRedirectAccessCheckError(new_request->Url(), @@ -823,9 +820,9 @@ if (ShouldCheckCorsInResourceLoader()) { bool new_cors_flag = - GetCorsFlag() || cors::CalculateCorsFlag(new_request->Url(), - resource_->GetOrigin().get(), - fetch_request_mode); + GetCorsFlag() || + cors::CalculateCorsFlag(new_request->Url(), + resource_->GetOrigin().get(), request_mode); resource_->MutableOptions().cors_flag = new_cors_flag; // Cross-origin requests are only allowed certain registered schemes. if (GetCorsFlag() && !SchemeRegistry::ShouldTreatURLSchemeAsCorsEnabled( @@ -837,7 +834,7 @@ return false; } response_tainting_ = cors::CalculateResponseTainting( - new_request->Url(), fetch_request_mode, resource_->GetOrigin().get(), + new_request->Url(), request_mode, resource_->GetOrigin().get(), GetCorsFlag() ? CorsFlag::Set : CorsFlag::Unset); } @@ -904,8 +901,7 @@ // The following parameters never change during the lifetime of a request. mojom::RequestContextType request_context = initial_request.GetRequestContext(); - network::mojom::FetchRequestMode fetch_request_mode = - initial_request.GetFetchRequestMode(); + network::mojom::RequestMode request_mode = initial_request.GetMode(); const ResourceLoaderOptions& options = resource_->Options(); @@ -929,7 +925,7 @@ if (response.WasFetchedViaServiceWorker()) { if (options.cors_handling_by_resource_fetcher == kEnableCorsHandlingByResourceFetcher && - fetch_request_mode == network::mojom::FetchRequestMode::kCors && + request_mode == network::mojom::RequestMode::kCors && response.WasFallbackRequiredByServiceWorker()) { ResourceRequest last_request = resource_->LastResourceRequest(); DCHECK(!last_request.GetSkipServiceWorker()); @@ -991,8 +987,8 @@ if (GetCorsFlag()) { base::Optional<network::CorsErrorStatus> cors_error = cors::CheckAccess( response.CurrentRequestUrl(), response.HttpStatusCode(), - response.HttpHeaderFields(), - initial_request.GetFetchCredentialsMode(), *resource_->GetOrigin()); + response.HttpHeaderFields(), initial_request.GetCredentialsMode(), + *resource_->GetOrigin()); if (cors_error) { HandleError(ResourceError(response.CurrentRequestUrl(), *cors_error)); return; @@ -1104,13 +1100,13 @@ "endData", EndResourceLoadData(RequestOutcome::kSuccess)); fetcher_->HandleLoaderFinish( - resource_.Get(), TimeTicks(), + resource_.Get(), base::TimeTicks(), ResourceFetcher::kDidFinishFirstPartInMultipart, 0, false, std::vector<network::cors::PreflightTimingInfo>()); } void ResourceLoader::DidFinishLoading( - TimeTicks response_end, + base::TimeTicks response_end, int64_t encoded_data_length, int64_t encoded_body_length, int64_t decoded_body_length,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h index d48e997..2e4833e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
@@ -131,7 +131,7 @@ void DidStartLoadingResponseBody( mojo::ScopedDataPipeConsumerHandle body) override; void DidFinishLoading( - TimeTicks response_end, + base::TimeTicks response_end, int64_t encoded_data_length, int64_t encoded_body_length, int64_t decoded_body_length, @@ -238,7 +238,7 @@ // struct is used to store the information needed to refire DidFinishLoading // when the blob is finished too. struct DeferredFinishLoadingInfo { - TimeTicks response_end; + base::TimeTicks response_end; bool should_report_corb_blocking; std::vector<network::cors::PreflightTimingInfo> cors_preflight_timing_info; };
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc index 690c78f8..d4a63c1f 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
@@ -39,12 +39,12 @@ : foo_url_("https://foo.test"), bar_url_("https://bar.test") {} protected: - using FetchRequestMode = network::mojom::FetchRequestMode; + using RequestMode = network::mojom::RequestMode; using FetchResponseType = network::mojom::FetchResponseType; struct TestCase { const KURL url; - const FetchRequestMode request_mode; + const RequestMode request_mode; const From from; const scoped_refptr<const SecurityOrigin> allowed_origin; const FetchResponseType original_response_type; @@ -128,41 +128,40 @@ TestCase cases[] = { // Same origin response: - {same_origin_url, FetchRequestMode::kNoCors, From::kNetwork, no_origin, + {same_origin_url, RequestMode::kNoCors, From::kNetwork, no_origin, FetchResponseType::kDefault, FetchResponseType::kBasic}, - {same_origin_url, FetchRequestMode::kCors, From::kNetwork, no_origin, + {same_origin_url, RequestMode::kCors, From::kNetwork, no_origin, FetchResponseType::kDefault, FetchResponseType::kBasic}, // Cross origin, no-cors: - {cross_origin_url, FetchRequestMode::kNoCors, From::kNetwork, no_origin, + {cross_origin_url, RequestMode::kNoCors, From::kNetwork, no_origin, FetchResponseType::kDefault, FetchResponseType::kOpaque}, // Cross origin, cors: - {cross_origin_url, FetchRequestMode::kCors, From::kNetwork, origin, + {cross_origin_url, RequestMode::kCors, From::kNetwork, origin, FetchResponseType::kDefault, FetchResponseType::kCors}, - {cross_origin_url, FetchRequestMode::kCors, From::kNetwork, no_origin, + {cross_origin_url, RequestMode::kCors, From::kNetwork, no_origin, FetchResponseType::kDefault, FetchResponseType::kError}, // From service worker, no-cors: - {same_origin_url, FetchRequestMode::kNoCors, From::kServiceWorker, - no_origin, FetchResponseType::kBasic, FetchResponseType::kBasic}, - {same_origin_url, FetchRequestMode::kNoCors, From::kServiceWorker, - no_origin, FetchResponseType::kCors, FetchResponseType::kCors}, - {same_origin_url, FetchRequestMode::kNoCors, From::kServiceWorker, - no_origin, FetchResponseType::kDefault, FetchResponseType::kDefault}, - {same_origin_url, FetchRequestMode::kNoCors, From::kServiceWorker, - no_origin, FetchResponseType::kOpaque, FetchResponseType::kOpaque}, - {same_origin_url, FetchRequestMode::kNoCors, From::kServiceWorker, - no_origin, FetchResponseType::kOpaqueRedirect, - FetchResponseType::kOpaqueRedirect}, + {same_origin_url, RequestMode::kNoCors, From::kServiceWorker, no_origin, + FetchResponseType::kBasic, FetchResponseType::kBasic}, + {same_origin_url, RequestMode::kNoCors, From::kServiceWorker, no_origin, + FetchResponseType::kCors, FetchResponseType::kCors}, + {same_origin_url, RequestMode::kNoCors, From::kServiceWorker, no_origin, + FetchResponseType::kDefault, FetchResponseType::kDefault}, + {same_origin_url, RequestMode::kNoCors, From::kServiceWorker, no_origin, + FetchResponseType::kOpaque, FetchResponseType::kOpaque}, + {same_origin_url, RequestMode::kNoCors, From::kServiceWorker, no_origin, + FetchResponseType::kOpaqueRedirect, FetchResponseType::kOpaqueRedirect}, // From service worker, cors: - {same_origin_url, FetchRequestMode::kCors, From::kServiceWorker, - no_origin, FetchResponseType::kBasic, FetchResponseType::kBasic}, - {same_origin_url, FetchRequestMode::kNoCors, From::kServiceWorker, - no_origin, FetchResponseType::kCors, FetchResponseType::kCors}, - {same_origin_url, FetchRequestMode::kNoCors, From::kServiceWorker, - no_origin, FetchResponseType::kDefault, FetchResponseType::kDefault}, + {same_origin_url, RequestMode::kCors, From::kServiceWorker, no_origin, + FetchResponseType::kBasic, FetchResponseType::kBasic}, + {same_origin_url, RequestMode::kNoCors, From::kServiceWorker, no_origin, + FetchResponseType::kCors, FetchResponseType::kCors}, + {same_origin_url, RequestMode::kNoCors, From::kServiceWorker, no_origin, + FetchResponseType::kDefault, FetchResponseType::kDefault}, }; for (const auto& test : cases) { @@ -183,13 +182,13 @@ MakeGarbageCollected<NoopLoaderFactory>())); ResourceRequest request; request.SetUrl(test.url); - request.SetFetchRequestMode(test.request_mode); + request.SetMode(test.request_mode); request.SetRequestContext(mojom::RequestContextType::FETCH); FetchParameters fetch_parameters(request); - if (test.request_mode == network::mojom::FetchRequestMode::kCors) { + if (test.request_mode == network::mojom::RequestMode::kCors) { fetch_parameters.SetCrossOriginAccessControl( - origin.get(), network::mojom::FetchCredentialsMode::kOmit); + origin.get(), network::mojom::CredentialsMode::kOmit); } Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr); ResourceLoader* loader = resource->Loader();
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index 3a8d3eb5..836744d 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -67,10 +67,10 @@ plugin_child_id_(-1), previews_state_(WebURLRequest::kPreviewsUnspecified), request_context_(mojom::RequestContextType::UNSPECIFIED), - fetch_request_mode_(network::mojom::FetchRequestMode::kNoCors), + mode_(network::mojom::RequestMode::kNoCors), fetch_importance_mode_(mojom::FetchImportanceMode::kImportanceAuto), - fetch_credentials_mode_(network::mojom::FetchCredentialsMode::kInclude), - fetch_redirect_mode_(network::mojom::FetchRedirectMode::kFollow), + credentials_mode_(network::mojom::CredentialsMode::kInclude), + redirect_mode_(network::mojom::RedirectMode::kFollow), referrer_string_(Referrer::ClientReferrerString()), referrer_policy_(network::mojom::ReferrerPolicy::kDefault), did_set_http_referrer_(false), @@ -112,8 +112,8 @@ request->SetUseStreamOnResponse(UseStreamOnResponse()); request->SetRequestContext(GetRequestContext()); request->SetShouldResetAppCache(ShouldResetAppCache()); - request->SetFetchRequestMode(GetFetchRequestMode()); - request->SetFetchCredentialsMode(GetFetchCredentialsMode()); + request->SetMode(GetMode()); + request->SetCredentialsMode(GetCredentialsMode()); request->SetKeepalive(GetKeepalive()); request->SetPriority(Priority());
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 57a6100..0cc04b6 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -291,12 +291,8 @@ request_context_ = context; } - network::mojom::FetchRequestMode GetFetchRequestMode() const { - return fetch_request_mode_; - } - void SetFetchRequestMode(network::mojom::FetchRequestMode mode) { - fetch_request_mode_ = mode; - } + network::mojom::RequestMode GetMode() const { return mode_; } + void SetMode(network::mojom::RequestMode mode) { mode_ = mode; } // A resource request's fetch_importance_mode_ is a developer-set priority // hint that differs from priority_. It is used in @@ -313,18 +309,18 @@ fetch_importance_mode_ = mode; } - network::mojom::FetchCredentialsMode GetFetchCredentialsMode() const { - return fetch_credentials_mode_; + network::mojom::CredentialsMode GetCredentialsMode() const { + return credentials_mode_; } - void SetFetchCredentialsMode(network::mojom::FetchCredentialsMode mode) { - fetch_credentials_mode_ = mode; + void SetCredentialsMode(network::mojom::CredentialsMode mode) { + credentials_mode_ = mode; } - network::mojom::FetchRedirectMode GetFetchRedirectMode() const { - return fetch_redirect_mode_; + network::mojom::RedirectMode GetRedirectMode() const { + return redirect_mode_; } - void SetFetchRedirectMode(network::mojom::FetchRedirectMode redirect) { - fetch_redirect_mode_ = redirect; + void SetRedirectMode(network::mojom::RedirectMode redirect) { + redirect_mode_ = redirect; } const String& GetFetchIntegrity() const { return fetch_integrity_; } @@ -444,7 +440,8 @@ // TODO(yoav): initial_url_for_resource_timing_ is a stop-gap only needed // until Out-of-Blink CORS lands: https://crbug.com/736308 KURL initial_url_for_resource_timing_; - // TimeDelta::Max() represents the default timeout on platforms that have one. + // base::TimeDelta::Max() represents the default timeout on platforms that + // have one. base::TimeDelta timeout_interval_; KURL site_for_cookies_; scoped_refptr<const SecurityOrigin> top_frame_origin_; @@ -474,10 +471,10 @@ WebURLRequest::PreviewsState previews_state_; scoped_refptr<SharableExtraData> sharable_extra_data_; mojom::RequestContextType request_context_; - network::mojom::FetchRequestMode fetch_request_mode_; + network::mojom::RequestMode mode_; mojom::FetchImportanceMode fetch_importance_mode_; - network::mojom::FetchCredentialsMode fetch_credentials_mode_; - network::mojom::FetchRedirectMode fetch_redirect_mode_; + network::mojom::CredentialsMode credentials_mode_; + network::mojom::RedirectMode redirect_mode_; String fetch_integrity_; // TODO(domfarolino): Use AtomicString for referrer_string_ once // off-main-thread fetch is fully implemented and ResourceRequest never gets
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/third_party/blink/renderer/platform/loader/fetch/resource_response.h index 858a47c8..edb97c3 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_response.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -353,8 +353,10 @@ did_service_worker_navigation_preload_ = value; } - Time ResponseTime() const { return response_time_; } - void SetResponseTime(Time response_time) { response_time_ = response_time; } + base::Time ResponseTime() const { return response_time_; } + void SetResponseTime(base::Time response_time) { + response_time_ = response_time; + } const AtomicString& RemoteIPAddress() const { return remote_ip_address_; } void SetRemoteIPAddress(const AtomicString& value) { @@ -545,7 +547,7 @@ // The time at which the response headers were received. For cached // responses, this time could be "far" in the past. - Time response_time_; + base::Time response_time_; // ALPN negotiated protocol of the socket which fetched this resource. AtomicString alpn_negotiated_protocol_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_test.cc index 55b6018e..97a3668 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
@@ -29,7 +29,7 @@ // From blink::Platform: void CacheMetadata(blink::mojom::CodeCacheType cache_type, const WebURL& url, - Time, + base::Time, const uint8_t*, size_t) override { cached_urls_.push_back(url);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h b/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h index 84304db..28e571f 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
@@ -49,15 +49,15 @@ public: static scoped_refptr<ResourceTimingInfo> Create(const AtomicString& type, - const TimeTicks time) { + const base::TimeTicks time) { return base::AdoptRef(new ResourceTimingInfo(type, time)); } - TimeTicks InitialTime() const { return initial_time_; } + base::TimeTicks InitialTime() const { return initial_time_; } const AtomicString& InitiatorType() const { return type_; } - void SetLoadResponseEnd(TimeTicks time) { load_response_end_ = time; } - TimeTicks LoadResponseEnd() const { return load_response_end_; } + void SetLoadResponseEnd(base::TimeTicks time) { load_response_end_ = time; } + base::TimeTicks LoadResponseEnd() const { return load_response_end_; } void SetInitialURL(const KURL& url) { initial_url_ = url; } const KURL& InitialURL() const { return initial_url_; } @@ -90,12 +90,12 @@ bool NegativeAllowed() const { return negative_allowed_; } private: - ResourceTimingInfo(const AtomicString& type, const TimeTicks time) + ResourceTimingInfo(const AtomicString& type, const base::TimeTicks time) : type_(type), initial_time_(time) {} AtomicString type_; - TimeTicks initial_time_; - TimeTicks load_response_end_; + base::TimeTicks initial_time_; + base::TimeTicks load_response_end_; KURL initial_url_; ResourceResponse final_response_; Vector<ResourceResponse> redirect_chain_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h b/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h index ab470d0..1dbb457 100644 --- a/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h +++ b/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h
@@ -37,7 +37,7 @@ // https://github.com/whatwg/html/pull/3656. ScriptFetchOptions() : parser_state_(ParserDisposition::kNotParserInserted), - credentials_mode_(network::mojom::FetchCredentialsMode::kOmit), + credentials_mode_(network::mojom::CredentialsMode::kOmit), referrer_policy_(network::mojom::ReferrerPolicy::kDefault), importance_(mojom::FetchImportanceMode::kImportanceAuto) {} @@ -45,7 +45,7 @@ const IntegrityMetadataSet& integrity_metadata, const String& integrity_attribute, ParserDisposition parser_state, - network::mojom::FetchCredentialsMode credentials_mode, + network::mojom::CredentialsMode credentials_mode, network::mojom::ReferrerPolicy referrer_policy, mojom::FetchImportanceMode importance) : nonce_(nonce), @@ -65,7 +65,7 @@ return integrity_attribute_; } const ParserDisposition& ParserState() const { return parser_state_; } - network::mojom::FetchCredentialsMode CredentialsMode() const { + network::mojom::CredentialsMode CredentialsMode() const { return credentials_mode_; } network::mojom::ReferrerPolicy GetReferrerPolicy() const { @@ -93,7 +93,7 @@ const ParserDisposition parser_state_; // https://html.spec.whatwg.org/C/#concept-script-fetch-options-credentials - const network::mojom::FetchCredentialsMode credentials_mode_; + const network::mojom::CredentialsMode credentials_mode_; // https://html.spec.whatwg.org/C/#concept-script-fetch-options-referrer-policy const network::mojom::ReferrerPolicy referrer_policy_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc b/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc index ad6e774..81691ef 100644 --- a/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc
@@ -85,7 +85,7 @@ private: const KURL response_url_; - const Time response_time_; + const base::Time response_time_; }; template <size_t N>
diff --git a/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc b/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc index ab2f54a1..c00566f 100644 --- a/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc +++ b/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc
@@ -21,7 +21,7 @@ GetMemoryCache()->Remove(stale_resource_); ClearResource(); - TimeTicks response_end = resource->LoadResponseEnd(); + base::TimeTicks response_end = resource->LoadResponseEnd(); if (!response_end.is_null()) { UMA_HISTOGRAM_LONG_TIMES( "Blink.ResourceFetcher.StaleWhileRevalidateDuration",
diff --git a/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc b/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc index 47b2d60..8bfa8ff 100644 --- a/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc +++ b/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc
@@ -189,7 +189,7 @@ struct TestCase { const KURL url; - network::mojom::FetchRequestMode request_mode; + network::mojom::RequestMode request_mode; network::mojom::FetchResponseType response_type; const Expectation expectation; }; @@ -219,14 +219,14 @@ Resource* CreateTestResource( const KURL& url, - network::mojom::FetchRequestMode request_mode, + network::mojom::RequestMode request_mode, network::mojom::FetchResponseType response_type) { Resource* resource = RawResource::CreateForTest( url, SecurityOrigin::CreateUniqueOpaque(), ResourceType::kRaw); ResourceRequest request; request.SetUrl(url); - request.SetFetchRequestMode(request_mode); + request.SetMode(request_mode); ResourceResponse response(url); response.SetHttpStatusCode(200); @@ -509,28 +509,27 @@ // requests, successful and failing CORS checks as well as when the response was // handled by a service worker. TEST_F(SubresourceIntegrityTest, OriginIntegrity) { - using network::mojom::FetchRequestMode; using network::mojom::FetchResponseType; + using network::mojom::RequestMode; constexpr auto kOk = kIntegritySuccess; constexpr auto kFail = kIntegrityFailure; const KURL& url = sec_url; const TestCase cases[] = { // FetchResponseType::kError never arrives because it is a loading error. - {url, FetchRequestMode::kNoCors, FetchResponseType::kBasic, kOk}, - {url, FetchRequestMode::kNoCors, FetchResponseType::kCors, kOk}, - {url, FetchRequestMode::kNoCors, FetchResponseType::kDefault, kOk}, - {url, FetchRequestMode::kNoCors, FetchResponseType::kOpaque, kFail}, - {url, FetchRequestMode::kNoCors, FetchResponseType::kOpaqueRedirect, - kFail}, + {url, RequestMode::kNoCors, FetchResponseType::kBasic, kOk}, + {url, RequestMode::kNoCors, FetchResponseType::kCors, kOk}, + {url, RequestMode::kNoCors, FetchResponseType::kDefault, kOk}, + {url, RequestMode::kNoCors, FetchResponseType::kOpaque, kFail}, + {url, RequestMode::kNoCors, FetchResponseType::kOpaqueRedirect, kFail}, // FetchResponseType::kError never arrives because it is a loading error. // FetchResponseType::kOpaque and FetchResponseType::kOpaqueResponse // never arrives: even when service worker is involved, it's handled as // an error. - {url, FetchRequestMode::kCors, FetchResponseType::kBasic, kOk}, - {url, FetchRequestMode::kCors, FetchResponseType::kCors, kOk}, - {url, FetchRequestMode::kCors, FetchResponseType::kDefault, kOk}, + {url, RequestMode::kCors, FetchResponseType::kBasic, kOk}, + {url, RequestMode::kCors, FetchResponseType::kCors, kOk}, + {url, RequestMode::kCors, FetchResponseType::kDefault, kOk}, }; for (const auto& test : cases) {
diff --git a/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc b/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc index c0531a5..ddb70c9 100644 --- a/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc +++ b/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc
@@ -299,7 +299,7 @@ const KURL& url, const String& title, const String& mime_type, - WTF::Time date, + base::Time date, Vector<char>& output_buffer) { DCHECK(!boundary.IsEmpty()); DCHECK(!mime_type.IsEmpty());
diff --git a/third_party/blink/renderer/platform/mhtml/mhtml_archive.h b/third_party/blink/renderer/platform/mhtml/mhtml_archive.h index 066ef4c..a7690a2a 100644 --- a/third_party/blink/renderer/platform/mhtml/mhtml_archive.h +++ b/third_party/blink/renderer/platform/mhtml/mhtml_archive.h
@@ -71,7 +71,7 @@ const KURL&, const String& title, const String& mime_type, - WTF::Time date, + base::Time date, Vector<char>& output_buffer); // Serializes SerializedResource as an MHTML part and appends it in @@ -104,7 +104,7 @@ ArchiveResource* SubresourceForURL(const KURL&) const; // The purported creation date (as expressed by the Date: header). - WTF::Time Date() const { return date_; } + base::Time Date() const { return date_; } void Trace(blink::Visitor*); blink::mojom::MHTMLLoadResult LoadResult() const { return load_result_; } @@ -118,7 +118,7 @@ void AddSubresource(ArchiveResource*); static bool CanLoadArchive(const KURL&); - WTF::Time date_; + base::Time date_; Member<ArchiveResource> main_resource_; SubArchiveResources subresources_; blink::mojom::MHTMLLoadResult load_result_;
diff --git a/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc b/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc index 41ede87..2e63321 100644 --- a/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc +++ b/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
@@ -117,7 +117,7 @@ } String ContentLocation() const { return content_location_; } String ContentID() const { return content_id_; } - WTF::Time Date() const { return date_; } + base::Time Date() const { return date_; } // Multi-part type and boundaries are only valid for multipart MIME headers. String MultiPartType() const { return multipart_type_; } @@ -134,7 +134,7 @@ Encoding content_transfer_encoding_; String content_location_; String content_id_; - WTF::Time date_; + base::Time date_; String multipart_type_; String end_of_part_boundary_; String end_of_document_boundary_; @@ -221,11 +221,11 @@ mime_parameters_iterator = key_value_pairs.find("date"); if (mime_parameters_iterator != key_value_pairs.end()) { - WTF::Time parsed_time; + base::Time parsed_time; // Behave like //net and parse time-valued headers with a default time zone // of UTC. - if (WTF::Time::FromUTCString(mime_parameters_iterator->value.Utf8().c_str(), - &parsed_time)) + if (base::Time::FromUTCString( + mime_parameters_iterator->value.Utf8().c_str(), &parsed_time)) mime_header->date_ = parsed_time; } @@ -276,7 +276,7 @@ return resources; } -WTF::Time MHTMLParser::CreationDate() const { +base::Time MHTMLParser::CreationDate() const { return creation_date_; }
diff --git a/third_party/blink/renderer/platform/mhtml/mhtml_parser.h b/third_party/blink/renderer/platform/mhtml/mhtml_parser.h index 732085a0..76ac460 100644 --- a/third_party/blink/renderer/platform/mhtml/mhtml_parser.h +++ b/third_party/blink/renderer/platform/mhtml/mhtml_parser.h
@@ -56,7 +56,7 @@ explicit MHTMLParser(scoped_refptr<const SharedBuffer>); HeapVector<Member<ArchiveResource>> ParseArchive(); - WTF::Time CreationDate() const; + base::Time CreationDate() const; // Translates |contentIDFromMimeHeader| (of the form "<foo@bar.com>") // into a cid-scheme URI (of the form "cid:foo@bar.com"). @@ -74,7 +74,7 @@ const String& end_of_document_boundary, bool& end_of_archive_reached); - WTF::Time creation_date_; + base::Time creation_date_; SharedBufferChunkReader line_reader_; };
diff --git a/third_party/blink/renderer/platform/mhtml/mhtml_parser_test.cc b/third_party/blink/renderer/platform/mhtml/mhtml_parser_test.cc index 4f3e910..ce61891 100644 --- a/third_party/blink/renderer/platform/mhtml/mhtml_parser_test.cc +++ b/third_party/blink/renderer/platform/mhtml/mhtml_parser_test.cc
@@ -33,7 +33,7 @@ return parser.ParseArchive(); } - WTF::Time ParseArchiveTime(const char* mhtml_data, size_t size) { + base::Time ParseArchiveTime(const char* mhtml_data, size_t size) { scoped_refptr<SharedBuffer> buf = SharedBuffer::Create(mhtml_data, size); MHTMLParser parser(buf); EXPECT_GT(parser.ParseArchive().size(), 0U); @@ -356,10 +356,10 @@ "bin\0ary\r\n" "--BoUnDaRy--\r\n"; - WTF::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); + base::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); // No header should produce an invalid time. - EXPECT_EQ(WTF::Time(), creation_time); + EXPECT_EQ(base::Time(), creation_time); } TEST_F(MHTMLParserTest, DateParsing_InvalidDate) { @@ -383,10 +383,10 @@ "bin\0ary\r\n" "--BoUnDaRy--\r\n"; - WTF::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); + base::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); // Invalid header should produce an invalid time. - EXPECT_EQ(WTF::Time(), creation_time); + EXPECT_EQ(base::Time(), creation_time); } TEST_F(MHTMLParserTest, DateParsing_ValidDate) { @@ -408,9 +408,9 @@ "bin\0ary\r\n" "--BoUnDaRy--\r\n"; - WTF::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); - WTF::Time expected_time; - ASSERT_TRUE(WTF::Time::FromUTCExploded( + base::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); + base::Time expected_time; + ASSERT_TRUE(base::Time::FromUTCExploded( {2017, 3 /* March */, 5 /* Friday */, 1, 22, 44, 17, 0}, &expected_time)); EXPECT_EQ(expected_time, creation_time); } @@ -443,8 +443,8 @@ "bin\0ary\r\n" "--BoUnDaRy--\r\n"; - WTF::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); - EXPECT_EQ(WTF::Time(), creation_time); + base::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); + EXPECT_EQ(base::Time(), creation_time); } TEST_F(MHTMLParserTest, OverflowedDay) { @@ -465,8 +465,8 @@ "bin\0ary\r\n" "--BoUnDaRy--\r\n"; - WTF::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); - EXPECT_EQ(WTF::Time(), creation_time); + base::Time creation_time = ParseArchiveTime(mhtml_data, sizeof(mhtml_data)); + EXPECT_EQ(base::Time(), creation_time); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc b/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc index 44dca7c0..61735335 100644 --- a/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc +++ b/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc
@@ -4,7 +4,7 @@ #include <utility> -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/mojo/geometry.mojom-blink.h" @@ -93,7 +93,7 @@ mojo::BindingSet<gfx::mojom::blink::GeometryTraitsTestService> traits_test_bindings_; - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; DISALLOW_COPY_AND_ASSIGN(GeometryStructTraitsTest); };
diff --git a/third_party/blink/renderer/platform/network/network_state_notifier.cc b/third_party/blink/renderer/platform/network/network_state_notifier.cc index 93d3f02..dbc9d03a 100644 --- a/third_party/blink/renderer/platform/network/network_state_notifier.cc +++ b/third_party/blink/renderer/platform/network/network_state_notifier.cc
@@ -135,8 +135,8 @@ } void NetworkStateNotifier::SetNetworkQuality(WebEffectiveConnectionType type, - TimeDelta http_rtt, - TimeDelta transport_rtt, + base::TimeDelta http_rtt, + base::TimeDelta transport_rtt, int downlink_throughput_kbps) { DCHECK(IsMainThread()); ScopedNotifier notifier(*this); @@ -219,7 +219,8 @@ override_.max_bandwidth_mbps = max_bandwidth_mbps; if (!effective_type && http_rtt_msec > 0) { - base::TimeDelta http_rtt(TimeDelta::FromMilliseconds(http_rtt_msec)); + base::TimeDelta http_rtt( + base::TimeDelta::FromMilliseconds(http_rtt_msec)); // Threshold values taken from // net/nqe/network_quality_estimator_params.cc. if (http_rtt >= net::kHttpRttEffectiveConnectionTypeThresholds @@ -238,7 +239,7 @@ override_.effective_type = effective_type ? effective_type.value() : WebEffectiveConnectionType::kTypeUnknown; - override_.http_rtt = TimeDelta::FromMilliseconds(http_rtt_msec); + override_.http_rtt = base::TimeDelta::FromMilliseconds(http_rtt_msec); override_.downlink_throughput_mbps = max_bandwidth_mbps; } } @@ -428,7 +429,7 @@ uint32_t NetworkStateNotifier::RoundRtt( const String& host, - const base::Optional<TimeDelta>& rtt) const { + const base::Optional<base::TimeDelta>& rtt) const { // Limit the size of the buckets and the maximum reported value to reduce // fingerprinting. static const size_t kBucketSize = 50; @@ -489,7 +490,8 @@ return state.network_quality_web_holdback; } -base::Optional<TimeDelta> NetworkStateNotifier::GetWebHoldbackHttpRtt() const { +base::Optional<base::TimeDelta> NetworkStateNotifier::GetWebHoldbackHttpRtt() + const { base::Optional<WebEffectiveConnectionType> override_ect = GetWebHoldbackEffectiveType(); @@ -516,7 +518,7 @@ WebConnectionType* type, double* downlink_max_mbps, WebEffectiveConnectionType* effective_type, - base::Optional<TimeDelta>* http_rtt, + base::Optional<base::TimeDelta>* http_rtt, base::Optional<double>* downlink_mbps, bool* save_data) const { MutexLocker locker(mutex_);
diff --git a/third_party/blink/renderer/platform/network/network_state_notifier.h b/third_party/blink/renderer/platform/network/network_state_notifier.h index 0814597..b61b4438 100644 --- a/third_party/blink/renderer/platform/network/network_state_notifier.h +++ b/third_party/blink/renderer/platform/network/network_state_notifier.h
@@ -58,8 +58,8 @@ double max_bandwidth_mbps = kInvalidMaxBandwidth; WebEffectiveConnectionType effective_type = WebEffectiveConnectionType::kTypeUnknown; - base::Optional<TimeDelta> http_rtt; - base::Optional<TimeDelta> transport_rtt; + base::Optional<base::TimeDelta> http_rtt; + base::Optional<base::TimeDelta> transport_rtt; base::Optional<double> downlink_throughput_mbps; bool save_data = false; @@ -77,8 +77,8 @@ WebConnectionType, double max_bandwidth_mbps, WebEffectiveConnectionType, - const base::Optional<TimeDelta>& http_rtt, - const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<base::TimeDelta>& http_rtt, + const base::Optional<base::TimeDelta>& transport_rtt, const base::Optional<double>& downlink_throughput_mbps, bool save_data) {} virtual void OnLineStateChange(bool on_line) {} @@ -136,7 +136,7 @@ // Returns the current HTTP RTT estimate. If the estimate is unavailable, the // returned optional value is null. - base::Optional<TimeDelta> HttpRtt() const { + base::Optional<base::TimeDelta> HttpRtt() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; // TODO (tbansal): Add a DCHECK to check that |state.on_line_initialized| is @@ -146,7 +146,7 @@ // Returns the current transport RTT estimate. If the estimate is unavailable, // the returned optional value is null. - base::Optional<TimeDelta> TransportRtt() const { + base::Optional<base::TimeDelta> TransportRtt() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; DCHECK(state.on_line_initialized); @@ -214,8 +214,8 @@ void SetWebConnection(WebConnectionType, double max_bandwidth_mbps); void SetNetworkQuality(WebEffectiveConnectionType, - TimeDelta http_rtt, - TimeDelta transport_rtt, + base::TimeDelta http_rtt, + base::TimeDelta transport_rtt, int downlink_throughput_kbps); void SetNetworkQualityWebHoldback(WebEffectiveConnectionType); void SetSaveDataEnabled(bool enabled); @@ -256,7 +256,7 @@ // Returns |rtt| after adding host-specific random noise, and rounding it as // per the NetInfo spec to improve privacy. uint32_t RoundRtt(const String& host, - const base::Optional<TimeDelta>& rtt) const; + const base::Optional<base::TimeDelta>& rtt) const; // Returns |downlink_mbps| after adding host-specific random noise, and // rounding it as per the NetInfo spec and to improve privacy. @@ -280,7 +280,7 @@ // the web consumers. If the returned value is null, then the actual network // quality value should be returned to the web consumers. // Consumers within Blink should not call this API. - base::Optional<TimeDelta> GetWebHoldbackHttpRtt() const; + base::Optional<base::TimeDelta> GetWebHoldbackHttpRtt() const; // Returns the overriding HTTP RTT estimate that should be returned to // the web consumers. If the returned value is null, then the actual network @@ -294,7 +294,7 @@ void GetMetricsWithWebHoldback(WebConnectionType* type, double* downlink_max_mbps, WebEffectiveConnectionType* effective_type, - base::Optional<TimeDelta>* http_rtt, + base::Optional<base::TimeDelta>* http_rtt, base::Optional<double>* downlink_mbps, bool* save_data) const;
diff --git a/third_party/blink/renderer/platform/network/network_state_notifier_test.cc b/third_party/blink/renderer/platform/network/network_state_notifier_test.cc index 3e01c4c..3dd27d114 100644 --- a/third_party/blink/renderer/platform/network/network_state_notifier_test.cc +++ b/third_party/blink/renderer/platform/network/network_state_notifier_test.cc
@@ -51,12 +51,12 @@ const double kNoneMaxBandwidthMbps = 0.0; const double kBluetoothMaxBandwidthMbps = 1.0; const double kEthernetMaxBandwidthMbps = 2.0; -const base::Optional<TimeDelta> kEthernetHttpRtt( - TimeDelta::FromMilliseconds(50)); -const base::Optional<TimeDelta> kEthernetTransportRtt( - TimeDelta::FromMilliseconds(25)); +const base::Optional<base::TimeDelta> kEthernetHttpRtt( + base::TimeDelta::FromMilliseconds(50)); +const base::Optional<base::TimeDelta> kEthernetTransportRtt( + base::TimeDelta::FromMilliseconds(25)); const base::Optional<double> kEthernetThroughputMbps(75.0); -const base::Optional<TimeDelta> kUnknownRtt; +const base::Optional<base::TimeDelta> kUnknownRtt; const base::Optional<double> kUnknownThroughputMbps; enum class SaveData { @@ -82,8 +82,8 @@ void ConnectionChange(WebConnectionType type, double max_bandwidth_mbps, WebEffectiveConnectionType effective_type, - const base::Optional<TimeDelta>& http_rtt, - const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<base::TimeDelta>& http_rtt, + const base::Optional<base::TimeDelta>& transport_rtt, const base::Optional<double>& downlink_throughput_mbps, bool save_data) override { observed_type_ = type; @@ -112,10 +112,10 @@ WebEffectiveConnectionType ObservedEffectiveType() const { return observed_effective_type_; } - base::Optional<TimeDelta> ObservedHttpRtt() const { + base::Optional<base::TimeDelta> ObservedHttpRtt() const { return observed_http_rtt_; } - base::Optional<TimeDelta> ObservedTransportRtt() const { + base::Optional<base::TimeDelta> ObservedTransportRtt() const { return observed_transport_rtt_; } base::Optional<double> ObservedDownlinkThroughputMbps() const { @@ -154,8 +154,8 @@ WebConnectionType observed_type_; double observed_max_bandwidth_mbps_; WebEffectiveConnectionType observed_effective_type_; - base::Optional<TimeDelta> observed_http_rtt_; - base::Optional<TimeDelta> observed_transport_rtt_; + base::Optional<base::TimeDelta> observed_http_rtt_; + base::Optional<base::TimeDelta> observed_transport_rtt_; base::Optional<double> observed_downlink_throughput_mbps_; bool observed_on_line_state_; SaveData observed_save_data_; @@ -196,8 +196,8 @@ void SetConnection(WebConnectionType type, double max_bandwidth_mbps, WebEffectiveConnectionType effective_type, - const base::Optional<TimeDelta>& http_rtt, - const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<base::TimeDelta>& http_rtt, + const base::Optional<base::TimeDelta>& transport_rtt, const base::Optional<double>& downlink_throughput_mbps, SaveData save_data) { notifier_.SetWebConnection(type, max_bandwidth_mbps); @@ -222,13 +222,13 @@ WebConnectionType expected_type, double expected_max_bandwidth_mbps, WebEffectiveConnectionType expected_effective_type, - const base::Optional<TimeDelta>& expected_http_rtt, + const base::Optional<base::TimeDelta>& expected_http_rtt, const base::Optional<double>& expected_downlink_throughput_mbps, SaveData expected_save_data) const { WebConnectionType initial_type; double initial_downlink_max_mbps; WebEffectiveConnectionType initial_effective_type; - base::Optional<TimeDelta> initial_http_rtt; + base::Optional<base::TimeDelta> initial_http_rtt; base::Optional<double> initial_downlink_mbps; bool initial_save_data; @@ -249,8 +249,8 @@ WebConnectionType type, double max_bandwidth_mbps, WebEffectiveConnectionType effective_type, - const base::Optional<TimeDelta>& http_rtt, - const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<base::TimeDelta>& http_rtt, + const base::Optional<base::TimeDelta>& transport_rtt, const base::Optional<double>& downlink_throughput_mbps, SaveData save_data) const { EXPECT_EQ(type, observer.ObservedType()); @@ -1002,13 +1002,16 @@ kNoneMaxBandwidthMbps, SaveData::kOff)); const struct { - base::Optional<TimeDelta> rtt; + base::Optional<base::TimeDelta> rtt; WebEffectiveConnectionType expected_effective_connection_type; } tests[] = { - {TimeDelta::FromMilliseconds(100), WebEffectiveConnectionType::kType4G}, - {TimeDelta::FromMilliseconds(600), WebEffectiveConnectionType::kType3G}, - {TimeDelta::FromMilliseconds(1600), WebEffectiveConnectionType::kType2G}, - {TimeDelta::FromMilliseconds(2800), + {base::TimeDelta::FromMilliseconds(100), + WebEffectiveConnectionType::kType4G}, + {base::TimeDelta::FromMilliseconds(600), + WebEffectiveConnectionType::kType3G}, + {base::TimeDelta::FromMilliseconds(1600), + WebEffectiveConnectionType::kType2G}, + {base::TimeDelta::FromMilliseconds(2800), WebEffectiveConnectionType::kTypeSlow2G}, };
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index b330dec2..05258d0f 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1354,6 +1354,12 @@ { name: "ScrollCustomization", }, + { + name: "ScrollTimeline", + status: "experimental", + origin_trial_feature_name: "AnimationWorklet", + implied_by: ['AnimationWorklet'] + }, // Implements documentElement.scrollTop/Left and bodyElement.scrollTop/Left // as per the spec, matching other Web engines. {
diff --git a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc index 640b114a..0dd868c 100644 --- a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc +++ b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
@@ -58,13 +58,17 @@ void CooperativeSchedulingManager::SafepointSlow() { // Avoid nesting more than two levels. - if (running_nested_loop_) + if (running_nested_loop_ || base::RunLoop::IsNestedOnCurrentThread()) return; // TODO(keishi): Also bail if V8 EnteredContextCount is more than 1 - Thread::MainThread()->Scheduler()->SetHasSafepoint(); + // This task slice completes here. + Thread::MainThread()->Scheduler()->OnSafepointEntered(); RunNestedLoop(); + + // A new task slice starts here. + Thread::MainThread()->Scheduler()->OnSafepointExited(); } void CooperativeSchedulingManager::RunNestedLoop() {
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc index 212ddd0..ba0f96d 100644 --- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
@@ -65,13 +65,15 @@ void SetUp() override { // A null clock triggers some assertions. - test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(5)); + test_task_runner_->AdvanceMockTickClock( + base::TimeDelta::FromMilliseconds(5)); scheduler_.reset(new MainThreadSchedulerImplForTest( base::sequence_manager::SequenceManagerForTest::Create( nullptr, test_task_runner_, GetTickClock()), base::nullopt)); - scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(TimeDelta()); + scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( + base::TimeDelta()); task_queue_throttler_ = scheduler_->task_queue_throttler(); timer_queue_ = scheduler_->NewTimerTaskQueue( MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); @@ -88,11 +90,11 @@ timer_queue->task_runner()->PostTask( FROM_HERE, base::BindOnce(&RunTenTimesTask, &count, timer_queue)); - test_task_runner_->FastForwardBy(TimeDelta::FromSeconds(1)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); EXPECT_LE(count, 1u); // Make sure the rest of the tasks run or we risk a UAF on |count|. - test_task_runner_->FastForwardBy(TimeDelta::FromSeconds(10)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10)); EXPECT_EQ(10u, count); } @@ -101,7 +103,7 @@ timer_queue->task_runner()->PostTask( FROM_HERE, base::BindOnce(&RunTenTimesTask, &count, timer_queue)); - test_task_runner_->FastForwardBy(TimeDelta::FromSeconds(1)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(10u, count); test_task_runner_->FastForwardUntilNoTasksRemain(); } @@ -134,11 +136,11 @@ : task_runner_(task_runner) {} ~AutoAdvancingProxyClock() override = default; - void SetAutoAdvanceInterval(TimeDelta interval) { + void SetAutoAdvanceInterval(base::TimeDelta interval) { advance_interval_ = interval; } - TimeTicks NowTicks() const override { + base::TimeTicks NowTicks() const override { if (!advance_interval_.is_zero()) task_runner_->AdvanceMockTickClock(advance_interval_); return task_runner_->NowTicks(); @@ -146,7 +148,7 @@ private: scoped_refptr<TestMockTimeTaskRunner> task_runner_; - TimeDelta advance_interval_; + base::TimeDelta advance_interval_; }; class TaskQueueThrottlerWithAutoAdvancingTimeTest @@ -161,7 +163,8 @@ TaskQueueThrottlerTest::SetUp(); if (GetParam()) { // Will advance the time by this value after running each task. - proxy_clock_.SetAutoAdvanceInterval(TimeDelta::FromMicroseconds(10)); + proxy_clock_.SetAutoAdvanceInterval( + base::TimeDelta::FromMicroseconds(10)); } } @@ -186,7 +189,8 @@ EXPECT_EQ(timer_queue_->GetTimeDomain()->Now(), test_task_runner_->NowTicks()); - test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(250)); + test_task_runner_->AdvanceMockTickClock( + base::TimeDelta::FromMilliseconds(250)); // Make sure the throttled time domain's Now() reports the same as the // underlying clock. EXPECT_EQ(timer_queue_->GetTimeDomain()->Now(), @@ -194,128 +198,130 @@ } TEST_F(TaskQueueThrottlerTest, AlignedThrottledRunTime) { - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(1.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(0.0))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(0.0))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(1.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(0.1))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(0.1))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(1.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(0.2))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(0.2))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(1.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(0.5))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(0.5))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(1.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(0.8))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(0.8))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(1.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(0.9))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(0.9))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(2.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(2.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(1.0))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(2.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(2.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(1.1))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(1.1))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(9.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(9.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(8.0))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(8.0))); - EXPECT_EQ(TimeTicks() + TimeDelta::FromSecondsD(9.0), + EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(9.0), TaskQueueThrottler::AlignedThrottledRunTime( - TimeTicks() + TimeDelta::FromSecondsD(8.1))); + base::TimeTicks() + base::TimeDelta::FromSecondsD(8.1))); } namespace { // Round up time to milliseconds to deal with autoadvancing time. // TODO(altimin): round time only when autoadvancing time is enabled. -TimeDelta RoundTimeToMilliseconds(TimeDelta time) { - return time - time % TimeDelta::FromMilliseconds(1); +base::TimeDelta RoundTimeToMilliseconds(base::TimeDelta time) { + return time - time % base::TimeDelta::FromMilliseconds(1); } -TimeTicks RoundTimeToMilliseconds(TimeTicks time) { - return TimeTicks() + RoundTimeToMilliseconds(time - TimeTicks()); +base::TimeTicks RoundTimeToMilliseconds(base::TimeTicks time) { + return base::TimeTicks() + RoundTimeToMilliseconds(time - base::TimeTicks()); } -void TestTask(std::vector<TimeTicks>* run_times, +void TestTask(std::vector<base::TimeTicks>* run_times, scoped_refptr<TestMockTimeTaskRunner> task_runner) { run_times->push_back(RoundTimeToMilliseconds(task_runner->NowTicks())); // FIXME No auto-advancing } -void ExpensiveTestTask(std::vector<TimeTicks>* run_times, +void ExpensiveTestTask(std::vector<base::TimeTicks>* run_times, scoped_refptr<TestMockTimeTaskRunner> task_runner) { run_times->push_back(RoundTimeToMilliseconds(task_runner->NowTicks())); - task_runner->AdvanceMockTickClock(TimeDelta::FromMilliseconds(250)); + task_runner->AdvanceMockTickClock(base::TimeDelta::FromMilliseconds(250)); // FIXME No auto-advancing } -void RecordThrottling(std::vector<TimeDelta>* reported_throttling_times, - TimeDelta throttling_duration) { +void RecordThrottling(std::vector<base::TimeDelta>* reported_throttling_times, + base::TimeDelta throttling_duration) { reported_throttling_times->push_back( RoundTimeToMilliseconds(throttling_duration)); } } // namespace TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TimerAlignment) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200.0)); + base::TimeDelta::FromMilliseconds(200.0)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(800.0)); + base::TimeDelta::FromMilliseconds(800.0)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(1200.0)); + base::TimeDelta::FromMilliseconds(1200.0)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(8300.0)); + base::TimeDelta::FromMilliseconds(8300.0)); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); test_task_runner_->FastForwardUntilNoTasksRemain(); // Times are aligned to a multiple of 1000 milliseconds. - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000.0), - TimeTicks() + TimeDelta::FromMilliseconds(1000.0), - TimeTicks() + TimeDelta::FromMilliseconds(2000.0), - TimeTicks() + TimeDelta::FromMilliseconds(9000.0))); + EXPECT_THAT( + run_times, + ElementsAre( + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000.0), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000.0), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000.0), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(9000.0))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TimerAlignment_Unthrottled) { - std::vector<TimeTicks> run_times; - TimeTicks start_time = test_task_runner_->NowTicks(); + std::vector<base::TimeTicks> run_times; + base::TimeTicks start_time = test_task_runner_->NowTicks(); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200.0)); + base::TimeDelta::FromMilliseconds(200.0)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(800.0)); + base::TimeDelta::FromMilliseconds(800.0)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(1200.0)); + base::TimeDelta::FromMilliseconds(1200.0)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(8300.0)); + base::TimeDelta::FromMilliseconds(8300.0)); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); @@ -325,14 +331,14 @@ // Times are not aligned. EXPECT_THAT( run_times, - ElementsAre(RoundTimeToMilliseconds(start_time + - TimeDelta::FromMilliseconds(200.0)), - RoundTimeToMilliseconds(start_time + - TimeDelta::FromMilliseconds(800.0)), - RoundTimeToMilliseconds(start_time + - TimeDelta::FromMilliseconds(1200.0)), + ElementsAre(RoundTimeToMilliseconds( + start_time + base::TimeDelta::FromMilliseconds(200.0)), RoundTimeToMilliseconds( - start_time + TimeDelta::FromMilliseconds(8300.0)))); + start_time + base::TimeDelta::FromMilliseconds(800.0)), + RoundTimeToMilliseconds( + start_time + base::TimeDelta::FromMilliseconds(1200.0)), + RoundTimeToMilliseconds( + start_time + base::TimeDelta::FromMilliseconds(8300.0)))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, Refcount) { @@ -368,7 +374,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, OnTimeDomainHasImmediateWork_EnabledQueue) { task_queue_throttler_->OnQueueNextWakeUpChanged(timer_queue_.get(), - TimeTicks()); + base::TimeTicks()); // Check PostPumpThrottledTasksLocked was called. EXPECT_FALSE(scheduler_->ControlTaskQueue()->IsEmpty()); } @@ -380,7 +386,7 @@ voter->SetVoteToEnable(false); task_queue_throttler_->OnQueueNextWakeUpChanged(timer_queue_.get(), - TimeTicks()); + base::TimeTicks()); // Check PostPumpThrottledTasksLocked was not called. EXPECT_TRUE(scheduler_->ControlTaskQueue()->IsEmpty()); } @@ -404,7 +410,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, ThrottlingADisabledQueueDoesNotPostPumpThrottledTasks_DelayedTask) { timer_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - TimeDelta::FromMilliseconds(1)); + base::TimeDelta::FromMilliseconds(1)); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = timer_queue_->CreateQueueEnabledVoter(); @@ -419,7 +425,7 @@ } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, WakeUpForNonDelayedTask) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; // Nothing is posted on timer_queue_ so PumpThrottledTasks will not tick. task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -430,11 +436,12 @@ test_task_runner_->FastForwardUntilNoTasksRemain(); EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000.0))); + ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(1000.0))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, WakeUpForDelayedTask) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; // Nothing is posted on timer_queue_ so PumpThrottledTasks will not tick. task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -442,18 +449,19 @@ // Posting a task should trigger the pump. timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(1200.0)); + base::TimeDelta::FromMilliseconds(1200.0)); test_task_runner_->FastForwardUntilNoTasksRemain(); EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(2000.0))); + ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(2000.0))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, SingleThrottledTaskPumpedAndRunWithNoExtraneousMessageLoopTasks) { task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - TimeDelta delay(TimeDelta::FromMilliseconds(10)); + base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); timer_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay); EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); @@ -463,7 +471,7 @@ SingleFutureThrottledTaskPumpedAndRunWithNoExtraneousMessageLoopTasks) { task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - TimeDelta delay(TimeDelta::FromSecondsD(15.5)); + base::TimeDelta delay(base::TimeDelta::FromSecondsD(15.5)); timer_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay); EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); @@ -472,14 +480,14 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TwoFutureThrottledTaskPumpedAndRunWithNoExtraneousMessageLoopTasks) { task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; - TimeDelta delay(TimeDelta::FromSecondsD(15.5)); + base::TimeDelta delay(base::TimeDelta::FromSecondsD(15.5)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), delay); - TimeDelta delay2(TimeDelta::FromSecondsD(5.5)); + base::TimeDelta delay2(base::TimeDelta::FromSecondsD(5.5)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), delay2); @@ -490,37 +498,42 @@ test_task_runner_->FastForwardBy(test_task_runner_->NextPendingTaskDelay()); EXPECT_EQ(0u, test_task_runner_->GetPendingTaskCount()); - EXPECT_THAT(run_times, ElementsAre(TimeTicks() + TimeDelta::FromSeconds(6), - TimeTicks() + TimeDelta::FromSeconds(16))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(6), + base::TimeTicks() + base::TimeDelta::FromSeconds(16))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TaskDelayIsBasedOnRealTime) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); // Post an initial task that should run at the first aligned time period. timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(900.0)); + base::TimeDelta::FromMilliseconds(900.0)); test_task_runner_->FastForwardUntilNoTasksRemain(); // Advance realtime. - test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(250)); + test_task_runner_->AdvanceMockTickClock( + base::TimeDelta::FromMilliseconds(250)); // Post a task that due to real time + delay must run in the third aligned // time period. timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(900.0)); + base::TimeDelta::FromMilliseconds(900.0)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000.0), - TimeTicks() + TimeDelta::FromMilliseconds(3000.0))); + EXPECT_THAT( + run_times, + ElementsAre( + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000.0), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000.0))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TaskQueueDisabledTillPump) { @@ -577,13 +590,13 @@ } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TimeBasedThrottling) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -592,16 +605,17 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, ElementsAre(TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(3))); + EXPECT_THAT(run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(3))); pool->RemoveQueue(test_task_runner_->NowTicks(), timer_queue_.get()); run_times.clear(); @@ -611,17 +625,18 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(4000), - TimeTicks() + TimeDelta::FromMilliseconds(4250))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(4000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(4250))); task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); pool->Close(); @@ -629,14 +644,14 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, EnableAndDisableCPUTimeBudgetPool) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); EXPECT_TRUE(pool->IsThrottlingEnabled()); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -644,12 +659,12 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(1000))); run_times.clear(); LazyNow lazy_now_1(test_task_runner_->GetMockTickClock()); @@ -660,12 +675,12 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(2000))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(2000))); run_times.clear(); LazyNow lazy_now_2(test_task_runner_->GetMockTickClock()); @@ -677,12 +692,12 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(4000))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(4000))); run_times.clear(); task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); @@ -693,13 +708,13 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, ImmediateTasksTimeBudgetThrottling) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -714,8 +729,9 @@ test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, ElementsAre(TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(3))); + EXPECT_THAT(run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(3))); pool->RemoveQueue(test_task_runner_->NowTicks(), timer_queue_.get()); run_times.clear(); @@ -731,9 +747,10 @@ test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(4000), - TimeTicks() + TimeDelta::FromMilliseconds(4250))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(4000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(4250))); task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); pool->Close(); @@ -741,7 +758,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TwoQueuesTimeBudgetThrottling) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; scoped_refptr<TaskQueue> second_queue = scheduler_->NewTimerTaskQueue( MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); @@ -749,9 +766,9 @@ CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); - pool->AddQueue(TimeTicks(), second_queue.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); + pool->AddQueue(base::TimeTicks(), second_queue.get()); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(second_queue.get()); @@ -765,8 +782,9 @@ test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, ElementsAre(TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(3))); + EXPECT_THAT(run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(3))); task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); task_queue_throttler_->DecreaseThrottleRefCount(second_queue.get()); @@ -779,7 +797,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, DisabledTimeBudgetDoesNotAffectThrottledQueues) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; LazyNow lazy_now(test_task_runner_->GetMockTickClock()); CPUTimeBudgetPool* pool = @@ -794,26 +812,27 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(100)); + base::TimeDelta::FromMilliseconds(100)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(100)); + base::TimeDelta::FromMilliseconds(100)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(1250))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1250))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TimeBudgetThrottlingDoesNotAffectUnthrottledQueues) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); LazyNow lazy_now(test_task_runner_->GetMockTickClock()); pool->DisableThrottling(&lazy_now); @@ -823,29 +842,31 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(100)); + base::TimeDelta::FromMilliseconds(100)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(100)); + base::TimeDelta::FromMilliseconds(100)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(105), - TimeTicks() + TimeDelta::FromMilliseconds(355))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(105), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(355))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, MaxThrottlingDelay) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetMaxThrottlingDelay(TimeTicks(), TimeDelta::FromMinutes(1)); + pool->SetMaxThrottlingDelay(base::TimeTicks(), + base::TimeDelta::FromMinutes(1)); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.001); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.001); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -853,44 +874,45 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); } test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(62), - TimeTicks() + TimeDelta::FromSeconds(123), - TimeTicks() + TimeDelta::FromSeconds(184), - TimeTicks() + TimeDelta::FromSeconds(245))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(62), + base::TimeTicks() + base::TimeDelta::FromSeconds(123), + base::TimeTicks() + base::TimeDelta::FromSeconds(184), + base::TimeTicks() + base::TimeDelta::FromSeconds(245))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, EnableAndDisableThrottling) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(295)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(295)); // Disable throttling - task should run immediately. task_queue_throttler_->DisableThrottling(); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(200)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(200)); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(300))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(300))); run_times.clear(); // Schedule a task at 900ms. It should proceed as normal. timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(400)); + base::TimeDelta::FromMilliseconds(400)); // Schedule a task at 1200ms. It should proceed as normal. // PumpThrottledTasks was scheduled at 1000ms, so it needs to be checked @@ -898,41 +920,42 @@ // 1s mark and scheduled to run after 1s mark. timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(700)); + base::TimeDelta::FromMilliseconds(700)); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(800)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(800)); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(900), - TimeTicks() + TimeDelta::FromMilliseconds(1200))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(900), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1200))); run_times.clear(); // Schedule a task at 1500ms. It should be throttled because of enabled // throttling. timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(100)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(100)); // Throttling is enabled and new task should be aligned. task_queue_throttler_->EnableThrottling(); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(2000))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(2000))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, ReportThrottling) { - std::vector<TimeTicks> run_times; - std::vector<TimeDelta> reported_throttling_times; + std::vector<base::TimeTicks> run_times; + std::vector<base::TimeDelta> reported_throttling_times; CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); pool->SetReportingCallback( base::BindRepeating(&RecordThrottling, &reported_throttling_times)); @@ -941,25 +964,26 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, ElementsAre(TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(3))); + EXPECT_THAT(run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(3))); EXPECT_THAT(reported_throttling_times, - ElementsAre(TimeDelta::FromMilliseconds(1255), - TimeDelta::FromMilliseconds(1755))); + ElementsAre(base::TimeDelta::FromMilliseconds(1255), + base::TimeDelta::FromMilliseconds(1755))); pool->RemoveQueue(test_task_runner_->NowTicks(), timer_queue_.get()); task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); @@ -967,14 +991,15 @@ } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, GrantAdditionalBudget) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); - pool->GrantAdditionalBudget(TimeTicks(), TimeDelta::FromMilliseconds(500)); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); + pool->GrantAdditionalBudget(base::TimeTicks(), + base::TimeDelta::FromMilliseconds(500)); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -984,17 +1009,18 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); } test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(1250), - TimeTicks() + TimeDelta::FromMilliseconds(1500), - TimeTicks() + TimeDelta::FromSeconds(3), - TimeTicks() + TimeDelta::FromSeconds(6))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1250), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1500), + base::TimeTicks() + base::TimeDelta::FromSeconds(3), + base::TimeTicks() + base::TimeDelta::FromSeconds(6))); pool->RemoveQueue(test_task_runner_->NowTicks(), timer_queue_.get()); task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); @@ -1005,7 +1031,7 @@ EnableAndDisableThrottlingAndTimeBudgets) { // This test checks that if time budget pool is enabled when throttling // is disabled, it does not throttle the queue. - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; task_queue_throttler_->DisableThrottling(); @@ -1016,28 +1042,28 @@ LazyNow lazy_now_1(test_task_runner_->GetMockTickClock()); pool->DisableThrottling(&lazy_now_1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(95)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(95)); LazyNow lazy_now_2(test_task_runner_->GetMockTickClock()); pool->EnableThrottling(&lazy_now_2); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(300))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(300))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, AddQueueToBudgetPoolWhenThrottlingDisabled) { // This test checks that a task queue is added to time budget pool // when throttling is disabled, is does not throttle queue. - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; task_queue_throttler_->DisableThrottling(); @@ -1045,23 +1071,23 @@ task_queue_throttler_->CreateCPUTimeBudgetPool("test"); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(95)); + test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(95)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(300))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(300))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, DisabledQueueThenEnabledQueue) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; scoped_refptr<MainThreadTaskQueue> second_queue = scheduler_->NewTimerTaskQueue( @@ -1072,46 +1098,48 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(100)); + base::TimeDelta::FromMilliseconds(100)); second_queue->task_runner()->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = timer_queue_->CreateQueueEnabledVoter(); voter->SetVoteToEnable(false); - test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(250)); + test_task_runner_->AdvanceMockTickClock( + base::TimeDelta::FromMilliseconds(250)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000))); + EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(1000))); voter->SetVoteToEnable(true); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(2000))); + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TwoBudgetPools) { - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; scoped_refptr<TaskQueue> second_queue = scheduler_->NewTimerTaskQueue( MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); CPUTimeBudgetPool* pool1 = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool1->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool1->AddQueue(TimeTicks(), timer_queue_.get()); - pool1->AddQueue(TimeTicks(), second_queue.get()); + pool1->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool1->AddQueue(base::TimeTicks(), timer_queue_.get()); + pool1->AddQueue(base::TimeTicks(), second_queue.get()); CPUTimeBudgetPool* pool2 = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool2->SetTimeBudgetRecoveryRate(TimeTicks(), 0.01); - pool2->AddQueue(TimeTicks(), timer_queue_.get()); + pool2->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.01); + pool2->AddQueue(base::TimeTicks(), timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(second_queue.get()); @@ -1131,20 +1159,22 @@ test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(3000), - TimeTicks() + TimeDelta::FromMilliseconds(6000), - TimeTicks() + TimeDelta::FromMilliseconds(26000))); + EXPECT_THAT( + run_times, + ElementsAre( + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(6000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(26000))); } namespace { -void RunChainedTask(std::deque<TimeDelta> task_durations, +void RunChainedTask(std::deque<base::TimeDelta> task_durations, scoped_refptr<TaskQueue> queue, scoped_refptr<TestMockTimeTaskRunner> task_runner, - std::vector<TimeTicks>* run_times, - TimeDelta delay) { + std::vector<base::TimeTicks>* run_times, + base::TimeDelta delay) { if (task_durations.empty()) return; @@ -1165,103 +1195,38 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, WakeUpBasedThrottling_ChainedTasks_Instantaneous) { scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( - TimeDelta::FromMilliseconds(10)); - std::vector<TimeTicks> run_times; + base::TimeDelta::FromMilliseconds(10)); + std::vector<base::TimeTicks> run_times; task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); timer_task_runner_->PostDelayedTask( FROM_HERE, - base::BindOnce(&RunChainedTask, std::deque<TimeDelta>(10, TimeDelta()), - timer_queue_, test_task_runner_, &run_times, TimeDelta()), - TimeDelta::FromMilliseconds(100)); + base::BindOnce( + &RunChainedTask, std::deque<base::TimeDelta>(10, base::TimeDelta()), + timer_queue_, test_task_runner_, &run_times, base::TimeDelta()), + base::TimeDelta::FromMilliseconds(100)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, ElementsAre(TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1), - TimeTicks() + TimeDelta::FromSeconds(1))); + EXPECT_THAT(run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(1))); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, WakeUpBasedThrottling_ImmediateTasks_Fast) { scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( - TimeDelta::FromMilliseconds(10)); - std::vector<TimeTicks> run_times; - - task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - - timer_task_runner_->PostDelayedTask( - FROM_HERE, - base::BindOnce(&RunChainedTask, - std::deque<TimeDelta>(10, TimeDelta::FromMilliseconds(3)), - timer_queue_, test_task_runner_, &run_times, TimeDelta()), - TimeDelta::FromMilliseconds(100)); - - test_task_runner_->FastForwardUntilNoTasksRemain(); - - // TODO(altimin): Add fence mechanism to block immediate tasks. - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(1003), - TimeTicks() + TimeDelta::FromMilliseconds(1006), - TimeTicks() + TimeDelta::FromMilliseconds(1009), - TimeTicks() + TimeDelta::FromMilliseconds(2000), - TimeTicks() + TimeDelta::FromMilliseconds(2003), - TimeTicks() + TimeDelta::FromMilliseconds(2006), - TimeTicks() + TimeDelta::FromMilliseconds(2009), - TimeTicks() + TimeDelta::FromMilliseconds(3000), - TimeTicks() + TimeDelta::FromMilliseconds(3003))); -} - -TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, - WakeUpBasedThrottling_DelayedTasks) { - scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( - TimeDelta::FromMilliseconds(10)); - std::vector<TimeTicks> run_times; - - task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - - timer_task_runner_->PostDelayedTask( - FROM_HERE, - base::BindOnce(&RunChainedTask, std::deque<TimeDelta>(10, TimeDelta()), - timer_queue_, test_task_runner_, &run_times, - TimeDelta::FromMilliseconds(3)), - TimeDelta::FromMilliseconds(100)); - - test_task_runner_->FastForwardUntilNoTasksRemain(); - - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(1003), - TimeTicks() + TimeDelta::FromMilliseconds(1006), - TimeTicks() + TimeDelta::FromMilliseconds(1009), - TimeTicks() + TimeDelta::FromMilliseconds(2000), - TimeTicks() + TimeDelta::FromMilliseconds(2003), - TimeTicks() + TimeDelta::FromMilliseconds(2006), - TimeTicks() + TimeDelta::FromMilliseconds(2009), - TimeTicks() + TimeDelta::FromMilliseconds(3000), - TimeTicks() + TimeDelta::FromMilliseconds(3003))); -} - -TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottlingWithCPUBudgetThrottling) { - scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( - TimeDelta::FromMilliseconds(10)); - - CPUTimeBudgetPool* pool = - task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); - - std::vector<TimeTicks> run_times; + base::TimeDelta::FromMilliseconds(10)); + std::vector<base::TimeTicks> run_times; task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); @@ -1269,39 +1234,113 @@ FROM_HERE, base::BindOnce( &RunChainedTask, - std::deque<TimeDelta>{ - TimeDelta::FromMilliseconds(250), TimeDelta(), TimeDelta(), - TimeDelta::FromMilliseconds(250), TimeDelta(), TimeDelta(), - TimeDelta::FromMilliseconds(250), TimeDelta(), TimeDelta()}, - timer_queue_, test_task_runner_, &run_times, TimeDelta()), - TimeDelta::FromMilliseconds(100)); + std::deque<base::TimeDelta>(10, base::TimeDelta::FromMilliseconds(3)), + timer_queue_, test_task_runner_, &run_times, base::TimeDelta()), + base::TimeDelta::FromMilliseconds(100)); test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT(run_times, - ElementsAre(TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(3000), - TimeTicks() + TimeDelta::FromMilliseconds(3000), - TimeTicks() + TimeDelta::FromMilliseconds(3000), - TimeTicks() + TimeDelta::FromMilliseconds(6000), - TimeTicks() + TimeDelta::FromMilliseconds(6000), - TimeTicks() + TimeDelta::FromMilliseconds(6000), - TimeTicks() + TimeDelta::FromMilliseconds(8000), - TimeTicks() + TimeDelta::FromMilliseconds(8000))); + // TODO(altimin): Add fence mechanism to block immediate tasks. + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1003), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1006), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1009), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2003), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2006), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2009), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3003))); +} + +TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, + WakeUpBasedThrottling_DelayedTasks) { + scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( + base::TimeDelta::FromMilliseconds(10)); + std::vector<base::TimeTicks> run_times; + + task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); + + timer_task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&RunChainedTask, + std::deque<base::TimeDelta>(10, base::TimeDelta()), + timer_queue_, test_task_runner_, &run_times, + base::TimeDelta::FromMilliseconds(3)), + base::TimeDelta::FromMilliseconds(100)); + + test_task_runner_->FastForwardUntilNoTasksRemain(); + + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1003), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1006), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1009), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2003), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2006), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2009), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3003))); +} + +TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottlingWithCPUBudgetThrottling) { + scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( + base::TimeDelta::FromMilliseconds(10)); + + CPUTimeBudgetPool* pool = + task_queue_throttler_->CreateCPUTimeBudgetPool("test"); + + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); + + std::vector<base::TimeTicks> run_times; + + task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); + + timer_task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce( + &RunChainedTask, + std::deque<base::TimeDelta>{base::TimeDelta::FromMilliseconds(250), + base::TimeDelta(), base::TimeDelta(), + base::TimeDelta::FromMilliseconds(250), + base::TimeDelta(), base::TimeDelta(), + base::TimeDelta::FromMilliseconds(250), + base::TimeDelta(), base::TimeDelta()}, + timer_queue_, test_task_runner_, &run_times, base::TimeDelta()), + base::TimeDelta::FromMilliseconds(100)); + + test_task_runner_->FastForwardUntilNoTasksRemain(); + + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(6000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(6000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(6000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(8000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(8000))); } TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottlingWithCPUBudgetThrottling_OnAndOff) { scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( - TimeDelta::FromMilliseconds(10)); + base::TimeDelta::FromMilliseconds(10)); CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.1); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; bool is_throttled = false; @@ -1309,10 +1348,10 @@ timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(200)); + base::TimeDelta::FromMilliseconds(200)); timer_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_), - TimeDelta::FromMilliseconds(300)); + base::TimeDelta::FromMilliseconds(300)); if (is_throttled) { task_queue_throttler_->DecreaseThrottleRefCount(timer_queue_.get()); @@ -1328,20 +1367,20 @@ EXPECT_THAT(run_times, ElementsAre( // Throttled due to cpu budget. - TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), // Unthrottled. - TimeTicks() + TimeDelta::FromMilliseconds(3200), - TimeTicks() + TimeDelta::FromMilliseconds(3450), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3200), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3450), // Throttled due to wake-up budget. Old tasks still run. - TimeTicks() + TimeDelta::FromMilliseconds(5000), - TimeTicks() + TimeDelta::FromMilliseconds(5250), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(5000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(5250), // Unthrottled. - TimeTicks() + TimeDelta::FromMilliseconds(6200), - TimeTicks() + TimeDelta::FromMilliseconds(6450), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(6200), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(6450), // Throttled due to wake-up budget. Old tasks still run. - TimeTicks() + TimeDelta::FromMilliseconds(8000), - TimeTicks() + TimeDelta::FromMilliseconds(8250))); + base::TimeTicks() + base::TimeDelta::FromMilliseconds(8000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(8250))); } TEST_F(TaskQueueThrottlerTest, @@ -1350,45 +1389,46 @@ // when time budget allows that and should be blocked when time budget is // exhausted. scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( - TimeDelta::FromMilliseconds(10)); + base::TimeDelta::FromMilliseconds(10)); CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); - pool->SetTimeBudgetRecoveryRate(TimeTicks(), 0.01); - pool->AddQueue(TimeTicks(), timer_queue_.get()); + pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.01); + pool->AddQueue(base::TimeTicks(), timer_queue_.get()); - std::vector<TimeTicks> run_times; + std::vector<base::TimeTicks> run_times; task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); timer_task_runner_->PostDelayedTask( FROM_HERE, - base::BindOnce(&RunChainedTask, - std::deque<TimeDelta>(10, TimeDelta::FromMilliseconds(7)), - timer_queue_, test_task_runner_, &run_times, TimeDelta()), - TimeDelta::FromMilliseconds(100)); + base::BindOnce( + &RunChainedTask, + std::deque<base::TimeDelta>(10, base::TimeDelta::FromMilliseconds(7)), + timer_queue_, test_task_runner_, &run_times, base::TimeDelta()), + base::TimeDelta::FromMilliseconds(100)); test_task_runner_->FastForwardUntilNoTasksRemain(); EXPECT_THAT(run_times, ElementsAre( // Time budget is ~10ms and we can run two 7ms tasks. - TimeTicks() + TimeDelta::FromMilliseconds(1000), - TimeTicks() + TimeDelta::FromMilliseconds(1007), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1007), // Time budget is ~6ms and we can run one 7ms task. - TimeTicks() + TimeDelta::FromMilliseconds(2000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000), // Time budget is ~8ms and we can run two 7ms tasks. - TimeTicks() + TimeDelta::FromMilliseconds(3000), - TimeTicks() + TimeDelta::FromMilliseconds(3007), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(3007), // Time budget is ~5ms and we can run one 7ms task. - TimeTicks() + TimeDelta::FromMilliseconds(4000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(4000), // Time budget is ~8ms and we can run two 7ms tasks. - TimeTicks() + TimeDelta::FromMilliseconds(5000), - TimeTicks() + TimeDelta::FromMilliseconds(5007), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(5000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(5007), // Time budget is ~4ms and we can run one 7ms task. - TimeTicks() + TimeDelta::FromMilliseconds(6000), - TimeTicks() + TimeDelta::FromMilliseconds(7000))); + base::TimeTicks() + base::TimeDelta::FromMilliseconds(6000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(7000))); } } // namespace task_queue_throttler_unittest
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc index 4b0b0890..c1cf00cc 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc
@@ -71,7 +71,9 @@ best_effort_task_queue_ = main_thread_scheduler_impl_->NewTaskQueue( MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kIdle) + .SetFrameScheduler(frame_scheduler_impl_) .SetFixedPriority(TaskQueue::QueuePriority::kBestEffortPriority)); + TaskQueueCreated(best_effort_task_queue_); } return best_effort_task_queue_; }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc index ac9947c..8fa2449 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
@@ -156,6 +156,18 @@ all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue); EXPECT_EQ(all_task_queues.size(), task_queue_created_count()); + // Add inspector task queue. + task_queue = frame_task_queue_controller_->InspectorTaskQueue(); + EXPECT_FALSE(all_task_queues.Contains(task_queue)); + all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue); + EXPECT_EQ(all_task_queues.size(), task_queue_created_count()); + + // Add best effort task queue. + task_queue = frame_task_queue_controller_->BestEffortTaskQueue(); + EXPECT_FALSE(all_task_queues.Contains(task_queue)); + all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue); + EXPECT_EQ(all_task_queues.size(), task_queue_created_count()); + // Verify that we get all of the queues that we added, and only those queues. EXPECT_EQ(all_task_queues.size(), frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc index 5568d16..eed841a 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
@@ -139,7 +139,9 @@ total_task_time_reporter_( "Scheduler.Experimental.Renderer.TotalTime.Wall.MainThread.Positive", "Scheduler.Experimental.Renderer.TotalTime.Wall.MainThread.Negative"), - main_thread_task_load_state_(MainThreadTaskLoadState::kUnknown) { + main_thread_task_load_state_(MainThreadTaskLoadState::kUnknown), + current_task_slice_start_time_(now), + safepoints_in_current_toplevel_task_count_(0) { main_thread_load_tracker_.Resume(now); if (renderer_backgrounded) { background_main_thread_load_tracker_.Resume(now); @@ -204,6 +206,37 @@ } // namespace +void MainThreadMetricsHelper::OnSafepointEntered(base::TimeTicks now) { + current_task_slice_start_time_ = now; +} + +void MainThreadMetricsHelper::OnSafepointExited(base::TimeTicks now) { + safepoints_in_current_toplevel_task_count_++; + RecordTaskSliceMetrics(now); +} + +void MainThreadMetricsHelper::RecordTaskSliceMetrics(base::TimeTicks now) { + UMA_HISTOGRAM_TIMES("RendererScheduler.TasksWithSafepoints.TaskSliceTime", + now - current_task_slice_start_time_); +} + +void MainThreadMetricsHelper::RecordMetricsForTasksWithSafepoints( + const base::sequence_manager::TaskQueue::TaskTiming& task_timing) { + if (safepoints_in_current_toplevel_task_count_ == 0) + return; + + RecordTaskSliceMetrics(task_timing.end_time()); + + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "RendererScheduler.TasksWithSafepoints.TaskTime", + task_timing.wall_duration(), base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromSeconds(1), 50); + UMA_HISTOGRAM_COUNTS_100( + "RendererScheduler.TasksWithSafepoints.SafepointCount", + safepoints_in_current_toplevel_task_count_); + safepoints_in_current_toplevel_task_count_ = 0; +} + void MainThreadMetricsHelper::RecordTaskMetrics( MainThreadTaskQueue* queue, const base::sequence_manager::Task& task, @@ -476,7 +509,7 @@ frame_status, FrameStatus::kCount); } - if (main_thread_scheduler_->main_thread_only().has_safepoint) { + if (safepoints_in_current_toplevel_task_count_ > 0) { UMA_HISTOGRAM_ENUMERATION(COUNT_PER_FRAME_METRIC_NAME_WITH_SAFEPOINT, frame_status, FrameStatus::kCount); if (duration >= base::TimeDelta::FromMilliseconds(16)) { @@ -508,6 +541,7 @@ ".LongerThan1s", frame_status, FrameStatus::kCount); } + RecordMetricsForTasksWithSafepoints(task_timing); } UseCase use_case =
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h index 0ceadb8..a3c75d5 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
@@ -49,11 +49,15 @@ MainThreadTaskQueue* queue, const base::sequence_manager::Task& task, const base::sequence_manager::TaskQueue::TaskTiming& task_timing); + void RecordTaskSliceMetrics(base::TimeTicks now); void OnRendererForegrounded(base::TimeTicks now); void OnRendererBackgrounded(base::TimeTicks now); void OnRendererShutdown(base::TimeTicks now); + void OnSafepointEntered(base::TimeTicks now); + void OnSafepointExited(base::TimeTicks now); + void RecordMainThreadTaskLoad(base::TimeTicks time, double load); void RecordForegroundMainThreadTaskLoad(base::TimeTicks time, double load); void RecordBackgroundMainThreadTaskLoad(base::TimeTicks time, double load); @@ -67,6 +71,10 @@ void ReportLowThreadLoadForPageAlmostIdleSignal(int load_percentage); + // Record metrics of only top-level tasks with safepoints. + void RecordMetricsForTasksWithSafepoints( + const base::sequence_manager::TaskQueue::TaskTiming& task_timing); + MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED // Set to true when OnRendererShutdown is called. Used to ensure that metrics @@ -143,6 +151,13 @@ MainThreadTaskLoadState main_thread_task_load_state_; + base::TimeTicks current_task_slice_start_time_; + + // Number of safepoints during inside the current top-level tasks in which + // cooperative scheduling had a chance to run a task (as we don't necessarily + // run a task in each safepoint). + int safepoints_in_current_toplevel_task_count_; + DISALLOW_COPY_AND_ASSIGN(MainThreadMetricsHelper); };
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc index b42bf282..93b8eb2 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc
@@ -546,5 +546,8 @@ // TODO(crbug.com/754656): Add tests for non-TaskDuration // histograms. +// TODO(crbug.com/754656): Add tests for +// RendererScheduler.TasksWithSafepoints histograms. + } // namespace scheduler } // namespace blink
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 e3d54ba..bc5cd1ac 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
@@ -473,8 +473,7 @@ virtual_time_stopped(false), nested_runloop(false), compositing_experiment(main_thread_scheduler_impl), - should_prioritize_compositing(false), - has_safepoint(false) {} + should_prioritize_compositing(false) {} MainThreadSchedulerImpl::MainThreadOnly::~MainThreadOnly() = default; @@ -2394,7 +2393,6 @@ if (main_thread_only().nested_runloop) return; - main_thread_only().has_safepoint = false; main_thread_only().current_task_start_time = task_timing.start_time(); main_thread_only().task_description_for_tracing = TaskDescriptionForTracing{ static_cast<TaskType>(task.task_type), @@ -2441,8 +2439,6 @@ // TODO(altimin): Per-page metrics should also be considered. main_thread_only().metrics_helper.RecordTaskMetrics(queue.get(), task, *task_timing); - main_thread_only().has_safepoint = false; - main_thread_only().task_description_for_tracing = base::nullopt; // Unset the state of |task_priority_for_tracing|. @@ -2713,9 +2709,16 @@ UpdatePolicy(); } -void MainThreadSchedulerImpl::SetHasSafepoint() { +void MainThreadSchedulerImpl::OnSafepointEntered() { DCHECK(WTF::IsMainThread()); - main_thread_only().has_safepoint = true; + DCHECK(!main_thread_only().nested_runloop); + main_thread_only().metrics_helper.OnSafepointEntered(helper_.NowTicks()); +} + +void MainThreadSchedulerImpl::OnSafepointExited() { + DCHECK(WTF::IsMainThread()); + DCHECK(!main_thread_only().nested_runloop); + main_thread_only().metrics_helper.OnSafepointExited(helper_.NowTicks()); } void MainThreadSchedulerImpl::ExecuteAfterCurrentTask(
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 f879bd2..3f41d5f 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
@@ -297,7 +297,7 @@ base::TimeTicks EnableVirtualTime(); // Tells the scheduler that all TaskQueues should use virtual time. Returns - // the TimeTicks that virtual time offsets will be relative to. + // the base::TimeTicks that virtual time offsets will be relative to. base::TimeTicks EnableVirtualTime(BaseTimeOverridePolicy policy); bool IsVirtualTimeEnabled() const; @@ -589,7 +589,8 @@ void OnIdlePeriodStarted() override; void OnIdlePeriodEnded() override; void OnPendingTasksChanged(bool has_tasks) override; - void SetHasSafepoint() override; + void OnSafepointEntered() override; + void OnSafepointExited() override; void DispatchRequestBeginMainFrameNotExpected(bool has_tasks); @@ -890,9 +891,6 @@ PrioritizeCompositingAfterInputExperiment compositing_experiment; bool should_prioritize_compositing; - // True if a task has a safepoint. - bool has_safepoint; - // List of callbacks to execute after the current task. WTF::Vector<base::OnceClosure> on_task_completion_callbacks; };
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc index e065b5c1f..5a337d3 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc
@@ -37,8 +37,9 @@ &MemoryPurgeManagerTest::OnMemoryPressure, base::Unretained(this))); base::MemoryPressureListener::SetNotificationsSuppressed(false); - // Set an initial delay to ensure that the first call to TimeTicks::Now() - // before incrementing the counter does not return a null value. + // Set an initial delay to ensure that the first call to + // base::TimeTicks::Now() before incrementing the counter does not return a + // null value. FastForwardBy(base::TimeDelta::FromSeconds(1)); }
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 fd1d531..885bbe8e 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
@@ -634,8 +634,8 @@ // If delay_for_background_and_network_idle_tab_freezing_ passes after // the page is not visible, we should freeze the page. - TimeDelta passed = main_thread_scheduler_->GetTickClock()->NowTicks() - - page_visibility_changed_time_; + base::TimeDelta passed = main_thread_scheduler_->GetTickClock()->NowTicks() - + page_visibility_changed_time_; if (passed < delay_for_background_and_network_idle_tab_freezing_) return; @@ -647,8 +647,9 @@ if (freeze_on_network_idle_enabled_) { DCHECK(delegate_); - TimeDelta passed = main_thread_scheduler_->GetTickClock()->NowTicks() - - page_visibility_changed_time_; + base::TimeDelta passed = + main_thread_scheduler_->GetTickClock()->NowTicks() - + page_visibility_changed_time_; // The page will be frozen if: // (1) the main frame is remote, or, // (2) the local main frame's network is almost idle, or,
diff --git a/third_party/blink/renderer/platform/scheduler/public/aggregated_metric_reporter.h b/third_party/blink/renderer/platform/scheduler/public/aggregated_metric_reporter.h index 222d3e7..ff9335f 100644 --- a/third_party/blink/renderer/platform/scheduler/public/aggregated_metric_reporter.h +++ b/third_party/blink/renderer/platform/scheduler/public/aggregated_metric_reporter.h
@@ -37,7 +37,7 @@ // to histogram and modifies the passed value. // Example: aggregate(time) { // return time.InMilliseconds(); - // time %= TimeDelta::FromMilliseconds(1); + // time %= base::TimeDelta::FromMilliseconds(1); // } using AggregatorFuncPtr = int (*)(ValueType&);
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 03a096e..43e6e76 100644 --- a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -62,8 +62,8 @@ // Instructs this PageScheduler to use virtual time. When virtual time is // enabled the system doesn't actually sleep for the delays between tasks - // before executing them. Returns the TimeTicks that virtual time offsets will - // be relative to. + // before executing them. Returns the base::TimeTicks that virtual time + // offsets will be relative to. // // E.g: A-E are delayed tasks //
diff --git a/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h index bf2deca..4c55334 100644 --- a/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h
@@ -133,7 +133,8 @@ // Associates |isolate| to the scheduler. virtual void SetV8Isolate(v8::Isolate* isolate) = 0; - virtual void SetHasSafepoint() {} + virtual void OnSafepointEntered() {} + virtual void OnSafepointExited() {} // Test helpers.
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.cc b/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.cc index 783b01ab8..c412e1f 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.cc +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.cc
@@ -19,7 +19,7 @@ SequenceManagerFuzzerProcessor::SequenceManagerFuzzerProcessor( bool log_for_testing) : log_for_testing_(log_for_testing), - initial_time_(TimeTicks() + TimeDelta::FromMilliseconds(1)), + initial_time_(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)), thread_pool_manager_(std::make_unique<ThreadPoolManager>(this)), main_thread_manager_( std::make_unique<ThreadManager>(initial_time_, this)) {} @@ -52,8 +52,8 @@ void SequenceManagerFuzzerProcessor::LogTaskForTesting( std::vector<TaskForTest>* ordered_tasks, uint64_t task_id, - TimeTicks start_time, - TimeTicks end_time) { + base::TimeTicks start_time, + base::TimeTicks end_time) { if (!log_for_testing_) return; @@ -67,7 +67,7 @@ std::vector<ActionForTest>* ordered_actions, uint64_t action_id, ActionForTest::ActionType type, - TimeTicks start_time) { + base::TimeTicks start_time) { if (!log_for_testing_) return;
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h b/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h index 276847a..ef6629b2 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h
@@ -97,19 +97,19 @@ // |log_for_testing_| is enabled. void LogTaskForTesting(std::vector<TaskForTest>* ordered_tasks, uint64_t task_id, - TimeTicks start_time, - TimeTicks end_time); + base::TimeTicks start_time, + base::TimeTicks end_time); // Logs the action defined by the parameters passed to |ordered_actions| if // |log_for_testing_| is enabled. void LogActionForTesting(std::vector<ActionForTest>* ordered_actions, uint64_t action_id, ActionForTest::ActionType type, - TimeTicks start_time); + base::TimeTicks start_time); const bool log_for_testing_; - const TimeTicks initial_time_; + const base::TimeTicks initial_time_; const std::unique_ptr<ThreadPoolManager> thread_pool_manager_;
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.cc b/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.cc index 90414bb..6406a508 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.cc
@@ -7,7 +7,7 @@ namespace sequence_manager { SimpleThreadImpl::SimpleThreadImpl(ThreadPoolManager* thread_pool_manager, - TimeTicks initial_time, + base::TimeTicks initial_time, ThreadCallback callback) : SimpleThread("TestThread"), thread_pool_manager_(thread_pool_manager),
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.h b/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.h index 0ef9d7e..cddb2be 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.h +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.h
@@ -24,7 +24,7 @@ using ThreadCallback = base::OnceCallback<void(ThreadManager*)>; SimpleThreadImpl(ThreadPoolManager* thread_pool_manager, - TimeTicks initial_time, + base::TimeTicks initial_time, ThreadCallback callback); ~SimpleThreadImpl() override; @@ -37,7 +37,7 @@ ThreadPoolManager* thread_pool_manager_ = nullptr; // Time in which the thread is created. - TimeTicks initial_time_; + base::TimeTicks initial_time_; // The object pointed to by |thread_manager_| is created and destructed from // the Run function. This is necessary since it has to be constructed from the
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc index 596f306..18c5654 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc
@@ -38,7 +38,7 @@ } // namespace -ThreadManager::ThreadManager(TimeTicks initial_time, +ThreadManager::ThreadManager(base::TimeTicks initial_time, SequenceManagerFuzzerProcessor* processor) : processor_(processor) { DCHECK(processor_); @@ -46,11 +46,12 @@ test_task_runner_ = WrapRefCounted( new TestMockTimeTaskRunner(TestMockTimeTaskRunner::Type::kBoundToThread)); - DCHECK(!(initial_time - TimeTicks()).is_zero()) - << "A zero clock is not allowed as empty TimeTicks have a special value " + DCHECK(!(initial_time - base::TimeTicks()).is_zero()) + << "A zero clock is not allowed as empty base::TimeTicks have a special " + "value " "(i.e. base::TimeTicks::is_null())"; - test_task_runner_->AdvanceMockTickClock(initial_time - TimeTicks()); + test_task_runner_->AdvanceMockTickClock(initial_time - base::TimeTicks()); manager_ = SequenceManagerForTest::Create(nullptr, ThreadTaskRunnerHandle::Get(), @@ -63,16 +64,16 @@ ThreadManager::~ThreadManager() = default; -TimeTicks ThreadManager::NowTicks() { +base::TimeTicks ThreadManager::NowTicks() { return test_task_runner_->GetMockTickClock()->NowTicks(); } -TimeDelta ThreadManager::NextPendingTaskDelay() { - return std::max(TimeDelta::FromMilliseconds(0), +base::TimeDelta ThreadManager::NextPendingTaskDelay() { + return std::max(base::TimeDelta::FromMilliseconds(0), test_task_runner_->NextPendingTaskDelay()); } -void ThreadManager::AdvanceMockTickClock(TimeDelta delta) { +void ThreadManager::AdvanceMockTickClock(base::TimeDelta delta) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return test_task_runner_->AdvanceMockTickClock(delta); @@ -85,7 +86,7 @@ RunAction(initial_thread_action); } - while (NowTicks() < TimeTicks::Max()) { + while (NowTicks() < base::TimeTicks::Max()) { RunLoop().RunUntilIdle(); processor_->thread_pool_manager() ->AdvanceClockSynchronouslyByPendingTaskDelay(this); @@ -208,7 +209,7 @@ FROM_HERE, BindOnce(&Task::Execute, pending_task->weak_ptr_factory_.GetWeakPtr(), task), - TimeDelta::FromMilliseconds(delay_ms)); + base::TimeDelta::FromMilliseconds(delay_ms)); { AutoLock lock(lock_); @@ -353,7 +354,7 @@ void ThreadManager::ExecuteTask( const SequenceManagerTestDescription::Task& task) { - TimeTicks start_time = NowTicks(); + base::TimeTicks start_time = NowTicks(); // We can limit the depth of the nested post delayed action when processing // the proto. @@ -363,12 +364,13 @@ RunAction(task_action); } - TimeTicks end_time = NowTicks(); + base::TimeTicks end_time = NowTicks(); - TimeTicks next_time = + base::TimeTicks next_time = start_time + - std::max(TimeDelta(), TimeDelta::FromMilliseconds(task.duration_ms()) - - (end_time - start_time)); + std::max(base::TimeDelta(), + base::TimeDelta::FromMilliseconds(task.duration_ms()) - + (end_time - start_time)); while (NowTicks() != next_time) { processor_->thread_pool_manager()->AdvanceClockSynchronouslyToTime(
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.h b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.h index 05fe289..9b0fdd13 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.h +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.h
@@ -30,20 +30,20 @@ public: // |initial_time| is the time in which |this| was instantiated. - ThreadManager(TimeTicks initial_time, + ThreadManager(base::TimeTicks initial_time, SequenceManagerFuzzerProcessor* processor); ~ThreadManager(); // Returns the time of the underlying task runner. - TimeTicks NowTicks(); + base::TimeTicks NowTicks(); // Returns the delay of the oldest pending task on the thread |this| is bound // to. - TimeDelta NextPendingTaskDelay(); + base::TimeDelta NextPendingTaskDelay(); // Advances the clock of the underlying task runner by |delta|. - void AdvanceMockTickClock(TimeDelta delta); + void AdvanceMockTickClock(base::TimeDelta delta); // Used to create a thread and register it with the thread pool manager owned // by |processor_|.
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.cc b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.cc index a9dae64..b5e90f5 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.cc +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.cc
@@ -12,7 +12,7 @@ ThreadPoolManager::ThreadPoolManager(SequenceManagerFuzzerProcessor* processor) : processor_(processor), - next_time_(TimeTicks::Max()), + next_time_(base::TimeTicks::Max()), ready_to_compute_time_(&lock_), ready_to_advance_time_(&lock_), ready_to_terminate_(&lock_), @@ -32,7 +32,7 @@ void ThreadPoolManager::CreateThread( const google::protobuf::RepeatedPtrField< SequenceManagerTestDescription::Action>& initial_thread_actions, - TimeTicks time) { + base::TimeTicks time) { SimpleThread* thread; { AutoLock lock(lock_); @@ -81,7 +81,7 @@ void ThreadPoolManager::AdvanceClockSynchronouslyToTime( ThreadManager* thread_manager, - TimeTicks time) { + base::TimeTicks time) { ThreadReadyToComputeTime(); { AutoLock lock(lock_); @@ -118,7 +118,7 @@ threads_waiting_to_advance_time_ = 0; threads_ready_for_next_round_ = 0; all_threads_ready_ = true; - next_time_ = TimeTicks::Max(); + next_time_ = base::TimeTicks::Max(); ready_for_next_round_.Broadcast(); } }
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h index 7cf9860..577dcc7 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h
@@ -35,13 +35,13 @@ void CreateThread( const google::protobuf::RepeatedPtrField< SequenceManagerTestDescription::Action>& initial_thread_actions, - TimeTicks initial_time); + base::TimeTicks initial_time); // Advances the mock tick clock of all the threads synchronously. // Note that this doesn't guarantee advancing the thread's clock to |time|. // The clock is advanced to the minimum desired time of all the owned threads. void AdvanceClockSynchronouslyToTime(ThreadManager* thread_manager, - TimeTicks time); + base::TimeTicks time); // Advances the mock tick clock of all the threads synchronously. // Note that this doesn't guarantee advancing the thread's clock by the next @@ -98,7 +98,7 @@ Lock lock_; // Used to synchronize virtual time across all threads. - TimeTicks next_time_; + base::TimeTicks next_time_; // Condition to ensure that all threads have their desired next time // computed, and thus the global |next_time_| can be computed as their
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h index 7ac9674..22369c28 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
@@ -75,7 +75,7 @@ std::unique_ptr<RendererPauseHandle> PauseScheduler() override WARN_UNUSED_RESULT; - // Returns TimeTicks::Now() by default. + // Returns base::TimeTicks::Now() by default. base::TimeTicks MonotonicallyIncreasingVirtualTime() override; NonMainThreadSchedulerImpl* AsNonMainThreadScheduler() override {
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc index b6ee288..e03ec9c 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
@@ -155,7 +155,7 @@ *thread_->GetTaskRunner(), FROM_HERE, CrossThreadBindOnce(&MockTask::Run, WTF::CrossThreadUnretained(&delayed_task)), - TimeDelta::FromMilliseconds(50)); + base::TimeDelta::FromMilliseconds(50)); thread_.reset(); }
diff --git a/third_party/blink/renderer/platform/testing/unit_test_helpers.cc b/third_party/blink/renderer/platform/testing/unit_test_helpers.cc index b3c2163..baf8da7 100644 --- a/third_party/blink/renderer/platform/testing/unit_test_helpers.cc +++ b/third_party/blink/renderer/platform/testing/unit_test_helpers.cc
@@ -71,7 +71,7 @@ ThreadState::Current()->LeaveGCForbiddenScope(); } -void RunDelayedTasks(TimeDelta delay) { +void RunDelayedTasks(base::TimeDelta delay) { Thread::Current()->GetTaskRunner()->PostDelayedTask( FROM_HERE, WTF::Bind(&ExitRunLoop), delay); EnterRunLoop();
diff --git a/third_party/blink/renderer/platform/testing/unit_test_helpers.h b/third_party/blink/renderer/platform/testing/unit_test_helpers.h index c1de99ae..9beffda 100644 --- a/third_party/blink/renderer/platform/testing/unit_test_helpers.h +++ b/third_party/blink/renderer/platform/testing/unit_test_helpers.h
@@ -42,7 +42,7 @@ void RunPendingTasks(); // Waits for delayed task to complete or timers to fire for |delay|. -void RunDelayedTasks(TimeDelta delay); +void RunDelayedTasks(base::TimeDelta delay); void EnterRunLoop(); void ExitRunLoop();
diff --git a/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc b/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc index 2e94088..ba7eb0b 100644 --- a/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc +++ b/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
@@ -82,8 +82,8 @@ if (!self) return; - delegate->DidFinishLoading(client_, TimeTicks(), data.size(), data.size(), - data.size()); + delegate->DidFinishLoading(client_, base::TimeTicks(), data.size(), + data.size(), data.size()); } WebURL WebURLLoaderMock::ServeRedirect(
diff --git a/third_party/blink/renderer/platform/timer.cc b/third_party/blink/renderer/platform/timer.cc index 87de498..5d55cbb 100644 --- a/third_party/blink/renderer/platform/timer.cc +++ b/third_party/blink/renderer/platform/timer.cc
@@ -48,8 +48,8 @@ Stop(); } -void TimerBase::Start(TimeDelta next_fire_interval, - TimeDelta repeat_interval, +void TimerBase::Start(base::TimeDelta next_fire_interval, + base::TimeDelta repeat_interval, const base::Location& caller) { #if DCHECK_IS_ON() DCHECK_EQ(thread_, CurrentThread()); @@ -65,16 +65,16 @@ DCHECK_EQ(thread_, CurrentThread()); #endif - repeat_interval_ = TimeDelta(); - next_fire_time_ = TimeTicks(); + repeat_interval_ = base::TimeDelta(); + next_fire_time_ = base::TimeTicks(); weak_ptr_factory_.InvalidateWeakPtrs(); } -TimeDelta TimerBase::NextFireInterval() const { +base::TimeDelta TimerBase::NextFireInterval() const { DCHECK(IsActive()); - TimeTicks current = TimerCurrentTimeTicks(); + base::TimeTicks current = TimerCurrentTimeTicks(); if (next_fire_time_ < current) - return TimeDelta(); + return base::TimeDelta(); return next_fire_time_ - current; } @@ -96,9 +96,9 @@ if (!active) return; - TimeTicks now = TimerCurrentTimeTicks(); - TimeTicks next_fire_time = std::max(next_fire_time_, now); - next_fire_time_ = TimeTicks(); + base::TimeTicks now = TimerCurrentTimeTicks(); + base::TimeTicks next_fire_time = std::max(next_fire_time_, now); + next_fire_time_ = base::TimeTicks(); SetNextFireTime(now, next_fire_time - now); } @@ -107,12 +107,12 @@ return web_task_runner_; } -void TimerBase::SetNextFireTime(TimeTicks now, TimeDelta delay) { +void TimerBase::SetNextFireTime(base::TimeTicks now, base::TimeDelta delay) { #if DCHECK_IS_ON() DCHECK_EQ(thread_, CurrentThread()); #endif - TimeTicks new_time = now + delay; + base::TimeTicks new_time = now + delay; if (next_fire_time_ != new_time) { next_fire_time_ = new_time; @@ -142,16 +142,16 @@ #endif if (!repeat_interval_.is_zero()) { - TimeTicks now = TimerCurrentTimeTicks(); + base::TimeTicks now = TimerCurrentTimeTicks(); // This computation should be drift free, and it will cope if we miss a // beat, which can easily happen if the thread is busy. It will also cope // if we get called slightly before m_unalignedNextFireTime, which can // happen due to lack of timer precision. - TimeDelta interval_to_next_fire_time = + base::TimeDelta interval_to_next_fire_time = repeat_interval_ - (now - next_fire_time_) % repeat_interval_; SetNextFireTime(now, interval_to_next_fire_time); } else { - next_fire_time_ = TimeTicks(); + next_fire_time_ = base::TimeTicks(); } Fired(); } @@ -162,8 +162,8 @@ } // static -TimeTicks TimerBase::TimerCurrentTimeTicks() const { - return WTF::TimeTicks( +base::TimeTicks TimerBase::TimerCurrentTimeTicks() const { + return base::TimeTicks( ThreadScheduler::Current()->MonotonicallyIncreasingVirtualTime()); }
diff --git a/third_party/blink/renderer/platform/timer.h b/third_party/blink/renderer/platform/timer.h index 428952d..3747294 100644 --- a/third_party/blink/renderer/platform/timer.h +++ b/third_party/blink/renderer/platform/timer.h
@@ -48,16 +48,17 @@ explicit TimerBase(scoped_refptr<base::SingleThreadTaskRunner>); virtual ~TimerBase(); - void Start(TimeDelta next_fire_interval, - TimeDelta repeat_interval, + void Start(base::TimeDelta next_fire_interval, + base::TimeDelta repeat_interval, const base::Location&); - void StartRepeating(TimeDelta repeat_interval, const base::Location& caller) { + void StartRepeating(base::TimeDelta repeat_interval, + const base::Location& caller) { Start(repeat_interval, repeat_interval, caller); } - void StartOneShot(TimeDelta interval, const base::Location& caller) { - Start(interval, TimeDelta(), caller); + void StartOneShot(base::TimeDelta interval, const base::Location& caller) { + Start(interval, base::TimeDelta(), caller); } // Timer cancellation is fast enough that you shouldn't have to worry @@ -66,12 +67,13 @@ bool IsActive() const; const base::Location& GetLocation() const { return location_; } - TimeDelta NextFireInterval() const; - TimeDelta RepeatInterval() const { return repeat_interval_; } + base::TimeDelta NextFireInterval() const; + base::TimeDelta RepeatInterval() const { return repeat_interval_; } - void AugmentRepeatInterval(TimeDelta delta) { - TimeTicks now = TimerCurrentTimeTicks(); - SetNextFireTime(now, std::max(next_fire_time_ - now + delta, TimeDelta())); + void AugmentRepeatInterval(base::TimeDelta delta) { + base::TimeTicks now = TimerCurrentTimeTicks(); + SetNextFireTime(now, + std::max(next_fire_time_ - now + delta, base::TimeDelta())); repeat_interval_ += delta; } @@ -89,14 +91,14 @@ NO_SANITIZE_ADDRESS virtual bool CanFire() const { return true; } - TimeTicks TimerCurrentTimeTicks() const; + base::TimeTicks TimerCurrentTimeTicks() const; - void SetNextFireTime(TimeTicks now, TimeDelta delay); + void SetNextFireTime(base::TimeTicks now, base::TimeDelta delay); void RunInternal(); - TimeTicks next_fire_time_; // 0 if inactive - TimeDelta repeat_interval_; // 0 if not repeating + base::TimeTicks next_fire_time_; // 0 if inactive + base::TimeDelta repeat_interval_; // 0 if not repeating base::Location location_; scoped_refptr<base::SingleThreadTaskRunner> web_task_runner_;
diff --git a/third_party/blink/renderer/platform/timer_perf_test.cc b/third_party/blink/renderer/platform/timer_perf_test.cc index e5feb28..796af13a 100644 --- a/third_party/blink/renderer/platform/timer_perf_test.cc +++ b/third_party/blink/renderer/platform/timer_perf_test.cc
@@ -47,13 +47,13 @@ scheduler::GetSingleThreadTaskRunnerForTesting(), this, &TimerPerfTest::RecordEndRunTime); - measure_run_start.StartOneShot(TimeDelta(), FROM_HERE); + measure_run_start.StartOneShot(base::TimeDelta(), FROM_HERE); base::ThreadTicks post_start = base::ThreadTicks::Now(); for (int i = 0; i < kNumIterations; i++) { - timers[i]->StartOneShot(TimeDelta(), FROM_HERE); + timers[i]->StartOneShot(base::TimeDelta(), FROM_HERE); } base::ThreadTicks post_end = base::ThreadTicks::Now(); - measure_run_end.StartOneShot(TimeDelta(), FROM_HERE); + measure_run_end.StartOneShot(base::TimeDelta(), FROM_HERE); test::EnterRunLoop(); @@ -83,13 +83,13 @@ scheduler::GetSingleThreadTaskRunnerForTesting(), this, &TimerPerfTest::RecordEndRunTime); - measure_run_start.StartOneShot(TimeDelta(), FROM_HERE); + measure_run_start.StartOneShot(base::TimeDelta(), FROM_HERE); base::ThreadTicks post_start = base::ThreadTicks::Now(); for (int i = 0; i < kNumIterations; i++) { - timers[i]->StartOneShot(TimeDelta(), FROM_HERE); + timers[i]->StartOneShot(base::TimeDelta(), FROM_HERE); } base::ThreadTicks post_end = base::ThreadTicks::Now(); - measure_run_end.StartOneShot(TimeDelta(), FROM_HERE); + measure_run_end.StartOneShot(base::TimeDelta(), FROM_HERE); base::ThreadTicks cancel_start = base::ThreadTicks::Now(); for (int i = 0; i < kNumIterations; i++) {
diff --git a/third_party/blink/renderer/platform/timer_test.cc b/third_party/blink/renderer/platform/timer_test.cc index f2e4b64..a72a273 100644 --- a/third_party/blink/renderer/platform/timer_test.cc +++ b/third_party/blink/renderer/platform/timer_test.cc
@@ -37,7 +37,7 @@ void SetUp() override { run_times_.clear(); - platform_->AdvanceClock(TimeDelta::FromSeconds(10)); + platform_->AdvanceClock(base::TimeDelta::FromSeconds(10)); start_time_ = Now(); } @@ -49,16 +49,16 @@ next_fire_times_.push_back(Now() + timer->NextFireInterval()); } - void RunUntilDeadline(TimeTicks deadline) { - TimeDelta period = deadline - Now(); - EXPECT_GE(period, TimeDelta()); + void RunUntilDeadline(base::TimeTicks deadline) { + base::TimeDelta period = deadline - Now(); + EXPECT_GE(period, base::TimeDelta()); platform_->RunForPeriod(period); } // Returns false if there are no pending delayed tasks, otherwise sets |time| // to the delay in seconds till the next pending delayed task is scheduled to // fire. - bool TimeTillNextDelayedTask(TimeDelta* time) const { + bool TimeTillNextDelayedTask(base::TimeDelta* time) const { base::sequence_manager::LazyNow lazy_now = platform_->GetMainThreadScheduler() ->real_time_domain() @@ -77,9 +77,9 @@ } protected: - TimeTicks start_time_; - WTF::Vector<TimeTicks> run_times_; - WTF::Vector<TimeTicks> next_fire_times_; + base::TimeTicks start_time_; + WTF::Vector<base::TimeTicks> run_times_; + WTF::Vector<base::TimeTicks> next_fire_times_; ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> platform_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; @@ -116,7 +116,7 @@ record_(std::move(record)) {} ~OnHeapTimerOwner() { record_->SetOwnerIsDestructed(); } - void StartOneShot(TimeDelta interval, const base::Location& caller) { + void StartOneShot(base::TimeDelta interval, const base::Location& caller) { timer_.StartOneShot(interval, caller); } @@ -143,9 +143,9 @@ TEST_F(TimerTest, StartOneShot_Zero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_FALSE(TimeTillNextDelayedTask(&run_time)); platform_->RunUntilIdle(); @@ -155,9 +155,9 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancel) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_FALSE(TimeTillNextDelayedTask(&run_time)); timer.Stop(); @@ -169,9 +169,9 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_FALSE(TimeTillNextDelayedTask(&run_time)); timer.Stop(); @@ -179,7 +179,7 @@ platform_->RunUntilIdle(); EXPECT_FALSE(run_times_.size()); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); EXPECT_FALSE(TimeTillNextDelayedTask(&run_time)); @@ -190,15 +190,15 @@ TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_FALSE(TimeTillNextDelayedTask(&run_time)); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, ElementsAre(start_time_)); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); EXPECT_FALSE(TimeTillNextDelayedTask(&run_time)); @@ -209,25 +209,25 @@ TEST_F(TimerTest, StartOneShot_NonZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(10), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), run_time); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(10))); + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(10))); } TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(10), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), run_time); timer.Stop(); EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); @@ -239,11 +239,11 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(10), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), run_time); timer.Stop(); EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); @@ -251,134 +251,140 @@ platform_->RunUntilIdle(); EXPECT_FALSE(run_times_.size()); - TimeTicks second_post_time = Now(); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + base::TimeTicks second_post_time = Now(); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(10), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), run_time); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, - ElementsAre(second_post_time + TimeDelta::FromSeconds(10))); + ElementsAre(second_post_time + base::TimeDelta::FromSeconds(10))); } TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(10), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), run_time); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(10))); + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(10))); - timer.StartOneShot(TimeDelta::FromSeconds(20), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(20), FROM_HERE); EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(20), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(20), run_time); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(10), - start_time_ + TimeDelta::FromSeconds(30))); + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(10), + start_time_ + base::TimeDelta::FromSeconds(30))); } TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(10), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), run_time); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(10))); + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(10))); } TEST_F(TimerTest, PostingTimerTwiceWithNewerRunTimeCancelsOriginalTask) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); platform_->RunUntilIdle(); - EXPECT_THAT(run_times_, ElementsAre(start_time_ + TimeDelta::FromSeconds(0))); + EXPECT_THAT(run_times_, + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(0))); } TEST_F(TimerTest, PostingTimerTwiceWithLaterRunTimeCancelsOriginalTask) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(10))); + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(10))); } TEST_F(TimerTest, StartRepeatingTask) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(1), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(1), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), run_time); - RunUntilDeadline(start_time_ + TimeDelta::FromMilliseconds(5500)); - EXPECT_THAT(run_times_, ElementsAre(start_time_ + TimeDelta::FromSeconds(1), - start_time_ + TimeDelta::FromSeconds(2), - start_time_ + TimeDelta::FromSeconds(3), - start_time_ + TimeDelta::FromSeconds(4), - start_time_ + TimeDelta::FromSeconds(5))); + RunUntilDeadline(start_time_ + base::TimeDelta::FromMilliseconds(5500)); + EXPECT_THAT(run_times_, + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(1), + start_time_ + base::TimeDelta::FromSeconds(2), + start_time_ + base::TimeDelta::FromSeconds(3), + start_time_ + base::TimeDelta::FromSeconds(4), + start_time_ + base::TimeDelta::FromSeconds(5))); } TEST_F(TimerTest, StartRepeatingTask_ThenCancel) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(1), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(1), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), run_time); - RunUntilDeadline(start_time_ + TimeDelta::FromMilliseconds(2500)); - EXPECT_THAT(run_times_, ElementsAre(start_time_ + TimeDelta::FromSeconds(1), - start_time_ + TimeDelta::FromSeconds(2))); + RunUntilDeadline(start_time_ + base::TimeDelta::FromMilliseconds(2500)); + EXPECT_THAT(run_times_, + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(1), + start_time_ + base::TimeDelta::FromSeconds(2))); timer.Stop(); platform_->RunUntilIdle(); - EXPECT_THAT(run_times_, ElementsAre(start_time_ + TimeDelta::FromSeconds(1), - start_time_ + TimeDelta::FromSeconds(2))); + EXPECT_THAT(run_times_, + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(1), + start_time_ + base::TimeDelta::FromSeconds(2))); } TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(1), FROM_HERE); - TimeDelta run_time; + base::TimeDelta run_time; EXPECT_TRUE(TimeTillNextDelayedTask(&run_time)); - EXPECT_EQ(TimeDelta::FromSeconds(1), run_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), run_time); - RunUntilDeadline(start_time_ + TimeDelta::FromMilliseconds(2500)); - EXPECT_THAT(run_times_, ElementsAre(start_time_ + TimeDelta::FromSeconds(1), - start_time_ + TimeDelta::FromSeconds(2))); + RunUntilDeadline(start_time_ + base::TimeDelta::FromMilliseconds(2500)); + EXPECT_THAT(run_times_, + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(1), + start_time_ + base::TimeDelta::FromSeconds(2))); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); platform_->RunUntilIdle(); - EXPECT_THAT(run_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(1), - start_time_ + TimeDelta::FromSeconds(2), - start_time_ + TimeDelta::FromMilliseconds(2500))); + EXPECT_THAT( + run_times_, + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(1), + start_time_ + base::TimeDelta::FromSeconds(2), + start_time_ + base::TimeDelta::FromMilliseconds(2500))); } TEST_F(TimerTest, IsActive_NeverPosted) { @@ -391,7 +397,7 @@ TEST_F(TimerTest, IsActive_AfterPosting_OneShotZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); EXPECT_TRUE(timer.IsActive()); } @@ -399,7 +405,7 @@ TEST_F(TimerTest, IsActive_AfterPosting_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); EXPECT_TRUE(timer.IsActive()); } @@ -407,7 +413,7 @@ TEST_F(TimerTest, IsActive_AfterPosting_Repeating) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(1), FROM_HERE); EXPECT_TRUE(timer.IsActive()); } @@ -415,7 +421,7 @@ TEST_F(TimerTest, IsActive_AfterRunning_OneShotZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); platform_->RunUntilIdle(); EXPECT_FALSE(timer.IsActive()); @@ -424,7 +430,7 @@ TEST_F(TimerTest, IsActive_AfterRunning_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); platform_->RunUntilIdle(); EXPECT_FALSE(timer.IsActive()); @@ -433,16 +439,16 @@ TEST_F(TimerTest, IsActive_AfterRunning_Repeating) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(1), FROM_HERE); - RunUntilDeadline(start_time_ + TimeDelta::FromSeconds(10)); + RunUntilDeadline(start_time_ + base::TimeDelta::FromSeconds(10)); EXPECT_TRUE(timer.IsActive()); // It should run until cancelled. } TEST_F(TimerTest, NextFireInterval_OneShotZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); EXPECT_TRUE(timer.NextFireInterval().is_zero()); } @@ -450,9 +456,9 @@ TEST_F(TimerTest, NextFireInterval_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); - EXPECT_EQ(TimeDelta::FromSeconds(10), timer.NextFireInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), timer.NextFireInterval()); } TEST_F(TimerTest, NextFireInterval_OneShotNonZero_AfterAFewSeconds) { @@ -460,18 +466,18 @@ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); - platform_->AdvanceClock(TimeDelta::FromSeconds(2)); - EXPECT_EQ(TimeDelta::FromSeconds(8), timer.NextFireInterval()); + platform_->AdvanceClock(base::TimeDelta::FromSeconds(2)); + EXPECT_EQ(base::TimeDelta::FromSeconds(8), timer.NextFireInterval()); } TEST_F(TimerTest, NextFireInterval_Repeating) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(20), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(20), FROM_HERE); - EXPECT_EQ(TimeDelta::FromSeconds(20), timer.NextFireInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(20), timer.NextFireInterval()); } TEST_F(TimerTest, RepeatInterval_NeverStarted) { @@ -484,7 +490,7 @@ TEST_F(TimerTest, RepeatInterval_OneShotZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); EXPECT_TRUE(timer.RepeatInterval().is_zero()); } @@ -492,7 +498,7 @@ TEST_F(TimerTest, RepeatInterval_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(10), FROM_HERE); EXPECT_TRUE(timer.RepeatInterval().is_zero()); } @@ -500,28 +506,28 @@ TEST_F(TimerTest, RepeatInterval_Repeating) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(20), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(20), FROM_HERE); - EXPECT_EQ(TimeDelta::FromSeconds(20), timer.RepeatInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(20), timer.RepeatInterval()); } TEST_F(TimerTest, AugmentRepeatInterval) { TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(10), FROM_HERE); - EXPECT_EQ(TimeDelta::FromSeconds(10), timer.RepeatInterval()); - EXPECT_EQ(TimeDelta::FromSeconds(10), timer.NextFireInterval()); + timer.StartRepeating(base::TimeDelta::FromSeconds(10), FROM_HERE); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), timer.RepeatInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), timer.NextFireInterval()); - platform_->AdvanceClock(TimeDelta::FromSeconds(2)); - timer.AugmentRepeatInterval(TimeDelta::FromSeconds(10)); + platform_->AdvanceClock(base::TimeDelta::FromSeconds(2)); + timer.AugmentRepeatInterval(base::TimeDelta::FromSeconds(10)); - EXPECT_EQ(TimeDelta::FromSeconds(20), timer.RepeatInterval()); - EXPECT_EQ(TimeDelta::FromSeconds(18), timer.NextFireInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(20), timer.RepeatInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(18), timer.NextFireInterval()); - RunUntilDeadline(start_time_ + TimeDelta::FromSeconds(50)); + RunUntilDeadline(start_time_ + base::TimeDelta::FromSeconds(50)); EXPECT_THAT(run_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(20), - start_time_ + TimeDelta::FromSeconds(40))); + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(20), + start_time_ + base::TimeDelta::FromSeconds(40))); } TEST_F(TimerTest, AugmentRepeatInterval_TimerFireDelayed) { @@ -529,15 +535,15 @@ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::CountingTask); - timer.StartRepeating(TimeDelta::FromSeconds(10), FROM_HERE); - EXPECT_EQ(TimeDelta::FromSeconds(10), timer.RepeatInterval()); - EXPECT_EQ(TimeDelta::FromSeconds(10), timer.NextFireInterval()); + timer.StartRepeating(base::TimeDelta::FromSeconds(10), FROM_HERE); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), timer.RepeatInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), timer.NextFireInterval()); platform_->AdvanceClock( - TimeDelta::FromSeconds(123)); // Make the timer long overdue. - timer.AugmentRepeatInterval(TimeDelta::FromSeconds(10)); + base::TimeDelta::FromSeconds(123)); // Make the timer long overdue. + timer.AugmentRepeatInterval(base::TimeDelta::FromSeconds(10)); - EXPECT_EQ(TimeDelta::FromSeconds(20), timer.RepeatInterval()); + EXPECT_EQ(base::TimeDelta::FromSeconds(20), timer.RepeatInterval()); // The timer is overdue so it should be scheduled to fire immediatly. EXPECT_TRUE(timer.NextFireInterval().is_zero()); } @@ -547,41 +553,41 @@ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this, &TimerTest::RecordNextFireTimeTask); - timer.StartRepeating(TimeDelta::FromSeconds(2), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(2), FROM_HERE); RecordNextFireTimeTask( &timer); // Next scheduled task to run at |start_time_| + 2s // Simulate timer firing early. Next scheduled task to run at // |start_time_| + 4s - platform_->AdvanceClock(TimeDelta::FromMilliseconds(1900)); - RunUntilDeadline(Now() + TimeDelta::FromMilliseconds(200)); + platform_->AdvanceClock(base::TimeDelta::FromMilliseconds(1900)); + RunUntilDeadline(Now() + base::TimeDelta::FromMilliseconds(200)); // Next scheduled task to run at |start_time_| + 6s - platform_->RunForPeriod(TimeDelta::FromSeconds(2)); + platform_->RunForPeriod(base::TimeDelta::FromSeconds(2)); // Next scheduled task to run at |start_time_| + 8s - platform_->RunForPeriod(TimeDelta::FromMilliseconds(2100)); + platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(2100)); // Next scheduled task to run at |start_time_| + 10s - platform_->RunForPeriod(TimeDelta::FromMilliseconds(2900)); + platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(2900)); // Next scheduled task to run at |start_time_| + 14s (skips a beat) - platform_->AdvanceClock(TimeDelta::FromMilliseconds(3100)); + platform_->AdvanceClock(base::TimeDelta::FromMilliseconds(3100)); platform_->RunUntilIdle(); // Next scheduled task to run at |start_time_| + 18s (skips a beat) - platform_->AdvanceClock(TimeDelta::FromSeconds(4)); + platform_->AdvanceClock(base::TimeDelta::FromSeconds(4)); platform_->RunUntilIdle(); // Next scheduled task to run at |start_time_| + 28s (skips 5 beats) - platform_->AdvanceClock(TimeDelta::FromSeconds(10)); + platform_->AdvanceClock(base::TimeDelta::FromSeconds(10)); platform_->RunUntilIdle(); EXPECT_THAT(next_fire_times_, - ElementsAre(start_time_ + TimeDelta::FromSeconds(2), - start_time_ + TimeDelta::FromSeconds(4), - start_time_ + TimeDelta::FromSeconds(6), - start_time_ + TimeDelta::FromSeconds(8), - start_time_ + TimeDelta::FromSeconds(10), - start_time_ + TimeDelta::FromSeconds(14), - start_time_ + TimeDelta::FromSeconds(18), - start_time_ + TimeDelta::FromSeconds(28))); + ElementsAre(start_time_ + base::TimeDelta::FromSeconds(2), + start_time_ + base::TimeDelta::FromSeconds(4), + start_time_ + base::TimeDelta::FromSeconds(6), + start_time_ + base::TimeDelta::FromSeconds(8), + start_time_ + base::TimeDelta::FromSeconds(10), + start_time_ + base::TimeDelta::FromSeconds(14), + start_time_ + base::TimeDelta::FromSeconds(18), + start_time_ + base::TimeDelta::FromSeconds(28))); } template <typename TimerFiredClass> @@ -608,7 +614,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner = task_queue->CreateTaskRunner(TaskType::kInternalTest); TimerForTest<TimerTest> timer(task_runner, this, &TimerTest::CountingTask); - timer.StartOneShot(TimeDelta(), FROM_HERE); + timer.StartOneShot(base::TimeDelta(), FROM_HERE); // Make sure the task was posted on taskRunner. EXPECT_FALSE(task_queue->IsEmpty()); @@ -620,7 +626,7 @@ Persistent<OnHeapTimerOwner> owner = MakeGarbageCollected<OnHeapTimerOwner>(record, GetTaskRunner()); - owner->StartOneShot(TimeDelta(), FROM_HERE); + owner->StartOneShot(base::TimeDelta(), FROM_HERE); EXPECT_FALSE(record->TimerHasFired()); platform_->RunUntilIdle(); @@ -634,7 +640,7 @@ MakeGarbageCollected<OnHeapTimerOwner>(record, GetTaskRunner()); record->Dispose(); - owner->StartOneShot(TimeDelta(), FROM_HERE); + owner->StartOneShot(base::TimeDelta(), FROM_HERE); owner = nullptr; ThreadState::Current()->CollectAllGarbageForTesting( @@ -653,7 +659,7 @@ MakeGarbageCollected<OnHeapTimerOwner>(record, GetTaskRunner()); record->Dispose(); - owner->StartOneShot(TimeDelta(), FROM_HERE); + owner->StartOneShot(base::TimeDelta(), FROM_HERE); owner = nullptr; // Explicit regular GC call to allow lazy sweeping. @@ -717,17 +723,18 @@ TimerForTest<TimerTest> timer(task_runner1, this, &TimerTest::CountingTask); - TimeTicks start_time = Now(); + base::TimeTicks start_time = Now(); - timer.StartOneShot(TimeDelta::FromSeconds(1), FROM_HERE); + timer.StartOneShot(base::TimeDelta::FromSeconds(1), FROM_HERE); - platform_->RunForPeriod(TimeDelta::FromMilliseconds(500)); + platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(500)); timer.MoveToNewTaskRunner(task_runner2); platform_->RunUntilIdle(); - EXPECT_THAT(run_times_, ElementsAre(start_time + TimeDelta::FromSeconds(1))); + EXPECT_THAT(run_times_, + ElementsAre(start_time + base::TimeDelta::FromSeconds(1))); EXPECT_THAT(run_order, ElementsAre(task_runner2)); @@ -758,20 +765,21 @@ TimerForTest<TimerTest> timer(task_runner1, this, &TimerTest::CountingTask); - TimeTicks start_time = Now(); + base::TimeTicks start_time = Now(); - timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); + timer.StartRepeating(base::TimeDelta::FromSeconds(1), FROM_HERE); - platform_->RunForPeriod(TimeDelta::FromMilliseconds(2500)); + platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(2500)); timer.MoveToNewTaskRunner(task_runner2); - platform_->RunForPeriod(TimeDelta::FromSeconds(2)); + platform_->RunForPeriod(base::TimeDelta::FromSeconds(2)); - EXPECT_THAT(run_times_, ElementsAre(start_time + TimeDelta::FromSeconds(1), - start_time + TimeDelta::FromSeconds(2), - start_time + TimeDelta::FromSeconds(3), - start_time + TimeDelta::FromSeconds(4))); + EXPECT_THAT(run_times_, + ElementsAre(start_time + base::TimeDelta::FromSeconds(1), + start_time + base::TimeDelta::FromSeconds(2), + start_time + base::TimeDelta::FromSeconds(3), + start_time + base::TimeDelta::FromSeconds(4))); EXPECT_THAT(run_order, ElementsAre(task_runner1, task_runner1, task_runner2, task_runner2));
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.h b/third_party/blink/renderer/platform/weborigin/security_origin.h index 2a3a067..03066f35e 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin.h +++ b/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -160,7 +160,7 @@ // the given URL. // Note: This function may return false when |url| has data scheme, which // is not aligned with CORS. If you want a CORS-aligned check, just use - // CORS mode (e.g., network::mojom::FetchRequestMode::kSameOrigin), or + // CORS mode (e.g., network::mojom::RequestMode::kSameOrigin), or // use CanReadContent. // See // https://docs.google.com/document/d/1_BD15unoPJVwKyf5yOUDu5kie492TTaBxzhJ58j1rD4/edit. @@ -305,6 +305,13 @@ // its precursor). scoped_refptr<SecurityOrigin> DeriveNewOpaqueOrigin() const; + // If this is an opaque origin that was derived from a tuple origin, return + // the origin from which this was derived. Otherwise returns |this|. This + // method may be used for things like CSP 'self' computation which require + // the origin before sandbox flags are applied. It should NOT be used for + // any security checks (such as bindings). + const SecurityOrigin* GetOriginOrPrecursorOriginIfOpaque() const; + // Only used for document.domain setting. The method should probably be moved // if we need it for something more general. static String CanonicalizeHost(const String& host, bool* success); @@ -341,10 +348,6 @@ // used only when trying to send an Origin across an IPC pipe. base::Optional<base::UnguessableToken> GetNonceForSerialization() const; - // If this is an opaque origin that was derived from a tuple origin, return - // the origin from which this was derived. Otherwise returns |this|. - const SecurityOrigin* GetOriginOrPrecursorOriginIfOpaque() const; - const String protocol_ = g_empty_string; const String host_ = g_empty_string; String domain_ = g_empty_string;
diff --git a/third_party/blink/renderer/platform/wtf/date_math.cc b/third_party/blink/renderer/platform/wtf/date_math.cc index 229b9cc7..4bbca32 100644 --- a/third_party/blink/renderer/platform/wtf/date_math.cc +++ b/third_party/blink/renderer/platform/wtf/date_math.cc
@@ -685,8 +685,8 @@ } // See http://tools.ietf.org/html/rfc2822#section-3.3 for more information. -String MakeRFC2822DateString(const Time date, int utc_offset) { - Time::Exploded time_exploded; +String MakeRFC2822DateString(const base::Time date, int utc_offset) { + base::Time::Exploded time_exploded; date.UTCExplode(&time_exploded); StringBuilder string_builder;
diff --git a/third_party/blink/renderer/platform/wtf/date_math.h b/third_party/blink/renderer/platform/wtf/date_math.h index 123b6331..d3c61ac 100644 --- a/third_party/blink/renderer/platform/wtf/date_math.h +++ b/third_party/blink/renderer/platform/wtf/date_math.h
@@ -62,7 +62,7 @@ const char* date_string); // utcOffset: [-720,720]. -WTF_EXPORT String MakeRFC2822DateString(const Time date, int utc_offset); +WTF_EXPORT String MakeRFC2822DateString(const base::Time date, int utc_offset); const char kWeekdayName[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
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 d27f098a..7cf8fe06 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
@@ -604,6 +604,7 @@ ], 'allowed': [ 'media::.+', + 'base::AutoLock', ] }, {
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b0a6ed86a..bc13cde 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3313,7 +3313,6 @@ crbug.com/968164 external/wpt/css/css-ui/webkit-appearance-menulist-button-001.html [ Failure ] # ====== New tests from wpt-importer added here ====== -crbug.com/626703 external/wpt/css/css-text-decor/text-underline-offset-001.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/start_alignment.html [ Failure ] crbug.com/626703 [ Retina ] external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html [ Timeout ] crbug.com/626703 external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html [ Timeout ] @@ -3326,7 +3325,6 @@ crbug.com/626703 [ Win10 ] external/wpt/html/cross-origin/anonymous.tentative.html [ Failure Crash ] crbug.com/626703 [ Win7 ] external/wpt/html/cross-origin/anonymous.tentative.html [ Failure Crash ] crbug.com/699040 external/wpt/svg/text/reftests/text-xml-space-001.svg [ Failure ] -crbug.com/626703 external/wpt/css/css-sizing/clone-nowrap-intrinsic-size-bidi.html [ Failure ] crbug.com/626703 external/wpt/service-workers/service-worker/ready.https.html [ Timeout ] crbug.com/626703 virtual/blink-cors/external/wpt/service-workers/service-worker/ready.https.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/ready.https.html [ Timeout ] @@ -4568,6 +4566,9 @@ # Other untriaged test failures, timeouts and crashes from newly-imported WPT tests. crbug.com/626703 external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html [ Failure Pass ] +# Underline offset and thickness +crbug.com/785230 external/wpt/css/css-text-decor/text-underline-offset-001.html [ Failure ] + crbug.com/785940 external/wpt/web-animations/timing-model/timelines/document-timelines.html [ Failure Pass ] crbug.com/912362 external/wpt/web-animations/timing-model/timelines/timelines.html [ Failure ]
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations index d944a75..f2c4922 100644 --- a/third_party/blink/web_tests/WebDriverExpectations +++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -924,6 +924,7 @@ crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/bubbling.py>>test_spin_event_loop [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state[realmSetting2-denied] [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/content_editable.py>>test_sets_insertion_point_to_after_last_text_node [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_session/create_alwaysMatch.py>>test_valid[pageLoadStrategy-eager] [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_invalid_parameters[parameters7] [ Failure ] @@ -951,6 +952,7 @@ crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/scroll_into_view.py>>test_option_stays_outside_of_scrollable_viewport [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state[realmSetting1-granted] [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_events.py>>test_special_key_sends_keydown[META-expected11] [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/content_editable.py>>test_sets_insertion_point_to_end [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_invalid_parameters[parameters0] [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_accept_and_notify[capabilities0-alert] [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_special_keys.py>>test_codepoint_keys_behave_correctly[\u1100\u1161\u11a8] [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 8407a01..c736a641 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -114933,6 +114933,42 @@ {} ] ], + "quirks/body-fills-html-quirk-float.html": [ + [ + "quirks/body-fills-html-quirk-float.html", + [ + [ + "/quirks/body-fills-html-quirk-ref.html", + "==" + ] + ], + {} + ] + ], + "quirks/body-fills-html-quirk-inline.html": [ + [ + "quirks/body-fills-html-quirk-inline.html", + [ + [ + "/quirks/body-fills-html-quirk-ref.html", + "==" + ] + ], + {} + ] + ], + "quirks/body-fills-html-quirk-positioned.html": [ + [ + "quirks/body-fills-html-quirk-positioned.html", + [ + [ + "/quirks/body-fills-html-quirk-ref.html", + "==" + ] + ], + {} + ] + ], "quirks/historical/list-item-bullet-size.html": [ [ "quirks/historical/list-item-bullet-size.html", @@ -114981,6 +115017,18 @@ {} ] ], + "quirks/table-cell-width-calculation-abspos.html": [ + [ + "quirks/table-cell-width-calculation-abspos.html", + [ + [ + "/quirks/reference/table-cell-width-calculation-abspos-ref.html", + "==" + ] + ], + {} + ] + ], "quirks/text-decoration-doesnt-propagate-into-tables/quirks.html": [ [ "quirks/text-decoration-doesnt-propagate-into-tables/quirks.html", @@ -161777,6 +161825,9 @@ "quirks/OWNERS": [ [] ], + "quirks/body-fills-html-quirk-ref.html": [ + [] + ], "quirks/hashless-hex-color/support/common.js": [ [] ], @@ -161792,6 +161843,9 @@ "quirks/reference/green-100px-square-no-red.html": [ [] ], + "quirks/reference/table-cell-width-calculation-abspos-ref.html": [ + [] + ], "quirks/support/test-ref-iframe.js": [ [] ], @@ -166595,9 +166649,6 @@ "svg/README.md": [ [] ], - "svg/coordinate-systems/outer-svg-intrinsic-size-002-expected.txt": [ - [] - ], "svg/coordinate-systems/support/abspos-ref.html": [ [] ], @@ -201892,6 +201943,12 @@ {} ] ], + "css/css-position/position-absolute-chrome-bug-002.html": [ + [ + "css/css-position/position-absolute-chrome-bug-002.html", + {} + ] + ], "css/css-position/position-absolute-container-dynamic-002.html": [ [ "css/css-position/position-absolute-container-dynamic-002.html", @@ -205870,6 +205927,12 @@ {} ] ], + "css/css-text/white-space/append-whitespace-only-node-crash-001.html": [ + [ + "css/css-text/white-space/append-whitespace-only-node-crash-001.html", + {} + ] + ], "css/css-text/white-space/nowrap-wbr-and-space-crash.html": [ [ "css/css-text/white-space/nowrap-wbr-and-space-crash.html", @@ -239974,6 +240037,12 @@ {} ] ], + "html/semantics/scripting-1/the-script-element/module/inactive-context-import.html": [ + [ + "html/semantics/scripting-1/the-script-element/module/inactive-context-import.html", + {} + ] + ], "html/semantics/scripting-1/the-script-element/module/inline-async-execorder.html": [ [ "html/semantics/scripting-1/the-script-element/module/inline-async-execorder.html", @@ -275663,30 +275732,6 @@ {} ] ], - "sms/constructor.tentative.https.any.js": [ - [ - "sms/constructor.tentative.https.any.html", - { - "script_metadata": [ - [ - "title", - "SMS Receiver API: Constructor" - ] - ] - } - ], - [ - "sms/constructor.tentative.https.any.worker.html", - { - "script_metadata": [ - [ - "title", - "SMS Receiver API: Constructor" - ] - ] - } - ] - ], "sms/idlharness.https.any.js": [ [ "sms/idlharness.https.any.html", @@ -364080,6 +364125,10 @@ "3e8899a94099983b147f0877a6d45a17341a0364", "testharness" ], + "css/css-position/position-absolute-chrome-bug-002.html": [ + "5fef5205f94576cc4834f98a2cb1f2007df94974", + "testharness" + ], "css/css-position/position-absolute-container-dynamic-002.html": [ "91d862835e6d1351deefb26f7e2b71a9539bbd6c", "testharness" @@ -374488,6 +374537,10 @@ "9d6b2c2bc7d0cde02d992f741884bf702c0398a4", "reftest" ], + "css/css-text/white-space/append-whitespace-only-node-crash-001.html": [ + "b32555b18876898beb1b3b7b4559268d64ae9c1c", + "testharness" + ], "css/css-text/white-space/break-spaces-001.html": [ "f3b881afc1074db7511acbc419e5083ebde3413e", "reftest" @@ -406989,7 +407042,7 @@ "testharness" ], "element-timing/background-image-multiple-elements.html": [ - "24f72a67c34d0cc5323c6d4a0acb2e25085ec87a", + "084bb9ca0205815a1c7ad7764ce1979485e88435", "testharness" ], "element-timing/background-image-stretched.html": [ @@ -407089,7 +407142,7 @@ "testharness" ], "element-timing/observe-text.html": [ - "a9a0e30adf353f342ad8bb6a2300ea90beb5d9fa", + "16382edaa9da45c246f34443ce3e70b7177f9203", "testharness" ], "element-timing/observe-video-poster.html": [ @@ -430028,6 +430081,10 @@ "ca6900744dcf3a07d98ddaa17b4173fd4bed5fb9", "testharness" ], + "html/semantics/scripting-1/the-script-element/module/inactive-context-import.html": [ + "ce88c0a1528613e6586f2188e583d44d5c89fe67", + "testharness" + ], "html/semantics/scripting-1/the-script-element/module/inline-async-execorder.html": [ "db03612e82b42b6bd3294ced7468bb6c8b702520", "testharness" @@ -435129,7 +435186,7 @@ "support" ], "interfaces/webxr.idl": [ - "f9bfdce58425350d1404c4beaac719e04c94a498", + "4af1c96a1847445c7559dabba20cb8a3a1de5c60", "support" ], "interfaces/worklets.idl": [ @@ -449696,6 +449753,22 @@ "608a7c15c7996b5ed3cf534379417c3c077c4e82", "testharness" ], + "quirks/body-fills-html-quirk-float.html": [ + "19438bc1bf35b2c4fe674ccaabb7ef32331c50a1", + "reftest" + ], + "quirks/body-fills-html-quirk-inline.html": [ + "4f15bb97c94219e566ad3c992ad37894f9d40e62", + "reftest" + ], + "quirks/body-fills-html-quirk-positioned.html": [ + "3ce416dd95cbc288318079c70890f5febc59a174", + "reftest" + ], + "quirks/body-fills-html-quirk-ref.html": [ + "180afbb84f8444aa4d83342e5679dfda26754acb", + "support" + ], "quirks/classname-query-after-sibling-adoption.html": [ "0fcad36776d5a7fe160244dc342f227b76083798", "testharness" @@ -449756,6 +449829,10 @@ "159d9a52a01a0b328680a530603cb496ab2d5fcf", "support" ], + "quirks/reference/table-cell-width-calculation-abspos-ref.html": [ + "3d365d25ad669f145a7e2ef5e4e6d0552713546a", + "support" + ], "quirks/support/test-ref-iframe.js": [ "e5df41d4249bc93b7458774524bf90f0a6f36be7", "support" @@ -449768,6 +449845,10 @@ "2ff00b9ee794c07309c05f2500b4be1b326afd7e", "testharness" ], + "quirks/table-cell-width-calculation-abspos.html": [ + "f26d06040775c8e2447ade4230fcf28ec06dee3b", + "reftest" + ], "quirks/table-cell-width-calculation.html": [ "eeb726627b78fdcbf81d3c29b9205f771bd0aca8", "testharness" @@ -464804,20 +464885,16 @@ "43b340dbb79f2585ef4acc4361ee94c6f22003f0", "testharness" ], - "sms/constructor.tentative.https.any.js": [ - "a624934ceeeace186038b15332d1c3c73968fbc7", - "testharness" - ], "sms/idlharness.https.any.js": [ - "c030a5073a0a376a1b337e563c955f78bdad41dc", + "0c31744937c6dbc9b292586ab8ce5f10b268f3ed", "testharness" ], "sms/interceptor.https.html": [ - "417120a12174859110f48a99a11405b7f2c0316e", + "4a6772f4416ab0550e451c710da1b48bbd9303d6", "testharness" ], "sms/resources/iframe.html": [ - "44410e805f7b2857809794f582a97df0d1b0ac14", + "9a00e84c63b9321d9e29c10aeb266ff5c0b1d5e1", "support" ], "sms/sms-top-level-frame-only.https.html": [ @@ -464825,11 +464902,11 @@ "testharness" ], "sms/sms_provider.js": [ - "dd3af9b747a3207d02c596b4fb6434772f3c44e3", + "a4759419a88670ec6e3f1cbd4ac3dcb3500ad57a", "support" ], "sms/sms_receiver.idl": [ - "bc6fb1dc1037fc263a5a2da35d03449fee4db48b", + "b71b6a3e0db2b74b127e4332cd83f218bb39d6aa", "support" ], "speech-api/META.yml": [ @@ -465740,10 +465817,6 @@ "0d9e2393ad0a16685fca1d5f2b9c378fbe2c851b", "testharness" ], - "svg/coordinate-systems/outer-svg-intrinsic-size-002-expected.txt": [ - "31c58585fd534b49406176a5c823ed9c7ed38cf9", - "support" - ], "svg/coordinate-systems/outer-svg-intrinsic-size-002.html": [ "8a65d6491842e150b3fcfc29759667b40764bc09", "testharness" @@ -467817,7 +467890,7 @@ "support" ], "tools/ci/website_build.sh": [ - "f91975719be21e7c1461e4f8603c4f34639b840f", + "aadfcbd6a212574fa5462447072b996ae214de6b", "support" ], "tools/conftest.py": [
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/meta/sandbox-iframe.html b/third_party/blink/web_tests/external/wpt/content-security-policy/meta/sandbox-iframe.html new file mode 100644 index 0000000..d353cafa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/meta/sandbox-iframe.html
@@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> + +<head> + <meta http-equiv="Content-Security-Policy" content="base-uri {{location[scheme]}}://{{domains[]}}:{{ports[http][0]}}/base/"> + + <title>base-uri works correctly inside a sandboxed iframe.</title> + <script src='/resources/testharness.js'></script> + <script src='/resources/testharnessreport.js'></script> +</head> + +<body> + <h1>self is derived correctly inside inside a sandboxed iframe.</h1> + <div id='log'></div> + + <script> + window.addEventListener('securitypolicyviolation', function(e) { + assert_unreached('No CSP violation report should have been fired.'); + }); + + async_test(function(t) { + var i = document.createElement('iframe'); + i.sandbox = 'allow-scripts'; + i.style.display = 'none'; + i.srcdoc = ` + <meta http-equiv="Content-Security-Policy" content="img-src 'self'"> + <body> + <script> + + var img = document.createElement('img'); + img.src = '../support/fail.png'; + img.onerror = function() { + top.postMessage('FAIL', '*'); + }; + img.onload = function() { + top.postMessage('PASS', '*'); + }; + document.body.appendChild(img); + </sc` + `ript></body>`; + + window.addEventListener('message', t.step_func(function(e) { + if (e.source === i.contentWindow) { + assert_equals(e.data, 'PASS'); + t.done(); + } + })); + + document.body.appendChild(i); + }, 'img-src \'self\' works when specified in a meta tag.'); + </script> + +</body> + +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/list-item-taller-than-opportunity-001.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/list-item-taller-than-opportunity-001.html new file mode 100644 index 0000000..ae8783ce --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/list-item-taller-than-opportunity-001.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>List item taller than the first opportunity should not crash</title> +<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/CSS22/visuren.html#float-position" title="9.5.1 Positioning the float: the 'float' property"> +<link rel="help" href="http://crbug.com/967997"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> + <div style="float: left; width: 5px; height: 5px;"></div> + <div style="clear: left; float: left; width: 10px; height: 5px;"></div> + <ul> + <li></li> + </ul> +<script> +test(() => {}, "Layout should not crash"); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-chrome-bug-002.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-chrome-bug-002.html new file mode 100644 index 0000000..5fef520 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-chrome-bug-002.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<link rel="author" href="mailto:atotic@google.com"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link rel="help" href="https://crbug.com/970166"> +<meta name="assert" content="simplified layout calculates correct abspos position with floats"> +<style> + +#container { + position: relative; + background: gray; +} +#container::after { + content: ''; + display: table; + clear:both; +} +#target { + position: absolute; + right: 0; + background: green; +} +</style> +<div id="container"> + <div style="float:left">floatleft</div> + <div id="target"> + <div>text</div> + <div id="toggle">toggle</div> + </div> +</div> +<script> +test(() => { + document.body.offsetTop; + let el = document.querySelector("#toggle"); + el.style.display = "none"; + document.body.offsetTop; + assert_equals(document.querySelector("#target").offsetTop, 0); +}, '#target position is recalculated correctly.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/append-whitespace-only-node-crash-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/append-whitespace-only-node-crash-001.html new file mode 100644 index 0000000..b32555b1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/append-whitespace-only-node-crash-001.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<link rel="help" href="https://crbug.com/971811"> +<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> + <div id="log"></div> +<script> +const strings = [' ', '\t', '\n', '\f', '\r']; +const whitespace_values = ['normal', 'pre', 'nowrap', 'pre-wrap', 'break-spaces', 'pre-line']; +const container = document.body; +for (let whitespace_value of whitespace_values) { + for (let string of strings) { + test(() => { + let div = document.createElement('div'); + div.style.whiteSpace = whitespace_value; + div.textContent = 'test'; + container.appendChild(div); + container.offsetTop; // Force layout + div.appendChild(document.createTextNode(string)); + container.offsetTop; // Force layout + }, `Append ${toCodePoints(string)} to 'white-space: ${whitespace_value}'`); + } +} + +function toCodePoints(string) { + let results = []; + for (let ch of string) { + let hex = ch.codePointAt(0).toString(16).toUpperCase(); + hex = ('000' + hex).substr(-4) + results.push('U+' + hex); + } + return results.join(' '); +} +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/attribute-changed-callback.html b/third_party/blink/web_tests/external/wpt/custom-elements/attribute-changed-callback.html index 5090bfb..db2a011 100644 --- a/third_party/blink/web_tests/external/wpt/custom-elements/attribute-changed-callback.html +++ b/third_party/blink/web_tests/external/wpt/custom-elements/attribute-changed-callback.html
@@ -91,6 +91,23 @@ }, 'setAttributeNode and removeAttributeNS must enqueue and invoke attributeChangedCallback for an SVG attribute'); test(function () { + const instance = document.createElement(customElement.name); + assert_array_equals(customElement.takeLog().types(), ['constructed']); + + instance.toggleAttribute('title', true); + assert_equals(instance.hasAttribute('title'), true); + var logEntries = customElement.takeLog(); + assert_array_equals(logEntries.types(), ['attributeChanged']); + assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: null, newValue: '', namespace: null}); + + instance.toggleAttribute('title'); + assert_equals(instance.hasAttribute('title'), false); + var logEntries = customElement.takeLog(); + assert_array_equals(logEntries.types(), ['attributeChanged']); + assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: '', newValue: null, namespace: null}); +}, 'toggleAttribute must enqueue and invoke attributeChangedCallback'); + +test(function () { const callsToOld = []; const callsToNew = []; class CustomElement extends HTMLElement { }
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reaction-timing.html b/third_party/blink/web_tests/external/wpt/custom-elements/reaction-timing.html index 9e5bafb..454cc26 100644 --- a/third_party/blink/web_tests/external/wpt/custom-elements/reaction-timing.html +++ b/third_party/blink/web_tests/external/wpt/custom-elements/reaction-timing.html
@@ -48,6 +48,31 @@ }, 'setAttribute and removeAttribute must enqueue and invoke attributeChangedCallback'); test(function () { + var instance = document.createElement('my-custom-element'); + var anotherInstance = document.createElement('my-custom-element'); + + var callbackOrder = []; + instance.handler = function () { + callbackOrder.push([this, 'begin']); + anotherInstance.toggleAttribute('data-title'); + callbackOrder.push([this, 'end']); + } + anotherInstance.handler = function () { + callbackOrder.push([this, 'begin']); + callbackOrder.push([this, 'end']); + } + + instance.toggleAttribute('title'); + assert_equals(callbackOrder.length, 4); + + assert_array_equals(callbackOrder[0], [instance, 'begin']); + assert_array_equals(callbackOrder[1], [anotherInstance, 'begin']); + assert_array_equals(callbackOrder[2], [anotherInstance, 'end']); + assert_array_equals(callbackOrder[3], [instance, 'end']); + +}, 'toggleAttribute must enqueue and invoke attributeChangedCallback'); + +test(function () { var shouldCloneAnotherInstance = false; var anotherInstanceClone; var log = [];
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Element.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Element.html index 83707240..e1576734 100644 --- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Element.html +++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Element.html
@@ -35,6 +35,15 @@ element.removeAttributeNS(null, name); }, 'removeAttributeNS on Element'); +testAttributeRemover(function (element, name, value) { + if (element.hasAttribute(name)) + element.toggleAttribute(name); +}, 'toggleAttribute (only removes) on Element'); + +testAttributeRemover(function (element, name, value) { + element.toggleAttribute(name, false); +}, 'toggleAttribute (force false) on Element'); + testAttributeAdder(function (element, name, value) { var attr = document.createAttribute(name); attr.value = value;
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/inactive-context-import.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/inactive-context-import.html new file mode 100644 index 0000000..ce88c0a1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/inactive-context-import.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Dynamic import triggered from inactive context should not crash</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div id="container"> +<iframe></iframe> +</div> + +<script> +test(() => { + const iframe = document.querySelector('iframe'); + const otherWindow = iframe.contentWindow; + iframe.remove(); + + // Below should not crash + otherWindow.eval(`import('foobar');`); +}, 'dynamic import from inactive context should not crash'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl index f9bfdce5..4af1c96a 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -203,8 +203,6 @@ optional XRWebGLLayerInit layerInit)] interface XRWebGLLayer { // Attributes - [SameObject] readonly attribute XRWebGLRenderingContext context; - readonly attribute boolean antialias; readonly attribute boolean ignoreDepthValues;
diff --git a/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-float.html b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-float.html new file mode 100644 index 0000000..19438bc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-float.html
@@ -0,0 +1,18 @@ +<!DOCTYPE quirks-mode> +<link rel="help" href="https://quirks.spec.whatwg.org/#the-body-element-fills-the-html-element-quirk"> +<link rel="match" href="body-fills-html-quirk-ref.html"> +<style> +body { + border: solid; + float: left; +} +span { + display: inline-block; + width: 100px; + height: 100px; + background: green; +} +</style> +<body> + <span></span> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-inline.html b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-inline.html new file mode 100644 index 0000000..4f15bb9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-inline.html
@@ -0,0 +1,18 @@ +<!DOCTYPE quirks-mode> +<link rel="help" href="https://quirks.spec.whatwg.org/#the-body-element-fills-the-html-element-quirk"> +<link rel="match" href="body-fills-html-quirk-ref.html"> +<style> +body { + border: solid; + display: inline-block; +} +span { + display: inline-block; + width: 100px; + height: 100px; + background: green; +} +</style> +<body> + <span></span> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-positioned.html b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-positioned.html new file mode 100644 index 0000000..3ce416d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-positioned.html
@@ -0,0 +1,18 @@ +<!DOCTYPE quirks-mode> +<link rel="help" href="https://quirks.spec.whatwg.org/#the-body-element-fills-the-html-element-quirk"> +<link rel="match" href="body-fills-html-quirk-ref.html"> +<style> +body { + border: solid; + position: absolute; +} +span { + display: inline-block; + width: 100px; + height: 100px; + background: green; +} +</style> +<body> + <span></span> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-ref.html b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-ref.html new file mode 100644 index 0000000..180afbb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/body-fills-html-quirk-ref.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div style="width: 100px; height: 100px; border: solid; background: green;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/quirks/reference/table-cell-width-calculation-abspos-ref.html b/third_party/blink/web_tests/external/wpt/quirks/reference/table-cell-width-calculation-abspos-ref.html new file mode 100644 index 0000000..3d365d2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/reference/table-cell-width-calculation-abspos-ref.html
@@ -0,0 +1,17 @@ +<style> +table { + font-size: 10px; + font-family: Ahem; +} +img { + vertical-align: bottom; + width: 10px; + height: 10px; + background: black; +} +</style> +<table> + <tr> + <td id="td">1234567<img id="img" src=""></td> + </tr> +</table>
diff --git a/third_party/blink/web_tests/external/wpt/quirks/table-cell-width-calculation-abspos.html b/third_party/blink/web_tests/external/wpt/quirks/table-cell-width-calculation-abspos.html new file mode 100644 index 0000000..f26d060 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/table-cell-width-calculation-abspos.html
@@ -0,0 +1,20 @@ +<title>An out-of-flow imagef in the table cell width calculation quirk</title> +<link rel="match" href="reference/table-cell-width-calculation-abspos-ref.html"> +<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org"> +<style> +table { + font-size: 10px; + font-family: Ahem; +} +img { + position: absolute; + width: 10px; + height: 10px; + background: black; +} +</style> +<table> + <tr> + <td id="td">1234567<img id="img" src=""></td> + </tr> +</table>
diff --git a/third_party/blink/web_tests/external/wpt/quirks/table-replaced-descendant-percentage-height-crash.html b/third_party/blink/web_tests/external/wpt/quirks/table-replaced-descendant-percentage-height-crash.html new file mode 100644 index 0000000..385d6caf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/table-replaced-descendant-percentage-height-crash.html
@@ -0,0 +1,14 @@ +<!-- quirks mode --> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://github.com/whatwg/quirks/issues/46"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=967069"> +<div style="display:table-cell; height:10000px;"> + <div style="writing-mode:vertical-rl;"> + <iframe style="height:100%;"></iframe> + </div> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + test(()=> { }, "No crash"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-animation.html b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-animation.html new file mode 100644 index 0000000..0320210f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-animation.html
@@ -0,0 +1,150 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test basic functionality of scroll linked animation.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/web-animations/testcommon.js"></script> +<style> + .scroller { + overflow: auto; + height: 100px; + width: 100px; + } + .contents { + height: 1000px; + width: 100%; + } +</style> +<div id="log"></div> +<script> + 'use strict'; + + function createScroller(test) { + var scroller = createDiv(test); + scroller.innerHTML = "<div class='contents'></div>"; + scroller.classList.add('scroller'); + return scroller; + } + + function createScrollTimeline(test) { + return new ScrollTimeline({ + scrollSource: createScroller(test), + timeRange: 1000 + }); + } + + function createScrollLinkedAnimation(test, timeline) { + if(timeline === undefined) + timeline = createScrollTimeline(test); + const DURATION = 1000; // ms + const KEYFRAMES = { opacity: [1, 0] }; + return new Animation( + new KeyframeEffect(createDiv(test), KEYFRAMES, DURATION), timeline); + } + + promise_test(async t => { + const animation = createScrollLinkedAnimation(t); + const scroller = animation.timeline.scrollSource; + const maxScroll = scroller.scrollHeight - scroller.clientHeight; + const timeRange = animation.timeline.timeRange; + + // Verify initial start and current times in Idle state. + assert_equals(animation.currentTime, null, + "The current time is null in Idle state."); + assert_equals(animation.startTime, null, + "The start time is null in Idle state."); + animation.play(); + // Verify initial start and current times in Pending state. + assert_equals(animation.currentTime, 0, + "The current time is a hold time in Pending state."); + assert_equals(animation.startTime, null, + "The start time is null in Pending state."); + + await animation.ready; + // Verify initial start and current times in Playing state. + assert_equals(animation.currentTime, 0, + "The current time is zero in Playing state."); + assert_equals(animation.startTime, 0, + "The start time is zero in Playing state."); + + // Now do some scrolling and make sure that the Animation current time is + // correct. + scroller.scrollTop = 0.2 * maxScroll; + assert_equals(animation.currentTime, animation.timeline.currentTime, + "The current time corresponds to the scroll position of the scroller."); +}, 'Animation start and current times are correct for each animation state.'); + +promise_test(async t => { + const animation = createScrollLinkedAnimation(t); + const scroller = animation.timeline.scrollSource; + const maxScroll = scroller.scrollHeight - scroller.clientHeight; + const timeRange = animation.timeline.timeRange; + // Advance the scroller. + scroller.scrollTop = 0.2 * maxScroll; + + // Verify initial start and current times in Idle state. + assert_equals(animation.currentTime, null, + "The current time is null in Idle state."); + assert_equals(animation.startTime, null, + "The start time is null in Idle state."); + animation.play(); + // Verify initial start and current times in Pending state. + assert_equals(animation.currentTime, 0, + "The current time is a hold time in Pending state."); + assert_equals(animation.startTime, null, + "The start time is null in Pending state."); + + await animation.ready; + // Verify initial start and current times in Playing state. + assert_equals(animation.currentTime, animation.timeline.currentTime, + "The current corresponds to the scroll position of the scroller."); + assert_equals(animation.startTime, 0, + "The start time is zero in Playing state."); +}, 'Animation start and current times are correct for each animation state' + + ' when the animation starts playing with advanced scroller.'); + +promise_test(async t => { + const timeline = createScrollTimeline(t); + const animation1 = createScrollLinkedAnimation(t, timeline); + const animation2 = createScrollLinkedAnimation(t, timeline); + const scroller = timeline.scrollSource; + const maxScroll = scroller.scrollHeight - scroller.clientHeight; + const timeRange = timeline.timeRange; + // Advance the scroller. + scroller.scrollTop = 0.2 * maxScroll; + + // Verify initial start and current times in Idle state. + assert_equals(animation1.currentTime, null, + "The current time is null in Idle state."); + assert_equals(animation1.startTime, null, + "The start time is null in Idle state."); + assert_equals(animation2.currentTime, null, + "The current time is null in Idle state."); + assert_equals(animation2.startTime, null, + "The start time is null in Idle state."); + animation1.play(); + animation2.play(); + // Verify initial start and current times in Pending state. + assert_equals(animation1.currentTime, 0, + "The current time is a hold time in Pending state."); + assert_equals(animation1.startTime, null, + "The start time is null in Pending state."); + assert_equals(animation2.currentTime, 0, + "The current time is a hold time in Pending state."); + assert_equals(animation2.startTime, null, + "The start time is null in Pending state."); + + await animation1.ready; + await animation2.ready; + // Verify initial start and current times in Playing state. + assert_equals(animation1.currentTime, timeline.currentTime, + "The current corresponds to the scroll position of the scroller."); + assert_equals(animation1.startTime, 0, + "The start time is zero in Playing state."); + assert_equals(animation2.currentTime, timeline.currentTime, + "The current corresponds to the scroll position of the scroller."); + assert_equals(animation2.startTime, 0, + "The start time is zero in Playing state."); +}, 'Animation start and current times are correct when multiple animations' + + ' are attached to the same timeline.'); +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/outer-svg-intrinsic-size-002-expected.txt b/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/outer-svg-intrinsic-size-002-expected.txt deleted file mode 100644 index 31c5858..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/outer-svg-intrinsic-size-002-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -PASS no sizing attributes set -PASS specified width -PASS modified specified width -PASS specified width and height -PASS specified width and modified specified height -FAIL specified height assert_equals: checking width. expected 300 but got 400 -FAIL modified specified height assert_equals: checking width. expected 300 but got 400 -FAIL no specified sizing attrs (after setting & removing them) assert_equals: checking width. expected 300 but got 400 -PASS set a 10x8 viewBox -PASS modified viewBox to 50x20 -PASS adding specified width, in presence of specified viewBox -PASS modifiying specified viewBox, in presence of specified width -PASS removing specified width, in presence of specified viewBox -PASS adding specified height, in presence of specified viewBox -PASS modifiying specified viewBox, in presence of specified height -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/website_build.sh b/third_party/blink/web_tests/external/wpt/tools/ci/website_build.sh index f919757..aadfcbd 100755 --- a/third_party/blink/web_tests/external/wpt/tools/ci/website_build.sh +++ b/third_party/blink/web_tests/external/wpt/tools/ci/website_build.sh
@@ -32,18 +32,6 @@ grep -E --silent '^(docs|tools)/' } -if is_pull_request ; then - echo Submission comes from a pull request. Exiting without building. - - exit ${neutral_status} -fi - -if ! targets_master ; then - echo Submission does not target the 'master' branch. Exiting without building. - - exit ${neutral_status} -fi - if ! modifies_relevant_files ; then echo No files related to the website have been modified. Exiting without echo building. @@ -78,6 +66,18 @@ # Publish the website by pushing the built contents to the `gh-pages` branch git add . +if is_pull_request ; then + echo Submission comes from a pull request. Exiting without publishing. + + exit ${neutral_status} +fi + +if ! targets_master ; then + echo Submission does not target the 'master' branch. Exiting without publishing. + + exit ${neutral_status} +fi + if git diff --exit-code --quiet --staged ; then echo No change to the website contents. Exiting without publishing.
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html index 80128cf..374e6a9 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html
@@ -21,4 +21,15 @@ test(t => { assert_element_accepts_trusted_url_set_ns(window, '3', t, 'a', 'b', RESULTS.URL); }, "Element.setAttributeNS assigned via policy (successful URL transformation)"); + + test(t => { + let p = createURL_policy(window, '5'); + let url = p.createURL(INPUTS.URL); + + let elem = document.createElementNS("http://www.w3.org/2000/svg", "image"); + elem.setAttributeNS("http://www.w3.org/1999/xlink", "href", url); + let attr_node = elem.getAttributeNodeNS("http://www.w3.org/1999/xlink", "href"); + assert_equals(attr_node.value + "", RESULTS.URL); + }, "Element.setAttributeNS accepts a URL on <svg:image xlink:href/>"); + </script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html index 3ad27e2..4bb9569 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html
@@ -25,11 +25,110 @@ assert_element_accepts_trusted_url_set_ns(window, '3', t, 'a', 'b', RESULTS.URL); }, "Element.setAttributeNS assigned via policy (successful URL transformation)"); + // Unknown, namespaced attributes should not be TT checked: test(t => { - assert_throws_no_trusted_type_set_ns('a', 'b', 'A string'); - }, "`Element.setAttributeNS = string` throws"); + assert_element_accepts_non_trusted_type_set_ns('a', 'b', 'A string', 'A string'); + }, "Element.setAttributeNS accepts untrusted string for non-specced accessor"); test(t => { - assert_throws_no_trusted_type_set_ns('a', 'b', null); - }, "`Element.setAttributeNS = null` throws"); + assert_element_accepts_non_trusted_type_set_ns('a', 'b', null, 'null'); + }, "Element.setAttributeNS accepts null for non-specced accessor"); + + // Setup trusted values for use in subsequent tests. + const url = createURL_policy(window, '4').createURL(INPUTS.URL); + const script_url = createScriptURL_policy(window, '5').createScriptURL(INPUTS.ScriptURL); + const html = createHTML_policy(window, '6').createHTML(INPUTS.HTML); + const script = createScript_policy(window, '7').createScript(INPUTS.Script); + + // SVG elements that use xlink:href (SVGURIReference) and that expect + // TrustedURL. + // There a number of affected elements, and there are several ways to set + // a namespaced attribute. Let's iterate over all combinations. + // TODO(vogelheim): Also SMIL timed elements. + const xlink = "http://www.w3.org/1999/xlink"; + const svg = "http://www.w3.org/2000/svg"; + const elems = [ "a", "feImage", "filter", "image", "linearGradient", + "mpath", "pattern", "radialGradient", "textPath", "use" ]; + + // There are multiple ways to set a namespaced attribute. Let's encapsulate + // each in a function. + const variants = { + "setAttributeNS with prefix": (element_name, value) => { + let elem = document.createElementNS(svg, element_name); + elem.setAttributeNS(xlink, "xlink:href", value); + return elem; + }, + "setAttributeNS without prefix": (element_name, value) => { + let elem = document.createElementNS(svg, element_name); + elem.setAttributeNS(xlink, "href", value); + return elem; + }, + "setAttribute with prefix": (element_name, value) => { + let elem = document.createElementNS(svg, element_name); + // Create the namespaced attribute with setAttributeNS. Then refer + // to it with the prefix in setAttribute. This test will break + // if either setAttributeNS or setAttribtue functionality it broken. + elem.setAttributeNS(xlink, "xlink:href", url); + elem.setAttribute("xlink:href", value); + return elem; + } + }; + for (const e of elems) { + for (const variant in variants) { + // Assigning a TrustedURL works. + test(t => { + let elem = variants[variant](e, url); + assert_equals("" + RESULTS.URL, + elem.getAttributeNodeNS(xlink, "href").value); + }, "Assigning TrustedURL to <svg:" + e + "> works via " + variant); + + // Assigning things that ought to not work. + const values = ["abc", null, script_url, html, script]; + values.forEach((value, index) => { + test(t => { + assert_throws(new TypeError(), _ => { variants[variant](e, value); }); + }, "Blocking non-TrustedURL assignment to <svg:" + e + "> via " + + variant + " value no " + index); + }); + } + } + + // Test 'synchronization' of 'xlink:href'. + test(t => { + // ..setAttribute("xlink:href") will behave differently, depending on + // whether the element already has an attribute by that name. Make sure + // that Trusted Type handling respects that difference. + + // Case 1: "xlink:href" on an empty element: This is an unknown attribute + // not processed by SVG, and string assignment should work. + let elem1 = document.createElementNS(svg, "a"); + elem1.setAttribute("xlink:href", "abc"); + + // Case 2: "xlink:href", after a namespaced attribute has been set: Now + // this mirrors the SVG attribute, and string assignment should fail. + let elem2 = document.createElementNS(svg, "a"); + elem2.setAttributeNS(xlink, "xlink:href", url); + assert_throws(new TypeError(), _ => { + elem2.setAttribute("xlink:href", "abc"); + }); + }, "Test synchronized, namespaced attributes."); + + // svg:script xlink:href=... expects a TrustedScriptURL. + let elem = document.createElementNS(svg, "script"); + // Assigning a TrustedScriptURL works. + test(t => { + elem.setAttributeNS(xlink, "href", script_url); + assert_equals("" + RESULTS.ScriptURL, + elem.getAttributeNodeNS(xlink, "href").value); + }, "Assigning TrustedScriptURL to <svg:script xlink:href=...> works"); + + // Assigning things that ought to not work. + test(t => { + const values = [ "abc", null, url, html, script ]; + for (const v of values) { + assert_throws(new TypeError(), _ => { + elem.setAttributeNS(xlink, "href", v); + }); + } + }, "Blocking non-TrustedScriptURL assignment to <svg:script xlink:href=...> works"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/websockets/remove-own-iframe-during-onerror.window.js b/third_party/blink/web_tests/external/wpt/websockets/remove-own-iframe-during-onerror.window.js new file mode 100644 index 0000000..55fa686c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/websockets/remove-own-iframe-during-onerror.window.js
@@ -0,0 +1,20 @@ +// META: script=websocket.sub.js + +async_test(t => { + window.wsurl = 'wss://' + __SERVER__NAME + ':' + __SECURE__PORT + + '/does-not-exist'; + let wsframe; + window.wsonerror = () => { + wsframe.remove(); + // If this didn't crash then the test passed. + t.done(); + }; + wsframe = document.createElement('iframe'); + wsframe.srcdoc = `<script> +const ws = new WebSocket(parent.wsurl); +ws.onerror = parent.wsonerror; +</script>`; + onload = () => document.body.appendChild(wsframe); +}, 'removing an iframe from within an onerror handler should work'); + +done();
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt index 105701e..4bff465 100644 --- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 217 tests; 209 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 202 tests; 198 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS Partial interface Navigator: original interface defined PASS Partial dictionary WebGLContextAttributes: original dictionary defined @@ -27,6 +27,7 @@ PASS XRSession interface: existence and properties of interface prototype object's "constructor" property PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property PASS XRSession interface: attribute environmentBlendMode +FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false PASS XRSession interface: attribute renderState PASS XRSession interface: attribute inputSources PASS XRSession interface: operation updateRenderState(XRRenderStateInit) @@ -34,13 +35,12 @@ PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) PASS XRSession interface: operation cancelAnimationFrame(long) PASS XRSession interface: operation end() -PASS XRSession interface: attribute onblur -PASS XRSession interface: attribute onfocus PASS XRSession interface: attribute onend PASS XRSession interface: attribute onselect PASS XRSession interface: attribute oninputsourceschange PASS XRSession interface: attribute onselectstart PASS XRSession interface: attribute onselectend +FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false PASS XRRenderState interface: existence and properties of interface object PASS XRRenderState interface object length PASS XRRenderState interface object name @@ -51,7 +51,6 @@ PASS XRRenderState interface: attribute depthFar PASS XRRenderState interface: attribute inlineVerticalFieldOfView PASS XRRenderState interface: attribute baseLayer -FAIL XRRenderState interface: attribute outputContext assert_true: The prototype object must have a property "outputContext" expected true got false PASS XRFrame interface: existence and properties of interface object PASS XRFrame interface object length PASS XRFrame interface object name @@ -154,19 +153,12 @@ PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property PASS XRInputSourceArray interface: iterable<XRInputSource> PASS XRInputSourceArray interface: attribute length -PASS XRLayer interface: existence and properties of interface object -PASS XRLayer interface object length -PASS XRLayer interface object name -PASS XRLayer interface: existence and properties of interface prototype object -PASS XRLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: existence and properties of interface object +FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" PASS XRWebGLLayer interface object length PASS XRWebGLLayer interface object name -PASS XRWebGLLayer interface: existence and properties of interface prototype object +FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context PASS XRWebGLLayer interface: attribute antialias PASS XRWebGLLayer interface: attribute ignoreDepthValues PASS XRWebGLLayer interface: attribute framebuffer @@ -174,13 +166,6 @@ PASS XRWebGLLayer interface: attribute framebufferHeight PASS XRWebGLLayer interface: operation getViewport(XRView) PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -FAIL XRPresentationContext interface: existence and properties of interface object assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing -FAIL XRPresentationContext interface object length assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing -FAIL XRPresentationContext interface object name assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing -FAIL XRPresentationContext interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing -FAIL XRPresentationContext interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing -FAIL XRPresentationContext interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing -FAIL XRPresentationContext interface: attribute canvas assert_own_property: self does not have own property "XRPresentationContext" expected property "XRPresentationContext" missing PASS XRSessionEvent interface: existence and properties of interface object PASS XRSessionEvent interface object length PASS XRSessionEvent interface object name
diff --git a/third_party/blink/web_tests/fast/animation/scroll-animations/animation-created-with-scroll-timeline.html b/third_party/blink/web_tests/fast/animation/scroll-animations/animation-created-with-scroll-timeline.html index 9429f62..c80c337 100644 --- a/third_party/blink/web_tests/fast/animation/scroll-animations/animation-created-with-scroll-timeline.html +++ b/third_party/blink/web_tests/fast/animation/scroll-animations/animation-created-with-scroll-timeline.html
@@ -1,14 +1,14 @@ <!DOCTYPE html> <meta charset="utf-8"> -<title>Test an Animation created with a ScrollTimeline doesn't crash</title> +<title>Test instantiating an Animation with a ScrollTimeline.</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> <script> -test(t => { - // We don't yet support ScrollTimeline, but creating an Animation object with - // one should not crash. - var timeline = new ScrollTimeline({ timeRange: 100, orientation: 'block' }); - assert_throws("NotSupportedError", function() { new Animation(null, timeline) }); -}, 'An Animation created with a ScrollTimeline should not crash'); + test(t => { + var scrollTimeline = new ScrollTimeline({ timeRange: 100, orientation: 'block' }); + var animationObject = new Animation(null, scrollTimeline); + assert_equals(animationObject.timeline, scrollTimeline, + "Animation timeline should be the ScrollTimeline passed in the constructor."); + }, 'Instantiating an Animation with a ScrollTimeline should be successful.'); </script>
diff --git a/third_party/blink/web_tests/fast/css/internal-properties-cssom.html b/third_party/blink/web_tests/fast/css/internal-properties-cssom.html new file mode 100644 index 0000000..c13f416 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/internal-properties-cssom.html
@@ -0,0 +1,110 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<style id="style"> + #color { + color: red; + } + #visited_color { + -internal-visited-color: red; + } + #visited_color:visited { + -internal-visited-color: red; + } + #zoom { + zoom: 2; + } + #effective_zoom { + -internal-effective-zoom: 4; + } +</style> +<div id="container"> + <a href="" id="color"></a> + <a href="" id="visited_color"></a> + <div id="zoom"></div> + <div id="effective_zoom"></div> +</div> +<script> + +const elements = Array.from(container.children); + +test(() => { + for (let element of elements) { + let names = Array.from(getComputedStyle(element)); + assert_true(names.every(x => !x.startsWith('-internal'))); + } +}, 'Internal properties do not appear in enumeration of computed style (CSSOM)'); + +test(() => { + for (let rule of style.sheet.cssRules) { + let names = Array.from(rule.style); + assert_true(names.every(x => !x.startsWith('-internal'))); + } +}, 'Internal properties do not appear in enumeration of specified style (CSSOM)'); + +test(() => { + for (let element of elements) { + let cs = getComputedStyle(element); + assert_equals(cs.getPropertyValue('-internal-visited-color'), ''); + assert_equals(cs['-internal-visited-color'], undefined); + assert_equals(cs.internalVisitedColor, undefined); + } +}, '-internal-visited-color does not appear on computed style (CSSOM)'); + +test(() => { + for (let rule of style.sheet.cssRules) { + assert_equals(rule.style.getPropertyValue('-internal-visited-color'), ''); + assert_equals(rule.style['-internal-visited-color'], undefined); + assert_equals(rule.style.internalVisitedColor, undefined); + } +}, '-internal-visited-color does not appear on specified style (CSSOM)'); + +test(() => { + for (let rule of style.sheet.cssRules) { + rule.style.setProperty('-internal-visited-color', 'red'); + assert_equals(rule.style.getPropertyValue('-internal-visited-color'), ''); + rule.style['-internal-visited-color'] = 'red'; + assert_equals(rule.style.getPropertyValue('-internal-visited-color'), ''); + } +}, '-internal-visited-color may not be set on specified style (CSSOM)'); + +test(() => { + for (let element of elements) { + let names = Array.from(element.computedStyleMap()).map(x => x[0]); + assert_true(names.every(x => !x.startsWith('-internal'))); + } +}, 'Internal properties do not appear in enumeration of computed style (CSS Typed OM)'); + +test(() => { + for (let rule of style.sheet.cssRules) { + let names = Array.from(rule.styleMap).map(x => x[0]); + assert_true(names.every(x => !x.startsWith('-internal'))); + } +}, 'Internal properties do not appear in enumeration of specified style (CSS Typed OM)'); + +test(() => { + for (let element of elements) { + let cs = element.computedStyleMap(); + assert_throws(new TypeError(), () => { + assert_equals(cs.get('-internal-visited-color'), ''); + }, 'get() should throw when attempting to access internal property'); + } +}, '-internal-visited-color does not appear on computed style (CSS Typed OM)'); + +test(() => { + for (let rule of style.sheet.cssRules) { + assert_throws(new TypeError(), () => { + assert_equals(rule.styleMap.get('-internal-visited-color'), ''); + }, 'get() should throw when attempting to access internal property'); + } +}, '-internal-visited-color does not appear on specified style (CSS Typed OM)'); + +test(() => { + for (let rule of style.sheet.cssRules) { + assert_throws(new TypeError(), () => { + assert_equals(rule.styleMap.set('-internal-visited-color'), 'red'); + }, 'set() should throw when attempting to access internal property'); + } +}, '-internal-visited-color may not be set on specified style (CSS Typed OM)'); + +</script>
diff --git a/third_party/blink/web_tests/fast/css/internal-properties-painting-expected.html b/third_party/blink/web_tests/fast/css/internal-properties-painting-expected.html new file mode 100644 index 0000000..23684c3 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/internal-properties-painting-expected.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<div> + <a>Should not be red</a><br> + <a href="">Should not be red</a><br> + <a href="">Should not be red</a><br> + <span>Should be default font-size</span> +</div> +<script> + let div = document.querySelector('div'); + document.body.append(div.cloneNode(true), div.cloneNode(true)); +</script>
diff --git a/third_party/blink/web_tests/fast/css/internal-properties-painting.html b/third_party/blink/web_tests/fast/css/internal-properties-painting.html new file mode 100644 index 0000000..d050a73 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/internal-properties-painting.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<style> + .class { + -internal-visited-color: red; + } + .visited_color:visited { + -internal-visited-color: red; + } + .effective_zoom { + -internal-effective-zoom: 4; + } +</style> +<div> + <a class="color">Should not be red</a><br> + <a href="" class="color">Should not be red</a><br> + <a href="" class="visited_color">Should not be red</a><br> + <span class="effective_zoom">Should be default font-size</span> +</div> +<script> + let div = document.querySelector('div'); + + // CSSOM: + let cssom_div = div.cloneNode(true); + for (let e of cssom_div.querySelectorAll('.color')) + e.style.setProperty('-internal-visited-color', 'red'); + for (let e of cssom_div.querySelectorAll('.visited_color')) + e.style.setProperty('-internal-visited-color', 'red'); + for (let e of cssom_div.querySelectorAll('.effective_zoom')) + e.style.setProperty('-internal-effective-zoom', '4'); + + // CSS Typed OM: + let css_typed_om_div = div.cloneNode(true); + let set_silently = (elm, name, value) => { + try { + elm.attributeStyleMap.set(name, value); + } catch (e) { + } + }; + for (let e of css_typed_om_div.querySelectorAll('.color')) + set_silently(e, '-internal-visited-color', 'red'); + for (let e of css_typed_om_div.querySelectorAll('.visited_color')) + set_silently(e, '-internal-visited-color', 'red'); + for (let e of css_typed_om_div.querySelectorAll('.effective_zoom')) + set_silently(e, '-internal-effective-zoom', '4'); + + document.body.append(cssom_div, css_typed_om_div); +</script>
diff --git a/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port-expected.txt b/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port-expected.txt index 7b8f0af..1ccd6b4 100644 --- a/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port-expected.txt +++ b/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port-expected.txt
@@ -13,7 +13,7 @@ Set port to null PASS a.href is 'https://www.mydomain.com:0/path/testurl.html?key=value' Set port to empty string -PASS a.href is 'https://www.mydomain.com:0/path/testurl.html?key=value' +PASS a.href is 'https://www.mydomain.com/path/testurl.html?key=value' Set port to undefined PASS a.href is 'https://www.mydomain.com:0/path/testurl.html?key=value' Set port to URL with foo: protocol
diff --git a/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port.html b/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port.html index f297331b..6149ddc5 100644 --- a/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port.html +++ b/third_party/blink/web_tests/fast/dom/HTMLAnchorElement/set-href-attribute-port.html
@@ -40,7 +40,7 @@ debug("Set port to empty string"); a.href = "https://www.mydomain.com:8080/path/testurl.html?key=value"; a.port = ""; -shouldBe("a.href", "'https://www.mydomain.com:0/path/testurl.html?key=value'"); +shouldBe("a.href", "'https://www.mydomain.com/path/testurl.html?key=value'"); debug("Set port to undefined"); a.href = "https://www.mydomain.com:8080/path/testurl.html?key=value";
diff --git a/third_party/blink/web_tests/fast/domurl/url-port.html b/third_party/blink/web_tests/fast/domurl/url-port.html index 550bb4f..77ac3c1 100644 --- a/third_party/blink/web_tests/fast/domurl/url-port.html +++ b/third_party/blink/web_tests/fast/domurl/url-port.html
@@ -15,7 +15,7 @@ assert_equals(url.port, '8081'); url.port = ''; - assert_equals(url.port, '0'); + assert_equals(url.port, ''); url.port = 80; assert_equals(url.port, '');
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 9ea2b99..8b2f5f2 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -2076,6 +2076,7 @@ method disable method disableVertexAttribArray method dispatchCompute + method dispatchComputeIndirect method drawArrays method drawArraysInstanced method drawBuffers
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt index fd516ea..c8bea77 100644 --- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 592 tests; 296 PASS, 296 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 592 tests; 299 PASS, 293 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS URL: Setting <a://example.net>.protocol = '' The empty string is not a valid scheme. Setter leaves the URL unchanged. PASS <a>: Setting <a://example.net>.protocol = '' The empty string is not a valid scheme. Setter leaves the URL unchanged. @@ -427,9 +427,9 @@ PASS URL: Setting <http://example.net>.port = '8080' PASS <a>: Setting <http://example.net>.port = '8080' PASS <area>: Setting <http://example.net>.port = '8080' -FAIL URL: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" -FAIL <a>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" -FAIL <area>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" +PASS URL: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value +PASS <a>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value +PASS <area>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value PASS URL: Setting <http://example.net:8080>.port = '80' Default port number is removed PASS <a>: Setting <http://example.net:8080>.port = '80' Default port number is removed PASS <area>: Setting <http://example.net:8080>.port = '80' Default port number is removed
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/linux/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-retina/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/mac-retina/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/mac-retina/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt index fd516ea..c8bea77 100644 --- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 592 tests; 296 PASS, 296 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 592 tests; 299 PASS, 293 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS URL: Setting <a://example.net>.protocol = '' The empty string is not a valid scheme. Setter leaves the URL unchanged. PASS <a>: Setting <a://example.net>.protocol = '' The empty string is not a valid scheme. Setter leaves the URL unchanged. @@ -427,9 +427,9 @@ PASS URL: Setting <http://example.net>.port = '8080' PASS <a>: Setting <http://example.net>.port = '8080' PASS <area>: Setting <http://example.net>.port = '8080' -FAIL URL: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" -FAIL <a>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" -FAIL <area>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" +PASS URL: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value +PASS <a>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value +PASS <area>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value PASS URL: Setting <http://example.net:8080>.port = '80' Default port number is removed PASS <a>: Setting <http://example.net:8080>.port = '80' Default port number is removed PASS <area>: Setting <http://example.net:8080>.port = '80' Default port number is removed
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt index 7b91a90..91788be4 100644 --- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 592 tests; 269 PASS, 323 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 592 tests; 272 PASS, 320 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… FAIL URL: Setting <a://example.net>.protocol = '' The empty string is not a valid scheme. Setter leaves the URL unchanged. assert_equals: expected "a://example.net" but got "file:///A://example.net" FAIL <a>: Setting <a://example.net>.protocol = '' The empty string is not a valid scheme. Setter leaves the URL unchanged. assert_equals: expected "a://example.net" but got "file:///A://example.net" @@ -427,9 +427,9 @@ PASS URL: Setting <http://example.net>.port = '8080' PASS <a>: Setting <http://example.net>.port = '8080' PASS <area>: Setting <http://example.net>.port = '8080' -FAIL URL: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" -FAIL <a>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" -FAIL <area>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value assert_equals: expected "http://example.net/" but got "http://example.net:0/" +PASS URL: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value +PASS <a>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value +PASS <area>: Setting <http://example.net:8080>.port = '' Port number is removed if empty is the new value PASS URL: Setting <http://example.net:8080>.port = '80' Default port number is removed PASS <a>: Setting <http://example.net:8080>.port = '80' Default port number is removed PASS <area>: Setting <http://example.net:8080>.port = '80' Default port number is removed
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/webxr/idlharness.https.window-expected.txt deleted file mode 100644 index e750790..0000000 --- a/third_party/blink/web_tests/platform/win7/external/wpt/webxr/idlharness.https.window-expected.txt +++ /dev/null
@@ -1,207 +0,0 @@ -This is a testharness.js-based test. -Found 203 tests; 199 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idl_test setup -PASS Partial interface Navigator: original interface defined -PASS Partial dictionary WebGLContextAttributes: original dictionary defined -PASS Partial interface mixin WebGLRenderingContextBase: original interface mixin defined -PASS XR interface: existence and properties of interface object -PASS XR interface object length -PASS XR interface object name -PASS XR interface: existence and properties of interface prototype object -PASS XR interface: existence and properties of interface prototype object's "constructor" property -PASS XR interface: existence and properties of interface prototype object's @@unscopables property -PASS XR interface: operation supportsSession(XRSessionMode) -PASS XR interface: operation requestSession(XRSessionMode) -PASS XR interface: attribute ondevicechange -PASS XR must be primary interface of navigator.xr -PASS Stringification of navigator.xr -PASS XR interface: navigator.xr must inherit property "supportsSession(XRSessionMode)" with the proper type -PASS XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "requestSession(XRSessionMode)" with the proper type -PASS XR interface: calling requestSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError -PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type -PASS XRSession interface: existence and properties of interface object -PASS XRSession interface object length -PASS XRSession interface object name -PASS XRSession interface: existence and properties of interface prototype object -PASS XRSession interface: existence and properties of interface prototype object's "constructor" property -PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSession interface: attribute environmentBlendMode -FAIL XRSession interface: attribute visibilityState assert_true: The prototype object must have a property "visibilityState" expected true got false -PASS XRSession interface: attribute renderState -PASS XRSession interface: attribute inputSources -PASS XRSession interface: operation updateRenderState(XRRenderStateInit) -PASS XRSession interface: operation requestReferenceSpace(XRReferenceSpaceType) -PASS XRSession interface: operation requestAnimationFrame(XRFrameRequestCallback) -PASS XRSession interface: operation cancelAnimationFrame(long) -PASS XRSession interface: operation end() -PASS XRSession interface: attribute onend -PASS XRSession interface: attribute onselect -PASS XRSession interface: attribute oninputsourceschange -PASS XRSession interface: attribute onselectstart -PASS XRSession interface: attribute onselectend -FAIL XRSession interface: attribute onvisibilitychange assert_true: The prototype object must have a property "onvisibilitychange" expected true got false -PASS XRRenderState interface: existence and properties of interface object -PASS XRRenderState interface object length -PASS XRRenderState interface object name -PASS XRRenderState interface: existence and properties of interface prototype object -PASS XRRenderState interface: existence and properties of interface prototype object's "constructor" property -PASS XRRenderState interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRenderState interface: attribute depthNear -PASS XRRenderState interface: attribute depthFar -PASS XRRenderState interface: attribute inlineVerticalFieldOfView -PASS XRRenderState interface: attribute baseLayer -PASS XRFrame interface: existence and properties of interface object -PASS XRFrame interface object length -PASS XRFrame interface object name -PASS XRFrame interface: existence and properties of interface prototype object -PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property -PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property -PASS XRFrame interface: attribute session -PASS XRFrame interface: operation getViewerPose(XRReferenceSpace) -PASS XRFrame interface: operation getPose(XRSpace, XRSpace) -PASS XRSpace interface: existence and properties of interface object -PASS XRSpace interface object length -PASS XRSpace interface object name -PASS XRSpace interface: existence and properties of interface prototype object -PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: existence and properties of interface object -PASS XRReferenceSpace interface object length -PASS XRReferenceSpace interface object name -PASS XRReferenceSpace interface: existence and properties of interface prototype object -PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpace interface: operation getOffsetReferenceSpace(XRRigidTransform) -PASS XRReferenceSpace interface: attribute onreset -PASS XRBoundedReferenceSpace interface: existence and properties of interface object -PASS XRBoundedReferenceSpace interface object length -PASS XRBoundedReferenceSpace interface object name -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property -PASS XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property -PASS XRBoundedReferenceSpace interface: attribute boundsGeometry -PASS XRView interface: existence and properties of interface object -PASS XRView interface object length -PASS XRView interface object name -PASS XRView interface: existence and properties of interface prototype object -PASS XRView interface: existence and properties of interface prototype object's "constructor" property -PASS XRView interface: existence and properties of interface prototype object's @@unscopables property -PASS XRView interface: attribute eye -PASS XRView interface: attribute projectionMatrix -PASS XRView interface: attribute transform -PASS XRViewport interface: existence and properties of interface object -PASS XRViewport interface object length -PASS XRViewport interface object name -PASS XRViewport interface: existence and properties of interface prototype object -PASS XRViewport interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewport interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewport interface: attribute x -PASS XRViewport interface: attribute y -PASS XRViewport interface: attribute width -PASS XRViewport interface: attribute height -PASS XRRigidTransform interface: existence and properties of interface object -PASS XRRigidTransform interface object length -PASS XRRigidTransform interface object name -PASS XRRigidTransform interface: existence and properties of interface prototype object -PASS XRRigidTransform interface: existence and properties of interface prototype object's "constructor" property -PASS XRRigidTransform interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRigidTransform interface: attribute position -PASS XRRigidTransform interface: attribute orientation -PASS XRRigidTransform interface: attribute matrix -PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix -PASS XRPose interface: existence and properties of interface object -PASS XRPose interface object length -PASS XRPose interface object name -PASS XRPose interface: existence and properties of interface prototype object -PASS XRPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRPose interface: attribute transform -PASS XRPose interface: attribute emulatedPosition -PASS XRViewerPose interface: existence and properties of interface object -PASS XRViewerPose interface object length -PASS XRViewerPose interface object name -PASS XRViewerPose interface: existence and properties of interface prototype object -PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property -PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property -PASS XRViewerPose interface: attribute views -PASS XRInputSource interface: existence and properties of interface object -PASS XRInputSource interface object length -PASS XRInputSource interface object name -PASS XRInputSource interface: existence and properties of interface prototype object -PASS XRInputSource interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSource interface: attribute handedness -PASS XRInputSource interface: attribute targetRayMode -PASS XRInputSource interface: attribute targetRaySpace -PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad -PASS XRInputSourceArray interface: existence and properties of interface object -PASS XRInputSourceArray interface object length -PASS XRInputSourceArray interface object name -PASS XRInputSourceArray interface: existence and properties of interface prototype object -PASS XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceArray interface: iterable<XRInputSource> -PASS XRInputSourceArray interface: attribute length -FAIL XRWebGLLayer interface: existence and properties of interface object assert_equals: prototype of self's property "XRWebGLLayer" is not Function.prototype expected function "function () { [native code] }" but got function "function XRLayer() { [native code] }" -PASS XRWebGLLayer interface object length -PASS XRWebGLLayer interface object name -FAIL XRWebGLLayer interface: existence and properties of interface prototype object assert_equals: prototype of XRWebGLLayer.prototype is not Object.prototype expected object "[object Object]" but got object "[object XRLayer]" -PASS XRWebGLLayer interface: existence and properties of interface prototype object's "constructor" property -PASS XRWebGLLayer interface: existence and properties of interface prototype object's @@unscopables property -PASS XRWebGLLayer interface: attribute context -PASS XRWebGLLayer interface: attribute antialias -PASS XRWebGLLayer interface: attribute ignoreDepthValues -PASS XRWebGLLayer interface: attribute framebuffer -PASS XRWebGLLayer interface: attribute framebufferWidth -PASS XRWebGLLayer interface: attribute framebufferHeight -PASS XRWebGLLayer interface: operation getViewport(XRView) -PASS XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession) -PASS XRSessionEvent interface: existence and properties of interface object -PASS XRSessionEvent interface object length -PASS XRSessionEvent interface object name -PASS XRSessionEvent interface: existence and properties of interface prototype object -PASS XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRSessionEvent interface: attribute session -PASS XRInputSourceEvent interface: existence and properties of interface object -PASS XRInputSourceEvent interface object length -PASS XRInputSourceEvent interface object name -PASS XRInputSourceEvent interface: existence and properties of interface prototype object -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourceEvent interface: attribute frame -PASS XRInputSourceEvent interface: attribute inputSource -PASS XRInputSourceEvent interface: attribute buttonIndex -PASS XRInputSourcesChangeEvent interface: existence and properties of interface object -PASS XRInputSourcesChangeEvent interface object length -PASS XRInputSourcesChangeEvent interface object name -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRInputSourcesChangeEvent interface: attribute session -PASS XRInputSourcesChangeEvent interface: attribute added -PASS XRInputSourcesChangeEvent interface: attribute removed -PASS XRReferenceSpaceEvent interface: existence and properties of interface object -PASS XRReferenceSpaceEvent interface object length -PASS XRReferenceSpaceEvent interface object name -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property -PASS XRReferenceSpaceEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS XRReferenceSpaceEvent interface: attribute referenceSpace -PASS XRReferenceSpaceEvent interface: attribute transform -PASS WebGLRenderingContext interface: operation makeXRCompatible() -PASS Navigator interface: attribute xr -PASS Navigator interface: navigator must inherit property "xr" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/serial/resources/serial-test-utils.js b/third_party/blink/web_tests/serial/resources/serial-test-utils.js index b0670bf..b2676e53 100644 --- a/third_party/blink/web_tests/serial/resources/serial-test-utils.js +++ b/third_party/blink/web_tests/serial/resources/serial-test-utils.js
@@ -63,10 +63,10 @@ let fakeSerialService = new FakeSerialService(); function serial_test(func, name, properties) { - promise_test(async () => { + promise_test(async (test) => { fakeSerialService.start(); try { - await func(fakeSerialService); + await func(test, fakeSerialService); } finally { fakeSerialService.stop(); fakeSerialService.reset();
diff --git a/third_party/blink/web_tests/serial/serial_getPorts.html b/third_party/blink/web_tests/serial/serial_getPorts.html index 08c9c5e..9657252 100644 --- a/third_party/blink/web_tests/serial/serial_getPorts.html +++ b/third_party/blink/web_tests/serial/serial_getPorts.html
@@ -19,7 +19,7 @@ interceptor.stop(); }, 'getPorts() returns empty list if Mojo service connection fails'); -serial_test(async (fake) => { +serial_test(async (t, fake) => { fake.addPort(); fake.addPort(); @@ -30,7 +30,7 @@ // TODO: Assert that product IDs (if provided) are passed through. }, 'getPorts() returns the set of configured fake ports'); -serial_test(async (fake) => { +serial_test(async (t, fake) => { fake.addPort(); let portsFirst = await navigator.serial.getPorts();
diff --git a/third_party/blink/web_tests/serial/serial_requestPort.html b/third_party/blink/web_tests/serial/serial_requestPort.html index 5abed21..5d40cc9 100644 --- a/third_party/blink/web_tests/serial/serial_requestPort.html +++ b/third_party/blink/web_tests/serial/serial_requestPort.html
@@ -10,43 +10,30 @@ <script src="resources/serial-test-utils.js"></script> <script> -promise_test(async () => { - try { - let port = await navigator.serial.requestPort({}); - assert_unreached(); - } catch (e) { - assert_equals(e.code, DOMException.SECURITY_ERR); - } +promise_test((t) => { + return promise_rejects(t, 'SecurityError', navigator.serial.requestPort({})); }, 'requestPort() rejects without a user gesture'); -promise_test(async () => { +promise_test(async (t) => { let interceptor = new MojoInterfaceInterceptor(blink.mojom.SerialService.name); interceptor.oninterfacerequest = e => e.handle.close(); interceptor.start(); + await trustedClick(); try { - await trustedClick(); - let port = await navigator.serial.requestPort({}); - assert_unreached(); - } catch (e) { - assert_equals(e.code, DOMException.NOT_FOUND_ERR); + await promise_rejects(t, 'NotFoundError', navigator.serial.requestPort({})); } finally { interceptor.stop(); } }, 'requestPort() rejects if Mojo service connection fails'); -serial_test(async (fake) => { - try { - await trustedClick(); - let port = await navigator.serial.requestPort({}); - assert_unreached(); - } catch (e) { - assert_equals(e.code, DOMException.NOT_FOUND_ERR); - } +serial_test(async (t, fake) => { + await trustedClick(); + return promise_rejects(t, 'NotFoundError', navigator.serial.requestPort({})); }, 'requestPort() rejects if no port has been selected'); -serial_test(async (fake) => { +serial_test(async (t, fake) => { let guid = fake.addPort(); fake.setSelectedPort(guid); @@ -56,7 +43,7 @@ // TODO: Assert that product IDs (if provided) are passed through. }, 'requestPort() returns the selected port'); -serial_test(async (fake) => { +serial_test(async (t, fake) => { let guid = fake.addPort(); fake.setSelectedPort(guid);
diff --git a/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-dont-interest-body.html b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-dont-interest-body.html new file mode 100644 index 0000000..eeb3f12 --- /dev/null +++ b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-dont-interest-body.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<script src="../../../../../resources/testharness.js"></script> +<script src="../../../../../resources/testharnessreport.js"></script> +<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="file:///gen/third_party/blink/public/mojom/page/spatial_navigation.mojom.js"></script> +<script src="../../../../../fast/spatial-navigation/resources/mock-snav-service.js"></script> +<script src="../../../../../fast/spatial-navigation/resources/snav-testharness.js"></script> + +<body> +<button id="button" autofocus>button</button> + +<script> + let button = document.getElementById("button"); + let initialState = snavCallback(); + + promise_test(async () => { + await snav.rAF(); + assert_equals(document.activeElement, + button, + "'button' should start focused."); + assert_equals(window.internals.interestedElement, + button, + "'button' should start interested."); + + await initialState; + assert_true(mockSnavService.canExitFocus, + "Should be able to exit focus."); + assert_true(mockSnavService.canSelectElement, + "Should be able to select element."); + + document.activeElement.blur() + await snavCallback(); + assert_equals(document.activeElement, + document.body, + "'body' should be focused."); + assert_equals(window.internals.interestedElement, + button, + "'button' should still be interested."); + assert_false(mockSnavService.canExitFocus, + "Should not be able to exit focus."); + assert_true(mockSnavService.canSelectElement, + "Should be able to select element."); + + }, 'Spat Nav does not pass interest to the body.'); +</script> +</body>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 353c3ee7..2b607e5 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -2121,6 +2121,7 @@ [Worker] method disable [Worker] method disableVertexAttribArray [Worker] method dispatchCompute +[Worker] method dispatchComputeIndirect [Worker] method drawArrays [Worker] method drawArraysInstanced [Worker] method drawBuffers
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 4f43ebf..eb0f3ffb 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -8882,6 +8882,7 @@ method disable method disableVertexAttribArray method dispatchCompute + method dispatchComputeIndirect method drawArrays method drawArraysInstanced method drawBuffers
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index 42307e0..b64fb764 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -1985,6 +1985,7 @@ [Worker] method disable [Worker] method disableVertexAttribArray [Worker] method dispatchCompute +[Worker] method dispatchComputeIndirect [Worker] method drawArrays [Worker] method drawArraysInstanced [Worker] method drawBuffers
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index f3ee185..4d64817 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Short Name: crashpad URL: https://crashpad.chromium.org/ Version: unknown -Revision: e0e83ad18af41dba0ae10e0204193ec9074aeb2a +Revision: de22b8d05097b82166866ca16abecbd168bfd7c9 License: Apache 2.0 License File: crashpad/LICENSE Security Critical: yes
diff --git a/third_party/crashpad/crashpad/client/crashpad_info.h b/third_party/crashpad/crashpad/client/crashpad_info.h index 5db9a6c..4c1633f 100644 --- a/third_party/crashpad/crashpad/client/crashpad_info.h +++ b/third_party/crashpad/crashpad/client/crashpad_info.h
@@ -208,7 +208,7 @@ //! Note that streams will appear in the minidump in the reverse order to //! which they are added. //! - //! TODO(scottmg) This is currently only supported on Windows. + //! TODO(scottmg) This is currently not supported on Mac. //! //! \param[in] stream_type The stream type identifier to use. This should be //! normally be larger than `MINIDUMP_STREAM_TYPE::LastReservedStream`
diff --git a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc index 34bed289..3ad071a9 100644 --- a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc +++ b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc
@@ -90,23 +90,13 @@ return false; } - return HandleExceptionHandles( - process, thread, exception_port, local_report_id); -} - -bool CrashReportExceptionHandler::HandleExceptionHandles( - const zx::process& process, - const zx::thread& thread, - const zx::unowned_port& exception_port, - UUID* local_report_id) { ScopedThreadResumeAfterException resume(thread, exception_port); return HandleException(process, thread, local_report_id); } -bool CrashReportExceptionHandler::HandleException( - const zx::process& process, - const zx::thread& thread, - UUID* local_report_id) { +bool CrashReportExceptionHandler::HandleException(const zx::process& process, + const zx::thread& thread, + UUID* local_report_id) { ScopedTaskSuspend suspend(process); ProcessSnapshotFuchsia process_snapshot;
diff --git a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h index 57afe7d..d913dc38 100644 --- a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h +++ b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h
@@ -84,8 +84,6 @@ //! \param[out] local_report_id The unique identifier for the report created //! in the local report database. Optional. //! \return `true` on success, or `false` with an error logged. - //! - //! \deprecated Use the port-less version instead and have the caller resume. bool HandleException(uint64_t process_id, uint64_t thread_id, const zx::unowned_port& exception_port, @@ -94,28 +92,6 @@ //! \brief Called when the exception handler server has caught an exception //! and wants a crash dump to be taken. //! - //! This function is expected to call `zx_task_resume_from_exception()` in - //! order to complete handling of the exception. - //! - //! \param[in] process The handle to the process which sustained the - //! exception. - //! \param[in] thread The handle to the thread of \a process which sustained - //! the exception. - //! \param[in] exception_port The exception port on which the exception was - //! serviced. This can be used to resume the excepting thread. - //! \param[out] local_report_id The unique identifier for the report created - //! in the local report database. Optional. - //! \return `true` on success, or `false` with an error logged. - //! - //! \deprecated Use the port-less #HandleException instead. - bool HandleExceptionHandles(const zx::process& process, - const zx::thread& thread, - const zx::unowned_port& exception_port, - UUID* local_report_id = nullptr); - - //! \brief Called when the exception handler server has caught an exception - //! and wants a crash dump to be taken. - //! //! \param[in] process The handle to the process which sustained the //! exception. //! \param[in] thread The handle to the thread of \a process which sustained
diff --git a/third_party/crashpad/crashpad/snapshot/BUILD.gn b/third_party/crashpad/crashpad/snapshot/BUILD.gn index 25805c2..ae5b9ce 100644 --- a/third_party/crashpad/crashpad/snapshot/BUILD.gn +++ b/third_party/crashpad/crashpad/snapshot/BUILD.gn
@@ -170,8 +170,6 @@ "win/exception_snapshot_win.h", "win/memory_map_region_snapshot_win.cc", "win/memory_map_region_snapshot_win.h", - "win/memory_snapshot_win.cc", - "win/memory_snapshot_win.h", "win/module_snapshot_win.cc", "win/module_snapshot_win.h", "win/pe_image_annotations_reader.cc",
diff --git a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.cc b/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.cc index cfe07dd..037e7cd 100644 --- a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.cc +++ b/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.cc
@@ -20,6 +20,7 @@ #include "base/files/file_path.h" #include "snapshot/crashpad_types/image_annotation_reader.h" +#include "snapshot/memory_snapshot_generic.h" #include "util/misc/elf_note_types.h" namespace crashpad { @@ -28,14 +29,17 @@ ModuleSnapshotElf::ModuleSnapshotElf(const std::string& name, ElfImageReader* elf_reader, ModuleSnapshot::ModuleType type, - ProcessMemoryRange* process_memory_range) + ProcessMemoryRange* process_memory_range, + const ProcessMemory* process_memory) : ModuleSnapshot(), name_(name), elf_reader_(elf_reader), process_memory_range_(process_memory_range), + process_memory_(process_memory), crashpad_info_(), type_(type), - initialized_() {} + initialized_(), + streams_() {} ModuleSnapshotElf::~ModuleSnapshotElf() = default; @@ -216,7 +220,33 @@ std::vector<const UserMinidumpStream*> ModuleSnapshotElf::CustomMinidumpStreams() const { - return std::vector<const UserMinidumpStream*>(); + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + streams_.clear(); + + std::vector<const UserMinidumpStream*> result; + if (!crashpad_info_) + return result; + + for (uint64_t cur = crashpad_info_->UserDataMinidumpStreamHead(); cur;) { + internal::UserDataMinidumpStreamListEntry list_entry; + if (!process_memory_->Read(cur, sizeof(list_entry), &list_entry)) { + LOG(WARNING) << "could not read user data stream entry from " << name_; + return result; + } + + if (list_entry.size != 0) { + auto memory = std::make_unique<internal::MemorySnapshotGeneric>(); + memory->Initialize( + process_memory_, list_entry.base_address, list_entry.size); + streams_.push_back(std::make_unique<UserMinidumpStream>( + list_entry.stream_type, memory.release())); + result.push_back(streams_.back().get()); + } + + cur = list_entry.next; + } + + return result; } } // namespace internal
diff --git a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.h b/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.h index be27242..67ecdf7 100644 --- a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.h +++ b/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.h
@@ -41,11 +41,15 @@ //! \param[in] name The pathname used to load the module from disk. //! \param[in] elf_reader An image reader for the module. //! \param[in] type The module's type. - //! \param[in] process_memory_range A memory reader for the target process. + //! \param[in] process_memory_range A memory reader giving protected access + //! to the target process. + //! \param[in] process_memory A memory reader for the target process which can + //! be used to initialize a MemorySnapshot. ModuleSnapshotElf(const std::string& name, ElfImageReader* elf_reader, ModuleSnapshot::ModuleType type, - ProcessMemoryRange* process_memory_range); + ProcessMemoryRange* process_memory_range, + const ProcessMemory* process_memory); ~ModuleSnapshotElf() override; //! \brief Initializes the object. @@ -88,9 +92,12 @@ std::string name_; ElfImageReader* elf_reader_; ProcessMemoryRange* process_memory_range_; + const ProcessMemory* process_memory_; std::unique_ptr<CrashpadInfoReader> crashpad_info_; ModuleType type_; InitializationStateDcheck initialized_; + // Too const-y: https://crashpad.chromium.org/bug/9. + mutable std::vector<std::unique_ptr<const UserMinidumpStream>> streams_; DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotElf); };
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc b/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc index 9ae414e..1ff758d1 100644 --- a/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc +++ b/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc
@@ -223,7 +223,8 @@ std::make_unique<internal::ModuleSnapshotElf>(reader_module.name, reader_module.reader, reader_module.type, - &memory_range_); + &memory_range_, + process_reader_.Memory()); if (module->Initialize()) { modules_.push_back(std::move(module)); }
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc b/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc index b3a4cec..462cdb1f 100644 --- a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc +++ b/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc
@@ -52,9 +52,9 @@ #endif if (thread.stack_regions.empty()) { - stack_.Initialize(process_reader, 0, 0); + stack_.Initialize(process_reader->Memory(), 0, 0); } else { - stack_.Initialize(process_reader, + stack_.Initialize(process_reader->Memory(), thread.stack_regions[0].base(), thread.stack_regions[0].size()); // TODO(scottmg): Handle split stack by adding other parts to ExtraMemory().
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h b/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h index db975976..45d4f11 100644 --- a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h +++ b/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h
@@ -67,7 +67,7 @@ #error Port. #endif CPUContext context_; - MemorySnapshotGeneric<ProcessReaderFuchsia> stack_; + MemorySnapshotGeneric stack_; zx_koid_t thread_id_; zx_vaddr_t thread_specific_data_address_; InitializationStateDcheck initialized_;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc index bd95ac7..bada3a9 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc
@@ -273,7 +273,8 @@ std::make_unique<internal::ModuleSnapshotElf>(reader_module.name, reader_module.elf_reader, reader_module.type, - &memory_range_); + &memory_range_, + process_reader_.Memory()); if (module->Initialize()) { modules_.push_back(std::move(module)); }
diff --git a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc index f40c78e..e3e2beb 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
@@ -190,8 +190,9 @@ #error Port. #endif - stack_.Initialize( - process_reader, thread.stack_region_address, thread.stack_region_size); + stack_.Initialize(process_reader->Memory(), + thread.stack_region_address, + thread.stack_region_size); thread_specific_data_address_ = thread.thread_info.thread_specific_data_address;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h index 17e471f..44cc6f6d 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h +++ b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
@@ -73,7 +73,7 @@ #endif // ARCH_CPU_X86_FAMILY } context_union_; CPUContext context_; - MemorySnapshotGeneric<ProcessReaderLinux> stack_; + MemorySnapshotGeneric stack_; LinuxVMAddress thread_specific_data_address_; pid_t thread_id_; int priority_;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc index f45fc41..8fbb3e7 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc
@@ -49,7 +49,7 @@ thread_specific_data_address_ = process_reader_thread.thread_specific_data_address; - stack_.Initialize(process_reader, + stack_.Initialize(process_reader->Memory(), process_reader_thread.stack_region_address, process_reader_thread.stack_region_size);
diff --git a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h index 8f5d722..946b008 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h +++ b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h
@@ -70,7 +70,7 @@ } context_union_; #endif CPUContext context_; - MemorySnapshotGeneric<ProcessReaderMac> stack_; + MemorySnapshotGeneric stack_; uint64_t thread_id_; uint64_t thread_specific_data_address_; thread_t thread_;
diff --git a/third_party/crashpad/crashpad/snapshot/memory_snapshot.h b/third_party/crashpad/crashpad/snapshot/memory_snapshot.h index 9e274a0e..5dbac5a 100644 --- a/third_party/crashpad/crashpad/snapshot/memory_snapshot.h +++ b/third_party/crashpad/crashpad/snapshot/memory_snapshot.h
@@ -111,31 +111,6 @@ const MemorySnapshot* b, CheckedRange<uint64_t, size_t>* merged); -namespace internal { - -//! \brief A standard implementation of MemorySnapshot::MergeWithOtherSnapshot() -//! for concrete MemorySnapshot implementations that use a -//! `process_reader_`. -template <class T> -const MemorySnapshot* MergeWithOtherSnapshotImpl(const T* self, - const MemorySnapshot* other) { - const T* other_as_memory_snapshot_concrete = - reinterpret_cast<const T*>(other); - if (self->process_reader_ != - other_as_memory_snapshot_concrete->process_reader_) { - LOG(ERROR) << "different process_reader_ for snapshots"; - return nullptr; - } - CheckedRange<uint64_t, size_t> merged(0, 0); - if (!LoggingDetermineMergedRange(self, other, &merged)) - return nullptr; - - std::unique_ptr<T> result(new T()); - result->Initialize(self->process_reader_, merged.base(), merged.size()); - return result.release(); -} - -} // namespace internal } // namespace crashpad #endif // CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_
diff --git a/third_party/crashpad/crashpad/snapshot/memory_snapshot_generic.h b/third_party/crashpad/crashpad/snapshot/memory_snapshot_generic.h index 402e913..1a74d4e4 100644 --- a/third_party/crashpad/crashpad/snapshot/memory_snapshot_generic.h +++ b/third_party/crashpad/crashpad/snapshot/memory_snapshot_generic.h
@@ -19,6 +19,7 @@ #include <sys/types.h> #include "base/macros.h" +#include "base/numerics/safe_math.h" #include "snapshot/memory_snapshot.h" #include "util/misc/address_types.h" #include "util/misc/initialization_state_dcheck.h" @@ -30,7 +31,6 @@ //! \brief A MemorySnapshot of a memory region in a process on the running //! system. Used on Mac, Linux, Android, and Fuchsia, templated on the //! platform-specific ProcessReader type. -template <class ProcessReaderType> class MemorySnapshotGeneric final : public MemorySnapshot { public: MemorySnapshotGeneric() = default; @@ -42,25 +42,25 @@ //! until Read() is called, and the memory snapshot data is discared when //! Read() returns. //! - //! \param[in] process_reader A reader for the process being snapshotted. + //! \param[in] process_memory A reader for the process being snapshotted. //! \param[in] address The base address of the memory region to snapshot, in //! the snapshot process’ address space. //! \param[in] size The size of the memory region to snapshot. - void Initialize(ProcessReaderType* process_reader, + void Initialize(const ProcessMemory* process_memory, VMAddress address, VMSize size) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); - process_reader_ = process_reader; + process_memory_ = process_memory; address_ = address; - size_ = size; + size_ = base::checked_cast<size_t>(size); INITIALIZATION_STATE_SET_VALID(initialized_); } // MemorySnapshot: uint64_t Address() const override { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return address_; + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return address_; } size_t Size() const override { @@ -76,7 +76,7 @@ } std::unique_ptr<uint8_t[]> buffer(new uint8_t[size_]); - if (!process_reader_->Memory()->Read(address_, size_, buffer.get())) { + if (!process_memory_->Read(address_, size_, buffer.get())) { return false; } return delegate->MemorySnapshotDelegateRead(buffer.get(), size_); @@ -84,7 +84,19 @@ const MemorySnapshot* MergeWithOtherSnapshot( const MemorySnapshot* other) const override { - return MergeWithOtherSnapshotImpl(this, other); + const MemorySnapshotGeneric* other_as_memory_snapshot_concrete = + reinterpret_cast<const MemorySnapshotGeneric*>(other); + if (process_memory_ != other_as_memory_snapshot_concrete->process_memory_) { + LOG(ERROR) << "different process_memory_ for snapshots"; + return nullptr; + } + CheckedRange<uint64_t, size_t> merged(0, 0); + if (!LoggingDetermineMergedRange(this, other, &merged)) + return nullptr; + + auto result = std::make_unique<MemorySnapshotGeneric>(); + result->Initialize(process_memory_, merged.base(), merged.size()); + return result.release(); } private: @@ -93,9 +105,9 @@ const T* self, const MemorySnapshot* other); - ProcessReaderType* process_reader_; // weak - uint64_t address_; - uint64_t size_; + const ProcessMemory* process_memory_; // weak + VMAddress address_; + size_t size_; InitializationStateDcheck initialized_; DISALLOW_COPY_AND_ASSIGN(MemorySnapshotGeneric);
diff --git a/third_party/crashpad/crashpad/snapshot/snapshot.gyp b/third_party/crashpad/crashpad/snapshot/snapshot.gyp index 0b4e157..c4b7d52 100644 --- a/third_party/crashpad/crashpad/snapshot/snapshot.gyp +++ b/third_party/crashpad/crashpad/snapshot/snapshot.gyp
@@ -155,8 +155,6 @@ 'win/capture_memory_delegate_win.h', 'win/memory_map_region_snapshot_win.cc', 'win/memory_map_region_snapshot_win.h', - 'win/memory_snapshot_win.cc', - 'win/memory_snapshot_win.h', 'win/module_snapshot_win.cc', 'win/module_snapshot_win.h', 'win/pe_image_annotations_reader.cc',
diff --git a/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.cc b/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.cc index b652f4a..ee5e5d64 100644 --- a/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.cc +++ b/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.cc
@@ -17,7 +17,7 @@ #include <utility> #include "base/numerics/safe_conversions.h" -#include "snapshot/win/memory_snapshot_win.h" +#include "snapshot/memory_snapshot_generic.h" namespace crashpad { namespace internal { @@ -25,7 +25,7 @@ CaptureMemoryDelegateWin::CaptureMemoryDelegateWin( ProcessReaderWin* process_reader, const ProcessReaderWin::Thread& thread, - std::vector<std::unique_ptr<MemorySnapshotWin>>* snapshots, + std::vector<std::unique_ptr<MemorySnapshotGeneric>>* snapshots, uint32_t* budget_remaining) : stack_(thread.stack_region_address, thread.stack_region_size), process_reader_(process_reader), @@ -57,9 +57,9 @@ return; if (budget_remaining_ && *budget_remaining_ == 0) return; - snapshots_->push_back(std::make_unique<internal::MemorySnapshotWin>()); - internal::MemorySnapshotWin* snapshot = snapshots_->back().get(); - snapshot->Initialize(process_reader_, range.base(), range.size()); + snapshots_->push_back(std::make_unique<internal::MemorySnapshotGeneric>()); + internal::MemorySnapshotGeneric* snapshot = snapshots_->back().get(); + snapshot->Initialize(process_reader_->Memory(), range.base(), range.size()); if (budget_remaining_) { if (!base::IsValueInRangeForNumericType<int64_t>(range.size())) { *budget_remaining_ = 0;
diff --git a/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.h b/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.h index 175b4c9..85c3db9 100644 --- a/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.h +++ b/third_party/crashpad/crashpad/snapshot/win/capture_memory_delegate_win.h
@@ -28,7 +28,7 @@ namespace crashpad { namespace internal { -class MemorySnapshotWin; +class MemorySnapshotGeneric; class CaptureMemoryDelegateWin : public CaptureMemory::Delegate { public: @@ -38,15 +38,15 @@ //! \param[in] thread The thread being inspected. Memory ranges overlapping //! this thread's stack will be ignored on the assumption that they're //! already captured elsewhere. - //! \param[in] snapshots A vector of MemorySnapshotWin to which the captured - //! memory will be added. + //! \param[in] snapshots A vector of MemorySnapshotGeneric to which the + //! captured memory will be added. //! \param[in] budget_remaining If non-null, a pointer to the remaining number //! of bytes to capture. If this is `0`, no further memory will be //! captured. CaptureMemoryDelegateWin( ProcessReaderWin* process_reader, const ProcessReaderWin::Thread& thread, - std::vector<std::unique_ptr<MemorySnapshotWin>>* snapshots, + std::vector<std::unique_ptr<MemorySnapshotGeneric>>* snapshots, uint32_t* budget_remaining); // MemoryCaptureDelegate: @@ -60,7 +60,7 @@ private: CheckedRange<uint64_t, uint64_t> stack_; ProcessReaderWin* process_reader_; // weak - std::vector<std::unique_ptr<MemorySnapshotWin>>* snapshots_; // weak + std::vector<std::unique_ptr<MemorySnapshotGeneric>>* snapshots_; // weak uint32_t* budget_remaining_; };
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc index e8ea1e8..3413a403 100644 --- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc +++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
@@ -17,9 +17,9 @@ #include "client/crashpad_client.h" #include "snapshot/capture_memory.h" #include "snapshot/memory_snapshot.h" -#include "snapshot/win/cpu_context_win.h" +#include "snapshot/memory_snapshot_generic.h" #include "snapshot/win/capture_memory_delegate_win.h" -#include "snapshot/win/memory_snapshot_win.h" +#include "snapshot/win/cpu_context_win.h" #include "snapshot/win/process_reader_win.h" #include "util/win/nt_internals.h"
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h index 1eed538..fd4e854 100644 --- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h +++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h
@@ -36,7 +36,7 @@ namespace internal { -class MemorySnapshotWin; +class MemorySnapshotGeneric; union CPUContextUnion { #if defined(ARCH_CPU_X86_FAMILY) @@ -96,7 +96,7 @@ CPUContextUnion context_union_; CPUContext context_; std::vector<uint64_t> codes_; - std::vector<std::unique_ptr<internal::MemorySnapshotWin>> extra_memory_; + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>> extra_memory_; uint64_t thread_id_; uint64_t exception_address_; uint32_t exception_flags_;
diff --git a/third_party/crashpad/crashpad/snapshot/win/memory_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/memory_snapshot_win.cc deleted file mode 100644 index d56b9520..0000000 --- a/third_party/crashpad/crashpad/snapshot/win/memory_snapshot_win.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2015 The Crashpad Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <memory> - -#include "snapshot/win/memory_snapshot_win.h" - -namespace crashpad { -namespace internal { - -MemorySnapshotWin::MemorySnapshotWin() - : MemorySnapshot(), - process_reader_(nullptr), - address_(0), - size_(0), - initialized_() { -} - -MemorySnapshotWin::~MemorySnapshotWin() { -} - -void MemorySnapshotWin::Initialize(ProcessReaderWin* process_reader, - uint64_t address, - uint64_t size) { - INITIALIZATION_STATE_SET_INITIALIZING(initialized_); - process_reader_ = process_reader; - address_ = address; - DLOG_IF(WARNING, size >= std::numeric_limits<size_t>::max()) - << "size overflow"; - size_ = static_cast<size_t>(size); - INITIALIZATION_STATE_SET_VALID(initialized_); -} - -uint64_t MemorySnapshotWin::Address() const { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return address_; -} - -size_t MemorySnapshotWin::Size() const { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return size_; -} - -bool MemorySnapshotWin::Read(Delegate* delegate) const { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - - if (size_ == 0) { - return delegate->MemorySnapshotDelegateRead(nullptr, size_); - } - - std::unique_ptr<uint8_t[]> buffer(new uint8_t[size_]); - if (!process_reader_->Memory()->Read(address_, size_, buffer.get())) { - return false; - } - return delegate->MemorySnapshotDelegateRead(buffer.get(), size_); -} - -const MemorySnapshot* MemorySnapshotWin::MergeWithOtherSnapshot( - const MemorySnapshot* other) const { - return MergeWithOtherSnapshotImpl(this, other); -} - -} // namespace internal -} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/win/memory_snapshot_win.h b/third_party/crashpad/crashpad/snapshot/win/memory_snapshot_win.h deleted file mode 100644 index ebc878b..0000000 --- a/third_party/crashpad/crashpad/snapshot/win/memory_snapshot_win.h +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2015 The Crashpad Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef CRASHPAD_SNAPSHOT_WIN_MEMORY_SNAPSHOT_WIN_H_ -#define CRASHPAD_SNAPSHOT_WIN_MEMORY_SNAPSHOT_WIN_H_ - -#include <stdint.h> -#include <sys/types.h> - -#include "base/macros.h" -#include "snapshot/memory_snapshot.h" -#include "snapshot/win/process_reader_win.h" -#include "util/misc/initialization_state_dcheck.h" - -namespace crashpad { -namespace internal { - -//! \brief A MemorySnapshot of a memory region in a process on the running -//! system, when the system runs Windows. -class MemorySnapshotWin final : public MemorySnapshot { - public: - MemorySnapshotWin(); - ~MemorySnapshotWin() override; - - //! \brief Initializes the object. - //! - //! Memory is read lazily. No attempt is made to read the memory snapshot data - //! until Read() is called, and the memory snapshot data is discared when - //! Read() returns. - //! - //! \param[in] process_reader A reader for the process being snapshotted. - //! \param[in] address The base address of the memory region to snapshot, in - //! the snapshot process' address space. - //! \param[in] size The size of the memory region to snapshot. - void Initialize(ProcessReaderWin* process_reader, - uint64_t address, - uint64_t size); - - // MemorySnapshot: - - uint64_t Address() const override; - size_t Size() const override; - bool Read(Delegate* delegate) const override; - const MemorySnapshot* MergeWithOtherSnapshot( - const MemorySnapshot* other) const override; - - private: - template <class T> - friend const MemorySnapshot* MergeWithOtherSnapshotImpl( - const T* self, - const MemorySnapshot* other); - - ProcessReaderWin* process_reader_; // weak - uint64_t address_; - size_t size_; - InitializationStateDcheck initialized_; - - DISALLOW_COPY_AND_ASSIGN(MemorySnapshotWin); -}; - -} // namespace internal -} // namespace crashpad - -#endif // CRASHPAD_SNAPSHOT_WIN_MEMORY_SNAPSHOT_WIN_H_
diff --git a/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.cc index 49d178a8..c7aaad8d 100644 --- a/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.cc +++ b/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.cc
@@ -19,7 +19,7 @@ #include "base/strings/utf_string_conversions.h" #include "client/crashpad_info.h" #include "client/simple_address_range_bag.h" -#include "snapshot/win/memory_snapshot_win.h" +#include "snapshot/memory_snapshot_generic.h" #include "snapshot/win/pe_image_annotations_reader.h" #include "snapshot/win/pe_image_reader.h" #include "util/misc/tri_state.h" @@ -327,10 +327,10 @@ } if (list_entry.size != 0) { - std::unique_ptr<internal::MemorySnapshotWin> memory( - new internal::MemorySnapshotWin()); + std::unique_ptr<internal::MemorySnapshotGeneric> memory( + new internal::MemorySnapshotGeneric()); memory->Initialize( - process_reader_, list_entry.base_address, list_entry.size); + process_reader_->Memory(), list_entry.base_address, list_entry.size); streams->push_back(std::make_unique<UserMinidumpStream>( list_entry.stream_type, memory.release())); }
diff --git a/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc index d2eef49a..cafe7b4 100644 --- a/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc +++ b/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
@@ -459,7 +459,7 @@ void ProcessSnapshotWin::AddMemorySnapshot( WinVMAddress address, WinVMSize size, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into) { + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into) { if (size == 0) return; @@ -480,14 +480,14 @@ } } - into->push_back(std::make_unique<internal::MemorySnapshotWin>()); - into->back()->Initialize(&process_reader_, address, size); + into->push_back(std::make_unique<internal::MemorySnapshotGeneric>()); + into->back()->Initialize(process_reader_.Memory(), address, size); } template <class Traits> void ProcessSnapshotWin::AddMemorySnapshotForUNICODE_STRING( const process_types::UNICODE_STRING<Traits>& us, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into) { + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into) { AddMemorySnapshot(us.Buffer, us.Length, into); } @@ -495,7 +495,7 @@ void ProcessSnapshotWin::AddMemorySnapshotForLdrLIST_ENTRY( const process_types::LIST_ENTRY<Traits>& le, size_t offset_of_member, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into) { + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into) { // Walk the doubly-linked list of entries, adding the list memory itself, as // well as pointed-to strings. typename Traits::Pointer last = le.Blink; @@ -545,7 +545,7 @@ template <class Traits> void ProcessSnapshotWin::ReadLock( WinVMAddress start, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into) { + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into) { // We're walking the RTL_CRITICAL_SECTION_DEBUG ProcessLocksList, but starting // from an actual RTL_CRITICAL_SECTION, so start by getting to the first // RTL_CRITICAL_SECTION_DEBUG.
diff --git a/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h b/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h index 4acfe3984..8b0bf52 100644 --- a/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h +++ b/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h
@@ -31,6 +31,7 @@ #include "snapshot/exception_snapshot.h" #include "snapshot/memory_map_region_snapshot.h" #include "snapshot/memory_snapshot.h" +#include "snapshot/memory_snapshot_generic.h" #include "snapshot/module_snapshot.h" #include "snapshot/process_snapshot.h" #include "snapshot/system_snapshot.h" @@ -38,7 +39,6 @@ #include "snapshot/unloaded_module_snapshot.h" #include "snapshot/win/exception_snapshot_win.h" #include "snapshot/win/memory_map_region_snapshot_win.h" -#include "snapshot/win/memory_snapshot_win.h" #include "snapshot/win/module_snapshot_win.h" #include "snapshot/win/system_snapshot_win.h" #include "snapshot/win/thread_snapshot_win.h" @@ -154,18 +154,18 @@ void AddMemorySnapshot( WinVMAddress address, WinVMSize size, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into); + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into); template <class Traits> void AddMemorySnapshotForUNICODE_STRING( const process_types::UNICODE_STRING<Traits>& us, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into); + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into); template <class Traits> void AddMemorySnapshotForLdrLIST_ENTRY( const process_types::LIST_ENTRY<Traits>& le, size_t offset_of_member, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into); + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into); WinVMSize DetermineSizeOfEnvironmentBlock( WinVMAddress start_of_environment_block); @@ -175,10 +175,10 @@ template <class Traits> void ReadLock( WinVMAddress start, - std::vector<std::unique_ptr<internal::MemorySnapshotWin>>* into); + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>>* into); internal::SystemSnapshotWin system_; - std::vector<std::unique_ptr<internal::MemorySnapshotWin>> extra_memory_; + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>> extra_memory_; std::vector<std::unique_ptr<internal::ThreadSnapshotWin>> threads_; std::vector<std::unique_ptr<internal::ModuleSnapshotWin>> modules_; std::vector<UnloadedModuleSnapshot> unloaded_modules_;
diff --git a/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.cc index f381a4b9..02cc63c 100644 --- a/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.cc +++ b/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.cc
@@ -48,19 +48,20 @@ if (process_reader->GetProcessInfo().LoggingRangeIsFullyReadable( CheckedRange<WinVMAddress, WinVMSize>(thread_.stack_region_address, thread_.stack_region_size))) { - stack_.Initialize(process_reader, + stack_.Initialize(process_reader->Memory(), thread_.stack_region_address, thread_.stack_region_size); } else { - stack_.Initialize(process_reader, 0, 0); + stack_.Initialize(process_reader->Memory(), 0, 0); } if (process_reader->GetProcessInfo().LoggingRangeIsFullyReadable( CheckedRange<WinVMAddress, WinVMSize>(thread_.teb_address, thread_.teb_size))) { - teb_.Initialize(process_reader, thread_.teb_address, thread_.teb_size); + teb_.Initialize( + process_reader->Memory(), thread_.teb_address, thread_.teb_size); } else { - teb_.Initialize(process_reader, 0, 0); + teb_.Initialize(process_reader->Memory(), 0, 0); } #if defined(ARCH_CPU_X86)
diff --git a/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.h b/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.h index 6346580..64ec43d 100644 --- a/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.h +++ b/third_party/crashpad/crashpad/snapshot/win/thread_snapshot_win.h
@@ -24,8 +24,8 @@ #include "build/build_config.h" #include "snapshot/cpu_context.h" #include "snapshot/memory_snapshot.h" +#include "snapshot/memory_snapshot_generic.h" #include "snapshot/thread_snapshot.h" -#include "snapshot/win/memory_snapshot_win.h" #include "snapshot/win/process_reader_win.h" #include "util/misc/initialization_state_dcheck.h" @@ -82,11 +82,11 @@ #endif } context_union_; CPUContext context_; - MemorySnapshotWin stack_; - MemorySnapshotWin teb_; + MemorySnapshotGeneric stack_; + MemorySnapshotGeneric teb_; ProcessReaderWin::Thread thread_; InitializationStateDcheck initialized_; - std::vector<std::unique_ptr<MemorySnapshotWin>> pointed_to_memory_; + std::vector<std::unique_ptr<MemorySnapshotGeneric>> pointed_to_memory_; DISALLOW_COPY_AND_ASSIGN(ThreadSnapshotWin); };
diff --git a/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cmx b/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cmx index 6b666379..7425898 100644 --- a/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cmx +++ b/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cmx
@@ -11,7 +11,8 @@ }, "sandbox": { "features": [ - "system-temp" + "system-temp", + "deprecated-ambient-replace-as-executable" ], "services": [ "fuchsia.net.SocketProvider",
diff --git a/third_party/dav1d/README.chromium b/third_party/dav1d/README.chromium index 33fb265..889da90 100644 --- a/third_party/dav1d/README.chromium +++ b/third_party/dav1d/README.chromium
@@ -1,7 +1,7 @@ Name: dav1d is an AV1 decoder :) Short Name: dav1d URL: https://code.videolan.org/videolan/dav1d -Version: d400361524ce739db30d552a9e54809d812710c6 +Version: a1e3f35842de92b526422af05360c84cf233f07f License: 2-Clause BSD License File: LICENSE Security Critical: yes
diff --git a/third_party/dav1d/config/linux-noasm/x64/config.h b/third_party/dav1d/config/linux-noasm/x64/config.h index 1ff5fc2..3a10d2fe 100644 --- a/third_party/dav1d/config/linux-noasm/x64/config.h +++ b/third_party/dav1d/config/linux-noasm/x64/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 0 +#define ARCH_PPC64LE 0 + #define ARCH_X86 1 #define ARCH_X86_32 0
diff --git a/third_party/dav1d/config/linux/arm/config.h b/third_party/dav1d/config/linux/arm/config.h index 4e6ccfa..5434948 100644 --- a/third_party/dav1d/config/linux/arm/config.h +++ b/third_party/dav1d/config/linux/arm/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 1 +#define ARCH_PPC64LE 0 + #define ARCH_X86 0 #define ARCH_X86_32 0
diff --git a/third_party/dav1d/config/linux/arm64/config.h b/third_party/dav1d/config/linux/arm64/config.h index 6bd4bb2..1df4565c 100644 --- a/third_party/dav1d/config/linux/arm64/config.h +++ b/third_party/dav1d/config/linux/arm64/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 0 +#define ARCH_PPC64LE 0 + #define ARCH_X86 0 #define ARCH_X86_32 0
diff --git a/third_party/dav1d/config/linux/x64/config.asm b/third_party/dav1d/config/linux/x64/config.asm index a28aa40..684c8eb 100644 --- a/third_party/dav1d/config/linux/x64/config.asm +++ b/third_party/dav1d/config/linux/x64/config.asm
@@ -5,4 +5,6 @@ %define ARCH_X86_64 1 +%define PIC 1 + ; %define STACK_ALIGNMENT 32 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/linux/x64/config.h b/third_party/dav1d/config/linux/x64/config.h index 01d84a92..bdbf64c 100644 --- a/third_party/dav1d/config/linux/x64/config.h +++ b/third_party/dav1d/config/linux/x64/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 0 +#define ARCH_PPC64LE 0 + #define ARCH_X86 1 #define ARCH_X86_32 0
diff --git a/third_party/dav1d/config/linux/x86/config.h b/third_party/dav1d/config/linux/x86/config.h index be70d8b..69222430 100644 --- a/third_party/dav1d/config/linux/x86/config.h +++ b/third_party/dav1d/config/linux/x86/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 0 +#define ARCH_PPC64LE 0 + #define ARCH_X86 1 #define ARCH_X86_32 1
diff --git a/third_party/dav1d/config/win/arm64/config.h b/third_party/dav1d/config/win/arm64/config.h index 23f3138..2371079 100644 --- a/third_party/dav1d/config/win/arm64/config.h +++ b/third_party/dav1d/config/win/arm64/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 0 +#define ARCH_PPC64LE 0 + #define ARCH_X86 0 #define ARCH_X86_32 0
diff --git a/third_party/dav1d/config/win/x64/config.asm b/third_party/dav1d/config/win/x64/config.asm index 6abf1a6..863f26e7 100644 --- a/third_party/dav1d/config/win/x64/config.asm +++ b/third_party/dav1d/config/win/x64/config.asm
@@ -5,4 +5,6 @@ %define ARCH_X86_64 1 +%define PIC 1 + ; %define STACK_ALIGNMENT 16 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/win/x64/config.h b/third_party/dav1d/config/win/x64/config.h index 6c44322..dbf688b 100644 --- a/third_party/dav1d/config/win/x64/config.h +++ b/third_party/dav1d/config/win/x64/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 0 +#define ARCH_PPC64LE 0 + #define ARCH_X86 1 #define ARCH_X86_32 0
diff --git a/third_party/dav1d/config/win/x86/config.h b/third_party/dav1d/config/win/x86/config.h index 4447b04..56275cbb 100644 --- a/third_party/dav1d/config/win/x86/config.h +++ b/third_party/dav1d/config/win/x86/config.h
@@ -9,6 +9,8 @@ #define ARCH_ARM 0 +#define ARCH_PPC64LE 0 + #define ARCH_X86 1 #define ARCH_X86_32 1
diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc index 6f5c1ab5..caf088df 100644 --- a/third_party/leveldatabase/env_chromium.cc +++ b/third_party/leveldatabase/env_chromium.cc
@@ -994,22 +994,8 @@ } while (!file.IsValid() && retrier.ShouldKeepTrying(error_code)); if (!file.IsValid()) { - if (error_code == base::File::FILE_ERROR_NOT_FOUND) { - FilePath parent = FilePath::FromUTF8Unsafe(fname).DirName(); - FilePath last_parent; - int num_missing_ancestors = 0; - do { - if (base::DirectoryExists(parent)) - break; - ++num_missing_ancestors; - last_parent = parent; - parent = parent.DirName(); - } while (parent != last_parent); - RecordLockFileAncestors(num_missing_ancestors); - } - - result = MakeIOError(fname, FileErrorString(error_code), kLockFile, - error_code); + result = + MakeIOError(fname, FileErrorString(error_code), kLockFile, error_code); RecordOSError(kLockFile, error_code); return result; } @@ -1183,10 +1169,6 @@ RecordStorageBytesWritten(name_.c_str(), amount); } -void ChromiumEnv::RecordLockFileAncestors(int num_missing_ancestors) const { - GetLockFileAncestorHistogram()->Add(num_missing_ancestors); -} - base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, int limit) const { std::string uma_name; @@ -1203,17 +1185,6 @@ kNumEntries + 1, base::Histogram::kUmaTargetedHistogramFlag); } -base::HistogramBase* ChromiumEnv::GetLockFileAncestorHistogram() const { - std::string uma_name(name_); - uma_name.append(".LockFileAncestorsNotFound"); - const int kMin = 1; - const int kMax = 10; - const int kNumBuckets = 11; - return base::LinearHistogram::FactoryGet( - uma_name, kMin, kMax, kNumBuckets, - base::Histogram::kUmaTargetedHistogramFlag); -} - base::HistogramBase* ChromiumEnv::GetRetryTimeHistogram(MethodID method) const { std::string uma_name(name_); // TODO(dgrogan): This is probably not the best way to concatenate strings.
diff --git a/third_party/leveldatabase/env_chromium.h b/third_party/leveldatabase/env_chromium.h index 1927050..a7027578 100644 --- a/third_party/leveldatabase/env_chromium.h +++ b/third_party/leveldatabase/env_chromium.h
@@ -225,9 +225,7 @@ reinterpret_cast<ChromiumEnv*>(arg)->BGThread(); } - void RecordLockFileAncestors(int num_missing_ancestors) const; base::HistogramBase* GetMethodIOErrorHistogram() const; - base::HistogramBase* GetLockFileAncestorHistogram() const; // RetrierProvider implementation. int MaxRetryTimeMillis() const override { return kMaxRetryTimeMillis; }
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 3849a412..55994a05 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Thursday June 06 2019 +Date: Saturday June 15 2019 Branch: master -Commit: 28cc5f3646bac9d01e583621f611303f738424f0 +Commit: bb9511684f70a735b3b909712666021e178c93e7 Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 806f15b7..330e299b 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,7 +2,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 8 #define VERSION_PATCH 0 -#define VERSION_EXTRA "538-g28cc5f3646" +#define VERSION_EXTRA "551-gbb9511684f" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.8.0-538-g28cc5f3646" -#define VERSION_STRING " v1.8.0-538-g28cc5f3646" +#define VERSION_STRING_NOSP "v1.8.0-551-gbb9511684f" +#define VERSION_STRING " v1.8.0-551-gbb9511684f"
diff --git a/third_party/lottie/BUILD.gn b/third_party/lottie/BUILD.gn new file mode 100644 index 0000000..e481acff --- /dev/null +++ b/third_party/lottie/BUILD.gn
@@ -0,0 +1,8 @@ +# 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("//third_party/closure_compiler/compile_js.gni") + +js_library("lottie_worker") { +}
diff --git a/third_party/lottie/README.chromium b/third_party/lottie/README.chromium index 33cd811..5ef3a69 100644 --- a/third_party/lottie/README.chromium +++ b/third_party/lottie/README.chromium
@@ -16,4 +16,4 @@ Generating Minified Version: To generate the minified version use node's uglify-js- -$ node uglifyjs --compress --mangle reserved=['onmessage'] lottie_worker.js -o lottie_worker.min.js +$ node uglifyjs --compress --mangle reserved=['onmessage'] lottie_worker.js -o lottie_worker.min.js -b beautify=false,ascii_only=true
diff --git a/third_party/lottie/lottie_worker.js b/third_party/lottie/lottie_worker.js index 792b0c2..ac40e37 100644 --- a/third_party/lottie/lottie_worker.js +++ b/third_party/lottie/lottie_worker.js
@@ -336,14 +336,6 @@ return blendModeEnums[mode] || ''; } }()) -/*! - Transformation Matrix v2.0 - (c) Epistemex 2014-2015 - www.epistemex.com - By Ken Fyrstenberg - Contributions by leeoniya. - License: MIT, header required. - */ /** * 2D transformation matrix object initialized with identity matrix. @@ -735,30 +727,6 @@ }; }()); -/* - Copyright 2014 David Bau. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - (function (pool, math) { // // The following constants are related to IEEE 754 limits. @@ -969,18 +937,7 @@ BMMath // math: package containing random, pow, and seedrandom ); var BezierFactory = (function(){ - /** - * BezierEasing - use bezier curve for transition easing function - * by Gaëtan Renaudeau 2014 - 2015 – MIT License - * - * Credits: is based on Firefox's nsSMILKeySpline.cpp - * Usage: - * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ]) - * spline.get(x) => returns the easing value | x must be in [0, 1] range - * - */ - - var ob = {}; + var ob = {}; ob.getBezierEasing = getBezierEasing; var beziers = {};
diff --git a/third_party/lottie/lottie_worker.min.js b/third_party/lottie/lottie_worker.min.js index a4dbfab..e400409 100644 --- a/third_party/lottie/lottie_worker.min.js +++ b/third_party/lottie/lottie_worker.min.js
@@ -1 +1 @@ -var lottiejs=function(window){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",initialDefaultFrame=-999999,subframeEnabled=!0,expressionsPlugin,isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),cachedColors={},bm_rounder=Math.round,bm_rnd,bm_pow=Math.pow,bm_sqrt=Math.sqrt,bm_abs=Math.abs,bm_floor=Math.floor,bm_max=Math.max,bm_min=Math.min,blitter=10,BMMath={};function ProjectInterface(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],r=e.length;for(t=0;t<r;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"==typeof t&&t.length){var e,r=createSizedArray(t.length),i=t.length;for(e=0;e<i;e+=1)r[e]=Math.abs(t[e]);return r}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){bm_rnd=t?Math.round:function(t){return t}}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin=t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility=t.style.webkitBackfaceVisibility="visible",t.style.transformStyle=t.style.webkitTransformStyle=t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,r,i){this.type=t,this.currentTime=e,this.totalTime=r,this.direction=i<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,r,i){this.type=t,this.currentLoop=r,this.totalLoops=e,this.direction=i<0?-1:1}function BMSegmentStartEvent(t,e,r){this.type=t,this.firstFrame=e,this.totalFrames=r}function BMDestroyEvent(t,e){this.type=t,this.target=e}roundValues(!1);var createElementID=(B=0,function(){return"__lottie_element_"+ ++B}),B;function HSVtoRGB(t,e,r){var i,s,a,n,o,h,p,l;switch(h=r*(1-e),p=r*(1-(o=6*t-(n=Math.floor(6*t)))*e),l=r*(1-(1-o)*e),n%6){case 0:i=r,s=l,a=h;break;case 1:i=p,s=r,a=h;break;case 2:i=h,s=r,a=l;break;case 3:i=h,s=p,a=r;break;case 4:i=l,s=h,a=r;break;case 5:i=r,s=h,a=p}return[i,s,a]}function RGBtoHSV(t,e,r){var i,s=Math.max(t,e,r),a=Math.min(t,e,r),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:i=0;break;case t:i=e-r+n*(e<r?6:0),i/=6*n;break;case e:i=r-t+2*n,i/=6*n;break;case r:i=t-e+4*n,i/=6*n}return[i,o,h]}function addSaturationToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[1]+=e,1<r[1]?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,1<r[2]?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,1<r[0]?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1==e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var r=this._cbs[t].length,i=0;i<r;i++)this._cbs[t][i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var r=0,i=this._cbs[t].length;r<i;)this._cbs[t][r]===e&&(this._cbs[t].splice(r,1),r-=1,i-=1),r+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var createTypedArray="function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):void 0}:function(t,e){var r,i=0,s=[];switch(t){case"int16":case"uint8c":r=1;break;default:r=1.1}for(i=0;i<e;i+=1)s.push(r);return s};function createSizedArray(t){return Array.apply(null,{length:t})}function createTag(t){return document.createElement(t)}function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){this._mdf=!1;var t,e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var getBlendMode=(Ja={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Ja[t]||""}),Ja,Matrix=(La=Math.cos,Ma=Math.sin,Na=Math.tan,Oa=Math.round,function(){this.reset=Pa,this.rotate=Qa,this.rotateX=Ra,this.rotateY=Sa,this.rotateZ=Ta,this.skew=Va,this.skewFromAxis=Wa,this.shear=Ua,this.scale=Xa,this.setTransform=Ya,this.translate=Za,this.transform=$a,this.applyToPoint=db,this.applyToX=eb,this.applyToY=fb,this.applyToZ=gb,this.applyToPointArray=kb,this.applyToTriplePoints=jb,this.applyToPointStringified=lb,this.toCSS=mb,this.to2dCSS=pb,this.clone=bb,this.cloneFromProps=cb,this.equals=ab,this.inversePoints=ib,this.inversePoint=hb,this._t=this.transform,this.isIdentity=_a,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}),La,Ma,Na,Oa;function Pa(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function Qa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ra(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(1,0,0,0,0,e,-r,0,0,r,e,0,0,0,0,1)}function Sa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,0,r,0,0,1,0,0,-r,0,e,0,0,0,0,1)}function Ta(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ua(t,e){return this._t(1,e,t,1,0,0)}function Va(t,e){return this.shear(Na(t),Na(e))}function Wa(t,e){var r=La(e),i=Ma(e);return this._t(r,i,0,0,-i,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,Na(t),1,0,0,0,0,1,0,0,0,0,1)._t(r,-i,0,0,i,r,0,0,0,0,1,0,0,0,0,1)}function Xa(t,e,r){return r||0===r||(r=1),1===t&&1===e&&1===r?this:this._t(t,0,0,0,0,e,0,0,0,0,r,0,0,0,0,1)}function Ya(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=r,this.props[3]=i,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=p,this.props[10]=l,this.props[11]=m,this.props[12]=f,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function Za(t,e,r){return r=r||0,0!==t||0!==e||0!==r?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,r,1):this}function $a(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){var y=this.props;if(1===t&&0===e&&0===r&&0===i&&0===s&&1===a&&0===n&&0===o&&0===h&&0===p&&1===l&&0===m)return y[12]=y[12]*t+y[15]*f,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*l+y[15]*d,y[15]=y[15]*u,this._identityCalculated=!1,this;var g=y[0],v=y[1],P=y[2],b=y[3],x=y[4],_=y[5],S=y[6],T=y[7],A=y[8],C=y[9],E=y[10],k=y[11],D=y[12],M=y[13],I=y[14],w=y[15];return y[0]=g*t+v*s+P*h+b*f,y[1]=g*e+v*a+P*p+b*c,y[2]=g*r+v*n+P*l+b*d,y[3]=g*i+v*o+P*m+b*u,y[4]=x*t+_*s+S*h+T*f,y[5]=x*e+_*a+S*p+T*c,y[6]=x*r+_*n+S*l+T*d,y[7]=x*i+_*o+S*m+T*u,y[8]=A*t+C*s+E*h+k*f,y[9]=A*e+C*a+E*p+k*c,y[10]=A*r+C*n+E*l+k*d,y[11]=A*i+C*o+E*m+k*u,y[12]=D*t+M*s+I*h+w*f,y[13]=D*e+M*a+I*p+w*c,y[14]=D*r+M*n+I*l+w*d,y[15]=D*i+M*o+I*m+w*u,this._identityCalculated=!1,this}function _a(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function ab(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function bb(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e]}function cb(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function db(t,e,r){return{x:t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}}function eb(t,e,r){return t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12]}function fb(t,e,r){return t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13]}function gb(t,e,r){return t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}function hb(t){var e=this.props[0]*this.props[5]-this.props[1]*this.props[4],r=this.props[5]/e,i=-this.props[1]/e,s=-this.props[4]/e,a=this.props[0]/e,n=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/e,o=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/e;return[t[0]*r+t[1]*s+n,t[0]*i+t[1]*a+o,0]}function ib(t){var e,r=t.length,i=[];for(e=0;e<r;e+=1)i[e]=hb(t[e]);return i}function jb(t,e,r){var i=createTypedArray("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=r[0],i[5]=r[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],p=this.props[13];i[0]=t[0]*s+t[1]*n+h,i[1]=t[0]*a+t[1]*o+p,i[2]=e[0]*s+e[1]*n+h,i[3]=e[0]*a+e[1]*o+p,i[4]=r[0]*s+r[1]*n+h,i[5]=r[0]*a+r[1]*o+p}return i}function kb(t,e,r){return this.isIdentity()?[t,e,r]:[t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]]}function lb(t,e){if(this.isIdentity())return t+","+e;var r=this.props;return Math.round(100*(t*r[0]+e*r[4]+r[12]))/100+","+Math.round(100*(t*r[1]+e*r[5]+r[13]))/100}function mb(){for(var t=0,e=this.props,r="matrix3d(";t<16;)r+=Oa(1e4*e[t])/1e4,r+=15===t?")":",",t+=1;return r}function nb(t){return t<1e-6&&0<t||-1e-6<t&&t<0?Oa(1e4*t)/1e4:t}function pb(){var t=this.props;return"matrix("+nb(t[0])+","+nb(t[1])+","+nb(t[4])+","+nb(t[5])+","+nb(t[12])+","+nb(t[13])+")"}!function(o,h){var p,l=this,m=256,f=6,c="random",d=h.pow(m,f),u=h.pow(2,52),y=2*u,g=m-1;function v(t){var e,r=t.length,n=this,i=0,s=n.i=n.j=0,a=n.S=[];for(r||(t=[r++]);i<m;)a[i]=i++;for(i=0;i<m;i++)a[i]=a[s=g&s+t[i%r]+(e=a[i])],a[s]=e;n.g=function(t){for(var e,r=0,i=n.i,s=n.j,a=n.S;t--;)e=a[i=g&i+1],r=r*m+a[g&(a[i]=a[s=g&s+e])+(a[s]=e)];return n.i=i,n.j=s,r}}function P(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function b(t,e){for(var r,i=t+"",s=0;s<i.length;)e[g&s]=g&(r^=19*e[g&s])+i.charCodeAt(s++);return x(e)}function x(t){return String.fromCharCode.apply(0,t)}h["seed"+c]=function(t,e,r){function i(){for(var t=n.g(f),e=d,r=0;t<u;)t=(t+r)*m,e*=m,r=n.g(1);for(;y<=t;)t/=2,e/=2,r>>>=1;return(t+r)/e}var s=[],a=b(function t(e,r){var i,s=[],a=typeof e;if(r&&"object"==a)for(i in e)try{s.push(t(e[i],r-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,x(o)]:null===t?function(){try{if(p)return x(p.randomBytes(m));var t=new Uint8Array(m);return(l.crypto||l.msCrypto).getRandomValues(t),x(t)}catch(t){var e=l.navigator,r=e&&e.plugins;return[+new Date,l,r,l.screen,x(o)]}}():t,3),s),n=new v(s);return i.int32=function(){return 0|n.g(4)},i.quick=function(){return n.g(4)/4294967296},i.double=i,b(x(n.S),o),(e.pass||r||function(t,e,r,i){return i&&(i.S&&P(i,n),t.state=function(){return P(n,{})}),r?(h[c]=t,e):t})(i,a,"global"in e?e.global:this==h,e.state)},b(h.random(),o)}([],BMMath);var BezierFactory=(_e={getBezierEasing:function(t,e,r,i,s){var a=s||("bez_"+t+"_"+e+"_"+r+"_"+i).replace(/\./g,"p");if(af[a])return af[a];var n=new rf([t,e,r,i]);return af[a]=n}},af={},gf=11,hf=1/(gf-1),jf="function"==typeof Float32Array,rf.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:nf(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r<gf;++r)this._mSampleValues[r]=nf(r*hf,t,e)},_getTForX:function(t){for(var e=this._p[0],r=this._p[2],i=this._mSampleValues,s=0,a=1,n=gf-1;a!==n&&i[a]<=t;++a)s+=hf;var o=s+(t-i[--a])/(i[a+1]-i[a])*hf,h=of(o,e,r);return.001<=h?function(t,e,r,i){for(var s=0;s<4;++s){var a=of(e,r,i);if(0===a)return e;e-=(nf(e,r,i)-t)/a}return e}(t,o,e,r):0===h?o:function(t,e,r,i,s){for(var a,n,o=0;0<(a=nf(n=e+(r-e)/2,i,s)-t)?r=n:e=n,1e-7<Math.abs(a)&&++o<10;);return n}(t,s,s+hf,e,r)}},_e),_e,af,gf,hf,jf;function kf(t,e){return 1-3*e+3*t}function lf(t,e){return 3*e-6*t}function mf(t){return 3*t}function nf(t,e,r){return((kf(e,r)*t+lf(e,r))*t+mf(e))*t}function of(t,e,r){return 3*kf(e,r)*t*t+2*lf(e,r)*t+mf(e)}function rf(t){this._p=t,this._mSampleValues=jf?new Float32Array(gf):new Array(gf),this._precomputed=!1,this.get=this.get.bind(this)}function extendPrototype(t,e){var r,i,s=t.length;for(r=0;r<s;r+=1)for(var a in i=t[r].prototype)i.hasOwnProperty(a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}function bezFunction(){Math;function y(t,e,r,i,s,a){var n=t*i+e*s+r*a-s*i-a*t-r*e;return-.001<n&&n<.001}var l=function(t,e,r,i){var s,a,n,o,h,p,l=defaultCurveSegments,m=0,f=[],c=[],d=bezier_length_pool.newElement();for(n=r.length,s=0;s<l;s+=1){for(h=s/(l-1),a=p=0;a<n;a+=1)o=bm_pow(1-h,3)*t[a]+3*bm_pow(1-h,2)*h*r[a]+3*(1-h)*bm_pow(h,2)*i[a]+bm_pow(h,3)*e[a],f[a]=o,null!==c[a]&&(p+=bm_pow(f[a]-c[a],2)),c[a]=f[a];p&&(m+=p=bm_sqrt(p)),d.percents[s]=h,d.lengths[s]=m}return d.addedLength=m,d};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}var P,t=(P={},function(t,e,r,i){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+r[0]+"_"+r[1]+"_"+i[0]+"_"+i[1]).replace(/\./g,"p");if(!P[s]){var a,n,o,h,p,l,m,f=defaultCurveSegments,c=0,d=null;2===t.length&&(t[0]!=e[0]||t[1]!=e[1])&&y(t[0],t[1],e[0],e[1],t[0]+r[0],t[1]+r[1])&&y(t[0],t[1],e[0],e[1],e[0]+i[0],e[1]+i[1])&&(f=2);var u=new g(f);for(o=r.length,a=0;a<f;a+=1){for(m=createSizedArray(o),p=a/(f-1),n=l=0;n<o;n+=1)h=bm_pow(1-p,3)*t[n]+3*bm_pow(1-p,2)*p*(t[n]+r[n])+3*(1-p)*bm_pow(p,2)*(e[n]+i[n])+bm_pow(p,3)*e[n],m[n]=h,null!==d&&(l+=bm_pow(m[n]-d[n],2));c+=l=bm_sqrt(l),u.points[a]=new v(l,m),d=m}u.segmentLength=c,P[s]=u}return P[s]});function D(t,e){var r=e.percents,i=e.lengths,s=r.length,a=bm_floor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===i[a])return r[a];for(var h=i[a]>n?-1:1,p=!0;p;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),p=!1):a+=h,a<0||s-1<=a){if(a===s-1)return r[a];p=!1}return r[a]+(r[a+1]-r[a])*o}var M=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segments_length_pool.newElement(),i=t.c,s=t.v,a=t.o,n=t.i,o=t._length,h=r.lengths,p=0;for(e=0;e<o-1;e+=1)h[e]=l(s[e],s[e+1],a[e],n[e+1]),p+=h[e].addedLength;return i&&o&&(h[e]=l(s[e],s[0],a[e],n[0]),p+=h[e].addedLength),r.totalLength=p,r},getNewSegment:function(t,e,r,i,s,a,n){var o,h=D(s=s<0?0:1<s?1:s,n),p=D(a=1<a?1:a,n),l=t.length,m=1-h,f=1-p,c=m*m*m,d=h*m*m*3,u=h*h*m*3,y=h*h*h,g=m*m*f,v=h*m*f+m*h*f+m*m*p,P=h*h*f+m*h*p+h*m*p,b=h*h*p,x=m*f*f,_=h*f*f+m*p*f+m*f*p,S=h*p*f+m*p*p+h*f*p,T=h*p*p,A=f*f*f,C=p*f*f+f*p*f+f*f*p,E=p*p*f+f*p*p+p*f*p,k=p*p*p;for(o=0;o<l;o+=1)M[4*o]=Math.round(1e3*(c*t[o]+d*r[o]+u*i[o]+y*e[o]))/1e3,M[4*o+1]=Math.round(1e3*(g*t[o]+v*r[o]+P*i[o]+b*e[o]))/1e3,M[4*o+2]=Math.round(1e3*(x*t[o]+_*r[o]+S*i[o]+T*e[o]))/1e3,M[4*o+3]=Math.round(1e3*(A*t[o]+C*r[o]+E*i[o]+k*e[o]))/1e3;return M},getPointInSegment:function(t,e,r,i,s,a){var n=D(s,a),o=1-n;return[Math.round(1e3*(o*o*o*t[0]+(n*o*o+o*n*o+o*o*n)*r[0]+(n*n*o+o*n*n+n*o*n)*i[0]+n*n*n*e[0]))/1e3,Math.round(1e3*(o*o*o*t[1]+(n*o*o+o*n*o+o*o*n)*r[1]+(n*n*o+o*n*n+n*o*n)*i[1]+n*n*n*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,r,i,s,a,n,o,h){if(0===r&&0===a&&0===h)return y(t,e,i,s,n,o);var p,l=Math.sqrt(Math.pow(i-t,2)+Math.pow(s-e,2)+Math.pow(a-r,2)),m=Math.sqrt(Math.pow(n-t,2)+Math.pow(o-e,2)+Math.pow(h-r,2)),f=Math.sqrt(Math.pow(n-i,2)+Math.pow(o-s,2)+Math.pow(h-a,2));return-1e-4<(p=m<l?f<l?l-m-f:f-m-l:m<f?f-m-l:m-l-f)&&p<1e-4}}}!function(){for(var a=0,t=["ms","moz","webkit","o"],e=0;e<t.length&&!window.requestAnimationFrame;++e)window.requestAnimationFrame=window[t[e]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[t[e]+"CancelAnimationFrame"]||window[t[e]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(t,e){var r=(new Date).getTime(),i=Math.max(0,16-(r-a)),s=setTimeout(function(){t(r+i)},i);return a=r+i,s}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)})}();var bez=bezFunction();function dataFunctionManager(){function m(t,e,r){var i,s,a,n,o,h,p=t.length;for(s=0;s<p;s+=1)if("ks"in(i=t[s])&&!i.completed){if(i.completed=!0,i.tt&&(t[s-1].td=i.tt),[],-1,i.hasMask){var l=i.masksProperties;for(n=l.length,a=0;a<n;a+=1)if(l[a].pt.k.i)d(l[a].pt.k);else for(h=l[a].pt.k.length,o=0;o<h;o+=1)l[a].pt.k[o].s&&d(l[a].pt.k[o].s[0]),l[a].pt.k[o].e&&d(l[a].pt.k[o].e[0])}0===i.ty?(i.layers=f(i.refId,e),m(i.layers,e,r)):4===i.ty?c(i.shapes):5==i.ty&&b(i,r)}}function f(t,e){for(var r=0,i=e.length;r<i;){if(e[r].id===t)return e[r].layers.__used?JSON.parse(JSON.stringify(e[r].layers)):(e[r].layers.__used=!0,e[r].layers);r+=1}}function c(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)d(t[e].ks.k);else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&d(t[e].ks.k[r].s[0]),t[e].ks.k[r].e&&d(t[e].ks.k[r].e[0]);!0}else"gr"==t[e].ty&&c(t[e].it)}function d(t){var e,r=t.i.length;for(e=0;e<r;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function o(t,e){var r=e?e.split("."):[100,100,100];return t[0]>r[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&void 0))}var i,r=(i=[4,4,14],function(t){if(o(i,t.v)&&(s(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}});function s(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=t[e],void 0,i=r.t.d,r.t.d={k:[{s:i,t:0}]})}var h,a,n=(h=[4,7,99],function(t){if(t.chars&&!o(h,t.v)){var e,r,i,s,a,n=t.chars.length;for(e=0;e<n;e+=1)if(t.chars[e].data&&t.chars[e].data.shapes)for(i=(a=t.chars[e].data.shapes[0].it).length,r=0;r<i;r+=1)(s=a[r].ks.k).__converted||(d(a[r].ks.k),s.__converted=!0)}}),p=(a=[4,1,9],function(t){if(o(a,t.v)&&(u(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&u(t.assets[e].layers)}});function l(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)if("gr"===t[e].ty)l(t[e].it);else if("fl"===t[e].ty||"st"===t[e].ty)if(t[e].c.k&&t[e].c.k[0].i)for(i=t[e].c.k.length,r=0;r<i;r+=1)t[e].c.k[r].s&&(t[e].c.k[r].s[0]/=255,t[e].c.k[r].s[1]/=255,t[e].c.k[r].s[2]/=255,t[e].c.k[r].s[3]/=255),t[e].c.k[r].e&&(t[e].c.k[r].e[0]/=255,t[e].c.k[r].e[1]/=255,t[e].c.k[r].e[2]/=255,t[e].c.k[r].e[3]/=255);else t[e].c.k[0]/=255,t[e].c.k[1]/=255,t[e].c.k[2]/=255,t[e].c.k[3]/=255}function u(t){var e,r=t.length;for(e=0;e<r;e+=1)4===t[e].ty&&l(t[e].shapes)}var y,g=(y=[4,4,18],function(t){if(o(y,t.v)&&(P(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&P(t.assets[e].layers)}});function v(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)t[e].ks.k.c=t[e].closed;else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&(t[e].ks.k[r].s[0].c=t[e].closed),t[e].ks.k[r].e&&(t[e].ks.k[r].e[0].c=t[e].closed);!0}else"gr"==t[e].ty&&v(t[e].it)}function P(t){var e,r,i,s,a,n,o=t.length;for(r=0;r<o;r+=1){if((e=t[r]).hasMask){var h=e.masksProperties;for(s=h.length,i=0;i<s;i+=1)if(h[i].pt.k.i)h[i].pt.k.c=h[i].cl;else for(n=h[i].pt.k.length,a=0;a<n;a+=1)h[i].pt.k[a].s&&(h[i].pt.k[a].s[0].c=h[i].cl),h[i].pt.k[a].e&&(h[i].pt.k[a].e[0].c=h[i].cl)}4===e.ty&&v(e.shapes)}}function b(t,e){0!==t.t.a.length||"m"in t.t.p||(t.singleShape=!0)}var t={completeData:function(t,e){t.__complete||(p(t),r(t),n(t),g(t),m(t.layers,t.assets,e),t.__complete=!0)}};return t.checkColors=p,t.checkChars=n,t.checkShapes=g,t.completeLayers=m,t}var dataManager=dataFunctionManager();dataManager.completeData=function(t,e){t.__complete||(this.checkColors(t),this.checkChars(t),this.checkShapes(t),this.completeLayers(t.layers,t.assets,e),t.__complete=!0)};var FontManager=function(){var a={w:0,size:0,shapes:[]},t=[];function u(t,e){var r=createTag("span");r.style.fontFamily=e;var i=createTag("span");i.innerHTML="giItT1WQy@!-/#",r.style.position="absolute",r.style.left="-10000px",r.style.top="-10000px",r.style.fontSize="300px",r.style.fontVariant="normal",r.style.fontStyle="normal",r.style.fontWeight="normal",r.style.letterSpacing="0",r.appendChild(i),document.body.appendChild(r);var s=i.offsetWidth;return i.style.fontFamily=t+", "+e,{node:i,w:s,parent:r}}t=t.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);function e(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()}return e.getCombinedCharacterCodes=function(){return t},e.prototype.addChars=function(t){if(t){this.chars||(this.chars=[]);var e,r,i,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(r=0,i=!1;r<a;)this.chars[r].style===t[e].style&&this.chars[r].fFamily===t[e].fFamily&&this.chars[r].ch===t[e].ch&&(i=!0),r+=1;i||(this.chars.push(t[e]),a+=1)}}},e.prototype.addFonts=function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);var r,i,s,a,n=t.list,o=n.length,h=o;for(r=0;r<o;r+=1){var p,l,m=!0;if(n[r].loaded=!1,n[r].monoCase=u(n[r].fFamily,"monospace"),n[r].sansCase=u(n[r].fFamily,"sans-serif"),n[r].fPath){if("p"===n[r].fOrigin||3===n[r].origin){if(0<(p=document.querySelectorAll('style[f-forigin="p"][f-family="'+n[r].fFamily+'"], style[f-origin="3"][f-family="'+n[r].fFamily+'"]')).length&&(m=!1),m){var f=createTag("style");f.setAttribute("f-forigin",n[r].fOrigin),f.setAttribute("f-origin",n[r].origin),f.setAttribute("f-family",n[r].fFamily),f.type="text/css",f.innerHTML="@font-face {font-family: "+n[r].fFamily+"; font-style: normal; src: url('"+n[r].fPath+"');}",e.appendChild(f)}}else if("g"===n[r].fOrigin||1===n[r].origin){for(p=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<p.length;l++)-1!==p[l].href.indexOf(n[r].fPath)&&(m=!1);if(m){var c=createTag("link");c.setAttribute("f-forigin",n[r].fOrigin),c.setAttribute("f-origin",n[r].origin),c.type="text/css",c.rel="stylesheet",c.href=n[r].fPath,document.body.appendChild(c)}}else if("t"===n[r].fOrigin||2===n[r].origin){for(p=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<p.length;l++)n[r].fPath===p[l].src&&(m=!1);if(m){var d=createTag("link");d.setAttribute("f-forigin",n[r].fOrigin),d.setAttribute("f-origin",n[r].origin),d.setAttribute("rel","stylesheet"),d.setAttribute("href",n[r].fPath),e.appendChild(d)}}}else n[r].loaded=!0,h-=1;n[r].helper=(i=e,s=n[r],a=void 0,(a=createNS("text")).style.fontSize="100px",a.setAttribute("font-family",s.fFamily),a.setAttribute("font-style",s.fStyle),a.setAttribute("font-weight",s.fWeight),a.textContent="1",s.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",s.fClass)):a.style.fontFamily=s.fFamily,i.appendChild(a),createTag("canvas").getContext("2d").font=s.fWeight+" "+s.fStyle+" 100px "+s.fFamily,a),n[r].cache={},this.fonts.push(n[r])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},e.prototype.getCharData=function(t,e,r){for(var i=0,s=this.chars.length;i<s;){if(this.chars[i].ch===t&&this.chars[i].style===e&&this.chars[i].fFamily===r)return this.chars[i];i+=1}return console&&console.warn&&console.warn("Missing character from exported characters list: ",t,e,r),a},e.prototype.getFontByName=function(t){for(var e=0,r=this.fonts.length;e<r;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},e.prototype.measureText=function(t,e,r){var i=this.getFontByName(e),s=t.charCodeAt(0);if(!i.cache[s+1]){var a=i.helper;if(" "===t){a.textContent="|"+t+"|";var n=a.getComputedTextLength();a.textContent="||";var o=a.getComputedTextLength();i.cache[s+1]=(n-o)/100}else a.textContent=t,i.cache[s+1]=a.getComputedTextLength()/100}return i.cache[s+1]*r},e.prototype.checkLoadedFonts=function(){var t,e,r,i=this.fonts.length,s=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,r=this.fonts[t].monoCase.w,e.offsetWidth!==r?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,r=this.fonts[t].sansCase.w,e.offsetWidth!==r&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFonts.bind(this),20):setTimeout(function(){this.isLoaded=!0}.bind(this),0)},e.prototype.loaded=function(){return this.isLoaded},e}();FontManager=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()};var PropertyFactory=(km=initialDefaultFrame,lm=Math.abs,{getProp:function(t,e,r,i,s){var a;if(e.k.length)if("number"==typeof e.k[0])a=new vm(t,e,i,s);else switch(r){case 0:a=new wm(t,e,i,s);break;case 1:a=new xm(t,e,i,s)}else a=new um(t,e,i,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}}),km,lm;function mm(t,e){var r,i=this.offsetTime;"multidimensional"===this.propType&&(r=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,p,l,m,f=e.lastIndex,c=f,d=this.keyframes.length-1,u=!0;u;){if(s=this.keyframes[c],a=this.keyframes[c+1],c===d-1&&t>=a.t-i){s.h&&(s=a),f=0;break}if(a.t-i>t){f=c;break}c<d-1?c+=1:(f=0,u=!1)}var y,g=a.t-i,v=s.t-i;if(s.to){s.bezierData||(s.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=s.bezierData;if(g<=t||t<v){var b=g<=t?P.points.length-1:0;for(o=P.points[b].point.length,n=0;n<o;n+=1)r[n]=P.points[b].point[n]}else{s.__fnct?m=s.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,s.__fnct=m),h=m((t-v)/(g-v));var x,_=P.segmentLength*h,S=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastAddedLength:0;for(l=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastPoint:0,u=!0,p=P.points.length;u;){if(S+=P.points[l].partialLength,0==_||0===h||l===P.points.length-1){for(o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n];break}if(S<=_&&_<S+P.points[l+1].partialLength){for(x=(_-S)/P.points[l+1].partialLength,o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n]+(P.points[l+1].point[n]-P.points[l].point[n])*x;break}l<p-1?l+=1:u=!1}e._lastPoint=l,e._lastAddedLength=S-P.points[l].partialLength,e._lastKeyframeIndex=c}}else{var T,A,C,E,k;if(d=s.s.length,y=a.s||s.e,this.sh&&1!==s.h)if(g<=t)r[0]=y[0],r[1]=y[1],r[2]=y[2];else if(t<=v)r[0]=s.s[0],r[1]=s.s[1],r[2]=s.s[2];else{!function(t,e){var r=e[0],i=e[1],s=e[2],a=e[3],n=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s),o=Math.asin(2*r*i+2*s*a),h=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}(r,function(t,e,r){var i,s,a,n,o,h=[],p=t[0],l=t[1],m=t[2],f=t[3],c=e[0],d=e[1],u=e[2],y=e[3];(s=p*c+l*d+m*u+f*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y);o=1e-6<1-s?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,Math.sin(r*i)/a):(n=1-r,r);return h[0]=n*p+o*c,h[1]=n*l+o*d,h[2]=n*m+o*u,h[3]=n*f+o*y,h}(pm(s.s),pm(y),(t-v)/(g-v)))}else for(c=0;c<d;c+=1)1!==s.h&&(h=g<=t?1:t<v?0:(s.o.x.constructor===Array?(s.__fnct||(s.__fnct=[]),s.__fnct[c]?m=s.__fnct[c]:(T=void 0===s.o.x[c]?s.o.x[0]:s.o.x[c],A=void 0===s.o.y[c]?s.o.y[0]:s.o.y[c],C=void 0===s.i.x[c]?s.i.x[0]:s.i.x[c],E=void 0===s.i.y[c]?s.i.y[0]:s.i.y[c],m=BezierFactory.getBezierEasing(T,A,C,E).get,s.__fnct[c]=m)):s.__fnct?m=s.__fnct:(T=s.o.x,A=s.o.y,C=s.i.x,E=s.i.y,m=BezierFactory.getBezierEasing(T,A,C,E).get,s.__fnct=m),m((t-v)/(g-v)))),y=a.s||s.e,k=1===s.h?s.s[c]:s.s[c]+(y[c]-s.s[c])*h,1===d?r=k:r[c]=k}return e.lastIndex=f,r}function pm(t){var e=t[0]*degToRads,r=t[1]*degToRads,i=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(r/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(r/2),p=Math.sin(i/2);return[o*h*n+s*a*p,o*a*n+s*h*p,s*h*n-o*a*p,s*a*n-o*h*p]}function qm(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==km&&(this._caching.lastFrame>=r&&r<=t||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function rm(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<lm(this.v-e)&&(this.v=e,this._mdf=!0);else for(var r=0,i=this.v.length;r<i;)e=t[r]*this.mult,1e-5<lm(this.v[r]-e)&&(this.v[r]=e,this._mdf=!0),r+=1}function sm(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=this._isFirstFrame;var t,e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)r=this.effectsSequence[t](r);this.setVValue(r),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function tm(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function um(t,e,r,i){this.propType="unidimensional",this.mult=r||1,this.data=e,this.v=r?e.k*r:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function vm(t,e,r,i){this.propType="multidimensional",this.mult=r||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var s,a=e.k.length;this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a);createTypedArray("float32",a);for(this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function wm(t,e,r,i){this.propType="unidimensional",this.keyframes=e.k,this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:km,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=km,this.pv=km,this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.effectsSequence=[qm.bind(this)],this.addEffect=tm}function xm(t,e,r,i){this.propType="multidimensional";var s,a,n,o,h,p=e.k.length;for(s=0;s<p-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s].e&&(a=e.k[s].s,n=e.k[s].e,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[qm.bind(this)],this.keyframes=e.k,this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.frameId=-1;var l=e.k[0].s.length;for(this.v=createTypedArray("float32",l),this.pv=createTypedArray("float32",l),s=0;s<l;s+=1)this.v[s]=km,this.pv[s]=km;this._caching={lastFrame:km,lastIndex:0,value:createTypedArray("float32",l)},this.addEffect=tm}var TransformPropertyFactory=(Qo.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||t){if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var e,r,i=this.elem.globalData.frameRate;if(this.p&&this.p.keyframes&&this.p.getValueAtTime)r=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(e=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(e=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.01)/i,0)):(e=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){e=[],r=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(e[0]=s.getValueAtTime((s.keyframes[0].t+.01)/i,0),e[1]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[0]=s.getValueAtTime(s.keyframes[0].t/i,0),r[1]=a.getValueAtTime(a.keyframes[0].t/i,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(e[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/i,0),e[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/i,0),r[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0)):(e=[s.pv,a.pv],r[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/i,s.offsetTime),r[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime))}this.v.rotate(-Math.atan2(e[1]-r[1],e[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(!this.a.k&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}if(this.r){if(this.r.effectsSequence.length)return;this.pre.rotate(-this.r.v),this.appliedTransformations=4}else this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],Qo),Qo.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},Qo.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,r){return new Qo(t,e,r)}});function Qo(t,e,r){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(r||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var i,s=e.or.k.length;for(i=0;i<s;i+=1)e.or.k[i].to=e.or.k[i].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r<e;)this.v[r]=point_pool.newElement(),this.o[r]=point_pool.newElement(),this.i[r]=point_pool.newElement(),r+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,r,i,s){var a;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o}a[i]&&(!a[i]||s)||(a[i]=point_pool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],r[n][0],r[n][1],a,!1),n-=1;return t};var ShapePropertyFactory=function(){var s=-999999;function t(t,e,r){var i,s,a,n,o,h,p,l,m,f=r.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)i=c[0].s[0],a=!0,f=0;else if(t>=c[c.length-1].t-this.offsetTime)i=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y=f,g=c.length-1,v=!0;v&&(d=c[y],!((u=c[y+1]).t-this.offsetTime>t));)y<g-1?y+=1:v=!1;if(f=y,!(a=1===d.h)){if(t>=u.t-this.offsetTime)l=1;else if(t<d.t-this.offsetTime)l=0;else{var P;d.__fnct?P=d.__fnct:(P=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,d.__fnct=P),l=P((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}i=d.s[0]}for(h=e._length,p=i.i[0].length,r.lastIndex=f,n=0;n<h;n+=1)for(o=0;o<p;o+=1)m=a?i.i[n][o]:i.i[n][o]+(s.i[n][o]-i.i[n][o])*l,e.i[n][o]=m,m=a?i.o[n][o]:i.o[n][o]+(s.o[n][o]-i.o[n][o])*l,e.o[n][o]=m,m=a?i.v[n][o]:i.v[n][o]+(s.v[n][o]-i.v[n][o])*l,e.v[n][o]=m}function a(){this.paths=this.localShapeCollection}function e(t){!function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var r,i=t._length;for(r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return!1;return!0}(this.v,t)&&(this.v=shape_pool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function r(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=!1;var t,e=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k,r=this.effectsSequence.length;for(t=0;t<r;t+=1)e=this.effectsSequence[t](e);this.setVValue(e),this.lock=!1,this.frameId=this.elem.globalData.frameId}}function n(t,e,r){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var i=3===r?e.pt.k:e.ks.k;this.v=shape_pool.clone(i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=a,this.effectsSequence=[]}function i(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,r){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=3===r?e.pt.k:e.ks.k,this.k=!0,this.kf=!0;var i=this.keyframes[0].s[0].i.length;this.keyframes[0].s[0].i[0].length;this.v=shape_pool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=a,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,i=this._caching.lastFrame;return i!==s&&(i<e&&t<e||r<i&&r<t)||(this._caching.lastIndex=i<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}n.prototype.interpolateShape=t,n.prototype.getValue=r,n.prototype.setVValue=e,n.prototype.addEffect=i,o.prototype.getValue=r,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=i;var h,p=(h=roundCorner,l.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-i,a.v[1][0]=s?t+r:t-r,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+i,a.v[3][0]=s?t-r:t+r,a.v[3][1]=e,a.i[0][0]=s?t-r*h:t+r*h,a.i[0][1]=e-i,a.i[1][0]=s?t+r:t-r,a.i[1][1]=e-i*h,a.i[2][0]=s?t+r*h:t-r*h,a.i[2][1]=e+i,a.i[3][0]=s?t-r:t+r,a.i[3][1]=e+i*h,a.o[0][0]=s?t+r*h:t-r*h,a.o[0][1]=e-i,a.o[1][0]=s?t+r:t-r,a.o[1][1]=e+i*h,a.o[2][0]=s?t-r*h:t+r*h,a.o[2][1]=e+i,a.o[3][0]=s?t-r:t+r,a.o[3][1]=e-i*h}},extendPrototype([DynamicPropertyContainer],l),l);function l(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}var m=(f.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,r,i,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,p=this.os.v,l=this.is.v,m=2*Math.PI*o/(2*s),f=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(t=this.v._length=0;t<s;t+=1){r=n?p:l,i=n?m:f;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*i*r*d,y-v*i*r*d,u+g*i*r*d,y+v*i*r*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),r=2*Math.PI/e,i=this.or.v,s=this.os.v,a=2*Math.PI*i/(4*e),n=-Math.PI/2,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=i*Math.cos(n),p=i*Math.sin(n),l=0===h&&0===p?0:p/Math.sqrt(h*h+p*p),m=0===h&&0===p?0:-h/Math.sqrt(h*h+p*p);h+=+this.p.v[0],p+=+this.p.v[1],this.v.setTripleAt(h,p,h-l*a*s*o,p-m*a*s*o,h+l*a*s*o,p+m*a*s*o,t,!0),n+=r*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],f),f);function f(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}var c=(d.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=bm_min(r,i,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+s,t+r,e-i+a,0,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-a,t+r,e+i-s,1,!0),0!==s?(this.v.setTripleAt(t+r-s,e+i,t+r-s,e+i,t+r-a,e+i,2,!0),this.v.setTripleAt(t-r+s,e+i,t-r+a,e+i,t-r+s,e+i,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-s,t-r,e+i-a,4,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+a,t-r,e-i+s,5,!0),this.v.setTripleAt(t-r+s,e-i,t-r+s,e-i,t-r+a,e-i,6,!0),this.v.setTripleAt(t+r-s,e-i,t+r-a,e-i,t+r-s,e-i,7,!0)):(this.v.setTripleAt(t-r,e+i,t-r+a,e+i,t-r,e+i,2),this.v.setTripleAt(t-r,e-i,t-r,e-i+a,t-r,e-i,3))):(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+a,t+r,e-i+s,0,!0),0!==s?(this.v.setTripleAt(t+r-s,e-i,t+r-s,e-i,t+r-a,e-i,1,!0),this.v.setTripleAt(t-r+s,e-i,t-r+a,e-i,t-r+s,e-i,2,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+s,t-r,e-i+a,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-a,t-r,e+i-s,4,!0),this.v.setTripleAt(t-r+s,e+i,t-r+s,e+i,t-r+a,e+i,5,!0),this.v.setTripleAt(t+r-s,e+i,t+r-a,e+i,t+r-s,e+i,6,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-s,t+r,e+i-a,7,!0)):(this.v.setTripleAt(t-r,e-i,t-r+a,e-i,t-r,e-i,1,!0),this.v.setTripleAt(t-r,e+i,t-r,e+i-a,t-r,e+i,2,!0),this.v.setTripleAt(t+r,e+i,t+r-a,e+i,t+r,e+i,3,!0)))},getValue:function(t){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:a},extendPrototype([DynamicPropertyContainer],d),d);function d(t,e){this.v=shape_pool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}var u={getShapeProp:function(t,e,r){var i;return 3===r||4===r?i=(3===r?e.pt:e.ks).k.length?new o(t,e,r):new n(t,e,r):5===r?i=new c(t,e):6===r?i=new p(t,e):7===r&&(i=new m(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return o}};return u}(),ShapeModifiers=(Tr={},Ur={},Tr.registerModifier=function(t,e){Ur[t]||(Ur[t]=e)},Tr.getModifier=function(t,e,r){return new Ur[t](e,r)},Tr),Tr,Ur;function ShapeModifier(){}function TrimModifier(){}function RoundCornersModifier(){}function RepeaterModifier(){}function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}function DashProperty(t,e,r,i){this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=r,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(i);var s,a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function GradientProperty(t,e,r){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(r),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){var e={shape:t.sh,data:t,localShapeCollection:shapeCollection_pool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,r,i,s){var a=[];e<=1?a.push({s:t,e:e}):1<=t?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],p=a.length;for(n=0;n<p;n+=1){var l,m;if((o=a[n]).e*s<i||o.s*s>i+r);else l=o.s*s<=i?0:(o.s*s-i)/r,m=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([l,m])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e<r;e+=1)segments_length_pool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,r,i;if(this._mdf||t){var s=this.o.v%360/360;if(s<0&&(s+=1),e=(1<this.s.v?1:this.s.v<0?0:this.s.v)+s,(r=(1<this.e.v?1:this.e.v<0?0:this.e.v)+s)<e){var a=e;e=r,r=a}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var n,o,h,p,l,m,f=this.shapes.length,c=0;if(r===e)for(n=0;n<f;n+=1)this.shapes[n].localShapeCollection.releaseShapes(),this.shapes[n].shape._mdf=!0,this.shapes[n].shape.paths=this.shapes[n].localShapeCollection;else if(1===r&&0===e||0===r&&1===e){if(this._mdf)for(n=0;n<f;n+=1)this.shapes[n].pathsData.length=0,this.shapes[n].shape._mdf=!0}else{var d,u,y=[];for(n=0;n<f;n+=1)if((d=this.shapes[n]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=d.shape.paths)._length,m=0,!d.shape._mdf&&d.pathsData.length)m=d.totalShapeLength;else{for(p=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)l=bez.getSegmentsLength(i.shapes[o]),p.push(l),m+=l.totalLength;d.totalShapeLength=m,d.pathsData=p}c+=m,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,P=r,b=0;for(n=f-1;0<=n;n-=1)if((d=this.shapes[n]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&1<f?(g=this.calculateShapeEdges(e,r,d.totalShapeLength,b,c),b+=d.totalShapeLength):g=[[v,P]],h=g.length,o=0;o<h;o+=1){v=g[o][0],P=g[o][1],y.length=0,P<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*P}):1<=v?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(P-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(P-1)}));var x=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(1<y.length)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var _=x.pop();this.addPaths(x,u),x=this.addShapes(d,y[1],_)}else this.addPaths(x,u),x=this.addShapes(d,y[1]);this.addPaths(x,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,r,i,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(r[0],r[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(i[0],i[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,r,i){e.setXYAt(t[1],t[5],"o",r),e.setXYAt(t[2],t[6],"i",r+1),i&&e.setXYAt(t[0],t[4],"v",r),e.setXYAt(t[3],t[7],"v",r+1)},TrimModifier.prototype.addShapes=function(t,e,r){var i,s,a,n,o,h,p,l,m=t.pathsData,f=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(l=r?(o=r._length,r._length):(r=shape_pool.newElement(),o=0),u.push(r),i=0;i<c;i+=1){for(h=m[i].lengths,r.c=f[i].c,a=f[i].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,r.c=!1;else{if(d>e.e){r.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[s],f[i].v[s],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[s],f[i].o[s-1],f[i].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1),d+=n.addedLength,o+=1}if(f[i].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[0],f[i].v[0],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[0],f[i].o[s-1],f[i].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1)}else r.c=!1;d+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[l][0],r.v[l][1],"i",l),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),d>e.e)break;i<c-1&&(r=shape_pool.newElement(),y=!0,u.push(r),o=0)}return u},ShapeModifiers.registerModifier("tm",TrimModifier),extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var r=shape_pool.newElement();r.c=t.c;var i,s,a,n,o,h,p,l,m,f,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=d=s[0]+(o[0]-s[0])*p,m=u=s[1]-(s[1]-o[1])*p,f=l-(l-s[0])*roundCorner,c=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=f=s[0]+(o[0]-s[0])*p,m=c=s[1]+(o[1]-s[1])*p,d=l-(l-s[0])*roundCorner,u=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g)):r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g):r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1;return r},RoundCornersModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(r=0;r<o;r+=1){if((a=this.shapes[r]).shape.paths,n=a.localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},ShapeModifiers.registerModifier("rd",RoundCornersModifier),extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,r,i,s,a){var n=a?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-s),h=i.s.v[1]+(1-i.s.v[1])*(1-s);t.translate(i.p.v[0]*n*s,i.p.v[1]*n*s,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*s),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),r.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),r.scale(a?1/o:o,a?1/h:h),r.translate(i.a.v[0],i.a.v[1],i.a.v[2])},RepeaterModifier.prototype.init=function(t,e,r,i){this.elem=t,this.arr=e,this.pos=r,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[r]);for(;0<r;)r-=1,this._elements.unshift(e[r]),1;this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){t.length;var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,r,i,s,a;if(this._mdf||t){var n,o=Math.ceil(this.c.v);if(this._groups.length<o){for(;this._groups.length<o;){var h={it:this.cloneElements(this._elements),ty:"gr"};h.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,h),this._groups.splice(0,0,h),this._currentCopies+=1}this.elem.reloadShapes()}for(i=a=0;i<=this._groups.length-1;i+=1)n=a<o,this._groups[i]._render=n,this.changeGroupRender(this._groups[i].it,n),a+=1;this._currentCopies=o;var p=this.o.v,l=p%1,m=0<p?Math.floor(p):Math.ceil(p),f=(this.tr.v.props,this.pMatrix.props),c=this.rMatrix.props,d=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var u,y,g=0;if(0<p){for(;g<m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),g+=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,l,!1),g+=l)}else if(p<0){for(;m<g;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),g-=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-l,!0),g-=l)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(y=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==g){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9],c[10],c[11],c[12],c[13],c[14],c[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),this.matrix.transform(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9],f[10],f[11],f[12],f[13],f[14],f[15]),u=0;u<y;u+=1)r[u]=this.matrix.props[u];this.matrix.reset()}else for(this.matrix.reset(),u=0;u<y;u+=1)r[u]=this.matrix.props[u];g+=1,a-=1,i+=s}}else for(a=this._currentCopies,i=0,s=1;a;)r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,i+=s},RepeaterModifier.prototype.addShape=function(){},ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shape_pool.release(this.shapes[t]);this._length=0},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,r=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<r;e+=1)"o"!=this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),GradientProperty.prototype.comparePoints=function(t,e){for(var r=0,i=this.o.length/2;r<i;){if(.01<Math.abs(t[4*r]-t[4*e+2*r]))return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,r,i,s=4*this.data.p;for(e=0;e<s;e+=1)r=e%4==0?100:255,i=Math.round(this.prop.v[e]*r),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)r=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty);var buildShapeString=function(t,e,r,i){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[s][0],n[s][1])+" "+i.applyToPointStringified(o[s][0],o[s][1]);return r&&e&&(h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},ImagePreloader=function(){},featureSupport=(Iv={maskType:!0},(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(Iv.maskType=!1),Iv),Iv,filtersFactory=(Jv={},Jv.createFilter=function(t){var e=createNS("filter");return e.setAttribute("id",t),e.setAttribute("filterUnits","objectBoundingBox"),e.setAttribute("x","0%"),e.setAttribute("y","0%"),e.setAttribute("width","100%"),e.setAttribute("height","100%"),e},Jv.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1"),t},Jv),Jv,assetLoader={load:function(t,e,r){var i,s=new XMLHttpRequest;s.open("GET",t,!0);try{s.responseType="json"}catch(t){}s.send(),s.onreadystatechange=function(){if(4==s.readyState)if(200==s.status)i=Pv(s),e(i);else try{i=Pv(s),e(i)}catch(t){r&&r(t)}}}};function Pv(t){return t.response&&"object"==typeof t.response?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):void 0}var assetLoader=null;function TextAnimatorProperty(t,e,r){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=r,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(r)}function TextAnimatorDataProperty(t,e,r){var i={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,r):i,rx:a.rx?s(t,a.rx,0,degToRads,r):i,ry:a.ry?s(t,a.ry,0,degToRads,r):i,sk:a.sk?s(t,a.sk,0,degToRads,r):i,sa:a.sa?s(t,a.sa,0,degToRads,r):i,s:a.s?s(t,a.s,1,.01,r):i,a:a.a?s(t,a.a,1,0,r):i,o:a.o?s(t,a.o,0,.01,r):i,p:a.p?s(t,a.p,1,0,r):i,sw:a.sw?s(t,a.sw,0,0,r):i,sc:a.sc?s(t,a.sc,1,0,r):i,fc:a.fc?s(t,a.fc,1,0,r):i,fh:a.fh?s(t,a.fh,0,0,r):i,fs:a.fs?s(t,a.fs,0,.01,r):i,fb:a.fb?s(t,a.fb,0,.01,r):i,t:a.t?s(t,a.t,0,0,r):i},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,r),this.s.t=e.s.t}function LetterProps(t,e,r,i,s,a){this.o=t,this.sw=e,this.sc=r,this.fc=i,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!r,fc:!!i,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,r=this._textData.a.length,i=PropertyFactory.getProp;for(t=0;t<r;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:this._textData.p.r,m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var r,i,s,a,n,o,h,p,l,m,f,c,d,u,y,g,v,P,b,x=this._moreOptions.alignment.v,_=this._animatorsData,S=this._textData,T=this.mHelper,A=this._renderType,C=this.renderedLetters.length,E=(this.data,t.l);if(this._hasMaskedPath){if(b=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,D=b.v;for(this._pathData.r&&(D=D.reverse()),n={tLength:0,segments:[]},a=D._length-1,s=g=0;s<a;s+=1)k=bez.buildBezierData(D.v[s],D.v[s+1],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[s+1][0]-D.v[s+1][0],D.i[s+1][1]-D.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,b.v.c&&(k=bez.buildBezierData(D.v[s],D.v[0],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[0][0]-D.v[0][0],D.i[0][1]-D.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=1,l=!(p=f=0),u=n.segments,o<0&&b.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),m=(d=u[f=u.length-1].points).length-1;o<0;)o+=d[m].partialLength,(m-=1)<0&&(m=(d=u[f-=1].points).length-1);c=(d=u[f].points)[m-1],y=(h=d[m]).partialLength}a=E.length,i=r=0;var M,I,w,F,V=1.2*t.finalSize*.714,R=!0;w=_.length;var L,z,O,B,N,G,j,J,K,q,H,W,X,Y=-1,Q=o,$=f,U=m,Z=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,it=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(E[s].n){for(rt&&(rt+=it);at<s;)E[at].animatorJustifyOffset=rt,at+=1;nt=!(rt=0)}else{for(I=0;I<w;I+=1)(M=_[I].a).t.propType&&(nt&&2===t.j&&(it+=M.t.v*st),(L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?rt+=M.t.v*L[0]*st:rt+=M.t.v*L*st);nt=!1}for(rt&&(rt+=it);at<s;)E[at].animatorJustifyOffset=rt,at+=1}for(s=0;s<a;s+=1){if(T.reset(),N=1,E[s].n)r=0,i+=t.yOffset,i+=R?1:0,o=Q,R=!1,0,this._hasMaskedPath&&(m=U,c=(d=u[f=$].points)[m-1],y=(h=d[m]).partialLength,p=0),X=q=W=tt="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Z!==E[s].line){switch(t.j){case 1:o+=g-t.lineWidths[E[s].line];break;case 2:o+=(g-t.lineWidths[E[s].line])/2}Z=E[s].line}Y!==E[s].ind&&(E[Y]&&(o+=E[Y].extra),o+=E[s].an/2,Y=E[s].ind),o+=x[0]*E[s].an/200;var ot=0;for(I=0;I<w;I+=1)(M=_[I].a).p.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?ot+=M.p.v[0]*L[0]:ot+=M.p.v[0]*L),M.a.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?ot+=M.a.v[0]*L[0]:ot+=M.a.v[0]*L);for(l=!0;l;)o+ot<=p+y||!d?(v=(o+ot-p)/h.partialLength,O=c.point[0]+(h.point[0]-c.point[0])*v,B=c.point[1]+(h.point[1]-c.point[1])*v,T.translate(-x[0]*E[s].an/200,-x[1]*V/100),l=!1):d&&(p+=h.partialLength,(m+=1)>=d.length&&(m=0,d=u[f+=1]?u[f].points:b.v.c?u[f=m=0].points:(p-=h.partialLength,null)),d&&(c=h,y=(h=d[m]).partialLength));z=E[s].an/2-E[s].add,T.translate(-z,0,0)}else z=E[s].an/2-E[s].add,T.translate(-z,0,0),T.translate(-x[0]*E[s].an/200,-x[1]*V/100,0);for(E[s].l/2,I=0;I<w;I+=1)(M=_[I].a).t.propType&&(L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars),0===r&&0===t.j||(this._hasMaskedPath?L.length?o+=M.t.v*L[0]:o+=M.t.v*L:L.length?r+=M.t.v*L[0]:r+=M.t.v*L));for(E[s].l/2,t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(G=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(J=[t.fc[0],t.fc[1],t.fc[2]]),I=0;I<w;I+=1)(M=_[I].a).a.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?T.translate(-M.a.v[0]*L[0],-M.a.v[1]*L[1],M.a.v[2]*L[2]):T.translate(-M.a.v[0]*L,-M.a.v[1]*L,M.a.v[2]*L));for(I=0;I<w;I+=1)(M=_[I].a).s.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?T.scale(1+(M.s.v[0]-1)*L[0],1+(M.s.v[1]-1)*L[1],1):T.scale(1+(M.s.v[0]-1)*L,1+(M.s.v[1]-1)*L,1));for(I=0;I<w;I+=1){if(M=_[I].a,L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars),M.sk.propType&&(L.length?T.skewFromAxis(-M.sk.v*L[0],M.sa.v*L[1]):T.skewFromAxis(-M.sk.v*L,M.sa.v*L)),M.r.propType&&(L.length?T.rotateZ(-M.r.v*L[2]):T.rotateZ(-M.r.v*L)),M.ry.propType&&(L.length?T.rotateY(M.ry.v*L[1]):T.rotateY(M.ry.v*L)),M.rx.propType&&(L.length?T.rotateX(M.rx.v*L[0]):T.rotateX(M.rx.v*L)),M.o.propType&&(L.length?N+=(M.o.v*L[0]-N)*L[0]:N+=(M.o.v*L-N)*L),t.strokeWidthAnim&&M.sw.propType&&(L.length?j+=M.sw.v*L[0]:j+=M.sw.v*L),t.strokeColorAnim&&M.sc.propType)for(K=0;K<3;K+=1)L.length?G[K]=G[K]+(M.sc.v[K]-G[K])*L[0]:G[K]=G[K]+(M.sc.v[K]-G[K])*L;if(t.fillColorAnim&&t.fc){if(M.fc.propType)for(K=0;K<3;K+=1)L.length?J[K]=J[K]+(M.fc.v[K]-J[K])*L[0]:J[K]=J[K]+(M.fc.v[K]-J[K])*L;M.fh.propType&&(J=L.length?addHueToRGB(J,M.fh.v*L[0]):addHueToRGB(J,M.fh.v*L)),M.fs.propType&&(J=L.length?addSaturationToRGB(J,M.fs.v*L[0]):addSaturationToRGB(J,M.fs.v*L)),M.fb.propType&&(J=L.length?addBrightnessToRGB(J,M.fb.v*L[0]):addBrightnessToRGB(J,M.fb.v*L))}}for(I=0;I<w;I+=1)(M=_[I].a).p.propType&&(L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars),this._hasMaskedPath?L.length?T.translate(0,M.p.v[1]*L[0],-M.p.v[2]*L[1]):T.translate(0,M.p.v[1]*L,-M.p.v[2]*L):L.length?T.translate(M.p.v[0]*L[0],M.p.v[1]*L[1],-M.p.v[2]*L[2]):T.translate(M.p.v[0]*L,M.p.v[1]*L,-M.p.v[2]*L));if(t.strokeWidthAnim&&(q=j<0?0:j),t.strokeColorAnim&&(H="rgb("+Math.round(255*G[0])+","+Math.round(255*G[1])+","+Math.round(255*G[2])+")"),t.fillColorAnim&&t.fc&&(W="rgb("+Math.round(255*J[0])+","+Math.round(255*J[1])+","+Math.round(255*J[2])+")"),this._hasMaskedPath){if(T.translate(0,-t.ls),T.translate(0,x[1]*V/100+i,0),S.p.p){P=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(P)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),T.rotate(-ht*Math.PI/180)}T.translate(O,B,0),o-=x[0]*E[s].an/200,E[s+1]&&Y!==E[s+1].ind&&(o+=E[s].an/2,o+=t.tr/1e3*t.finalSize)}else{switch(T.translate(r,i,0),t.ps&&T.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:T.translate(E[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[E[s].line]),0,0);break;case 2:T.translate(E[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[E[s].line])/2,0,0)}T.translate(0,-t.ls),T.translate(z,0,0),T.translate(x[0]*E[s].an/200,x[1]*V/100,0),r+=E[s].l+t.tr/1e3*t.finalSize}"html"===A?tt=T.toCSS():"svg"===A?tt=T.to2dCSS():et=[T.props[0],T.props[1],T.props[2],T.props[3],T.props[4],T.props[5],T.props[6],T.props[7],T.props[8],T.props[9],T.props[10],T.props[11],T.props[12],T.props[13],T.props[14],T.props[15]],X=N}C<=s?(F=new LetterProps(X,q,H,W,tt,et),this.renderedLetters.push(F),C+=1,this.lettersChangedFlag=!0):(F=this.renderedLetters[s],this.lettersChangedFlag=F.update(X,q,H,W,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),LetterProps.prototype.update=function(t,e,r,i,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==r&&(this.sc=r,n=this._mdf.sc=!0),this.fc!==i&&(this.fc=i,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{this.lock=!0,this._mdf=!1;var i,s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;i<s;i+=1)a=r!==this.keysIndex?this.effectsSequence[i](a,a.t):this.effectsSequence[i](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.pv=this.v=this.currentData,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,r=0,i=t.length;r<=i-1&&(t[r].s,!(r===i-1||t[r+1].t>e));)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e=FontManager.getCombinedCharacterCodes(),r=[],i=0,s=t.length;i<s;)-1!==e.indexOf(t.charCodeAt(i))?r[r.length-1]+=t.charAt(i):r.push(t.charAt(i)),i+=1;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,p=this.data,l=[],m=0,f=p.m.g,c=0,d=0,u=0,y=[],g=0,v=0,P=h.getFontByName(t.f),b=0,x=P.fStyle?P.fStyle.split(" "):[],_="normal",S="normal";for(r=x.length,e=0;e<r;e+=1)switch(x[e].toLowerCase()){case"italic":S="italic";break;case"bold":_="700";break;case"black":_="900";break;case"medium":_="500";break;case"regular":case"normal":_="400";break;case"light":case"thin":_="200"}t.fWeight=P.fWeight||_,t.fStyle=S,r=t.t.length,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),t.finalLineHeight=t.lh;var T,A=t.tr/1e3*t.finalSize;if(t.sz)for(var C,E,k=!0,D=t.sz[0],M=t.sz[1];k;){g=C=0,r=(E=this.buildFinalText(t.t)).length,A=t.tr/1e3*t.finalSize;var I=-1;for(e=0;e<r;e+=1)T=E[e].charCodeAt(0),i=!1," "===E[e]?I=e:13!==T&&3!==T||(i=!(g=0),C+=t.finalLineHeight||1.2*t.finalSize),D<g+(b=h.chars?(o=h.getCharData(E[e],P.fStyle,P.fFamily),i?0:o.w*t.finalSize/100):h.measureText(E[e],t.f,t.finalSize))&&" "!==E[e]?(-1===I?r+=1:e=I,C+=t.finalLineHeight||1.2*t.finalSize,E.splice(e,I===e?1:0,"\r"),I=-1,g=0):(g+=b,g+=A);C+=P.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&M<C?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=E,r=t.finalText.length,k=!1)}g=-A;var w,F=b=0;for(e=0;e<r;e+=1)if(i=!1,T=(w=t.finalText[e]).charCodeAt(0)," "===w?s=" ":13===T||3===T?(F=0,y.push(g),v=v<g?g:v,g=-2*A,i=!(s=""),u+=1):s=t.finalText[e],b=h.chars?(o=h.getCharData(w,P.fStyle,h.getFontByName(t.f).fFamily),i?0:o.w*t.finalSize/100):h.measureText(s,t.f,t.finalSize)," "===w?F+=b+A:(g+=b+A+F,F=0),l.push({l:b,an:b,add:c,n:i,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==f){if(c+=b,""===s||" "===s||e===r-1){for(""!==s&&" "!==s||(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;m+=1,c=0}}else if(3==f){if(c+=b,""===s||e===r-1){for(""===s&&(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;c=0,m+=1}}else l[m].ind=m,l[m].extra=0,m+=1;if(t.l=l,v=v<g?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var V,R,L=p.a;n=L.length;var z,O,B=[];for(a=0;a<n;a+=1){for((V=L[a]).a.sc&&(t.strokeColorAnim=!0),V.a.sw&&(t.strokeWidthAnim=!0),(V.a.fc||V.a.fh||V.a.fs||V.a.fb)&&(t.fillColorAnim=!0),O=0,z=V.s.b,e=0;e<r;e+=1)(R=l[e]).anIndexes[a]=O,(1==z&&""!==R.val||2==z&&""!==R.val&&" "!==R.val||3==z&&(R.n||" "==R.val||e==r-1)||4==z&&(R.n||e==r-1))&&(1===V.s.rn&&B.push(O),O+=1);p.a[a].s.totalChars=O;var N,G=-1;if(1===V.s.rn)for(e=0;e<r;e+=1)G!=(R=l[e]).anIndexes[a]&&(G=R.anIndexes[a],N=B.splice(Math.floor(Math.random()*B.length),1)[0]),R.anIndexes[a]=N}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=P.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var r=this.copyData({},this.data.d.k[e].s);r=this.copyData(r,t),this.data.d.k[e].s=r,this.recalculate(e),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=(cz=Math.max,dz=Math.min,ez=Math.floor,fz.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e=BezierFactory.getBezierEasing(this.ne.v/100,0,1-this.xe.v/100,1).get,r=0,i=this.finalS,s=this.finalE,a=this.data.sh;if(2==a)r=e(r=s===i?s<=t?1:0:cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(3==a)r=e(r=s===i?s<=t?0:1:1-cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(4==a)s===i?r=0:(r=cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)))<.5?r*=2:r=1-2*(r-.5),r=e(r);else if(5==a){if(s===i)r=0;else{var n=s-i,o=-n/2+(t=dz(cz(0,t+.5-i),s-i)),h=n/2;r=Math.sqrt(1-o*o/(h*h))}r=e(r)}else r=6==a?e(r=s===i?0:(t=dz(cz(0,t+.5-i),s-i),(1+Math.cos(Math.PI+2*Math.PI*t/(s-i)))/2)):(t>=ez(i)&&(r=t-i<0?1-(i-t):cz(0,dz(s-t,1))),e(r));return r*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(s<i){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],fz),{getTextSelectorProp:function(t,e,r){return new fz(t,e,r)}}),cz,dz,ez;function fz(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}var pool_factory=function(t,e,r,i){var s=0,a=t,n=createSizedArray(a);function o(){return s?n[s-=1]:e()}return{newElement:o,release:function(t){s===a&&(n=pooling.double(n),a*=2),r&&r(t),n[s]=t,s+=1}}},pooling={double:function(t){return t.concat(createSizedArray(t.length))}},point_pool=pool_factory(8,function(){return createTypedArray("float32",2)}),shape_pool=(Vz=pool_factory(4,function(){return new ShapePath},function(t){var e,r=t._length;for(e=0;e<r;e+=1)point_pool.release(t.v[e]),point_pool.release(t.i[e]),point_pool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}),Vz.clone=function(t){var e,r=Vz.newElement(),i=void 0===t._length?t.v.length:t._length;for(r.setLength(i),r.c=t.c,e=0;e<i;e+=1)r.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return r},Vz),Vz,shapeCollection_pool=(cA={newShapeCollection:function(){var t;t=dA?fA[dA-=1]:new ShapeCollection;return t},release:function(t){var e,r=t._length;for(e=0;e<r;e+=1)shape_pool.release(t.shapes[e]);t._length=0,dA===eA&&(fA=pooling.double(fA),eA*=2);fA[dA]=t,dA+=1}},dA=0,eA=4,fA=createSizedArray(eA),cA),cA,dA,eA,fA,segments_length_pool=pool_factory(8,function(){return{lengths:[],totalLength:0}},function(t){var e,r=t.lengths.length;for(e=0;e<r;e+=1)bezier_length_pool.release(t.lengths[e]);t.lengths.length=0}),bezier_length_pool=pool_factory(8,function(){return{addedLength:0,percents:createTypedArray("float32",defaultCurveSegments),lengths:createTypedArray("float32",defaultCurveSegments)}});function BaseRenderer(){}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var r="";if(e&&e.title){var i=createNS("title"),s=createElementID();i.setAttribute("id",s),i.textContent=e.title,this.svgElement.appendChild(i),r+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),r+=" "+n}r&&this.svgElement.setAttribute("aria-labelledby",r);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!e||!1!==e.hideOnTransparent,viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||""},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",className:e&&e.className||""},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas"}function MaskElement(t,e,r){this.data=t,this.element=e,this.globalData=r,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var i,s=this.globalData.defs,a=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(a),this.solidPath="";var n,o,h,p,l,m,f,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(i=0;i<a;i++)if(("a"!==c[i].mode&&"n"!==c[i].mode||c[i].inv||100!==c[i].o.k)&&(v=g="mask"),"s"!=c[i].mode&&"i"!=c[i].mode||0!==d?p=null:((p=createNS("rect")).setAttribute("fill","#ffffff"),p.setAttribute("width",this.element.comp.data.w||0),p.setAttribute("height",this.element.comp.data.h||0),u.push(p)),n=createNS("path"),"n"!=c[i].mode){var P;if(d+=1,n.setAttribute("fill","s"===c[i].mode?"#000000":"#ffffff"),n.setAttribute("clip-rule","nonzero"),0!==c[i].x.k?(v=g="mask",f=PropertyFactory.getProp(this.element,c[i].x,0,null,this.element),P=createElementID(),(l=createNS("filter")).setAttribute("id",P),(m=createNS("feMorphology")).setAttribute("operator","erode"),m.setAttribute("in","SourceGraphic"),m.setAttribute("radius","0"),l.appendChild(m),s.appendChild(l),n.setAttribute("stroke","s"===c[i].mode?"#000000":"#ffffff")):f=m=null,this.storedData[i]={elem:n,x:f,expan:m,lastPath:"",lastOperator:"",filterId:P,lastRadius:0},"i"==c[i].mode){h=u.length;var b=createNS("g");for(o=0;o<h;o+=1)b.appendChild(u[o]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",y+"_"+d),x.appendChild(n),s.appendChild(x),b.setAttribute("mask","url("+locationHref+"#"+y+"_"+d+")"),u.length=0,u.push(b)}else u.push(n);c[i].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[i]={elem:n,lastPath:"",op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),invRect:p},this.viewData[i].prop.k||this.drawPath(c[i],this.viewData[i].prop.v,this.viewData[i])}else this.viewData[i]={op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),elem:n,lastPath:""},s.appendChild(n);for(this.maskElement=createNS(g),a=u.length,i=0;i<a;i+=1)this.maskElement.appendChild(u[i]);0<d&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+locationHref+"#"+y+")"),s.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}function HierarchyElement(){}function FrameElement(){}function TransformElement(){}function RenderableElement(){}function RenderableDOMElement(){}function ProcessedElement(t,e){this.elem=t,this.pos=e}function SVGShapeData(t,e,r){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=r,this.lvl=e,this._isAnimated=!!r.k;for(var i=0,s=t.length;i<s;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}function CVShapeData(t,e,r,i){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s=4;"rc"==e.ty?s=5:"el"==e.ty?s=6:"sr"==e.ty&&(s=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,s,t);var a,n,o=r.length;for(a=0;a<o;a+=1)r[a].closed||(n={transforms:i.addTransformSequence(r[a].transforms),trNodes:[]},this.styledShapes.push(n),r[a].elements.push(n))}function BaseElement(){}function NullElement(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initFrame(),this.initTransform(t,e,r),this.initHierarchy()}function SVGBaseElement(){}function IShapeElement(){}function ITextElement(){}function ICompElement(){}function IImageElement(t,e,r){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,r),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ISolidElement(t,e,r){this.initElement(t,e,r)}function SVGShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,r),this.prevViewData=[]}function CVContextData(){this.saved=[],this.cArrPos=0,this.cTr=new Matrix,this.cO=1;var t;for(this.savedOp=createTypedArray("float32",15),t=0;t<15;t+=1)this.saved[t]=createTypedArray("float32",16);this._length=15}function CVBaseElement(){}function CVCompElement(t,e,r){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,r),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CVMaskElement(t,e){this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r,i=this.masksProperties.length,s=!1;for(r=0;r<i;r++)"n"!==this.masksProperties[r].mode&&(s=!0),this.viewData[r]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[r],3);(this.hasMasks=s)&&this.element.addRenderableComponent(this)}function CVShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,r)}function CVSolidElement(t,e,r){this.initElement(t,e,r)}function CVEffects(){}BaseRenderer.prototype.checkLayers=function(t){var e,r,i=this.layers.length;for(this.completeLayers=!0,e=i-1;0<=e;e--)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 13:return this.createCamera(t)}return this.createNull(t)},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){this.completeLayers=!1;var e,r,i=t.length,s=this.layers.length;for(e=0;e<i;e+=1)for(r=0;r<s;){if(this.layers[r].id==t[e].id){this.layers[r]=t[e];break}r+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,r){for(var i=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(i[a]&&!0!==i[a]?(r.push(i[a]),i[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,r):t.setHierarchy(r)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,r=t.length;for(e=0;e<r;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}},extendPrototype([BaseRenderer],SVGRenderer),SVGRenderer.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRenderer.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRenderer.prototype.createText=function(t){return new SVGTextElement(t,this.globalData,this)},SVGRenderer.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},SVGRenderer.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRenderer.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)"),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var r=createNS("clipPath"),i=createNS("rect");i.setAttribute("width",t.w),i.setAttribute("height",t.h),i.setAttribute("x",0),i.setAttribute("y",0);var s=createElementID();r.setAttribute("id",s),r.appendChild(i),this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+s+")"),e.appendChild(r),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRenderer.prototype.destroy=function(){this.animationItem.wrapper.innerHTML="",this.layerElement=null,this.globalData.defs=null;var t,e=this.layers?this.layers.length:0;for(t=0;t<e;t++)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRenderer.prototype.updateContainerSize=function(){},SVGRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){e[t]=!0;var r=this.createItem(this.layers[t]);e[t]=r,expressionsPlugin&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(r),r.initExpressions()),this.appendElementInPos(r,t),this.layers[t].tt&&(this.elements[t-1]&&!0!==this.elements[t-1]?r.setMatte(e[t-1].layerId):(this.buildItem(t-1),this.addPendingElement(r)))}},SVGRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,r=this.elements.length;e<r;){if(this.elements[e]===t){t.setMatte(this.elements[e-1].layerId);break}e+=1}}},SVGRenderer.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var e,r=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=r-1;0<=e;e--)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<r;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRenderer.prototype.appendElementInPos=function(t,e){var r=t.getBaseElement();if(r){for(var i,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(r,i):this.layerElement.appendChild(r)}},SVGRenderer.prototype.hide=function(){this.layerElement.style.display="none"},SVGRenderer.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseRenderer],CanvasRenderer),CanvasRenderer.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRenderer.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRenderer.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},CanvasRenderer.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRenderer.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRenderer.prototype.ctxTransform=function(t){if(1!==t[0]||0!==t[1]||0!==t[4]||1!==t[5]||0!==t[12]||0!==t[13])if(this.renderConfig.clearCanvas){this.transformMat.cloneFromProps(t);var e=this.contextData.cTr.props;this.transformMat.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]),this.contextData.cTr.cloneFromProps(this.transformMat.props);var r=this.contextData.cTr.props;this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13])}else this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRenderer.prototype.ctxOpacity=function(t){if(!this.renderConfig.clearCanvas)return this.canvasContext.globalAlpha*=t<0?0:t,void(this.globalData.currentGlobalAlpha=this.contextData.cO);this.contextData.cO*=t<0?0:t,this.globalData.currentGlobalAlpha!==this.contextData.cO&&(this.canvasContext.globalAlpha=this.contextData.cO,this.globalData.currentGlobalAlpha=this.contextData.cO)},CanvasRenderer.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRenderer.prototype.save=function(t){if(this.renderConfig.clearCanvas){t&&this.canvasContext.save();var e=this.contextData.cTr.props;this.contextData._length<=this.contextData.cArrPos&&this.contextData.duplicate();var r,i=this.contextData.saved[this.contextData.cArrPos];for(r=0;r<16;r+=1)i[r]=e[r];this.contextData.savedOp[this.contextData.cArrPos]=this.contextData.cO,this.contextData.cArrPos+=1}else this.canvasContext.save()},CanvasRenderer.prototype.restore=function(t){if(this.renderConfig.clearCanvas){t&&(this.canvasContext.restore(),this.globalData.blendMode="source-over"),this.contextData.cArrPos-=1;var e,r=this.contextData.saved[this.contextData.cArrPos],i=this.contextData.cTr.props;for(e=0;e<16;e+=1)i[e]=r[e];this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),r=this.contextData.savedOp[this.contextData.cArrPos],this.contextData.cO=r,this.globalData.currentGlobalAlpha!==r&&(this.canvasContext.globalAlpha=r,this.globalData.currentGlobalAlpha=r)}else this.canvasContext.restore()},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRenderer.prototype.updateContainerSize=function(){var t,e,r,i;if(this.reset(),this.animationItem.wrapper&&this.animationItem.container?(t=this.animationItem.wrapper.offsetWidth,e=this.animationItem.wrapper.offsetHeight,this.animationItem.container.setAttribute("width",t*this.renderConfig.dpr),this.animationItem.container.setAttribute("height",e*this.renderConfig.dpr)):(t=this.canvasContext.canvas.width*this.renderConfig.dpr,e=this.canvasContext.canvas.height*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var s=this.renderConfig.preserveAspectRatio.split(" "),a=s[1]||"meet",n=s[0]||"xMidYMid",o=n.substr(0,4),h=n.substr(4);(r=t/e)<(i=this.transformCanvas.w/this.transformCanvas.h)&&"meet"===a||i<r&&"slice"===a?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=t/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=e/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"==this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0;this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRenderer.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&(this.animationItem.wrapper.innerHTML=""),t=(this.layers?this.layers.length:0)-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRenderer.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r,i=this.layers.length;for(this.completeLayers||this.checkLayers(t),r=0;r<i;r++)(this.completeLayers||this.elements[r])&&this.elements[r].prepareFrame(t-this.layers[r].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&this.elements[r].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){var r=this.createItem(this.layers[t],this,this.globalData);(e[t]=r).initExpressions()}},CanvasRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRenderer.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRenderer.prototype.show=function(){this.animationItem.container.style.display="block"},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h},this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,r=this.element.finalTransform.mat,i=this.masksProperties.length;for(e=0;e<i;e++)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&(this.viewData[e].invRect.setAttribute("x",-r.props[12]),this.viewData[e].invRect.setAttribute("y",-r.props[13])),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+locationHref+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,r){var i,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,i=1;i<s;i+=1)a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&1<s&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var r,i=this.dynamicProperties.length;for(r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},TransformElement.prototype={initTransform:function(){this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_opMdf:!1,mat:new Matrix},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,r=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;r<i;){if(this.hierarchy[r].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}r+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),r=0;r<i;r+=1)t=this.hierarchy[r].finalTransform.mProp.v.props,e.transform(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var r=!0,i=this.comp;r;)i.finalTransform?(i.data.hasMask&&e.splice(0,0,i.finalTransform),i=i.comp):r=!1;var s,a,n=e.length;for(s=0;s<n;s+=1)a=e[s].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,r=t.length,i="_";for(e=0;e<r;e+=1)i+=t[e].transform.key+"_";var s=this.sequences[i];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[i]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var r,i=0,s=t.transforms.length,a=e;i<s&&!e;){if(t.transforms[i].transform.mProps._mdf){a=!0;break}i+=1}if(a)for(t.finalTransform.reset(),i=s-1;0<=i;i-=1)r=t.transforms[i].transform.mProps.v.props,t.finalTransform.transform(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11],r[12],r[13],r[14],r[15]);t._mdf=a},processSequences:function(t){var e,r=this.sequenceList.length;for(e=0;e<r;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return"_"+this.transform_key_count++}},CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){this.layerInterface=LayerExpressionInterface(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var t=EffectsExpressionInterface.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(t),0===this.data.ty||this.data.xt?this.compInterface=CompExpressionInterface(this):4===this.data.ty?(this.layerInterface.shapeInterface=ShapeExpressionInterface(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=TextExpressionInterface(this),this.layerInterface.text=this.layerInterface.textInterface)},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,r){this.globalData=e,this.comp=r,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t,e,r,i=null;if(this.data.td){if(3==this.data.td||1==this.data.td){var s=createNS("mask");s.setAttribute("id",this.layerId),s.setAttribute("mask-type",3==this.data.td?"luminance":"alpha"),s.appendChild(this.layerElement),i=s,this.globalData.defs.appendChild(s),featureSupport.maskType||1!=this.data.td||(s.setAttribute("mask-type","luminance"),t=createElementID(),e=filtersFactory.createFilter(t),this.globalData.defs.appendChild(e),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(r=createNS("g")).appendChild(this.layerElement),i=r,s.appendChild(r),r.setAttribute("filter","url("+locationHref+"#"+t+")"))}else if(2==this.data.td){var a=createNS("mask");a.setAttribute("id",this.layerId),a.setAttribute("mask-type","alpha");var n=createNS("g");a.appendChild(n),t=createElementID(),e=filtersFactory.createFilter(t);var o=createNS("feComponentTransfer");o.setAttribute("in","SourceGraphic"),e.appendChild(o);var h=createNS("feFuncA");h.setAttribute("type","table"),h.setAttribute("tableValues","1.0 0.0"),o.appendChild(h),this.globalData.defs.appendChild(e);var p=createNS("rect");p.setAttribute("width",this.comp.data.w),p.setAttribute("height",this.comp.data.h),p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("fill","#ffffff"),p.setAttribute("opacity","0"),n.setAttribute("filter","url("+locationHref+"#"+t+")"),n.appendChild(p),n.appendChild(this.layerElement),i=n,featureSupport.maskType||(a.setAttribute("mask-type","luminance"),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),r=createNS("g"),n.appendChild(p),r.appendChild(this.layerElement),i=r,n.appendChild(r)),this.globalData.defs.appendChild(a)}}else this.data.tt?(this.matteElement.appendChild(this.layerElement),i=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var l=createNS("clipPath"),m=createNS("path");m.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var f=createElementID();if(l.setAttribute("id",f),l.appendChild(m),this.globalData.defs.appendChild(l),this.checkMasks()){var c=createNS("g");c.setAttribute("clip-path","url("+locationHref+"#"+f+")"),c.appendChild(this.layerElement),this.transformedElement=c,i?i.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+f+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._matMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.mat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.mProp.o.v)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this)},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+locationHref+"#"+t+")")}},IShapeElement.prototype={addShapeToModifiers:function(t){var e,r=this.shapeModifiers.length;for(e=0;e<r;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;0<=t;t-=1)this.shapeModifiers[t].processShapes(this._isFirstFrame)}},lcEnum:{1:"butt",2:"round",3:"square"},ljEnum:{1:"miter",2:"round",3:"bevel"},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r<i;){if(e[r].elem===t)return e[r].pos;r+=1}return 0},addProcessedElement:function(t,e){for(var r=this.processedElements,i=r.length;i;)if(r[i-=1].elem===t)return void(r[i].pos=e);r.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}},ITextElement.prototype.initElement=function(t,e,r){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,r),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)},ITextElement.prototype.createPathShape=function(t,e){var r,i,s=e.length,a="";for(r=0;r<s;r+=1)i=e[r].ks.k,a+=buildShapeString(i,i.i.length,!0,t);return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,r,i,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r])/2,0,0)}e.translate(i,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var r,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,r,i,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(r=0;r<a;r+=1){for(i=this.stylesList[r],o=!1,t=n.length=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);1<n.length&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var r,i=new SVGStyleData(t,e),s=i.pElem;if("st"===t.ty)r=new SVGStrokeStyleData(this,t,i);else if("fl"===t.ty)r=new SVGFillStyleData(this,t,i);else if("gf"===t.ty||"gs"===t.ty){r=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,i),this.globalData.defs.appendChild(r.gf),r.maskId&&(this.globalData.defs.appendChild(r.ms),this.globalData.defs.appendChild(r.of),s.setAttribute("mask","url("+locationHref+"#"+r.maskId+")"))}return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",this.lcEnum[t.lc]||"round"),s.setAttribute("stroke-linejoin",this.ljEnum[t.lj]||"round"),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(i),this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var r=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(r,r.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,r){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var s=new SVGShapeData(e,r,ShapePropertyFactory.getShapeProp(this,t,i,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var r=0,i=this.animatedContents.length;r<i;){if(this.animatedContents[r].element===e)return;r+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,r=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||r.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,r,i,s,a,n){var o,h,p,l,m,f,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;0<=o;o-=1){if((f=this.searchProcessedElement(t[o]))?e[o]=r[f-1]:t[o]._render=n,"fl"==t[o].ty||"st"==t[o].ty||"gf"==t[o].ty||"gs"==t[o].ty)f?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"==t[o].ty){if(f)for(p=e[o].it.length,h=0;h<p;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&i.appendChild(e[o].gr)}else"tr"==t[o].ty?(f||(e[o]=this.createTransformElement(t[o],i)),l=e[o].transform,c.push(l)):"sh"==t[o].ty||"rc"==t[o].ty||"el"==t[o].ty||"sr"==t[o].ty?(f||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"==t[o].ty||"rd"==t[o].ty||"ms"==t[o].ty?(f?(m=e[o]).closed=!1:((m=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=m,this.shapeModifiers.push(m)),y.push(m)):"rp"==t[o].ty&&(f?(m=e[o]).closed=!0:(m=ShapeModifiers.getModifier(t[o].ty),(e[o]=m).init(this,t,o,e),this.shapeModifiers.push(m),n=!1),y.push(m));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){this.renderModifiers();var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,r=this.animatedContents.length;for(t=0;t<r;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=this.savedOp;this.savedOp=createTypedArray("float32",t),this.savedOp.set(e);var r=0;for(r=this._length;r<t;r+=1)this.saved[r]=createTypedArray("float32",16);this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.cO=1},CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){this.canvasContext=this.globalData.canvasContext,this.renderableEffectsManager=new CVEffects(this)},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},renderFrame:function(){this.hidden||this.data.hd||(this.renderTransform(),this.renderRenderable(),this.setBlendMode(),this.globalData.renderer.save(),this.globalData.renderer.ctxTransform(this.finalTransform.mat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.mProp.o.v),this.renderInnerContent(),this.globalData.renderer.restore(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,extendPrototype([CanvasRenderer,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,r,i,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t++)if("n"!==this.masksProperties[t].mode){this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),i=this.viewData[t].v,e=s.applyToPointArray(i.v[0][0],i.v[0][1],0),a.moveTo(e[0],e[1]);var o,h=i._length;for(o=1;o<h;o++)r=s.applyToTriplePoints(i.o[o-1],i.i[o],i.v[o]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);r=s.applyToTriplePoints(i.o[o-1],i.i[0],i.v[0]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var r={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},i={};if("fl"==t.ty||"st"==t.ty?(i.c=PropertyFactory.getProp(this,t.c,1,255,this),i.c.k||(r.co="rgb("+bm_floor(i.c.v[0])+","+bm_floor(i.c.v[1])+","+bm_floor(i.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(i.s=PropertyFactory.getProp(this,t.s,1,null,this),i.e=PropertyFactory.getProp(this,t.e,1,null,this),i.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),i.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),i.g=new GradientProperty(this,t.g,this)),i.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"==t.ty||"gs"==t.ty){if(r.lc=this.lcEnum[t.lc]||"round",r.lj=this.ljEnum[t.lj]||"round",1==t.lj&&(r.ml=t.ml),i.w=PropertyFactory.getProp(this,t.w,0,null,this),i.w.k||(r.wi=i.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);i.d=s,i.d.k||(r.da=i.d.dashArray,r.do=i.d.dashoffset[0])}}else r.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(r),i.style=r,i},CVShapeElement.prototype.createGroupElement=function(t){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,r,i,s){var a,n,o,h,p,l,m=t.length-1,f=[],c=[],d=[].concat(s);for(a=m;0<=a;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=r[h-1]:t[a]._shouldRender=i,"fl"==t[a].ty||"st"==t[a].ty||"gf"==t[a].ty||"gs"==t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),f.push(e[a].style);else if("gr"==t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,i,d)}else"tr"==t[a].ty?(h||(l=this.createTransformElement(t[a]),e[a]=l),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"==t[a].ty||"rc"==t[a].ty||"el"==t[a].ty||"sr"==t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"==t[a].ty||"rd"==t[a].ty?(h?(p=e[a]).closed=!1:((p=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=p,this.shapeModifiers.push(p)),c.push(p)):"rp"==t[a].ty&&(h?(p=e[a]).closed=!0:(p=ShapeModifiers.getModifier(t[a].ty),(e[a]=p).init(this,t,a,e),this.shapeModifiers.push(p),i=!1),c.push(p));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(f),m=c.length,a=0;a<m;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,r,i,s,a,n,o,h,p=this.stylesList.length,l=this.globalData.renderer,m=this.globalData.canvasContext;for(t=0;t<p;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(l.save(),a=h.elements,"st"===o||"gs"===o?(m.strokeStyle="st"===o?h.co:h.grd,m.lineWidth=h.wi,m.lineCap=h.lc,m.lineJoin=h.lj,m.miterLimit=h.ml||0):m.fillStyle="fl"===o?h.co:h.grd,l.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&m.beginPath(),l.ctxTransform(h.preTransforms.finalTransform.props),r=a.length,e=0;e<r;e+=1){for("st"!==o&&"gs"!==o||(m.beginPath(),h.da&&(m.setLineDash(h.da),m.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,i=0;i<s;i+=1)"m"==n[i].t?m.moveTo(n[i].p[0],n[i].p[1]):"c"==n[i].t?m.bezierCurveTo(n[i].pts[0],n[i].pts[1],n[i].pts[2],n[i].pts[3],n[i].pts[4],n[i].pts[5]):m.closePath();"st"!==o&&"gs"!==o||(m.stroke(),h.da&&m.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&m.fill(h.r),l.restore()}},CVShapeElement.prototype.renderShape=function(t,e,r,i){var s,a;for(a=t,s=e.length-1;0<=s;s-=1)"tr"==e[s].ty?(a=r[s].transform,this.renderShapeTransform(t,a)):"sh"==e[s].ty||"el"==e[s].ty||"rc"==e[s].ty||"sr"==e[s].ty?this.renderPath(e[s],r[s]):"fl"==e[s].ty?this.renderFill(e[s],r[s],a):"st"==e[s].ty?this.renderStroke(e[s],r[s],a):"gf"==e[s].ty||"gs"==e[s].ty?this.renderGradientFill(e[s],r[s],a):"gr"==e[s].ty?this.renderShape(a,e[s].it,r[s].it):e[s].ty;i&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var r,i,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var p=n.shapes[s];if(p&&p.v){for(i=p._length,r=1;r<i;r+=1)1===r&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[r],p.v[r])});1===i&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),p.c&&i&&(a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[0],p.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var r,i=e.styledShapes.length;for(r=0;r<i;r+=1)this.renderStyledShape(e.styledShapes[r],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,r){var i=e.style;(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,r){var i=e.style;if(!i.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var s=this.globalData.canvasContext,a=e.s.v,n=e.e.v;if(1===t.t)f=s.createLinearGradient(a[0],a[1],n[0],n[1]);else var o=Math.sqrt(Math.pow(a[0]-n[0],2)+Math.pow(a[1]-n[1],2)),h=Math.atan2(n[1]-a[1],n[0]-a[0]),p=o*(1<=e.h.v?.99:e.h.v<=-1?-.99:e.h.v),l=Math.cos(h+e.a.v)*p+a[0],m=Math.sin(h+e.a.v)*p+a[1],f=s.createRadialGradient(l,m,0,a[0],a[1],o);var c,d=t.g.p,u=e.g.c,y=1;for(c=0;c<d;c+=1)e.g._hasOpacity&&e.g._collapsable&&(y=e.g.o[2*c+1]),f.addColorStop(u[4*c]/100,"rgba("+u[4*c+1]+","+u[4*c+2]+","+u[4*c+3]+","+y+")");i.grd=f}i.coOp=e.o.v*r.opacity},CVShapeElement.prototype.renderStroke=function(t,e,r){var i=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(i.da=s.dashArray,i.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity),(e.w._mdf||this._isFirstFrame)&&(i.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){var t=this.canvasContext;t.fillStyle=this.data.sc,t.fillRect(0,0,this.data.sw,this.data.sh)},CVEffects.prototype.renderFrame=function(){};var animationManager=(tJ={},uJ=[],vJ=0,wJ=0,xJ=0,yJ=!0,zJ=!1,tJ.registerAnimation=BJ,tJ.loadAnimation=function(t){var e=new AnimationItem;return FJ(e,null),e.setParams(t),e},tJ.setSpeed=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setSpeed(t,e)},tJ.setDirection=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setDirection(t,e)},tJ.play=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.play(t)},tJ.pause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.pause(t)},tJ.stop=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.stop(t)},tJ.togglePause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.togglePause(t)},tJ.searchAnimations=function(t,e,r){var i,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(i=0;i<a;i+=1)r&&s[i].setAttribute("data-bm-type",r),BJ(s[i],t);if(e&&0===a){r||(r="svg");var n=document.getElementsByTagName("body")[0];n.innerHTML="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",r),n.appendChild(o),BJ(o,t)}},tJ.resize=function(){var t;for(t=0;t<wJ;t+=1)uJ[t].animation.resize()},tJ.goToAndStop=function(t,e,r){var i;for(i=0;i<wJ;i+=1)uJ[i].animation.goToAndStop(t,e,r)},tJ.destroy=function(t){var e;for(e=wJ-1;0<=e;e-=1)uJ[e].animation.destroy(t)},tJ.freeze=function(){zJ=!0},tJ.unfreeze=function(){zJ=!1,TJ()},tJ.getRegisteredAnimations=function(){var t,e=uJ.length,r=[];for(t=0;t<e;t+=1)r.push(uJ[t].animation);return r},tJ),tJ,uJ,vJ,wJ,xJ,yJ,zJ,PK,QK,RK,SK,TK,UK,VK;function AJ(t){for(var e=0,r=t.target;e<wJ;)uJ[e].animation===r&&(uJ.splice(e,1),e-=1,wJ-=1,r.isPaused||EJ()),e+=1}function BJ(t,e){if(!t)return null;for(var r=0;r<wJ;){if(uJ[r].elem==t&&null!==uJ[r].elem)return uJ[r].animation;r+=1}var i=new AnimationItem;return FJ(i,t),i.setData(t,e),i}function DJ(){xJ+=1,TJ()}function EJ(){xJ-=1}function FJ(t,e){t.addEventListener("destroy",AJ),t.addEventListener("_active",DJ),t.addEventListener("_idle",EJ),uJ.push({elem:e,animation:t}),wJ+=1}function KJ(t){var e,r=t-vJ;for(e=0;e<wJ;e+=1)uJ[e].animation.advanceTime(r);vJ=t,xJ&&!zJ?window.requestAnimationFrame(KJ):yJ=!0}function LJ(t){vJ=t,window.requestAnimationFrame(KJ)}function TJ(){!zJ&&xJ&&yJ&&(window.requestAnimationFrame(LJ),yJ=!1)}function WK(t){for(var e=0,r=t.target;e<SK;)QK[e].animation===r&&(QK.splice(e,1),e-=1,SK-=1,r.isPaused||$K()),e+=1}function ZK(){TK+=1,nL()}function $K(){TK-=1}function _K(t,e){t.addEventListener("destroy",WK),t.addEventListener("_active",ZK),t.addEventListener("_idle",$K),QK.push({elem:e,animation:t}),SK+=1}function eL(t){var e,r=t-RK;for(e=0;e<SK;e+=1)QK[e].animation.advanceTime(r);RK=t,TK&&!VK?requestAnimationFrame(eL):UK=!0}function fL(t){RK=t,requestAnimationFrame(eL)}function nL(){!VK&&TK&&UK&&(requestAnimationFrame(fL),UK=!1)}PK={},QK=[],RK=0,SK=0,TK=0,UK=!0,VK=!1,PK.registerAnimation=function(t,e){if(!t)return null;for(var r=0;r<SK;){if(QK[r].elem==t&&null!==QK[r].elem)return QK[r].animation;r+=1}var i=new AnimationItem;return _K(i,t),i.setData(t,e),i},PK.loadAnimation=function(t){var e=new AnimationItem;return _K(e,null),e.setParams(t),e},PK.setSpeed=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setSpeed(t,e)},PK.setDirection=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setDirection(t,e)},PK.play=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.play(t)},PK.pause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.pause(t)},PK.stop=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.stop(t)},PK.togglePause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.togglePause(t)},PK.searchAnimations=function(t,e,r){throw new Error("Cannot access DOM from worker thread")},PK.resize=function(){var t;for(t=0;t<SK;t+=1)QK[t].animation.resize()},PK.goToAndStop=function(t,e,r){var i;for(i=0;i<SK;i+=1)QK[i].animation.goToAndStop(t,e,r)},PK.destroy=function(t){var e;for(e=SK-1;0<=e;e-=1)QK[e].animation.destroy(t)},PK.freeze=function(){VK=!0},PK.unfreeze=function(){VK=!1,nL()},PK.getRegisteredAnimations=function(){var t,e=QK.length,r=[];for(t=0;t<e;t+=1)r.push(QK[t].animation);return r},animationManager=PK;var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.subframeEnabled=subframeEnabled,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context),(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;case"svg":this.renderer=new SVGRenderer(this,t.rendererSettings);break;default:this.renderer=new HybridRenderer(this,t.rendererSettings)}this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,t.animationData?this.configAnimation(t.animationData):t.path&&("json"!=t.path.substr(-4)&&("/"!=t.path.substr(-1,1)&&(t.path+="/"),t.path+="data.json"),-1!=t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),assetLoader.load(t.path,this.configAnimation.bind(this),function(){this.trigger("data_failed")}.bind(this)))},AnimationItem.prototype.setData=function(t,e){var r={wrapper:t,animationData:e?"object"==typeof e?e:JSON.parse(e):null},i=t.attributes;r.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",r.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:"canvas";var s=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";""===s||(r.loop="false"!==s&&("true"===s||parseInt(s)));var a=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;r.autoplay="false"!==a,r.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(r.prerender=!1),this.setParams(r)},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var r=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,assetLoader.load(r,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded())},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.loaded()?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){this.isLoaded||!this.renderer.globalData.fontManager.loaded()||!this.imagePreloader.loaded()&&"canvas"===this.renderer.rendererType||(this.isLoaded=!0,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play())},AnimationItem.prototype.resize=function(){this.renderer.updateContainerSize()},AnimationItem.prototype.setSubframe=function(t){this.subframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.subframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame()},AnimationItem.prototype.renderFrame=function(){!1!==this.isLoaded&&this.renderer.renderFrame(this.currentFrame+this.firstFrame)},AnimationItem.prototype.play=function(t){t&&this.name!=t||!0===this.isPaused&&(this.isPaused=!1,this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!=t||!1===this.isPaused&&(this.isPaused=!0,this._idle=!0,this.trigger("_idle"))},AnimationItem.prototype.togglePause=function(t){t&&this.name!=t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!=t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.goToAndStop=function(t,e,r){r&&this.name!=r||(e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier),this.pause())},AnimationItem.prototype.goToAndPlay=function(t,e,r){this.goToAndStop(t,e,r),this.play()},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,r=!1;e>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.timeCompleted=this.totalFrames=t[0]-t[1],this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.timeCompleted=this.totalFrames=t[1]-t[0],this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?r=t:this.currentRawFrame+this.firstFrame>e&&(r=e-t)),this.firstFrame=t,this.timeCompleted=this.totalFrames=e-t,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"==typeof t[0]){var r,i=t.length;for(r=0;r<i;r+=1)this.segments.push(t[r])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var r=t.p;-1!==r.indexOf("images/")&&(r=r.split("/")[1]),e=this.assetsPath+r}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,r=this.assets.length;e<r;){if(t==this.assets[e].id)return this.assets[e];e+=1}},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;default:throw new Error("Only canvas renderer is supported when using worker.")}if(this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=null,t.animationData)this.configAnimation(t.animationData);else if(t.path)throw new Error("Canvas worker renderer cannot load animation from url")},AnimationItem.prototype.setData=function(t,e){throw new Error("Cannot set data on wrapper for canvas worker renderer")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(t&&0!==t.length&&this.autoloadSegments)throw new Error("Cannot load multiple segments in worker.");this.timeCompleted=this.totalFrames},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=null,AnimationItem.prototype.preloadImages=null,AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.loadSegments(),this.updaFrameModifier(),this.checkLoaded())},AnimationItem.prototype.waitForFontsLoaded=null,AnimationItem.prototype.checkLoaded=function(){this.isLoaded||(this.isLoaded=!0,dataManager.completeData(this.animationData,null),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),this.gotoFrame())},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.getPath=null;var Expressions=(xN={},xN.initExpressions=function(t){var e=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},xN),xN;expressionsPlugin=Expressions;var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null;function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||"boolean"===t||"string"===t||e instanceof Number}function $bm_neg(t){var e=typeof t;if("number"==e||"boolean"==e||t instanceof Number)return-t;if($bm_isInstanceOfArray(t)){var r,i=t.length,s=[];for(r=0;r<i;r+=1)s[r]=-t[r];return s}return t.propType?t.v:void 0}var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var r=typeof t,i=typeof e;if("string"==r||"string"==i)return t+e;if(isNumerable(r,t)&&isNumerable(i,e))return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]+e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var r=typeof t,i=typeof e;if(isNumerable(r,t)&&isNumerable(i,e))return"string"==r&&(t=parseInt(t)),"string"==i&&(e=parseInt(e)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]-e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]*e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t*e[i];return r}return 0}function div(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]/e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t/e[i];return r}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t)),"string"==typeof e&&(e=parseInt(e)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,r){if(r<e){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);e||(e=helperLengthArray);var r,i=Math.min(t.length,e.length),s=0;for(r=0;r<i;r+=1)s+=Math.pow(e[r]-t[r],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,r,i=t[0],s=t[1],a=t[2],n=Math.max(i,s,a),o=Math.min(i,s,a),h=(n+o)/2;if(n==o)e=r=0;else{var p=n-o;switch(r=.5<h?p/(2-n-o):p/(n+o),n){case i:e=(s-a)/p+(s<a?6:0);break;case s:e=(a-i)/p+2;break;case a:e=(i-s)/p+4}e/=6}return[e,r,h,t[3]]}function hue2rgb(t,e,r){return r<0&&(r+=1),1<r&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=r=i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r<e){var a=r;r=e,e=a}if(t<=e)return i;if(r<=t)return s;var n=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*n;var o,h=i.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=i[o]+(s[o]-i[o])*n;return p}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var r,i=e.length;t||(t=createTypedArray("float32",i));var s=createTypedArray("float32",i),a=BMMath.random();for(r=0;r<i;r+=1)s[r]=t[r]+a*(e[r]-t[r]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,r,i){var s,a=t.length,n=shape_pool.newElement();n.setPathData(!!i,a);var o,h,p=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:p,h=r&&r[s]?r[s]:p,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,__expression_functions=[],scoped_bm_rt;if(data.xf){var i,len=data.xf.length;for(i=0;i<len;i+=1)__expression_functions[i]=eval("(function(){ return "+data.xf[i]+"}())")}var expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var r,i,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=r=0;r<n;){for(i=0;i<s;i+=1)a[i]+=-e+2*e*BMMath.random();r+=1}var o=5*time,h=o-Math.floor(o),p=createTypedArray("float32",s);if(1<s){for(i=0;i<s;i+=1)p[i]=this.pv[i]+a[i]+(-e+2*e*BMMath.random())*h;return p}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],i=Math.atan2(r[0],Math.sqrt(r[1]*r[1]+r[2]*r[2]))/degToRads;return[-Math.atan2(r[1],r[2])/degToRads,i,0]}function easeOut(t,e,r,i,s){return applyEase(easeOutBez,t,e,r,i,s)}function easeIn(t,e,r,i,s){return applyEase(easeInBez,t,e,r,i,s)}function ease(t,e,r,i,s){return applyEase(easeInOutBez,t,e,r,i,s)}function applyEase(t,e,r,i,s,a){void 0===s?(s=r,a=i):e=(e-r)/(i-r);var n=t(e=1<e?1:e<0?0:e);if($bm_isInstanceOfArray(s)){var o,h=s.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=(a[o]-s[o])*n+s[o];return p}return(a-s)*n+s}function nearestKey(t){var e,r,i,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(r=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)r=1,i=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){r=e+1,i=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){i=t-data.k[e].t>data.k[e+1].t-t?(r=e+2,data.k[e+1].t):(r=e+1,data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else i=r=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i,s;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);for(t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]},i=(s=t!==data.k.length-1||data.k[t].h?data.k[t].s:data.k[t].s||0===data.k[t].s?data.k[t-1].s:data.k[t].e).length,r=0;r<i;r+=1)e[r]=s[r],e.value[r]=s[r];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,_needsRandom&&seedRandom(randSeed),this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),($bm_transform=transform)&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,"shape"===scoped_bm_rt.propType&&(scoped_bm_rt=scoped_bm_rt.v),scoped_bm_rt)}return executeExpression}return ob.initiateExpression=initiateExpression,ob}(),expressionHelpers={searchExpressions:function(t,e,r){e.x&&(r.k=!0,r.x=!0,r.initiateExpression=ExpressionManager.initiateExpression,r.effectsSequence.push(r.initiateExpression(t,e,r).bind(r)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),r=this.getValueAtTime(t+-.01),i=0;if(e.length){var s;for(s=0;s<e.length;s+=1)i+=Math.pow(r[s]-e[s],2);i=100*Math.sqrt(i)}else i=0;return i},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,r,i=this.getValueAtTime(t),s=this.getValueAtTime(t+-.001);if(i.length)for(e=createTypedArray("float32",i.length),r=0;r<i.length;r+=1)e[r]=(s[r]-i[r])/-.001;else e=(s-i)/-.001;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};!function(){function o(t,e,r){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[p.length-1].t;if(h<=l)return this.pv;if(r?s=l-(i=e?Math.abs(l-elem.comp.globalData.frameRate*e):Math.max(0,l-this.elem.data.ip)):((!e||e>p.length-1)&&(e=p.length-1),i=l-(s=p[p.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),f=this.getValueAtTime(l/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=(f[a]-m[a])*d+c[a];return o}return(f-m)*d+c}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-l)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-l)/.001*(u-y)}}return this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0)}function h(t,e,r){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[0].t;if(l<=h)return this.pv;if(r?s=l+(i=e?Math.abs(elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-l)):((!e||e>p.length-1)&&(e=p.length-1),i=(s=p[e].t)-l),"pingpong"===t){if(Math.floor((l-h)/i)%2==0)return this.getValueAtTime(((l-h)%i+l)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(l/this.comp.globalData.frameRate,0),f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0),d=Math.floor((l-h)/i)+1;if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(f[a]-m[a])*d;return o}return c-(f-m)*d}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(l-h)/.001;return o}return u+(u-y)*(l-h)/.001}}return this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0)}function p(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var r,i,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=1<e?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(i=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]+=i[h];else r+=i;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]/=e;else r/=e;return r}var s=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,r){var i=s(t,e,r);return i.dynamicProperties.length?i.getValueAtTime=function(t){console.warn("Transform at time not supported")}.bind(i):i.getValueAtTime=function(t){}.bind(i),i.setGroupProperty=expressionHelpers.setGroupProperty,i};var l=PropertyFactory.getProp;PropertyFactory.getProp=function(t,e,r,i,s){var a=l(t,e,r,i,s);a.kf?a.getValueAtTime=expressionHelpers.getValueAtTime.bind(a):a.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(a),a.setGroupProperty=expressionHelpers.setGroupProperty,a.loopOut=o,a.loopIn=h,a.smooth=p,a.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(a),a.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(a),a.numKeys=1===e.a?e.k.length:0,a.propertyIndex=e.ix;var n=0;return 0!==r&&(n=createTypedArray("float32",1===e.a?e.k[0].s.length:e.k.length)),a._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:n},expressionHelpers.searchExpressions(t,e,a),a.k&&s.addDynamicProperty(a),a};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function r(){}r.prototype={vertices:function(t,e){this.k&&this.getValue();var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var i,s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(r));for(var i,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,p=0;o<h;){if(p+a[o].addedLength>n){var l=o,m=r.c&&o===h-1?0:o+1,f=(n-p)/a[o].addedLength;i=bez.getPointInSegment(r.v[l],r.v[m],r.o[l],r.i[m],f,a[o]);break}p+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){t=1==t?this.v.c?0:.999:t;var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([r],t),extendPrototype([r],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shape_pool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var n=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,r,i,s){var a=n(t,e,r,i,s);return a.propertyIndex=e.ix,a.lock=!1,3===r?expressionHelpers.searchExpressions(t,e.pt,a):4===r&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}(),TextProperty.prototype.getExpressionValue=function(t,e){var r=this.calculateExpression(e);if(t.t===r)return t;var i={};return this.copyData(i,t),i.t=r.toString(),i.__complete=!1,i},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){if(this.data.d.x)return this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0};var ShapeExpressionInterface=function(t,e,r){var i;function s(t){if("number"==typeof t)return i[t-1];for(var e=0,r=i.length;e<r;){if(i[e]._name===t)return i[e];e+=1}}return s.propertyGroup=r,i=DT(t,e,s),s.numProperties=i.length,s};function DT(t,e,r){var i,s=[],a=t?t.length:0;for(i=0;i<a;i+=1)"gr"==t[i].ty?s.push(FT(t[i],e[i],r)):"fl"==t[i].ty?s.push(GT(t[i],e[i],r)):"st"==t[i].ty?s.push(HT(t[i],e[i],r)):"tm"==t[i].ty?s.push(IT(t[i],e[i],r)):"tr"==t[i].ty||("el"==t[i].ty?s.push(KT(t[i],e[i],r)):"sr"==t[i].ty?s.push(LT(t[i],e[i],r)):"sh"==t[i].ty?s.push(PT(t[i],e[i],r)):"rc"==t[i].ty?s.push(MT(t[i],e[i],r)):"rd"==t[i].ty?s.push(NT(t[i],e[i],r)):"rp"==t[i].ty&&s.push(OT(t[i],e[i],r)));return s}function FT(t,e,r){var i=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return i.content;default:return i.transform}};i.propertyGroup=function(t){return 1===t?i:r(t-1)};var s=function(t,e,r){function i(t){for(var e=0,r=s.length;e<r;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}if("number"==typeof t)return s[t-1]}var s;return i.propertyGroup=function(t){return 1===t?i:r(t-1)},s=DT(t.it,e.it,i.propertyGroup),i.numProperties=s.length,i.propertyIndex=t.cix,i._name=t.nm,i}(t,e,i.propertyGroup),a=function(e,t,r){function i(t){return 1==t?s:r(--t)}t.transform.mProps.o.setGroupProperty(i),t.transform.mProps.p.setGroupProperty(i),t.transform.mProps.a.setGroupProperty(i),t.transform.mProps.s.setGroupProperty(i),t.transform.mProps.r.setGroupProperty(i),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(i),t.transform.mProps.sa.setGroupProperty(i));function s(t){return e.a.ix===t||"Anchor Point"===t?s.anchorPoint:e.o.ix===t||"Opacity"===t?s.opacity:e.p.ix===t||"Position"===t?s.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?s.rotation:e.s.ix===t||"Scale"===t?s.scale:e.sk&&e.sk.ix===t||"Skew"===t?s.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?s.skewAxis:void 0}return t.transform.op.setGroupProperty(i),Object.defineProperties(s,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),s.ty="tr",s.mn=e.mn,s.propertyGroup=r,s}(t.it[t.it.length-1],e.it[e.it.length-1],i.propertyGroup);return i.content=s,i.transform=a,Object.defineProperty(i,"_name",{get:function(){return t.nm}}),i.numProperties=t.np,i.propertyIndex=t.ix,i.nm=t.nm,i.mn=t.mn,i}function GT(t,e,r){function i(t){return"Color"===t||"color"===t?i.color:"Opacity"===t||"opacity"===t?i.opacity:void 0}return Object.defineProperties(i,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(r),e.o.setGroupProperty(r),i}function HT(t,e,r){function i(t){return 1===t?ob:r(t-1)}function s(t){return 1===t?h:i(t-1)}var a,n,o=t.d?t.d.length:0,h={};for(a=0;a<o;a+=1)n=a,Object.defineProperty(h,t.d[n].nm,{get:ExpressionPropertyInterface(e.d.dataProps[n].p)}),e.d.dataProps[a].p.setGroupProperty(s);function p(t){return"Color"===t||"color"===t?p.color:"Opacity"===t||"opacity"===t?p.opacity:"Stroke Width"===t||"stroke width"===t?p.strokeWidth:void 0}return Object.defineProperties(p,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(i),e.o.setGroupProperty(i),e.w.setGroupProperty(i),p}function IT(e,t,r){function i(t){return 1==t?s:r(--t)}function s(t){return t===e.e.ix||"End"===t||"end"===t?s.end:t===e.s.ix?s.start:t===e.o.ix?s.offset:void 0}return s.propertyIndex=e.ix,t.s.setGroupProperty(i),t.e.setGroupProperty(i),t.o.setGroupProperty(i),s.propertyIndex=e.ix,s.propertyGroup=r,Object.defineProperties(s,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),s.mn=e.mn,s}function KT(e,t,r){function i(t){return 1==t?a:r(--t)}a.propertyIndex=e.ix;var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.s.ix===t?a.size:void 0}return s.s.setGroupProperty(i),s.p.setGroupProperty(i),Object.defineProperties(a,{size:{get:ExpressionPropertyInterface(s.s)},position:{get:ExpressionPropertyInterface(s.p)},_name:{value:e.nm}}),a.mn=e.mn,a}function LT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.rotation:e.pt.ix===t?a.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?a.outerRadius:e.os.ix===t?a.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?a.innerRoundness:void 0:a.innerRadius}return a.propertyIndex=e.ix,s.or.setGroupProperty(i),s.os.setGroupProperty(i),s.pt.setGroupProperty(i),s.p.setGroupProperty(i),s.r.setGroupProperty(i),e.ir&&(s.ir.setGroupProperty(i),s.is.setGroupProperty(i)),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},rotation:{get:ExpressionPropertyInterface(s.r)},points:{get:ExpressionPropertyInterface(s.pt)},outerRadius:{get:ExpressionPropertyInterface(s.or)},outerRoundness:{get:ExpressionPropertyInterface(s.os)},innerRadius:{get:ExpressionPropertyInterface(s.ir)},innerRoundness:{get:ExpressionPropertyInterface(s.is)},_name:{value:e.nm}}),a.mn=e.mn,a}function MT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?a.size:void 0}return a.propertyIndex=e.ix,s.p.setGroupProperty(i),s.s.setGroupProperty(i),s.r.setGroupProperty(i),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},roundness:{get:ExpressionPropertyInterface(s.r)},size:{get:ExpressionPropertyInterface(s.s)},_name:{value:e.nm}}),a.mn=e.mn,a}function NT(e,t,r){var i=t;function s(t){if(e.r.ix===t||"Round Corners 1"===t)return s.radius}return s.propertyIndex=e.ix,i.rd.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{radius:{get:ExpressionPropertyInterface(i.rd)},_name:{value:e.nm}}),s.mn=e.mn,s}function OT(e,t,r){function i(t){return 1==t?a:r(--t)}var s=t;function a(t){return e.c.ix===t||"Copies"===t?a.copies:e.o.ix===t||"Offset"===t?a.offset:void 0}return a.propertyIndex=e.ix,s.c.setGroupProperty(i),s.o.setGroupProperty(i),Object.defineProperties(a,{copies:{get:ExpressionPropertyInterface(s.c)},offset:{get:ExpressionPropertyInterface(s.o)},_name:{value:e.nm}}),a.mn=e.mn,a}function PT(t,e,r){var i=e.sh;function s(t){if("Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t)return s.path}return i.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{path:{get:function(){return i.k&&i.getValue(),i}},shape:{get:function(){return i.k&&i.getValue(),i}},_name:{value:t.nm},ix:{value:t.ix},mn:{value:t.mn}}),s}var TextExpressionInterface=function(e){var r;function t(){}return Object.defineProperty(t,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return void 0!==t&&(e.textProperty.currentData.t=void 0,(r=new String(t)).value=t||new String(t)),r}}),t},LayerExpressionInterface=function(e){var r;function i(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return i.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return r;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return i.effect}}i.toWorld=_V,i.fromWorld=aW,i.toComp=_V,i.fromComp=bW,i.sampleImage=cW,i.sourceRectAtTime=e.sourceRectAtTime.bind(e);var t=getDescriptor(r=TransformExpressionInterface((i._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(i,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(r,"rotation"),scale:getDescriptor(r,"scale"),position:getDescriptor(r,"position"),opacity:getDescriptor(r,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return r}},active:{get:function(){return e.isInRange}}}),i.startTime=e.data.st,i.index=e.data.ind,i.source=e.data.refId,i.height=0===e.data.ty?e.data.h:100,i.width=0===e.data.ty?e.data.w:100,i.inPoint=e.data.ip/e.comp.globalData.frameRate,i.outPoint=e.data.op/e.comp.globalData.frameRate,i._name=e.data.nm,i.registerMaskInterface=function(t){i.mask=new MaskManagerInterface(t,e)},i.registerEffectsInterface=function(t){i.effect=t},i};function _V(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.applyToPointArray(t[0],t[1],t[2]||0)}return r.applyToPointArray(t[0],t[1],t[2]||0)}function aW(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.inversePoint(t)}return r.inversePoint(t)}function bW(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function cW(){return[1,1,1,1]}var CompExpressionInterface=function(i){function t(t){for(var e=0,r=i.layers.length;e<r;){if(i.layers[e].nm===t||i.layers[e].ind===t)return i.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:i.data.nm}),(t.layer=t).pixelAspect=1,t.height=i.data.h||i.globalData.compSize.h,t.width=i.data.w||i.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/i.globalData.frameRate,t.displayStartTime=0,t.numLayers=i.layers.length,t},TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity}}if(Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p)var r=ExpressionPropertyInterface(t.p);return Object.defineProperty(e,"position",{get:function(){return t.p?r():[t.px.v,t.py.v,t.pz?t.pz.v:0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},ProjectInterface=function(){function t(t){for(var e=0,r=this.compositions.length;e<r;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}}return t.compositions=[],t.currentFrame=0,t.registerComposition=LW,t};function LW(t){this.compositions.push(t)}var EffectsExpressionInterface={createEffectsInterface:function(s,t){if(s.effectsManager){var e,a=[],r=s.data.ef,i=s.effectsManager.effectElements.length;for(e=0;e<i;e+=1)a.push(TW(r[e],s.effectsManager.effectElements[e],t,s));return function(t){for(var e=s.data.ef||[],r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return a[r];r+=1}}}}};function TW(s,t,e,r){var i,a=[],n=s.ef.length;for(i=0;i<n;i+=1)5===s.ef[i].ty?a.push(TW(s.ef[i],t.effectElements[i],t.effectElements[i].propertyGroup,r)):a.push(UW(t.effectElements[i],s.ef[i].ty,r,o));function o(t){return 1===t?h:e(t-1)}var h=function(t){for(var e=s.ef,r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?a[r]:a[r]();r+=1}return a[0]()};return h.propertyGroup=o,"ADBE Color Control"===s.mn&&Object.defineProperty(h,"color",{get:function(){return a[0]()}}),Object.defineProperty(h,"numProperties",{get:function(){return s.np}}),h.active=h.enabled=0!==s.en,h}function UW(t,e,r,i){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(i),function(){return 10===e?r.comp.compInterface(t.p.v):s()}}var MaskManagerInterface=function(){function a(t,e){this._mask=t,this._data=e}Object.defineProperty(a.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}});return function(e,t){var r,i=createSizedArray(e.viewData.length),s=e.viewData.length;for(r=0;r<s;r+=1)i[r]=new a(e.viewData[r],e.masksProperties[r]);return function(t){for(r=0;r<s;){if(e.masksProperties[r].nm===t)return i[r];r+=1}}}}(),ExpressionPropertyInterface=(KX={pv:0,v:0,mult:1},LX={pv:[0,0,0],v:[0,0,0],mult:1},function(t){return t?"unidimensional"===t.propType?function(t){t&&"pv"in t||(t=KX);var e=1/t.mult,r=t.pv*e,i=new Number(r);return i.value=r,MX(i,t,"unidimensional"),function(){return t.k&&t.getValue(),r=t.v*e,i.value!==r&&((i=new Number(r)).value=r,MX(i,t,"unidimensional")),i}}(t):function(e){e&&"pv"in e||(e=LX);var r=1/e.mult,i=e.pv.length,s=createTypedArray("float32",i),a=createTypedArray("float32",i);return s.value=a,MX(s,e,"multidimensional"),function(){e.k&&e.getValue();for(var t=0;t<i;t+=1)s[t]=a[t]=e.v[t]*r;return s}}(t):PX}),KX,LX,fY,gY;function MX(i,s,a){Object.defineProperty(i,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),i.numKeys=s.keyframes?s.keyframes.length:0,i.key=function(t){if(i.numKeys){var e="";e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s;var r="unidimensional"===a?new Number(e):Object.assign({},e);return r.time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,r}return 0},i.valueAtTime=s.getValueAtTime,i.speedAtTime=s.getSpeedAtTime,i.velocityAtTime=s.getVelocityAtTime,i.propertyGroup=s.propertyGroup}function PX(){return KX}function hY(t,e){return this.textIndex=t+1,this.textTotal=e,this.v=this.getValue()*this.mult,this.v}function SliderEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function AngleEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function ColorEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function PointEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function LayerIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function MaskIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function CheckboxEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var r=t.ef||[];this.effectElements=[];var i,s,a=r.length;for(i=0;i<a;i++)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}fY=function(t,e){this.pv=1,this.comp=t.comp,this.elem=t,this.mult=.01,this.propType="textSelector",this.textTotal=e.totalChars,this.selectorValue=100,this.lastValue=[1,1,1],this.k=!0,this.x=!0,this.getValue=ExpressionManager.initiateExpression.bind(this)(t,e,this),this.getMult=hY,this.getVelocityAtTime=expressionHelpers.getVelocityAtTime,this.kf?this.getValueAtTime=expressionHelpers.getValueAtTime.bind(this):this.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(this),this.setGroupProperty=expressionHelpers.setGroupProperty},gY=TextSelectorProp.getTextSelectorProp,TextSelectorProp.getTextSelectorProp=function(t,e,r){return 1===e.t?new fY(t,e,r):gY(t,e,r)},extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,i,s=this.data.ef.length,a=this.data.ef;for(r=0;r<s;r+=1){switch(i=null,a[r].ty){case 0:i=new SliderEffect(a[r],e,this);break;case 1:i=new AngleEffect(a[r],e,this);break;case 2:i=new ColorEffect(a[r],e,this);break;case 3:i=new PointEffect(a[r],e,this);break;case 4:case 7:i=new CheckboxEffect(a[r],e,this);break;case 10:i=new LayerIndexEffect(a[r],e,this);break;case 11:i=new MaskIndexEffect(a[r],e,this);break;case 5:i=new EffectsManager(a[r],e,this);break;default:i=new NoValueEffect(a[r],e,this)}i&&this.effectElements.push(i)}};var lottiejs={},_isFrozen=!1;function loadAnimation(t){return animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":defaultCurveSegments=200;break;case"medium":defaultCurveSegments=50;break;case"low":defaultCurveSegments=10}else!isNaN(t)&&1<t&&(defaultCurveSegments=t);roundValues(!(50<=defaultCurveSegments))}lottiejs.play=animationManager.play,lottiejs.pause=animationManager.pause,lottiejs.togglePause=animationManager.togglePause,lottiejs.setSpeed=animationManager.setSpeed,lottiejs.setDirection=animationManager.setDirection,lottiejs.stop=animationManager.stop,lottiejs.registerAnimation=animationManager.registerAnimation,lottiejs.loadAnimation=loadAnimation,lottiejs.resize=animationManager.resize,lottiejs.goToAndStop=animationManager.goToAndStop,lottiejs.destroy=animationManager.destroy,lottiejs.setQuality=setQuality,lottiejs.freeze=animationManager.freeze,lottiejs.unfreeze=animationManager.unfreeze,lottiejs.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottiejs.version="5.5.2";var renderer="";return lottiejs}({}),animations=[];onmessage=function(t){if(t&&t.data&&t.data.params&&t.data.canvas){var e=t.data.canvas,r=t.data.params,i=e.getContext("2d"),s=lottiejs.loadAnimation({renderer:"canvas",loop:r.loop,autoplay:r.autoplay,animationData:t.data.animationData,rendererSettings:{context:i,scaleMode:"noScale",clearCanvas:!0}});animations.push(s),s.play()}}; \ No newline at end of file +var lottiejs=function(window){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",initialDefaultFrame=-999999,subframeEnabled=!0,expressionsPlugin,isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),cachedColors={},bm_rounder=Math.round,bm_rnd,bm_pow=Math.pow,bm_sqrt=Math.sqrt,bm_abs=Math.abs,bm_floor=Math.floor,bm_max=Math.max,bm_min=Math.min,blitter=10,BMMath={};function ProjectInterface(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],r=e.length;for(t=0;t<r;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"==typeof t&&t.length){var e,r=createSizedArray(t.length),i=t.length;for(e=0;e<i;e+=1)r[e]=Math.abs(t[e]);return r}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){bm_rnd=t?Math.round:function(t){return t}}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin=t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility=t.style.webkitBackfaceVisibility="visible",t.style.transformStyle=t.style.webkitTransformStyle=t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,r,i){this.type=t,this.currentTime=e,this.totalTime=r,this.direction=i<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,r,i){this.type=t,this.currentLoop=r,this.totalLoops=e,this.direction=i<0?-1:1}function BMSegmentStartEvent(t,e,r){this.type=t,this.firstFrame=e,this.totalFrames=r}function BMDestroyEvent(t,e){this.type=t,this.target=e}roundValues(!1);var createElementID=(B=0,function(){return"__lottie_element_"+ ++B}),B;function HSVtoRGB(t,e,r){var i,s,a,n,o,h,p,l;switch(h=r*(1-e),p=r*(1-(o=6*t-(n=Math.floor(6*t)))*e),l=r*(1-(1-o)*e),n%6){case 0:i=r,s=l,a=h;break;case 1:i=p,s=r,a=h;break;case 2:i=h,s=r,a=l;break;case 3:i=h,s=p,a=r;break;case 4:i=l,s=h,a=r;break;case 5:i=r,s=h,a=p}return[i,s,a]}function RGBtoHSV(t,e,r){var i,s=Math.max(t,e,r),a=Math.min(t,e,r),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:i=0;break;case t:i=e-r+n*(e<r?6:0),i/=6*n;break;case e:i=r-t+2*n,i/=6*n;break;case r:i=t-e+4*n,i/=6*n}return[i,o,h]}function addSaturationToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[1]+=e,1<r[1]?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,1<r[2]?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,1<r[0]?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1==e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var r=this._cbs[t].length,i=0;i<r;i++)this._cbs[t][i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var r=0,i=this._cbs[t].length;r<i;)this._cbs[t][r]===e&&(this._cbs[t].splice(r,1),r-=1,i-=1),r+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var createTypedArray="function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):void 0}:function(t,e){var r,i=0,s=[];switch(t){case"int16":case"uint8c":r=1;break;default:r=1.1}for(i=0;i<e;i+=1)s.push(r);return s};function createSizedArray(t){return Array.apply(null,{length:t})}function createTag(t){return document.createElement(t)}function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){this._mdf=!1;var t,e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var getBlendMode=(Ja={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Ja[t]||""}),Ja,Matrix=(La=Math.cos,Ma=Math.sin,Na=Math.tan,Oa=Math.round,function(){this.reset=Pa,this.rotate=Qa,this.rotateX=Ra,this.rotateY=Sa,this.rotateZ=Ta,this.skew=Va,this.skewFromAxis=Wa,this.shear=Ua,this.scale=Xa,this.setTransform=Ya,this.translate=Za,this.transform=$a,this.applyToPoint=db,this.applyToX=eb,this.applyToY=fb,this.applyToZ=gb,this.applyToPointArray=kb,this.applyToTriplePoints=jb,this.applyToPointStringified=lb,this.toCSS=mb,this.to2dCSS=pb,this.clone=bb,this.cloneFromProps=cb,this.equals=ab,this.inversePoints=ib,this.inversePoint=hb,this._t=this.transform,this.isIdentity=_a,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}),La,Ma,Na,Oa;function Pa(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function Qa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ra(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(1,0,0,0,0,e,-r,0,0,r,e,0,0,0,0,1)}function Sa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,0,r,0,0,1,0,0,-r,0,e,0,0,0,0,1)}function Ta(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ua(t,e){return this._t(1,e,t,1,0,0)}function Va(t,e){return this.shear(Na(t),Na(e))}function Wa(t,e){var r=La(e),i=Ma(e);return this._t(r,i,0,0,-i,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,Na(t),1,0,0,0,0,1,0,0,0,0,1)._t(r,-i,0,0,i,r,0,0,0,0,1,0,0,0,0,1)}function Xa(t,e,r){return r||0===r||(r=1),1===t&&1===e&&1===r?this:this._t(t,0,0,0,0,e,0,0,0,0,r,0,0,0,0,1)}function Ya(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=r,this.props[3]=i,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=p,this.props[10]=l,this.props[11]=m,this.props[12]=f,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function Za(t,e,r){return r=r||0,0!==t||0!==e||0!==r?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,r,1):this}function $a(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){var y=this.props;if(1===t&&0===e&&0===r&&0===i&&0===s&&1===a&&0===n&&0===o&&0===h&&0===p&&1===l&&0===m)return y[12]=y[12]*t+y[15]*f,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*l+y[15]*d,y[15]=y[15]*u,this._identityCalculated=!1,this;var g=y[0],v=y[1],P=y[2],b=y[3],x=y[4],_=y[5],S=y[6],T=y[7],A=y[8],C=y[9],E=y[10],k=y[11],D=y[12],M=y[13],I=y[14],w=y[15];return y[0]=g*t+v*s+P*h+b*f,y[1]=g*e+v*a+P*p+b*c,y[2]=g*r+v*n+P*l+b*d,y[3]=g*i+v*o+P*m+b*u,y[4]=x*t+_*s+S*h+T*f,y[5]=x*e+_*a+S*p+T*c,y[6]=x*r+_*n+S*l+T*d,y[7]=x*i+_*o+S*m+T*u,y[8]=A*t+C*s+E*h+k*f,y[9]=A*e+C*a+E*p+k*c,y[10]=A*r+C*n+E*l+k*d,y[11]=A*i+C*o+E*m+k*u,y[12]=D*t+M*s+I*h+w*f,y[13]=D*e+M*a+I*p+w*c,y[14]=D*r+M*n+I*l+w*d,y[15]=D*i+M*o+I*m+w*u,this._identityCalculated=!1,this}function _a(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function ab(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function bb(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e]}function cb(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function db(t,e,r){return{x:t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}}function eb(t,e,r){return t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12]}function fb(t,e,r){return t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13]}function gb(t,e,r){return t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}function hb(t){var e=this.props[0]*this.props[5]-this.props[1]*this.props[4],r=this.props[5]/e,i=-this.props[1]/e,s=-this.props[4]/e,a=this.props[0]/e,n=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/e,o=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/e;return[t[0]*r+t[1]*s+n,t[0]*i+t[1]*a+o,0]}function ib(t){var e,r=t.length,i=[];for(e=0;e<r;e+=1)i[e]=hb(t[e]);return i}function jb(t,e,r){var i=createTypedArray("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=r[0],i[5]=r[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],p=this.props[13];i[0]=t[0]*s+t[1]*n+h,i[1]=t[0]*a+t[1]*o+p,i[2]=e[0]*s+e[1]*n+h,i[3]=e[0]*a+e[1]*o+p,i[4]=r[0]*s+r[1]*n+h,i[5]=r[0]*a+r[1]*o+p}return i}function kb(t,e,r){return this.isIdentity()?[t,e,r]:[t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]]}function lb(t,e){if(this.isIdentity())return t+","+e;var r=this.props;return Math.round(100*(t*r[0]+e*r[4]+r[12]))/100+","+Math.round(100*(t*r[1]+e*r[5]+r[13]))/100}function mb(){for(var t=0,e=this.props,r="matrix3d(";t<16;)r+=Oa(1e4*e[t])/1e4,r+=15===t?")":",",t+=1;return r}function nb(t){return t<1e-6&&0<t||-1e-6<t&&t<0?Oa(1e4*t)/1e4:t}function pb(){var t=this.props;return"matrix("+nb(t[0])+","+nb(t[1])+","+nb(t[4])+","+nb(t[5])+","+nb(t[12])+","+nb(t[13])+")"}!function(o,h){var p,l=this,m=256,f=6,c="random",d=h.pow(m,f),u=h.pow(2,52),y=2*u,g=m-1;function v(t){var e,r=t.length,n=this,i=0,s=n.i=n.j=0,a=n.S=[];for(r||(t=[r++]);i<m;)a[i]=i++;for(i=0;i<m;i++)a[i]=a[s=g&s+t[i%r]+(e=a[i])],a[s]=e;n.g=function(t){for(var e,r=0,i=n.i,s=n.j,a=n.S;t--;)e=a[i=g&i+1],r=r*m+a[g&(a[i]=a[s=g&s+e])+(a[s]=e)];return n.i=i,n.j=s,r}}function P(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function b(t,e){for(var r,i=t+"",s=0;s<i.length;)e[g&s]=g&(r^=19*e[g&s])+i.charCodeAt(s++);return x(e)}function x(t){return String.fromCharCode.apply(0,t)}h["seed"+c]=function(t,e,r){function i(){for(var t=n.g(f),e=d,r=0;t<u;)t=(t+r)*m,e*=m,r=n.g(1);for(;y<=t;)t/=2,e/=2,r>>>=1;return(t+r)/e}var s=[],a=b(function t(e,r){var i,s=[],a=typeof e;if(r&&"object"==a)for(i in e)try{s.push(t(e[i],r-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,x(o)]:null===t?function(){try{if(p)return x(p.randomBytes(m));var t=new Uint8Array(m);return(l.crypto||l.msCrypto).getRandomValues(t),x(t)}catch(t){var e=l.navigator,r=e&&e.plugins;return[+new Date,l,r,l.screen,x(o)]}}():t,3),s),n=new v(s);return i.int32=function(){return 0|n.g(4)},i.quick=function(){return n.g(4)/4294967296},i.double=i,b(x(n.S),o),(e.pass||r||function(t,e,r,i){return i&&(i.S&&P(i,n),t.state=function(){return P(n,{})}),r?(h[c]=t,e):t})(i,a,"global"in e?e.global:this==h,e.state)},b(h.random(),o)}([],BMMath);var BezierFactory=(_e={getBezierEasing:function(t,e,r,i,s){var a=s||("bez_"+t+"_"+e+"_"+r+"_"+i).replace(/\./g,"p");if(af[a])return af[a];var n=new rf([t,e,r,i]);return af[a]=n}},af={},gf=11,hf=1/(gf-1),jf="function"==typeof Float32Array,rf.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:nf(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r<gf;++r)this._mSampleValues[r]=nf(r*hf,t,e)},_getTForX:function(t){for(var e=this._p[0],r=this._p[2],i=this._mSampleValues,s=0,a=1,n=gf-1;a!==n&&i[a]<=t;++a)s+=hf;var o=s+(t-i[--a])/(i[a+1]-i[a])*hf,h=of(o,e,r);return.001<=h?function(t,e,r,i){for(var s=0;s<4;++s){var a=of(e,r,i);if(0===a)return e;e-=(nf(e,r,i)-t)/a}return e}(t,o,e,r):0===h?o:function(t,e,r,i,s){for(var a,n,o=0;0<(a=nf(n=e+(r-e)/2,i,s)-t)?r=n:e=n,1e-7<Math.abs(a)&&++o<10;);return n}(t,s,s+hf,e,r)}},_e),_e,af,gf,hf,jf;function kf(t,e){return 1-3*e+3*t}function lf(t,e){return 3*e-6*t}function mf(t){return 3*t}function nf(t,e,r){return((kf(e,r)*t+lf(e,r))*t+mf(e))*t}function of(t,e,r){return 3*kf(e,r)*t*t+2*lf(e,r)*t+mf(e)}function rf(t){this._p=t,this._mSampleValues=jf?new Float32Array(gf):new Array(gf),this._precomputed=!1,this.get=this.get.bind(this)}function extendPrototype(t,e){var r,i,s=t.length;for(r=0;r<s;r+=1)for(var a in i=t[r].prototype)i.hasOwnProperty(a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}function bezFunction(){Math;function y(t,e,r,i,s,a){var n=t*i+e*s+r*a-s*i-a*t-r*e;return-.001<n&&n<.001}var l=function(t,e,r,i){var s,a,n,o,h,p,l=defaultCurveSegments,m=0,f=[],c=[],d=bezier_length_pool.newElement();for(n=r.length,s=0;s<l;s+=1){for(h=s/(l-1),a=p=0;a<n;a+=1)o=bm_pow(1-h,3)*t[a]+3*bm_pow(1-h,2)*h*r[a]+3*(1-h)*bm_pow(h,2)*i[a]+bm_pow(h,3)*e[a],f[a]=o,null!==c[a]&&(p+=bm_pow(f[a]-c[a],2)),c[a]=f[a];p&&(m+=p=bm_sqrt(p)),d.percents[s]=h,d.lengths[s]=m}return d.addedLength=m,d};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}var P,t=(P={},function(t,e,r,i){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+r[0]+"_"+r[1]+"_"+i[0]+"_"+i[1]).replace(/\./g,"p");if(!P[s]){var a,n,o,h,p,l,m,f=defaultCurveSegments,c=0,d=null;2===t.length&&(t[0]!=e[0]||t[1]!=e[1])&&y(t[0],t[1],e[0],e[1],t[0]+r[0],t[1]+r[1])&&y(t[0],t[1],e[0],e[1],e[0]+i[0],e[1]+i[1])&&(f=2);var u=new g(f);for(o=r.length,a=0;a<f;a+=1){for(m=createSizedArray(o),p=a/(f-1),n=l=0;n<o;n+=1)h=bm_pow(1-p,3)*t[n]+3*bm_pow(1-p,2)*p*(t[n]+r[n])+3*(1-p)*bm_pow(p,2)*(e[n]+i[n])+bm_pow(p,3)*e[n],m[n]=h,null!==d&&(l+=bm_pow(m[n]-d[n],2));c+=l=bm_sqrt(l),u.points[a]=new v(l,m),d=m}u.segmentLength=c,P[s]=u}return P[s]});function D(t,e){var r=e.percents,i=e.lengths,s=r.length,a=bm_floor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===i[a])return r[a];for(var h=i[a]>n?-1:1,p=!0;p;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),p=!1):a+=h,a<0||s-1<=a){if(a===s-1)return r[a];p=!1}return r[a]+(r[a+1]-r[a])*o}var M=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segments_length_pool.newElement(),i=t.c,s=t.v,a=t.o,n=t.i,o=t._length,h=r.lengths,p=0;for(e=0;e<o-1;e+=1)h[e]=l(s[e],s[e+1],a[e],n[e+1]),p+=h[e].addedLength;return i&&o&&(h[e]=l(s[e],s[0],a[e],n[0]),p+=h[e].addedLength),r.totalLength=p,r},getNewSegment:function(t,e,r,i,s,a,n){var o,h=D(s=s<0?0:1<s?1:s,n),p=D(a=1<a?1:a,n),l=t.length,m=1-h,f=1-p,c=m*m*m,d=h*m*m*3,u=h*h*m*3,y=h*h*h,g=m*m*f,v=h*m*f+m*h*f+m*m*p,P=h*h*f+m*h*p+h*m*p,b=h*h*p,x=m*f*f,_=h*f*f+m*p*f+m*f*p,S=h*p*f+m*p*p+h*f*p,T=h*p*p,A=f*f*f,C=p*f*f+f*p*f+f*f*p,E=p*p*f+f*p*p+p*f*p,k=p*p*p;for(o=0;o<l;o+=1)M[4*o]=Math.round(1e3*(c*t[o]+d*r[o]+u*i[o]+y*e[o]))/1e3,M[4*o+1]=Math.round(1e3*(g*t[o]+v*r[o]+P*i[o]+b*e[o]))/1e3,M[4*o+2]=Math.round(1e3*(x*t[o]+_*r[o]+S*i[o]+T*e[o]))/1e3,M[4*o+3]=Math.round(1e3*(A*t[o]+C*r[o]+E*i[o]+k*e[o]))/1e3;return M},getPointInSegment:function(t,e,r,i,s,a){var n=D(s,a),o=1-n;return[Math.round(1e3*(o*o*o*t[0]+(n*o*o+o*n*o+o*o*n)*r[0]+(n*n*o+o*n*n+n*o*n)*i[0]+n*n*n*e[0]))/1e3,Math.round(1e3*(o*o*o*t[1]+(n*o*o+o*n*o+o*o*n)*r[1]+(n*n*o+o*n*n+n*o*n)*i[1]+n*n*n*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,r,i,s,a,n,o,h){if(0===r&&0===a&&0===h)return y(t,e,i,s,n,o);var p,l=Math.sqrt(Math.pow(i-t,2)+Math.pow(s-e,2)+Math.pow(a-r,2)),m=Math.sqrt(Math.pow(n-t,2)+Math.pow(o-e,2)+Math.pow(h-r,2)),f=Math.sqrt(Math.pow(n-i,2)+Math.pow(o-s,2)+Math.pow(h-a,2));return-1e-4<(p=m<l?f<l?l-m-f:f-m-l:m<f?f-m-l:m-l-f)&&p<1e-4}}}!function(){for(var a=0,t=["ms","moz","webkit","o"],e=0;e<t.length&&!window.requestAnimationFrame;++e)window.requestAnimationFrame=window[t[e]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[t[e]+"CancelAnimationFrame"]||window[t[e]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(t,e){var r=(new Date).getTime(),i=Math.max(0,16-(r-a)),s=setTimeout(function(){t(r+i)},i);return a=r+i,s}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)})}();var bez=bezFunction();function dataFunctionManager(){function m(t,e,r){var i,s,a,n,o,h,p=t.length;for(s=0;s<p;s+=1)if("ks"in(i=t[s])&&!i.completed){if(i.completed=!0,i.tt&&(t[s-1].td=i.tt),[],-1,i.hasMask){var l=i.masksProperties;for(n=l.length,a=0;a<n;a+=1)if(l[a].pt.k.i)d(l[a].pt.k);else for(h=l[a].pt.k.length,o=0;o<h;o+=1)l[a].pt.k[o].s&&d(l[a].pt.k[o].s[0]),l[a].pt.k[o].e&&d(l[a].pt.k[o].e[0])}0===i.ty?(i.layers=f(i.refId,e),m(i.layers,e,r)):4===i.ty?c(i.shapes):5==i.ty&&b(i,r)}}function f(t,e){for(var r=0,i=e.length;r<i;){if(e[r].id===t)return e[r].layers.__used?JSON.parse(JSON.stringify(e[r].layers)):(e[r].layers.__used=!0,e[r].layers);r+=1}}function c(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)d(t[e].ks.k);else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&d(t[e].ks.k[r].s[0]),t[e].ks.k[r].e&&d(t[e].ks.k[r].e[0]);!0}else"gr"==t[e].ty&&c(t[e].it)}function d(t){var e,r=t.i.length;for(e=0;e<r;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function o(t,e){var r=e?e.split("."):[100,100,100];return t[0]>r[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&void 0))}var i,r=(i=[4,4,14],function(t){if(o(i,t.v)&&(s(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}});function s(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=t[e],void 0,i=r.t.d,r.t.d={k:[{s:i,t:0}]})}var h,a,n=(h=[4,7,99],function(t){if(t.chars&&!o(h,t.v)){var e,r,i,s,a,n=t.chars.length;for(e=0;e<n;e+=1)if(t.chars[e].data&&t.chars[e].data.shapes)for(i=(a=t.chars[e].data.shapes[0].it).length,r=0;r<i;r+=1)(s=a[r].ks.k).__converted||(d(a[r].ks.k),s.__converted=!0)}}),p=(a=[4,1,9],function(t){if(o(a,t.v)&&(u(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&u(t.assets[e].layers)}});function l(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)if("gr"===t[e].ty)l(t[e].it);else if("fl"===t[e].ty||"st"===t[e].ty)if(t[e].c.k&&t[e].c.k[0].i)for(i=t[e].c.k.length,r=0;r<i;r+=1)t[e].c.k[r].s&&(t[e].c.k[r].s[0]/=255,t[e].c.k[r].s[1]/=255,t[e].c.k[r].s[2]/=255,t[e].c.k[r].s[3]/=255),t[e].c.k[r].e&&(t[e].c.k[r].e[0]/=255,t[e].c.k[r].e[1]/=255,t[e].c.k[r].e[2]/=255,t[e].c.k[r].e[3]/=255);else t[e].c.k[0]/=255,t[e].c.k[1]/=255,t[e].c.k[2]/=255,t[e].c.k[3]/=255}function u(t){var e,r=t.length;for(e=0;e<r;e+=1)4===t[e].ty&&l(t[e].shapes)}var y,g=(y=[4,4,18],function(t){if(o(y,t.v)&&(P(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&P(t.assets[e].layers)}});function v(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)t[e].ks.k.c=t[e].closed;else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&(t[e].ks.k[r].s[0].c=t[e].closed),t[e].ks.k[r].e&&(t[e].ks.k[r].e[0].c=t[e].closed);!0}else"gr"==t[e].ty&&v(t[e].it)}function P(t){var e,r,i,s,a,n,o=t.length;for(r=0;r<o;r+=1){if((e=t[r]).hasMask){var h=e.masksProperties;for(s=h.length,i=0;i<s;i+=1)if(h[i].pt.k.i)h[i].pt.k.c=h[i].cl;else for(n=h[i].pt.k.length,a=0;a<n;a+=1)h[i].pt.k[a].s&&(h[i].pt.k[a].s[0].c=h[i].cl),h[i].pt.k[a].e&&(h[i].pt.k[a].e[0].c=h[i].cl)}4===e.ty&&v(e.shapes)}}function b(t,e){0!==t.t.a.length||"m"in t.t.p||(t.singleShape=!0)}var t={completeData:function(t,e){t.__complete||(p(t),r(t),n(t),g(t),m(t.layers,t.assets,e),t.__complete=!0)}};return t.checkColors=p,t.checkChars=n,t.checkShapes=g,t.completeLayers=m,t}var dataManager=dataFunctionManager();dataManager.completeData=function(t,e){t.__complete||(this.checkColors(t),this.checkChars(t),this.checkShapes(t),this.completeLayers(t.layers,t.assets,e),t.__complete=!0)};var FontManager=function(){var a={w:0,size:0,shapes:[]},t=[];function u(t,e){var r=createTag("span");r.style.fontFamily=e;var i=createTag("span");i.innerHTML="giItT1WQy@!-/#",r.style.position="absolute",r.style.left="-10000px",r.style.top="-10000px",r.style.fontSize="300px",r.style.fontVariant="normal",r.style.fontStyle="normal",r.style.fontWeight="normal",r.style.letterSpacing="0",r.appendChild(i),document.body.appendChild(r);var s=i.offsetWidth;return i.style.fontFamily=t+", "+e,{node:i,w:s,parent:r}}t=t.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);function e(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()}return e.getCombinedCharacterCodes=function(){return t},e.prototype.addChars=function(t){if(t){this.chars||(this.chars=[]);var e,r,i,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(r=0,i=!1;r<a;)this.chars[r].style===t[e].style&&this.chars[r].fFamily===t[e].fFamily&&this.chars[r].ch===t[e].ch&&(i=!0),r+=1;i||(this.chars.push(t[e]),a+=1)}}},e.prototype.addFonts=function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);var r,i,s,a,n=t.list,o=n.length,h=o;for(r=0;r<o;r+=1){var p,l,m=!0;if(n[r].loaded=!1,n[r].monoCase=u(n[r].fFamily,"monospace"),n[r].sansCase=u(n[r].fFamily,"sans-serif"),n[r].fPath){if("p"===n[r].fOrigin||3===n[r].origin){if(0<(p=document.querySelectorAll('style[f-forigin="p"][f-family="'+n[r].fFamily+'"], style[f-origin="3"][f-family="'+n[r].fFamily+'"]')).length&&(m=!1),m){var f=createTag("style");f.setAttribute("f-forigin",n[r].fOrigin),f.setAttribute("f-origin",n[r].origin),f.setAttribute("f-family",n[r].fFamily),f.type="text/css",f.innerHTML="@font-face {font-family: "+n[r].fFamily+"; font-style: normal; src: url('"+n[r].fPath+"');}",e.appendChild(f)}}else if("g"===n[r].fOrigin||1===n[r].origin){for(p=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<p.length;l++)-1!==p[l].href.indexOf(n[r].fPath)&&(m=!1);if(m){var c=createTag("link");c.setAttribute("f-forigin",n[r].fOrigin),c.setAttribute("f-origin",n[r].origin),c.type="text/css",c.rel="stylesheet",c.href=n[r].fPath,document.body.appendChild(c)}}else if("t"===n[r].fOrigin||2===n[r].origin){for(p=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<p.length;l++)n[r].fPath===p[l].src&&(m=!1);if(m){var d=createTag("link");d.setAttribute("f-forigin",n[r].fOrigin),d.setAttribute("f-origin",n[r].origin),d.setAttribute("rel","stylesheet"),d.setAttribute("href",n[r].fPath),e.appendChild(d)}}}else n[r].loaded=!0,h-=1;n[r].helper=(i=e,s=n[r],a=void 0,(a=createNS("text")).style.fontSize="100px",a.setAttribute("font-family",s.fFamily),a.setAttribute("font-style",s.fStyle),a.setAttribute("font-weight",s.fWeight),a.textContent="1",s.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",s.fClass)):a.style.fontFamily=s.fFamily,i.appendChild(a),createTag("canvas").getContext("2d").font=s.fWeight+" "+s.fStyle+" 100px "+s.fFamily,a),n[r].cache={},this.fonts.push(n[r])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},e.prototype.getCharData=function(t,e,r){for(var i=0,s=this.chars.length;i<s;){if(this.chars[i].ch===t&&this.chars[i].style===e&&this.chars[i].fFamily===r)return this.chars[i];i+=1}return console&&console.warn&&console.warn("Missing character from exported characters list: ",t,e,r),a},e.prototype.getFontByName=function(t){for(var e=0,r=this.fonts.length;e<r;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},e.prototype.measureText=function(t,e,r){var i=this.getFontByName(e),s=t.charCodeAt(0);if(!i.cache[s+1]){var a=i.helper;if(" "===t){a.textContent="|"+t+"|";var n=a.getComputedTextLength();a.textContent="||";var o=a.getComputedTextLength();i.cache[s+1]=(n-o)/100}else a.textContent=t,i.cache[s+1]=a.getComputedTextLength()/100}return i.cache[s+1]*r},e.prototype.checkLoadedFonts=function(){var t,e,r,i=this.fonts.length,s=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,r=this.fonts[t].monoCase.w,e.offsetWidth!==r?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,r=this.fonts[t].sansCase.w,e.offsetWidth!==r&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFonts.bind(this),20):setTimeout(function(){this.isLoaded=!0}.bind(this),0)},e.prototype.loaded=function(){return this.isLoaded},e}();FontManager=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()};var PropertyFactory=(km=initialDefaultFrame,lm=Math.abs,{getProp:function(t,e,r,i,s){var a;if(e.k.length)if("number"==typeof e.k[0])a=new vm(t,e,i,s);else switch(r){case 0:a=new wm(t,e,i,s);break;case 1:a=new xm(t,e,i,s)}else a=new um(t,e,i,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}}),km,lm;function mm(t,e){var r,i=this.offsetTime;"multidimensional"===this.propType&&(r=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,p,l,m,f=e.lastIndex,c=f,d=this.keyframes.length-1,u=!0;u;){if(s=this.keyframes[c],a=this.keyframes[c+1],c===d-1&&t>=a.t-i){s.h&&(s=a),f=0;break}if(a.t-i>t){f=c;break}c<d-1?c+=1:(f=0,u=!1)}var y,g=a.t-i,v=s.t-i;if(s.to){s.bezierData||(s.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=s.bezierData;if(g<=t||t<v){var b=g<=t?P.points.length-1:0;for(o=P.points[b].point.length,n=0;n<o;n+=1)r[n]=P.points[b].point[n]}else{s.__fnct?m=s.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,s.__fnct=m),h=m((t-v)/(g-v));var x,_=P.segmentLength*h,S=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastAddedLength:0;for(l=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastPoint:0,u=!0,p=P.points.length;u;){if(S+=P.points[l].partialLength,0==_||0===h||l===P.points.length-1){for(o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n];break}if(S<=_&&_<S+P.points[l+1].partialLength){for(x=(_-S)/P.points[l+1].partialLength,o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n]+(P.points[l+1].point[n]-P.points[l].point[n])*x;break}l<p-1?l+=1:u=!1}e._lastPoint=l,e._lastAddedLength=S-P.points[l].partialLength,e._lastKeyframeIndex=c}}else{var T,A,C,E,k;if(d=s.s.length,y=a.s||s.e,this.sh&&1!==s.h)if(g<=t)r[0]=y[0],r[1]=y[1],r[2]=y[2];else if(t<=v)r[0]=s.s[0],r[1]=s.s[1],r[2]=s.s[2];else{!function(t,e){var r=e[0],i=e[1],s=e[2],a=e[3],n=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s),o=Math.asin(2*r*i+2*s*a),h=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}(r,function(t,e,r){var i,s,a,n,o,h=[],p=t[0],l=t[1],m=t[2],f=t[3],c=e[0],d=e[1],u=e[2],y=e[3];(s=p*c+l*d+m*u+f*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y);o=1e-6<1-s?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,Math.sin(r*i)/a):(n=1-r,r);return h[0]=n*p+o*c,h[1]=n*l+o*d,h[2]=n*m+o*u,h[3]=n*f+o*y,h}(pm(s.s),pm(y),(t-v)/(g-v)))}else for(c=0;c<d;c+=1)1!==s.h&&(h=g<=t?1:t<v?0:(s.o.x.constructor===Array?(s.__fnct||(s.__fnct=[]),s.__fnct[c]?m=s.__fnct[c]:(T=void 0===s.o.x[c]?s.o.x[0]:s.o.x[c],A=void 0===s.o.y[c]?s.o.y[0]:s.o.y[c],C=void 0===s.i.x[c]?s.i.x[0]:s.i.x[c],E=void 0===s.i.y[c]?s.i.y[0]:s.i.y[c],m=BezierFactory.getBezierEasing(T,A,C,E).get,s.__fnct[c]=m)):s.__fnct?m=s.__fnct:(T=s.o.x,A=s.o.y,C=s.i.x,E=s.i.y,m=BezierFactory.getBezierEasing(T,A,C,E).get,s.__fnct=m),m((t-v)/(g-v)))),y=a.s||s.e,k=1===s.h?s.s[c]:s.s[c]+(y[c]-s.s[c])*h,1===d?r=k:r[c]=k}return e.lastIndex=f,r}function pm(t){var e=t[0]*degToRads,r=t[1]*degToRads,i=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(r/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(r/2),p=Math.sin(i/2);return[o*h*n+s*a*p,o*a*n+s*h*p,s*h*n-o*a*p,s*a*n-o*h*p]}function qm(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==km&&(this._caching.lastFrame>=r&&r<=t||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function rm(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<lm(this.v-e)&&(this.v=e,this._mdf=!0);else for(var r=0,i=this.v.length;r<i;)e=t[r]*this.mult,1e-5<lm(this.v[r]-e)&&(this.v[r]=e,this._mdf=!0),r+=1}function sm(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=this._isFirstFrame;var t,e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)r=this.effectsSequence[t](r);this.setVValue(r),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function tm(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function um(t,e,r,i){this.propType="unidimensional",this.mult=r||1,this.data=e,this.v=r?e.k*r:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function vm(t,e,r,i){this.propType="multidimensional",this.mult=r||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var s,a=e.k.length;this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a);createTypedArray("float32",a);for(this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function wm(t,e,r,i){this.propType="unidimensional",this.keyframes=e.k,this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:km,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=km,this.pv=km,this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.effectsSequence=[qm.bind(this)],this.addEffect=tm}function xm(t,e,r,i){this.propType="multidimensional";var s,a,n,o,h,p=e.k.length;for(s=0;s<p-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s].e&&(a=e.k[s].s,n=e.k[s].e,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[qm.bind(this)],this.keyframes=e.k,this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.frameId=-1;var l=e.k[0].s.length;for(this.v=createTypedArray("float32",l),this.pv=createTypedArray("float32",l),s=0;s<l;s+=1)this.v[s]=km,this.pv[s]=km;this._caching={lastFrame:km,lastIndex:0,value:createTypedArray("float32",l)},this.addEffect=tm}var TransformPropertyFactory=(Qo.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||t){if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var e,r,i=this.elem.globalData.frameRate;if(this.p&&this.p.keyframes&&this.p.getValueAtTime)r=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(e=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(e=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.01)/i,0)):(e=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){e=[],r=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(e[0]=s.getValueAtTime((s.keyframes[0].t+.01)/i,0),e[1]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[0]=s.getValueAtTime(s.keyframes[0].t/i,0),r[1]=a.getValueAtTime(a.keyframes[0].t/i,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(e[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/i,0),e[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/i,0),r[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0)):(e=[s.pv,a.pv],r[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/i,s.offsetTime),r[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime))}this.v.rotate(-Math.atan2(e[1]-r[1],e[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(!this.a.k&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}if(this.r){if(this.r.effectsSequence.length)return;this.pre.rotate(-this.r.v),this.appliedTransformations=4}else this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],Qo),Qo.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},Qo.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,r){return new Qo(t,e,r)}});function Qo(t,e,r){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(r||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var i,s=e.or.k.length;for(i=0;i<s;i+=1)e.or.k[i].to=e.or.k[i].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r<e;)this.v[r]=point_pool.newElement(),this.o[r]=point_pool.newElement(),this.i[r]=point_pool.newElement(),r+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,r,i,s){var a;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o}a[i]&&(!a[i]||s)||(a[i]=point_pool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],r[n][0],r[n][1],a,!1),n-=1;return t};var ShapePropertyFactory=function(){var s=-999999;function t(t,e,r){var i,s,a,n,o,h,p,l,m,f=r.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)i=c[0].s[0],a=!0,f=0;else if(t>=c[c.length-1].t-this.offsetTime)i=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y=f,g=c.length-1,v=!0;v&&(d=c[y],!((u=c[y+1]).t-this.offsetTime>t));)y<g-1?y+=1:v=!1;if(f=y,!(a=1===d.h)){if(t>=u.t-this.offsetTime)l=1;else if(t<d.t-this.offsetTime)l=0;else{var P;d.__fnct?P=d.__fnct:(P=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,d.__fnct=P),l=P((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}i=d.s[0]}for(h=e._length,p=i.i[0].length,r.lastIndex=f,n=0;n<h;n+=1)for(o=0;o<p;o+=1)m=a?i.i[n][o]:i.i[n][o]+(s.i[n][o]-i.i[n][o])*l,e.i[n][o]=m,m=a?i.o[n][o]:i.o[n][o]+(s.o[n][o]-i.o[n][o])*l,e.o[n][o]=m,m=a?i.v[n][o]:i.v[n][o]+(s.v[n][o]-i.v[n][o])*l,e.v[n][o]=m}function a(){this.paths=this.localShapeCollection}function e(t){!function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var r,i=t._length;for(r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return!1;return!0}(this.v,t)&&(this.v=shape_pool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function r(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=!1;var t,e=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k,r=this.effectsSequence.length;for(t=0;t<r;t+=1)e=this.effectsSequence[t](e);this.setVValue(e),this.lock=!1,this.frameId=this.elem.globalData.frameId}}function n(t,e,r){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var i=3===r?e.pt.k:e.ks.k;this.v=shape_pool.clone(i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=a,this.effectsSequence=[]}function i(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,r){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=3===r?e.pt.k:e.ks.k,this.k=!0,this.kf=!0;var i=this.keyframes[0].s[0].i.length;this.keyframes[0].s[0].i[0].length;this.v=shape_pool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=a,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,i=this._caching.lastFrame;return i!==s&&(i<e&&t<e||r<i&&r<t)||(this._caching.lastIndex=i<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}n.prototype.interpolateShape=t,n.prototype.getValue=r,n.prototype.setVValue=e,n.prototype.addEffect=i,o.prototype.getValue=r,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=i;var h,p=(h=roundCorner,l.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-i,a.v[1][0]=s?t+r:t-r,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+i,a.v[3][0]=s?t-r:t+r,a.v[3][1]=e,a.i[0][0]=s?t-r*h:t+r*h,a.i[0][1]=e-i,a.i[1][0]=s?t+r:t-r,a.i[1][1]=e-i*h,a.i[2][0]=s?t+r*h:t-r*h,a.i[2][1]=e+i,a.i[3][0]=s?t-r:t+r,a.i[3][1]=e+i*h,a.o[0][0]=s?t+r*h:t-r*h,a.o[0][1]=e-i,a.o[1][0]=s?t+r:t-r,a.o[1][1]=e+i*h,a.o[2][0]=s?t-r*h:t+r*h,a.o[2][1]=e+i,a.o[3][0]=s?t-r:t+r,a.o[3][1]=e-i*h}},extendPrototype([DynamicPropertyContainer],l),l);function l(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}var m=(f.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,r,i,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,p=this.os.v,l=this.is.v,m=2*Math.PI*o/(2*s),f=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(t=this.v._length=0;t<s;t+=1){r=n?p:l,i=n?m:f;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*i*r*d,y-v*i*r*d,u+g*i*r*d,y+v*i*r*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),r=2*Math.PI/e,i=this.or.v,s=this.os.v,a=2*Math.PI*i/(4*e),n=-Math.PI/2,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=i*Math.cos(n),p=i*Math.sin(n),l=0===h&&0===p?0:p/Math.sqrt(h*h+p*p),m=0===h&&0===p?0:-h/Math.sqrt(h*h+p*p);h+=+this.p.v[0],p+=+this.p.v[1],this.v.setTripleAt(h,p,h-l*a*s*o,p-m*a*s*o,h+l*a*s*o,p+m*a*s*o,t,!0),n+=r*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],f),f);function f(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}var c=(d.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=bm_min(r,i,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+s,t+r,e-i+a,0,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-a,t+r,e+i-s,1,!0),0!==s?(this.v.setTripleAt(t+r-s,e+i,t+r-s,e+i,t+r-a,e+i,2,!0),this.v.setTripleAt(t-r+s,e+i,t-r+a,e+i,t-r+s,e+i,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-s,t-r,e+i-a,4,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+a,t-r,e-i+s,5,!0),this.v.setTripleAt(t-r+s,e-i,t-r+s,e-i,t-r+a,e-i,6,!0),this.v.setTripleAt(t+r-s,e-i,t+r-a,e-i,t+r-s,e-i,7,!0)):(this.v.setTripleAt(t-r,e+i,t-r+a,e+i,t-r,e+i,2),this.v.setTripleAt(t-r,e-i,t-r,e-i+a,t-r,e-i,3))):(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+a,t+r,e-i+s,0,!0),0!==s?(this.v.setTripleAt(t+r-s,e-i,t+r-s,e-i,t+r-a,e-i,1,!0),this.v.setTripleAt(t-r+s,e-i,t-r+a,e-i,t-r+s,e-i,2,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+s,t-r,e-i+a,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-a,t-r,e+i-s,4,!0),this.v.setTripleAt(t-r+s,e+i,t-r+s,e+i,t-r+a,e+i,5,!0),this.v.setTripleAt(t+r-s,e+i,t+r-a,e+i,t+r-s,e+i,6,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-s,t+r,e+i-a,7,!0)):(this.v.setTripleAt(t-r,e-i,t-r+a,e-i,t-r,e-i,1,!0),this.v.setTripleAt(t-r,e+i,t-r,e+i-a,t-r,e+i,2,!0),this.v.setTripleAt(t+r,e+i,t+r-a,e+i,t+r,e+i,3,!0)))},getValue:function(t){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:a},extendPrototype([DynamicPropertyContainer],d),d);function d(t,e){this.v=shape_pool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}var u={getShapeProp:function(t,e,r){var i;return 3===r||4===r?i=(3===r?e.pt:e.ks).k.length?new o(t,e,r):new n(t,e,r):5===r?i=new c(t,e):6===r?i=new p(t,e):7===r&&(i=new m(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return o}};return u}(),ShapeModifiers=(Tr={},Ur={},Tr.registerModifier=function(t,e){Ur[t]||(Ur[t]=e)},Tr.getModifier=function(t,e,r){return new Ur[t](e,r)},Tr),Tr,Ur;function ShapeModifier(){}function TrimModifier(){}function RoundCornersModifier(){}function RepeaterModifier(){}function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}function DashProperty(t,e,r,i){this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=r,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(i);var s,a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function GradientProperty(t,e,r){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(r),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){var e={shape:t.sh,data:t,localShapeCollection:shapeCollection_pool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,r,i,s){var a=[];e<=1?a.push({s:t,e:e}):1<=t?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],p=a.length;for(n=0;n<p;n+=1){var l,m;if((o=a[n]).e*s<i||o.s*s>i+r);else l=o.s*s<=i?0:(o.s*s-i)/r,m=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([l,m])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e<r;e+=1)segments_length_pool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,r,i;if(this._mdf||t){var s=this.o.v%360/360;if(s<0&&(s+=1),e=(1<this.s.v?1:this.s.v<0?0:this.s.v)+s,(r=(1<this.e.v?1:this.e.v<0?0:this.e.v)+s)<e){var a=e;e=r,r=a}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var n,o,h,p,l,m,f=this.shapes.length,c=0;if(r===e)for(n=0;n<f;n+=1)this.shapes[n].localShapeCollection.releaseShapes(),this.shapes[n].shape._mdf=!0,this.shapes[n].shape.paths=this.shapes[n].localShapeCollection;else if(1===r&&0===e||0===r&&1===e){if(this._mdf)for(n=0;n<f;n+=1)this.shapes[n].pathsData.length=0,this.shapes[n].shape._mdf=!0}else{var d,u,y=[];for(n=0;n<f;n+=1)if((d=this.shapes[n]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=d.shape.paths)._length,m=0,!d.shape._mdf&&d.pathsData.length)m=d.totalShapeLength;else{for(p=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)l=bez.getSegmentsLength(i.shapes[o]),p.push(l),m+=l.totalLength;d.totalShapeLength=m,d.pathsData=p}c+=m,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,P=r,b=0;for(n=f-1;0<=n;n-=1)if((d=this.shapes[n]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&1<f?(g=this.calculateShapeEdges(e,r,d.totalShapeLength,b,c),b+=d.totalShapeLength):g=[[v,P]],h=g.length,o=0;o<h;o+=1){v=g[o][0],P=g[o][1],y.length=0,P<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*P}):1<=v?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(P-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(P-1)}));var x=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(1<y.length)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var _=x.pop();this.addPaths(x,u),x=this.addShapes(d,y[1],_)}else this.addPaths(x,u),x=this.addShapes(d,y[1]);this.addPaths(x,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,r,i,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(r[0],r[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(i[0],i[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,r,i){e.setXYAt(t[1],t[5],"o",r),e.setXYAt(t[2],t[6],"i",r+1),i&&e.setXYAt(t[0],t[4],"v",r),e.setXYAt(t[3],t[7],"v",r+1)},TrimModifier.prototype.addShapes=function(t,e,r){var i,s,a,n,o,h,p,l,m=t.pathsData,f=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(l=r?(o=r._length,r._length):(r=shape_pool.newElement(),o=0),u.push(r),i=0;i<c;i+=1){for(h=m[i].lengths,r.c=f[i].c,a=f[i].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,r.c=!1;else{if(d>e.e){r.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[s],f[i].v[s],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[s],f[i].o[s-1],f[i].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1),d+=n.addedLength,o+=1}if(f[i].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[0],f[i].v[0],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[0],f[i].o[s-1],f[i].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1)}else r.c=!1;d+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[l][0],r.v[l][1],"i",l),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),d>e.e)break;i<c-1&&(r=shape_pool.newElement(),y=!0,u.push(r),o=0)}return u},ShapeModifiers.registerModifier("tm",TrimModifier),extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var r=shape_pool.newElement();r.c=t.c;var i,s,a,n,o,h,p,l,m,f,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=d=s[0]+(o[0]-s[0])*p,m=u=s[1]-(s[1]-o[1])*p,f=l-(l-s[0])*roundCorner,c=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=f=s[0]+(o[0]-s[0])*p,m=c=s[1]+(o[1]-s[1])*p,d=l-(l-s[0])*roundCorner,u=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g)):r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g):r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1;return r},RoundCornersModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(r=0;r<o;r+=1){if((a=this.shapes[r]).shape.paths,n=a.localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},ShapeModifiers.registerModifier("rd",RoundCornersModifier),extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,r,i,s,a){var n=a?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-s),h=i.s.v[1]+(1-i.s.v[1])*(1-s);t.translate(i.p.v[0]*n*s,i.p.v[1]*n*s,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*s),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),r.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),r.scale(a?1/o:o,a?1/h:h),r.translate(i.a.v[0],i.a.v[1],i.a.v[2])},RepeaterModifier.prototype.init=function(t,e,r,i){this.elem=t,this.arr=e,this.pos=r,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[r]);for(;0<r;)r-=1,this._elements.unshift(e[r]),1;this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){t.length;var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,r,i,s,a;if(this._mdf||t){var n,o=Math.ceil(this.c.v);if(this._groups.length<o){for(;this._groups.length<o;){var h={it:this.cloneElements(this._elements),ty:"gr"};h.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,h),this._groups.splice(0,0,h),this._currentCopies+=1}this.elem.reloadShapes()}for(i=a=0;i<=this._groups.length-1;i+=1)n=a<o,this._groups[i]._render=n,this.changeGroupRender(this._groups[i].it,n),a+=1;this._currentCopies=o;var p=this.o.v,l=p%1,m=0<p?Math.floor(p):Math.ceil(p),f=(this.tr.v.props,this.pMatrix.props),c=this.rMatrix.props,d=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var u,y,g=0;if(0<p){for(;g<m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),g+=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,l,!1),g+=l)}else if(p<0){for(;m<g;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),g-=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-l,!0),g-=l)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(y=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==g){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9],c[10],c[11],c[12],c[13],c[14],c[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),this.matrix.transform(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9],f[10],f[11],f[12],f[13],f[14],f[15]),u=0;u<y;u+=1)r[u]=this.matrix.props[u];this.matrix.reset()}else for(this.matrix.reset(),u=0;u<y;u+=1)r[u]=this.matrix.props[u];g+=1,a-=1,i+=s}}else for(a=this._currentCopies,i=0,s=1;a;)r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,i+=s},RepeaterModifier.prototype.addShape=function(){},ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shape_pool.release(this.shapes[t]);this._length=0},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,r=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<r;e+=1)"o"!=this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),GradientProperty.prototype.comparePoints=function(t,e){for(var r=0,i=this.o.length/2;r<i;){if(.01<Math.abs(t[4*r]-t[4*e+2*r]))return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,r,i,s=4*this.data.p;for(e=0;e<s;e+=1)r=e%4==0?100:255,i=Math.round(this.prop.v[e]*r),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)r=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty);var buildShapeString=function(t,e,r,i){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[s][0],n[s][1])+" "+i.applyToPointStringified(o[s][0],o[s][1]);return r&&e&&(h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},ImagePreloader=function(){},featureSupport=(Iv={maskType:!0},(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(Iv.maskType=!1),Iv),Iv,filtersFactory=(Jv={},Jv.createFilter=function(t){var e=createNS("filter");return e.setAttribute("id",t),e.setAttribute("filterUnits","objectBoundingBox"),e.setAttribute("x","0%"),e.setAttribute("y","0%"),e.setAttribute("width","100%"),e.setAttribute("height","100%"),e},Jv.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1"),t},Jv),Jv,assetLoader={load:function(t,e,r){var i,s=new XMLHttpRequest;s.open("GET",t,!0);try{s.responseType="json"}catch(t){}s.send(),s.onreadystatechange=function(){if(4==s.readyState)if(200==s.status)i=Pv(s),e(i);else try{i=Pv(s),e(i)}catch(t){r&&r(t)}}}};function Pv(t){return t.response&&"object"==typeof t.response?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):void 0}var assetLoader=null;function TextAnimatorProperty(t,e,r){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=r,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(r)}function TextAnimatorDataProperty(t,e,r){var i={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,r):i,rx:a.rx?s(t,a.rx,0,degToRads,r):i,ry:a.ry?s(t,a.ry,0,degToRads,r):i,sk:a.sk?s(t,a.sk,0,degToRads,r):i,sa:a.sa?s(t,a.sa,0,degToRads,r):i,s:a.s?s(t,a.s,1,.01,r):i,a:a.a?s(t,a.a,1,0,r):i,o:a.o?s(t,a.o,0,.01,r):i,p:a.p?s(t,a.p,1,0,r):i,sw:a.sw?s(t,a.sw,0,0,r):i,sc:a.sc?s(t,a.sc,1,0,r):i,fc:a.fc?s(t,a.fc,1,0,r):i,fh:a.fh?s(t,a.fh,0,0,r):i,fs:a.fs?s(t,a.fs,0,.01,r):i,fb:a.fb?s(t,a.fb,0,.01,r):i,t:a.t?s(t,a.t,0,0,r):i},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,r),this.s.t=e.s.t}function LetterProps(t,e,r,i,s,a){this.o=t,this.sw=e,this.sc=r,this.fc=i,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!r,fc:!!i,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,r=this._textData.a.length,i=PropertyFactory.getProp;for(t=0;t<r;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:this._textData.p.r,m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var r,i,s,a,n,o,h,p,l,m,f,c,d,u,y,g,v,P,b,x=this._moreOptions.alignment.v,_=this._animatorsData,S=this._textData,T=this.mHelper,A=this._renderType,C=this.renderedLetters.length,E=(this.data,t.l);if(this._hasMaskedPath){if(b=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,D=b.v;for(this._pathData.r&&(D=D.reverse()),n={tLength:0,segments:[]},a=D._length-1,s=g=0;s<a;s+=1)k=bez.buildBezierData(D.v[s],D.v[s+1],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[s+1][0]-D.v[s+1][0],D.i[s+1][1]-D.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,b.v.c&&(k=bez.buildBezierData(D.v[s],D.v[0],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[0][0]-D.v[0][0],D.i[0][1]-D.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=1,l=!(p=f=0),u=n.segments,o<0&&b.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),m=(d=u[f=u.length-1].points).length-1;o<0;)o+=d[m].partialLength,(m-=1)<0&&(m=(d=u[f-=1].points).length-1);c=(d=u[f].points)[m-1],y=(h=d[m]).partialLength}a=E.length,i=r=0;var M,I,w,F,V=1.2*t.finalSize*.714,R=!0;w=_.length;var L,z,O,B,N,G,j,J,K,q,H,W,X,Y=-1,Q=o,$=f,U=m,Z=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,it=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(E[s].n){for(rt&&(rt+=it);at<s;)E[at].animatorJustifyOffset=rt,at+=1;nt=!(rt=0)}else{for(I=0;I<w;I+=1)(M=_[I].a).t.propType&&(nt&&2===t.j&&(it+=M.t.v*st),(L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?rt+=M.t.v*L[0]*st:rt+=M.t.v*L*st);nt=!1}for(rt&&(rt+=it);at<s;)E[at].animatorJustifyOffset=rt,at+=1}for(s=0;s<a;s+=1){if(T.reset(),N=1,E[s].n)r=0,i+=t.yOffset,i+=R?1:0,o=Q,R=!1,0,this._hasMaskedPath&&(m=U,c=(d=u[f=$].points)[m-1],y=(h=d[m]).partialLength,p=0),X=q=W=tt="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Z!==E[s].line){switch(t.j){case 1:o+=g-t.lineWidths[E[s].line];break;case 2:o+=(g-t.lineWidths[E[s].line])/2}Z=E[s].line}Y!==E[s].ind&&(E[Y]&&(o+=E[Y].extra),o+=E[s].an/2,Y=E[s].ind),o+=x[0]*E[s].an/200;var ot=0;for(I=0;I<w;I+=1)(M=_[I].a).p.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?ot+=M.p.v[0]*L[0]:ot+=M.p.v[0]*L),M.a.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?ot+=M.a.v[0]*L[0]:ot+=M.a.v[0]*L);for(l=!0;l;)o+ot<=p+y||!d?(v=(o+ot-p)/h.partialLength,O=c.point[0]+(h.point[0]-c.point[0])*v,B=c.point[1]+(h.point[1]-c.point[1])*v,T.translate(-x[0]*E[s].an/200,-x[1]*V/100),l=!1):d&&(p+=h.partialLength,(m+=1)>=d.length&&(m=0,d=u[f+=1]?u[f].points:b.v.c?u[f=m=0].points:(p-=h.partialLength,null)),d&&(c=h,y=(h=d[m]).partialLength));z=E[s].an/2-E[s].add,T.translate(-z,0,0)}else z=E[s].an/2-E[s].add,T.translate(-z,0,0),T.translate(-x[0]*E[s].an/200,-x[1]*V/100,0);for(E[s].l/2,I=0;I<w;I+=1)(M=_[I].a).t.propType&&(L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars),0===r&&0===t.j||(this._hasMaskedPath?L.length?o+=M.t.v*L[0]:o+=M.t.v*L:L.length?r+=M.t.v*L[0]:r+=M.t.v*L));for(E[s].l/2,t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(G=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(J=[t.fc[0],t.fc[1],t.fc[2]]),I=0;I<w;I+=1)(M=_[I].a).a.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?T.translate(-M.a.v[0]*L[0],-M.a.v[1]*L[1],M.a.v[2]*L[2]):T.translate(-M.a.v[0]*L,-M.a.v[1]*L,M.a.v[2]*L));for(I=0;I<w;I+=1)(M=_[I].a).s.propType&&((L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars)).length?T.scale(1+(M.s.v[0]-1)*L[0],1+(M.s.v[1]-1)*L[1],1):T.scale(1+(M.s.v[0]-1)*L,1+(M.s.v[1]-1)*L,1));for(I=0;I<w;I+=1){if(M=_[I].a,L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars),M.sk.propType&&(L.length?T.skewFromAxis(-M.sk.v*L[0],M.sa.v*L[1]):T.skewFromAxis(-M.sk.v*L,M.sa.v*L)),M.r.propType&&(L.length?T.rotateZ(-M.r.v*L[2]):T.rotateZ(-M.r.v*L)),M.ry.propType&&(L.length?T.rotateY(M.ry.v*L[1]):T.rotateY(M.ry.v*L)),M.rx.propType&&(L.length?T.rotateX(M.rx.v*L[0]):T.rotateX(M.rx.v*L)),M.o.propType&&(L.length?N+=(M.o.v*L[0]-N)*L[0]:N+=(M.o.v*L-N)*L),t.strokeWidthAnim&&M.sw.propType&&(L.length?j+=M.sw.v*L[0]:j+=M.sw.v*L),t.strokeColorAnim&&M.sc.propType)for(K=0;K<3;K+=1)L.length?G[K]=G[K]+(M.sc.v[K]-G[K])*L[0]:G[K]=G[K]+(M.sc.v[K]-G[K])*L;if(t.fillColorAnim&&t.fc){if(M.fc.propType)for(K=0;K<3;K+=1)L.length?J[K]=J[K]+(M.fc.v[K]-J[K])*L[0]:J[K]=J[K]+(M.fc.v[K]-J[K])*L;M.fh.propType&&(J=L.length?addHueToRGB(J,M.fh.v*L[0]):addHueToRGB(J,M.fh.v*L)),M.fs.propType&&(J=L.length?addSaturationToRGB(J,M.fs.v*L[0]):addSaturationToRGB(J,M.fs.v*L)),M.fb.propType&&(J=L.length?addBrightnessToRGB(J,M.fb.v*L[0]):addBrightnessToRGB(J,M.fb.v*L))}}for(I=0;I<w;I+=1)(M=_[I].a).p.propType&&(L=_[I].s.getMult(E[s].anIndexes[I],S.a[I].s.totalChars),this._hasMaskedPath?L.length?T.translate(0,M.p.v[1]*L[0],-M.p.v[2]*L[1]):T.translate(0,M.p.v[1]*L,-M.p.v[2]*L):L.length?T.translate(M.p.v[0]*L[0],M.p.v[1]*L[1],-M.p.v[2]*L[2]):T.translate(M.p.v[0]*L,M.p.v[1]*L,-M.p.v[2]*L));if(t.strokeWidthAnim&&(q=j<0?0:j),t.strokeColorAnim&&(H="rgb("+Math.round(255*G[0])+","+Math.round(255*G[1])+","+Math.round(255*G[2])+")"),t.fillColorAnim&&t.fc&&(W="rgb("+Math.round(255*J[0])+","+Math.round(255*J[1])+","+Math.round(255*J[2])+")"),this._hasMaskedPath){if(T.translate(0,-t.ls),T.translate(0,x[1]*V/100+i,0),S.p.p){P=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(P)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),T.rotate(-ht*Math.PI/180)}T.translate(O,B,0),o-=x[0]*E[s].an/200,E[s+1]&&Y!==E[s+1].ind&&(o+=E[s].an/2,o+=t.tr/1e3*t.finalSize)}else{switch(T.translate(r,i,0),t.ps&&T.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:T.translate(E[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[E[s].line]),0,0);break;case 2:T.translate(E[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[E[s].line])/2,0,0)}T.translate(0,-t.ls),T.translate(z,0,0),T.translate(x[0]*E[s].an/200,x[1]*V/100,0),r+=E[s].l+t.tr/1e3*t.finalSize}"html"===A?tt=T.toCSS():"svg"===A?tt=T.to2dCSS():et=[T.props[0],T.props[1],T.props[2],T.props[3],T.props[4],T.props[5],T.props[6],T.props[7],T.props[8],T.props[9],T.props[10],T.props[11],T.props[12],T.props[13],T.props[14],T.props[15]],X=N}C<=s?(F=new LetterProps(X,q,H,W,tt,et),this.renderedLetters.push(F),C+=1,this.lettersChangedFlag=!0):(F=this.renderedLetters[s],this.lettersChangedFlag=F.update(X,q,H,W,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),LetterProps.prototype.update=function(t,e,r,i,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==r&&(this.sc=r,n=this._mdf.sc=!0),this.fc!==i&&(this.fc=i,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{this.lock=!0,this._mdf=!1;var i,s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;i<s;i+=1)a=r!==this.keysIndex?this.effectsSequence[i](a,a.t):this.effectsSequence[i](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.pv=this.v=this.currentData,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,r=0,i=t.length;r<=i-1&&(t[r].s,!(r===i-1||t[r+1].t>e));)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e=FontManager.getCombinedCharacterCodes(),r=[],i=0,s=t.length;i<s;)-1!==e.indexOf(t.charCodeAt(i))?r[r.length-1]+=t.charAt(i):r.push(t.charAt(i)),i+=1;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,p=this.data,l=[],m=0,f=p.m.g,c=0,d=0,u=0,y=[],g=0,v=0,P=h.getFontByName(t.f),b=0,x=P.fStyle?P.fStyle.split(" "):[],_="normal",S="normal";for(r=x.length,e=0;e<r;e+=1)switch(x[e].toLowerCase()){case"italic":S="italic";break;case"bold":_="700";break;case"black":_="900";break;case"medium":_="500";break;case"regular":case"normal":_="400";break;case"light":case"thin":_="200"}t.fWeight=P.fWeight||_,t.fStyle=S,r=t.t.length,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),t.finalLineHeight=t.lh;var T,A=t.tr/1e3*t.finalSize;if(t.sz)for(var C,E,k=!0,D=t.sz[0],M=t.sz[1];k;){g=C=0,r=(E=this.buildFinalText(t.t)).length,A=t.tr/1e3*t.finalSize;var I=-1;for(e=0;e<r;e+=1)T=E[e].charCodeAt(0),i=!1," "===E[e]?I=e:13!==T&&3!==T||(i=!(g=0),C+=t.finalLineHeight||1.2*t.finalSize),D<g+(b=h.chars?(o=h.getCharData(E[e],P.fStyle,P.fFamily),i?0:o.w*t.finalSize/100):h.measureText(E[e],t.f,t.finalSize))&&" "!==E[e]?(-1===I?r+=1:e=I,C+=t.finalLineHeight||1.2*t.finalSize,E.splice(e,I===e?1:0,"\r"),I=-1,g=0):(g+=b,g+=A);C+=P.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&M<C?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=E,r=t.finalText.length,k=!1)}g=-A;var w,F=b=0;for(e=0;e<r;e+=1)if(i=!1,T=(w=t.finalText[e]).charCodeAt(0)," "===w?s="\xa0":13===T||3===T?(F=0,y.push(g),v=v<g?g:v,g=-2*A,i=!(s=""),u+=1):s=t.finalText[e],b=h.chars?(o=h.getCharData(w,P.fStyle,h.getFontByName(t.f).fFamily),i?0:o.w*t.finalSize/100):h.measureText(s,t.f,t.finalSize)," "===w?F+=b+A:(g+=b+A+F,F=0),l.push({l:b,an:b,add:c,n:i,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==f){if(c+=b,""===s||"\xa0"===s||e===r-1){for(""!==s&&"\xa0"!==s||(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;m+=1,c=0}}else if(3==f){if(c+=b,""===s||e===r-1){for(""===s&&(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;c=0,m+=1}}else l[m].ind=m,l[m].extra=0,m+=1;if(t.l=l,v=v<g?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var V,R,L=p.a;n=L.length;var z,O,B=[];for(a=0;a<n;a+=1){for((V=L[a]).a.sc&&(t.strokeColorAnim=!0),V.a.sw&&(t.strokeWidthAnim=!0),(V.a.fc||V.a.fh||V.a.fs||V.a.fb)&&(t.fillColorAnim=!0),O=0,z=V.s.b,e=0;e<r;e+=1)(R=l[e]).anIndexes[a]=O,(1==z&&""!==R.val||2==z&&""!==R.val&&"\xa0"!==R.val||3==z&&(R.n||"\xa0"==R.val||e==r-1)||4==z&&(R.n||e==r-1))&&(1===V.s.rn&&B.push(O),O+=1);p.a[a].s.totalChars=O;var N,G=-1;if(1===V.s.rn)for(e=0;e<r;e+=1)G!=(R=l[e]).anIndexes[a]&&(G=R.anIndexes[a],N=B.splice(Math.floor(Math.random()*B.length),1)[0]),R.anIndexes[a]=N}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=P.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var r=this.copyData({},this.data.d.k[e].s);r=this.copyData(r,t),this.data.d.k[e].s=r,this.recalculate(e),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=(cz=Math.max,dz=Math.min,ez=Math.floor,fz.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e=BezierFactory.getBezierEasing(this.ne.v/100,0,1-this.xe.v/100,1).get,r=0,i=this.finalS,s=this.finalE,a=this.data.sh;if(2==a)r=e(r=s===i?s<=t?1:0:cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(3==a)r=e(r=s===i?s<=t?0:1:1-cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(4==a)s===i?r=0:(r=cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)))<.5?r*=2:r=1-2*(r-.5),r=e(r);else if(5==a){if(s===i)r=0;else{var n=s-i,o=-n/2+(t=dz(cz(0,t+.5-i),s-i)),h=n/2;r=Math.sqrt(1-o*o/(h*h))}r=e(r)}else r=6==a?e(r=s===i?0:(t=dz(cz(0,t+.5-i),s-i),(1+Math.cos(Math.PI+2*Math.PI*t/(s-i)))/2)):(t>=ez(i)&&(r=t-i<0?1-(i-t):cz(0,dz(s-t,1))),e(r));return r*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(s<i){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],fz),{getTextSelectorProp:function(t,e,r){return new fz(t,e,r)}}),cz,dz,ez;function fz(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}var pool_factory=function(t,e,r,i){var s=0,a=t,n=createSizedArray(a);function o(){return s?n[s-=1]:e()}return{newElement:o,release:function(t){s===a&&(n=pooling.double(n),a*=2),r&&r(t),n[s]=t,s+=1}}},pooling={double:function(t){return t.concat(createSizedArray(t.length))}},point_pool=pool_factory(8,function(){return createTypedArray("float32",2)}),shape_pool=(Vz=pool_factory(4,function(){return new ShapePath},function(t){var e,r=t._length;for(e=0;e<r;e+=1)point_pool.release(t.v[e]),point_pool.release(t.i[e]),point_pool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}),Vz.clone=function(t){var e,r=Vz.newElement(),i=void 0===t._length?t.v.length:t._length;for(r.setLength(i),r.c=t.c,e=0;e<i;e+=1)r.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return r},Vz),Vz,shapeCollection_pool=(cA={newShapeCollection:function(){var t;t=dA?fA[dA-=1]:new ShapeCollection;return t},release:function(t){var e,r=t._length;for(e=0;e<r;e+=1)shape_pool.release(t.shapes[e]);t._length=0,dA===eA&&(fA=pooling.double(fA),eA*=2);fA[dA]=t,dA+=1}},dA=0,eA=4,fA=createSizedArray(eA),cA),cA,dA,eA,fA,segments_length_pool=pool_factory(8,function(){return{lengths:[],totalLength:0}},function(t){var e,r=t.lengths.length;for(e=0;e<r;e+=1)bezier_length_pool.release(t.lengths[e]);t.lengths.length=0}),bezier_length_pool=pool_factory(8,function(){return{addedLength:0,percents:createTypedArray("float32",defaultCurveSegments),lengths:createTypedArray("float32",defaultCurveSegments)}});function BaseRenderer(){}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var r="";if(e&&e.title){var i=createNS("title"),s=createElementID();i.setAttribute("id",s),i.textContent=e.title,this.svgElement.appendChild(i),r+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),r+=" "+n}r&&this.svgElement.setAttribute("aria-labelledby",r);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!e||!1!==e.hideOnTransparent,viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||""},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",className:e&&e.className||""},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas"}function MaskElement(t,e,r){this.data=t,this.element=e,this.globalData=r,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var i,s=this.globalData.defs,a=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(a),this.solidPath="";var n,o,h,p,l,m,f,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(i=0;i<a;i++)if(("a"!==c[i].mode&&"n"!==c[i].mode||c[i].inv||100!==c[i].o.k)&&(v=g="mask"),"s"!=c[i].mode&&"i"!=c[i].mode||0!==d?p=null:((p=createNS("rect")).setAttribute("fill","#ffffff"),p.setAttribute("width",this.element.comp.data.w||0),p.setAttribute("height",this.element.comp.data.h||0),u.push(p)),n=createNS("path"),"n"!=c[i].mode){var P;if(d+=1,n.setAttribute("fill","s"===c[i].mode?"#000000":"#ffffff"),n.setAttribute("clip-rule","nonzero"),0!==c[i].x.k?(v=g="mask",f=PropertyFactory.getProp(this.element,c[i].x,0,null,this.element),P=createElementID(),(l=createNS("filter")).setAttribute("id",P),(m=createNS("feMorphology")).setAttribute("operator","erode"),m.setAttribute("in","SourceGraphic"),m.setAttribute("radius","0"),l.appendChild(m),s.appendChild(l),n.setAttribute("stroke","s"===c[i].mode?"#000000":"#ffffff")):f=m=null,this.storedData[i]={elem:n,x:f,expan:m,lastPath:"",lastOperator:"",filterId:P,lastRadius:0},"i"==c[i].mode){h=u.length;var b=createNS("g");for(o=0;o<h;o+=1)b.appendChild(u[o]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",y+"_"+d),x.appendChild(n),s.appendChild(x),b.setAttribute("mask","url("+locationHref+"#"+y+"_"+d+")"),u.length=0,u.push(b)}else u.push(n);c[i].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[i]={elem:n,lastPath:"",op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),invRect:p},this.viewData[i].prop.k||this.drawPath(c[i],this.viewData[i].prop.v,this.viewData[i])}else this.viewData[i]={op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),elem:n,lastPath:""},s.appendChild(n);for(this.maskElement=createNS(g),a=u.length,i=0;i<a;i+=1)this.maskElement.appendChild(u[i]);0<d&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+locationHref+"#"+y+")"),s.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}function HierarchyElement(){}function FrameElement(){}function TransformElement(){}function RenderableElement(){}function RenderableDOMElement(){}function ProcessedElement(t,e){this.elem=t,this.pos=e}function SVGShapeData(t,e,r){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=r,this.lvl=e,this._isAnimated=!!r.k;for(var i=0,s=t.length;i<s;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}function CVShapeData(t,e,r,i){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s=4;"rc"==e.ty?s=5:"el"==e.ty?s=6:"sr"==e.ty&&(s=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,s,t);var a,n,o=r.length;for(a=0;a<o;a+=1)r[a].closed||(n={transforms:i.addTransformSequence(r[a].transforms),trNodes:[]},this.styledShapes.push(n),r[a].elements.push(n))}function BaseElement(){}function NullElement(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initFrame(),this.initTransform(t,e,r),this.initHierarchy()}function SVGBaseElement(){}function IShapeElement(){}function ITextElement(){}function ICompElement(){}function IImageElement(t,e,r){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,r),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ISolidElement(t,e,r){this.initElement(t,e,r)}function SVGShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,r),this.prevViewData=[]}function CVContextData(){this.saved=[],this.cArrPos=0,this.cTr=new Matrix,this.cO=1;var t;for(this.savedOp=createTypedArray("float32",15),t=0;t<15;t+=1)this.saved[t]=createTypedArray("float32",16);this._length=15}function CVBaseElement(){}function CVCompElement(t,e,r){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,r),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CVMaskElement(t,e){this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r,i=this.masksProperties.length,s=!1;for(r=0;r<i;r++)"n"!==this.masksProperties[r].mode&&(s=!0),this.viewData[r]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[r],3);(this.hasMasks=s)&&this.element.addRenderableComponent(this)}function CVShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,r)}function CVSolidElement(t,e,r){this.initElement(t,e,r)}function CVEffects(){}BaseRenderer.prototype.checkLayers=function(t){var e,r,i=this.layers.length;for(this.completeLayers=!0,e=i-1;0<=e;e--)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 13:return this.createCamera(t)}return this.createNull(t)},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){this.completeLayers=!1;var e,r,i=t.length,s=this.layers.length;for(e=0;e<i;e+=1)for(r=0;r<s;){if(this.layers[r].id==t[e].id){this.layers[r]=t[e];break}r+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,r){for(var i=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(i[a]&&!0!==i[a]?(r.push(i[a]),i[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,r):t.setHierarchy(r)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,r=t.length;for(e=0;e<r;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}},extendPrototype([BaseRenderer],SVGRenderer),SVGRenderer.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRenderer.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRenderer.prototype.createText=function(t){return new SVGTextElement(t,this.globalData,this)},SVGRenderer.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},SVGRenderer.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRenderer.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)"),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var r=createNS("clipPath"),i=createNS("rect");i.setAttribute("width",t.w),i.setAttribute("height",t.h),i.setAttribute("x",0),i.setAttribute("y",0);var s=createElementID();r.setAttribute("id",s),r.appendChild(i),this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+s+")"),e.appendChild(r),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRenderer.prototype.destroy=function(){this.animationItem.wrapper.innerHTML="",this.layerElement=null,this.globalData.defs=null;var t,e=this.layers?this.layers.length:0;for(t=0;t<e;t++)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRenderer.prototype.updateContainerSize=function(){},SVGRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){e[t]=!0;var r=this.createItem(this.layers[t]);e[t]=r,expressionsPlugin&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(r),r.initExpressions()),this.appendElementInPos(r,t),this.layers[t].tt&&(this.elements[t-1]&&!0!==this.elements[t-1]?r.setMatte(e[t-1].layerId):(this.buildItem(t-1),this.addPendingElement(r)))}},SVGRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,r=this.elements.length;e<r;){if(this.elements[e]===t){t.setMatte(this.elements[e-1].layerId);break}e+=1}}},SVGRenderer.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var e,r=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=r-1;0<=e;e--)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<r;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRenderer.prototype.appendElementInPos=function(t,e){var r=t.getBaseElement();if(r){for(var i,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(r,i):this.layerElement.appendChild(r)}},SVGRenderer.prototype.hide=function(){this.layerElement.style.display="none"},SVGRenderer.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseRenderer],CanvasRenderer),CanvasRenderer.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRenderer.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRenderer.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},CanvasRenderer.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRenderer.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRenderer.prototype.ctxTransform=function(t){if(1!==t[0]||0!==t[1]||0!==t[4]||1!==t[5]||0!==t[12]||0!==t[13])if(this.renderConfig.clearCanvas){this.transformMat.cloneFromProps(t);var e=this.contextData.cTr.props;this.transformMat.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]),this.contextData.cTr.cloneFromProps(this.transformMat.props);var r=this.contextData.cTr.props;this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13])}else this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRenderer.prototype.ctxOpacity=function(t){if(!this.renderConfig.clearCanvas)return this.canvasContext.globalAlpha*=t<0?0:t,void(this.globalData.currentGlobalAlpha=this.contextData.cO);this.contextData.cO*=t<0?0:t,this.globalData.currentGlobalAlpha!==this.contextData.cO&&(this.canvasContext.globalAlpha=this.contextData.cO,this.globalData.currentGlobalAlpha=this.contextData.cO)},CanvasRenderer.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRenderer.prototype.save=function(t){if(this.renderConfig.clearCanvas){t&&this.canvasContext.save();var e=this.contextData.cTr.props;this.contextData._length<=this.contextData.cArrPos&&this.contextData.duplicate();var r,i=this.contextData.saved[this.contextData.cArrPos];for(r=0;r<16;r+=1)i[r]=e[r];this.contextData.savedOp[this.contextData.cArrPos]=this.contextData.cO,this.contextData.cArrPos+=1}else this.canvasContext.save()},CanvasRenderer.prototype.restore=function(t){if(this.renderConfig.clearCanvas){t&&(this.canvasContext.restore(),this.globalData.blendMode="source-over"),this.contextData.cArrPos-=1;var e,r=this.contextData.saved[this.contextData.cArrPos],i=this.contextData.cTr.props;for(e=0;e<16;e+=1)i[e]=r[e];this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),r=this.contextData.savedOp[this.contextData.cArrPos],this.contextData.cO=r,this.globalData.currentGlobalAlpha!==r&&(this.canvasContext.globalAlpha=r,this.globalData.currentGlobalAlpha=r)}else this.canvasContext.restore()},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRenderer.prototype.updateContainerSize=function(){var t,e,r,i;if(this.reset(),this.animationItem.wrapper&&this.animationItem.container?(t=this.animationItem.wrapper.offsetWidth,e=this.animationItem.wrapper.offsetHeight,this.animationItem.container.setAttribute("width",t*this.renderConfig.dpr),this.animationItem.container.setAttribute("height",e*this.renderConfig.dpr)):(t=this.canvasContext.canvas.width*this.renderConfig.dpr,e=this.canvasContext.canvas.height*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var s=this.renderConfig.preserveAspectRatio.split(" "),a=s[1]||"meet",n=s[0]||"xMidYMid",o=n.substr(0,4),h=n.substr(4);(r=t/e)<(i=this.transformCanvas.w/this.transformCanvas.h)&&"meet"===a||i<r&&"slice"===a?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=t/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=e/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"==this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0;this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRenderer.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&(this.animationItem.wrapper.innerHTML=""),t=(this.layers?this.layers.length:0)-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRenderer.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r,i=this.layers.length;for(this.completeLayers||this.checkLayers(t),r=0;r<i;r++)(this.completeLayers||this.elements[r])&&this.elements[r].prepareFrame(t-this.layers[r].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&this.elements[r].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){var r=this.createItem(this.layers[t],this,this.globalData);(e[t]=r).initExpressions()}},CanvasRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRenderer.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRenderer.prototype.show=function(){this.animationItem.container.style.display="block"},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h},this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,r=this.element.finalTransform.mat,i=this.masksProperties.length;for(e=0;e<i;e++)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&(this.viewData[e].invRect.setAttribute("x",-r.props[12]),this.viewData[e].invRect.setAttribute("y",-r.props[13])),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+locationHref+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,r){var i,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,i=1;i<s;i+=1)a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&1<s&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var r,i=this.dynamicProperties.length;for(r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},TransformElement.prototype={initTransform:function(){this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_opMdf:!1,mat:new Matrix},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,r=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;r<i;){if(this.hierarchy[r].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}r+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),r=0;r<i;r+=1)t=this.hierarchy[r].finalTransform.mProp.v.props,e.transform(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var r=!0,i=this.comp;r;)i.finalTransform?(i.data.hasMask&&e.splice(0,0,i.finalTransform),i=i.comp):r=!1;var s,a,n=e.length;for(s=0;s<n;s+=1)a=e[s].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,r=t.length,i="_";for(e=0;e<r;e+=1)i+=t[e].transform.key+"_";var s=this.sequences[i];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[i]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var r,i=0,s=t.transforms.length,a=e;i<s&&!e;){if(t.transforms[i].transform.mProps._mdf){a=!0;break}i+=1}if(a)for(t.finalTransform.reset(),i=s-1;0<=i;i-=1)r=t.transforms[i].transform.mProps.v.props,t.finalTransform.transform(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11],r[12],r[13],r[14],r[15]);t._mdf=a},processSequences:function(t){var e,r=this.sequenceList.length;for(e=0;e<r;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return"_"+this.transform_key_count++}},CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){this.layerInterface=LayerExpressionInterface(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var t=EffectsExpressionInterface.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(t),0===this.data.ty||this.data.xt?this.compInterface=CompExpressionInterface(this):4===this.data.ty?(this.layerInterface.shapeInterface=ShapeExpressionInterface(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=TextExpressionInterface(this),this.layerInterface.text=this.layerInterface.textInterface)},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,r){this.globalData=e,this.comp=r,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t,e,r,i=null;if(this.data.td){if(3==this.data.td||1==this.data.td){var s=createNS("mask");s.setAttribute("id",this.layerId),s.setAttribute("mask-type",3==this.data.td?"luminance":"alpha"),s.appendChild(this.layerElement),i=s,this.globalData.defs.appendChild(s),featureSupport.maskType||1!=this.data.td||(s.setAttribute("mask-type","luminance"),t=createElementID(),e=filtersFactory.createFilter(t),this.globalData.defs.appendChild(e),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(r=createNS("g")).appendChild(this.layerElement),i=r,s.appendChild(r),r.setAttribute("filter","url("+locationHref+"#"+t+")"))}else if(2==this.data.td){var a=createNS("mask");a.setAttribute("id",this.layerId),a.setAttribute("mask-type","alpha");var n=createNS("g");a.appendChild(n),t=createElementID(),e=filtersFactory.createFilter(t);var o=createNS("feComponentTransfer");o.setAttribute("in","SourceGraphic"),e.appendChild(o);var h=createNS("feFuncA");h.setAttribute("type","table"),h.setAttribute("tableValues","1.0 0.0"),o.appendChild(h),this.globalData.defs.appendChild(e);var p=createNS("rect");p.setAttribute("width",this.comp.data.w),p.setAttribute("height",this.comp.data.h),p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("fill","#ffffff"),p.setAttribute("opacity","0"),n.setAttribute("filter","url("+locationHref+"#"+t+")"),n.appendChild(p),n.appendChild(this.layerElement),i=n,featureSupport.maskType||(a.setAttribute("mask-type","luminance"),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),r=createNS("g"),n.appendChild(p),r.appendChild(this.layerElement),i=r,n.appendChild(r)),this.globalData.defs.appendChild(a)}}else this.data.tt?(this.matteElement.appendChild(this.layerElement),i=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var l=createNS("clipPath"),m=createNS("path");m.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var f=createElementID();if(l.setAttribute("id",f),l.appendChild(m),this.globalData.defs.appendChild(l),this.checkMasks()){var c=createNS("g");c.setAttribute("clip-path","url("+locationHref+"#"+f+")"),c.appendChild(this.layerElement),this.transformedElement=c,i?i.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+f+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._matMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.mat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.mProp.o.v)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this)},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+locationHref+"#"+t+")")}},IShapeElement.prototype={addShapeToModifiers:function(t){var e,r=this.shapeModifiers.length;for(e=0;e<r;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;0<=t;t-=1)this.shapeModifiers[t].processShapes(this._isFirstFrame)}},lcEnum:{1:"butt",2:"round",3:"square"},ljEnum:{1:"miter",2:"round",3:"bevel"},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r<i;){if(e[r].elem===t)return e[r].pos;r+=1}return 0},addProcessedElement:function(t,e){for(var r=this.processedElements,i=r.length;i;)if(r[i-=1].elem===t)return void(r[i].pos=e);r.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}},ITextElement.prototype.initElement=function(t,e,r){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,r),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)},ITextElement.prototype.createPathShape=function(t,e){var r,i,s=e.length,a="";for(r=0;r<s;r+=1)i=e[r].ks.k,a+=buildShapeString(i,i.i.length,!0,t);return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,r,i,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r])/2,0,0)}e.translate(i,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var r,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,r,i,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(r=0;r<a;r+=1){for(i=this.stylesList[r],o=!1,t=n.length=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);1<n.length&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var r,i=new SVGStyleData(t,e),s=i.pElem;if("st"===t.ty)r=new SVGStrokeStyleData(this,t,i);else if("fl"===t.ty)r=new SVGFillStyleData(this,t,i);else if("gf"===t.ty||"gs"===t.ty){r=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,i),this.globalData.defs.appendChild(r.gf),r.maskId&&(this.globalData.defs.appendChild(r.ms),this.globalData.defs.appendChild(r.of),s.setAttribute("mask","url("+locationHref+"#"+r.maskId+")"))}return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",this.lcEnum[t.lc]||"round"),s.setAttribute("stroke-linejoin",this.ljEnum[t.lj]||"round"),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(i),this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var r=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(r,r.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,r){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var s=new SVGShapeData(e,r,ShapePropertyFactory.getShapeProp(this,t,i,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var r=0,i=this.animatedContents.length;r<i;){if(this.animatedContents[r].element===e)return;r+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,r=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||r.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,r,i,s,a,n){var o,h,p,l,m,f,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;0<=o;o-=1){if((f=this.searchProcessedElement(t[o]))?e[o]=r[f-1]:t[o]._render=n,"fl"==t[o].ty||"st"==t[o].ty||"gf"==t[o].ty||"gs"==t[o].ty)f?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"==t[o].ty){if(f)for(p=e[o].it.length,h=0;h<p;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&i.appendChild(e[o].gr)}else"tr"==t[o].ty?(f||(e[o]=this.createTransformElement(t[o],i)),l=e[o].transform,c.push(l)):"sh"==t[o].ty||"rc"==t[o].ty||"el"==t[o].ty||"sr"==t[o].ty?(f||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"==t[o].ty||"rd"==t[o].ty||"ms"==t[o].ty?(f?(m=e[o]).closed=!1:((m=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=m,this.shapeModifiers.push(m)),y.push(m)):"rp"==t[o].ty&&(f?(m=e[o]).closed=!0:(m=ShapeModifiers.getModifier(t[o].ty),(e[o]=m).init(this,t,o,e),this.shapeModifiers.push(m),n=!1),y.push(m));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){this.renderModifiers();var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,r=this.animatedContents.length;for(t=0;t<r;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=this.savedOp;this.savedOp=createTypedArray("float32",t),this.savedOp.set(e);var r=0;for(r=this._length;r<t;r+=1)this.saved[r]=createTypedArray("float32",16);this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.cO=1},CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){this.canvasContext=this.globalData.canvasContext,this.renderableEffectsManager=new CVEffects(this)},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},renderFrame:function(){this.hidden||this.data.hd||(this.renderTransform(),this.renderRenderable(),this.setBlendMode(),this.globalData.renderer.save(),this.globalData.renderer.ctxTransform(this.finalTransform.mat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.mProp.o.v),this.renderInnerContent(),this.globalData.renderer.restore(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,extendPrototype([CanvasRenderer,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,r,i,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t++)if("n"!==this.masksProperties[t].mode){this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),i=this.viewData[t].v,e=s.applyToPointArray(i.v[0][0],i.v[0][1],0),a.moveTo(e[0],e[1]);var o,h=i._length;for(o=1;o<h;o++)r=s.applyToTriplePoints(i.o[o-1],i.i[o],i.v[o]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);r=s.applyToTriplePoints(i.o[o-1],i.i[0],i.v[0]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var r={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},i={};if("fl"==t.ty||"st"==t.ty?(i.c=PropertyFactory.getProp(this,t.c,1,255,this),i.c.k||(r.co="rgb("+bm_floor(i.c.v[0])+","+bm_floor(i.c.v[1])+","+bm_floor(i.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(i.s=PropertyFactory.getProp(this,t.s,1,null,this),i.e=PropertyFactory.getProp(this,t.e,1,null,this),i.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),i.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),i.g=new GradientProperty(this,t.g,this)),i.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"==t.ty||"gs"==t.ty){if(r.lc=this.lcEnum[t.lc]||"round",r.lj=this.ljEnum[t.lj]||"round",1==t.lj&&(r.ml=t.ml),i.w=PropertyFactory.getProp(this,t.w,0,null,this),i.w.k||(r.wi=i.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);i.d=s,i.d.k||(r.da=i.d.dashArray,r.do=i.d.dashoffset[0])}}else r.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(r),i.style=r,i},CVShapeElement.prototype.createGroupElement=function(t){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,r,i,s){var a,n,o,h,p,l,m=t.length-1,f=[],c=[],d=[].concat(s);for(a=m;0<=a;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=r[h-1]:t[a]._shouldRender=i,"fl"==t[a].ty||"st"==t[a].ty||"gf"==t[a].ty||"gs"==t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),f.push(e[a].style);else if("gr"==t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,i,d)}else"tr"==t[a].ty?(h||(l=this.createTransformElement(t[a]),e[a]=l),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"==t[a].ty||"rc"==t[a].ty||"el"==t[a].ty||"sr"==t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"==t[a].ty||"rd"==t[a].ty?(h?(p=e[a]).closed=!1:((p=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=p,this.shapeModifiers.push(p)),c.push(p)):"rp"==t[a].ty&&(h?(p=e[a]).closed=!0:(p=ShapeModifiers.getModifier(t[a].ty),(e[a]=p).init(this,t,a,e),this.shapeModifiers.push(p),i=!1),c.push(p));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(f),m=c.length,a=0;a<m;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,r,i,s,a,n,o,h,p=this.stylesList.length,l=this.globalData.renderer,m=this.globalData.canvasContext;for(t=0;t<p;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(l.save(),a=h.elements,"st"===o||"gs"===o?(m.strokeStyle="st"===o?h.co:h.grd,m.lineWidth=h.wi,m.lineCap=h.lc,m.lineJoin=h.lj,m.miterLimit=h.ml||0):m.fillStyle="fl"===o?h.co:h.grd,l.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&m.beginPath(),l.ctxTransform(h.preTransforms.finalTransform.props),r=a.length,e=0;e<r;e+=1){for("st"!==o&&"gs"!==o||(m.beginPath(),h.da&&(m.setLineDash(h.da),m.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,i=0;i<s;i+=1)"m"==n[i].t?m.moveTo(n[i].p[0],n[i].p[1]):"c"==n[i].t?m.bezierCurveTo(n[i].pts[0],n[i].pts[1],n[i].pts[2],n[i].pts[3],n[i].pts[4],n[i].pts[5]):m.closePath();"st"!==o&&"gs"!==o||(m.stroke(),h.da&&m.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&m.fill(h.r),l.restore()}},CVShapeElement.prototype.renderShape=function(t,e,r,i){var s,a;for(a=t,s=e.length-1;0<=s;s-=1)"tr"==e[s].ty?(a=r[s].transform,this.renderShapeTransform(t,a)):"sh"==e[s].ty||"el"==e[s].ty||"rc"==e[s].ty||"sr"==e[s].ty?this.renderPath(e[s],r[s]):"fl"==e[s].ty?this.renderFill(e[s],r[s],a):"st"==e[s].ty?this.renderStroke(e[s],r[s],a):"gf"==e[s].ty||"gs"==e[s].ty?this.renderGradientFill(e[s],r[s],a):"gr"==e[s].ty?this.renderShape(a,e[s].it,r[s].it):e[s].ty;i&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var r,i,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var p=n.shapes[s];if(p&&p.v){for(i=p._length,r=1;r<i;r+=1)1===r&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[r],p.v[r])});1===i&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),p.c&&i&&(a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[0],p.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var r,i=e.styledShapes.length;for(r=0;r<i;r+=1)this.renderStyledShape(e.styledShapes[r],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,r){var i=e.style;(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,r){var i=e.style;if(!i.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var s=this.globalData.canvasContext,a=e.s.v,n=e.e.v;if(1===t.t)f=s.createLinearGradient(a[0],a[1],n[0],n[1]);else var o=Math.sqrt(Math.pow(a[0]-n[0],2)+Math.pow(a[1]-n[1],2)),h=Math.atan2(n[1]-a[1],n[0]-a[0]),p=o*(1<=e.h.v?.99:e.h.v<=-1?-.99:e.h.v),l=Math.cos(h+e.a.v)*p+a[0],m=Math.sin(h+e.a.v)*p+a[1],f=s.createRadialGradient(l,m,0,a[0],a[1],o);var c,d=t.g.p,u=e.g.c,y=1;for(c=0;c<d;c+=1)e.g._hasOpacity&&e.g._collapsable&&(y=e.g.o[2*c+1]),f.addColorStop(u[4*c]/100,"rgba("+u[4*c+1]+","+u[4*c+2]+","+u[4*c+3]+","+y+")");i.grd=f}i.coOp=e.o.v*r.opacity},CVShapeElement.prototype.renderStroke=function(t,e,r){var i=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(i.da=s.dashArray,i.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity),(e.w._mdf||this._isFirstFrame)&&(i.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){var t=this.canvasContext;t.fillStyle=this.data.sc,t.fillRect(0,0,this.data.sw,this.data.sh)},CVEffects.prototype.renderFrame=function(){};var animationManager=(tJ={},uJ=[],vJ=0,wJ=0,xJ=0,yJ=!0,zJ=!1,tJ.registerAnimation=BJ,tJ.loadAnimation=function(t){var e=new AnimationItem;return FJ(e,null),e.setParams(t),e},tJ.setSpeed=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setSpeed(t,e)},tJ.setDirection=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setDirection(t,e)},tJ.play=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.play(t)},tJ.pause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.pause(t)},tJ.stop=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.stop(t)},tJ.togglePause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.togglePause(t)},tJ.searchAnimations=function(t,e,r){var i,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(i=0;i<a;i+=1)r&&s[i].setAttribute("data-bm-type",r),BJ(s[i],t);if(e&&0===a){r||(r="svg");var n=document.getElementsByTagName("body")[0];n.innerHTML="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",r),n.appendChild(o),BJ(o,t)}},tJ.resize=function(){var t;for(t=0;t<wJ;t+=1)uJ[t].animation.resize()},tJ.goToAndStop=function(t,e,r){var i;for(i=0;i<wJ;i+=1)uJ[i].animation.goToAndStop(t,e,r)},tJ.destroy=function(t){var e;for(e=wJ-1;0<=e;e-=1)uJ[e].animation.destroy(t)},tJ.freeze=function(){zJ=!0},tJ.unfreeze=function(){zJ=!1,TJ()},tJ.getRegisteredAnimations=function(){var t,e=uJ.length,r=[];for(t=0;t<e;t+=1)r.push(uJ[t].animation);return r},tJ),tJ,uJ,vJ,wJ,xJ,yJ,zJ,PK,QK,RK,SK,TK,UK,VK;function AJ(t){for(var e=0,r=t.target;e<wJ;)uJ[e].animation===r&&(uJ.splice(e,1),e-=1,wJ-=1,r.isPaused||EJ()),e+=1}function BJ(t,e){if(!t)return null;for(var r=0;r<wJ;){if(uJ[r].elem==t&&null!==uJ[r].elem)return uJ[r].animation;r+=1}var i=new AnimationItem;return FJ(i,t),i.setData(t,e),i}function DJ(){xJ+=1,TJ()}function EJ(){xJ-=1}function FJ(t,e){t.addEventListener("destroy",AJ),t.addEventListener("_active",DJ),t.addEventListener("_idle",EJ),uJ.push({elem:e,animation:t}),wJ+=1}function KJ(t){var e,r=t-vJ;for(e=0;e<wJ;e+=1)uJ[e].animation.advanceTime(r);vJ=t,xJ&&!zJ?window.requestAnimationFrame(KJ):yJ=!0}function LJ(t){vJ=t,window.requestAnimationFrame(KJ)}function TJ(){!zJ&&xJ&&yJ&&(window.requestAnimationFrame(LJ),yJ=!1)}function WK(t){for(var e=0,r=t.target;e<SK;)QK[e].animation===r&&(QK.splice(e,1),e-=1,SK-=1,r.isPaused||$K()),e+=1}function ZK(){TK+=1,nL()}function $K(){TK-=1}function _K(t,e){t.addEventListener("destroy",WK),t.addEventListener("_active",ZK),t.addEventListener("_idle",$K),QK.push({elem:e,animation:t}),SK+=1}function eL(t){var e,r=t-RK;for(e=0;e<SK;e+=1)QK[e].animation.advanceTime(r);RK=t,TK&&!VK?requestAnimationFrame(eL):UK=!0}function fL(t){RK=t,requestAnimationFrame(eL)}function nL(){!VK&&TK&&UK&&(requestAnimationFrame(fL),UK=!1)}PK={},QK=[],RK=0,SK=0,TK=0,UK=!0,VK=!1,PK.registerAnimation=function(t,e){if(!t)return null;for(var r=0;r<SK;){if(QK[r].elem==t&&null!==QK[r].elem)return QK[r].animation;r+=1}var i=new AnimationItem;return _K(i,t),i.setData(t,e),i},PK.loadAnimation=function(t){var e=new AnimationItem;return _K(e,null),e.setParams(t),e},PK.setSpeed=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setSpeed(t,e)},PK.setDirection=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setDirection(t,e)},PK.play=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.play(t)},PK.pause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.pause(t)},PK.stop=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.stop(t)},PK.togglePause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.togglePause(t)},PK.searchAnimations=function(t,e,r){throw new Error("Cannot access DOM from worker thread")},PK.resize=function(){var t;for(t=0;t<SK;t+=1)QK[t].animation.resize()},PK.goToAndStop=function(t,e,r){var i;for(i=0;i<SK;i+=1)QK[i].animation.goToAndStop(t,e,r)},PK.destroy=function(t){var e;for(e=SK-1;0<=e;e-=1)QK[e].animation.destroy(t)},PK.freeze=function(){VK=!0},PK.unfreeze=function(){VK=!1,nL()},PK.getRegisteredAnimations=function(){var t,e=QK.length,r=[];for(t=0;t<e;t+=1)r.push(QK[t].animation);return r},animationManager=PK;var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.subframeEnabled=subframeEnabled,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context),(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;case"svg":this.renderer=new SVGRenderer(this,t.rendererSettings);break;default:this.renderer=new HybridRenderer(this,t.rendererSettings)}this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,t.animationData?this.configAnimation(t.animationData):t.path&&("json"!=t.path.substr(-4)&&("/"!=t.path.substr(-1,1)&&(t.path+="/"),t.path+="data.json"),-1!=t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),assetLoader.load(t.path,this.configAnimation.bind(this),function(){this.trigger("data_failed")}.bind(this)))},AnimationItem.prototype.setData=function(t,e){var r={wrapper:t,animationData:e?"object"==typeof e?e:JSON.parse(e):null},i=t.attributes;r.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",r.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:"canvas";var s=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";""===s||(r.loop="false"!==s&&("true"===s||parseInt(s)));var a=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;r.autoplay="false"!==a,r.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(r.prerender=!1),this.setParams(r)},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var r=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,assetLoader.load(r,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded())},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.loaded()?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){this.isLoaded||!this.renderer.globalData.fontManager.loaded()||!this.imagePreloader.loaded()&&"canvas"===this.renderer.rendererType||(this.isLoaded=!0,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play())},AnimationItem.prototype.resize=function(){this.renderer.updateContainerSize()},AnimationItem.prototype.setSubframe=function(t){this.subframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.subframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame()},AnimationItem.prototype.renderFrame=function(){!1!==this.isLoaded&&this.renderer.renderFrame(this.currentFrame+this.firstFrame)},AnimationItem.prototype.play=function(t){t&&this.name!=t||!0===this.isPaused&&(this.isPaused=!1,this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!=t||!1===this.isPaused&&(this.isPaused=!0,this._idle=!0,this.trigger("_idle"))},AnimationItem.prototype.togglePause=function(t){t&&this.name!=t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!=t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.goToAndStop=function(t,e,r){r&&this.name!=r||(e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier),this.pause())},AnimationItem.prototype.goToAndPlay=function(t,e,r){this.goToAndStop(t,e,r),this.play()},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,r=!1;e>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.timeCompleted=this.totalFrames=t[0]-t[1],this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.timeCompleted=this.totalFrames=t[1]-t[0],this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?r=t:this.currentRawFrame+this.firstFrame>e&&(r=e-t)),this.firstFrame=t,this.timeCompleted=this.totalFrames=e-t,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"==typeof t[0]){var r,i=t.length;for(r=0;r<i;r+=1)this.segments.push(t[r])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var r=t.p;-1!==r.indexOf("images/")&&(r=r.split("/")[1]),e=this.assetsPath+r}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,r=this.assets.length;e<r;){if(t==this.assets[e].id)return this.assets[e];e+=1}},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;default:throw new Error("Only canvas renderer is supported when using worker.")}if(this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=null,t.animationData)this.configAnimation(t.animationData);else if(t.path)throw new Error("Canvas worker renderer cannot load animation from url")},AnimationItem.prototype.setData=function(t,e){throw new Error("Cannot set data on wrapper for canvas worker renderer")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(t&&0!==t.length&&this.autoloadSegments)throw new Error("Cannot load multiple segments in worker.");this.timeCompleted=this.totalFrames},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=null,AnimationItem.prototype.preloadImages=null,AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.loadSegments(),this.updaFrameModifier(),this.checkLoaded())},AnimationItem.prototype.waitForFontsLoaded=null,AnimationItem.prototype.checkLoaded=function(){this.isLoaded||(this.isLoaded=!0,dataManager.completeData(this.animationData,null),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),this.gotoFrame())},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.getPath=null;var Expressions=(xN={},xN.initExpressions=function(t){var e=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},xN),xN;expressionsPlugin=Expressions;var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null;function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||"boolean"===t||"string"===t||e instanceof Number}function $bm_neg(t){var e=typeof t;if("number"==e||"boolean"==e||t instanceof Number)return-t;if($bm_isInstanceOfArray(t)){var r,i=t.length,s=[];for(r=0;r<i;r+=1)s[r]=-t[r];return s}return t.propType?t.v:void 0}var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var r=typeof t,i=typeof e;if("string"==r||"string"==i)return t+e;if(isNumerable(r,t)&&isNumerable(i,e))return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]+e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var r=typeof t,i=typeof e;if(isNumerable(r,t)&&isNumerable(i,e))return"string"==r&&(t=parseInt(t)),"string"==i&&(e=parseInt(e)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]-e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]*e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t*e[i];return r}return 0}function div(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]/e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t/e[i];return r}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t)),"string"==typeof e&&(e=parseInt(e)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,r){if(r<e){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);e||(e=helperLengthArray);var r,i=Math.min(t.length,e.length),s=0;for(r=0;r<i;r+=1)s+=Math.pow(e[r]-t[r],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,r,i=t[0],s=t[1],a=t[2],n=Math.max(i,s,a),o=Math.min(i,s,a),h=(n+o)/2;if(n==o)e=r=0;else{var p=n-o;switch(r=.5<h?p/(2-n-o):p/(n+o),n){case i:e=(s-a)/p+(s<a?6:0);break;case s:e=(a-i)/p+2;break;case a:e=(i-s)/p+4}e/=6}return[e,r,h,t[3]]}function hue2rgb(t,e,r){return r<0&&(r+=1),1<r&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=r=i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r<e){var a=r;r=e,e=a}if(t<=e)return i;if(r<=t)return s;var n=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*n;var o,h=i.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=i[o]+(s[o]-i[o])*n;return p}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var r,i=e.length;t||(t=createTypedArray("float32",i));var s=createTypedArray("float32",i),a=BMMath.random();for(r=0;r<i;r+=1)s[r]=t[r]+a*(e[r]-t[r]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,r,i){var s,a=t.length,n=shape_pool.newElement();n.setPathData(!!i,a);var o,h,p=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:p,h=r&&r[s]?r[s]:p,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,__expression_functions=[],scoped_bm_rt;if(data.xf){var i,len=data.xf.length;for(i=0;i<len;i+=1)__expression_functions[i]=eval("(function(){ return "+data.xf[i]+"}())")}var expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var r,i,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=r=0;r<n;){for(i=0;i<s;i+=1)a[i]+=-e+2*e*BMMath.random();r+=1}var o=5*time,h=o-Math.floor(o),p=createTypedArray("float32",s);if(1<s){for(i=0;i<s;i+=1)p[i]=this.pv[i]+a[i]+(-e+2*e*BMMath.random())*h;return p}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],i=Math.atan2(r[0],Math.sqrt(r[1]*r[1]+r[2]*r[2]))/degToRads;return[-Math.atan2(r[1],r[2])/degToRads,i,0]}function easeOut(t,e,r,i,s){return applyEase(easeOutBez,t,e,r,i,s)}function easeIn(t,e,r,i,s){return applyEase(easeInBez,t,e,r,i,s)}function ease(t,e,r,i,s){return applyEase(easeInOutBez,t,e,r,i,s)}function applyEase(t,e,r,i,s,a){void 0===s?(s=r,a=i):e=(e-r)/(i-r);var n=t(e=1<e?1:e<0?0:e);if($bm_isInstanceOfArray(s)){var o,h=s.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=(a[o]-s[o])*n+s[o];return p}return(a-s)*n+s}function nearestKey(t){var e,r,i,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(r=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)r=1,i=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){r=e+1,i=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){i=t-data.k[e].t>data.k[e+1].t-t?(r=e+2,data.k[e+1].t):(r=e+1,data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else i=r=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i,s;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);for(t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]},i=(s=t!==data.k.length-1||data.k[t].h?data.k[t].s:data.k[t].s||0===data.k[t].s?data.k[t-1].s:data.k[t].e).length,r=0;r<i;r+=1)e[r]=s[r],e.value[r]=s[r];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,_needsRandom&&seedRandom(randSeed),this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),($bm_transform=transform)&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,"shape"===scoped_bm_rt.propType&&(scoped_bm_rt=scoped_bm_rt.v),scoped_bm_rt)}return executeExpression}return ob.initiateExpression=initiateExpression,ob}(),expressionHelpers={searchExpressions:function(t,e,r){e.x&&(r.k=!0,r.x=!0,r.initiateExpression=ExpressionManager.initiateExpression,r.effectsSequence.push(r.initiateExpression(t,e,r).bind(r)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),r=this.getValueAtTime(t+-.01),i=0;if(e.length){var s;for(s=0;s<e.length;s+=1)i+=Math.pow(r[s]-e[s],2);i=100*Math.sqrt(i)}else i=0;return i},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,r,i=this.getValueAtTime(t),s=this.getValueAtTime(t+-.001);if(i.length)for(e=createTypedArray("float32",i.length),r=0;r<i.length;r+=1)e[r]=(s[r]-i[r])/-.001;else e=(s-i)/-.001;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};!function(){function o(t,e,r){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[p.length-1].t;if(h<=l)return this.pv;if(r?s=l-(i=e?Math.abs(l-elem.comp.globalData.frameRate*e):Math.max(0,l-this.elem.data.ip)):((!e||e>p.length-1)&&(e=p.length-1),i=l-(s=p[p.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),f=this.getValueAtTime(l/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=(f[a]-m[a])*d+c[a];return o}return(f-m)*d+c}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-l)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-l)/.001*(u-y)}}return this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0)}function h(t,e,r){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[0].t;if(l<=h)return this.pv;if(r?s=l+(i=e?Math.abs(elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-l)):((!e||e>p.length-1)&&(e=p.length-1),i=(s=p[e].t)-l),"pingpong"===t){if(Math.floor((l-h)/i)%2==0)return this.getValueAtTime(((l-h)%i+l)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(l/this.comp.globalData.frameRate,0),f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0),d=Math.floor((l-h)/i)+1;if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(f[a]-m[a])*d;return o}return c-(f-m)*d}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(l-h)/.001;return o}return u+(u-y)*(l-h)/.001}}return this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0)}function p(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var r,i,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=1<e?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(i=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]+=i[h];else r+=i;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]/=e;else r/=e;return r}var s=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,r){var i=s(t,e,r);return i.dynamicProperties.length?i.getValueAtTime=function(t){console.warn("Transform at time not supported")}.bind(i):i.getValueAtTime=function(t){}.bind(i),i.setGroupProperty=expressionHelpers.setGroupProperty,i};var l=PropertyFactory.getProp;PropertyFactory.getProp=function(t,e,r,i,s){var a=l(t,e,r,i,s);a.kf?a.getValueAtTime=expressionHelpers.getValueAtTime.bind(a):a.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(a),a.setGroupProperty=expressionHelpers.setGroupProperty,a.loopOut=o,a.loopIn=h,a.smooth=p,a.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(a),a.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(a),a.numKeys=1===e.a?e.k.length:0,a.propertyIndex=e.ix;var n=0;return 0!==r&&(n=createTypedArray("float32",1===e.a?e.k[0].s.length:e.k.length)),a._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:n},expressionHelpers.searchExpressions(t,e,a),a.k&&s.addDynamicProperty(a),a};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function r(){}r.prototype={vertices:function(t,e){this.k&&this.getValue();var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var i,s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(r));for(var i,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,p=0;o<h;){if(p+a[o].addedLength>n){var l=o,m=r.c&&o===h-1?0:o+1,f=(n-p)/a[o].addedLength;i=bez.getPointInSegment(r.v[l],r.v[m],r.o[l],r.i[m],f,a[o]);break}p+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){t=1==t?this.v.c?0:.999:t;var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([r],t),extendPrototype([r],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shape_pool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var n=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,r,i,s){var a=n(t,e,r,i,s);return a.propertyIndex=e.ix,a.lock=!1,3===r?expressionHelpers.searchExpressions(t,e.pt,a):4===r&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}(),TextProperty.prototype.getExpressionValue=function(t,e){var r=this.calculateExpression(e);if(t.t===r)return t;var i={};return this.copyData(i,t),i.t=r.toString(),i.__complete=!1,i},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){if(this.data.d.x)return this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0};var ShapeExpressionInterface=function(t,e,r){var i;function s(t){if("number"==typeof t)return i[t-1];for(var e=0,r=i.length;e<r;){if(i[e]._name===t)return i[e];e+=1}}return s.propertyGroup=r,i=DT(t,e,s),s.numProperties=i.length,s};function DT(t,e,r){var i,s=[],a=t?t.length:0;for(i=0;i<a;i+=1)"gr"==t[i].ty?s.push(FT(t[i],e[i],r)):"fl"==t[i].ty?s.push(GT(t[i],e[i],r)):"st"==t[i].ty?s.push(HT(t[i],e[i],r)):"tm"==t[i].ty?s.push(IT(t[i],e[i],r)):"tr"==t[i].ty||("el"==t[i].ty?s.push(KT(t[i],e[i],r)):"sr"==t[i].ty?s.push(LT(t[i],e[i],r)):"sh"==t[i].ty?s.push(PT(t[i],e[i],r)):"rc"==t[i].ty?s.push(MT(t[i],e[i],r)):"rd"==t[i].ty?s.push(NT(t[i],e[i],r)):"rp"==t[i].ty&&s.push(OT(t[i],e[i],r)));return s}function FT(t,e,r){var i=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return i.content;default:return i.transform}};i.propertyGroup=function(t){return 1===t?i:r(t-1)};var s=function(t,e,r){function i(t){for(var e=0,r=s.length;e<r;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}if("number"==typeof t)return s[t-1]}var s;return i.propertyGroup=function(t){return 1===t?i:r(t-1)},s=DT(t.it,e.it,i.propertyGroup),i.numProperties=s.length,i.propertyIndex=t.cix,i._name=t.nm,i}(t,e,i.propertyGroup),a=function(e,t,r){function i(t){return 1==t?s:r(--t)}t.transform.mProps.o.setGroupProperty(i),t.transform.mProps.p.setGroupProperty(i),t.transform.mProps.a.setGroupProperty(i),t.transform.mProps.s.setGroupProperty(i),t.transform.mProps.r.setGroupProperty(i),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(i),t.transform.mProps.sa.setGroupProperty(i));function s(t){return e.a.ix===t||"Anchor Point"===t?s.anchorPoint:e.o.ix===t||"Opacity"===t?s.opacity:e.p.ix===t||"Position"===t?s.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?s.rotation:e.s.ix===t||"Scale"===t?s.scale:e.sk&&e.sk.ix===t||"Skew"===t?s.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?s.skewAxis:void 0}return t.transform.op.setGroupProperty(i),Object.defineProperties(s,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),s.ty="tr",s.mn=e.mn,s.propertyGroup=r,s}(t.it[t.it.length-1],e.it[e.it.length-1],i.propertyGroup);return i.content=s,i.transform=a,Object.defineProperty(i,"_name",{get:function(){return t.nm}}),i.numProperties=t.np,i.propertyIndex=t.ix,i.nm=t.nm,i.mn=t.mn,i}function GT(t,e,r){function i(t){return"Color"===t||"color"===t?i.color:"Opacity"===t||"opacity"===t?i.opacity:void 0}return Object.defineProperties(i,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(r),e.o.setGroupProperty(r),i}function HT(t,e,r){function i(t){return 1===t?ob:r(t-1)}function s(t){return 1===t?h:i(t-1)}var a,n,o=t.d?t.d.length:0,h={};for(a=0;a<o;a+=1)n=a,Object.defineProperty(h,t.d[n].nm,{get:ExpressionPropertyInterface(e.d.dataProps[n].p)}),e.d.dataProps[a].p.setGroupProperty(s);function p(t){return"Color"===t||"color"===t?p.color:"Opacity"===t||"opacity"===t?p.opacity:"Stroke Width"===t||"stroke width"===t?p.strokeWidth:void 0}return Object.defineProperties(p,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(i),e.o.setGroupProperty(i),e.w.setGroupProperty(i),p}function IT(e,t,r){function i(t){return 1==t?s:r(--t)}function s(t){return t===e.e.ix||"End"===t||"end"===t?s.end:t===e.s.ix?s.start:t===e.o.ix?s.offset:void 0}return s.propertyIndex=e.ix,t.s.setGroupProperty(i),t.e.setGroupProperty(i),t.o.setGroupProperty(i),s.propertyIndex=e.ix,s.propertyGroup=r,Object.defineProperties(s,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),s.mn=e.mn,s}function KT(e,t,r){function i(t){return 1==t?a:r(--t)}a.propertyIndex=e.ix;var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.s.ix===t?a.size:void 0}return s.s.setGroupProperty(i),s.p.setGroupProperty(i),Object.defineProperties(a,{size:{get:ExpressionPropertyInterface(s.s)},position:{get:ExpressionPropertyInterface(s.p)},_name:{value:e.nm}}),a.mn=e.mn,a}function LT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.rotation:e.pt.ix===t?a.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?a.outerRadius:e.os.ix===t?a.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?a.innerRoundness:void 0:a.innerRadius}return a.propertyIndex=e.ix,s.or.setGroupProperty(i),s.os.setGroupProperty(i),s.pt.setGroupProperty(i),s.p.setGroupProperty(i),s.r.setGroupProperty(i),e.ir&&(s.ir.setGroupProperty(i),s.is.setGroupProperty(i)),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},rotation:{get:ExpressionPropertyInterface(s.r)},points:{get:ExpressionPropertyInterface(s.pt)},outerRadius:{get:ExpressionPropertyInterface(s.or)},outerRoundness:{get:ExpressionPropertyInterface(s.os)},innerRadius:{get:ExpressionPropertyInterface(s.ir)},innerRoundness:{get:ExpressionPropertyInterface(s.is)},_name:{value:e.nm}}),a.mn=e.mn,a}function MT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?a.size:void 0}return a.propertyIndex=e.ix,s.p.setGroupProperty(i),s.s.setGroupProperty(i),s.r.setGroupProperty(i),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},roundness:{get:ExpressionPropertyInterface(s.r)},size:{get:ExpressionPropertyInterface(s.s)},_name:{value:e.nm}}),a.mn=e.mn,a}function NT(e,t,r){var i=t;function s(t){if(e.r.ix===t||"Round Corners 1"===t)return s.radius}return s.propertyIndex=e.ix,i.rd.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{radius:{get:ExpressionPropertyInterface(i.rd)},_name:{value:e.nm}}),s.mn=e.mn,s}function OT(e,t,r){function i(t){return 1==t?a:r(--t)}var s=t;function a(t){return e.c.ix===t||"Copies"===t?a.copies:e.o.ix===t||"Offset"===t?a.offset:void 0}return a.propertyIndex=e.ix,s.c.setGroupProperty(i),s.o.setGroupProperty(i),Object.defineProperties(a,{copies:{get:ExpressionPropertyInterface(s.c)},offset:{get:ExpressionPropertyInterface(s.o)},_name:{value:e.nm}}),a.mn=e.mn,a}function PT(t,e,r){var i=e.sh;function s(t){if("Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t)return s.path}return i.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{path:{get:function(){return i.k&&i.getValue(),i}},shape:{get:function(){return i.k&&i.getValue(),i}},_name:{value:t.nm},ix:{value:t.ix},mn:{value:t.mn}}),s}var TextExpressionInterface=function(e){var r;function t(){}return Object.defineProperty(t,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return void 0!==t&&(e.textProperty.currentData.t=void 0,(r=new String(t)).value=t||new String(t)),r}}),t},LayerExpressionInterface=function(e){var r;function i(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return i.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return r;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return i.effect}}i.toWorld=_V,i.fromWorld=aW,i.toComp=_V,i.fromComp=bW,i.sampleImage=cW,i.sourceRectAtTime=e.sourceRectAtTime.bind(e);var t=getDescriptor(r=TransformExpressionInterface((i._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(i,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(r,"rotation"),scale:getDescriptor(r,"scale"),position:getDescriptor(r,"position"),opacity:getDescriptor(r,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return r}},active:{get:function(){return e.isInRange}}}),i.startTime=e.data.st,i.index=e.data.ind,i.source=e.data.refId,i.height=0===e.data.ty?e.data.h:100,i.width=0===e.data.ty?e.data.w:100,i.inPoint=e.data.ip/e.comp.globalData.frameRate,i.outPoint=e.data.op/e.comp.globalData.frameRate,i._name=e.data.nm,i.registerMaskInterface=function(t){i.mask=new MaskManagerInterface(t,e)},i.registerEffectsInterface=function(t){i.effect=t},i};function _V(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.applyToPointArray(t[0],t[1],t[2]||0)}return r.applyToPointArray(t[0],t[1],t[2]||0)}function aW(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.inversePoint(t)}return r.inversePoint(t)}function bW(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function cW(){return[1,1,1,1]}var CompExpressionInterface=function(i){function t(t){for(var e=0,r=i.layers.length;e<r;){if(i.layers[e].nm===t||i.layers[e].ind===t)return i.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:i.data.nm}),(t.layer=t).pixelAspect=1,t.height=i.data.h||i.globalData.compSize.h,t.width=i.data.w||i.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/i.globalData.frameRate,t.displayStartTime=0,t.numLayers=i.layers.length,t},TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity}}if(Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p)var r=ExpressionPropertyInterface(t.p);return Object.defineProperty(e,"position",{get:function(){return t.p?r():[t.px.v,t.py.v,t.pz?t.pz.v:0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},ProjectInterface=function(){function t(t){for(var e=0,r=this.compositions.length;e<r;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}}return t.compositions=[],t.currentFrame=0,t.registerComposition=LW,t};function LW(t){this.compositions.push(t)}var EffectsExpressionInterface={createEffectsInterface:function(s,t){if(s.effectsManager){var e,a=[],r=s.data.ef,i=s.effectsManager.effectElements.length;for(e=0;e<i;e+=1)a.push(TW(r[e],s.effectsManager.effectElements[e],t,s));return function(t){for(var e=s.data.ef||[],r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return a[r];r+=1}}}}};function TW(s,t,e,r){var i,a=[],n=s.ef.length;for(i=0;i<n;i+=1)5===s.ef[i].ty?a.push(TW(s.ef[i],t.effectElements[i],t.effectElements[i].propertyGroup,r)):a.push(UW(t.effectElements[i],s.ef[i].ty,r,o));function o(t){return 1===t?h:e(t-1)}var h=function(t){for(var e=s.ef,r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?a[r]:a[r]();r+=1}return a[0]()};return h.propertyGroup=o,"ADBE Color Control"===s.mn&&Object.defineProperty(h,"color",{get:function(){return a[0]()}}),Object.defineProperty(h,"numProperties",{get:function(){return s.np}}),h.active=h.enabled=0!==s.en,h}function UW(t,e,r,i){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(i),function(){return 10===e?r.comp.compInterface(t.p.v):s()}}var MaskManagerInterface=function(){function a(t,e){this._mask=t,this._data=e}Object.defineProperty(a.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}});return function(e,t){var r,i=createSizedArray(e.viewData.length),s=e.viewData.length;for(r=0;r<s;r+=1)i[r]=new a(e.viewData[r],e.masksProperties[r]);return function(t){for(r=0;r<s;){if(e.masksProperties[r].nm===t)return i[r];r+=1}}}}(),ExpressionPropertyInterface=(KX={pv:0,v:0,mult:1},LX={pv:[0,0,0],v:[0,0,0],mult:1},function(t){return t?"unidimensional"===t.propType?function(t){t&&"pv"in t||(t=KX);var e=1/t.mult,r=t.pv*e,i=new Number(r);return i.value=r,MX(i,t,"unidimensional"),function(){return t.k&&t.getValue(),r=t.v*e,i.value!==r&&((i=new Number(r)).value=r,MX(i,t,"unidimensional")),i}}(t):function(e){e&&"pv"in e||(e=LX);var r=1/e.mult,i=e.pv.length,s=createTypedArray("float32",i),a=createTypedArray("float32",i);return s.value=a,MX(s,e,"multidimensional"),function(){e.k&&e.getValue();for(var t=0;t<i;t+=1)s[t]=a[t]=e.v[t]*r;return s}}(t):PX}),KX,LX,fY,gY;function MX(i,s,a){Object.defineProperty(i,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),i.numKeys=s.keyframes?s.keyframes.length:0,i.key=function(t){if(i.numKeys){var e="";e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s;var r="unidimensional"===a?new Number(e):Object.assign({},e);return r.time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,r}return 0},i.valueAtTime=s.getValueAtTime,i.speedAtTime=s.getSpeedAtTime,i.velocityAtTime=s.getVelocityAtTime,i.propertyGroup=s.propertyGroup}function PX(){return KX}function hY(t,e){return this.textIndex=t+1,this.textTotal=e,this.v=this.getValue()*this.mult,this.v}function SliderEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function AngleEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function ColorEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function PointEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function LayerIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function MaskIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function CheckboxEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var r=t.ef||[];this.effectElements=[];var i,s,a=r.length;for(i=0;i<a;i++)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}fY=function(t,e){this.pv=1,this.comp=t.comp,this.elem=t,this.mult=.01,this.propType="textSelector",this.textTotal=e.totalChars,this.selectorValue=100,this.lastValue=[1,1,1],this.k=!0,this.x=!0,this.getValue=ExpressionManager.initiateExpression.bind(this)(t,e,this),this.getMult=hY,this.getVelocityAtTime=expressionHelpers.getVelocityAtTime,this.kf?this.getValueAtTime=expressionHelpers.getValueAtTime.bind(this):this.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(this),this.setGroupProperty=expressionHelpers.setGroupProperty},gY=TextSelectorProp.getTextSelectorProp,TextSelectorProp.getTextSelectorProp=function(t,e,r){return 1===e.t?new fY(t,e,r):gY(t,e,r)},extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,i,s=this.data.ef.length,a=this.data.ef;for(r=0;r<s;r+=1){switch(i=null,a[r].ty){case 0:i=new SliderEffect(a[r],e,this);break;case 1:i=new AngleEffect(a[r],e,this);break;case 2:i=new ColorEffect(a[r],e,this);break;case 3:i=new PointEffect(a[r],e,this);break;case 4:case 7:i=new CheckboxEffect(a[r],e,this);break;case 10:i=new LayerIndexEffect(a[r],e,this);break;case 11:i=new MaskIndexEffect(a[r],e,this);break;case 5:i=new EffectsManager(a[r],e,this);break;default:i=new NoValueEffect(a[r],e,this)}i&&this.effectElements.push(i)}};var lottiejs={},_isFrozen=!1;function loadAnimation(t){return animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":defaultCurveSegments=200;break;case"medium":defaultCurveSegments=50;break;case"low":defaultCurveSegments=10}else!isNaN(t)&&1<t&&(defaultCurveSegments=t);roundValues(!(50<=defaultCurveSegments))}lottiejs.play=animationManager.play,lottiejs.pause=animationManager.pause,lottiejs.togglePause=animationManager.togglePause,lottiejs.setSpeed=animationManager.setSpeed,lottiejs.setDirection=animationManager.setDirection,lottiejs.stop=animationManager.stop,lottiejs.registerAnimation=animationManager.registerAnimation,lottiejs.loadAnimation=loadAnimation,lottiejs.resize=animationManager.resize,lottiejs.goToAndStop=animationManager.goToAndStop,lottiejs.destroy=animationManager.destroy,lottiejs.setQuality=setQuality,lottiejs.freeze=animationManager.freeze,lottiejs.unfreeze=animationManager.unfreeze,lottiejs.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottiejs.version="5.5.2";var renderer="";return lottiejs}({}),animations=[];onmessage=function(t){if(t&&t.data&&t.data.params&&t.data.canvas){var e=t.data.canvas,r=t.data.params,i=e.getContext("2d"),s=lottiejs.loadAnimation({renderer:"canvas",loop:r.loop,autoplay:r.autoplay,animationData:t.data.animationData,rendererSettings:{context:i,scaleMode:"noScale",clearCanvas:!0}});animations.push(s),s.play()}};
diff --git a/third_party/webxr_test_pages/webxr-samples/js/xrray-module.js b/third_party/webxr_test_pages/webxr-samples/js/xrray-module.js index 218967e..71f30efdc 100644 --- a/third_party/webxr_test_pages/webxr-samples/js/xrray-module.js +++ b/third_party/webxr_test_pages/webxr-samples/js/xrray-module.js
@@ -21,12 +21,12 @@ // |matrix| - Float32Array representing 4x4 matrix (column major) // |point| - DOMPointReadOnly const transformByMatrix = function(matrix, point){ - return new DOMPointReadOnly({ - x : matrix[0] * point.x + matrix[4] * point.y + matrix[8] * point.z + matrix[12] * point.w, - y : matrix[1] * point.x + matrix[5] * point.y + matrix[9] * point.z + matrix[13] * point.w, - z : matrix[2] * point.x + matrix[6] * point.y + matrix[10] * point.z + matrix[14] * point.w, - w : matrix[3] * point.x + matrix[7] * point.y + matrix[11] * point.z + matrix[15] * point.w, - }); + return new DOMPointReadOnly( + matrix[0] * point.x + matrix[4] * point.y + matrix[8] * point.z + matrix[12] * point.w, + matrix[1] * point.x + matrix[5] * point.y + matrix[9] * point.z + matrix[13] * point.w, + matrix[2] * point.x + matrix[6] * point.y + matrix[10] * point.z + matrix[14] * point.w, + matrix[3] * point.x + matrix[7] * point.y + matrix[11] * point.z + matrix[15] * point.w, + ); }; // |lhs|, |rhs| - Float32Arrays representing 4x4 matrices (column major)
diff --git a/tools/android/BUILD.gn b/tools/android/BUILD.gn index ab51dc0..83b67f7a 100644 --- a/tools/android/BUILD.gn +++ b/tools/android/BUILD.gn
@@ -26,6 +26,12 @@ } } +group("fincore") { + deps = [ + "//tools/android/fincore", + ] +} + group("memdump") { deps = [ "//tools/android/memdump",
diff --git a/tools/android/asan/third_party/with_asan.py b/tools/android/asan/third_party/with_asan.py index 767a134c..cd73fe89 100755 --- a/tools/android/asan/third_party/with_asan.py +++ b/tools/android/asan/third_party/with_asan.py
@@ -36,8 +36,12 @@ disable_verity = device.build_version_sdk >= version_codes.MARSHMALLOW try: if disable_verity: + device.EnableRoot() device.adb.DisableVerity() device.Reboot() + # Call EnableRoot prior to asan_device_setup.sh to ensure it doesn't + # get tripped up by the root timeout. + device.EnableRoot() setup_cmd = [_SCRIPT_PATH, '--lib', args.lib] if args.device: setup_cmd += ['--device', args.device]
diff --git a/tools/android/fincore/BUILD.gn b/tools/android/fincore/BUILD.gn new file mode 100644 index 0000000..b6f3d37 --- /dev/null +++ b/tools/android/fincore/BUILD.gn
@@ -0,0 +1,9 @@ +# 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. + +executable("fincore") { + sources = [ + "fincore.cc", + ] +}
diff --git a/tools/android/fincore/fincore.cc b/tools/android/fincore/fincore.cc new file mode 100644 index 0000000..01988722 --- /dev/null +++ b/tools/android/fincore/fincore.cc
@@ -0,0 +1,75 @@ +// Copyright (c) 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. + +#include <fcntl.h> +#include <stdint.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <iomanip> +#include <iostream> + +void PrintUsage(char* prog) { + std::cout << "Usage: " << prog << " FILE" << std::endl + << "Determine what portion of the FILE is resident in memory." + << std::endl; +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + PrintUsage(argv[0]); + return 1; + } + char* file_name = argv[1]; + if (!std::string("--help").compare(file_name)) { + PrintUsage(argv[0]); + return 0; + } + + int fd = open(file_name, O_RDONLY); + if (fd == -1) { + perror(file_name); + return 1; + } + + struct stat st; + if (fstat(fd, &st)) { + perror("fstat"); + return 1; + } + + size_t len = static_cast<size_t>(st.st_size); + if (len > SIZE_MAX) { + std::cerr << "File too large" << std::endl; + return 1; + } + void* start_address = mmap(nullptr, len, PROT_READ, MAP_SHARED, fd, 0); + if (start_address == MAP_FAILED) { + perror("mmap"); + return 1; + } + + size_t total_pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; + std::unique_ptr<uint8_t[]> page_residency(new uint8_t[total_pages]); + if (mincore(start_address, len, page_residency.get())) { + perror("mincore"); + return 1; + } + + size_t resident_pages = 0; + for (size_t i = 0; i < total_pages; ++i) { + if (page_residency[i] != 0) { + resident_pages++; + } + } + + std::cout << "File size: " << len << ", resident pages: " << resident_pages + << ", which is " << std::setprecision(4) + << 100.0 * resident_pages / total_pages << "\% of all pages (" + << resident_pages / 256 << "MiB)." << std::endl; + + return 0; +}
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index e4d2405..5c31f07 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -9455,6 +9455,8 @@ <int value="50" label="Periodic background sync"/> <int value="51" label="HID guard"/> <int value="52" label="HID permission data"/> + <int value="54" label="Screen wake lock"/> + <int value="55" label="System wake lock"/> </enum> <enum name="ContentTypeParseableResult"> @@ -46131,6 +46133,8 @@ <int value="17" label="PERMISSION_BACKGROUND_FETCH"/> <int value="18" label="PERMISSION_IDLE_DETECTION"/> <int value="19" label="PERMISSION_PERIODIC_BACKGROUND_SYNC"/> + <int value="20" label="PERMISSION_WAKE_LOCK_SCREEN"/> + <int value="21" label="PERMISSION_WAKE_LOCK_SYSTEM"/> </enum> <enum name="PersistedLogsLogReadStatus"> @@ -47779,6 +47783,7 @@ <int value="21" label="FIT_TO_PAGE"/> <int value="22" label="DEFAULT_DPI"/> <int value="23" label="NON_DEFAULT_DPI"/> + <int value="24" label="PIN"/> </enum> <enum name="PrivetNotificationsEvent"> @@ -49639,63 +49644,170 @@ Enumerates names of Mojo interfaces that are requests through RenderFrameHostImpl::GetInterface. </summary> + <int value="4595745" label="blink.mojom.NativeFileSystemManager"/> + <int value="28688772" label="snippets_internals.mojom.PageHandlerFactory"/> <int value="39256405" label="device.mojom.Geolocation"/> + <int value="70273688" label="device.mojom.VRService"/> <int value="81966276" label="blink.mojom.KeyboardLockService"/> + <int value="83462680" label="media.mojom.MediaMetricsProvider"/> <int value="112672197" label="blink.mojom.SharedWorkerConnector"/> + <int value="116454628" label="blink.mojom.CacheStorage"/> + <int value="118314811" label="media.mojom.RemoterFactory"/> + <int value="127672107" label="mojom.UsbInternalsPageHandler"/> <int value="141486647" label="webauth.mojom.Authenticator"/> <int value="155545232" label="blink.mojom.GeolocationService"/> <int value="188516542" label="content.mojom.MediaStreamDispatcherHost"/> <int value="190256703" label="network.mojom.RestrictedCookieManager"/> + <int value="194725745" label="app_management.mojom.PageHandlerFactory"/> + <int value="202417688" label="resource_coordinator.mojom.WebUIGraphDump"/> + <int value="241045822" label="blink.mojom.DateTimeChooser"/> + <int value="242965667" label="blink.mojom.MediaSessionService"/> + <int value="250652837" label="mojom.ProcessInternalsHandler"/> <int value="264532149" label="blink.mojom.LockManager"/> + <int value="271849582" label="performance_manager.mojom.WebUIGraphDump"/> + <int value="273500403" label="blink.mojom.PresentationService"/> <int value="298400659" label="media.mojom.MediaMetricsProvider"/> + <int value="302655516" label="blink.mojom.WakeLockService"/> + <int value="323903839" label="feed_internals.mojom.PageHandler"/> + <int value="389086904" label="content.mojom.BrowserTarget"/> + <int value="390613312" label="autofill.mojom.AutofillDriver"/> + <int value="390850644" label="device.mojom.GamepadMonitor"/> + <int value="398982196" label="mojom.InterventionsInternalsPageHandler"/> + <int value="423966775" label="blink.mojom.IDBFactory"/> + <int value="443506227" label="blink.mojom.SpeechRecognizer"/> + <int value="450992839" label="blink.mojom.WebBluetoothService"/> + <int value="453803103" label="device.mojom.Geolocation"/> + <int value="465691137" label="blink.mojom.BadgeService"/> + <int value="470231457" label="extensions.KeepAlive"/> <int value="473587909" label="autofill.mojom.AutofillDriver"/> <int value="480255287" label="content.mojom.BrowserTarget"/> + <int value="485751698" label="blink.mojom.MediaStreamDispatcherHost"/> + <int value="536067486" label="ws.mojom.Gpu"/> + <int value="575717011" label="blink.mojom.AnchorElementMetricsHost"/> <int value="583861320" label="media.mojom.InterfaceFactory"/> <int value="593735191" label="blink.mojom.PresentationService"/> <int value="620853817" label="media.mojom.Renderer"/> + <int value="660485518" label="payments.mojom.PaymentRequest"/> + <int value="664813603" label="blink.mojom.ShareService"/> + <int value="668914812" label="autofill.mojom.PasswordManagerDriver"/> <int value="670026296" label="blink.mojom.CacheStorage"/> + <int value="738435690" label="blink.mojom.SharedWorkerConnector"/> + <int value="772959538" + label="dom_distiller.mojom.DistillerJavaScriptService"/> + <int value="781395216" label="dom_distiller.mojom.DistillabilityService"/> <int value="833468074" label="device.mojom.VRService"/> <int value="846414148" label="blink.mojom.MediaDevicesDispatcherHost"/> + <int value="893321775" + label="resource_coordinator.mojom.FrameCoordinationUnit"/> + <int value="902740039" label="blink.mojom.PermissionService"/> <int value="917382314" label="blink.mojom.TextSuggestionHost"/> <int value="917568449" label="media.mojom.ImageCapture"/> <int value="948847120" label="blink.mojom.WebUsbService"/> + <int value="958735765" label="shape_detection.mojom.FaceDetectionProvider"/> <int value="968027799" label="blink.mojom.MediaSessionService"/> + <int value="979421400" label="device.mojom.NFC"/> + <int value="982123735" label="blink.mojom.ColorChooserFactory"/> + <int value="994757370" label="blink.mojom.InsecureInputService"/> <int value="996732224" label="autofill.mojom.PasswordManagerDriver"/> + <int value="1014286658" label="blink.mojom.NotificationService"/> + <int value="1037735345" label="extensions.mime_handler.BeforeUnloadControl"/> + <int value="1044427386" label="blink.mojom.SmsManager"/> + <int value="1048723358" label="content.mojom.InputInjector"/> + <int value="1049460515" label="translate.mojom.ContentTranslateDriver"/> <int value="1071268620" label="blink.mojom.QuotaDispatcherHost"/> + <int value="1100311626" label="blink.mojom.TextSuggestionHost"/> + <int value="1102158904" label="chrome.mojom.PrerenderCanceler"/> <int value="1116085333" label="content.mojom.RendererAudioOutputStreamFactory"/> + <int value="1117840258" label="media.mojom.InterfaceFactory"/> + <int value="1123228604" label="blink.mojom.QuotaDispatcherHost"/> + <int value="1144764995" label="network.mojom.WebSocket"/> <int value="1144778719" label="ui.mojom.Gpu"/> + <int value="1148580579" label="blink.mojom.LockManager"/> + <int value="1157068323" + label="resource_coordinator.mojom.DocumentCoordinationUnit"/> + <int value="1207132298" label="media.mojom.Renderer"/> <int value="1214902026" label="device.mojom.VibrationManager"/> + <int value="1225155271" label="blink.mojom.DedicatedWorkerHostFactory"/> <int value="1237802022" label="blink.mojom.PermissionService"/> + <int value="1241592573" label="media.mojom.VideoDecodePerfHistory"/> + <int value="1258017914" label="blink.mojom.UnhandledTapNotifier"/> + <int value="1293422219" label="media.mojom.ImageCapture"/> <int value="1298636847" label="media.mojom.RemoterFactory"/> + <int value="1303034727" label="blink.mojom.PictureInPictureService"/> + <int value="1311956027" + label="discardable_memory.mojom.DiscardableSharedMemoryManager"/> <int value="1321671191" label="blink.mojom.BudgetService"/> <int value="1337066913" label="resource_coordinator.mojom.FrameCoordinationUnit"/> + <int value="1363277053" label="mojom.OmniboxPageHandler"/> <int value="1374541190" label="payments.mojom.PaymentManager"/> + <int value="1391649397" label="blink.mojom.InstalledAppProvider"/> <int value="1416694600" label="payments.mojom.PaymentRequest"/> <int value="1419976867" label="blink.mojom.DedicatedWorkerHostFactory"/> <int value="1448556545" label="content.mojom.InputInjector"/> + <int value="1450167594" label="device.mojom.WakeLock"/> + <int value="1454720654" label="blink.mojom.ContactsManager"/> + <int value="1487601584" label="blink.mojom.SerialService"/> + <int value="1494628140" label="blink.mojom.BackgroundFetchService"/> + <int value="1497405510" label="blink.mojom.Portal"/> + <int value="1514474533" label="blink.mojom.DisplayCutoutHost"/> + <int value="1517562643" + label="content.mojom.RendererAudioInputStreamFactory"/> + <int value="1528642323" label="mojom.BluetoothInternalsHandler"/> <int value="1548931182" label="shape_detection.mojom.FaceDetectionProvider"/> + <int value="1558418769" label="mojom.DiscardsDetailsProvider"/> <int value="1558900994" label="device.mojom.NFC"/> + <int value="1566236400" label="mojom.SiteEngagementDetailsProvider"/> + <int value="1569949878" label="mojom.ResetPasswordHandler"/> <int value="1608786055" label="network.mojom.WebSocket"/> + <int value="1617971260" label="blink.mojom.HidService"/> + <int value="1625278273" + label="shape_detection.mojom.BarcodeDetectionProvider"/> + <int value="1637627623" label="device.mojom.SensorProvider"/> <int value="1658893493" label="device.mojom.WakeLock"/> <int value="1659485640" label="password_manager.mojom.CredentialManager"/> + <int value="1664576526" + label="media.mojom.MediaEngagementScoreDetailsProvider"/> + <int value="1694940426" label="blink.mojom.KeyboardLockService"/> <int value="1725898486" label="blink.mojom.UnhandledTapNotifier"/> <int value="1726661029" label="blink.mojom.ColorChooserFactory"/> <int value="1727086043" label="content.mojom.RendererAudioInputStreamFactory"/> <int value="1729889736" label="discardable_memory.mojom.DiscardableSharedMemoryManager"/> + <int value="1736030522" label="downloads.mojom.PageHandlerFactory"/> <int value="1750772802" label="blink.mojom.NotificationService"/> + <int value="1751386040" label="page_load_metrics.mojom.PageLoadMetrics"/> <int value="1769429998" label="blink.mojom.PrefetchURLLoaderService"/> + <int value="1780600451" label="blink.mojom.MediaDevicesDispatcherHost"/> <int value="1785235899" label="shape_detection.mojom.BarcodeDetection"/> <int value="1798060917" label="blink.mojom.BackgroundFetchService"/> + <int value="1811548070" label="payments.mojom.PaymentManager"/> + <int value="1831896638" + label="content.mojom.RendererAudioOutputStreamFactory"/> + <int value="1844445757" label="image_annotation.mojom.Annotator"/> <int value="1851878773" label="blink.mojom.WebBluetoothService"/> + <int value="1872102254" label="blink.mojom.PrefetchURLLoaderService"/> + <int value="1872706686" + label="contextual_search.mojom.ContextualSearchJsApiService"/> + <int value="1884536898" label="blink.mojom.FileSystemManager"/> + <int value="1893297160" label="network.mojom.RestrictedCookieManager"/> + <int value="1921948028" label="blink.mojom.GeolocationService"/> <int value="1951066980" label="shape_detection.mojom.TextDetection"/> + <int value="1972006840" label="blink.mojom.FileChooser"/> + <int value="2015729329" label="extensions.mime_handler.MimeHandlerService"/> + <int value="2019700793" label="device.mojom.VibrationManager"/> + <int value="2036010684" label="chrome.mojom.OfflinePageAutoFetcher"/> + <int value="2051587908" label="blink.mojom.IdleManager"/> + <int value="2056556199" label="media_router.mojom.MediaRouter"/> <int value="2060513738" label="webauth.test.mojom.VirtualAuthenticatorManager"/> <int value="2067597900" label="blink.mojom.InsecureInputService"/> + <int value="2076591855" label="viz.mojom.Gpu"/> <int value="2109171099" label="device.mojom.SensorProvider"/> + <int value="2137870010" label="web_ui_test.mojom.TestRunner"/> + <int value="2147202291" label="shape_detection.mojom.TextDetection"/> </enum> <enum name="RenderViewContextMenuItem"> @@ -51813,6 +51925,9 @@ </enum> <enum name="ServiceWorkerPreparationType"> + <obsolete> + Removed on June 2019 + </obsolete> <summary> The type of preparation that was required for the browser to find and possibly start up a service worker to dispatch a fetch event to. From @@ -51848,6 +51963,9 @@ </enum> <enum name="ServiceWorkerResponseError"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <int value="0" label="ErrorUnknown"/> <int value="1" label="ErrorPromiseRejected"/> <int value="2" label="ErrorDefaultPrevented"/> @@ -51928,6 +52046,9 @@ </enum> <enum name="ServiceWorkerURLRequestJobResult"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <int value="0" label="REQUEST_JOB_FALLBACK_RESPONSE"/> <int value="1" label="REQUEST_JOB_FALLBACK_FOR_CORS"/> <int value="2" label="REQUEST_JOB_HEADERS_ONLY_RESPONSE"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ca0ee6b..a486d48c 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -2577,7 +2577,7 @@ </histogram> <histogram name="Android.NativeBackgroundTask.TaskFinished" - enum="BackgroundTaskId" expires_after="2019-08-01"> + enum="BackgroundTaskId" expires_after="2020-06-17"> <owner>mheikal@chromium.org</owner> <owner>hanxi@chromium.org</owner> <owner>hnakashima@chromium.org</owner> @@ -2615,7 +2615,7 @@ </histogram> <histogram name="Android.NativeBackgroundTask.TaskStarted" - enum="BackgroundTaskId" expires_after="2019-08-01"> + enum="BackgroundTaskId" expires_after="2020-06-17"> <owner>mheikal@chromium.org</owner> <owner>hanxi@chromium.org</owner> <owner>hnakashima@chromium.org</owner> @@ -15733,7 +15733,7 @@ </histogram> <histogram name="BrowserServices.VerificationResult" - enum="BrowserServicesVerificationResult" expires_after="M77"> + enum="BrowserServicesVerificationResult" expires_after="M83"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -15742,7 +15742,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.CacheFile.MkDirSuccess" enum="BooleanSuccess"> +<histogram name="BrowserSwitcher.CacheFile.MkDirSuccess" enum="BooleanSuccess" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15751,7 +15752,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.CacheFile.MkTempSuccess" enum="BooleanSuccess"> +<histogram name="BrowserSwitcher.CacheFile.MkTempSuccess" enum="BooleanSuccess" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15761,7 +15763,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.CacheFile.MoveSuccess" enum="BooleanSuccess"> +<histogram name="BrowserSwitcher.CacheFile.MoveSuccess" enum="BooleanSuccess" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15772,7 +15775,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.Decision" enum="BooleanBrowserSwitch"> +<histogram name="BrowserSwitcher.Decision" enum="BooleanBrowserSwitch" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15784,7 +15788,7 @@ </histogram> <histogram name="BrowserSwitcher.ExternalGreylistSize" units="rules" - expires_after="M79"> + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15793,7 +15797,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.ExternalSitelistSize" units="rules"> +<histogram name="BrowserSwitcher.ExternalSitelistSize" units="rules" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15802,7 +15807,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.GreylistSize" units="rules"> +<histogram name="BrowserSwitcher.GreylistSize" units="rules" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15811,7 +15817,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.GreylistWildcard" enum="BooleanPresent"> +<histogram name="BrowserSwitcher.GreylistWildcard" enum="BooleanPresent" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15821,7 +15828,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.IeemSitelistSize" units="rules"> +<histogram name="BrowserSwitcher.IeemSitelistSize" units="rules" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15830,7 +15838,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.LaunchSuccess" enum="BooleanSuccess"> +<histogram name="BrowserSwitcher.LaunchSuccess" enum="BooleanSuccess" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15839,7 +15848,8 @@ </summary> </histogram> -<histogram name="BrowserSwitcher.UrlListSize" units="rules"> +<histogram name="BrowserSwitcher.UrlListSize" units="rules" + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -15849,7 +15859,7 @@ </histogram> <histogram name="BrowserSwitcher.UrlListWildcard" enum="BooleanPresent" - expires_after="M77"> + expires_after="2020-06-18"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -18036,17 +18046,17 @@ <histogram name="CloudPrint.AuthEvent" enum="CloudPrintAuthEventType" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Event counts in CloudPrintAuth.</summary> </histogram> <histogram name="CloudPrint.AvailablePrinters"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The number of printers availible for registration.</summary> </histogram> <histogram name="CloudPrint.AvailablePrintersList"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The number of printers availible for registration in Windows Service. </summary> @@ -18057,61 +18067,61 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time between capabilities updates.</summary> </histogram> <histogram name="CloudPrint.JobHandlerEvent" enum="CloudPrintJobHandlerEventType" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Event counts in PrinterJobHandler.</summary> </histogram> <histogram name="CloudPrint.JobsDonePerInterval"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The number of jobs successfully completed per hour.</summary> </histogram> <histogram name="CloudPrint.JobsStartedPerInterval" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The number of jobs started per hour.</summary> </histogram> <histogram name="CloudPrint.JobStatus" enum="CloudPrintJobStatusType" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Then number of job completion statuses.</summary> </histogram> <histogram name="CloudPrint.NativeJobStatus" enum="CloudPrintNativeJobStatusType" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Event counts in PrintSystem.</summary> </histogram> <histogram name="CloudPrint.PrepareTime" units="ms" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time needed to prepare job for spooling.</summary> </histogram> <histogram name="CloudPrint.PrinterBlacklistSize" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The number of printers user has blacklisted.</summary> </histogram> <histogram name="CloudPrint.PrinterWhitelistSize" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The number of printers user has whitelisted.</summary> </histogram> <histogram name="CloudPrint.PrintingTime" units="ms"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time needed to finish print job.</summary> </histogram> <histogram name="CloudPrint.ServiceEvents" enum="ServiceProcessEventType" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Event counts in ServiceProcessControl.</summary> </histogram> @@ -18120,7 +18130,7 @@ <obsolete> Removed 12/2015. http://crbug.com/466644 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Temporarily histogram with size of IPC sockets in default location. </summary> @@ -18131,7 +18141,7 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The amount of time used to fail to collect printer capabilities. </summary> @@ -18142,7 +18152,7 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time used to collect printer capabilities.</summary> </histogram> @@ -18151,7 +18161,7 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The amount of time the utility process runs before disconnect. </summary> @@ -18162,7 +18172,7 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time used to fail to generate metafile.</summary> </histogram> @@ -18171,13 +18181,13 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time used to generate metafile.</summary> </histogram> <histogram name="CloudPrint.ServiceUtilityProcessHostEvent" enum="ServiceUtilityProcessHostEventType" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Event counts in ServiceUtilityProcessHost.</summary> </histogram> @@ -18186,7 +18196,7 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The amount of time used to fail to collect printer capabilities. </summary> @@ -18197,48 +18207,48 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time used to collect printer capabilities.</summary> </histogram> <histogram name="CloudPrint.SpoolingTime" units="ms" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time needed to spool print job.</summary> </histogram> <histogram name="CloudPrint.UnregisterPrinters" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The number of printers to unregister.</summary> </histogram> <histogram name="CloudPrint.UrlFetcherDownloadSize" units="KB"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of data downloaded on cloud print request.</summary> </histogram> <histogram name="CloudPrint.UrlFetcherRequestTime" units="ms"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of time needed for cloud print request.</summary> </histogram> <histogram name="CloudPrint.UrlFetcherRequestType" enum="CloudPrintUrlFetcherRequestType" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Request counts to cloud print service.</summary> </histogram> <histogram name="CloudPrint.UrlFetcherRetries"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The number of retries used to complete cloud print request.</summary> </histogram> <histogram name="CloudPrint.UrlFetcherUploadSize" units="KB"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>The amount of data uploaded with cloud print request.</summary> </histogram> <histogram name="CloudPrint.XmppPingTry" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Number of tries before successful ping. 99 means giving up.</summary> </histogram> @@ -18246,7 +18256,7 @@ <obsolete> Removed 02/2017. http://crbug.com/643570 </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Xmpp timeout option value provided by server.</summary> </histogram> @@ -23204,7 +23214,7 @@ </histogram> <histogram name="CustomTabs.ConnectionStatusOnReturn.GSA" - enum="CustomTabsConnection" expires_after="M77"> + enum="CustomTabsConnection" expires_after="M83"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary> @@ -23216,7 +23226,7 @@ </histogram> <histogram name="CustomTabs.ConnectionStatusOnReturn.NonGSA" - enum="CustomTabsConnection" expires_after="M77"> + enum="CustomTabsConnection" expires_after="M83"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary> @@ -23255,7 +23265,7 @@ </histogram> <histogram name="CustomTabs.DynamicModule.CreateActivityDelegateTime" - units="ms"> + units="ms" expires_after="2019-11-01"> <owner>mvanouwerkerk@chromium.org</owner> <summary> Time to create an activity delegate for a custom tabs dynamic module. @@ -23263,7 +23273,8 @@ </summary> </histogram> -<histogram name="CustomTabs.DynamicModule.CreatePackageContextTime" units="ms"> +<histogram name="CustomTabs.DynamicModule.CreatePackageContextTime" units="ms" + expires_after="2019-11-01"> <owner>mvanouwerkerk@chromium.org</owner> <summary> Time to create the package context for a custom tabs dynamic module. Android @@ -23272,7 +23283,7 @@ </histogram> <histogram name="CustomTabs.DynamicModule.DestructionReason" - enum="CustomTabsDynamicModuleDestructionReason" expires_after="2019-07-01"> + enum="CustomTabsDynamicModuleDestructionReason" expires_after="2019-11-01"> <owner>mvanouwerkerk@chromium.org</owner> <summary> Possible reasons for destroying a custom tabs dynamic module. Android only. @@ -23280,7 +23291,8 @@ </histogram> <histogram name="CustomTabs.DynamicModule.EntryPointInitTime" units="ms" - expires_after="2019-04-22"> + expires_after="2019-11-01"> + <owner>mvanouwerkerk@chromium.org</owner> <owner>amalova@chromium.org</owner> <summary> Time to initialize the entry point class for a custom tabs dynamic module. @@ -23288,7 +23300,8 @@ </summary> </histogram> -<histogram name="CustomTabs.DynamicModule.EntryPointLoadClassTime" units="ms"> +<histogram name="CustomTabs.DynamicModule.EntryPointLoadClassTime" units="ms" + expires_after="2019-11-01"> <owner>mvanouwerkerk@chromium.org</owner> <summary> Time to load the entry point class for a custom tabs dynamic module. Android @@ -23296,7 +23309,8 @@ </summary> </histogram> -<histogram name="CustomTabs.DynamicModule.EntryPointNewInstanceTime" units="ms"> +<histogram name="CustomTabs.DynamicModule.EntryPointNewInstanceTime" units="ms" + expires_after="2019-11-01"> <owner>mvanouwerkerk@chromium.org</owner> <summary> Time to instantiate the entry point class for a custom tabs dynamic module. @@ -23305,7 +23319,7 @@ </histogram> <histogram name="CustomTabs.DynamicModule.LoadResult" - enum="CustomTabsDynamicModuleLoadResult"> + enum="CustomTabsDynamicModuleLoadResult" expires_after="2019-11-01"> <owner>mvanouwerkerk@chromium.org</owner> <summary> Possible results when loading a custom tabs dynamic module. Android only. @@ -23313,9 +23327,10 @@ </histogram> <histogram name="CustomTabs.DynamicModule.ProportionalSet.OnModuleDestroy" - units="KB" expires_after="2019-05-10"> + units="KB" expires_after="2019-11-01"> <owner>msalama@google.com</owner> <owner>lizeb@chromium.org</owner> + <owner>mvanouwerkerk@chromium.org</owner> <summary> The proportional set size (PSS) of code pages occupied by a custom tabs dynamic module. Recorded before the module destruction. Android only. @@ -23323,9 +23338,10 @@ </histogram> <histogram name="CustomTabs.DynamicModule.ProportionalSet.OnModuleLoad" - units="KB" expires_after="2019-05-10"> + units="KB" expires_after="2019-11-01"> <owner>msalama@google.com</owner> <owner>lizeb@chromium.org</owner> + <owner>mvanouwerkerk@chromium.org</owner> <summary> The proportional set size (PSS) of code pages occupied by a custom tabs dynamic module. Recorded when a module is loaded. Android only. @@ -23333,9 +23349,10 @@ </histogram> <histogram name="CustomTabs.DynamicModule.ResidentSet.OnModuleDestroy" - units="KB" expires_after="2019-05-10"> + units="KB" expires_after="2019-11-01"> <owner>msalama@google.com</owner> <owner>lizeb@chromium.org</owner> + <owner>mvanouwerkerk@chromium.org</owner> <summary> The resident set size (RSS) of code pages occupied by a custom tabs dynamic module. Recorded before the module destruction. Android only. @@ -23343,9 +23360,10 @@ </histogram> <histogram name="CustomTabs.DynamicModule.ResidentSet.OnModuleLoad" units="KB" - expires_after="2019-05-10"> + expires_after="2019-11-01"> <owner>msalama@google.com</owner> <owner>lizeb@chromium.org</owner> + <owner>mvanouwerkerk@chromium.org</owner> <summary> The resident set size (RSS) of code pages occupied by a custom tabs dynamic module. Recorded when a module is loaded. Android only. @@ -39048,7 +39066,9 @@ </histogram> <histogram name="Extensions.HasPermissions_Install3" enum="Boolean" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -39085,7 +39105,9 @@ </histogram> <histogram name="Extensions.HasPermissions_Load3" enum="Boolean" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -39256,7 +39278,9 @@ </summary> </histogram> -<histogram name="Extensions.IncognitoAllowed" expires_after="M77"> +<histogram name="Extensions.IncognitoAllowed" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of extensions (and friends) that could have been allowed in @@ -39468,7 +39492,9 @@ </histogram> <histogram name="Extensions.InstallType" enum="ExtensionType" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary>Installs grouped by Extension::HistogramType.</summary> </histogram> @@ -39493,7 +39519,9 @@ </summary> </histogram> -<histogram name="Extensions.LoadAll" expires_after="M77"> +<histogram name="Extensions.LoadAll" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary>The number of extensions and themes loaded at profile open.</summary> </histogram> @@ -39526,12 +39554,16 @@ </summary> </histogram> -<histogram name="Extensions.LoadApp" expires_after="M77"> +<histogram name="Extensions.LoadApp" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary>The number of apps loaded by each user at profile open.</summary> </histogram> -<histogram name="Extensions.LoadAppExternal" expires_after="M77"> +<histogram name="Extensions.LoadAppExternal" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of externally managed apps loaded by each user at profile open. @@ -39571,12 +39603,16 @@ </summary> </histogram> -<histogram name="Extensions.LoadExtension"> +<histogram name="Extensions.LoadExtension" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary>The number of extensions loaded at profile open.</summary> </histogram> -<histogram name="Extensions.LoadExtensionExternal" expires_after="M77"> +<histogram name="Extensions.LoadExtensionExternal" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of externally managed extensions loaded at profile open. @@ -39584,20 +39620,26 @@ </histogram> <histogram name="Extensions.LoadExtensionUser"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of user-installed extensions loaded at profile open. </summary> </histogram> -<histogram name="Extensions.LoadExternal"> +<histogram name="Extensions.LoadExternal" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of externally managed extensions and apps loaded at profile open. </summary> </histogram> -<histogram name="Extensions.LoadHostedApp" expires_after="M77"> +<histogram name="Extensions.LoadHostedApp" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of hosted apps loaded by each user at profile open. @@ -39620,14 +39662,18 @@ </summary> </histogram> -<histogram name="Extensions.LoadPackagedApp" expires_after="M77"> +<histogram name="Extensions.LoadPackagedApp" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of legacy packaged apps loaded by each user at profile open. </summary> </histogram> -<histogram name="Extensions.LoadPlatformApp" expires_after="M77"> +<histogram name="Extensions.LoadPlatformApp" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary>The number of platform apps loaded at profile open.</summary> </histogram> @@ -39799,7 +39845,9 @@ </summary> </histogram> -<histogram name="Extensions.ManifestVersion" expires_after="M77"> +<histogram name="Extensions.ManifestVersion" expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary>The manifest version of each loaded extension.</summary> </histogram> @@ -39918,7 +39966,9 @@ </histogram> <histogram name="Extensions.NonWebstoreLocation" enum="ExtensionLocation" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: Monitoring extension usage. --> + <owner>rdevlin.cronin@chromium.org</owner> <summary> The number of apps/extensions with a non-webstore update_url loaded at @@ -41702,8 +41752,12 @@ </histogram> <histogram name="Favicons.LargeIconService.DownloadedSize" units="pixels" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: This metric is needed for informing future UX decisions on + mobile (how to display favicons / scrabble tiles). --> + <owner>jkrcal@chromium.org</owner> + <owner>mastiz@chromium.org</owner> <summary> Records the size (concretely the width) in pixel of the favicon downloaded from Google favicon server (size 0 denotes that download has failed). @@ -41711,8 +41765,12 @@ </histogram> <histogram name="Favicons.LargeIconService.FallbackSize" units="pixels" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: This metric is needed for informing future UX decisions on + mobile (how to display favicons / scrabble tiles). --> + <owner>jkrcal@chromium.org</owner> + <owner>mastiz@chromium.org</owner> <summary> Records the size (concretely the width) in pixel of the favicon that is used to generate a fallback style in the case when large enough favicon is not @@ -43165,7 +43223,7 @@ </histogram> <histogram name="Gamepad.KnownGamepadConnectedWithId" - enum="GamepadVendorProduct" expires_after="2019-07-18"> + enum="GamepadVendorProduct" expires_after="2019-12-12"> <owner>mattreynolds@chromium.org</owner> <summary> Records an integer value that can be used to identify a connected gamepad @@ -43181,7 +43239,7 @@ </histogram> <histogram name="Gamepad.UnknownGamepadConnected" enum="GamepadSource" - expires_after="2019-07-18"> + expires_after="2019-12-12"> <owner>mattreynolds@chromium.org</owner> <summary> Records an enumeration value identifying the active data fetcher when a @@ -47827,6 +47885,9 @@ <histogram name="Import.IncludesPasswords.Firefox" enum="BooleanChecked" expires_after="M77"> + <obsolete> + Deprecated 06/19. + </obsolete> <owner>vasilii@chromium.org</owner> <owner>hurims@gmail.com</owner> <summary> @@ -47835,7 +47896,7 @@ </summary> </histogram> -<histogram name="Import.NumberOfImportedPasswords.Firefox" expires_after="M77"> +<histogram name="Import.NumberOfImportedPasswords.Firefox" expires_after="M82"> <owner>vasilii@chromium.org</owner> <owner>hurims@gmail.com</owner> <summary> @@ -51635,6 +51696,9 @@ <histogram name="LevelDBEnv.LockFileAncestorsNotFound" units="directories" expires_after="M77"> + <obsolete> + Deprecated 2019-06. + </obsolete> <owner>dgrogan@chromium.org</owner> <summary> Number of directories missing when Non-IDB LevelDBEnv tries to create a Lock @@ -51892,36 +51956,31 @@ </histogram> <histogram name="LocalDiscovery.ClientRestartAttempts" expires_after="M77"> - <owner>noamsml@chromium.org</owner> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Records number of attempts to start local discovery.</summary> </histogram> <histogram name="LocalDiscovery.DetectorRestartTime" units="ms" expires_after="M77"> - <owner>noamsml@chromium.org</owner> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Time between detector restarts.</summary> </histogram> <histogram name="LocalDiscovery.DetectorTriggerTime" units="ms" expires_after="M77"> - <owner>noamsml@chromium.org</owner> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Time before detector trigger notifications.</summary> </histogram> <histogram name="LocalDiscovery.DevicesPage" enum="DevicesPageEvents" expires_after="M77"> - <owner>noamsml@chromium.org</owner> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Records events related to devices page.</summary> </histogram> <histogram name="LocalDiscovery.FirewallAccessTime" units="ms" expires_after="M77"> - <owner>noamsml@chromium.org</owner> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Windows only histogram that reports request time spend accessing firewall rules. It's logged once per browser process lifetime, when local discovery @@ -51930,8 +51989,7 @@ </histogram> <histogram name="LocalDiscovery.IsFirewallReady" enum="BooleanEnabled"> - <owner>noamsml@chromium.org</owner> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Windows only histogram that reports, whether a firewall is set, so we can bind inbound sockets. It's logged once per browser process lifetime, when @@ -51941,8 +51999,7 @@ <histogram name="LocalDiscovery.PrivetNotificationsEvent" enum="PrivetNotificationsEvent"> - <owner>noamsml@chromium.org</owner> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Records events related to local discovery notifications.</summary> </histogram> @@ -55268,7 +55325,7 @@ </histogram> <histogram name="Media.Engagement.PreloadedList.CheckResult" - enum="PreloadedListCheckResult" expires_after="M77"> + enum="PreloadedListCheckResult" expires_after="M82"> <owner>beccahughes@chromium.org</owner> <owner>media-dev@chromium.org</owner> <summary> @@ -55280,7 +55337,7 @@ </histogram> <histogram name="Media.Engagement.PreloadedList.LoadResult" - enum="PreloadedListLoadResult" expires_after="M77"> + enum="PreloadedListLoadResult" expires_after="M82"> <owner>beccahughes@chromium.org</owner> <owner>media-dev@chromium.org</owner> <summary> @@ -66143,7 +66200,9 @@ </histogram> <histogram name="Net.Certificate.TrustAnchor.Request" enum="NetTrustAnchors" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: Used for CA risk assessment ( https://goto.google.com/chrome-root-ca-stats ) --> + <owner>rsleevi@chromium.org</owner> <summary> The SHA-256 hash of the subjectPublicKeyInfo of the most-specific trust @@ -66154,7 +66213,9 @@ </histogram> <histogram name="Net.Certificate.TrustAnchor.Verify" enum="NetTrustAnchors" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: Used for CA risk assessment ( https://goto.google.com/chrome-root-ca-stats ) --> + <owner>rsleevi@chromium.org</owner> <summary> The SHA-256 hash of the subjectPublicKeyInfo of the most-specific trust @@ -68753,6 +68814,10 @@ <histogram name="Net.FoundSystemTrustRootsAndroid" enum="BooleanFound" expires_after="M77"> + <obsolete> + Underlying implementation changed to no longer depend on OS. Removed in + Chrome 77. + </obsolete> <owner>davidben@chromium.org</owner> <owner>rsleevi@chromium.org</owner> <summary> @@ -79403,7 +79468,7 @@ </histogram> <histogram name="NewTabPage.LogoClick" enum="NewTabPageLogoClick" - expires_after="M77"> + expires_after="M81"> <owner>kmilka@chromium.org</owner> <owner>ramyan@chromium.org</owner> <summary> @@ -79412,7 +79477,7 @@ </histogram> <histogram name="NewTabPage.LogoDownloadOutcome" - enum="NewTabPageLogoDownloadOutcome" expires_after="M77"> + enum="NewTabPageLogoDownloadOutcome" expires_after="M81"> <owner>kmilka@chromium.org</owner> <owner>ramyan@chromium.org</owner> <summary> @@ -79433,7 +79498,7 @@ </histogram> <histogram name="NewTabPage.LogoImageDownloaded" enum="BooleanFromHTTPCache" - expires_after="M77"> + expires_after="M81"> <owner>kmilka@chromium.org</owner> <owner>ramyan@chromium.org</owner> <summary> @@ -80690,7 +80755,7 @@ </histogram> <histogram name="NewTabPage.VoiceErrors" enum="NewTabPageVoiceError" - expires_after="M77"> + expires_after="M81"> <owner>kmilka@chromium.org</owner> <owner>ramyan@chromium.org</owner> <summary> @@ -83504,7 +83569,7 @@ </histogram> <histogram base="true" name="OfflinePages.MhtmlLoadResult" - enum="MhtmlLoadResult" expires_after="2019-06-30"> + enum="MhtmlLoadResult" expires_after="2020-06-30"> <owner>iwells@chromium.org</owner> <owner>carlosk@chromium.org</owner> <summary> @@ -83515,7 +83580,7 @@ </histogram> <histogram name="OfflinePages.MhtmlLoadResultUntrusted" enum="MhtmlLoadResult" - expires_after="2019-06-30"> + expires_after="2020-06-30"> <owner>iwells@chromium.org</owner> <owner>carlosk@chromium.org</owner> <summary> @@ -84031,7 +84096,7 @@ </histogram> <histogram name="OfflinePages.SavedPageCountUponQuery" units="pages" - expires_after="M77"> + expires_after="2020-06-30"> <owner>carlosk@chromium.org</owner> <summary> Total number of saved offline pages recorded when they are all queried from @@ -90029,7 +90094,7 @@ </histogram> <histogram name="PageSerialization.MhtmlGeneration.FinalSaveStatus" - enum="MhtmlGenerationFinalSaveStatus" expires_after="M77"> + enum="MhtmlGenerationFinalSaveStatus" expires_after="2020-06-30"> <owner>carlosk@chromium.org</owner> <owner>offline-dev@chromium.org</owner> <summary>Final status of the MHTML save operation for a page.</summary> @@ -90149,7 +90214,7 @@ </histogram> <histogram name="PageSerialization.SerializationTime.CSSElement" - units="microseconds" expires_after="M77"> + units="microseconds" expires_after="2020-06-30"> <owner>carlosk@chromium.org</owner> <summary> Time spent serializing a CSS element (including embedded "sub"-CSS @@ -90164,7 +90229,7 @@ </histogram> <histogram name="PageSerialization.SerializationTime.Html" units="microseconds" - expires_after="M77"> + expires_after="2020-06-30"> <owner>carlosk@chromium.org</owner> <summary> Time taken to generate HTML data from a frame's DOM and serialize it @@ -90179,7 +90244,7 @@ </histogram> <histogram name="PageSerialization.SerializationTime.ImageElement" - units="microseconds"> + units="microseconds" expires_after="2020-06-30"> <owner>carlosk@chromium.org</owner> <summary> Time spent serializing an image element. @@ -101114,7 +101179,7 @@ <histogram name="PrinterService.PrinterServiceEvent" enum="PrinterServiceEventType"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Count of events in PrinterService on Chrome OS related to USB printers. </summary> @@ -101300,7 +101365,7 @@ <histogram name="PrintPreview.DestinationAction" enum="PrintPreviewPrintDestinationBuckets"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Actions performed by the user when the print destination search widget is shown to the user. @@ -101308,7 +101373,7 @@ </histogram> <histogram name="PrintPreview.FontType" enum="PrintPreviewFontTypeType"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Count of font file formats embeeded in print preview PDFs. These numbers are biased by what the platforms supports in terms of detection. @@ -101320,7 +101385,7 @@ <obsolete> No longer used as of 09/2017. </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Actions performed by the user when the Google Cloud Print add-printers promotion is shown to the user. @@ -101328,7 +101393,7 @@ </histogram> <histogram name="PrintPreview.InitialDisplayTime" units="ms"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Time from when print preview is intiated until the intial preview is sent to the preview tab for rendering. @@ -101336,7 +101401,7 @@ </histogram> <histogram name="PrintPreview.InitializationTime" units="ms"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Time from when print preview is intiated until the preview PDF generation is started. @@ -101354,14 +101419,14 @@ </histogram> <histogram name="PrintPreview.ManagePrinters" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Count the number of requests received to show the manage printers dialog. </summary> </histogram> <histogram name="PrintPreview.NumberOfPrinters"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Count the total number of printers shown in destination drop down list. </summary> @@ -101379,7 +101444,7 @@ </histogram> <histogram name="PrintPreview.PageCount.Initial" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The page count of the initial print preview, a.k.a. the total number of pages in documents to be printed. @@ -101395,7 +101460,7 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintToCloudPrint"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to a cloud printer. @@ -101407,15 +101472,14 @@ <obsolete> No longer used as of 01/2016. </obsolete> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to a cloud printer using web dialog. </summary> </histogram> -<histogram name="PrintPreview.PageCount.PrintToGoogleDrive" - expires_after="2019-06-18"> +<histogram name="PrintPreview.PageCount.PrintToGoogleDrive" expires_after="M77"> <owner>rbpotter@chromium.org</owner> <owner>thestig@chromium.org</owner> <summary> @@ -101425,14 +101489,14 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintToPDF"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to PDF. </summary> </histogram> <histogram name="PrintPreview.PageCount.PrintToPrinter"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to a printer. @@ -101440,7 +101504,7 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintWithExtension"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to an extension printer (using printerProvider API). @@ -101448,7 +101512,7 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintWithPrivet"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to a privet printer. @@ -101456,7 +101520,7 @@ </histogram> <histogram name="PrintPreview.PageCount.SystemDialog"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed using system dialog. @@ -101472,7 +101536,7 @@ </histogram> <histogram name="PrintPreview.PreviewEvent" enum="PrintPreviewHelperEvents"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Print preview events.</summary> </histogram> @@ -101500,7 +101564,7 @@ </histogram> <histogram name="PrintPreview.PrintSettings" enum="PrintSettings"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Track the popularity of print settings. (Settings when printing to PDF are excluded from this statistic.) @@ -101510,7 +101574,6 @@ <histogram name="PrintPreview.PrintSettingsUi" enum="PrintPreviewPrintSettingsUiBuckets"> <owner>thestig@chromium.org</owner> - <owner>avi@chromium.org</owner> <summary> Actions performed by the user interacting with print settings UI elements. </summary> @@ -101518,7 +101581,7 @@ <histogram name="PrintPreview.RegeneratePreviewRequest.BeforeCancel" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The number of times regenerate preview requests received before the user clicked the cancel button. @@ -101527,7 +101590,7 @@ <histogram name="PrintPreview.RegeneratePreviewRequest.BeforeFirstData" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The number of times regenerate preview requests received before the first preview data is availible. @@ -101536,7 +101599,7 @@ <histogram name="PrintPreview.RegeneratePreviewRequest.BeforePrint" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> The number of times regenerate preview requests received before the user clicked the print button. @@ -101545,7 +101608,7 @@ <histogram name="PrintPreview.RenderAndGeneratePDFTime" units="ms" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Time taken to render and generate PDF for print preview. (Includes time to reflow the page back to normal, but not the time to reflow the page to @@ -101554,7 +101617,7 @@ </histogram> <histogram name="PrintPreview.RenderAndGeneratePDFTimeAvgPerPage" units="ms"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Time taken to render and generate PDF for print preview divided by the number of pages. (Includes time to reflow the page back to normal, but not @@ -101563,19 +101626,19 @@ </histogram> <histogram name="PrintPreview.RendererError" enum="PrintPreviewFailureType"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Count how frequently a set of pre-defined print preview errors occur. </summary> </histogram> <histogram name="PrintPreview.RenderPDFPageTime" units="ms" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Time taken to render each PDF page for print preview.</summary> </histogram> <histogram name="PrintPreview.RenderToPDFTime" units="ms" expires_after="M77"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary>Time taken to render to PDF for print preview.</summary> </histogram> @@ -101604,7 +101667,7 @@ </histogram> <histogram name="PrintPreview.UserAction" enum="PrintPreviewUserActionType"> - <owner>avi@chromium.org</owner> + <owner>thestig@chromium.org</owner> <summary> Action taken by the user in the preview tab such as print, cancel, print to pdf and show advanced print settings dialog. @@ -105779,6 +105842,47 @@ </summary> </histogram> +<histogram name="RendererScheduler.TasksWithSafepoints.SafepointCount" + units="count" expires_after="2020-04-01"> + <owner>tasak@google.com</owner> + <owner>keishi@chromium.org</owner> + <summary> + Number of safepoints (defined by cooperative scheduling manager) inside a + single non-nested task executed on the main thread of a renderer process. + This is recorded when each non-nested task stops executing. + </summary> +</histogram> + +<histogram name="RendererScheduler.TasksWithSafepoints.TaskSliceTime" + units="ms" expires_after="2020-04-01"> + <owner>tasak@google.com</owner> + <owner>keishi@chromium.org</owner> + <summary> + The duration of every task slices. The non-nested task executed in main + thread of the renderer process scheduler is split into slices by the + safepoints defined by cooperative scheduling manager. This metrics doesn't + record the duration of task without any safepoints. This is recorded both + inside a safepoint and when the tasak finishes. + + Note that this metric discards tasks longer than 30 seconds because they are + considered to be a result of measurement glitch. + </summary> +</histogram> + +<histogram name="RendererScheduler.TasksWithSafepoints.TaskTime" + units="microseconds" expires_after="2020-04-01"> + <owner>tasak@google.com</owner> + <owner>keishi@chromium.org</owner> + <summary> + The duration of every non-nested task executed in main thread of the + renderer process which has more than one safepoint. This is recorded when + the task finishes. + + Note that this metric discards tasks longer than 30 seconds because they are + considered to be a result of measurement glitch. + </summary> +</histogram> + <histogram name="RendererScheduler.TaskTime" units="microseconds" expires_after="2017-05-23"> <obsolete> @@ -116012,6 +116116,9 @@ <histogram name="ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type" enum="ServiceWorkerPreparationType" expires_after="M77"> + <obsolete> + Removed June 2019. + </obsolete> <owner>falken@chromium.org</owner> <summary> The type of preparation needed for the browser to find and possibly start an @@ -117662,6 +117769,9 @@ <histogram name="ServiceWorker.URLRequestJob.FallbackedRequestMode" enum="FetchRequestMode" expires_after="M77"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <owner>horo@chromium.org</owner> <summary> Records the the mode of request that was fallbacked to the network by the @@ -117671,6 +117781,9 @@ <histogram name="ServiceWorker.URLRequestJob.MainResource.Result" enum="ServiceWorkerURLRequestJobResult"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <owner>falken@chromium.org</owner> <summary> Records the result of a main resource request forwarded to a Service Worker. @@ -117679,6 +117792,9 @@ <histogram name="ServiceWorker.URLRequestJob.MainResource.StatusZeroError" enum="ServiceWorkerResponseError" expires_after="M77"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <owner>falken@chromium.org</owner> <summary> Records the error provided when the renderer returns a response with status @@ -117690,6 +117806,9 @@ <histogram name="ServiceWorker.URLRequestJob.Subresource.Result" enum="ServiceWorkerURLRequestJobResult"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <owner>falken@chromium.org</owner> <summary> Records the result of a subresource request forwarded to a Service Worker. @@ -117698,6 +117817,9 @@ <histogram name="ServiceWorker.URLRequestJob.Subresource.StatusZeroError" enum="ServiceWorkerResponseError" expires_after="M77"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <owner>falken@chromium.org</owner> <summary> Records the error provided when the renderer returns a response with status @@ -120191,7 +120313,7 @@ </histogram> <histogram name="Signin.AndroidAccountSigninViewSeedingTime" units="ms" - expires_after="M77"> + expires_after="M80"> <owner>bsazonov@chromium.org</owner> <summary> The time it takes to seed accounts before proceeding to the account @@ -120655,7 +120777,7 @@ </histogram> <histogram name="Signin.Reconciler.ExternalCcResultTime.NotCompleted" - expires_after="M77"> + expires_after="2020-06-14"> <owner>msarda@chromium.org</owner> <owner>droger@chromium.org</owner> <summary> @@ -137539,17 +137661,21 @@ </histogram> <histogram name="V8.AsmModuleSizeBytes" units="bytes" expires_after="M77"> + <obsolete> + Deprecated on 2019-06 (crbug.com/969997). + </obsolete> <owner>mstarzinger@chromium.org</owner> <owner>titzer@chromium.org</owner> - <owner>aseemgarg@chromium.org</owner> <summary>Size of asm.js module (in asm.js format).</summary> </histogram> <histogram name="V8.AsmWasmTranslationMicroSeconds" units="microseconds" expires_after="M77"> + <obsolete> + Deprecated on 2019-06 (crbug.com/969997). + </obsolete> <owner>mstarzinger@chromium.org</owner> <owner>titzer@chromium.org</owner> - <owner>aseemgarg@chromium.org</owner> <summary> Time to convert asm.js code to WebAssembly. @@ -149902,6 +150028,7 @@ <histogram_suffixes name="ContentSetting" separator="."> <suffix name="Allow" label="Allow"/> + <suffix name="AllowThirdParty" label="All third parties allowed on a domain"/> <suffix name="Ask" label="Ask"/> <suffix name="Block" label="Block"/> <suffix name="DetectImportantContent" label="Detect important content"/>
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc index 281d832..44aca79 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -83,6 +83,12 @@ .Append(FILE_PATH_LITERAL("scripts")) .Append(FILE_PATH_LITERAL("run_tool.py")); +const base::FilePath kExtractorScript = + base::FilePath(FILE_PATH_LITERAL("tools")) + .Append(FILE_PATH_LITERAL("traffic_annotation")) + .Append(FILE_PATH_LITERAL("scripts")) + .Append(FILE_PATH_LITERAL("extractor.py")); + // Checks if the list of |path_filters| include the given |file_path|, or there // are path filters which are a folder (don't have a '.' in their name), and // match the file name. @@ -112,6 +118,7 @@ #else base::FilePath converted_file_path(file_path); #endif + converted_file_path = base::MakeAbsoluteFilePath(converted_file_path); base::FilePath normalized_path; if (base::NormalizeFilePath(converted_file_path, &normalized_path) && normalized_path.IsAbsolute()) { @@ -123,7 +130,7 @@ file_str.length() - base_str.length() - 1); } } - return file_path; + return converted_file_path.MaybeAsASCII(); } } // namespace @@ -176,12 +183,16 @@ .Next(); } -bool TrafficAnnotationAuditor::RunClangTool( +bool TrafficAnnotationAuditor::RunExtractor( + ExtractorBackend backend, const std::vector<std::string>& path_filters, bool filter_files_based_on_heuristics, bool use_compile_commands, bool rerun_on_errors, const base::FilePath& errors_file) { + DCHECK(backend == ExtractorBackend::CLANG_TOOL || + backend == ExtractorBackend::PYTHON_SCRIPT); + if (!safe_list_loaded_ && !LoadSafeList()) return false; @@ -204,51 +215,41 @@ return false; } - // As the checked out clang tool may be in a directory different from the - // default one (third_party/llvm-buid/Release+Asserts/bin), its path and - // clang's library folder should be passed to the run_tool.py script. - fprintf( - options_file, - "--generate-compdb --tool=traffic_annotation_extractor -p=%s " - "--tool-path=%s " - "--tool-arg=--extra-arg=-resource-dir=%s ", - build_path_.MaybeAsASCII().c_str(), - base::MakeAbsoluteFilePath(clang_tool_path_).MaybeAsASCII().c_str(), - base::MakeAbsoluteFilePath(GetClangLibraryPath()).MaybeAsASCII().c_str()); + // Write some options to the file, which depends on the backend used. + if (backend == ExtractorBackend::CLANG_TOOL) + WriteClangToolOptions(options_file, use_compile_commands); + else if (backend == ExtractorBackend::PYTHON_SCRIPT) + WritePythonScriptOptions(options_file); - for (const std::string& item : clang_tool_switches_) - fprintf(options_file, "--tool-arg=--extra-arg=%s ", item.c_str()); - - if (use_compile_commands) - fprintf(options_file, "--all "); - + // Write the file paths regardless of backend. for (const std::string& file_path : file_paths) fprintf(options_file, "%s ", file_path.c_str()); base::CloseFile(options_file); + const base::FilePath& script_path = + (backend == ExtractorBackend::CLANG_TOOL ? kRunToolScript + : kExtractorScript); base::CommandLine cmdline( - base::MakeAbsoluteFilePath(source_path_.Append(kRunToolScript))); - + base::MakeAbsoluteFilePath(source_path_.Append(script_path))); #if defined(OS_WIN) cmdline.PrependWrapper(L"python"); #endif - cmdline.AppendArg(base::StringPrintf( "--options-file=%s", options_filepath.MaybeAsASCII().c_str())); - // Change current folder to source before running run_tool.py as it expects to + // Change current folder to source before running the command as it expects to // be run from there. base::FilePath original_path; base::GetCurrentDirectory(&original_path); base::SetCurrentDirectory(source_path_); - bool result = base::GetAppOutput(cmdline, &clang_tool_raw_output_); + bool result = base::GetAppOutput(cmdline, &extractor_raw_output_); - // If running clang tool had no output, it means that the script running it - // could not perform the task. - if (clang_tool_raw_output_.empty()) { + // If the extractor had no output, it means that the script running it could + // not perform the task. + if (extractor_raw_output_.empty()) { result = false; - } else if (!result) { + } else if (backend == ExtractorBackend::CLANG_TOOL && !result) { // If clang tool had errors but also returned results, the errors can be // ignored as we do not separate platform specific files here and processing // them fails. This is a post-build test and if there exists any actual @@ -258,7 +259,8 @@ } if (!result) { - if (use_compile_commands && !clang_tool_raw_output_.empty()) { + if (backend == ExtractorBackend::CLANG_TOOL && use_compile_commands && + !extractor_raw_output_.empty()) { printf( "\nWARNING: Ignoring clang tool error as it is called using " "compile_commands.json which will result in processing some " @@ -305,6 +307,33 @@ return result; } +void TrafficAnnotationAuditor::WriteClangToolOptions( + FILE* options_file, + bool use_compile_commands) { + // As the checked out clang tool may be in a directory different from the + // default one (third_party/llvm-buid/Release+Asserts/bin), its path and + // clang's library folder should be passed to the run_tool.py script. + fprintf( + options_file, + "--generate-compdb --tool=traffic_annotation_extractor -p=%s " + "--tool-path=%s " + "--tool-arg=--extra-arg=-resource-dir=%s ", + build_path_.MaybeAsASCII().c_str(), + base::MakeAbsoluteFilePath(clang_tool_path_).MaybeAsASCII().c_str(), + base::MakeAbsoluteFilePath(GetClangLibraryPath()).MaybeAsASCII().c_str()); + + for (const std::string& item : clang_tool_switches_) + fprintf(options_file, "--tool-arg=--extra-arg=%s ", item.c_str()); + + if (use_compile_commands) + fprintf(options_file, "--all "); +} + +void TrafficAnnotationAuditor::WritePythonScriptOptions(FILE* options_file) { + fprintf(options_file, "--generate-compdb --build-path=%s ", + build_path_.MaybeAsASCII().c_str()); +} + void TrafficAnnotationAuditor::GenerateFilesListForClangTool( const std::vector<std::string>& path_filters, bool filter_files_based_on_heuristics, @@ -400,7 +429,7 @@ return false; // Remove possible carriage return characters before splitting lines. std::string temp_string; - base::RemoveChars(clang_tool_raw_output_, "\r", &temp_string); + base::RemoveChars(extractor_raw_output_, "\r", &temp_string); std::vector<std::string> lines = base::SplitString( temp_string, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); for (unsigned int current = 0; current < lines.size(); current++) {
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h index c95e5f3a..27cbc46 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h
@@ -14,6 +14,12 @@ #include "tools/traffic_annotation/auditor/traffic_annotation_exporter.h" #include "tools/traffic_annotation/traffic_annotation.pb.h" +enum class ExtractorBackend { + CLANG_TOOL, + PYTHON_SCRIPT, + INVALID, +}; + // Holds an item of safe list rules for auditor. struct AuditorException { enum class ExceptionType { @@ -53,23 +59,23 @@ const base::FilePath& clang_tool_path); ~TrafficAnnotationAuditor(); - // Runs traffic_annotation_extractor clang tool and puts its output in - // |clang_tool_raw_output_|. If |filter_files_based_on_heuristics| flag is - // set, the list of files will be received from repository and heuristically - // filtered to only process the relevant files. If |use_compile_commands| flag - // is set, the list of files is extracted from compile_commands.json instead - // of git and will not be filtered. - // If clang tool returns error, and |rerun_on_errors| is true, the tool is run - // again to record errors. - // Errors are written to |errors_file| if it is not empty, otherwise - // LOG(ERROR). - bool RunClangTool(const std::vector<std::string>& path_filters, + // Runs traffic_annotation_extractor clang tool (or extractor.py script) and + // puts its output in |extractor_raw_output_|. If + // |filter_files_based_on_heuristics| flag is set, the list of files will be + // received from repository and heuristically filtered to only process the + // relevant files. If |use_compile_commands| flag is set, the list of files is + // extracted from compile_commands.json instead of git and will not be + // filtered. If clang tool returns error, and |rerun_on_errors| is true, the + // tool is run again to record errors. Errors are written to |errors_file| if + // it is not empty, otherwise LOG(ERROR). + bool RunExtractor(ExtractorBackend backend, + const std::vector<std::string>& path_filters, bool filter_files_based_on_heuristics, bool use_compile_commands, bool rerun_on_errors, const base::FilePath& errors_file); - // Parses the output of clang tool (|clang_tool_raw_output_|) and populates + // Parses the output of clang tool (|extractor_raw_output_|) and populates // |extracted_annotations_|, |extracted_calls_|, and |errors_|. // Errors include not finding the file, incorrect content, or missing or not // provided annotations. @@ -117,10 +123,10 @@ // net/traffic_annotation/network_traffic_annotation_test_helper.h static std::set<int> GetReservedIDsSet(); - std::string clang_tool_raw_output() const { return clang_tool_raw_output_; } + std::string extractor_raw_output() const { return extractor_raw_output_; } - void set_clang_tool_raw_output(const std::string& raw_output) { - clang_tool_raw_output_ = raw_output; + void set_extractor_raw_output(const std::string& raw_output) { + extractor_raw_output_ = raw_output; } const std::vector<AnnotationInstance>& extracted_annotations() const { @@ -168,7 +174,7 @@ TrafficAnnotationExporter exporter_; - std::string clang_tool_raw_output_; + std::string extractor_raw_output_; std::vector<AnnotationInstance> extracted_annotations_; std::vector<CallInstance> extracted_calls_; std::vector<AuditorResult> errors_; @@ -187,7 +193,7 @@ // 3- Path matches an item in |path_filters|. void AddMissingAnnotations(const std::vector<std::string>& path_filters); - // Generates files list to Run clang tool on. Please refer to RunClangTool + // Generates files list to Run clang tool on. Please refer to RunExtractor // function's comment. void GenerateFilesListForClangTool( const std::vector<std::string>& path_filters, @@ -195,6 +201,10 @@ bool use_compile_commands, std::vector<std::string>* file_paths); + // Write flags to the options file, for RunExtractor. + void WriteClangToolOptions(FILE* options_file, bool use_compile_commands); + void WritePythonScriptOptions(FILE* options_file); + base::FilePath gn_file_for_test_; std::map<std::string, bool> checked_dependencies_; };
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc index 5bcc9d0..be06e48 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc
@@ -64,6 +64,10 @@ --error-resilient Optional flag, stating not to return error in exit code if auditor fails to perform the tests. This flag can be used for trybots to avoid spamming when tests cannot run. + --extractor-backend=[clang_tool,python_script] + Optional flag specifying which backend to use for + extracting annotation definitions from source code (Clang + Tool or extractor.py). Defaults to "clang_tool". path_filters Optional paths to filter which files the tool is run on. It can also include deleted files names when auditor is run on a partial repository. @@ -128,6 +132,14 @@ return text; } +ExtractorBackend GetExtractorBackend(const std::string& backend_switch) { + if (backend_switch.empty() || backend_switch == "clang_tool") + return ExtractorBackend::CLANG_TOOL; + if (backend_switch == "python_script") + return ExtractorBackend::PYTHON_SCRIPT; + return ExtractorBackend::INVALID; +} + // TODO(rhalavati): Update this function to extract the policy name and value // directly from the ChromeSettingsProto object (gen/components/policy/proto/ // chrome_settings.proto). Since ChromeSettingsProto has over 300+ @@ -368,7 +380,15 @@ // Extract annotations. if (extractor_input.empty()) { - if (!auditor.RunClangTool(path_filters, filter_files, all_files, + std::string backend_switch = + command_line.GetSwitchValueASCII("extractor-backend"); + ExtractorBackend backend = GetExtractorBackend(backend_switch); + if (backend == ExtractorBackend::INVALID) { + LOG(ERROR) << "Unrecognized extractor backend '" << backend_switch << "'"; + return error_value; + } + + if (!auditor.RunExtractor(backend, path_filters, filter_files, all_files, !error_resilient, errors_file)) { LOG(ERROR) << "Failed to run clang tool."; return error_value; @@ -376,7 +396,7 @@ // Write extractor output if requested. if (!extractor_output.empty()) { - std::string raw_output = auditor.clang_tool_raw_output(); + std::string raw_output = auditor.extractor_raw_output(); base::WriteFile(extractor_output, raw_output.c_str(), raw_output.length()); } @@ -387,7 +407,7 @@ << extractor_input.value().c_str(); return error_value; } else { - auditor.set_clang_tool_raw_output(raw_output); + auditor.set_extractor_raw_output(raw_output); } } @@ -469,4 +489,4 @@ printf("Traffic annotations are all OK.\n"); return static_cast<int>(errors.size()); -} \ No newline at end of file +}
diff --git a/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 b/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 index 3af4147f8..e2ec441b 100644 --- a/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 +++ b/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1
@@ -1 +1 @@ -d9314aa2e3fab7ef7eb3fb38a392b40877cf5826 \ No newline at end of file +198682969f5828ec0081960c973c97b11269b8c1 \ No newline at end of file
diff --git a/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1 b/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1 index 969d5d55..0c16c44 100644 --- a/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1 +++ b/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1
@@ -1 +1 @@ -7164ebdf3c7b5e7d886ba415792493a71924c0a8 \ No newline at end of file +9cfcdb168b14e3d7252207cafb9f5c4794311b6a \ No newline at end of file
diff --git a/tools/traffic_annotation/scripts/annotation_tools.py b/tools/traffic_annotation/scripts/annotation_tools.py index 8180f4d..68d4436 100644 --- a/tools/traffic_annotation/scripts/annotation_tools.py +++ b/tools/traffic_annotation/scripts/annotation_tools.py
@@ -4,6 +4,7 @@ """Tools for annotation test scripts.""" +import json import os import subprocess import sys @@ -66,13 +67,23 @@ return all(os.path.exists( os.path.join(path, item)) for item in ('gen', 'build.ninja')) - def GetCompDBFiles(self): + def GetCompDBFiles(self, generate_compdb): """Gets the list of files. + Args: + generate_compdb: if true, generate a new compdb and write it to + compile_commands.json. + Returns: A set of absolute filepaths, with all compile-able C++ files (based on the compilation database). """ + if generate_compdb: + compile_commands = compile_db.GenerateWithNinja(self.build_path) + compdb_path = os.path.join(self.build_path, 'compile_commands.json') + with open(compdb_path, 'w') as f: + f.write(json.dumps(compile_commands, indent=2)) + compdb = compile_db.Read(self.build_path) return set( os.path.abspath(os.path.join(self.build_path, e['file']))
diff --git a/tools/traffic_annotation/scripts/extractor.py b/tools/traffic_annotation/scripts/extractor.py index 0b2c2f7..df61f493 100755 --- a/tools/traffic_annotation/scripts/extractor.py +++ b/tools/traffic_annotation/scripts/extractor.py
@@ -149,21 +149,30 @@ def main(): - parser = argparse.ArgumentParser( - description="Network Traffic Annotation Extractor.") + parser = argparse.ArgumentParser() + parser.add_argument( + '--options-file', + help='optional file to read options from') + args, argv = parser.parse_known_args() + if args.options_file: + argv = open(args.options_file).read().split() + parser.add_argument( '--build-path', help='Specifies a compiled build directory, e.g. out/Debug.') parser.add_argument( + '--generate-compdb', action='store_true', + help='Generate a new compile_commands.json before running') + parser.add_argument( '--no-filter', action='store_true', help='Do not filter files based on compdb entries') parser.add_argument( 'file_paths', nargs='+', help='List of files to process.') - args = parser.parse_args() + args = parser.parse_args(argv) tools = NetworkTrafficAnnotationTools(args.build_path) - compdb_files = tools.GetCompDBFiles() + compdb_files = tools.GetCompDBFiles(args.generate_compdb) annotation_definitions = []
diff --git a/tools/traffic_annotation/scripts/extractor_test.py b/tools/traffic_annotation/scripts/extractor_test.py index d3c58e4..531ab2b 100755 --- a/tools/traffic_annotation/scripts/extractor_test.py +++ b/tools/traffic_annotation/scripts/extractor_test.py
@@ -27,6 +27,11 @@ return (stdout_file, stderr_file) +def dos2unix(str): + """Convers CRLF to LF.""" + return str.replace('\r\n', '\n') + + def remove_tracebacks(str): """Removes python tracebacks from the string.""" regex = re.compile( @@ -46,12 +51,12 @@ print("Running test on %s..." % source_file) (stdout_file, stderr_file) = get_expected_files(source_file) with open(stdout_file) as f: - expected_stdout = f.read() + expected_stdout = dos2unix(f.read()) with open(stderr_file) as f: - expected_stderr = f.read() + expected_stderr = dos2unix(f.read()) proc = run_extractor(source_file) - (stdout, stderr) = proc.communicate() + (stdout, stderr) = map(dos2unix, proc.communicate()) self.assertEqual(expected_stderr, remove_tracebacks(stderr)) self.assertEqual(int(bool(expected_stderr)), proc.returncode)
diff --git a/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt b/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt index 749d5c2..7d92dcf 100644 --- a/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt +++ b/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt
@@ -1,5 +1,5 @@ ==== NEW ANNOTATION ==== -source_file.cc +valid_file.cc XXX_UNIMPLEMENTED_XXX 14 Definition @@ -25,7 +25,7 @@ comments: "comment1" ==== ANNOTATION ENDS ==== ==== NEW ANNOTATION ==== -source_file.cc +valid_file.cc XXX_UNIMPLEMENTED_XXX 36 Partial @@ -41,7 +41,7 @@ } ==== ANNOTATION ENDS ==== ==== NEW ANNOTATION ==== -source_file.cc +valid_file.cc XXX_UNIMPLEMENTED_XXX 46 Completing @@ -61,7 +61,7 @@ comments: "comment3" ==== ANNOTATION ENDS ==== ==== NEW ANNOTATION ==== -source_file.cc +valid_file.cc XXX_UNIMPLEMENTED_XXX 61 BranchedCompleting
diff --git a/tools/wayland_aux/Makefile b/tools/wayland_aux/Makefile deleted file mode 100644 index 56a9fc7..0000000 --- a/tools/wayland_aux/Makefile +++ /dev/null
@@ -1,31 +0,0 @@ -THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -XDGSHELL := $(THIS_DIR)/../../third_party/wayland-protocols/src/unstable/xdg-shell/xdg-shell-unstable-v6.xml $(wildcard *.py) - -all: x.in.svg x.de.svg l.in.svg l.de.svg fuzz_actions.proto - @echo $(XDG_SHELL) - -fuzz_actions.proto: $(XDGSHELL) - python main.py --spec $< -t proto > $@ - -%.in.svg: %.in.gv - fdp -Tsvg $< -o $@ - -%.de.svg: %.de.gv - dot -Tsvg $< -o $@ - -x.in.gv: $(XDGSHELL) - python main.py --spec $< -t interfaces -x > $@ - -l.in.gv: $(XDGSHELL) - python main.py --spec $< -t interfaces > $@ - -x.de.gv: $(XDGSHELL) - python main.py --spec $< -t deps -x > $@ - -l.de.gv: $(XDGSHELL) - python main.py --spec $< -t deps > $@ - -clean: - rm -f *.svg *.gv - rm -rf __pycache__ - rm -f fuzz_actions.proto
diff --git a/tools/wayland_aux/OWNERS b/tools/wayland_aux/OWNERS deleted file mode 100644 index a86b2ce..0000000 --- a/tools/wayland_aux/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -benwells@chromium.org -hollingum@google.com
diff --git a/tools/wayland_aux/gv_diagram.py b/tools/wayland_aux/gv_diagram.py deleted file mode 100644 index 99cabb1..0000000 --- a/tools/wayland_aux/gv_diagram.py +++ /dev/null
@@ -1,220 +0,0 @@ -# Copyright (c) 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. - -"""Draw wayland protocols with Graphviz. - -Provides a GvPrinter class which is used to output one (or more) wayland -protocols as a graph, showing the relationships between interfaces, their -messages, and how those messages create new interfaces. -""" - -from __future__ import absolute_import -from __future__ import print_function -import protocol_util - - -class GvPrinter(object): - """Base class for printing graphviz graphs. - - The base printer class, has several generic utilities for printing different - graph representations of the protocols. - - Users of this class will call the "draw(protocols)" method to print a - graphviz-syntax graph. - """ - - def __init__(self): - self.nodes = {} - - def force_iface(self, arg): - i_name = arg.attrib.get('interface', 'unknown') - if (i_name, None) not in self.nodes: - self.out('"%s" [label="%s" shape=parallelogram]' % (i_name, i_name)) - self.nodes[(i_name, None)] = i_name - return (i_name, None) - - def out(self, text): - print(text) - - def draw_nodes(self, protocol): - pass - - def draw_edges(self, protocol): - pass - - def draw(self, protocols): - """Draw the graph. - - Args: - protocols: the list of xml.etree.ElementTree.Element protocols which you - want to draw as a graph. See third_party/wayland/src/protocol/ for more - information. - """ - self.out('digraph g {') - self.out('pack=false;') - self.out('start="random";') - self.out('overlap=false;') - self.out('splines=true;') - self.out('graph [rankdir = "LR"];') - for protocol in protocols: - self.draw_nodes(protocol) - for protocol in protocols: - self.draw_edges(protocol) - self.out('}') - - -class InterfacesPrinter(GvPrinter): - """Print protocol interfaces as a graphviz graph. - - A specialization of the graph printer which draws interfaces and their - methods as a class diagram, where edges indicate relationships between the - methods. - """ - - def __init__(self, draw_enums=False): - super(InterfacesPrinter, self).__init__() - self.draw_enums = draw_enums - - def draw_edge(self, src, snk): - for n in [src, snk]: - if n not in self.nodes: - raise Exception('Unable to find node "%s" when drawing (%s, %s)' % - (n, src, snk)) - self.out(self.nodes[src] + ' -> ' + self.nodes[snk] + ' [];') - - def draw_edges(self, protocol): - """Draw edges between interfaces and methods. - - Draws all the edges: - - From an enum to a method that uses that enum as an argument. - - From an interface to a method that uses that interface as an argument. - - From a method to an interface that invoking that method will create. - - Args: - protocol: a wayland <protocol> as an xml.etree.ElementTree.Element. - """ - for interface in protocol.findall('interface'): - i_name = interface.attrib['name'] - for message in protocol_util.grab_interface_messages(interface): - m_name = message.attrib['name'] - for arg in message.findall('arg'): - if self.draw_enums and 'enum' in arg.attrib: - self.draw_edge((i_name, arg.attrib['enum']), (i_name, m_name)) - continue - ty = arg.attrib['type'] - if ty == 'new_id': - self.draw_edge((i_name, m_name), self.force_iface(arg)) - elif ty == 'object': - self.draw_edge(self.force_iface(arg), (i_name, m_name)) - - def draw_nodes(self, protocol): - """Draw record nodes for each interface. - - Draws a record-style node for each interface. The header is the interface - name and each subsequent entry is an event or request which that interface - defines. - - As a side-effect, this method populates the |nodes| map. - - Args: - protocol: a wayland <protocol> as an xml.etree.ElementTree.Element. - """ - for interface in protocol.findall('interface'): - i_name = interface.attrib['name'] - i_label = '<i>'+i_name - if self.draw_enums: - for enum in interface.findall('enum'): - e_name = enum.attrib['name'] - node_name = i_name + '_' + e_name - fields = [ - e.attrib['name'] + ' = ' + e.attrib['value'] - for e in enum.findall('entry') - ] - self.out('"%s" [label="%s" shape=record]' % - (node_name, '|'.join(['<e>'+e_name]+fields))) - self.nodes[(i_name, e_name)] = node_name+':e' - for count, message in enumerate( - protocol_util.grab_interface_messages(interface)): - m_name = message.attrib['name'] - is_request = message.tag == 'request' - m_label = ('<m%d>'%count) + (m_name + ' -\\>' if is_request - else '-\\> ' + m_name) - i_label += '|' + m_label - self.nodes[(i_name, m_name)] = i_name + (':m%d'%count) - self.out('"%s" [label="%s" shape=record]' % (i_name, i_label)) - self.nodes[(i_name, None)] = i_name+':i' - - -class DepsPrinter(GvPrinter): - """Print message dependencies as a graphviz graph. - - A specialization of the graph printer for showind dependencies between - methods. Nodes in this graph are either interfaces or methods, and edges - indicate a relationship of "defines" (when the interface is the method's - 'this' object), "uses" (when the interface is an argument), or "creates" - (when the result of the call is the creation of an object). - """ - - def __init__(self, draw_all=False): - super(DepsPrinter, self).__init__() - self.draw_all = draw_all - - def should_draw_message(self, message): - return self.draw_all or protocol_util.is_constructor(message) - - def draw_nodes(self, protocol): - """Draws a node for each message/interface. - - Draws a node for every interface and all of its methods. As a side effect, - calling this method will populate the |nodes| map. - - Args: - protocol: a wayland <protocol> as an xml.etree.ElementTree.Element. - """ - self.nodes[(None, None)] = '_unknown_' - self.out('"_unknown_" [label="?" shape=diamond]') - for i in protocol.findall('interface'): - i_name = i.attrib['name'] - self.nodes[(i_name, None)] = i_name - self.out('"%s" [shape=box]' % (i_name)) - for m in protocol_util.grab_interface_messages(i): - if self.should_draw_message(m): - m_name = m.attrib['name'] - m_node = i_name + ':' + m_name - m_shape = 'hexagon' if m.tag == 'event' else 'ellipse' - self.nodes[(i_name, m_name)] = m_node - self.out('"%s" [label="%s" shape=%s]' % - (m_node, m_name, m_shape)) - - def get_obj(self, arg): - if 'interface' in arg.attrib: - return self.nodes[self.force_iface(arg)] - return self.nodes[(None, None)] - - def draw_edges(self, protocol): - """Draw edges showing message arguments. - - Draws edges showing the relationship between the messages and the - interfaces. Bold edges signify "defines" or "creates" relationships, while - dotted edges signify "uses" relationships. - - Args: - protocol: a wayland <protocol> as an xml.etree.ElementTree.Element. - """ - for i in protocol.findall('interface'): - i_name = i.attrib['name'] - for m in protocol_util.grab_interface_messages(i): - if self.should_draw_message(m): - m_name = m.attrib['name'] - self.out('"%s" -> "%s" [style=bold]' % - (self.nodes[(i_name, None)], self.nodes[(i_name, m_name)])) - for pa in m.findall('arg'): - if pa.attrib['type'] == 'object': - self.out('"%s" -> "%s" [style=dotted]' % - (self.get_obj(pa), self.nodes[(i_name, m_name)])) - for pa in m.findall('arg'): - if pa.attrib['type'] == 'new_id': - self.out('"%s" -> "%s" [style=bold]' % - (self.nodes[(i_name, m_name)], self.get_obj(pa))) -
diff --git a/tools/wayland_aux/main.py b/tools/wayland_aux/main.py deleted file mode 100644 index 70aebc1..0000000 --- a/tools/wayland_aux/main.py +++ /dev/null
@@ -1,67 +0,0 @@ -# Copyright (c) 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. - -"""Process wayland specifications. - -Various functions for converting/processing/understanding wayland protocols. -""" - -from __future__ import absolute_import -import argparse -import sys -import xml.etree.ElementTree as xml -import gv_diagram -import proto_gen - - -def strip_protocol(protocol): - for desc in protocol.findall('description'): - protocol.remove(desc) - for copy in protocol.findall('copyright'): - protocol.remove(copy) - if 'summary' in protocol.attrib: - protocol.attrib.pop('summary') - for c in protocol.getchildren(): - strip_protocol(c) - return protocol - - -def dump_protocol(protocol): - xml.dump(protocol) - - -def read_protocol(path): - return xml.parse(path).getroot() - - -def main(argv): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('-s', '--spec', - help='path(s) to the wayland specification(s)', - nargs='+', required=True) - parser.add_argument('-t', '--type', - help='Output different types of graph', - choices=['interfaces', 'deps', - 'harness', 'proto'], required=True) - parser.add_argument('-x', '--extra', - help='add extra detail to the normal printout', - action='store_true') - - parsed = parser.parse_args(argv[1:]) - protocols = [strip_protocol(read_protocol(path)) for path in parsed.spec] - extra = parsed.extra - if parsed.type == 'deps': - gv_diagram.DepsPrinter(extra).draw(protocols) - elif parsed.type == 'interfaces': - gv_diagram.InterfacesPrinter(extra).draw(protocols) - elif parsed.type == 'harness': - pass - elif parsed.type == 'proto': - proto_gen.generate(protocols) - else: - raise Exception('%s not implemented' % parsed.type) - - -if __name__ == '__main__': - main(sys.argv)
diff --git a/tools/wayland_aux/proto_gen.py b/tools/wayland_aux/proto_gen.py deleted file mode 100644 index 1fddc628..0000000 --- a/tools/wayland_aux/proto_gen.py +++ /dev/null
@@ -1,121 +0,0 @@ -# Copyright (c) 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. - -"""Generates a protobuf for fuzzing purposes. - -Use the generate() function to print a protobuf file, which allows libfuzzer to -fuzz the given protocols.. -""" - -from __future__ import absolute_import -from __future__ import print_function -import protocol_util - - -class Generator(object): - """Base class for generating something from a list of protocols. - - Provides several utilities for generating files of things from a list of - protocols. - """ - - def out(self, text): - print(text) - - def generate(self, protocols): - pass - - -proto_type_conversions = { - 'object': 'uint32', - 'int': 'int32', - 'uint': 'uint32', - 'string': 'string', - 'fd': 'uint32', -} - - -class ProtoGenerator(Generator): - """Generate a libfuzzable protobuf. - - Creates a protobuf for use when fuzzing wayland. This protobuf defines all the - client-side messages which the fuzzer might call. - """ - - def named(self, *args): - return '_'.join((e.attrib['name'] for e in args)) - - def get_type(self, ty): - if ty in proto_type_conversions: - return proto_type_conversions[ty] - raise Exception('unknown conversion for type: ' + ty) - - def generate_action(self, name, args): - self.out('message %s {' % name) - for (idx, (a_type, a_name)) in enumerate([('uint32', 'receiver')] + args): - self.out('required %s %s = %d;'%(a_type, a_name, idx+1)) - self.out('}') - - def generate_req_action(self, ptc, ifc, msg): - """Generate an action protobuf message. - - Args: - ptc: the <protocol> xml element. - ifc: the <interface> xml element. - msg: the <request> xml element (given that <event>s don't need messages). - """ - args = [] - name = self.named(ptc, ifc, msg) - if name == 'wayland_wl_registry_bind': - args = [('global', 'global'), ('uint32', 'name'), ('uint32', 'version')] - else: - args = [(self.get_type(arg.attrib['type']), arg.attrib['name']) - for arg in msg.findall('arg') - if arg.attrib['type'] != 'new_id'] - if protocol_util.is_constructor(msg): - c_type = protocol_util.get_constructed(msg) - self.out('// Constructs %s' % (c_type if c_type else '???')) - self.generate_action(name, args) - - def generate(self, protocols): - self.out('syntax = "proto2";') - self.out('package = exo.wayland_fuzzer;') - - # Make the globals enum for identifying globals to bind. - self.out('enum global {') - self.out('GLOBAL_UNSPECIFIED=0;') - for (idx, (pro, ifc)) in enumerate(protocol_util.get_globals(protocols)): - self.out('%s = %d;'%(self.named(pro, ifc), idx+1)) - self.out('}') - - # List all the possible actions. - self.out('message actions {') - self.out('repeated action acts = 1;') - self.out('}') - self.out('message action {') - self.out('oneof act {') - actions = ['meta_dispatch', 'meta_roundtrip'] + [ - self.named(p, i, m) - for (p, i, m) in protocol_util.all_messages(protocols) - if protocol_util.is_request(m)] - for (idx, act) in enumerate(actions): - self.out('%s act_%s = %d;' % (act, act, idx+1)) - self.out('}') - self.out('}') - self.generate_action('meta_dispatch', []) - self.generate_action('meta_roundtrip', []) - for (p, i, m) in protocol_util.all_messages(protocols): - if protocol_util.is_request(m): - self.generate_req_action(p, i, m) - - -def generate(protocols): - """Make a protobuf for fuzzing the |protocols|. - - Args: - protocols: a list of xml.etree.ElementTree.Element where each element is a - wayland <protocol> node. This list will be converted to a protobuf file - that can be used for fuzzing. - """ - ProtoGenerator().generate(protocols)
diff --git a/tools/wayland_aux/protocol_util.py b/tools/wayland_aux/protocol_util.py deleted file mode 100644 index 59d886e..0000000 --- a/tools/wayland_aux/protocol_util.py +++ /dev/null
@@ -1,124 +0,0 @@ -# Copyright (c) 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. - -"""Misc utils. - -Misc utils for interpreting protocols. -""" - -from __future__ import absolute_import - - -def grab_interface_messages(interface): - """Get the events+requests in this interface. - - Args: - interface: the interface which you want the messages of. - - Yields: - All the events followed by all the requests. - """ - for e in interface.findall('event'): - yield e - for r in interface.findall('request'): - yield r - - -def is_event(message): - return message.tag == 'event' - - -def is_request(message): - return message.tag == 'request' - - -def is_constructor(message): - """Check if a message is a constructor. - - Args: - message: the message which you want to check. - - Returns: - True if the message constructs an object (via new_id), False otherwise. - """ - return any(['type' in arg.attrib and arg.attrib['type'] == 'new_id' - for arg in message.findall('arg')]) - - -def is_destructor(message): - """Check if a message is a destructor. - - Args: - message: the message which you want to check. - - Returns: - True if the message destroys its "this" object (i.e. it has a - type=destructor attribute). - """ - return 'type' in message.attrib and message.attrib['type'] == 'destructor' - - -def all_interfaces(protocols): - """Get the interfaces in these protocols. - - Args: - protocols: the list of protocols you want the interfaces of. - - Yields: - Tuples (p, i) of (p)rotocol (i)nterface. - """ - for p in protocols: - for i in p.findall('interface'): - yield (p, i) - - -def all_messages(protocols): - """Get the messages in these protocols. - - Args: - protocols: the list of protocols you want the messages of. - - Yields: - Tuples (p, i, m) of (p)rotocol, (i)nterface, and (m)essage. - """ - for (p, i) in all_interfaces(protocols): - for m in grab_interface_messages(i): - yield (p, i, m) - - -def get_constructed(message): - """Gets the interface constructed by a message. - - Note that even if is_constructor(message) returns true, get_constructed can - still return None when the message constructs an unknown interface (e.g. - wl_registry.bind()). - - Args: - message: the message which may be a constructor. - - Returns: - The name of the constructed interface (if there is one), or None. - """ - for arg in message.findall('arg'): - if 'type' in arg.attrib and arg.attrib['type'] == 'new_id': - return arg.attrib.get('interface', None) - return None - - -def get_globals(protocols): - """List all of the global interfaces (i.e. those without a constructor). - - Args: - protocols: the list of protocols you want the globals for. - - Yields: - Tuples (p, i) of (p)rotocol, (i)nterface, where the interface is a global. - """ - non_globals = set(get_constructed(m) - for (p, i, m) in all_messages(protocols) - if get_constructed(m)) - for (p, i) in all_interfaces(protocols): - if i.attrib['name'] not in non_globals: - yield (p, i) -
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java index 46236e40..b696a18 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java
@@ -16,25 +16,25 @@ /** * Called when a resource as finished loading. Note that it is up to the caller to recycle * any {@link android.graphics.Bitmap}s or clean up any state after making this call. - * @param resType The {@link ResourceType} that loaded the resource. + * @param resType The {@link AndroidResourceType} that loaded the resource. * @param resId The Android id of the loaded resource. * @param resource The {@link Resource} of the resource, or {@code null} if one could * not be loaded. */ - void onResourceLoaded(int resType, int resId, Resource resource); + void onResourceLoaded(@AndroidResourceType int resType, int resId, Resource resource); /** * Called when a resource is unregistered (unneeded). This should only be called for - * dynamic bitmap resources since they change constantly and are replaced with new bitmaps. - * Other resource types should not need this since thay are static for the lifetime of the + * dynamic resources. Dynamic bitmap change constantly and are replaced with new bitmaps. + * Other resource types should not need this since they are static for the lifetime of the * application. - * @param resType The {@link ResourceType} of resource that was removed. - * @param redId The Android id of the removed resource. + * @param resType The {@link AndroidResourceType} of resource that was removed. + * @param resId The Android id of the removed resource. */ - void onResourceUnregistered(int resType, int resId); + void onResourceUnregistered(@AndroidResourceType int resType, int resId); } - private final int mResourceType; + private final @AndroidResourceType int mResourceType; private final ResourceLoaderCallback mCallback; /** @@ -51,7 +51,7 @@ /** * @return What resource type this {@link ResourceLoader} is responsible for loading. */ - public int getResourceType() { + public @AndroidResourceType int getResourceType() { return mResourceType; }
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java index 01f41b4..8c6a902 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java
@@ -122,14 +122,14 @@ * @param resId The id of the Android resource. * @return The corresponding {@link LayoutResource}. */ - public LayoutResource getResource(int resType, int resId) { + public LayoutResource getResource(@AndroidResourceType int resType, int resId) { SparseArray<LayoutResource> bucket = mLoadedResources.get(resType); return bucket != null ? bucket.get(resId) : null; } @SuppressWarnings("cast") @Override - public void onResourceLoaded(int resType, int resId, Resource resource) { + public void onResourceLoaded(@AndroidResourceType int resType, int resId, Resource resource) { if (resource == null) return; Bitmap bitmap = resource.getBitmap(); if (bitmap == null) return; @@ -144,9 +144,10 @@ } @Override - public void onResourceUnregistered(int resType, int resId) { - // Only remove dynamic bitmaps that were unregistered. - if (resType != AndroidResourceType.DYNAMIC_BITMAP) return; + public void onResourceUnregistered(@AndroidResourceType int resType, int resId) { + // Only remove dynamic resources that were unregistered. + if (resType != AndroidResourceType.DYNAMIC_BITMAP && resType != AndroidResourceType.DYNAMIC) + return; nativeRemoveResource(mNativeResourceManagerPtr, resType, resId); } @@ -159,7 +160,8 @@ nativeClearTintedResourceCache(mNativeResourceManagerPtr); } - private void saveMetadataForLoadedResource(int resType, int resId, Resource resource) { + private void saveMetadataForLoadedResource( + @AndroidResourceType int resType, int resId, Resource resource) { SparseArray<LayoutResource> bucket = mLoadedResources.get(resType); if (bucket == null) { bucket = new SparseArray<LayoutResource>();
diff --git a/ui/events/cocoa/cocoa_event_utils.h b/ui/events/cocoa/cocoa_event_utils.h index b1ba7801..f447342 100644 --- a/ui/events/cocoa/cocoa_event_utils.h +++ b/ui/events/cocoa/cocoa_event_utils.h
@@ -7,6 +7,8 @@ #import <Cocoa/Cocoa.h> +#include <vector> + #include "ui/events/events_export.h" namespace ui { @@ -29,6 +31,13 @@ // released. EVENTS_EXPORT bool IsKeyUpEvent(NSEvent* event); +// Convert an NSEvent to an opaque serialization using CGEventCreateData. +EVENTS_EXPORT std::vector<uint8_t> EventToData(NSEvent* event); + +// Create an NSEvent from an opaque serialization using CGEventCreateFromData. +// The result is autoreleased. +EVENTS_EXPORT NSEvent* EventFromData(const std::vector<uint8_t>& data); + } // namespace ui #endif // UI_EVENTS_COCOA_COCOA_EVENT_UTILS_H_
diff --git a/ui/events/cocoa/cocoa_event_utils.mm b/ui/events/cocoa/cocoa_event_utils.mm index e540e0fa..1ba23d8 100644 --- a/ui/events/cocoa/cocoa_event_utils.mm +++ b/ui/events/cocoa/cocoa_event_utils.mm
@@ -4,6 +4,7 @@ #import "ui/events/cocoa/cocoa_event_utils.h" +#include "base/mac/scoped_cftyperef.h" #include "ui/events/event_constants.h" #include "ui/events/event_utils.h" @@ -133,4 +134,20 @@ return false; } +std::vector<uint8_t> EventToData(NSEvent* event) { + base::ScopedCFTypeRef<CFDataRef> cf_data( + CGEventCreateData(nullptr, [event CGEvent])); + const uint8_t* cf_data_ptr = CFDataGetBytePtr(cf_data.get()); + size_t cf_data_size = CFDataGetLength(cf_data.get()); + return std::vector<uint8_t>(cf_data_ptr, cf_data_ptr + cf_data_size); +} + +NSEvent* EventFromData(const std::vector<uint8_t>& data) { + base::ScopedCFTypeRef<CFDataRef> cf_data( + CFDataCreate(nullptr, data.data(), data.size())); + base::ScopedCFTypeRef<CGEventRef> cg_event( + CGEventCreateFromData(nullptr, cf_data.get())); + return [NSEvent eventWithCGEvent:cg_event.get()]; +} + } // namespace ui
diff --git a/ui/file_manager/file_manager/foreground/elements/xf_activity_complete.js b/ui/file_manager/file_manager/foreground/elements/xf_activity_complete.js index 240229f9..a1c72d2 100644 --- a/ui/file_manager/file_manager/foreground/elements/xf_activity_complete.js +++ b/ui/file_manager/file_manager/foreground/elements/xf_activity_complete.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. /** - * Activity complete indicator custom element for use in PanelEntry(s). + * Activity complete indicator custom element for use in PanelItem(s). */ class ActivityComplete extends HTMLElement { constructor() { @@ -42,8 +42,8 @@ /** * Registers this instance to listen to these attribute changes. + * @return {!Array<string>} * @private - * @return {Array<String>} */ static get observedAttributes() { return ['status']; @@ -52,8 +52,8 @@ /** * Callback triggered by the browser when our attribute values change. * @param {string} name Attribute that's changed. - * @param {string} oldValue Old value of the attribute. - * @param {string} newValue New value of the attribute. + * @param {?string} oldValue Old value of the attribute. + * @param {?string} newValue New value of the attribute. * @private */ attributeChangedCallback(name, oldValue, newValue) {
diff --git a/ui/file_manager/file_manager/foreground/elements/xf_display_panel.js b/ui/file_manager/file_manager/foreground/elements/xf_display_panel.js index 6f676620..26dc5cb 100644 --- a/ui/file_manager/file_manager/foreground/elements/xf_display_panel.js +++ b/ui/file_manager/file_manager/foreground/elements/xf_display_panel.js
@@ -3,17 +3,20 @@ // found in the LICENSE file. /** - * A panel to display a collection (or list) of PanelItem. + * A panel to display a collection of PanelItem. */ class DisplayPanel extends HTMLElement { constructor() { - super(); - const host = document.createElement('template'); - host.innerHTML = this.constructor.template_; - this.attachShadow({mode: 'open'}).appendChild(host.content.cloneNode(true)); + DisplayPanel.createElement_.call(super()); - /** @private {Element} */ - this.container_ = this.shadowRoot.querySelector('#container'); + /** @private {!HTMLElement} */ + this.summary_ = this.shadowRoot.querySelector('#summary'); + + /** @private {!HTMLElement} */ + this.separator_ = this.shadowRoot.querySelector('#separator'); + + /** @private {!HTMLElement} */ + this.panels_ = this.shadowRoot.querySelector('#panels'); /** * True if the panel is not visible. @@ -23,25 +26,36 @@ this.hidden_ = true; /** - * True if the panel been collapsed into summary view. + * True if the panel is collapsed to summary view. * @type {boolean} * @private */ this.collapsed_ = false; /** - * PanelItems that are being hosted in the UI. - * @type {Array<PanelItem>} + * Collection of PanelItems hosted in this DisplayPanel. + * @type {!Array<PanelItem>} * @private */ this.items_ = []; } /** - * Static getter for the custom element template. + * Creates an instance of DisplayPanel, attaching the template clone. * @private */ - static get template_() { + static createElement_() { + const template = document.createElement('template'); + template.innerHTML = DisplayPanel.html_(); + const fragment = template.content.cloneNode(true); + this.attachShadow({mode: 'open'}).appendChild(fragment); + } + + /** + * Get the custom element template string. + * @private + */ + static html_() { return `<style> #container { align-items: stretch; @@ -55,21 +69,126 @@ max-width: min-content; z-index: 100; } + #separator { + background-color: rgba(60, 64, 67, 0.15); + height: 1px; + } + #panels { + max-height: 204px; + overflow-y: auto; + } </style> - <div id="container"></div>`; + <div id="container"> + <div id="summary"></div> + <div id="separator" hidden></div> + <div id="panels"></div> + </div>`; + } + + /** + * Event handler to toggle the visible state of panel items. + * @private + */ + toggleSummary(event) { + const panel = event.target.parent; + const summaryPanel = panel.summary_.querySelector('xf-panel-item'); + const expandButton = + summaryPanel.shadowRoot.querySelector('#primary-action'); + if (panel.collapsed_) { + panel.collapsed_ = false; + expandButton.setAttribute('data-category', 'collapse'); + panel.panels_.hidden = false; + panel.separator_.hidden = false; + } else { + panel.collapsed_ = true; + expandButton.setAttribute('data-category', 'expand'); + panel.panels_.hidden = true; + panel.separator_.hidden = true; + } + } + + /** + * Update the summary panel item progress indicator. + * @private + */ + updateProgress() { + let total = 0; + + if (this.items_.length == 0) { + return; + } + for (let i = 0; i < this.items_.length; ++i) { + total += Number(this.items_[i].progress); + } + total /= this.items_.length; + const summaryPanel = this.summary_.querySelector('xf-panel-item'); + if (summaryPanel) { + // TODO(crbug.com/947388) i18n this string (add setter). + summaryPanel.primaryText = total.toFixed(0) + '% complete'; + summaryPanel.progress = total; + } + } + + /** + * Update the summary panel. + * @private + */ + updateSummaryPanel() { + let summaryHost = this.shadowRoot.querySelector('#summary'); + let summaryPanel = summaryHost.querySelector('#summary-panel'); + + // If there's only one panel item active, no need for summary. + if (this.items_.length <= 1 && summaryPanel) { + const button = summaryPanel.primaryButton; + if (button) { + button.removeEventListener('click', this.toggleSummary); + } + summaryPanel.remove(); + return; + } + // Show summary panel if there are more than 1 progress panels. + let count = 0; + for (let i = 0; i < this.items_.length; ++i) { + if (this.items_[i].panelType == this.items_[i].panelTypeProgress) { + count++; + } + } + if (count > 1 && !summaryPanel) { + summaryPanel = document.createElement('xf-panel-item'); + summaryPanel.setAttribute('panel-type', 1); + summaryPanel.id = 'summary-panel'; + const button = summaryPanel.primaryButton; + if (button) { + button.parent = this; + button.addEventListener('click', this.toggleSummary); + } + summaryHost.appendChild(summaryPanel); + this.panels_.hidden = true; + this.collapsed_ = true; + } + if (summaryPanel) { + summaryPanel.setAttribute('count', count); + this.updateProgress(); + } } /** * Add a panel entry element inside our display panel. + * @param {string} id The identifier attached to this panel. * @return {PanelItem} * @public */ - addPanelItem() { + addPanelItem(id) { const panel = document.createElement('xf-panel-item'); + panel.id = id; + // Set the containing parent so the child panel can + // trigger updates in the parent (e.g. progress summary %). + panel.parent = this; panel.setAttribute('indicator', 'progress'); - this.container_.appendChild(panel); - this.items_.push(panel); - return panel; + this.panels_.appendChild(panel); + this.items_.push(/** @type {!PanelItem} */ (panel)); + this.updateSummaryPanel(); + return /** @type {!PanelItem} */ (panel); } /** @@ -78,12 +197,22 @@ * @public */ removePanelItem(item) { - const pos = this.items_.indexOf(item); - if (pos === -1) { + const index = this.items_.indexOf(item); + if (index === -1) { return; } item.remove(); - this.items_.splice(pos, 1); + this.items_.splice(index, 1); + this.updateSummaryPanel(); + } + + /** + * Find a panel with given 'id'. + * @private + */ + findPanelItemById(id) { + const panel = this.shadowRoot.querySelector('xf-panel-item[id=' + id + ']'); + return panel || null; } }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js index 0f90659..379bcbd9 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -1043,13 +1043,6 @@ * @private */ updateDate_(div, entry) { - // For now, Team Drive roots have the incorrect modified date value. Hide it - // until we get the proper one (see https://crbug.com/861622). - if (util.isTeamDriveRoot(entry)) { - div.textContent = '--'; - return; - } - const item = this.metadataModel_.getCache( [entry], ['modificationTime', 'modificationByMeTime'])[0]; const modTime = this.useModificationByMeTime_ ?
diff --git a/ui/gfx/client_native_pixmap_factory.h b/ui/gfx/client_native_pixmap_factory.h index a1b644f..566590a 100644 --- a/ui/gfx/client_native_pixmap_factory.h +++ b/ui/gfx/client_native_pixmap_factory.h
@@ -30,6 +30,7 @@ virtual std::unique_ptr<ClientNativePixmap> ImportFromHandle( gfx::NativePixmapHandle handle, const gfx::Size& size, + gfx::BufferFormat format, gfx::BufferUsage usage) = 0; };
diff --git a/ui/gfx/font_fallback_win_unittest.cc b/ui/gfx/font_fallback_win_unittest.cc index 0066035..a00f6c8c 100644 --- a/ui/gfx/font_fallback_win_unittest.cc +++ b/ui/gfx/font_fallback_win_unittest.cc
@@ -353,6 +353,7 @@ FallbackFontTestCase kGetFontFallbackTests[] = { {USCRIPT_ARABIC, L"\u062A\u062D", {"Segoe UI", "Tahoma"}}, {USCRIPT_ARMENIAN, L"\u0540\u0541", {"Segoe UI", "Tahoma"}}, + {USCRIPT_BENGALI, L"\u09B8\u09AE", {"Nirmala UI", "Vrinda"}}, {USCRIPT_BRAILLE, L"\u2870\u2871", {"Segoe UI Symbol"}}, {USCRIPT_BUGINESE, L"\u1A00\u1A01", {"Leelawadee UI"}, kWin10Only}, {USCRIPT_CANADIAN_ABORIGINAL, L"\u1410\u1411", {"Gadugi", "Euphemia"}}, @@ -379,12 +380,20 @@ {"Segoe UI Historic"}, kWin10Only}, + {USCRIPT_CYRILLIC, L"\u0410\u0411\u0412", {"Times New Roman"}}, + {USCRIPT_DESERET, L"\U00010400\U00010401", {"Segoe UI Symbol"}, kWin10Only}, {USCRIPT_DEVANAGARI, L"\u0905\u0906", {"Mangal", "Nirmala UI"}}, {USCRIPT_ETHIOPIC, L"\u1201\u1202", {"Ebrima", "Nyala"}}, + {USCRIPT_GEORGIAN, L"\u10A0\u10A1", {"Sylfaen", "Segoe UI"}, kWin10Only}, + {USCRIPT_GREEK, L"\u0391\u0392", {"Times New Roman"}}, {USCRIPT_GURMUKHI, L"\u0A21\u0A22", {"Raavi", "Nirmala UI"}}, + {USCRIPT_HANGUL, L"\u1100\u1101", {"Malgun Gothic", "Gulim"}, kWin10Only}, {USCRIPT_HEBREW, L"\u05D1\u05D2", {"Segoe UI", "Tahoma"}}, + {USCRIPT_KHMER, + L"\u1780\u1781", + {"Leelawadee UI", "Khmer UI", "Khmer OS", "MoolBoran", "DaunPenh"}}, {USCRIPT_IMPERIAL_ARAMAIC, L"\U00010841\U00010842", @@ -474,6 +483,10 @@ {USCRIPT_TAMIL, L"\u0BB1\u0BB2", {"Latha", "Nirmala UI"}}, {USCRIPT_TELUGU, L"\u0C21\u0C22", {"Gautami", "Nirmala UI"}}, {USCRIPT_THAANA, L"\u0781\u0782", {"Mv Boli", "MV Boli"}}, + {USCRIPT_THAI, + L"\u0e01\u0e02", + {"Tahoma", "Leelawadee UI", "Leelawadee"}, + kWin10Only}, {USCRIPT_TIBETAN, L"\u0F01\u0F02", {"Microsoft Himalaya"}}, {USCRIPT_TIFINAGH, L"\u2D31\u2D32", {"Ebrima"}}, {USCRIPT_VAI, L"\uA501\uA502", {"Ebrima"}},
diff --git a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc index 83eba31..652c23d 100644 --- a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc +++ b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc
@@ -51,6 +51,7 @@ std::unique_ptr<ClientNativePixmap> ImportFromHandle( gfx::NativePixmapHandle handle, const gfx::Size& size, + gfx::BufferFormat format, gfx::BufferUsage usage) override { DCHECK(!handle.planes.empty()); switch (usage) {
diff --git a/ui/ozone/common/stub_client_native_pixmap_factory.cc b/ui/ozone/common/stub_client_native_pixmap_factory.cc index 0754a60..737e9cdc 100644 --- a/ui/ozone/common/stub_client_native_pixmap_factory.cc +++ b/ui/ozone/common/stub_client_native_pixmap_factory.cc
@@ -21,6 +21,7 @@ std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( gfx::NativePixmapHandle handle, const gfx::Size& size, + gfx::BufferFormat format, gfx::BufferUsage usage) override { NOTREACHED(); return nullptr;
diff --git a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc index 309eed8..d78a2fe 100644 --- a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc +++ b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
@@ -40,7 +40,7 @@ if (usage == gfx::BufferUsage::GPU_READ_CPU_READ_WRITE || usage == gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE) { auto client_pixmap = client_native_pixmap_factory_->ImportFromHandle( - pixmap->ExportHandle(), size, usage); + pixmap->ExportHandle(), size, format, usage); bool mapped = client_pixmap->Map(); EXPECT_TRUE(mapped);
diff --git a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc index 0a1a672..f957a36 100644 --- a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc +++ b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
@@ -42,6 +42,7 @@ std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( gfx::NativePixmapHandle handle, const gfx::Size& size, + gfx::BufferFormat format, gfx::BufferUsage usage) override { return std::make_unique<ClientNativePixmapCast>(); }
diff --git a/ui/ozone/platform/scenic/client_native_pixmap_factory_scenic.cc b/ui/ozone/platform/scenic/client_native_pixmap_factory_scenic.cc index be96f8f..392670e 100644 --- a/ui/ozone/platform/scenic/client_native_pixmap_factory_scenic.cc +++ b/ui/ozone/platform/scenic/client_native_pixmap_factory_scenic.cc
@@ -99,6 +99,7 @@ std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( gfx::NativePixmapHandle handle, const gfx::Size& size, + gfx::BufferFormat format, gfx::BufferUsage usage) override { if (handle.planes.empty()) return nullptr;
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm index 99d591f..143cb56 100644 --- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm +++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -23,6 +23,7 @@ #include "ui/base/ime/input_method.h" #include "ui/compositor/recyclable_compositor_mac.h" #include "ui/display/screen.h" +#include "ui/events/cocoa/cocoa_event_utils.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/mac/coordinate_conversion.h" #include "ui/native_theme/native_theme_mac.h" @@ -646,11 +647,7 @@ // If the target window is out of process then always report the event as // handled (because it should never be handled in this process). - GetNSWindowMojo()->RedispatchKeyEvent( - [event type], [event modifierFlags], [event timestamp], - base::SysNSStringToUTF16([event characters]), - base::SysNSStringToUTF16([event charactersIgnoringModifiers]), - [event keyCode]); + GetNSWindowMojo()->RedispatchKeyEvent(ui::EventToData(event)); return true; }
diff --git a/ui/views/controls/menu/menu_image_util.cc b/ui/views/controls/menu/menu_image_util.cc index d1cc32b..8067390 100644 --- a/ui/views/controls/menu/menu_image_util.cc +++ b/ui/views/controls/menu/menu_image_util.cc
@@ -15,16 +15,6 @@ return gfx::CreateVectorIcon(kMenuCheckIcon, icon_color); } -gfx::ImageSkia GetRadioButtonImage(bool toggled, - bool hovered, - SkColor default_icon_color) { - const gfx::VectorIcon& icon = - toggled ? kMenuRadioSelectedIcon : kMenuRadioEmptyIcon; - SkColor color = - toggled && !hovered ? gfx::kGoogleBlue500 : default_icon_color; - return gfx::CreateVectorIcon(icon, kMenuCheckSize, color); -} - gfx::ImageSkia GetSubmenuArrowImage(SkColor icon_color) { return gfx::CreateVectorIcon(kSubmenuArrowIcon, icon_color); }
diff --git a/ui/views/controls/menu/menu_image_util.h b/ui/views/controls/menu/menu_image_util.h index bda8226..10713e0 100644 --- a/ui/views/controls/menu/menu_image_util.h +++ b/ui/views/controls/menu/menu_image_util.h
@@ -17,14 +17,6 @@ // Returns the Menu Check box image (always checked). gfx::ImageSkia GetMenuCheckImage(SkColor icon_color); -// Return the RadioButton image for given state. |toggled| is true when -// the radio option is active, |hovered| describes the menu higlight/selection -// state, and |default_icon_color| is the base color that should be used for -// the icon (which may be ignored based on the other two flags). -gfx::ImageSkia GetRadioButtonImage(bool toggled, - bool hovered, - SkColor default_icon_color); - // Returns the image for submenu arrow for current RTL setting. gfx::ImageSkia GetSubmenuArrowImage(SkColor icon_color);
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index abb9d1a..c8a32b58 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -40,6 +40,7 @@ #include "ui/views/controls/menu/menu_separator.h" #include "ui/views/controls/menu/submenu_view.h" #include "ui/views/controls/separator.h" +#include "ui/views/vector_icons.h" #include "ui/views/view_class_properties.h" #include "ui/views/widget/widget.h" @@ -974,8 +975,14 @@ if (type_ == CHECKBOX && delegate->IsItemChecked(GetCommand())) { radio_check_image_view_->SetImage(GetMenuCheckImage(icon_color)); } else if (type_ == RADIO) { - radio_check_image_view_->SetImage(GetRadioButtonImage( - delegate->IsItemChecked(GetCommand()), render_selection, icon_color)); + const bool toggled = delegate->IsItemChecked(GetCommand()); + const gfx::VectorIcon& radio_icon = + toggled ? kMenuRadioSelectedIcon : kMenuRadioEmptyIcon; + const SkColor radio_icon_color = GetNativeTheme()->GetSystemColor( + toggled ? ui::NativeTheme::kColorId_ProminentButtonColor + : ui::NativeTheme::kColorId_ButtonEnabledColor); + radio_check_image_view_->SetImage( + gfx::CreateVectorIcon(radio_icon, kMenuCheckSize, radio_icon_color)); } // Render the foreground.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index 81ef3828..7330742 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -4,8 +4,13 @@ #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" +#include <algorithm> +#include <list> #include <memory> +#include <set> +#include <string> #include <utility> +#include <vector> #include "base/bind.h" #include "base/command_line.h" @@ -19,13 +24,13 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "third_party/skia/include/core/SkPath.h" -#include "ui/accessibility/platform/atk_util_auralinux.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/null_window_targeter.h" #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" +#include "ui/base/buildflags.h" #include "ui/base/class_property.h" #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" #include "ui/base/hit_test.h" @@ -65,6 +70,10 @@ #include "ui/wm/core/compound_event_filter.h" #include "ui/wm/core/window_util.h" +#if BUILDFLAG(USE_ATK) +#include "ui/accessibility/platform/atk_util_auralinux.h" +#endif + DEFINE_UI_CLASS_PROPERTY_TYPE(views::DesktopWindowTreeHostX11*) namespace views { @@ -166,6 +175,15 @@ DISALLOW_COPY_AND_ASSIGN(SwapWithNewSizeObserverHelper); }; +bool ShouldDiscardKeyEvent(XEvent* xev) { +#if BUILDFLAG(USE_ATK) + return ui::AtkUtilAuraLinux::HandleKeyEvent(xev) == + ui::DiscardAtkKeyEvent::Discard; +#else + return false; +#endif +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -2114,8 +2132,7 @@ break; } case KeyPress: { - if (ui::AtkUtilAuraLinux::HandleKeyEvent(xev) != - ui::DiscardAtkKeyEvent::Discard) { + if (!ShouldDiscardKeyEvent(xev)) { ui::KeyEvent keydown_event(xev); DispatchKeyEvent(&keydown_event); } @@ -2127,8 +2144,7 @@ if (!IsActive() && !HasCapture()) break; - if (ui::AtkUtilAuraLinux::HandleKeyEvent(xev) != - ui::DiscardAtkKeyEvent::Discard) { + if (!ShouldDiscardKeyEvent(xev)) { ui::KeyEvent key_event(xev); DispatchKeyEvent(&key_event); }
diff --git a/ui/webui/resources/html/dark_mode.html b/ui/webui/resources/html/dark_mode.html deleted file mode 100644 index b652ff82..0000000 --- a/ui/webui/resources/html/dark_mode.html +++ /dev/null
@@ -1,2 +0,0 @@ -<link rel="import" href="chrome://resources/html/cr.html"> -<script src="chrome://resources/js/dark_mode.js"></script>
diff --git a/ui/webui/resources/js/BUILD.gn b/ui/webui/resources/js/BUILD.gn index f42ed51..15a185ca 100644 --- a/ui/webui/resources/js/BUILD.gn +++ b/ui/webui/resources/js/BUILD.gn
@@ -20,7 +20,6 @@ ":action_link", ":assert", ":cr", - ":dark_mode", ":event_tracker", ":find_shortcut_behavior", ":i18n_behavior", @@ -57,12 +56,6 @@ externs_list = [ "$externs_path/chrome_send.js" ] } -js_library("dark_mode") { - deps = [ - ":cr", - ] -} - js_library("event_tracker") { }
diff --git a/ui/webui/resources/js/cr/ui/focus_outline_manager.js b/ui/webui/resources/js/cr/ui/focus_outline_manager.js index 3071ba8d..3432f1e6 100644 --- a/ui/webui/resources/js/cr/ui/focus_outline_manager.js +++ b/ui/webui/resources/js/cr/ui/focus_outline_manager.js
@@ -9,9 +9,6 @@ */ const CLASS_NAME = 'focus-outline-visible'; - /** @type {!Map<!Document, !cr.ui.FocusOutlineManager>} */ - const docsToManager = new Map(); - /** * This class sets a CSS class name on the HTML element of |doc| when the user * presses the tab key. It removes the class name when the user clicks @@ -26,47 +23,46 @@ * And the outline will only be shown if the user uses the keyboard to get to * it. * + * @param {Document} doc The document to attach the focus outline manager to. + * @constructor */ - class FocusOutlineManager { - /** - * @param {Document} doc The document to attach the focus outline manager - * to. - */ - constructor(doc) { - /** - * Whether focus change is triggered by TAB key. - * @private {boolean} - */ - this.focusByKeyboard_ = true; + function FocusOutlineManager(doc) { + this.classList_ = doc.documentElement.classList; - this.classList_ = doc.documentElement.classList; - - const onEvent = function(focusByKeyboard, e) { - if (this.focusByKeyboard_ === focusByKeyboard) { - return; - } - this.focusByKeyboard_ = focusByKeyboard; - this.updateVisibility(); - }; - - doc.addEventListener('keydown', onEvent.bind(this, true), true); - doc.addEventListener('mousedown', onEvent.bind(this, false), true); - - doc.addEventListener('focusout', event => { - window.setTimeout(() => { - if (!doc.hasFocus()) { - this.focusByKeyboard_ = true; - this.updateVisibility(); - } - }, 0); - }); - + const onEvent = function(focusByKeyboard, e) { + if (this.focusByKeyboard_ === focusByKeyboard) { + return; + } + this.focusByKeyboard_ = focusByKeyboard; this.updateVisibility(); - } + }; - updateVisibility() { + doc.addEventListener('keydown', onEvent.bind(this, true), true); + doc.addEventListener('mousedown', onEvent.bind(this, false), true); + + doc.addEventListener('focusout', function(event) { + window.setTimeout(function() { + if (!doc.hasFocus()) { + this.focusByKeyboard_ = true; + this.updateVisibility(); + } + }.bind(this), 0); + }.bind(this)); + + this.updateVisibility(); + } + + FocusOutlineManager.prototype = { + /** + * Whether focus change is triggered by TAB key. + * @type {boolean} + * @private + */ + focusByKeyboard_: true, + + updateVisibility: function() { this.visible = this.focusByKeyboard_; - } + }, /** * Whether the focus outline should be visible. @@ -74,27 +70,29 @@ */ set visible(visible) { this.classList_.toggle(CLASS_NAME, visible); - } - + }, get visible() { return this.classList_.contains(CLASS_NAME); } + }; - /** - * Gets a per document singleton focus outline manager. - * @param {!Document} doc The document to get the |FocusOutlineManager| for. - * @return {!cr.ui.FocusOutlineManager} The per document singleton focus - * outline manager. - */ - static forDocument(doc) { - let manager = docsToManager.get(doc); - if (!manager) { - manager = new FocusOutlineManager(doc); - docsToManager.set(doc, manager); - } - return manager; + /** @type {!Map<!Document, !cr.ui.FocusOutlineManager>} */ + const docsToManager = new Map(); + + /** + * Gets a per document singleton focus outline manager. + * @param {!Document} doc The document to get the |FocusOutlineManager| for. + * @return {!cr.ui.FocusOutlineManager} The per document singleton focus + * outline manager. + */ + FocusOutlineManager.forDocument = function(doc) { + let manager = docsToManager.get(doc); + if (!manager) { + manager = new FocusOutlineManager(doc); + docsToManager.set(doc, manager); } - } + return manager; + }; return {FocusOutlineManager: FocusOutlineManager}; });
diff --git a/ui/webui/resources/js/dark_mode.js b/ui/webui/resources/js/dark_mode.js deleted file mode 100644 index 495d9d3..0000000 --- a/ui/webui/resources/js/dark_mode.js +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2018 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. - -cr.addWebUIListener('dark-mode-changed', darkMode => { - document.documentElement.toggleAttribute('dark', darkMode); -}); - -chrome.send('observeDarkMode'); - -/** @return {boolean} Whether the page is in dark mode. */ -function inDarkMode() { - return document.documentElement.hasAttribute('dark'); -}
diff --git a/ui/webui/resources/js/promise_resolver.js b/ui/webui/resources/js/promise_resolver.js index 93a1164..d19f7f73 100644 --- a/ui/webui/resources/js/promise_resolver.js +++ b/ui/webui/resources/js/promise_resolver.js
@@ -16,65 +16,63 @@ * resolver.resolve({hello: 'world'}); */ -// eslint-disable-next-line no-var -var PromiseResolver = class { - /** @template T */ - constructor() { - /** @private {function(T=): void} */ - this.resolve_; +/** + * @constructor @struct + * @template T + */ +function PromiseResolver() { + /** @private {function(T=): void} */ + this.resolve_; - /** @private {function(*=): void} */ - this.reject_; + /** @private {function(*=): void} */ + this.reject_; - /** @private {boolean} */ - this.isFulfilled_ = false; + /** @private {boolean} */ + this.isFulfilled_ = false; - /** @private {!Promise<T>} */ - this.promise_ = new Promise((resolve, reject) => { - this.resolve_ = /** @param {T=} resolution */ (resolution) => { - resolve(resolution); - this.isFulfilled_ = true; - }; - this.reject_ = /** @param {*=} reason */ (reason) => { - reject(reason); - this.isFulfilled_ = true; - }; - }); - } + /** @private {!Promise<T>} */ + this.promise_ = new Promise(function(resolve, reject) { + this.resolve_ = /** @param {T=} resolution */ function(resolution) { + resolve(resolution); + this.isFulfilled_ = true; + }; + this.reject_ = /** @param {*=} reason */ function(reason) { + reject(reason); + this.isFulfilled_ = true; + }; + }.bind(this)); +} +PromiseResolver.prototype = { /** @return {boolean} Whether this resolver has been resolved or rejected. */ get isFulfilled() { return this.isFulfilled_; - } - + }, set isFulfilled(i) { assertNotReached(); - } + }, /** @return {!Promise<T>} */ get promise() { return this.promise_; - } - + }, set promise(p) { assertNotReached(); - } + }, /** @return {function(T=): void} */ get resolve() { return this.resolve_; - } - + }, set resolve(r) { assertNotReached(); - } + }, /** @return {function(*=): void} */ get reject() { return this.reject_; - } - + }, set reject(s) { assertNotReached(); - } + }, };
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd index 15e3f76..781a9bc 100644 --- a/ui/webui/resources/webui_resources.grd +++ b/ui/webui/resources/webui_resources.grd
@@ -237,8 +237,6 @@ <structure name="IDR_WEBUI_HTML_CR_UI_STORE_CLIENT" file="html/cr/ui/store_client.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_HTML_DARK_MODE" - file="html/dark_mode.html" type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_HTML_EVENT_TRACKER" file="html/event_tracker.html" type="chrome_html" compress="gzip" /> @@ -370,9 +368,6 @@ <structure name="IDR_WEBUI_JS_CR_UI_TOUCH_HANDLER" file="js/cr/ui/touch_handler.js" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_DARK_MODE" - file="js/dark_mode.js" type="chrome_html" - compress="gzip" /> <structure name="IDR_WEBUI_JS_EVENT_TRACKER" file="js/event_tracker.js" type="chrome_html" compress="gzip" />