diff --git a/DEPS b/DEPS index b2773db..a358ddd 100644 --- a/DEPS +++ b/DEPS
@@ -172,11 +172,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': '99b558b594a12ec1d09172f85a6586b17de75ccc', + 'skia_revision': 'a53e47fe9483117e65e05a006e88c2cccf974a1a', # 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': '814c68a96da7afea756c9f8aea57244f017bd715', + 'v8_revision': 'fdd7f4213eb74e4f796b3a9ef2cddb51e93bbfe9', # 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. @@ -184,11 +184,11 @@ # 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': 'dc98ca69edd0a803eed76e16d650fa69ea5610f0', + 'angle_revision': '50919254cbc716d09703f93c2d38a0368809dbda', # 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': 'd9ed1c2732ba9b1bd36461367d348e3030043a25', + 'swiftshader_revision': 'c03ce008b9fe5056e3dc225473602419e987e94c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -243,7 +243,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '7eee1a626bd162ff8eaa017c6a1f94a83613b6c3', + 'devtools_frontend_revision': '80a89976c1420ca7cc12b6e4702cefb0eb7bfc29', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -896,7 +896,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1917f7a099407369280b2cc74a33e44f4ed8c84c', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '039522eb577eb99dc9b931c2c63e327239aa0c8a', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1311,7 +1311,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '5e3eacac1ca1dcd6f8a18da9a39aeccf48aa13c5', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'e9709db85ca95f1cc0cc65d9a2a0928ea9184841', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
diff --git a/android_webview/variables.gni b/android_webview/variables.gni index 8bbf434..3efed5b7 100644 --- a/android_webview/variables.gni +++ b/android_webview/variables.gni
@@ -16,6 +16,7 @@ upstream_only_webview_deps = [ "//android_webview:platform_service_bridge_upstream_implementation_java", "//android_webview/apk:icon_resources", + "//weblayer/browser/java:gms_bridge_upstream_impl_java", ] webview_product_config_java_package = "org.chromium.android_webview"
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 2384f696e..6e79379 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -877,8 +877,44 @@ <message name="IDS_ASH_STATUS_TRAY_NETWORK" desc="The label used in the network dialog header."> Network </message> - <message name="IDS_ASH_STATUS_TRAY_NETWORK_ACCESSIBILITY_LABEL" desc="Accessibility label for a network in the quick settings network list, to be read outloud by a screenreader or braile console."> - <ph name="NETWORK_NAME">$1<ex>GuestNetwork</ex></ph> - <ph name="CONNECTION_STATUS">$2<ex>Connecting</ex></ph> + <message name="IDS_ASH_STATUS_TRAY_ETHERNET_A11Y_LABEL_WITH_CONNECTION_STATUS" desc="Accessibility label for an ethernet network in the quick settings network list."> + <ph name="NETWORK_NAME">$1<ex>Ethernet</ex></ph>, <ph name="CONNECTION_STATUS">$2<ex>Connected</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_ETHERNET_A11Y_LABEL_MANAGED" desc="Accessibility label for an enterprise managed ethernet network in the quick settings network list."> + <ph name="NETWORK_NAME">$1<ex>Ethernet</ex></ph>, Managed by your Administrator + </message> + <message name="IDS_ASH_STATUS_TRAY_ETHERNET_A11Y_LABEL_MANAGED_WITH_CONNECTION_STATUS" desc="Accessibility label for an enterprise managed ethernet network in the quick settings network list. Includes connection status."> + <ph name="NETWORK_NAME">$1<ex>Ethernet</ex></ph>, <ph name="CONNECTION_STATUS">$2<ex>Connected</ex></ph>, Managed by your Administrator + </message> + <message name="IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL" desc="Accessibility label for a cellular network in the quick settings network list."> + <ph name="NETWORK_NAME">$1<ex>Verizon Wireless</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$2<ex>80%</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL_WITH_CONNECTION_STATUS" desc="Accessibility label for a cellular network in the quick settings network list . Includes connection status."> + <ph name="NETWORK_NAME">$1<ex>Verizon Wireless</ex></ph>, <ph name="CONNECTION_STATUS">$2<ex>Connecting...</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$3<ex>80%</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL_MANAGED" desc="Accessibility label for an enterprise managed cellular network in the quick settings network list."> + <ph name="NETWORK_NAME">$1<ex>Verizon Wireless</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$2<ex>80%</ex></ph>, Managed by your Administrator + </message> + <message name="IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL_MANAGED_WITH_CONNECTION_STATUS" desc="Accessibility label for an enterprise managed cellular network in the quick settings network list. Includes connection status."> + <ph name="NETWORK_NAME">$1<ex>Verizon Wireless</ex></ph>, <ph name="CONNECTION_STATUS">$2<ex>Connecting...</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$3<ex>80%</ex></ph>, Managed by your Administrator + </message> + <message name="IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL" desc="Accessibility label for a Wi-Fi network in the quick settings network list."> + <ph name="NETWORK_NAME">$1<ex>GuestNetwork</ex></ph>, <ph name="SECURITY_STATUS">$2<ex>Unsecured</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$3<ex>80%</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL_WITH_CONNECTION_STATUS" desc="Accessibility label for a Wi-Fi network in the quick settings network list. Includes connection status."> + <ph name="NETWORK_NAME">$1<ex>GuestNetwork</ex></ph>, <ph name="SECURITY_STATUS">$2<ex>Unsecured</ex></ph>, <ph name="CONNECTION_STATUS">$3<ex>Connecting</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$4<ex>80%</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL_MANAGED" desc="Accessibility label for an enterprise managed Wi-Fi network in the quick settings network list."> + <ph name="NETWORK_NAME">$1<ex>GuestNetwork</ex></ph>, <ph name="SECURITY_STATUS">$2<ex>Unsecured</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$3<ex>80%</ex></ph>, Managed by your Administrator + </message> + <message name="IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL_MANAGED_WITH_CONNECTION_STATUS" desc="Accessibility label for an enterprise managed Wi-Fi network in the quick settings network list. Incldues connection status."> + <ph name="NETWORK_NAME">$1<ex>GuestNetwork</ex></ph>, <ph name="SECURITY_STATUS">$2<ex>Unsecured</ex></ph>, <ph name="CONNECTION_STATUS">$3<ex>Connecting</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$4<ex>80%</ex></ph>, Managed by your Administrator + </message> + <message name="IDS_ASH_STATUS_TRAY_TETHER_NETWORK_A11Y_LABEL" desc="Accessibility label for a phone tether network in the quick settings network list."> + <ph name="PHONE_NAME">$1<ex>Pixel 4</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$2<ex>80%</ex></ph>, Phone Battery <ph name="BATTERY_STATUS">$3<ex>80%</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_TETHER_NETWORK_A11Y_LABEL_WITH_CONNECTION_STATUS" desc="Accessibility label for a phone tether network in the quick settings network list. Includes connection status."> + <ph name="PHONE_NAME">$1<ex>Pixel 4</ex></ph>, <ph name="CONNECTION_STATUS">$2<ex>Connecting...</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$3<ex>80%</ex></ph>, Phone Battery <ph name="BATTERY_STATUS">$4<ex>80%</ex></ph> </message> <message name="IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED" desc="The label used when a network connection is connected."> Connected @@ -886,6 +922,12 @@ <message name="IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING" desc="The label used when a network connection is connecting."> Connecting... </message> + <message name="IDS_ASH_STATUS_TRAY_NETWORK_STATUS_SECURED" desc="a11y label used when a Wi-Fi network is secured."> + Secured + </message> + <message name="IDS_ASH_STATUS_TRAY_NETWORK_STATUS_UNSECURED" desc="a11y label used when a Wi-Fi network connection is not secured."> + Unsecured + </message> <message name="IDS_ASH_STATUS_TRAY_VPN" desc="The label used in the VPN detailed view header."> Private network </message>
diff --git a/ash/autotest_private_api_utils.cc b/ash/autotest_private_api_utils.cc index ee9c3ba..324179b 100644 --- a/ash/autotest_private_api_utils.cc +++ b/ash/autotest_private_api_utils.cc
@@ -85,10 +85,6 @@ ash::kAllDesks); } -ash::HeaderView* GetHeaderViewForWindow(aura::Window* window) { - return ash::NonClientFrameViewAsh::Get(window)->GetHeaderView(); -} - bool WaitForLauncherState(AppListViewState target_state, base::Closure closure) { // In the tablet mode, some of the app-list state switching is handled
diff --git a/ash/home_screen/OWNERS b/ash/home_screen/OWNERS new file mode 100644 index 0000000..c2248ac --- /dev/null +++ b/ash/home_screen/OWNERS
@@ -0,0 +1,5 @@ +manucornet@chromium.org +newcomer@chromium.org +sammiequon@chromium.org +tbarzic@chromium.org +xdai@chromium.org
diff --git a/ash/home_screen/window_transform_to_home_screen_animation.cc b/ash/home_screen/window_transform_to_home_screen_animation.cc index c7b36f5..e9dd0a4 100644 --- a/ash/home_screen/window_transform_to_home_screen_animation.cc +++ b/ash/home_screen/window_transform_to_home_screen_animation.cc
@@ -11,6 +11,7 @@ #include "ash/screen_util.h" #include "ash/shell.h" #include "ash/wm/window_state.h" +#include "ash/wm/window_util.h" #include "base/time/time.h" #include "ui/aura/window.h" #include "ui/compositor/layer.h" @@ -65,9 +66,8 @@ void WindowTransformToHomeScreenAnimation::OnImplicitAnimationsCompleted() { // Minimize the dragged window after transform animation is completed. - ScopedAnimationDisabler disable(window_); - window_->Hide(); - WindowState::Get(window_)->Minimize(); + window_util::HideAndMaybeMinimizeWithoutAnimation({window_}, + /*minimize=*/true); // Reset its transform to identity transform and its original backdrop mode. window_->layer()->SetTransform(gfx::Transform());
diff --git a/ash/public/cpp/autotest_private_api_utils.h b/ash/public/cpp/autotest_private_api_utils.h index 02c6626..4068624 100644 --- a/ash/public/cpp/autotest_private_api_utils.h +++ b/ash/public/cpp/autotest_private_api_utils.h
@@ -8,7 +8,6 @@ #include <vector> #include "ash/ash_export.h" -#include "ash/frame/header_view.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "base/callback.h" @@ -18,14 +17,10 @@ // Utility functions for autotest private APIs and ShellTestAPI. namespace ash { -class HeaderView; // Get application windows, windows that are shown in overview grid. ASH_EXPORT std::vector<aura::Window*> GetAppWindowList(); -// Get HeaderView from application windows. -ASH_EXPORT ash::HeaderView* GetHeaderViewForWindow(aura::Window* window); - // Runs the callback when the launcher state becomes |state| after // state transition animation. For clamshell launcher, it invokes closure // immediately if the state is already at the target state. For home
diff --git a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc index 43f4ce2..3d457b2dd 100644 --- a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc +++ b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc
@@ -144,9 +144,10 @@ case views::CAPTION_BUTTON_ICON_ZOOM: return false; case views::CAPTION_BUTTON_ICON_LOCATION: + // not used + return false; case views::CAPTION_BUTTON_ICON_COUNT: break; - // not used } NOTREACHED(); return false;
diff --git a/ash/public/cpp/frame_header.cc b/ash/public/cpp/frame_header.cc index 405daa0..b334f41 100644 --- a/ash/public/cpp/frame_header.cc +++ b/ash/public/cpp/frame_header.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/public/cpp/window_properties.h" #include "base/logging.h" // DCHECK +#include "ui/base/class_property.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/font_list.h" @@ -21,9 +22,14 @@ #include "ui/views/window/caption_button_layout_constants.h" #include "ui/views/window/vector_icons/vector_icons.h" +DEFINE_UI_CLASS_PROPERTY_TYPE(ash::FrameHeader*) + namespace ash { namespace { + +DEFINE_UI_CLASS_PROPERTY_KEY(FrameHeader*, kFrameHeaderKey, nullptr) + // Returns the available bounds for the header's title given the views to the // left and right of the title, and the font used. |left_view| should be null // if there is no view to the left of the title. @@ -82,7 +88,15 @@ /////////////////////////////////////////////////////////////////////////////// // FrameHeader, public: -FrameHeader::~FrameHeader() = default; +// static +FrameHeader* FrameHeader::Get(views::Widget* widget) { + return widget->GetNativeView()->GetProperty(kFrameHeaderKey); +} + +FrameHeader::~FrameHeader() { + if (target_widget_->GetNativeView()) + target_widget_->GetNativeView()->ClearProperty(kFrameHeaderKey); +} int FrameHeader::GetMinimumHeaderWidth() const { // Ensure we have enough space for the window icon and buttons. We allow @@ -172,6 +186,10 @@ return back_button_; } +const CaptionButtonModel* FrameHeader::GetCaptionButtonModel() const { + return caption_button_container_->model(); +} + void FrameHeader::SetFrameTextOverride( const base::string16& frame_text_override) { frame_text_override_ = frame_text_override; @@ -194,6 +212,7 @@ view_(view) { DCHECK(target_widget); DCHECK(view); + target_widget_->GetNativeView()->SetProperty(kFrameHeaderKey, this); } gfx::Rect FrameHeader::GetPaintedBounds() const {
diff --git a/ash/public/cpp/frame_header.h b/ash/public/cpp/frame_header.h index 13bfa68..6074eb2c 100644 --- a/ash/public/cpp/frame_header.h +++ b/ash/public/cpp/frame_header.h
@@ -26,12 +26,15 @@ } // namespace views namespace ash { +class CaptionButtonModel; // Helper class for managing the window header. class ASH_PUBLIC_EXPORT FrameHeader : public views::AnimationDelegateViews { public: enum Mode { MODE_ACTIVE, MODE_INACTIVE }; + static FrameHeader* Get(views::Widget* widget); + ~FrameHeader() override; const base::string16& frame_text_override() const { @@ -69,6 +72,7 @@ void SetLeftHeaderView(views::View* view); void SetBackButton(views::FrameCaptionButton* view); views::FrameCaptionButton* GetBackButton() const; + const CaptionButtonModel* GetCaptionButtonModel() const; // Updates the frame header painting to reflect a change in frame colors. virtual void UpdateFrameColors() = 0;
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc b/ash/public/cpp/immersive/immersive_fullscreen_controller.cc index 41960266..7cac1a3 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc +++ b/ash/public/cpp/immersive/immersive_fullscreen_controller.cc
@@ -278,7 +278,7 @@ } // static -ImmersiveFullscreenController* ImmersiveFullscreenController::GetForTest( +ImmersiveFullscreenController* ImmersiveFullscreenController::Get( views::Widget* widget) { return widget->GetNativeWindow()->GetProperty( kImmersiveFullscreenControllerKey);
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller.h b/ash/public/cpp/immersive/immersive_fullscreen_controller.h index c7cbc21..0e78095 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller.h +++ b/ash/public/cpp/immersive/immersive_fullscreen_controller.h
@@ -136,7 +136,7 @@ static void EnableForWidget(views::Widget* widget, bool enabled); - static ImmersiveFullscreenController* GetForTest(views::Widget* widget); + static ImmersiveFullscreenController* Get(views::Widget* widget); private: friend class ImmersiveFullscreenControllerTest;
diff --git a/ash/shelf/scrollable_shelf_view.cc b/ash/shelf/scrollable_shelf_view.cc index 5b8bd676d..df5e42c 100644 --- a/ash/shelf/scrollable_shelf_view.cc +++ b/ash/shelf/scrollable_shelf_view.cc
@@ -4,6 +4,7 @@ #include "ash/shelf/scrollable_shelf_view.h" +#include "ash/app_list/app_list_controller_impl.h" #include "ash/drag_drop/drag_image_view.h" #include "ash/public/cpp/shelf_config.h" #include "ash/screen_util.h" @@ -13,6 +14,7 @@ #include "ash/shelf/shelf_widget.h" #include "ash/system/status_area_widget.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "base/metrics/histogram_macros.h" #include "base/numerics/ranges.h" #include "chromeos/constants/chromeos_switches.h" #include "ui/base/l10n/l10n_util.h" @@ -215,6 +217,33 @@ }; //////////////////////////////////////////////////////////////////////////////// +// ScrollableShelfAnimationMetricsReporter + +class ScrollableShelfAnimationMetricsReporter + : public ui::AnimationMetricsReporter { + public: + ScrollableShelfAnimationMetricsReporter() {} + + ~ScrollableShelfAnimationMetricsReporter() override = default; + + // ui::AnimationMetricsReporter: + void Report(int value) override { + UMA_HISTOGRAM_PERCENTAGE("Apps.ScrollableShelf.AnimationSmoothness", value); + if (Shell::Get()->app_list_controller()->IsVisible()) { + UMA_HISTOGRAM_PERCENTAGE( + "Apps.ScrollableShelf.AnimationSmoothness.VisibleHomeLauncher", + value); + } else { + UMA_HISTOGRAM_PERCENTAGE( + "Apps.ScrollableShelf.AnimationSmoothness.NotVisibleHomeLauncher", + value); + } + } + + DISALLOW_COPY_AND_ASSIGN(ScrollableShelfAnimationMetricsReporter); +}; + +//////////////////////////////////////////////////////////////////////////////// // ScrollableShelfContainerView class ScrollableShelfContainerView : public ShelfContainerView, @@ -342,7 +371,9 @@ shelf, /*drag_and_drop_host=*/this, /*shelf_button_delegate=*/this)), - page_flip_time_threshold_(kShelfPageFlipDelay) { + page_flip_time_threshold_(kShelfPageFlipDelay), + animation_metrics_reporter_( + std::make_unique<ScrollableShelfAnimationMetricsReporter>()) { Shell::Get()->AddShellObserver(this); set_allow_deactivate_on_esc(true); } @@ -512,6 +543,8 @@ animation_settings.SetTweenType(gfx::Tween::EASE_OUT); animation_settings.SetPreemptionStrategy( ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); + animation_settings.SetAnimationMetricsReporter( + animation_metrics_reporter_.get()); animation_settings.AddObserver(this); shelf_view_->layer()->SetTransform(current_transform); }
diff --git a/ash/shelf/scrollable_shelf_view.h b/ash/shelf/scrollable_shelf_view.h index 4e41892..da1e5b8 100644 --- a/ash/shelf/scrollable_shelf_view.h +++ b/ash/shelf/scrollable_shelf_view.h
@@ -375,6 +375,10 @@ base::OneShotTimer page_flip_timer_; + // Metric reporter for scrolling animations. + const std::unique_ptr<ui::AnimationMetricsReporter> + animation_metrics_reporter_; + DISALLOW_COPY_AND_ASSIGN(ScrollableShelfView); };
diff --git a/ash/system/network/network_info.h b/ash/system/network/network_info.h index 5254248..2f1b538f 100644 --- a/ash/system/network/network_info.h +++ b/ash/system/network/network_info.h
@@ -32,11 +32,13 @@ base::string16 tooltip; gfx::ImageSkia image; bool disable = false; + bool secured = false; // Initialized in .cc file because full (non-forward) mojom headers are large. chromeos::network_config::mojom::ConnectionStateType connection_state; chromeos::network_config::mojom::NetworkType type; chromeos::network_config::mojom::OncSource source; int battery_percentage = 0; + int signal_strength = 0; std::string captive_portal_provider_name; };
diff --git a/ash/system/network/network_list_view.cc b/ash/system/network/network_list_view.cc index 3c97357..38a14f1 100644 --- a/ash/system/network/network_list_view.cc +++ b/ash/system/network/network_list_view.cc
@@ -76,6 +76,11 @@ AshColorProvider::AshColorMode::kDark); } +bool IsManagedByPolicy(const NetworkInfo& info) { + return info.source == OncSource::kDevicePolicy || + info.source == OncSource::kUserPolicy; +} + } // namespace // NetworkListView: @@ -151,6 +156,8 @@ break; case NetworkType::kWiFi: wifi_has_networks_ = true; + info->secured = network->type_state->get_wifi()->security != + chromeos::network_config::mojom::SecurityType::kNone; break; case NetworkType::kTether: mobile_has_networks_ = true; @@ -175,6 +182,9 @@ info->connection_state = connection_state; + info->signal_strength = + chromeos::network_config::GetWirelessSignalStrength(network.get()); + if (network->captive_portal_provider) { info->captive_portal_provider_name = network->captive_portal_provider->name; @@ -379,9 +389,103 @@ view->AddRightView(icon); } + view->SetAccessibleName(GenerateAccessibilityLabel(info)); + needs_relayout_ = true; } +base::string16 NetworkListView::GenerateAccessibilityLabel( + const NetworkInfo& info) { + base::string16 connection_status; + if (StateIsConnected(info.connection_state) || + info.connection_state == ConnectionStateType::kConnecting) { + connection_status = l10n_util::GetStringUTF16( + StateIsConnected(info.connection_state) + ? IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED + : IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING); + } + + switch (info.type) { + case NetworkType::kEthernet: + if (!connection_status.empty()) { + if (IsManagedByPolicy(info)) { + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_ETHERNET_A11Y_LABEL_MANAGED_WITH_CONNECTION_STATUS, + info.label, connection_status); + } + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_ETHERNET_A11Y_LABEL_WITH_CONNECTION_STATUS, + info.label, connection_status); + } + if (IsManagedByPolicy(info)) { + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_ETHERNET_A11Y_LABEL_MANAGED, info.label, + connection_status); + } + return info.label; + case NetworkType::kWiFi: { + base::string16 security_label = l10n_util::GetStringUTF16( + info.secured ? IDS_ASH_STATUS_TRAY_NETWORK_STATUS_SECURED + : IDS_ASH_STATUS_TRAY_NETWORK_STATUS_UNSECURED); + if (!connection_status.empty()) { + if (IsManagedByPolicy(info)) { + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL_MANAGED_WITH_CONNECTION_STATUS, + info.label, security_label, connection_status, + base::FormatPercent(info.signal_strength)); + } + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL_WITH_CONNECTION_STATUS, + info.label, security_label, connection_status, + base::FormatPercent(info.signal_strength)); + } + if (IsManagedByPolicy(info)) { + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL_MANAGED, info.label, + security_label, base::FormatPercent(info.signal_strength)); + } + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_WIFI_NETWORK_A11Y_LABEL, info.label, + security_label, base::FormatPercent(info.signal_strength)); + } + case NetworkType::kCellular: + if (!connection_status.empty()) { + if (IsManagedByPolicy(info)) { + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL_MANAGED_WITH_CONNECTION_STATUS, + info.label, connection_status, + base::FormatPercent(info.signal_strength)); + } + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL_WITH_CONNECTION_STATUS, + info.label, connection_status, + base::FormatPercent(info.signal_strength)); + } + if (IsManagedByPolicy(info)) { + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL_MANAGED, info.label, + base::FormatPercent(info.signal_strength)); + } + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_CELLULAR_NETWORK_A11Y_LABEL, info.label, + base::FormatPercent(info.signal_strength)); + case NetworkType::kTether: + if (!connection_status.empty()) { + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_TETHER_NETWORK_A11Y_LABEL_WITH_CONNECTION_STATUS, + info.label, connection_status, + base::FormatPercent(info.signal_strength), + base::FormatPercent(info.battery_percentage)); + } + return l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_TETHER_NETWORK_A11Y_LABEL, info.label, + base::FormatPercent(info.signal_strength), + base::FormatPercent(info.battery_percentage)); + default: + return info.label; + } +} // namespace tray + views::View* NetworkListView::CreatePowerStatusView(const NetworkInfo& info) { // Mobile can be Cellular or Tether. if (!NetworkTypeMatchesType(info.type, NetworkType::kMobile))
diff --git a/ash/system/network/network_list_view.h b/ash/system/network/network_list_view.h index e683ddb6..263d61a 100644 --- a/ash/system/network/network_list_view.h +++ b/ash/system/network/network_list_view.h
@@ -128,6 +128,10 @@ // otherwise false. bool NeedUpdateViewForNetwork(const NetworkInfo& info) const; + // Creates a label for the given network which includes all information + // that is shown in the ui. + base::string16 GenerateAccessibilityLabel(const NetworkInfo& info); + bool needs_relayout_ = false; // Owned by the views heirarchy.
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc index bd8b640b..900fe06 100644 --- a/ash/system/tray/tray_detailed_view.cc +++ b/ash/system/tray/tray_detailed_view.cc
@@ -365,34 +365,24 @@ base::string16 status; if (battery_percentage) { - status = l10n_util::GetStringFUTF16( + view->SetSubText(l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_CONNECTED_WITH_BATTERY_LABEL, - base::NumberToString16(battery_percentage.value())); + base::NumberToString16(battery_percentage.value()))); } else { - status = - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED); + view->SetSubText(l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTED)); } - view->SetSubText(status); TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::CAPTION); style.set_color_style(TrayPopupItemStyle::ColorStyle::CONNECTED); style.SetupLabel(view->sub_text_label()); - - view->SetAccessibleName(l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_NETWORK_ACCESSIBILITY_LABEL, - view->text_label()->GetText(), status)); } void TrayDetailedView::SetupConnectingScrollListItem(HoverHighlightView* view) { DCHECK(view->is_populated()); - base::string16 status = - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING); - - view->SetSubText(status); - view->SetAccessibleName(l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_NETWORK_ACCESSIBILITY_LABEL, - view->text_label()->GetText(), status)); + view->SetSubText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_STATUS_CONNECTING)); } TriView* TrayDetailedView::AddScrollListSubHeader(const gfx::VectorIcon& icon,
diff --git a/ash/wm/immersive_fullscreen_controller_unittest.cc b/ash/wm/immersive_fullscreen_controller_unittest.cc index 0ce1eb69..a60d6d2 100644 --- a/ash/wm/immersive_fullscreen_controller_unittest.cc +++ b/ash/wm/immersive_fullscreen_controller_unittest.cc
@@ -140,7 +140,7 @@ ~ImmersiveFullscreenControllerTest() override = default; ImmersiveFullscreenController* controller() { - return ImmersiveFullscreenController::GetForTest(widget()); + return ImmersiveFullscreenController::Get(widget()); } views::NativeViewHost* content_view() { return content_view_; }
diff --git a/base/android/junit/src/org/chromium/base/task/AsyncTaskThreadTest.java b/base/android/junit/src/org/chromium/base/task/AsyncTaskThreadTest.java index 5072c573..8bd26086 100644 --- a/base/android/junit/src/org/chromium/base/task/AsyncTaskThreadTest.java +++ b/base/android/junit/src/org/chromium/base/task/AsyncTaskThreadTest.java
@@ -14,6 +14,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -171,6 +172,7 @@ @Test @SmallTest + @Ignore("crbug.com/1022954") public void testCancel_MayInterrupt_TaskIsInterrupted() throws Exception { mTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
diff --git a/base/containers/intrusive_heap_unittest.cc b/base/containers/intrusive_heap_unittest.cc index f0927243..65aee84 100644 --- a/base/containers/intrusive_heap_unittest.cc +++ b/base/containers/intrusive_heap_unittest.cc
@@ -652,8 +652,9 @@ TEST(IntrusiveHeapTest, CopyOnlyNoDefaultConstructorTest) { using ValueType = Value_dmC; ValidateValueType<ValueType, false, false, true>(); - CopyStressTest<ValueType>(); - GeneralStressTest<ValueType>(); + // We cannot perform CopyStressTest nor GeneralStressTest here, because + // Value_dmC has deleted move constructor and assignment operator. See + // crbug.com/1022576. } TEST(IntrusiveHeapTest, CopyAndMoveNoDefaultConstructorTest) { @@ -674,8 +675,9 @@ TEST(IntrusiveHeapTest, CopyOnlyWithDefaultConstructorTest) { using ValueType = Value_DmC; ValidateValueType<ValueType, true, false, true>(); - CopyStressTest<ValueType>(); - GeneralStressTest<ValueType>(); + // We cannot perform CopyStressTest nor GeneralStressTest here, because + // Value_DmC has deleted move constructor and assignment operator. See + // crbug.com/1022576. } TEST(IntrusiveHeapTest, CopyAndMoveWithDefaultConstructorTest) {
diff --git a/base/debug/stack_trace_unittest.cc b/base/debug/stack_trace_unittest.cc index 673420f4..07f51a0 100644 --- a/base/debug/stack_trace_unittest.cc +++ b/base/debug/stack_trace_unittest.cc
@@ -31,11 +31,25 @@ typedef testing::Test StackTraceTest; #endif -#if !defined(__UCLIBC__) && !defined(_AIX) -// StackTrace::OutputToStream() is not implemented under uclibc, nor AIX. -// See https://crbug.com/706728 +// TODO(https://crbug.com/999737): Rewrite this test for better clarity and +// correctness. +// Note: On Linux, this test currently only fully works on Debug builds. +// See comments in the #ifdef soup if you intend to change this. +#if defined(OS_WIN) -TEST_F(StackTraceTest, OutputToStream) { +// Always fails on Windows: crbug.com/32070 +#define MAYBE_OutputToStream DISABLED_OutputToStream + +#elif defined(OS_FUCHSIA) && defined(OFFICIAL_BUILD) + +// Backtraces aren't supported by Fuchsia release-optimized builds. +#define MAYBE_OutputToStream DISABLED_OutputToStream + +#else +#define MAYBE_OutputToStream OutputToStream +#endif +#if !defined(__UCLIBC__) && !defined(_AIX) +TEST_F(StackTraceTest, MAYBE_OutputToStream) { StackTrace trace; // Dump the trace into a string. @@ -46,54 +60,76 @@ // ToString() should produce the same output. EXPECT_EQ(backtrace_message, trace.ToString()); - size_t frames_found = 0; - const void* const* addresses = trace.Addresses(&frames_found); - ASSERT_TRUE(addresses); - ASSERT_GT(frames_found, 0u) << "No stack frames found."; - -#if defined(OFFICIAL_BUILD) && defined(OS_POSIX) && !defined(OS_MACOSX) +#if defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG // Stack traces require an extra data table that bloats our binaries, - // so they're turned off for official builds. Stop the test here, so - // it at least verifies that StackTrace calls don't crash. + // so they're turned off for release builds. We stop the test here, + // at least letting us verify that the calls don't crash. return; -#endif // defined(OFFICIAL_BUILD) && defined(OS_POSIX) && !defined(OS_MACOSX) +#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG - ASSERT_GT(frames_found, 5u) << "Too few frames found."; - -#if defined(OS_FUCHSIA) || defined(OS_ANDROID) - // Under Fuchsia and Android, StackTrace emits executable build-Ids and - // address offsets which are symbolized on the test host system, rather than - // being symbolized in-process. - return; -#endif // defined(OS_FUCHSIA) || defined(OS_ANDROID) - -#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) - // Configurations such as ASAN and TSan emit unsymbolized stacks. - return; -#endif // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) + size_t frames_found = 0; + trace.Addresses(&frames_found); + ASSERT_GE(frames_found, 5u) << + "No stack frames found. Skipping rest of test."; // Check if the output has symbol initialization warning. If it does, fail. ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"), - std::string::npos) - << "Unable to resolve symbols."; + std::string::npos) << + "Unable to resolve symbols. Skipping rest of test."; +#if defined(OS_MACOSX) +#if 0 + // Disabled due to -fvisibility=hidden in build config. + + // Symbol resolution via the backtrace_symbol function does not work well + // in OS X. + // See this thread: + // + // http://lists.apple.com/archives/darwin-dev/2009/Mar/msg00111.html + // + // Just check instead that we find our way back to the "start" symbol + // which should be the first symbol in the trace. + // + // TODO(port): Find a more reliable way to resolve symbols. + + // Expect to at least find main. + EXPECT_TRUE(backtrace_message.find("start") != std::string::npos) + << "Expected to find start in backtrace:\n" + << backtrace_message; + +#endif +#elif defined(USE_SYMBOLIZE) + // This branch is for gcc-compiled code, but not Mac due to the + // above #if. // Expect a demangled symbol. - // Note that Windows Release builds omit the function parameters from the - // demangled stack output, otherwise this could be "testing::Test::Run()". - EXPECT_TRUE(backtrace_message.find("testing::Test::Run") != std::string::npos) + EXPECT_TRUE(backtrace_message.find("testing::Test::Run()") != + std::string::npos) << "Expected a demangled symbol in backtrace:\n" << backtrace_message; +#elif 0 + // This is the fall-through case; it used to cover Windows. + // But it's disabled because of varying buildbot configs; + // some lack symbols. + // Expect to at least find main. EXPECT_TRUE(backtrace_message.find("main") != std::string::npos) << "Expected to find main in backtrace:\n" << backtrace_message; +#if defined(OS_WIN) +// MSVC doesn't allow the use of C99's __func__ within C++, so we fake it with +// MSVC's __FUNCTION__ macro. +#define __func__ __FUNCTION__ +#endif + // Expect to find this function as well. // Note: This will fail if not linked with -rdynamic (aka -export_dynamic) EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos) << "Expected to find " << __func__ << " in backtrace:\n" << backtrace_message; + +#endif // define(OS_MACOSX) } #if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES) @@ -110,7 +146,7 @@ truncated.Addresses(&count); EXPECT_EQ(2u, count); } -#endif // !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES) +#endif // !defined(OFFICIAL_BUILD) // The test is used for manual testing, e.g., to see the raw output. TEST_F(StackTraceTest, DebugOutputToStream) { @@ -158,7 +194,7 @@ trace.ToStringWithPrefix(nullptr); } -#endif // !defined(__UCLIBC__) && !defined(_AIX) +#endif // !defined(__UCLIBC__) #if defined(OS_POSIX) && !defined(OS_ANDROID) #if !defined(OS_IOS)
diff --git a/base/task/post_job.h b/base/task/post_job.h index cf8ca1a..7c7014cd 100644 --- a/base/task/post_job.h +++ b/base/task/post_job.h
@@ -84,6 +84,9 @@ JobHandle(JobHandle&&); JobHandle& operator=(JobHandle&&); + // Returns true if associated with a Job. + explicit operator bool() const { return task_source_ != nullptr; } + // Update this Job's priority. void UpdatePriority(TaskPriority new_priority);
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 8cc1458..f0ff35a 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8897362889837801216 \ No newline at end of file +8897331871501701008 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 640e107..6128bd99 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8897363254003807056 \ No newline at end of file +8897334129707393184 \ No newline at end of file
diff --git a/build/win/copy_cdb_to_output.py b/build/win/copy_cdb_to_output.py index 1f0f22a..a0b99bb7 100755 --- a/build/win/copy_cdb_to_output.py +++ b/build/win/copy_cdb_to_output.py
@@ -102,7 +102,13 @@ _CopyImpl('exts.dll', dst_winxp_dir, src_winxp_dir) _CopyImpl('ntsdexts.dll', dst_winxp_dir, src_winxp_dir) if src_arch in ['x64', 'x86']: - _CopyImpl('api-ms-win-eventing-provider-l1-1-0.dll', output_dir, src_dir) + # Copy all UCRT files from the debuggers directory, for compatibility with + # the Windows 10 18362 SDK (one UCRT file) and later versions (two UCRT + # files). The new file is api-ms-win-downlevel-kernel32-l2-1-0.dll and + # should be added to the copy_cdb_to_output outputs when we require a newer + # SDK. + for file in glob.glob(os.path.join(src_dir, 'api-ms-win*.dll')): + _CopyImpl(os.path.split(file)[1], output_dir, src_dir) _CopyImpl('ucrtbase.dll', output_dir, src_crt_dir) for dll_path in glob.glob(os.path.join(src_crt_dir, 'api-ms-win-*.dll')): _CopyImpl(os.path.split(dll_path)[1], output_dir, src_crt_dir)
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index a834d4c..7b9cf47 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1560,6 +1560,7 @@ if (!is_android) { public_deps += [ + "//chrome/browser/resources:bookmarks_resources", "//chrome/browser/resources:component_extension_resources", "//chrome/browser/resources:dev_ui_paks", "//chrome/browser/resources:downloads_resources",
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index 8133889..dfbf1c46 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -6,6 +6,7 @@ import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_FAKE_SEARCH_BOX_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_INCOGNITO; +import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_VOICE_RECOGNITION_BUTTON_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MORE_TABS_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MV_TILES_VISIBLE; @@ -32,6 +33,8 @@ import org.chromium.chrome.browser.night_mode.NightModeStateProvider; import org.chromium.chrome.browser.ntp.FakeboxDelegate; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -67,6 +70,7 @@ private final ObserverList<StartSurface.OverviewModeObserver> mObservers = new ObserverList<>(); private final TabSwitcher.Controller mController; + private final TabModelSelector mTabModelSelector; @Nullable private final PropertyModel mPropertyModel; @Nullable @@ -95,6 +99,7 @@ @SurfaceMode int surfaceMode, @Nullable FakeboxDelegate fakeboxDelegate, NightModeStateProvider nightModeStateProvider) { mController = controller; + mTabModelSelector = tabModelSelector; mPropertyModel = propertyModel; mFeedSurfaceCreator = feedSurfaceCreator; mSecondaryTasksSurfaceInitializer = secondaryTasksSurfaceInitializer; @@ -107,8 +112,9 @@ || mSurfaceMode == SurfaceMode.TASKS_ONLY; assert mFakeboxDelegate != null; - mIsIncognito = tabModelSelector.isIncognitoSelected(); - tabModelSelector.addObserver(new EmptyTabModelSelectorObserver() { + mIsIncognito = mTabModelSelector.isIncognitoSelected(); + + mTabModelSelector.addObserver(new EmptyTabModelSelectorObserver() { @Override public void onTabModelSelected(TabModel newModel, TabModel oldModel) { // TODO(crbug.com/982018): Optimize to not listen for selected Tab model change @@ -148,6 +154,25 @@ if (mSurfaceMode == SurfaceMode.SINGLE_PANE) { mPropertyModel.set(MORE_TABS_CLICK_LISTENER, this); + + // Hide tab carousel, which does not exist in incognito mode, when closing all + // normal tabs. + TabModel normalTabModel = mTabModelSelector.getModel(false); + normalTabModel.addObserver(new EmptyTabModelObserver() { + @Override + public void willCloseTab(Tab tab, boolean animate) { + if (normalTabModel.getCount() <= 1 + || mPropertyModel.get(IS_SHOWING_OVERVIEW)) { + setTabCarouselVisibility(false); + } + } + @Override + public void tabClosureUndone(Tab tab) { + if (mPropertyModel.get(IS_SHOWING_OVERVIEW)) { + setTabCarouselVisibility(true); + } + } + }); } // Set the initial state. @@ -241,6 +266,7 @@ setSecondaryTasksSurfaceVisibility(true); } else { setExploreSurfaceVisibility(true); + setTabCarouselVisibility(mTabModelSelector.getModel(false).getCount() > 0); } } else if (mSurfaceMode == SurfaceMode.TWO_PANES) { RecordUserAction.record("StartSurface.TwoPanes"); @@ -467,4 +493,19 @@ // Do not show Tab switcher toolbar when focusing the Omnibox. return mPropertyModel.get(IS_FAKE_SEARCH_BOX_VISIBLE); } + + private void setTabCarouselVisibility(boolean isVisible) { + assert !mIsIncognito; + + if (isVisible == mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE)) return; + + // Hide the more Tabs view when the last Tab is closed. + if (!isVisible && mSecondaryTasksSurfaceController != null + && mSecondaryTasksSurfaceController.overviewVisible()) { + setSecondaryTasksSurfaceVisibility(false); + setExploreSurfaceVisibility(true); + } + + mPropertyModel.set(IS_TAB_CAROUSEL_VISIBLE, isVisible); + } }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index 2f9bab8..6a35731c 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -13,7 +13,6 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import static org.chromium.base.test.util.CallbackHelper.WAIT_TIMEOUT_SECONDS; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.areAnimatorsEnabled; import static org.chromium.chrome.browser.util.UrlConstants.NTP_URL; import static org.chromium.content_public.browser.test.util.CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL; @@ -49,12 +48,9 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabFeatureUtilities; -import org.chromium.chrome.browser.tabmodel.TabModel; -import org.chromium.chrome.browser.tabmodel.TabSelectionType; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper; import org.chromium.chrome.tab_ui.R; @@ -72,7 +68,6 @@ import org.chromium.net.test.EmbeddedTestServer; import org.chromium.ui.test.util.UiRestriction; -import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.LinkedList; @@ -137,9 +132,7 @@ .getCurrentTabModelFilter()::isTabModelRestored)); assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting()); - // Only skip thumbnail releasing assertion when "warm" (large soft-cleanup-delay) or in - // RenderTest. - // TODO(wychen): figure out why thumbnails are not released in RenderTest. + // Only skip thumbnail releasing assertion when "warm" (large soft-cleanup-delay). mSkipAssertThumbnailsAreReleased = false; } @@ -153,16 +146,14 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_3WebTabs() throws InterruptedException, IOException { - mSkipAssertThumbnailsAreReleased = true; - prepareTabs(3, 0, mUrl); TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); enterGTS(); - mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( - org.chromium.chrome.tab_ui.R.id.tab_list_view), - "3_web_tabs"); + mRenderTestRule.render( + mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "3_web_tabs"); + leaveGTS(); } @Test @@ -170,16 +161,14 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_10WebTabs() throws InterruptedException, IOException { - mSkipAssertThumbnailsAreReleased = true; - prepareTabs(10, 0, mUrl); TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); enterGTS(); - mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( - org.chromium.chrome.tab_ui.R.id.tab_list_view), - "10_web_tabs"); + mRenderTestRule.render( + mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "10_web_tabs"); + leaveGTS(); } @Test @@ -187,8 +176,6 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_10WebTabs_InitialScroll() throws InterruptedException, IOException { - mSkipAssertThumbnailsAreReleased = true; - prepareTabs(10, 0, mUrl); TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); TabUiTestHelper.clickNthCardFromTabSwitcher(mActivityTestRule.getActivity(), @@ -197,9 +184,9 @@ enterGTS(); // Make sure the grid tab switcher is scrolled down to show the selected tab. - mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( - org.chromium.chrome.tab_ui.R.id.tab_list_view), + mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "10_web_tabs-select_last"); + leaveGTS(); } @Test @@ -207,8 +194,6 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_Incognito() throws InterruptedException, IOException { - mSkipAssertThumbnailsAreReleased = true; - // Prepare some incognito tabs and enter tab switcher. prepareTabs(1, 3, mUrl); assertTrue(mActivityTestRule.getActivity().getCurrentTabModel().isIncognito()); @@ -216,9 +201,28 @@ TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); enterGTS(); - mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( - org.chromium.chrome.tab_ui.R.id.tab_list_view), + mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "3_incognito_web_tabs"); + leaveGTS(); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + @CommandLineFlags.Add({BASE_PARAMS}) + public void testRenderGrid_3IncognitoNTPs() throws InterruptedException, IOException { + // Prepare some incognito native tabs and enter tab switcher. + // NTP in incognito mode is chosen for its consistency in look, and we don't have to mock + // away the MV tiles, login promo, feed, etc. + prepareTabs(1, 3, null); + assertTrue(mActivityTestRule.getActivity().getCurrentTabModel().isIncognito()); + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); + + enterGTS(); + mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), + "3_incognito_ntps"); + leaveGTS(); } @Test @@ -311,119 +315,18 @@ /** * Make Chrome have {@code numTabs} of regular Tabs and {@code numIncognitoTabs} of incognito - * tabs with {@code url} loaded. + * tabs with {@code url} loaded, and assert no bitmap fetching occurred. * * @param numTabs The number of regular tabs. * @param numIncognitoTabs The number of incognito tabs. * @param url The URL to load. */ private void prepareTabs(int numTabs, int numIncognitoTabs, @Nullable String url) { - assertTrue(numTabs >= 1); - assertTrue(numIncognitoTabs >= 0); - int oldCount = mTabListDelegate.getBitmapFetchCountForTesting(); - assertEquals(1, - mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount()); - assertEquals( - 0, mActivityTestRule.getActivity().getTabModelSelector().getModel(true).getCount()); - - if (numTabs == 1) { - if (url != null) mActivityTestRule.loadUrl(url); - } else { - // When Chrome started, there is already one Tab created by default. - createTabs(numTabs - 1, url, true, false); - } - if (numIncognitoTabs > 0) createTabs(numIncognitoTabs, url, true, true); - - assertEquals(numTabs, - mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount()); - assertEquals(numIncognitoTabs, - mActivityTestRule.getActivity().getTabModelSelector().getModel(true).getCount()); + TabUiTestHelper.prepareTabsWithThumbnail(mActivityTestRule, numTabs, numIncognitoTabs, url); assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting() - oldCount); } - /** - * When Chrome started, there is already one Tab created by default. This method is used to add - * additional {@code numTabs} of {@link Tab}s with {@code url} loaded to Chrome. - * @param numTabs The number of tabs to create. - * @param url The URL to load. Skip loading when null, but the thumbnail for the NTP might not - * be saved. - * @param waitForLoading Whether wait for URL loading. - * @param isIncognito Whether the tab is incognito tab. - */ - private void createTabs( - int numTabs, @Nullable String url, boolean waitForLoading, boolean isIncognito) { - assertTrue(numTabs >= 1); - - if (url != null) mActivityTestRule.loadUrl(url); - - int previousTabCount = mActivityTestRule.getActivity() - .getTabModelSelector() - .getModel(isIncognito) - .getCount(); - - for (int i = 0; i < numTabs; i++) { - TabModel previousTabModel = - mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel(); - int previousTabIndex = previousTabModel.index(); - Tab previousTab = previousTabModel.getTabAt(previousTabIndex); - - ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(), - mActivityTestRule.getActivity(), isIncognito, waitForLoading); - - if (url != null) mActivityTestRule.loadUrl(url); - if (!waitForLoading) continue; - - TabModel currentTabModel = - mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel(); - int currentTabIndex = currentTabModel.index(); - - boolean fixPendingReadbacks = mActivityTestRule.getActivity() - .getTabContentManager() - .getPendingReadbacksForTesting() - != 0; - - // When there are pending readbacks due to detached Tabs, try to fix it by switching - // back to that tab. - if (fixPendingReadbacks && previousTabIndex != TabModel.INVALID_TAB_INDEX) { - // clang-format off - TestThreadUtils.runOnUiThreadBlocking(() -> - previousTabModel.setIndex(previousTabIndex, TabSelectionType.FROM_USER) - ); - // clang-format on - } - - checkThumbnailsExist(previousTab); - - if (fixPendingReadbacks) { - // clang-format off - TestThreadUtils.runOnUiThreadBlocking(() -> currentTabModel.setIndex( - currentTabIndex, TabSelectionType.FROM_USER) - ); - // clang-format on - } - } - - ChromeTabUtils.waitForTabPageLoaded(mActivityTestRule.getActivity().getActivityTab(), null, - null, WAIT_TIMEOUT_SECONDS * 10); - - assertEquals(numTabs + previousTabCount, - mActivityTestRule.getActivity() - .getTabModelSelector() - .getModel(isIncognito) - .getCount()); - - if (waitForLoading) { - // clang-format off - CriteriaHelper.pollUiThread(Criteria.equals(0, () -> - mActivityTestRule.getActivity() - .getTabContentManager() - .getPendingReadbacksForTesting() - )); - // clang-format on - } - } - private void testTabToGrid(String fromUrl) throws InterruptedException { mActivityTestRule.loadUrl(fromUrl); @@ -476,10 +379,12 @@ if (!isEmulator()) return; for (int i = 0; i < 10; i++) { - mActivityTestRule.loadUrl(mUrl); // Quickly create some tabs, navigate to web pages, and don't wait for thumbnail // capturing. - createTabs(1, mUrl, false, false); + mActivityTestRule.loadUrl(mUrl); + ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(), + mActivityTestRule.getActivity(), false, false); + mActivityTestRule.loadUrl(mUrl); // Hopefully we are in a state where some pending readbacks are stuck because their tab // is not attached to the view. if (mActivityTestRule.getActivity() @@ -563,7 +468,7 @@ waitForCaptureRateControl(); } int count = getCaptureCount(); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + onView(withId(R.id.tab_list_view)) .perform(RecyclerViewActions.actionOnItemAtPosition(targetIndex, click())); CriteriaHelper.pollUiThread(() -> { boolean doneHiding = @@ -686,16 +591,16 @@ public void testIncognitoEnterGts() throws InterruptedException { prepareTabs(1, 1, null); enterGTS(); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + onView(withId(R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(1)); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + onView(withId(R.id.tab_list_view)) .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); CriteriaHelper.pollInstrumentationThread( () -> !mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); enterGTS(); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + onView(withId(R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(1)); } @@ -708,16 +613,16 @@ // Prepare two incognito tabs and enter tab switcher. prepareTabs(1, 2, mUrl); enterGTS(); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + onView(withId(R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(2)); for (int i = 0; i < mRepeat; i++) { switchTabModel(false); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + onView(withId(R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(1)); switchTabModel(true); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + onView(withId(R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(2)); } leaveGTS(); @@ -819,7 +724,7 @@ } } checkCaptureCount(delta, count); - if (checkThumbnail) checkThumbnailsExist(currentTab); + if (checkThumbnail) TabUiTestHelper.checkThumbnailsExist(currentTab); } private void leaveGTS() { @@ -859,18 +764,6 @@ Criteria.equals(expectedDelta, () -> getCaptureCount() - initCount)); } - private void checkThumbnailsExist(Tab tab) { - File etc1File = TabContentManager.getTabThumbnailFileEtc1(tab); - CriteriaHelper.pollInstrumentationThread(etc1File::exists, - "The thumbnail " + etc1File.getName() + " is not found", - DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL); - - File jpegFile = TabContentManager.getTabThumbnailFileJpeg(tab); - CriteriaHelper.pollInstrumentationThread(jpegFile::exists, - "The thumbnail " + jpegFile.getName() + " is not found", - DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL); - } - private int getCaptureCount() { return RecordHistogram.getHistogramTotalCountForTesting("Compositing.CopyFromSurfaceTime"); }
diff --git a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java index 714a414..e2a6ebe5 100644 --- a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java +++ b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java
@@ -8,11 +8,13 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_FAKE_SEARCH_BOX_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_INCOGNITO; +import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_VOICE_RECOGNITION_BUTTON_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MV_TILES_VISIBLE; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_EXPLORE_SURFACE_VISIBLE; @@ -34,7 +36,10 @@ import org.chromium.chrome.browser.ntp.FakeboxDelegate; import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; +import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.TasksSurfaceProperties; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; @@ -57,14 +62,20 @@ @Mock private TabModelSelector mTabModelSelector; @Mock + private TabModel mNormalTabModel; + @Mock private FakeboxDelegate mFakeBoxDelegate; @Mock + private ExploreSurfaceCoordinator.FeedSurfaceCreator mFeedSurfaceCreator; + @Mock private NightModeStateProvider mNightModeStateProvider; @Mock private LocationBarVoiceRecognitionHandler mLocationBarVoiceRecognitionHandler; @Captor private ArgumentCaptor<EmptyTabModelSelectorObserver> mTabModelSelectorObserverCaptor; @Captor + private ArgumentCaptor<EmptyTabModelObserver> mTabModelObserverCaptor; + @Captor private ArgumentCaptor<OverviewModeObserver> mOverviewModeObserverCaptor; @Captor private ArgumentCaptor<UrlFocusChangeListener> mUrlFocusChangeListenerCaptor; @@ -78,6 +89,7 @@ new ArrayList<>(Arrays.asList(TasksSurfaceProperties.ALL_KEYS)); allProperties.addAll(Arrays.asList(StartSurfaceProperties.ALL_KEYS)); mPropertyModel = new PropertyModel(allProperties); + doReturn(mNormalTabModel).when(mTabModelSelector).getModel(false); } @After @@ -154,10 +166,71 @@ } // TODO(crbug.com/1020223): Test SurfaceMode.SINGLE_PANE and SurfaceMode.TWO_PANES modes. + @Test + public void hideTabCarouselWithNoTabs() { + doReturn(false).when(mTabModelSelector).isIncognitoSelected(); + doReturn(mLocationBarVoiceRecognitionHandler) + .when(mFakeBoxDelegate) + .getLocationBarVoiceRecognitionHandler(); + doReturn(true).when(mLocationBarVoiceRecognitionHandler).isVoiceSearchEnabled(); + + StartSurfaceMediator mediator = createStartSurfaceMediator(SurfaceMode.SINGLE_PANE); + verify(mNormalTabModel).addObserver(mTabModelObserverCaptor.capture()); + + doReturn(0).when(mNormalTabModel).getCount(); + mediator.showOverview(false); + assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); + assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(false)); + } + + @Test + public void hideTabCarouselWhenClosingLastTab() { + doReturn(false).when(mTabModelSelector).isIncognitoSelected(); + doReturn(mLocationBarVoiceRecognitionHandler) + .when(mFakeBoxDelegate) + .getLocationBarVoiceRecognitionHandler(); + doReturn(true).when(mLocationBarVoiceRecognitionHandler).isVoiceSearchEnabled(); + + StartSurfaceMediator mediator = createStartSurfaceMediator(SurfaceMode.SINGLE_PANE); + verify(mNormalTabModel).addObserver(mTabModelObserverCaptor.capture()); + + doReturn(1).when(mNormalTabModel).getCount(); + mediator.showOverview(false); + assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); + assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(true)); + + doReturn(0).when(mNormalTabModel).getCount(); + mTabModelObserverCaptor.getValue().willCloseTab(mock(Tab.class), false); + assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); + assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(false)); + } + + @Test + public void reshowTabCarouselWhenTabClosureUndone() { + doReturn(false).when(mTabModelSelector).isIncognitoSelected(); + doReturn(mLocationBarVoiceRecognitionHandler) + .when(mFakeBoxDelegate) + .getLocationBarVoiceRecognitionHandler(); + doReturn(true).when(mLocationBarVoiceRecognitionHandler).isVoiceSearchEnabled(); + + StartSurfaceMediator mediator = createStartSurfaceMediator(SurfaceMode.SINGLE_PANE); + verify(mNormalTabModel).addObserver(mTabModelObserverCaptor.capture()); + + doReturn(1).when(mNormalTabModel).getCount(); + mediator.showOverview(false); + mTabModelObserverCaptor.getValue().willCloseTab(mock(Tab.class), false); + assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); + assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(false)); + + mTabModelObserverCaptor.getValue().tabClosureUndone(mock(Tab.class)); + assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); + assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(true)); + } private StartSurfaceMediator createStartSurfaceMediator(@SurfaceMode int mode) { return new StartSurfaceMediator(mMainTabGridController, mTabModelSelector, - mode == SurfaceMode.NO_START_SURFACE ? null : mPropertyModel, null, null, mode, + mode == SurfaceMode.NO_START_SURFACE ? null : mPropertyModel, + mode == SurfaceMode.SINGLE_PANE ? mFeedSurfaceCreator : null, null, mode, mFakeBoxDelegate, mNightModeStateProvider); } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediator.java index 16ca0ab..409941d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediator.java
@@ -7,7 +7,7 @@ import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_TEXT_WATCHER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_FAKE_SEARCH_BOX_VISIBLE; -import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL; +import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_VOICE_RECOGNITION_BUTTON_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.VOICE_SEARCH_BUTTON_CLICK_LISTENER; @@ -36,7 +36,7 @@ assert mFakeboxDelegate != null; mModel = model; - mModel.set(IS_TAB_CAROUSEL, isTabCarousel); + mModel.set(IS_TAB_CAROUSEL_VISIBLE, isTabCarousel); mModel.set(FAKE_SEARCH_BOX_CLICK_LISTENER, new View.OnClickListener() { @Override public void onClick(View v) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java index b931fdb..cf541dd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java
@@ -20,7 +20,7 @@ new PropertyModel.WritableBooleanPropertyKey(); public static final PropertyModel.WritableBooleanPropertyKey IS_INCOGNITO = new PropertyModel.WritableBooleanPropertyKey(); - public static final PropertyModel.WritableBooleanPropertyKey IS_TAB_CAROUSEL = + public static final PropertyModel.WritableBooleanPropertyKey IS_TAB_CAROUSEL_VISIBLE = new PropertyModel.WritableBooleanPropertyKey(); public static final PropertyModel .WritableBooleanPropertyKey IS_VOICE_RECOGNITION_BUTTON_VISIBLE = @@ -39,7 +39,7 @@ .WritableObjectPropertyKey<View.OnClickListener> VOICE_SEARCH_BUTTON_CLICK_LISTENER = new PropertyModel.WritableObjectPropertyKey<View.OnClickListener>(); public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {IS_FAKE_SEARCH_BOX_VISIBLE, - IS_INCOGNITO, IS_TAB_CAROUSEL, IS_VOICE_RECOGNITION_BUTTON_VISIBLE, + IS_INCOGNITO, IS_TAB_CAROUSEL_VISIBLE, IS_VOICE_RECOGNITION_BUTTON_VISIBLE, FAKE_SEARCH_BOX_CLICK_LISTENER, FAKE_SEARCH_BOX_TEXT_WATCHER, MORE_TABS_CLICK_LISTENER, MV_TILES_VISIBLE, VOICE_SEARCH_BUTTON_CLICK_LISTENER}; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java index 67095c2..4c884c7 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java
@@ -59,15 +59,12 @@ } /** - * Sets whether the tasks view should behave in Carousel mode. - * @param isTabCarousel whether the tab switcher is in .CAROUSEL mode + * Set the visibility of the tab carousel. + * @param isVisible Whether it's visible. */ - void setIsTabCarousel(boolean isTabCarousel) { - if (isTabCarousel) { - // TODO(crbug.com/982018): Change view according to incognito and dark mode. - findViewById(R.id.tab_switcher_title).setVisibility(View.VISIBLE); - mCarouselTabSwitcherContainer.setVisibility(View.VISIBLE); - } + void setTabCarouselVisibility(boolean isVisible) { + mCarouselTabSwitcherContainer.setVisibility(isVisible ? View.VISIBLE : View.GONE); + findViewById(R.id.tab_switcher_title).setVisibility(isVisible ? View.VISIBLE : View.GONE); } /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java index 3016070..033dd49 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java
@@ -8,7 +8,7 @@ import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_TEXT_WATCHER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_FAKE_SEARCH_BOX_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_INCOGNITO; -import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL; +import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_VOICE_RECOGNITION_BUTTON_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MORE_TABS_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MV_TILES_VISIBLE; @@ -30,8 +30,8 @@ view.setFakeSearchBoxVisibility(model.get(IS_FAKE_SEARCH_BOX_VISIBLE)); } else if (propertyKey == IS_INCOGNITO) { view.setIncognitoMode(model.get(IS_INCOGNITO)); - } else if (propertyKey == IS_TAB_CAROUSEL) { - view.setIsTabCarousel(model.get(IS_TAB_CAROUSEL)); + } else if (propertyKey == IS_TAB_CAROUSEL_VISIBLE) { + view.setTabCarouselVisibility(model.get(IS_TAB_CAROUSEL_VISIBLE)); } else if (propertyKey == IS_VOICE_RECOGNITION_BUTTON_VISIBLE) { view.setVoiceRecognitionButtonVisibility( model.get(IS_VOICE_RECOGNITION_BUTTON_VISIBLE));
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index 1e83aae8..c67f1dd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -129,6 +129,13 @@ }, TabGridViewBinder::bindClosableTab); recyclerListener = (holder) -> { + int holderItemViewType = holder.getItemViewType(); + + if (holderItemViewType != UiType.CLOSABLE + && holderItemViewType != UiType.SELECTABLE) { + return; + } + ViewLookupCachingFrameLayout root = (ViewLookupCachingFrameLayout) holder.itemView; ImageView thumbnail = (ImageView) root.fastFindViewById(R.id.tab_thumbnail); if (thumbnail == null) return; @@ -305,4 +312,13 @@ PropertyModelChangeProcessor.ViewBinder<PropertyModel, T, PropertyKey> binder) { mAdapter.registerType(typeId, builder, binder); } + + /** + * Inserts a special {@link org.chromium.ui.modelutil.MVCListAdapter.ListItem} at given index of + * the model list. + * @see TabListMediator#addSpecialItemToModel(int, int, PropertyModel). + */ + void addSpecialListItem(int index, @UiType int uiType, PropertyModel model) { + mMediator.addSpecialItemToModel(index, uiType, model); + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index 23082cd..4b2aaed 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -1155,4 +1155,17 @@ void setTabRestoreCompletedForTesting(boolean isRestored) { mTabRestoreCompleted = isRestored; } + + /** + * Inserts a special {@link org.chromium.ui.modelutil.MVCListAdapter.ListItem} at given index of + * the current {@link TabListModel}. + * + * @param index The index of the {@link org.chromium.ui.modelutil.MVCListAdapter.ListItem} to be + * inserted. + * @param uiType The view type the model will bind to. + * @param model The model that will be bound to a view. + */ + void addSpecialItemToModel(int index, @UiType int uiType, PropertyModel model) { + mModel.add(index, new SimpleRecyclerViewAdapter.ListItem(uiType, model)); + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java index 9e15da9f..921b9b7 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java
@@ -23,13 +23,14 @@ */ public class TabProperties { /** IDs for possible types of UI in the tab list. */ - @IntDef({UiType.SELECTABLE, UiType.CLOSABLE, UiType.STRIP, UiType.MESSAGE}) + @IntDef({UiType.SELECTABLE, UiType.CLOSABLE, UiType.STRIP, UiType.MESSAGE, UiType.DIVIDER}) @Retention(RetentionPolicy.SOURCE) public @interface UiType { int SELECTABLE = 0; int CLOSABLE = 1; int STRIP = 2; int MESSAGE = 3; + int DIVIDER = 4; } public static final PropertyModel.WritableIntPropertyKey TAB_ID =
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java index 22ade65..964e68e0 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.tasks.tab_management; import android.content.Context; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -38,6 +40,14 @@ void show(List<Tab> tabs); /** + * Shows the TabSelectionEditor with the given {@Link Tab}s, and the first + * {@code preSelectedTabCount} tabs being selected. + * @param tabs List of {@link Tab}s to show. + * @param preSelectedTabCount Number of selected {@link Tab}s. + */ + void show(List<Tab> tabs, int preSelectedTabCount); + + /** * Hides the TabSelectionEditor. */ void hide(); @@ -79,10 +89,32 @@ mContext = context; mParentView = parentView; mTabModelSelector = tabModelSelector; + mTabListCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context, mTabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, false, null, null, null, TabProperties.UiType.SELECTABLE, this::getSelectionDelegate, null, null, false, COMPONENT_NAME); + mTabListCoordinator.registerItemType(TabProperties.UiType.DIVIDER, () -> { + return LayoutInflater.from(context).inflate(R.layout.divider_preference, null, false); + }, (model, view, propertyKey) -> {}); + RecyclerView.LayoutManager layoutManager = + mTabListCoordinator.getContainerView().getLayoutManager(); + if (layoutManager instanceof GridLayoutManager) { + ((GridLayoutManager) layoutManager) + .setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int i) { + int itemType = mTabListCoordinator.getContainerView() + .getAdapter() + .getItemViewType(i); + + if (itemType == TabProperties.UiType.DIVIDER) { + return ((GridLayoutManager) layoutManager).getSpanCount(); + } + return 1; + } + }); + } mTabSelectionEditorLayout = LayoutInflater.from(context) .inflate(R.layout.tab_selection_editor_layout, null) @@ -108,9 +140,16 @@ /** * Resets {@link TabListCoordinator} with the provided list. * @param tabs List of {@link Tab}s to reset. + * @param preSelectedCount First {@code preSelectedCount} {@code tabs} are pre-selected. */ - void resetWithListOfTabs(@Nullable List<Tab> tabs) { + void resetWithListOfTabs(@Nullable List<Tab> tabs, int preSelectedCount) { mTabListCoordinator.resetWithListOfTabs(tabs); + + if (tabs != null && preSelectedCount > 0) { + assert preSelectedCount < tabs.size(); + mTabListCoordinator.addSpecialListItem( + preSelectedCount, TabProperties.UiType.DIVIDER, new PropertyModel()); + } } /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java index 58ee797..3abfada 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java
@@ -29,7 +29,9 @@ import org.chromium.ui.modelutil.PropertyModel; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * This class is the mediator that contains all business logic for TabSelectionEditor component. It @@ -45,8 +47,9 @@ /** * Handles the reset event. * @param tabs List of {@link Tab}s to reset. + * @param preSelectedCount First {@code preSelectedCount} {@code tabs} are pre-selected. */ - void resetWithListOfTabs(@Nullable List<Tab> tabs); + void resetWithListOfTabs(@Nullable List<Tab> tabs, int preSelectedCount); } /** @@ -181,8 +184,27 @@ */ @Override public void show(List<Tab> tabs) { - mResetHandler.resetWithListOfTabs(tabs); + show(tabs, 0); + } + + @Override + public void show(List<Tab> tabs, int preSelectedTabCount) { mSelectionDelegate.setSelectionModeEnabledForZeroItems(true); + + if (preSelectedTabCount > 0) { + assert preSelectedTabCount <= tabs.size(); + + Set<Integer> preSelectedTabIds = new HashSet<>(); + + for (int i = 0; i < preSelectedTabCount; i++) { + preSelectedTabIds.add(tabs.get(i).getId()); + } + + mSelectionDelegate.setSelectedItems(preSelectedTabIds); + } + + mResetHandler.resetWithListOfTabs(tabs, preSelectedTabCount); + if (mPositionProvider != null) { mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_POSITION_RECT, mPositionProvider.getSelectionEditorPositionRect()); @@ -221,7 +243,7 @@ @Override public void hide() { - mResetHandler.resetWithListOfTabs(null); + mResetHandler.resetWithListOfTabs(null, 0); mModel.set(TabSelectionEditorProperties.IS_VISIBLE, false); }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/RecyclerViewMatcherUtils.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/RecyclerViewMatcherUtils.java index fd9d81b..5d24075e 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/RecyclerViewMatcherUtils.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/RecyclerViewMatcherUtils.java
@@ -10,6 +10,7 @@ import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; /** * Contains useful RecyclerViewMatcher. @@ -66,4 +67,75 @@ } }; } + + /** + * This matcher matches RecyclerView that has a ViewHolder that matches the given view holder + * matcher at the given adapter position. + * + * @param position The adapter position. + * @param viewHolderMatcher A view holder to match. + * @return A matcher that matches view at adapter position and matches the given viewHolder + * matcher. + */ + public static Matcher<View> atPositionWithViewHolder( + int position, Matcher<RecyclerView.ViewHolder> viewHolderMatcher) { + return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) { + @Override + protected boolean matchesSafely(RecyclerView recyclerView) { + recyclerView.scrollToPosition(position); + RecyclerView.ViewHolder viewHolder = + recyclerView.findViewHolderForAdapterPosition(position); + + if (viewHolder == null) return false; + + return viewHolderMatcher.matches(viewHolder); + } + + @Override + public void describeTo(Description description) { + description.appendText(viewHolderMatcher + " at position " + position); + } + }; + } + + /** + * This matcher matches the ViewHolder that has an adapter position equals to the given + * position. + * + * @param position The position to match. + * @return A matcher that matches the viewHolder at the given position. + */ + public static Matcher<RecyclerView.ViewHolder> withViewHolderAtPosition(int position) { + return new TypeSafeMatcher<RecyclerView.ViewHolder>() { + @Override + protected boolean matchesSafely(RecyclerView.ViewHolder viewHolder) { + return viewHolder.getAdapterPosition() == position; + } + + @Override + public void describeTo(Description description) { + description.appendText("ViewHolder with adapter position: " + position); + } + }; + } + + /** + * This matcher matches a ViewHolder that has the given item type. + * + * @param itemType The item type to match. + * @return A matcher that matches a ViewHolder with the given item type. + */ + public static Matcher<RecyclerView.ViewHolder> withItemType(int itemType) { + return new TypeSafeMatcher<RecyclerView.ViewHolder>() { + @Override + protected boolean matchesSafely(RecyclerView.ViewHolder viewHolder) { + return viewHolder.getItemViewType() == itemType; + } + + @Override + public void describeTo(Description description) { + description.appendText("ViewHolder with item type: " + itemType); + } + }; + } }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java index 1565ff4..0964ab50 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tasks.tab_management; import android.os.Build; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import org.junit.Before; @@ -24,6 +25,7 @@ import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.browser.Features; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiRestriction; @@ -183,6 +185,58 @@ mRobot.resultRobot.verifyToolbarActionButtonDisabled(); } + @Test + @MediumTest + public void testShowTabsWithPreSelectedTabs() { + List<Tab> tabs = getTabsInCurrentTabModel(); + int preSelectedTabCount = 1; + TestThreadUtils.runOnUiThreadBlocking( + () -> { mTabSelectionEditorController.show(tabs, preSelectedTabCount); }); + + mRobot.resultRobot.verifyTabSelectionEditorIsVisible() + .verifyToolbarActionButtonDisabled() + .verifyToolbarActionButtonWithResourceId(R.string.tab_selection_editor_group) + .verifyToolbarSelectionText("1 selected") + .verifyHasAtLeastNItemVisible(tabs.size() + 1) + .verifyItemSelectedAtAdapterPosition(0) + .verifyHasItemViewTypeAtAdapterPosition(1, TabProperties.UiType.DIVIDER) + .verifyDividerAlwaysStartsAtTheEdgeOfScreen(); + } + + @Test + @MediumTest + public void testShowTabsWithPreSelectedTabs_10Tabs() { + int preSelectedTabCount = 10; + int additionalTabCount = + preSelectedTabCount + 1 - mTabModelSelector.getCurrentModel().getCount(); + + for (int i = 0; i < additionalTabCount; i++) { + ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(), + mActivityTestRule.getActivity(), mTabModelSelector.isIncognitoSelected(), true); + } + + List<Tab> tabs = getTabsInCurrentTabModel(); + + TestThreadUtils.runOnUiThreadBlocking( + () -> { mTabSelectionEditorController.show(tabs, preSelectedTabCount); }); + + mRobot.resultRobot.verifyToolbarSelectionText("10 selected") + .verifyHasItemViewTypeAtAdapterPosition( + preSelectedTabCount, TabProperties.UiType.DIVIDER) + .verifyDividerAlwaysStartsAtTheEdgeOfScreenAtPosition(preSelectedTabCount); + } + + @Test + @MediumTest + public void testDividerIsNotClickable() { + List<Tab> tabs = getTabsInCurrentTabModel(); + int preSelectedTabCount = 1; + TestThreadUtils.runOnUiThreadBlocking( + () -> { mTabSelectionEditorController.show(tabs, preSelectedTabCount); }); + + mRobot.resultRobot.verifyDividerNotClickableNotFocusable(); + } + private List<Tab> getTabsInCurrentTabModel() { List<Tab> tabs = new ArrayList<>();
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTestingRobot.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTestingRobot.java index dc501bfd3..821ba65 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTestingRobot.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTestingRobot.java
@@ -8,9 +8,12 @@ import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; +import static android.support.test.espresso.contrib.RecyclerViewActions.scrollToPosition; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; +import static android.support.test.espresso.matcher.ViewMatchers.isClickable; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isEnabled; +import static android.support.test.espresso.matcher.ViewMatchers.isFocusable; import static android.support.test.espresso.matcher.ViewMatchers.withClassName; import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; import static android.support.test.espresso.matcher.ViewMatchers.withId; @@ -21,6 +24,10 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; +import static org.chromium.chrome.browser.tasks.tab_management.RecyclerViewMatcherUtils.atPosition; +import static org.chromium.chrome.browser.tasks.tab_management.RecyclerViewMatcherUtils.atPositionWithViewHolder; +import static org.chromium.chrome.browser.tasks.tab_management.RecyclerViewMatcherUtils.withItemType; + import android.os.Build; import android.support.test.espresso.NoMatchingRootException; import android.support.test.espresso.Root; @@ -41,7 +48,7 @@ /** * @return A root matcher that matches the TabSelectionEditor popup decor view. */ - private static Matcher<Root> isTabSelectionEditorPopup() { + public static Matcher<Root> isTabSelectionEditorPopup() { return new TypeSafeMatcher<Root>() { @Override public void describeTo(Description description) { @@ -66,7 +73,7 @@ /** * @return A view matcher that matches the item is selected. */ - private static Matcher<View> itemIsSelected() { + public static Matcher<View> itemIsSelected() { return new BoundedMatcher<View, SelectableTabGridView>(SelectableTabGridView.class) { private SelectableTabGridView mSelectableTabGridView; @Override @@ -105,6 +112,23 @@ }; } + /** + * @return A view matcher that matches a divider view. + */ + public static Matcher<View> isDivider() { + return new TypeSafeMatcher<View>() { + @Override + protected boolean matchesSafely(View view) { + return view.getId() == org.chromium.chrome.tab_ui.R.id.divider_view; + } + + @Override + public void describeTo(Description description) { + description.appendText("is divider"); + } + }; + } + public final TabSelectionEditorTestingRobot.Result resultRobot; public final TabSelectionEditorTestingRobot.Action actionRobot; @@ -252,5 +276,67 @@ onView(withText(text)).check(matches(isDisplayed())); return this; } + + Result verifyDividerAlwaysStartsAtTheEdgeOfScreen() { + onView(allOf(isDivider(), + withParent(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)))) + .inRoot(isTabSelectionEditorPopup()) + .check(matches(isDisplayed())) + .check((v, noMatchException) -> { + if (noMatchException != null) throw noMatchException; + + View parentView = (View) v.getParent(); + Assert.assertEquals(parentView.getPaddingStart(), (int) v.getX()); + }); + return this; + } + + Result verifyDividerAlwaysStartsAtTheEdgeOfScreenAtPosition(int position) { + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + .inRoot(isTabSelectionEditorPopup()) + .perform(scrollToPosition(position)); + + onView(atPosition(position, isDivider())) + .inRoot(isTabSelectionEditorPopup()) + .check(matches(isDisplayed())) + .check((v, noMatchException) -> { + if (noMatchException != null) throw noMatchException; + + View parentView = (View) v.getParent(); + Assert.assertEquals(parentView.getPaddingStart(), (int) v.getX()); + }); + + return this; + } + + Result verifyDividerNotClickableNotFocusable() { + onView(allOf(isDivider(), + withParent(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)))) + .inRoot(isTabSelectionEditorPopup()) + .check(matches(not(isClickable()))) + .check(matches(not(isFocusable()))); + return this; + } + + /** + * Verifies the TabSelectionEditor has an ItemView at given position that matches the given + * targetItemViewType. + * + * First this method scrolls to the given adapter position to make sure ViewHolder for the + * given position is visible. + * + * @param position Adapter position. + * @param targetItemViewType The item view type to be matched. + * @return {@link Result} to do chain verification. + */ + Result verifyHasItemViewTypeAtAdapterPosition(int position, int targetItemViewType) { + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + .inRoot(isTabSelectionEditorPopup()) + .perform(scrollToPosition(position)); + onView(atPositionWithViewHolder(position, withItemType(targetItemViewType))) + .inRoot(isTabSelectionEditorPopup()) + .check(matches(isDisplayed())); + return this; + } } }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java index cf8a3254..1a77451f 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -14,10 +14,15 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.chromium.base.test.util.CallbackHelper.WAIT_TIMEOUT_SECONDS; +import static org.chromium.content_public.browser.test.util.CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL; +import static org.chromium.content_public.browser.test.util.CriteriaHelper.DEFAULT_POLLING_INTERVAL; + import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.os.Build; import android.provider.Settings; +import android.support.annotation.Nullable; import android.support.test.InstrumentationRegistry; import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.ViewAssertion; @@ -27,15 +32,20 @@ import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.ChromeTabbedActivity; +import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabSelectionType; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.tab_ui.R; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import java.io.File; import java.util.List; /** @@ -194,6 +204,121 @@ } /** + * Make Chrome have {@code numTabs} of regular Tabs and {@code numIncognitoTabs} of incognito + * tabs with {@code url} loaded. + * @param rule The {@link ChromeTabbedActivityTestRule}. + * @param numTabs The number of regular tabs. + * @param numIncognitoTabs The number of incognito tabs. + * @param url The URL to load. + */ + public static void prepareTabsWithThumbnail(ChromeTabbedActivityTestRule rule, int numTabs, + int numIncognitoTabs, @Nullable String url) { + assertTrue(numTabs >= 1); + assertTrue(numIncognitoTabs >= 0); + + assertEquals(1, rule.getActivity().getTabModelSelector().getModel(false).getCount()); + assertEquals(0, rule.getActivity().getTabModelSelector().getModel(true).getCount()); + + if (url != null) rule.loadUrl(url); + if (numTabs > 1) { + // When Chrome started, there is already one Tab created by default. + createTabsWithThumbnail(rule, numTabs - 1, url, false); + } + if (numIncognitoTabs > 0) createTabsWithThumbnail(rule, numIncognitoTabs, url, true); + + assertEquals(numTabs, rule.getActivity().getTabModelSelector().getModel(false).getCount()); + assertEquals(numIncognitoTabs, + rule.getActivity().getTabModelSelector().getModel(true).getCount()); + if (url != null) { + verifyAllTabsHaveUrl(rule.getActivity().getTabModelSelector().getModel(false), url); + verifyAllTabsHaveUrl(rule.getActivity().getTabModelSelector().getModel(true), url); + } + } + + private static void verifyAllTabsHaveUrl(TabModel tabModel, String url) { + for (int i = 0; i < tabModel.getCount(); i++) { + assertEquals(url, tabModel.getTabAt(i).getUrl()); + } + } + + /** + * Create {@code numTabs} of {@link Tab}s with {@code url} loaded to Chrome. + * Note that if the test doesn't care about thumbnail, use {@link TabUiTestHelper#createTabs} + * instead since it's faster. + * + * @param rule The {@link ChromeTabbedActivityTestRule}. + * @param numTabs The number of tabs to create. + * @param url The URL to load. Skip loading when null, but the thumbnail for the NTP might not + * be saved. + * @param isIncognito Whether the tab is incognito tab. + */ + private static void createTabsWithThumbnail(ChromeTabbedActivityTestRule rule, int numTabs, + @Nullable String url, boolean isIncognito) { + assertTrue(numTabs >= 1); + + int previousTabCount = + rule.getActivity().getTabModelSelector().getModel(isIncognito).getCount(); + + for (int i = 0; i < numTabs; i++) { + TabModel previousTabModel = rule.getActivity().getTabModelSelector().getCurrentModel(); + int previousTabIndex = previousTabModel.index(); + Tab previousTab = previousTabModel.getTabAt(previousTabIndex); + + ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(), + rule.getActivity(), isIncognito, true); + + if (url != null) rule.loadUrl(url); + + TabModel currentTabModel = rule.getActivity().getTabModelSelector().getCurrentModel(); + int currentTabIndex = currentTabModel.index(); + + boolean fixPendingReadbacks = + rule.getActivity().getTabContentManager().getPendingReadbacksForTesting() != 0; + + // When there are pending readbacks due to detached Tabs, try to fix it by switching + // back to that tab. + if (fixPendingReadbacks && previousTabIndex != TabModel.INVALID_TAB_INDEX) { + // clang-format off + TestThreadUtils.runOnUiThreadBlocking(() -> + previousTabModel.setIndex(previousTabIndex, TabSelectionType.FROM_USER) + ); + // clang-format on + } + + checkThumbnailsExist(previousTab); + + if (fixPendingReadbacks) { + // clang-format off + TestThreadUtils.runOnUiThreadBlocking(() -> currentTabModel.setIndex( + currentTabIndex, TabSelectionType.FROM_USER) + ); + // clang-format on + } + } + + ChromeTabUtils.waitForTabPageLoaded( + rule.getActivity().getActivityTab(), null, null, WAIT_TIMEOUT_SECONDS * 10); + + assertEquals(numTabs + previousTabCount, + rule.getActivity().getTabModelSelector().getModel(isIncognito).getCount()); + + CriteriaHelper.pollUiThread(Criteria.equals(0, + () -> rule.getActivity().getTabContentManager().getPendingReadbacksForTesting())); + } + + public static void checkThumbnailsExist(Tab tab) { + File etc1File = TabContentManager.getTabThumbnailFileEtc1(tab); + CriteriaHelper.pollInstrumentationThread(etc1File::exists, + "The thumbnail " + etc1File.getName() + " is not found", + DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL); + + File jpegFile = TabContentManager.getTabThumbnailFileJpeg(tab); + CriteriaHelper.pollInstrumentationThread(jpegFile::exists, + "The thumbnail " + jpegFile.getName() + " is not found", + DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL); + } + + /** * Implementation of {@link ViewAssertion} to verify the {@link RecyclerView} has correct number * of children, and children are showing correctly. */
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediatorUnitTest.java index a677391..48994053 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediatorUnitTest.java
@@ -15,7 +15,7 @@ import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_TEXT_WATCHER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_FAKE_SEARCH_BOX_VISIBLE; -import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL; +import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.IS_VOICE_RECOGNITION_BUTTON_VISIBLE; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.VOICE_SEARCH_BUTTON_CLICK_LISTENER; @@ -75,7 +75,7 @@ @Test public void initialization() { - verify(mPropertyModel).set(eq(IS_TAB_CAROUSEL), eq(true)); + verify(mPropertyModel).set(eq(IS_TAB_CAROUSEL_VISIBLE), eq(true)); verify(mPropertyModel) .set(eq(FAKE_SEARCH_BOX_CLICK_LISTENER), mFakeboxClickListenerCaptor.capture()); verify(mPropertyModel)
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index b43dd77..97f72375 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -7,9 +7,12 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -1355,6 +1358,30 @@ verify(mRemoveEditor).apply(); } + @Test + public void addSpecialItem() { + mMediator.addSpecialItemToModel(0, TabProperties.UiType.DIVIDER, new PropertyModel()); + + assertTrue(mModel.size() > 0); + assertEquals(TabProperties.UiType.DIVIDER, mModel.get(0).type); + } + + @Test + public void addSpecialItem_notPersistOnReset() { + mMediator.addSpecialItemToModel(0, TabProperties.UiType.DIVIDER, new PropertyModel()); + assertEquals(TabProperties.UiType.DIVIDER, mModel.get(0).type); + + List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); + mMediator.resetWithListOfTabs(tabs, false, false); + assertThat(mModel.size(), equalTo(2)); + assertNotEquals(TabProperties.UiType.DIVIDER, mModel.get(0).type); + assertNotEquals(TabProperties.UiType.DIVIDER, mModel.get(1).type); + + mMediator.addSpecialItemToModel(1, TabProperties.UiType.DIVIDER, new PropertyModel()); + assertThat(mModel.size(), equalTo(3)); + assertEquals(TabProperties.UiType.DIVIDER, mModel.get(1).type); + } + private void initAndAssertAllProperties() { List<Tab> tabs = new ArrayList<>(); for (int i = 0; i < mTabModel.getCount(); i++) {
diff --git a/chrome/android/java/res/layout/divider_preference.xml b/chrome/android/java/res/layout/divider_preference.xml index 7035011..571811c 100644 --- a/chrome/android/java/res/layout/divider_preference.xml +++ b/chrome/android/java/res/layout/divider_preference.xml
@@ -3,7 +3,8 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<View +<View xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/divider_view" style="@style/HorizontalDivider" android:importantForAccessibility="no" />
diff --git a/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml b/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml index 9229373..29eb4724 100644 --- a/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml +++ b/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml
@@ -64,6 +64,7 @@ android:layout_marginTop="16dp" android:layout_toStartOf="@id/open_in_new_tab" android:layout_toEndOf="@id/favicon" + android:textAlignment="viewStart" android:ellipsize="end" android:singleLine="true" android:textAppearance="@style/TextAppearance.BlackBodyDefault" /> @@ -85,6 +86,7 @@ android:layout_toEndOf="@id/security_icon" android:layout_below="@id/ephemeral_tab_text" android:layout_marginLeft="4dp" + android:textAlignment="viewStart" android:ellipsize="start" android:singleLine="true" android:textAppearance="@style/TextAppearance.BlackHint2" />
diff --git a/chrome/android/java/res_download/layout/download_storage_summary.xml b/chrome/android/java/res_download/layout/download_storage_summary.xml index 73d0cf7..4d3d415c 100644 --- a/chrome/android/java/res_download/layout/download_storage_summary.xml +++ b/chrome/android/java/res_download/layout/download_storage_summary.xml
@@ -5,13 +5,13 @@ <TextView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/download_storage_summary" android:paddingStart="@dimen/list_item_default_margin" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:textAppearance="@style/TextAppearance.BlackDisabledText2" + android:textAlignment="viewStart" android:maxLines="1" android:paddingTop="8dp" android:paddingBottom="8dp" /> \ No newline at end of file
diff --git a/chrome/android/java/res_download/values-v17/styles.xml b/chrome/android/java/res_download/values-v17/styles.xml index fb40daf6..cc965b9 100644 --- a/chrome/android/java/res_download/values-v17/styles.xml +++ b/chrome/android/java/res_download/values-v17/styles.xml
@@ -9,6 +9,7 @@ <style name="DownloadItemText"> <item name="android:layout_width">0dp</item> <item name="android:layout_height">wrap_content</item> + <item name="android:textAlignment">viewStart</item> <item name="android:maxLines">1</item> <item name="android:ellipsize">end</item> <item name="android:singleLine">true</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java index 731c0f1..a9ea4ca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java
@@ -7,10 +7,6 @@ import android.os.Bundle; import android.util.Pair; -import org.chromium.base.ActivityState; -import org.chromium.base.ApplicationStatus; -import org.chromium.base.CommandLine; -import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabBuilder; @@ -21,7 +17,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabSelectionType; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; -import org.chromium.content_public.browser.UiThreadTaskTraits; /** * Base class for task-focused activities that need to display a single tab. @@ -32,8 +27,6 @@ */ public abstract class SingleTabActivity<C extends ChromeActivityComponent> extends ChromeActivity<C> { - private static final int PREWARM_RENDERER_DELAY_MS = 500; - protected static final String BUNDLE_TAB_ID = "tabId"; @Override @@ -136,31 +129,4 @@ @Override public void onUpdateStateChanged() {} - - @Override - public void onStopWithNative() { - super.onStopWithNative(); - if (CommandLine.getInstance().hasSwitch(ChromeSwitches.AGGRESSIVELY_PREWARM_RENDERERS)) { - PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, new Runnable() { - @Override - public void run() { - // If we're not still stopped, we don't need the spare WebContents. - if (ApplicationStatus.getStateForActivity(SingleTabActivity.this) - == ActivityState.STOPPED) { - WarmupManager.getInstance().createSpareWebContents(!WarmupManager.FOR_CCT); - } - } - }, PREWARM_RENDERER_DELAY_MS); - } - } - - @Override - public void onTrimMemory(int level) { - super.onTrimMemory(level); - if (CommandLine.getInstance().hasSwitch(ChromeSwitches.AGGRESSIVELY_PREWARM_RENDERERS)) { - if (ChromeApplication.isSevereMemorySignal(level)) { - WarmupManager.getInstance().destroySpareWebContents(); - } - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java index 27f11d1b..6574914 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java
@@ -195,6 +195,8 @@ @Override public boolean startAndExpand(boolean forward, boolean animate) { + // Called from activity for navigation popup. No need to check + // bottom sheet controller since it is guaranteed to available. start(forward, /* showCloseIndicator= */ false); mOpenedAsPopup = true; @@ -242,6 +244,7 @@ @Override public void close(boolean animate) { + if (mBottomSheetController.get() == null) return; if (!isHidden()) mBottomSheetController.get().hideContent(this, animate); mBottomSheetController.get().removeObserver(mSheetObserver); mMediator.clear(); @@ -309,7 +312,9 @@ @Override public int getPeekHeight() { - if (mOpenedAsPopup) return BottomSheetContent.HeightMode.DISABLED; + if (mBottomSheetController.get() == null || mOpenedAsPopup) { + return BottomSheetContent.HeightMode.DISABLED; + } // Makes peek state as 'not present' when bottom sheet is in expanded state (i.e. animating // from expanded to close state). It avoids the sheet animating in two distinct steps, which // looks awkward.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index be1989f..5e09720 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -1396,7 +1396,7 @@ } if (details.modifiers != null) { - if (details.modifiers.length == 0) mModifiers.clear(); + if (details.modifiers.length == 0 && mModifiers != null) mModifiers.clear(); for (int i = 0; i < details.modifiers.length; i++) { PaymentDetailsModifier modifier = details.modifiers[i];
diff --git a/chrome/android/java_templates/ChromeSwitches.java.tmpl b/chrome/android/java_templates/ChromeSwitches.java.tmpl index 1c32232..a1e48a0 100644 --- a/chrome/android/java_templates/ChromeSwitches.java.tmpl +++ b/chrome/android/java_templates/ChromeSwitches.java.tmpl
@@ -78,12 +78,6 @@ */ public static final String DISABLE_TAB_MERGING_FOR_TESTING = "disable-tab-merging"; - /** - * Aggressively pre-warms renderers when Chrome is backgrounded. Currently only works for - * SingleTabActivity-derived Activities. - */ - public static final String AGGRESSIVELY_PREWARM_RENDERERS = "aggressively-prewarm-renderers"; - /////////////////////////////////////////////////////////////////////////////////////////////// // Native Switches ///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.cc b/chrome/browser/android/vr/arcore_device/arcore_device.cc index 875a4c2..e4b222d 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_device.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_device.cc
@@ -38,13 +38,7 @@ const gfx::Size& frame_size) { mojom::VRDisplayInfoPtr device = mojom::VRDisplayInfo::New(); device->id = device_id; - device->display_name = "ARCore VR Device"; device->webxr_default_framebuffer_scale = 1.0; - device->capabilities = mojom::VRDisplayCapabilities::New(); - device->capabilities->has_position = true; - device->capabilities->has_external_display = false; - device->capabilities->can_present = false; - device->capabilities->can_provide_environment_integration = true; device->left_eye = mojom::VREyeParameters::New(); device->right_eye = nullptr; mojom::VREyeParametersPtr& left_eye = device->left_eye;
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc index e0d7db6..053f502 100644 --- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -1073,6 +1073,51 @@ NEEDS_TEST_SERVER); } +// Ensure that when one <webview> makes a window.open() call that references +// another <webview> by name, the opener is updated without a crash. Regression +// test for https://crbug.com/1013553. +IN_PROC_BROWSER_TEST_F(WebViewNewWindowInteractiveTest, + NewWindow_UpdateOpener) { + TestHelper("testNewWindowAndUpdateOpener", "web_view/newwindow", + NEEDS_TEST_SERVER); + + // The first <webview> tag in the test will run window.open(), which the + // embedder will translate into an injected second <webview> tag, after which + // test control will return here. Wait until there are two guests; i.e., + // until the second <webview>'s guest is also created. + GetGuestViewManager()->WaitForNumGuestsCreated(2); + + std::vector<content::WebContents*> guest_contents_list; + GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list); + ASSERT_EQ(2u, guest_contents_list.size()); + content::WebContents* guest1 = guest_contents_list[0]; + content::WebContents* guest2 = guest_contents_list[1]; + EXPECT_TRUE(content::WaitForLoadStop(guest1)); + EXPECT_TRUE(content::WaitForLoadStop(guest2)); + ASSERT_NE(guest1, guest2); + + // Change first guest's window.name to "foo" and check that it does not + // have an opener to start with. + EXPECT_TRUE(content::ExecJs(guest1, "window.name = 'foo'")); + EXPECT_EQ("foo", content::EvalJs(guest1, "window.name")); + EXPECT_EQ(true, content::EvalJs(guest1, "window.opener == null")); + + // Create a subframe in the second guest. This is needed because the crash + // in crbug.com/1013553 only happened when trying to incorrectly create + // proxies for a subframe. + EXPECT_TRUE(content::ExecuteScript( + guest2, "document.body.appendChild(document.createElement('iframe'));")); + + // Update the opener of |guest1| to point to |guest2|. This triggers + // creation of proxies on the new opener chain, which should not crash. + EXPECT_TRUE(content::ExecuteScript(guest2, "window.open('', 'foo');")); + + // Ensure both guests have the proper opener relationship set up. Namely, + // each guest's opener should point to the other guest, creating a cycle. + EXPECT_EQ(true, content::EvalJs(guest1, "window.opener.opener === window")); + EXPECT_EQ(true, content::EvalJs(guest2, "window.opener.opener === window")); +} + // There is a problem of missing keyup events with the command key after // the NSEvent is sent to NSApplication in ui/base/test/ui_controls_mac.mm . // This test is disabled on only the Mac until the problem is resolved.
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index fb05f6d..c2582b9 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -20,57 +20,6 @@ <structure name="IDR_NEW_TAB_4_HTML" file="resources\ntp4\new_tab.html" compress="gzip" flattenhtml="true" type="chrome_html" /> <structure name="IDR_NEW_TAB_4_THEME_CSS" file="resources\ntp4\new_tab_theme.css" compress="gzip" flattenhtml="true" type="chrome_html" /> - <!-- Bookmarks WebUI. --> - <if expr="optimize_webui"> - <then> - <structure name="IDR_BOOKMARKS_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\bookmarks\vulcanized.html" use_base_dir="false" preprocess="true" type="chrome_html" compress="gzip" /> - <structure name="IDR_BOOKMARKS_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\bookmarks\crisper.js" use_base_dir="false" preprocess="true" type="chrome_html" compress="gzip" /> - </then> - <else> - <structure name="IDR_BOOKMARKS_ACTIONS_HTML" file="resources\bookmarks\actions.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_ACTIONS_JS" file="resources\bookmarks\actions.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_API_LISTENER_HTML" file="resources\bookmarks\api_listener.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_API_LISTENER_JS" file="resources\bookmarks\api_listener.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_APP_HTML" file="resources\bookmarks\app.html" type="chrome_html" preprocess="true" /> - <structure name="IDR_BOOKMARKS_APP_JS" file="resources\bookmarks\app.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_BOOKMARKS_HTML" file="resources\bookmarks\bookmarks.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_COMMAND_MANAGER_HTML" file="resources\bookmarks\command_manager.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_COMMAND_MANAGER_JS" file="resources\bookmarks\command_manager.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_CONSTANTS_HTML" file="resources\bookmarks\constants.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_CONSTANTS_JS" file="resources\bookmarks\constants.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_DEBOUNCER_HTML" file="resources\bookmarks\debouncer.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_DEBOUNCER_JS" file="resources\bookmarks\debouncer.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_DIALOG_FOCUS_MANAGER_HTML" file="resources\bookmarks\dialog_focus_manager.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_DIALOG_FOCUS_MANAGER_JS" file="resources\bookmarks\dialog_focus_manager.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_DND_MANAGER_HTML" file="resources\bookmarks\dnd_manager.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_DND_MANAGER_JS" file="resources\bookmarks\dnd_manager.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_EDIT_DIALOG_HTML" file="resources\bookmarks\edit_dialog.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_EDIT_DIALOG_JS" file="resources\bookmarks\edit_dialog.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_FOLDER_NODE_HTML" file="resources\bookmarks\folder_node.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_FOLDER_NODE_JS" file="resources\bookmarks\folder_node.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_ITEM_HTML" file="resources\bookmarks\item.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_ITEM_JS" file="resources\bookmarks\item.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_LIST_HTML" file="resources\bookmarks\list.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_LIST_JS" file="resources\bookmarks\list.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_MOUSE_FOCUS_BEHAVIOR_HTML" file="resources\bookmarks\mouse_focus_behavior.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_MOUSE_FOCUS_BEHAVIOR_JS" file="resources\bookmarks\mouse_focus_behavior.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_REDUCERS_HTML" file="resources\bookmarks\reducers.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_REDUCERS_JS" file="resources\bookmarks\reducers.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_ROUTER_HTML" file="resources\bookmarks\router.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_ROUTER_JS" file="resources\bookmarks\router.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_SHARED_STYLE_HTML" file="resources\bookmarks\shared_style.html" preprocess="true" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_SHARED_VARS_HTML" file="resources\bookmarks\shared_vars.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_STORE_CLIENT_HTML" file="resources\bookmarks\store_client.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_STORE_CLIENT_JS" file="resources\bookmarks\store_client.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_STORE_HTML" file="resources\bookmarks\store.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_STORE_JS" file="resources\bookmarks\store.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_STRINGS_HTML" file="resources\bookmarks\strings.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_TOOLBAR_HTML" file="resources\bookmarks\toolbar.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_TOOLBAR_JS" file="resources\bookmarks\toolbar.js" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_UTIL_HTML" file="resources\bookmarks\util.html" type="chrome_html" /> - <structure name="IDR_BOOKMARKS_UTIL_JS" file="resources\bookmarks\util.js" type="chrome_html" /> - </else> - </if> </if> <if expr="chromeos"> <structure name="IDR_FIRST_RUN_HTML" file="resources\chromeos\first_run\first_run.html" compress="gzip" flattenhtml="true" type="chrome_html" />
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 8dc95a1..b31c1b5 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3987,7 +3987,7 @@ const std::string& key_system, const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols, base::flat_set<media::VideoCodec>* video_codecs, - base::flat_set<media::EncryptionMode>* encryption_schemes) { + base::flat_set<media::EncryptionScheme>* encryption_schemes) { #if defined(OS_WIN) && BUILDFLAG(ENABLE_LIBRARY_CDMS) && \ BUILDFLAG(ENABLE_WIDEVINE) if (key_system == kWidevineKeySystem) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index f0e1c292..64826f0 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -445,7 +445,7 @@ const std::string& key_system, const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols, base::flat_set<media::VideoCodec>* video_codecs, - base::flat_set<media::EncryptionMode>* encryption_schemes) override; + base::flat_set<media::EncryptionScheme>* encryption_schemes) override; ::rappor::RapporService* GetRapporService() override; #if BUILDFLAG(ENABLE_MEDIA_REMOTING) void CreateMediaRemoter(
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index b77fbc2..2e15bae 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -17,6 +17,7 @@ #include "ash/public/cpp/default_frame_header.h" #include "ash/public/cpp/desks_helper.h" #include "ash/public/cpp/frame_header.h" +#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/login_screen.h" #include "ash/public/cpp/overview_test_api.h" #include "ash/public/cpp/shelf_item.h" @@ -3056,36 +3057,43 @@ static_cast<int>(ash::AppType::ARC_APP)) { window_info.arc_package_name = std::make_unique<std::string>( *window->GetProperty(ash::kArcPackageNameKey)); - - ash::HeaderView* header_view = ash::GetHeaderViewForWindow(window); - ash::DefaultFrameHeader* frame_header = header_view->GetFrameHeader(); - window_info.caption_height = frame_header->GetHeaderHeight(); - - const ash::CaptionButtonModel* buttonModel = - header_view->caption_button_container()->model(); - int caption_button_enabled_status = 0; - int caption_button_visible_status = 0; - constexpr views::CaptionButtonIcon all_button_icons[] = { - views::CAPTION_BUTTON_ICON_MINIMIZE, - views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, - views::CAPTION_BUTTON_ICON_CLOSE, - views::CAPTION_BUTTON_ICON_LEFT_SNAPPED, - views::CAPTION_BUTTON_ICON_RIGHT_SNAPPED, - views::CAPTION_BUTTON_ICON_BACK, - views::CAPTION_BUTTON_ICON_LOCATION, - views::CAPTION_BUTTON_ICON_MENU, - views::CAPTION_BUTTON_ICON_ZOOM, - views::CAPTION_BUTTON_ICON_COUNT}; - - for (const auto button : all_button_icons) { - if (buttonModel->IsEnabled(button)) - caption_button_enabled_status |= (1 << button); - if (buttonModel->IsVisible(button)) - caption_button_visible_status |= (1 << button); - } - window_info.caption_button_enabled_status = caption_button_enabled_status; - window_info.caption_button_visible_status = caption_button_visible_status; } + + // Frame information + auto* widget = views::Widget::GetWidgetForNativeWindow(window); + auto* immersive_controller = + ash::ImmersiveFullscreenController::Get(widget); + // The widget that hosts the immersive frame can be different from the + // application's widget itself. Use the widget from the immersive + // controller to obtain the FrameHeader. + auto* frame_header = ash::FrameHeader::Get(immersive_controller->widget()); + window_info.caption_height = frame_header->GetHeaderHeight(); + + const ash::CaptionButtonModel* button_model = + frame_header->GetCaptionButtonModel(); + int caption_button_enabled_status = 0; + int caption_button_visible_status = 0; + + constexpr views::CaptionButtonIcon all_button_icons[] = { + views::CAPTION_BUTTON_ICON_MINIMIZE, + views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, + views::CAPTION_BUTTON_ICON_CLOSE, + views::CAPTION_BUTTON_ICON_LEFT_SNAPPED, + views::CAPTION_BUTTON_ICON_RIGHT_SNAPPED, + views::CAPTION_BUTTON_ICON_BACK, + views::CAPTION_BUTTON_ICON_LOCATION, + views::CAPTION_BUTTON_ICON_MENU, + views::CAPTION_BUTTON_ICON_ZOOM}; + + for (const auto button : all_button_icons) { + if (button_model->IsEnabled(button)) + caption_button_enabled_status |= (1 << button); + if (button_model->IsVisible(button)) + caption_button_visible_status |= (1 << button); + } + window_info.caption_button_enabled_status = caption_button_enabled_status; + window_info.caption_button_visible_status = caption_button_visible_status; + result_list.emplace_back(std::move(window_info)); } return RespondNow(ArgumentList(
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index 6e6c686..d0c59bb 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -162,6 +162,14 @@ return node_data; } +bool HasPermanentNodes(const std::vector<const BookmarkNode*>& list) { + for (const BookmarkNode* node : list) { + if (node->is_permanent_node()) + return true; + } + return false; +} + } // namespace BookmarkManagerPrivateEventRouter::BookmarkManagerPrivateEventRouter( @@ -316,6 +324,10 @@ error_ = bookmark_keys::kModifyManagedError; return false; } + if (cut && HasPermanentNodes(nodes)) { + error_ = bookmark_keys::kModifySpecialError; + return false; + } bookmarks::CopyToClipboard(model, nodes, cut); return true; }
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc index b5099b0..1994167 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h" +#include "base/memory/scoped_refptr.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" @@ -33,6 +34,7 @@ node_id_ = base::NumberToString(node->id()); } + const bookmarks::BookmarkModel* model() const { return model_; } std::string node_id() const { return node_id_; } private: @@ -47,15 +49,14 @@ // Regression test for https://crbug.com/739260. TEST_F(BookmarkManagerPrivateApiUnitTest, RunOnDeletedNode) { // Remove our only bookmark node. - scoped_refptr<BookmarksRemoveFunction> remove_function( - new BookmarksRemoveFunction()); + auto remove_function = base::MakeRefCounted<BookmarksRemoveFunction>(); api_test_utils::RunFunction(remove_function.get(), base::StringPrintf("[\"%s\"]", node_id().c_str()), profile()); // Call bookmarkManagerPrivate.copy() with the removed bookmark node's id. - scoped_refptr<BookmarkManagerPrivateCopyFunction> copy_function( - new BookmarkManagerPrivateCopyFunction()); + auto copy_function = + base::MakeRefCounted<BookmarkManagerPrivateCopyFunction>(); EXPECT_EQ( "Could not find bookmark nodes with given ids.", api_test_utils::RunFunctionAndReturnError( @@ -63,4 +64,17 @@ base::StringPrintf("[[\"%s\"]]", node_id().c_str()), profile())); } +// Tests that calling bookmarkManagerPrivate.cut() to cut a permanent bookmark +// node into the clipboard gracefully fails. +// Regression test for https://crbug.com/1021829. +TEST_F(BookmarkManagerPrivateApiUnitTest, RunCutOnPermanentNode) { + auto cut_function = base::MakeRefCounted<BookmarkManagerPrivateCutFunction>(); + std::string node_id = + base::NumberToString(model()->bookmark_bar_node()->id()); + EXPECT_EQ("Can't modify the root bookmark folders.", + api_test_utils::RunFunctionAndReturnError( + cut_function.get(), + base::StringPrintf("[[\"%s\"]]", node_id.c_str()), profile())); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 4b3d7cde..8fe4fe3 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -1190,8 +1190,9 @@ // Tests that updating a packed extension with modified scripts works // properly -- we expect that the new script will execute, rather than the // previous one. +// Flaky on all platforms: https://crbug.com/1003244 IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, - UpdatePackedExtension) { + DISABLED_UpdatePackedExtension) { constexpr char kManifest1[] = R"({ "name": "Test Extension",
diff --git a/chrome/browser/heavy_ad_intervention/heavy_ad_service.cc b/chrome/browser/heavy_ad_intervention/heavy_ad_service.cc index 85a2420b..e819ecf 100644 --- a/chrome/browser/heavy_ad_intervention/heavy_ad_service.cc +++ b/chrome/browser/heavy_ad_intervention/heavy_ad_service.cc
@@ -54,3 +54,14 @@ heavy_ad_blocklist_ = std::make_unique<HeavyAdBlocklist>( std::move(opt_out_store), base::DefaultClock::GetInstance(), this); } + +void HeavyAdService::InitializeOffTheRecord() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (!base::FeatureList::IsEnabled(features::kHeavyAdPrivacyMitigations)) + return; + + // Providing a null out_out_store which sets up the blocklist in-memory only. + heavy_ad_blocklist_ = std::make_unique<HeavyAdBlocklist>( + nullptr /* opt_out_store */, base::DefaultClock::GetInstance(), this); +}
diff --git a/chrome/browser/heavy_ad_intervention/heavy_ad_service.h b/chrome/browser/heavy_ad_intervention/heavy_ad_service.h index 3d387a3..7c6e2e35 100644 --- a/chrome/browser/heavy_ad_intervention/heavy_ad_service.h +++ b/chrome/browser/heavy_ad_intervention/heavy_ad_service.h
@@ -29,6 +29,9 @@ // disk. void Initialize(const base::FilePath& profile_path); + // Initializes the blocklist with no backing store for incognito mode. + void InitializeOffTheRecord(); + HeavyAdBlocklist* heavy_ad_blocklist() { return heavy_ad_blocklist_.get(); } private:
diff --git a/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc b/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc index 211949d..58a3e3f9 100644 --- a/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc +++ b/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h" #include "chrome/browser/heavy_ad_intervention/heavy_ad_service.h" +#include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_context.h" @@ -39,3 +40,8 @@ content::BrowserContext* context) const { return new HeavyAdService(); } + +content::BrowserContext* HeavyAdServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextOwnInstanceInIncognito(context); +}
diff --git a/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h b/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h index d2afd08..2a97731 100644 --- a/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h +++ b/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h
@@ -34,6 +34,8 @@ // BrowserContextKeyedServiceFactory: KeyedService* BuildServiceInstanceFor( content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; DISALLOW_COPY_AND_ASSIGN(HeavyAdServiceFactory); };
diff --git a/chrome/browser/media/widevine_hardware_caps_win.cc b/chrome/browser/media/widevine_hardware_caps_win.cc index eadfcc1..357cb82 100644 --- a/chrome/browser/media/widevine_hardware_caps_win.cc +++ b/chrome/browser/media/widevine_hardware_caps_win.cc
@@ -110,7 +110,7 @@ void GetWidevineHardwareCaps( const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols, base::flat_set<media::VideoCodec>* video_codecs, - base::flat_set<media::EncryptionMode>* encryption_schemes) { + base::flat_set<media::EncryptionScheme>* encryption_schemes) { DCHECK(!cdm_proxy_protocols.empty()); DCHECK(video_codecs->empty()); DCHECK(encryption_schemes->empty()); @@ -155,5 +155,5 @@ } if (!video_codecs->empty()) - encryption_schemes->insert(media::EncryptionMode::kCenc); + encryption_schemes->insert(media::EncryptionScheme::kCenc); }
diff --git a/chrome/browser/media/widevine_hardware_caps_win.h b/chrome/browser/media/widevine_hardware_caps_win.h index 0bd4118f..fe159a6 100644 --- a/chrome/browser/media/widevine_hardware_caps_win.h +++ b/chrome/browser/media/widevine_hardware_caps_win.h
@@ -10,7 +10,7 @@ #include "media/cdm/cdm_proxy.h" namespace media { -enum class EncryptionMode; +enum class EncryptionScheme; } // Get supported Widevine hardware capabilities, including supported @@ -18,6 +18,6 @@ void GetWidevineHardwareCaps( const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols, base::flat_set<media::VideoCodec>* video_codecs, - base::flat_set<media::EncryptionMode>* encryption_schemes); + base::flat_set<media::EncryptionScheme>* encryption_schemes); #endif // CHROME_BROWSER_MEDIA_WIDEVINE_HARDWARE_CAPS_WIN_H_
diff --git a/chrome/browser/media/widevine_hardware_caps_win_unittest.cc b/chrome/browser/media/widevine_hardware_caps_win_unittest.cc index 7475e04..7468826 100644 --- a/chrome/browser/media/widevine_hardware_caps_win_unittest.cc +++ b/chrome/browser/media/widevine_hardware_caps_win_unittest.cc
@@ -13,7 +13,7 @@ base::flat_set<media::CdmProxy::Protocol> cdm_proxy_protocols = { media::CdmProxy::Protocol::kIntel}; base::flat_set<media::VideoCodec> video_codecs; - base::flat_set<media::EncryptionMode> encryption_schemes; + base::flat_set<media::EncryptionScheme> encryption_schemes; // Not checking the results since it's hardware dependent. GetWidevineHardwareCaps(cdm_proxy_protocols, &video_codecs,
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc index 4f44f8a..5ff8708 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -1103,8 +1103,7 @@ auto* blocklist = GetHeavyAdBlocklist(); - // Treat instances where the blocklist is unavailable as blocklisted. This - // includes incognito profiles, which do not create a blocklist service. + // Treat instances where the blocklist is unavailable as blocklisted. if (!blocklist) { heavy_ads_blocklist_blocklisted_ = true; return true;
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc index 6e34e3ad..a492349c 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -1130,10 +1130,10 @@ ->trial_name())); } -// Verifies that when the blacklist is at threshold, the heavy ad intervention +// Verifies that when the blocklist is at threshold, the heavy ad intervention // does not trigger. IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest, - HeavyAdInterventionBlacklistFull_InterventionBlocked) { + HeavyAdInterventionBlocklistFull_InterventionBlocked) { base::HistogramTester histogram_tester; auto large_resource_1 = std::make_unique<net::test_server::ControllableHttpResponse>( @@ -1196,6 +1196,43 @@ FrameData::HeavyAdStatus::kNetwork, 1); } +// Verifies that the blocklist is setup correctly and the intervention triggers +// in incognito mode. +IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest, + HeavyAdInterventionIncognitoMode_InterventionFired) { + base::HistogramTester histogram_tester; + auto incomplete_resource_response = + std::make_unique<net::test_server::ControllableHttpResponse>( + embedded_test_server(), "/ads_observer/incomplete_resource.js", + true /*relative_url_is_prefix*/); + ASSERT_TRUE(embedded_test_server()->Start()); + + Browser* incognito_browser = CreateIncognitoBrowser(); + content::WebContents* web_contents = + incognito_browser->tab_strip_model()->GetActiveWebContents(); + + // Create a navigation observer that will watch for the intervention to + // navigate the frame. + content::TestNavigationObserver error_observer(web_contents, + net::ERR_BLOCKED_BY_CLIENT); + + // Create a waiter for the incognito contents. + auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( + web_contents); + GURL url = embedded_test_server()->GetURL( + "/ads_observer/ad_with_incomplete_resource.html"); + ui_test_utils::NavigateToURL(incognito_browser, url); + + // Load a resource large enough to trigger the intervention. + LoadLargeResource(incomplete_resource_response.get(), kMaxHeavyAdNetworkSize); + + // Wait for the intervention page navigation to finish on the frame. + error_observer.WaitForNavigationFinished(); + + // Check that the ad frame was navigated to the intervention page. + EXPECT_FALSE(error_observer.last_navigation_succeeded()); +} + // Verify that UKM metrics are recorded correctly. IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest, RecordedUKMMetrics) {
diff --git a/chrome/browser/payments/empty_parameters_browsertest.cc b/chrome/browser/payments/empty_parameters_browsertest.cc new file mode 100644 index 0000000..0edbbdb --- /dev/null +++ b/chrome/browser/payments/empty_parameters_browsertest.cc
@@ -0,0 +1,57 @@ +// 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 "base/macros.h" +#include "build/build_config.h" +#include "chrome/test/base/chrome_test_utils.h" +#include "content/public/test/browser_test_utils.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(OS_ANDROID) +#include "chrome/test/base/android/android_browser_test.h" +#else +#include "chrome/test/base/in_process_browser_test.h" +#endif + +namespace content { +class WebContents; +} // namespace content + +namespace payments { +namespace { + +class EmptyParametersTest : public PlatformBrowserTest { + public: + EmptyParametersTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + ~EmptyParametersTest() override {} + + void SetUpOnMainThread() override { + https_server_.ServeFilesFromSourceDirectory( + "components/test/data/payments"); + ASSERT_TRUE(https_server_.Start()); + + ASSERT_TRUE(content::NavigateToURL( + GetActiveWebContents(), + https_server_.GetURL("/empty_parameters_test.html"))); + + PlatformBrowserTest::SetUpOnMainThread(); + } + + content::WebContents* GetActiveWebContents() { + return chrome_test_utils::GetActiveWebContents(this); + } + + private: + net::EmbeddedTestServer https_server_; + + DISALLOW_COPY_AND_ASSIGN(EmptyParametersTest); +}; + +IN_PROC_BROWSER_TEST_F(EmptyParametersTest, NoCrash) { + EXPECT_EQ(true, content::EvalJs(GetActiveWebContents(), "runTest()")); +} + +} // namespace +} // namespace payments
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index f974c9b..170b888 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -208,11 +208,11 @@ FAIL() << catcher.message(); } - // Load the PDF at the given URL and use the PDFScriptingAPI to ensure it has - // finished loading. Return true if it loads successfully or false if it - // fails. If it doesn't finish loading the test will hang. This is done from - // outside of the BrowserPlugin guest to ensure the PDFScriptingAPI works - // correctly from there. + // Load the PDF at the given URL and ensure it has finished loading. Return + // true if it loads successfully or false if it fails. If it doesn't finish + // loading the test will hang. This is done from outside of the BrowserPlugin + // guest to ensure sending messages to/from the plugin works correctly from + // there, since the PDFScriptingAPI relies on doing this as well. bool LoadPdf(const GURL& url) { ui_test_utils::NavigateToURL(browser(), url); WebContents* web_contents = GetActiveWebContents(); @@ -1110,10 +1110,10 @@ ASSERT_TRUE(guest_contents); WebContents* web_contents = GetActiveWebContents(); - CHECK(content::ExecuteScript(web_contents, - "var scriptingAPI = new PDFScriptingAPI(window, " - " document.getElementsByTagName('embed')[0]);" - "scriptingAPI.selectAll();")); + CHECK(content::ExecuteScript( + web_contents, + "document.getElementsByTagName('embed')[0].postMessage(" + "{type: 'selectAll'});")); EnableAccessibilityForWebContents(guest_contents); WaitForAccessibilityTreeToContainNodeWithName(guest_contents,
diff --git a/chrome/browser/pdf/pdf_extension_test_util.cc b/chrome/browser/pdf/pdf_extension_test_util.cc index cd1dc783..b30a0a12 100644 --- a/chrome/browser/pdf/pdf_extension_test_util.cc +++ b/chrome/browser/pdf/pdf_extension_test_util.cc
@@ -4,27 +4,25 @@ #include "chrome/browser/pdf/pdf_extension_test_util.h" -#include "chrome/grit/component_extension_resources.h" #include "content/public/test/browser_test_utils.h" -#include "ui/base/resource/resource_bundle.h" namespace pdf_extension_test_util { bool EnsurePDFHasLoaded(content::WebContents* web_contents) { - std::string scripting_api_js = - ui::ResourceBundle::GetSharedInstance() - .GetRawDataResource(IDR_PDF_PDF_SCRIPTING_API_JS) - .as_string(); - CHECK(content::ExecuteScript(web_contents, scripting_api_js)); - bool load_success = false; CHECK(content::ExecuteScriptAndExtractBool( web_contents, - "var scriptingAPI = new PDFScriptingAPI(window, " - " document.getElementsByTagName('embed')[0]);" - "scriptingAPI.setLoadCallback(function(success) {" - " window.domAutomationController.send(success);" - "});", + "window.addEventListener('message', event => {" + " if (event.origin !=" + " 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai' ||" + " event.data.type != 'documentLoaded') {" + " return;" + " }" + " window.domAutomationController.send(" + " event.data.load_state == 'success');" + "});" + "document.getElementsByTagName('embed')[0].postMessage(" + " {type: 'initialize'});", &load_success)); return load_success; }
diff --git a/chrome/browser/pdf/pdf_extension_test_util.h b/chrome/browser/pdf/pdf_extension_test_util.h index 2c5c8b8..3853a296 100644 --- a/chrome/browser/pdf/pdf_extension_test_util.h +++ b/chrome/browser/pdf/pdf_extension_test_util.h
@@ -11,8 +11,7 @@ namespace pdf_extension_test_util { -// Ensures through PDFScriptingAPI that a PDF has finished loading inside the -// given |web_contents|. +// Ensures that a PDF has finished loading inside the given |web_contents|. // Returns true if it loads successfully or false if it fails. If it doesn't // finish loading the test will hang. bool EnsurePDFHasLoaded(content::WebContents* web_contents);
diff --git a/chrome/browser/previews/previews_browsertest.cc b/chrome/browser/previews/previews_browsertest.cc index 09ac162..dfa865d 100644 --- a/chrome/browser/previews/previews_browsertest.cc +++ b/chrome/browser/previews/previews_browsertest.cc
@@ -360,9 +360,8 @@ EXPECT_TRUE(noscript_js_requested()); } -IN_PROC_BROWSER_TEST_P( - PreviewsNoScriptBrowserTest, - DISABLE_ON_WIN_MAC_CHROMEOS(NoScriptPreviewsEnabledButHttpRequest)) { +IN_PROC_BROWSER_TEST_P(PreviewsNoScriptBrowserTest, + DISABLE_ON_WIN_MAC_CHROMEOS(NoScriptPreviewsForHttp)) { GURL url = http_url(); // Whitelist NoScript for http_hint_setup_url() host. @@ -370,9 +369,9 @@ ui_test_utils::NavigateToURL(browser(), url); - // Verify loaded js resource but not css triggered by noscript tag. - EXPECT_TRUE(noscript_js_requested()); - EXPECT_FALSE(noscript_css_requested()); + // Verify loaded noscript tag triggered css resource but not js one. + EXPECT_TRUE(noscript_css_requested()); + EXPECT_FALSE(noscript_js_requested()); } IN_PROC_BROWSER_TEST_P(PreviewsNoScriptBrowserTest,
diff --git a/chrome/browser/previews/previews_content_util.cc b/chrome/browser/previews/previews_content_util.cc index bcfef1b..ec9b83f8 100644 --- a/chrome/browser/previews/previews_content_util.cc +++ b/chrome/browser/previews/previews_content_util.cc
@@ -401,7 +401,6 @@ content::PreviewsState previews_state, const previews::PreviewsDecider* previews_decider, content::NavigationHandle* navigation_handle) { - bool is_https = url.SchemeIs(url::kHttpsScheme); // Record whether the hint cache has a matching entry for this committed URL. previews_decider->LogHintCacheMatch(url, true /* is_committed */); @@ -512,10 +511,9 @@ if (previews_state & content::DEFER_ALL_SCRIPT_ON) { // DeferAllScript was allowed for the original URL but only continue with it // if the committed URL has HTTPS scheme and is allowed by decider. - if (is_https && previews_decider && - previews_decider->ShouldCommitPreview( - previews_data, navigation_handle, - previews::PreviewsType::DEFER_ALL_SCRIPT)) { + if (previews_decider && previews_decider->ShouldCommitPreview( + previews_data, navigation_handle, + previews::PreviewsType::DEFER_ALL_SCRIPT)) { LogCommittedPreview(previews_data, PreviewsType::DEFER_ALL_SCRIPT); return content::DEFER_ALL_SCRIPT_ON; } @@ -527,7 +525,7 @@ if (previews_state & content::RESOURCE_LOADING_HINTS_ON) { // Resource loading hints was chosen for the original URL but only continue // with it if the committed URL has HTTPS scheme and is allowed by decider. - if (is_https && previews_decider && + if (previews_decider && previews_decider->ShouldCommitPreview( previews_data, navigation_handle, previews::PreviewsType::RESOURCE_LOADING_HINTS)) { @@ -542,10 +540,9 @@ if (previews_state & content::NOSCRIPT_ON) { // NoScript was chosen for the original URL but only continue with it // if the committed URL has HTTPS scheme and is allowed by decider. - if (is_https && previews_decider && - previews_decider->ShouldCommitPreview( - previews_data, navigation_handle, - previews::PreviewsType::NOSCRIPT)) { + if (previews_decider && previews_decider->ShouldCommitPreview( + previews_data, navigation_handle, + previews::PreviewsType::NOSCRIPT)) { LogCommittedPreview(previews_data, PreviewsType::NOSCRIPT); return content::NOSCRIPT_ON; }
diff --git a/chrome/browser/previews/previews_content_util_unittest.cc b/chrome/browser/previews/previews_content_util_unittest.cc index 52367e4a..357ab98 100644 --- a/chrome/browser/previews/previews_content_util_unittest.cc +++ b/chrome/browser/previews/previews_content_util_unittest.cc
@@ -447,25 +447,26 @@ user_data.set_navigation_ect(net::EFFECTIVE_CONNECTION_TYPE_2G); base::HistogramTester histogram_tester; - // Verify that currently these previews do not commit on HTTP. - EXPECT_EQ(content::PREVIEWS_OFF, + // Verify that these previews do now commit on HTTP. + EXPECT_EQ(content::DEFER_ALL_SCRIPT_ON, previews::DetermineCommittedClientPreviewsState( &user_data, GURL("http://www.google.com"), content::NOSCRIPT_ON | content::RESOURCE_LOADING_HINTS_ON | content::DEFER_ALL_SCRIPT_ON, enabled_previews_decider(), nullptr)); histogram_tester.ExpectTotalCount( - "Previews.Triggered.EffectiveConnectionType2", 0); - - // Ensure one does commit on HTTPS (to confirm test setup). - EXPECT_NE(content::PREVIEWS_OFF, - previews::DetermineCommittedClientPreviewsState( - &user_data, GURL("https://www.google.com"), - content::NOSCRIPT_ON | content::RESOURCE_LOADING_HINTS_ON | - content::DEFER_ALL_SCRIPT_ON, - enabled_previews_decider(), nullptr)); - histogram_tester.ExpectTotalCount( "Previews.Triggered.EffectiveConnectionType2", 1); + + EXPECT_EQ(content::RESOURCE_LOADING_HINTS_ON, + previews::DetermineCommittedClientPreviewsState( + &user_data, GURL("http://www.google.com"), + content::RESOURCE_LOADING_HINTS_ON, enabled_previews_decider(), + nullptr)); + + EXPECT_EQ(content::NOSCRIPT_ON, + previews::DetermineCommittedClientPreviewsState( + &user_data, GURL("http://www.google.com"), content::NOSCRIPT_ON, + enabled_previews_decider(), nullptr)); } TEST_F(PreviewsContentUtilTest,
diff --git a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc index 406525d2..c8a18ea 100644 --- a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc +++ b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc
@@ -936,14 +936,15 @@ "ResourceLoadingHints.CountBlockedSubresourcePatterns", 0); } -IN_PROC_BROWSER_TEST_P(ResourceLoadingHintsBrowserTest, - DISABLE_ON_WIN_MAC_CHROMEOS(ResourceLoadingHintsHttp)) { +IN_PROC_BROWSER_TEST_P( + ResourceLoadingHintsBrowserTest, + DISABLE_ON_WIN_MAC_CHROMEOS(ResourceLoadingHintsForHttp)) { GURL url = http_url(); // Whitelist resource loading hints for http_hint_setup_url()'s' host. SetDefaultOnlyResourceLoadingHints(http_hint_setup_url()); - SetExpectedFooJpgRequest(true); + SetExpectedFooJpgRequest(false); SetExpectedBarJpgRequest(true); base::HistogramTester histogram_tester; @@ -953,11 +954,7 @@ histogram_tester.ExpectBucketCount( "Previews.EligibilityReason.ResourceLoadingHints", - static_cast<int>(previews::PreviewsEligibilityReason::ALLOWED), 1); - histogram_tester.ExpectTotalCount( - "Previews.PreviewShown.ResourceLoadingHints", 0); - histogram_tester.ExpectTotalCount( - "ResourceLoadingHints.CountBlockedSubresourcePatterns", 0); + static_cast<int>(previews::PreviewsEligibilityReason::COMMITTED), 1); } IN_PROC_BROWSER_TEST_P(ResourceLoadingHintsBrowserTest,
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index f3ffc0e5..ea4ea9f 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -31,6 +31,8 @@ #include "chrome/browser/download/chrome_download_manager_delegate.h" #include "chrome/browser/download/download_core_service.h" #include "chrome/browser/download/download_core_service_factory.h" +#include "chrome/browser/heavy_ad_intervention/heavy_ad_service.h" +#include "chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h" #include "chrome/browser/native_file_system/chrome_native_file_system_permission_context.h" #include "chrome/browser/native_file_system/native_file_system_permission_context_factory.h" #include "chrome/browser/permissions/permission_manager.h" @@ -187,6 +189,8 @@ // AccessibilityLabelsService has a default prefs behavior in incognito. AccessibilityLabelsService::InitOffTheRecordPrefs(this); + + HeavyAdServiceFactory::GetForBrowserContext(this)->InitializeOffTheRecord(); } OffTheRecordProfileImpl::~OffTheRecordProfileImpl() {
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index a842791..93d5f6e 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -108,6 +108,34 @@ } if (!is_android) { + grit("bookmarks_resources") { + if (optimize_webui) { + source = "bookmarks/bookmarks_resources_vulcanized.grd" + + # The .grd contains references to generated files. + source_is_generated = true + + deps = [ + "//chrome/browser/resources/bookmarks:build", + ] + grit_flags = [ + "-E", + "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), + ] + } else { + source = "bookmarks/bookmarks_resources.grd" + } + + defines = chrome_grit_defines + outputs = [ + "grit/bookmarks_resources.h", + "grit/bookmarks_resources_map.cc", + "grit/bookmarks_resources_map.h", + "bookmarks_resources.pak", + ] + output_dir = "$root_gen_dir/chrome" + } + grit("component_extension_resources") { source = "component_extension_resources.grd" @@ -381,27 +409,34 @@ ] } -js2gtest("resources_unitjs_tests") { - test_type = "webui" - sources = [ - "gaia_auth_host/password_change_authenticator_test.unitjs", - ] +# TODO(https://crbug.com/930109): Figure out why this test fails on MAC ASAN. +if (!is_asan || !is_mac) { + js2gtest("resources_unitjs_tests") { + test_type = "webui" + sources = [ + "gaia_auth_host/password_change_authenticator_test.unitjs", + ] - # This has to be a gen_include, so it doesn't collide with other js2gtests - gen_include_files = [ "//ui/webui/resources/js/cr.js" ] + # This has to be a gen_include, so it doesn't collide with other js2gtests + gen_include_files = [ "//ui/webui/resources/js/cr.js" ] - # But these have to be extra_js_files, since it uses a native object - # EventTarget, which doesn't work at compile time. - extra_js_files = [ - "//ui/webui/resources/js/cr/event_target.js", - "gaia_auth_host/password_change_authenticator.js", - ] - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] -} + # But these have to be extra_js_files, since it uses a native object + # EventTarget, which doesn't work at compile time. + extra_js_files = [ + "//ui/webui/resources/js/cr/event_target.js", + "gaia_auth_host/password_change_authenticator.js", + ] + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + } -source_set("browser_tests") { - testonly = true - deps = [ - ":resources_unitjs_tests", - ] + source_set("browser_tests") { + testonly = true + deps = [ + ":resources_unitjs_tests", + ] + } +} else { + source_set("browser_tests") { + testonly = true + } }
diff --git a/chrome/browser/resources/bookmarks/BUILD.gn b/chrome/browser/resources/bookmarks/BUILD.gn index 3fc62cd..5029f2a5 100644 --- a/chrome/browser/resources/bookmarks/BUILD.gn +++ b/chrome/browser/resources/bookmarks/BUILD.gn
@@ -2,18 +2,52 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//chrome/common/features.gni") import("//third_party/closure_compiler/compile_js.gni") +import("//tools/grit/grit_rule.gni") import("../optimize_webui.gni") -optimize_webui("build") { - host = "bookmarks" - html_in_files = [ "bookmarks.html" ] - html_out_files = [ "vulcanized.html" ] +if (optimize_webui) { + bookmarks_pak_file = "bookmarks_resources.pak" + unpak_folder = "bookmarks_resources.unpak" - input = rebase_path(".", root_build_dir) - js_out_files = [ "crisper.js" ] + optimize_webui("build") { + host = "bookmarks" + html_in_files = [ "bookmarks.html" ] + html_out_files = [ "vulcanized.html" ] - deps = [] + input = rebase_path(".", root_build_dir) + js_out_files = [ "crisper.js" ] + + deps = [ + ":unpak", + ] + } + + unpak("unpak") { + pak_file = bookmarks_pak_file + out_folder = unpak_folder + + deps = [ + ":flattened_resources", + ] + } + + grit("flattened_resources") { + source = "bookmarks_resources.grd" + + # The .grd contains references to generated files. + source_is_generated = true + + defines = chrome_grit_defines + outputs = [ + "grit/bookmarks_resources.h", + "grit/bookmarks_resources_map.cc", + "grit/bookmarks_resources_map.h", + bookmarks_pak_file, + ] + output_dir = "$root_gen_dir/chrome/browser/resources/bookmarks" + } } js_type_check("closure_compile") {
diff --git a/chrome/browser/resources/bookmarks/bookmarks_resources.grd b/chrome/browser/resources/bookmarks/bookmarks_resources.grd new file mode 100644 index 0000000..9a80d1a --- /dev/null +++ b/chrome/browser/resources/bookmarks/bookmarks_resources.grd
@@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/bookmarks_resources.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="grit/bookmarks_resources_map.cc" + type="resource_file_map_source" /> + <output filename="grit/bookmarks_resources_map.h" + type="resource_map_header" /> + <output filename="bookmarks_resources.pak" type="data_package" /> + </outputs> + <release seq="1"> + <structures> + <structure name="IDR_BOOKMARKS_ACTIONS_HTML" + file="actions.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_ACTIONS_JS" + file="actions.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_API_LISTENER_HTML" + file="api_listener.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_API_LISTENER_JS" + file="api_listener.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_APP_HTML" + file="app.html" + type="chrome_html" + preprocess="true" /> + <structure name="IDR_BOOKMARKS_APP_JS" + file="app.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_BOOKMARKS_HTML" + file="bookmarks.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_COMMAND_MANAGER_HTML" + file="command_manager.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_COMMAND_MANAGER_JS" + file="command_manager.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_CONSTANTS_HTML" + file="constants.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_CONSTANTS_JS" + file="constants.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_DEBOUNCER_HTML" + file="debouncer.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_DEBOUNCER_JS" + file="debouncer.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_DIALOG_FOCUS_MANAGER_HTML" + file="dialog_focus_manager.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_DIALOG_FOCUS_MANAGER_JS" + file="dialog_focus_manager.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_DND_MANAGER_HTML" + file="dnd_manager.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_DND_MANAGER_JS" + file="dnd_manager.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_EDIT_DIALOG_HTML" + file="edit_dialog.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_EDIT_DIALOG_JS" + file="edit_dialog.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_FOLDER_NODE_HTML" + file="folder_node.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_FOLDER_NODE_JS" + file="folder_node.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_ITEM_HTML" + file="item.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_ITEM_JS" + file="item.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_LIST_HTML" + file="list.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_LIST_JS" + file="list.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_MOUSE_FOCUS_BEHAVIOR_HTML" + file="mouse_focus_behavior.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_MOUSE_FOCUS_BEHAVIOR_JS" + file="mouse_focus_behavior.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_REDUCERS_HTML" + file="reducers.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_REDUCERS_JS" + file="reducers.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_ROUTER_HTML" + file="router.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_ROUTER_JS" + file="router.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_SHARED_STYLE_HTML" + file="shared_style.html" + preprocess="true" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_SHARED_VARS_HTML" + file="shared_vars.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_STORE_CLIENT_HTML" + file="store_client.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_STORE_CLIENT_JS" + file="store_client.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_STORE_HTML" + file="store.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_STORE_JS" + file="store.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_STRINGS_HTML" + file="strings.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_TOOLBAR_HTML" + file="toolbar.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_TOOLBAR_JS" + file="toolbar.js" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_UTIL_HTML" + file="util.html" + type="chrome_html" /> + <structure name="IDR_BOOKMARKS_UTIL_JS" + file="util.js" + type="chrome_html" /> + </structures> + </release> +</grit>
diff --git a/chrome/browser/resources/bookmarks/bookmarks_resources_vulcanized.grd b/chrome/browser/resources/bookmarks/bookmarks_resources_vulcanized.grd new file mode 100644 index 0000000..d43bc5f --- /dev/null +++ b/chrome/browser/resources/bookmarks/bookmarks_resources_vulcanized.grd
@@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/bookmarks_resources.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="grit/bookmarks_resources_map.cc" + type="resource_map_source" /> + <output filename="grit/bookmarks_resources_map.h" + type="resource_map_header" /> + <output filename="bookmarks_resources.pak" type="data_package" /> + </outputs> + <release seq="1"> + <structures> + <structure name="IDR_BOOKMARKS_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\bookmarks\vulcanized.html" use_base_dir="false" preprocess="true" type="chrome_html" compress="gzip" /> + <structure name="IDR_BOOKMARKS_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\bookmarks\crisper.js" use_base_dir="false" preprocess="true" type="chrome_html" compress="gzip" /> + </structures> + </release> +</grit>
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css index ca819b4a..bdcd2e0 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css +++ b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
@@ -856,22 +856,26 @@ } #message-container { - background-color: rgba(0, 0, 0, 0.7); - border-radius: 16px; bottom: 12px; - color: #fff; - display: block; - left: 50%; - max-width: 90%; - min-width: 75%; - padding: 8px 28px; + display: none; position: absolute; text-align: center; - transform: translateX(-50%); - visibility: hidden; /* Need this for correct positioning. */ + width: 100%; z-index: 4; } +#message-content { + background-color: rgba(0, 0, 0, 0.7); + border-radius: 16px; + color: #fff; + display: inline-block; + left: 50%; + margin: 0 auto; + max-width: 90%; + padding: 8px 28px; + text-align: center; +} + #preview-spinner, #current-wallpaper-spinner { background: url(chrome://resources/images/throbber_medium.svg) no-repeat;
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js index 4cc49b3..7e6dd10 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js +++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
@@ -313,22 +313,18 @@ if (!wallpaperPickerWindow) return; var wpDocument = wallpaperPickerWindow.contentWindow.document; - var messageContainer = wpDocument.querySelector('#message-container'); + var messageContent = wpDocument.querySelector('#message-content'); chrome.wallpaperPrivate.getStrings(strings => { if (appName) { + wpDocument.querySelector('#message-container').display = 'block'; var message = strings.currentWallpaperSetByMessage.replace(/\$1/g, appName); - messageContainer.textContent = message; - messageContainer.style.visibility = 'visible'; + messageContent.textContent = message; wpDocument.querySelector('#checkbox').classList.remove('checked'); wpDocument.querySelector('#categories-list').disabled = false; wpDocument.querySelector('#wallpaper-grid').disabled = false; } else { - if (messageContainer.textContent != - strings.setSuccessfullyMessage) { - messageContainer.style.visibility = 'hidden'; - } Constants.WallpaperSyncStorage.get( Constants.AccessSyncSurpriseMeEnabledKey, function(item) { // TODO(crbug.com/810169): Try to combine this part with
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js index e14d494..bf52664 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js +++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
@@ -363,8 +363,8 @@ * @param {string} errroMessage The string to show in the error dialog. */ WallpaperManager.prototype.showError_ = function(errorMessage) { - $('message-container').textContent = errorMessage; - $('message-container').style.visibility = 'visible'; + $('message-content').textContent = errorMessage; + $('message-container').style.display = 'block'; }; /** @@ -429,11 +429,11 @@ getThirdPartyAppName(function(appName) { if (appName) { - $('message-container').textContent = + $('message-content').textContent = loadTimeData.getStringF('currentWallpaperSetByMessage', appName); - $('message-container').style.visibility = 'visible'; + $('message-container').style.display = 'block'; } else { - $('message-container').style.visibility = 'hidden'; + $('message-container').style.display = 'none'; } }); @@ -451,7 +451,7 @@ // Force refreshing the images. this.wallpaperGrid_.dataModel = null; this.onCategoriesChange_(); - $('message-container').style.visibility = 'hidden'; + $('message-container').style.display = 'none'; this.downloadedListMap_ = null; $('wallpaper-grid').classList.remove('image-picker-offline'); }); @@ -712,7 +712,7 @@ */ WallpaperManager.prototype.onWallpaperChanged_ = function( activeItem, currentWallpaperURL) { - $('message-container').style.visibility = 'hidden'; + $('message-container').style.display = 'none'; this.wallpaperGrid_.activeItem = activeItem; this.currentWallpaper_ = currentWallpaperURL; this.decorateCurrentWallpaperInfoBar_(); @@ -1059,7 +1059,7 @@ var nextPreviewImage = dataModel.item(nextPreviewIndex); if (nextPreviewImage.source == Constants.WallpaperSourceEnum.Online) this.updateSpinnerVisibility_(true); - $('message-container').style.visibility = 'hidden'; + $('message-container').style.display = 'none'; this.setWallpaperAttribution(nextPreviewImage); this.setSelectedWallpaper_(nextPreviewImage); this.currentPreviewIndex_ = nextPreviewIndex; @@ -1094,7 +1094,7 @@ }; this.addEventToButton_($('cancel-preview-wallpaper'), onCancelClicked); - $('message-container').style.visibility = 'hidden'; + $('message-container').style.display = 'none'; }; /* @@ -1103,10 +1103,10 @@ */ WallpaperManager.prototype.showSuccessMessageAndQuit_ = function() { this.document_.body.classList.add('wallpaper-set-successfully'); - $('message-container').textContent = str('setSuccessfullyMessage'); + $('message-content').textContent = str('setSuccessfullyMessage'); // Success message must be shown in full screen mode. chrome.app.window.current().fullscreen(); - $('message-container').style.visibility = 'visible'; + $('message-container').style.display = 'block'; // Close the window after showing the success message. window.setTimeout(() => { window.close();
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/main.html b/chrome/browser/resources/chromeos/wallpaper_manager/main.html index beb055f..3816df2 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/main.html +++ b/chrome/browser/resources/chromeos/wallpaper_manager/main.html
@@ -182,7 +182,10 @@ </div> </div> </div> - <div id="message-container" i18n-content="connectionFailed"></div> + <div id="message-container"> + <div id="message-content" i18n-content="connectionFailed"> + </div> + </div> <div id="preview-canvas"></div> <div id="preview-spinner" hidden></div> <div id="daily-refresh-banner-template" hidden>
diff --git a/chrome/browser/resources/settings/device_page/display.js b/chrome/browser/resources/settings/device_page/display.js index 01f136c..cb87eeb 100644 --- a/chrome/browser/resources/settings/device_page/display.js +++ b/chrome/browser/resources/settings/device_page/display.js
@@ -700,8 +700,7 @@ this.logicalResolutionText_ = ''; return; } - const mode = this.selectedDisplay.modes[ - /** @type {number} */ (this.selectedModePref_.value)]; + const mode = this.selectedDisplay.modes[this.currentSelectedModeIndex_]; const deviceScaleFactor = mode.deviceScaleFactor; const inverseZoomFactor = 1.0 / zoomFactor; let logicalResolutionStrId = 'displayZoomLogicalResolutionText'; @@ -710,17 +709,38 @@ } else if (Math.abs(inverseZoomFactor - 1.0) < 0.001) { logicalResolutionStrId = 'displayZoomLogicalResolutionDefaultText'; } - const widthStr = + let widthStr = Math.round(mode.widthInNativePixels / (deviceScaleFactor * zoomFactor)) .toString(); - const heightStr = + let heightStr = Math.round(mode.heightInNativePixels / (deviceScaleFactor * zoomFactor)) .toString(); + if (this.shouldSwapLogicalResolutionText_()) { + const temp = widthStr; + widthStr = heightStr; + heightStr = temp; + } this.logicalResolutionText_ = this.i18n(logicalResolutionStrId, widthStr, heightStr); }, /** + * Determines whether width and height should be swapped in the + * Logical Resolution Text. Returns true if the aspect ratio of the display's + * native pixels is not equal to the aspect ratio of the displays current + * bounds. + * @private + */ + shouldSwapLogicalResolutionText_: function() { + const mode = this.selectedDisplay.modes[this.currentSelectedModeIndex_]; + const bounds = this.selectedDisplay.bounds; + + return (bounds.width / bounds.height).toPrecision(4) != + (mode.widthInNativePixels / mode.heightInNativePixels).toPrecision(4); + }, + + + /** * Handles the event where the display size slider is being dragged, i.e. the * mouse or tap has not been released. * @private
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc index 75c4972..48892e0 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc
@@ -34,6 +34,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_types.h" +using BrowserDMToken = policy::BrowserDMTokenStorage::BrowserDMToken; + namespace safe_browsing { const base::Feature kDeepScanningOfUploads{"SafeBrowsingDeepScanningOfUploads", @@ -45,9 +47,15 @@ namespace { -std::string* GetDMTokenForTestingStorage() { - static std::string dm_token; - return &dm_token; +const char** GetDMTokenForTestingStorage() { + static const char* dm_token_storage = ""; + return &dm_token_storage; +} + +BrowserDMToken GetDMTokenForTesting() { + const char* dm_token = *GetDMTokenForTestingStorage(); + return dm_token && dm_token[0] ? BrowserDMToken::CreateValidToken(dm_token) + : BrowserDMToken::CreateEmptyToken(); } // Global pointer of factory function (RepeatingCallback) used to create @@ -298,8 +306,8 @@ if (profile->IsOffTheRecord()) return false; - // If there's no DM token, the upload will fail. - if (GetDMToken().empty()) + // If there's no valid DM token, the upload will fail. + if (!GetDMToken().is_valid()) return false; // See if content compliance checks are needed. @@ -473,8 +481,8 @@ } // static -std::string DeepScanningDialogDelegate::GetDMToken() { - std::string dm_token = *GetDMTokenForTestingStorage(); +BrowserDMToken DeepScanningDialogDelegate::GetDMToken() { + auto dm_token = GetDMTokenForTesting(); #if !defined(OS_CHROMEOS) // This is not compiled on chromeos because @@ -482,9 +490,9 @@ // policy::BrowserDMTokenStorage::Get()->RetrieveDMToken() does not return a // valid token either. Once these are fixed the #if !defined can be removed. - if (dm_token.empty() && + if (dm_token.is_empty() && policy::ChromeBrowserCloudManagementController::IsEnabled()) { - dm_token = policy::BrowserDMTokenStorage::Get()->RetrieveDMToken(); + dm_token = policy::BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken(); } #endif @@ -550,7 +558,7 @@ request->set_request_malware_scan(std::move(malware_request)); } - request->set_dm_token(GetDMToken()); + request->set_dm_token(GetDMToken().value()); } void DeepScanningDialogDelegate::FillAllResultsWith(bool status) {
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h index 3e2783c..c4d5694 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" +#include "chrome/browser/policy/browser_dm_token_storage.h" #include "chrome/browser/safe_browsing/download_protection/binary_upload_service.h" #include "chrome/browser/ui/tab_modal_confirm_dialog.h" #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h" @@ -190,7 +191,7 @@ class FileSourceRequest; // Gets the device level DM token to use with deep scans. - static std::string GetDMToken(); + static policy::BrowserDMTokenStorage::BrowserDMToken GetDMToken(); // Uploads data for deep scanning. Returns true if uploading is occurring in // the background and false if there is nothing to do.
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc index 6cf084f..de9413f 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc
@@ -28,16 +28,16 @@ namespace { -const char kDmToken[] = "dm_token"; -const char kTestUrl[] = "http://example.com"; +constexpr char kDmToken[] = "dm_token"; +constexpr char kTestUrl[] = "http://example.com"; -const char kTestHttpsSchemePatternUrl[] = "https://*"; -const char kTestChromeSchemePatternUrl[] = "chrome://*"; -const char kTestDevtoolsSchemePatternUrl[] = "devtools://*"; +constexpr char kTestHttpsSchemePatternUrl[] = "https://*"; +constexpr char kTestChromeSchemePatternUrl[] = "chrome://*"; +constexpr char kTestDevtoolsSchemePatternUrl[] = "devtools://*"; -const char kTestPathPatternUrl[] = "*/a/specific/path/"; -const char kTestPortPatternUrl[] = "*:1234"; -const char kTestQueryPatternUrl[] = "*?q=5678"; +constexpr char kTestPathPatternUrl[] = "*/a/specific/path/"; +constexpr char kTestPortPatternUrl[] = "*:1234"; +constexpr char kTestQueryPatternUrl[] = "*?q=5678"; class BaseTest : public testing::Test { public:
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc index cf37255..5ee0860 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_context_menu.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_context_menu.h" #include "chrome/browser/ui/app_list/extension_app_context_menu.h" +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" // static const char AppServiceAppItem::kItemType[] = "AppServiceAppItem"; @@ -103,6 +104,14 @@ } void AppServiceAppItem::Activate(int event_flags) { + // TODO(crbug.com/1022541): Move the Chrome special case to ExtensionApps, + // when AppService Instance feature is done. + if (id() == extension_misc::kChromeAppId) { + ChromeLauncherController::instance()->ActivateApp( + id(), ash::LAUNCH_FROM_APP_LIST, event_flags, + GetController()->GetAppListDisplayId()); + return; + } Launch(event_flags, apps::mojom::LaunchSource::kFromAppListGrid); }
diff --git a/chrome/browser/ui/libgtkui/gtk_event_loop_x11.cc b/chrome/browser/ui/libgtkui/gtk_event_loop_x11.cc index 421e8a61..96106ef 100644 --- a/chrome/browser/ui/libgtkui/gtk_event_loop_x11.cc +++ b/chrome/browser/ui/libgtkui/gtk_event_loop_x11.cc
@@ -11,30 +11,12 @@ #include <gtk/gtk.h> #include "base/memory/singleton.h" +#include "chrome/browser/ui/libgtkui/gtk_util.h" #include "ui/events/platform/x11/x11_event_source.h" #include "ui/gfx/x/x11_types.h" namespace libgtkui { -namespace { - -// Xkb Events store group attribute into XKeyEvent::state bit field, along with -// other state-related info, while GdkEventKey objects have separate fields for -// that purpose, they are ::state and ::group. This function is responsible for -// recomposing them into a single bit field value when translating GdkEventKey -// into XKeyEvent. This is similar to XkbBuildCoreState(), but assumes state is -// an uint rather than an uchar. -// -// More details: -// https://gitlab.freedesktop.org/xorg/proto/xorgproto/blob/master/include/X11/extensions/XKB.h#L372 -int BuildXkbStateFromGdkEvent(const GdkEventKey& keyev) { - DCHECK_EQ(0u, XkbGroupForCoreState(keyev.state)); - DCHECK(XkbIsLegalGroup(keyev.group)); - return keyev.state | ((keyev.group & 0x3) << 13); -} - -} // namespace - // static GtkEventLoopX11* GtkEventLoopX11::GetInstance() { return base::Singleton<GtkEventLoopX11>::get(); @@ -88,9 +70,10 @@ x_event.xkey.window = GDK_WINDOW_XID(gdk_event_key.window); x_event.xkey.root = DefaultRootWindow(x_event.xkey.display); x_event.xkey.time = gdk_event_key.time; - x_event.xkey.state = BuildXkbStateFromGdkEvent(gdk_event_key); x_event.xkey.keycode = gdk_event_key.hardware_keycode; x_event.xkey.same_screen = true; + x_event.xkey.state = + BuildXkbStateFromGdkEvent(gdk_event_key.state, gdk_event_key.group); // We want to process the gtk event; mapped to an X11 event immediately // otherwise if we put it back on the queue we may get items out of order.
diff --git a/chrome/browser/ui/libgtkui/gtk_util.cc b/chrome/browser/ui/libgtkui/gtk_util.cc index 1f2abb3..94174c8 100644 --- a/chrome/browser/ui/libgtkui/gtk_util.cc +++ b/chrome/browser/ui/libgtkui/gtk_util.cc
@@ -607,6 +607,11 @@ return display; } +int BuildXkbStateFromGdkEvent(unsigned int state, unsigned char group) { + DCHECK_EQ(0u, ((state >> 13) & 0x3)); + return state | ((group & 0x3) << 13); +} + GdkEvent* GdkEventFromKeyEvent(const ui::KeyEvent& key_event) { GdkEventType event_type = key_event.type() == ui::ET_KEY_PRESSED ? GDK_KEY_PRESS : GDK_KEY_RELEASE; @@ -632,7 +637,7 @@ gdk_event->key.time = event_time.InMilliseconds(); gdk_event->key.hardware_keycode = hw_code; gdk_event->key.keyval = keyval; - gdk_event->key.state = state; + gdk_event->key.state = BuildXkbStateFromGdkEvent(state, group); gdk_event->key.group = group; gdk_event->key.send_event = key_event.flags() & ui::EF_FINAL; gdk_event->key.is_modifier = state & GDK_MODIFIER_MASK;
diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h index c9712cd..ab87074 100644 --- a/chrome/browser/ui/libgtkui/gtk_util.h +++ b/chrome/browser/ui/libgtkui/gtk_util.h
@@ -177,6 +177,17 @@ // Get current GdkDisplay instance GdkDisplay* GetGdkDisplay(); +// Xkb Events store group attribute into XKeyEvent::state bit field, along with +// other state-related info, while GdkEventKey objects have separate fields for +// that purpose, they are ::state and ::group. This function is responsible for +// recomposing them into a single bit field value when translating GdkEventKey +// into XKeyEvent. This is similar to XkbBuildCoreState(), but assumes state is +// an uint rather than an uchar. +// +// More details: +// https://gitlab.freedesktop.org/xorg/proto/xorgproto/blob/master/include/X11/extensions/XKB.h#L372 +int BuildXkbStateFromGdkEvent(unsigned int state, unsigned char group); + // Translates |key_event| into a GdkEvent. GdkEvent::key::window is the only // field not set by this function, callers must set it, as the way for // retrieving it may vary depending on the event being processed. E.g: for IME
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index 08ff0064..aa5aed56 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -58,8 +58,6 @@ #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/content_settings_utils.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" -#include "components/rappor/public/rappor_utils.h" -#include "components/rappor/rappor_service_impl.h" #include "components/safe_browsing/buildflags.h" #include "components/safe_browsing/password_protection/metrics_util.h" #include "components/safe_browsing/proto/csd.pb.h" @@ -520,12 +518,6 @@ UMA_HISTOGRAM_EXACT_LINEAR( "WebsiteSettings.OriginInfo.PermissionChanged.Allowed", histogram_value, num_values); - - if (type == ContentSettingsType::PLUGINS) { - rappor::SampleDomainAndRegistryFromGURL( - g_browser_process->rappor_service(), - "ContentSettings.Plugins.AddedAllowException", site_url_); - } } else if (setting == ContentSetting::CONTENT_SETTING_BLOCK) { UMA_HISTOGRAM_EXACT_LINEAR( "WebsiteSettings.OriginInfo.PermissionChanged.Blocked", histogram_value,
diff --git a/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc b/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc index 788ee09..517fd52 100644 --- a/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc +++ b/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc
@@ -20,7 +20,8 @@ #include "chrome/browser/ui/webui/plural_string_handler.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" +#include "chrome/grit/bookmarks_resources.h" +#include "chrome/grit/bookmarks_resources_map.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/favicon_base/favicon_url_parser.h"
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc index 414c7ce..92910dd 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc +++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
@@ -419,7 +419,9 @@ #if defined(OS_WIN) // Don't show the update bubbles to enterprise users. if (base::IsMachineExternallyManaged() || - !policy::BrowserDMTokenStorage::Get()->RetrieveDMToken().empty()) { + policy::BrowserDMTokenStorage::Get() + ->RetrieveBrowserDMToken() + .is_valid()) { return false; } #endif
diff --git a/chrome/browser/vr/service/browser_xr_runtime.cc b/chrome/browser/vr/service/browser_xr_runtime.cc index cd06168..0e6db832 100644 --- a/chrome/browser/vr/service/browser_xr_runtime.cc +++ b/chrome/browser/vr/service/browser_xr_runtime.cc
@@ -116,12 +116,6 @@ // Rather than just cloning everything, we copy over each field and validate // individually. This ensures new fields don't bypass validation. ret->id = id; - ret->display_name = info->display_name; - DCHECK(info->capabilities); // Ensured by mojo. - ret->capabilities = device::mojom::VRDisplayCapabilities::New( - info->capabilities->has_position, - info->capabilities->has_external_display, info->capabilities->can_present, - info->capabilities->can_provide_environment_integration); // Maximum 1000km translation. if (info->stage_parameters && @@ -137,13 +131,6 @@ float kMinFramebufferScale = 0.1f; float kMaxFramebufferScale = 1.0f; - if (info->webvr_default_framebuffer_scale <= kMaxFramebufferScale && - info->webvr_default_framebuffer_scale >= kMinFramebufferScale) { - ret->webvr_default_framebuffer_scale = - info->webvr_default_framebuffer_scale; - } else { - ret->webvr_default_framebuffer_scale = 1; - } if (info->webxr_default_framebuffer_scale <= kMaxFramebufferScale && info->webxr_default_framebuffer_scale >= kMinFramebufferScale) { @@ -403,14 +390,6 @@ } } -void BrowserXRRuntime::OnInitialized() { - DVLOG(2) << __func__; - for (auto& callback : pending_initialization_callbacks_) { - std::move(callback).Run(display_info_.Clone()); - } - pending_initialization_callbacks_.clear(); -} - void BrowserXRRuntime::OnServiceAdded(VRServiceImpl* service) { DVLOG(2) << __func__ << ": id=" << id_; services_.insert(service); @@ -501,19 +480,4 @@ StopImmersiveSession(base::DoNothing()); } -void BrowserXRRuntime::InitializeAndGetDisplayInfo( - content::RenderFrameHost* render_frame_host, - device::mojom::VRService::GetImmersiveVRDisplayInfoCallback callback) { - DVLOG(2) << __func__ << ": id=" << id_; - device::mojom::VRDisplayInfoPtr device_info = GetVRDisplayInfo(); - if (device_info) { - std::move(callback).Run(std::move(device_info)); - return; - } - - pending_initialization_callbacks_.push_back(std::move(callback)); - runtime_->EnsureInitialized( - base::BindOnce(&BrowserXRRuntime::OnInitialized, base::Unretained(this))); -} - } // namespace vr
diff --git a/chrome/browser/vr/service/browser_xr_runtime.h b/chrome/browser/vr/service/browser_xr_runtime.h index d4d566a1..13b5b73 100644 --- a/chrome/browser/vr/service/browser_xr_runtime.h +++ b/chrome/browser/vr/service/browser_xr_runtime.h
@@ -83,9 +83,6 @@ device::mojom::VRDisplayInfoPtr GetVRDisplayInfo() { return display_info_.Clone(); } - void InitializeAndGetDisplayInfo( - content::RenderFrameHost* render_frame_host, - device::mojom::VRService::GetImmersiveVRDisplayInfoCallback callback); // Methods called to support metrics/overlays on Windows. void AddObserver(BrowserXRRuntimeObserver* observer) { @@ -114,7 +111,6 @@ mojo::PendingRemote<device::mojom::XRSessionController> immersive_session_controller); void OnImmersiveSessionError(); - void OnInitialized(); device::mojom::XRDeviceId id_; mojo::Remote<device::mojom::XRRuntime> runtime_; @@ -128,8 +124,6 @@ mojo::AssociatedReceiver<device::mojom::XRRuntimeEventListener> receiver_{ this}; - std::vector<device::mojom::VRService::GetImmersiveVRDisplayInfoCallback> - pending_initialization_callbacks_; base::ObserverList<BrowserXRRuntimeObserver> observers_;
diff --git a/chrome/browser/vr/service/vr_service_impl.cc b/chrome/browser/vr/service/vr_service_impl.cc index f903b13..55ce1cf7 100644 --- a/chrome/browser/vr/service/vr_service_impl.cc +++ b/chrome/browser/vr/service/vr_service_impl.cc
@@ -605,26 +605,6 @@ } } -void VRServiceImpl::GetImmersiveVRDisplayInfo( - device::mojom::VRService::GetImmersiveVRDisplayInfoCallback callback) { - if (!initialization_complete_) { - pending_requests_.push_back( - base::BindOnce(&VRServiceImpl::GetImmersiveVRDisplayInfo, - base::Unretained(this), std::move(callback))); - return; - } - - BrowserXRRuntime* immersive_runtime = - runtime_manager_->GetImmersiveVrRuntime(); - if (immersive_runtime) { - immersive_runtime->InitializeAndGetDisplayInfo(render_frame_host_, - std::move(callback)); - return; - } - - std::move(callback).Run(nullptr); -} - void VRServiceImpl::OnExitPresent() { DVLOG(2) << __func__;
diff --git a/chrome/browser/vr/service/vr_service_impl.h b/chrome/browser/vr/service/vr_service_impl.h index 44b98156..4389255f 100644 --- a/chrome/browser/vr/service/vr_service_impl.h +++ b/chrome/browser/vr/service/vr_service_impl.h
@@ -65,10 +65,6 @@ device::mojom::VRService::SupportsSessionCallback callback) override; void ExitPresent(ExitPresentCallback on_exited) override; void SetFramesThrottled(bool throttled) override; - // device::mojom::VRService WebVR compatibility functions - void GetImmersiveVRDisplayInfo( - device::mojom::VRService::GetImmersiveVRDisplayInfoCallback callback) - override; void InitializationComplete(); @@ -81,7 +77,6 @@ void OnExitPresent(); void OnVisibilityStateChanged( device::mojom::XRVisibilityState visibility_state); - bool InFocusedFrame() { return in_focused_frame_; } void OnDisplayInfoChanged(); void RuntimesChanged();
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 82927ac..ed39f54 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -133,6 +133,7 @@ } else { # New paks should be added here by default. sources += [ + "$root_gen_dir/chrome/bookmarks_resources.pak", "$root_gen_dir/chrome/component_extension_resources.pak", "$root_gen_dir/chrome/dev_ui_resources.pak", "$root_gen_dir/chrome/downloads_resources.pak", @@ -142,6 +143,7 @@ "$root_gen_dir/headless/headless_lib_resources.pak", ] deps += [ + "//chrome/browser/resources:bookmarks_resources", "//chrome/browser/resources:component_extension_resources", "//chrome/browser/resources:dev_ui_paks", "//chrome/browser/resources:downloads_resources",
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index a5c5055f..8978e11 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -417,8 +417,8 @@ #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) // Both encryption schemes are supported on ChromeOS. - capability.encryption_schemes.insert(media::EncryptionMode::kCenc); - capability.encryption_schemes.insert(media::EncryptionMode::kCbcs); + capability.encryption_schemes.insert(media::EncryptionScheme::kCenc); + capability.encryption_schemes.insert(media::EncryptionScheme::kCbcs); // Both temporary and persistent sessions are supported on ChromeOS. capability.session_types.insert(media::CdmSessionType::kTemporary); @@ -656,7 +656,7 @@ // Supported codecs are hard-coded in ExternalClearKeyProperties. content::CdmCapability capability( - {}, {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}, + {}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs}, {media::CdmSessionType::kTemporary, media::CdmSessionType::kPersistentLicense, media::CdmSessionType::kPersistentUsageRecord},
diff --git a/chrome/common/media/cdm_manifest.cc b/chrome/common/media/cdm_manifest.cc index e7147156..a35b5e9 100644 --- a/chrome/common/media/cdm_manifest.cc +++ b/chrome/common/media/cdm_manifest.cc
@@ -218,7 +218,7 @@ // fail. Unrecognized values will be reported but otherwise ignored. bool GetEncryptionSchemes( const base::Value& manifest, - base::flat_set<media::EncryptionMode>* encryption_schemes) { + base::flat_set<media::EncryptionScheme>* encryption_schemes) { DCHECK(manifest.is_dict()); DCHECK(encryption_schemes); @@ -227,7 +227,7 @@ if (!value) { // No manifest entry found, so assume only 'cenc' supported for backwards // compatibility. - encryption_schemes->insert(media::EncryptionMode::kCenc); + encryption_schemes->insert(media::EncryptionScheme::kCenc); return true; } @@ -238,7 +238,7 @@ } base::span<const base::Value> list = value->GetList(); - base::flat_set<media::EncryptionMode> result; + base::flat_set<media::EncryptionScheme> result; for (const auto& item : list) { if (!item.is_string()) { DLOG(ERROR) << "Unrecognized item type in CDM manifest entry " @@ -248,9 +248,9 @@ const std::string& scheme = item.GetString(); if (scheme == kCdmSupportedEncryptionSchemeCenc) { - result.insert(media::EncryptionMode::kCenc); + result.insert(media::EncryptionScheme::kCenc); } else if (scheme == kCdmSupportedEncryptionSchemeCbcs) { - result.insert(media::EncryptionMode::kCbcs); + result.insert(media::EncryptionScheme::kCbcs); } else { DLOG(WARNING) << "Unrecognized encryption scheme '" << scheme << "' in CDM manifest entry "
diff --git a/chrome/common/media/cdm_manifest_unittest.cc b/chrome/common/media/cdm_manifest_unittest.cc index b12ee87..df99ccdd 100644 --- a/chrome/common/media/cdm_manifest_unittest.cc +++ b/chrome/common/media/cdm_manifest_unittest.cc
@@ -107,8 +107,8 @@ } void CheckEncryptionSchemes( - const base::flat_set<media::EncryptionMode>& actual, - const std::vector<media::EncryptionMode>& expected) { + const base::flat_set<media::EncryptionScheme>& actual, + const std::vector<media::EncryptionScheme>& expected) { EXPECT_EQ(expected.size(), actual.size()); for (const auto& encryption_scheme : expected) { EXPECT_TRUE(base::Contains(actual, encryption_scheme)); @@ -198,7 +198,7 @@ media::VideoCodec::kCodecAV1}); CheckEncryptionSchemes( capability.encryption_schemes, - {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}); + {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs}); CheckSessionTypes(capability.session_types, {media::CdmSessionType::kTemporary, media::CdmSessionType::kPersistentLicense}); @@ -212,7 +212,7 @@ EXPECT_TRUE(ParseCdmManifest(manifest, &capability)); CheckCodecs(capability.video_codecs, {}); CheckEncryptionSchemes(capability.encryption_schemes, - {media::EncryptionMode::kCenc}); + {media::EncryptionScheme::kCenc}); CheckSessionTypes(capability.session_types, {media::CdmSessionType::kTemporary}); CheckProxyProtocols(capability.cdm_proxy_protocols, {}); @@ -298,14 +298,14 @@ manifest.SetKey(kCdmSupportedEncryptionSchemesName, MakeListValue("cenc")); EXPECT_TRUE(ParseCdmManifest(manifest, &capability)); CheckEncryptionSchemes(capability.encryption_schemes, - {media::EncryptionMode::kCenc}); + {media::EncryptionScheme::kCenc}); } { CdmCapability capability; manifest.SetKey(kCdmSupportedEncryptionSchemesName, MakeListValue("cbcs")); EXPECT_TRUE(ParseCdmManifest(manifest, &capability)); CheckEncryptionSchemes(capability.encryption_schemes, - {media::EncryptionMode::kCbcs}); + {media::EncryptionScheme::kCbcs}); } { // Try multiple valid entries. @@ -315,7 +315,7 @@ EXPECT_TRUE(ParseCdmManifest(manifest, &capability)); CheckEncryptionSchemes( capability.encryption_schemes, - {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}); + {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs}); } { // Invalid encryption schemes are ignored. However, if value specified then @@ -331,7 +331,7 @@ MakeListValue("invalid", "cenc")); EXPECT_TRUE(ParseCdmManifest(manifest, &capability)); CheckEncryptionSchemes(capability.encryption_schemes, - {media::EncryptionMode::kCenc}); + {media::EncryptionScheme::kCenc}); } { // Wrong types are an error. @@ -345,7 +345,7 @@ EXPECT_TRUE(manifest.RemoveKey(kCdmSupportedEncryptionSchemesName)); EXPECT_TRUE(ParseCdmManifest(manifest, &capability)); CheckEncryptionSchemes(capability.encryption_schemes, - {media::EncryptionMode::kCenc}); + {media::EncryptionScheme::kCenc}); } } @@ -442,7 +442,7 @@ media::VideoCodec::kCodecAV1}); CheckEncryptionSchemes( capability.encryption_schemes, - {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}); + {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs}); CheckSessionTypes(capability.session_types, {media::CdmSessionType::kTemporary, media::CdmSessionType::kPersistentLicense}); @@ -522,7 +522,7 @@ EXPECT_TRUE(ParseCdmManifestFromPath(manifest_path, &version, &capability)); CheckCodecs(capability.video_codecs, {}); CheckEncryptionSchemes(capability.encryption_schemes, - {media::EncryptionMode::kCenc}); + {media::EncryptionScheme::kCenc}); CheckSessionTypes(capability.session_types, {media::CdmSessionType::kTemporary}); CheckProxyProtocols(capability.cdm_proxy_protocols, {});
diff --git a/chrome/installer/mac/signing/pipeline.py b/chrome/installer/mac/signing/pipeline.py index c1fb432..e3d520c8 100644 --- a/chrome/installer/mac/signing/pipeline.py +++ b/chrome/installer/mac/signing/pipeline.py
@@ -163,10 +163,15 @@ # 2. The outer product archive (which is the installable thing that has # pre-install requirements). This is built with `productbuild`. - # The component package. + ## The component package. - component_pkg_path = os.path.join(paths.work, - '{}.pkg'.format(dist_config.app_product)) + # The spaces are removed from |dist_config.app_product| for the component + # package path due to a bug in Installer.app that causes the "Show Files" + # window to be blank if there is a space in a component package name. + # https://stackoverflow.com/questions/43031272/ + component_pkg_name = '{}.pkg'.format(dist_config.app_product).replace( + ' ', '') + component_pkg_path = os.path.join(paths.work, component_pkg_name) app_path = os.path.join(paths.work, dist_config.app_dir) commands.run_command([ @@ -175,7 +180,7 @@ '/Applications', component_pkg_path ]) - # The product archive. + ## The product archive. # There are two steps here. The first is to create the "distribution file" # which describes the product archive. `productbuild` has a mode to generate
diff --git a/chrome/installer/mac/signing/pipeline_test.py b/chrome/installer/mac/signing/pipeline_test.py index 68ca9796..fc6917a 100644 --- a/chrome/installer/mac/signing/pipeline_test.py +++ b/chrome/installer/mac/signing/pipeline_test.py
@@ -314,7 +314,7 @@ '$W/App Product.req', _get_adjacent_item(productbuild_synthesize_args, '--product')) self.assertEqual( - '$W/App Product.pkg', + '$W/AppProduct.pkg', _get_adjacent_item(productbuild_synthesize_args, '--package')) self.assertEqual( @@ -401,7 +401,7 @@ '$W/App Product.req', _get_adjacent_item(productbuild_synthesize_args, '--product')) self.assertEqual( - '$W/App Product.pkg', + '$W/AppProduct.pkg', _get_adjacent_item(productbuild_synthesize_args, '--package')) self.assertEqual(
diff --git a/chrome/renderer/media/chrome_key_systems_provider_unittest.cc b/chrome/renderer/media/chrome_key_systems_provider_unittest.cc index a57a4ab..31c21b1 100644 --- a/chrome/renderer/media/chrome_key_systems_provider_unittest.cc +++ b/chrome/renderer/media/chrome_key_systems_provider_unittest.cc
@@ -29,7 +29,7 @@ } media::EmeConfigRule GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_scheme) const override { + media::EncryptionScheme encryption_scheme) const override { return media::EmeConfigRule::NOT_SUPPORTED; }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 048cdfb..f85cbbe67 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -525,6 +525,7 @@ sources = [ "../browser/engagement/important_sites_util_browsertest.cc", + "../browser/payments/empty_parameters_browsertest.cc", "../browser/payments/has_enrolled_instrument_browsertest.cc", "../browser/payments/has_enrolled_instrument_query_quota_browsertest.cc", "../browser/payments/hybrid_request_skip_ui_browsertest.cc", @@ -1426,6 +1427,7 @@ "//chrome/browser/media/router:test_support", "//chrome/browser/resources/chromeos/autoclick:browser_tests", "//chrome/browser/resources/chromeos/chromevox:browser_tests", + "//chrome/browser/resources/chromeos/login:browser_tests", "//chrome/browser/resources/chromeos/select_to_speak:browser_tests", "//chrome/browser/resources/chromeos/switch_access:browser_tests", "//chrome/services/file_util/public/cpp:browser_tests", @@ -1457,7 +1459,6 @@ ] if (is_chromeos) { deps += [ - "//chrome/browser/resources/chromeos/login:browser_tests", "//chromeos/components/help_app_ui:browser_tests_js", "//chromeos/components/media_app_ui:browser_tests_js", ] @@ -1841,6 +1842,7 @@ } if (toolkit_views) { sources += [ + "../browser/payments/empty_parameters_browsertest.cc", "../browser/payments/has_enrolled_instrument_browsertest.cc", "../browser/payments/has_enrolled_instrument_query_quota_browsertest.cc", "../browser/payments/journey_logger_browsertest.cc",
diff --git a/chrome/test/data/android/render_tests/StartSurfaceLayoutTest.3_incognito_ntps.Nexus_5-19.png.sha1 b/chrome/test/data/android/render_tests/StartSurfaceLayoutTest.3_incognito_ntps.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..59c7543 --- /dev/null +++ b/chrome/test/data/android/render_tests/StartSurfaceLayoutTest.3_incognito_ntps.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +aa72b682f2a1056919067f870c576e0f9f531302 \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/autotest_private/test.js b/chrome/test/data/extensions/api_test/autotest_private/test.js index ae5846c..ac15733d 100644 --- a/chrome/test/data/extensions/api_test/autotest_private/test.js +++ b/chrome/test/data/extensions/api_test/autotest_private/test.js
@@ -613,15 +613,22 @@ // This test verifies that test can get the window list and set // window state. function getWindowInfoAndSetState() { + // Button Masks + var kMinimizeMask = 1 << 0; + var kMaximizeRestoreMask = 1 << 1; + var kCloseMask = 1 << 2; + var kLeftSnappedMask = 1 << 3; + var kRightSnappedMask = 1 << 4; + chrome.autotestPrivate.getAppWindowList(function(list) { - var found = false; + var browserFrameIndex = -1; chrome.test.assertEq(1, list.length); - for (i = 0; i < list.length; i++) { + for (var i = 0; i < list.length; i++) { var window = list[i]; - if (window.name != 'BrowserFrame') { + if (window.windowType != 'Browser') { continue; } - found = true; + browserFrameIndex = i; // Sanity check chrome.test.assertEq('BrowserFrame', window.name); chrome.test.assertTrue(window.title.includes('New Tab') > 0); @@ -634,10 +641,14 @@ chrome.test.assertTrue(window.hasFocus); chrome.test.assertTrue(window.isActive); chrome.test.assertFalse(window.hasCapture); + chrome.test.assertEq(42, window.captionHeight); + chrome.test.assertEq( + window.captionButtonVisibleStatus, + kMinimizeMask | kMaximizeRestoreMask | kCloseMask | + kLeftSnappedMask | kRightSnappedMask); var change = new Object(); change.eventType = 'WMEventMaximize'; - console.log('maximizing'); chrome.autotestPrivate.setAppWindowState( window.id, change, @@ -647,7 +658,7 @@ chrome.test.succeed(); }); } - chrome.test.assertTrue(found); + chrome.test.assertTrue(-1 != browserFrameIndex); }); },
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js index b3c0877..ca50809e 100644 --- a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js +++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
@@ -570,6 +570,33 @@ embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName); } +function testNewWindowAndUpdateOpener() { + var testName = 'testNewWindowAndUpdateOpener'; + var webview = embedder.setUpGuest_('foobar'); + + // Convert window.open requests into new <webview> tags. + var onNewWindow = function(e) { + chrome.test.log('Embedder notified on newwindow'); + embedder.assertCorrectEvent_(e, ''); + + var newwebview = document.createElement('webview'); + document.querySelector('#webview-tag-container').appendChild(newwebview); + try { + e.window.attach(newwebview); + } catch (e) { + embedder.test.fail(); + } + + // Exit after the first opened window is attached. The rest of the test is + // implemented on the C++ side. + embedder.test.succeed(); + }; + webview.addEventListener('newwindow', onNewWindow); + + // Load a new window with the given name. + embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName); +} + embedder.test.testList = { 'testNewWindowAttachAfterOpenerDestroyed': testNewWindowAttachAfterOpenerDestroyed, @@ -589,7 +616,8 @@ 'testNewWindowWebRequestCloseWindow': testNewWindowWebRequestCloseWindow, 'testNewWindowWebRequestRemoveElement': testNewWindowWebRequestRemoveElement, 'testNewWindowWebViewNameTakesPrecedence': - testNewWindowWebViewNameTakesPrecedence + testNewWindowWebViewNameTakesPrecedence, + 'testNewWindowAndUpdateOpener': testNewWindowAndUpdateOpener }; onload = function() {
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java index 43bbf7e7..394b2ed 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java
@@ -10,8 +10,9 @@ import android.os.Build; import android.support.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; import org.chromium.chromecast.base.Controller; import org.chromium.chromecast.base.Observable;
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java index 1211d132..ea3a3b8 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java
@@ -7,13 +7,14 @@ import android.content.Intent; import android.content.SharedPreferences; +import androidx.annotation.VisibleForTesting; + import org.json.JSONException; import org.json.JSONObject; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; import org.chromium.chromecast.base.Itertools; import java.util.concurrent.atomic.AtomicBoolean;
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java index b114443..4b82070 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java
@@ -13,8 +13,9 @@ import android.os.IBinder; import android.os.PatternMatcher; +import androidx.annotation.VisibleForTesting; + import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; import org.chromium.chromecast.base.Controller; import org.chromium.content_public.browser.WebContents;
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/ElidedLogcatProvider.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/ElidedLogcatProvider.java index 05e6ddb..9305d31b 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/ElidedLogcatProvider.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/ElidedLogcatProvider.java
@@ -6,8 +6,9 @@ import android.os.SystemClock; +import androidx.annotation.VisibleForTesting; + import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; import org.chromium.base.task.AsyncTask; import java.io.BufferedReader;
diff --git a/chromecast/media/cma/base/decoder_config_adapter.cc b/chromecast/media/cma/base/decoder_config_adapter.cc index fad7a9f..2b60efc 100644 --- a/chromecast/media/cma/base/decoder_config_adapter.cc +++ b/chromecast/media/cma/base/decoder_config_adapter.cc
@@ -130,28 +130,13 @@ } } -::media::EncryptionScheme::CipherMode ToMediaCipherMode( - EncryptionScheme scheme) { +EncryptionScheme ToEncryptionScheme(::media::EncryptionScheme scheme) { switch (scheme) { - case EncryptionScheme::kUnencrypted: - return ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED; - case EncryptionScheme::kAesCtr: - return ::media::EncryptionScheme::CIPHER_MODE_AES_CTR; - case EncryptionScheme::kAesCbc: - return ::media::EncryptionScheme::CIPHER_MODE_AES_CBC; - default: - NOTREACHED(); - return ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED; - } -} - -EncryptionScheme ToEncryptionScheme(const ::media::EncryptionScheme& scheme) { - switch (scheme.mode()) { - case ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED: + case ::media::EncryptionScheme::kUnencrypted: return EncryptionScheme::kUnencrypted; - case ::media::EncryptionScheme::CIPHER_MODE_AES_CTR: + case ::media::EncryptionScheme::kCenc: return EncryptionScheme::kAesCtr; - case ::media::EncryptionScheme::CIPHER_MODE_AES_CBC: + case ::media::EncryptionScheme::kCbcs: return EncryptionScheme::kAesCbc; default: NOTREACHED(); @@ -159,10 +144,18 @@ } } -// TODO(yucliu): Remove pattern after update ::media::Audio/VideoDecoderConfig. ::media::EncryptionScheme ToMediaEncryptionScheme(EncryptionScheme scheme) { - return ::media::EncryptionScheme(ToMediaCipherMode(scheme), - ::media::EncryptionPattern()); + switch (scheme) { + case EncryptionScheme::kUnencrypted: + return ::media::EncryptionScheme::kUnencrypted; + case EncryptionScheme::kAesCtr: + return ::media::EncryptionScheme::kCenc; + case EncryptionScheme::kAesCbc: + return ::media::EncryptionScheme::kCbcs; + default: + NOTREACHED(); + return ::media::EncryptionScheme::kUnencrypted; + } } } // namespace
diff --git a/chromecast/media/cma/base/demuxer_stream_for_test.cc b/chromecast/media/cma/base/demuxer_stream_for_test.cc index 99d79204..f1c11a720 100644 --- a/chromecast/media/cma/base/demuxer_stream_for_test.cc +++ b/chromecast/media/cma/base/demuxer_stream_for_test.cc
@@ -61,7 +61,7 @@ ::media::VideoDecoderConfig::AlphaMode::kIsOpaque, ::media::VideoColorSpace(), ::media::kNoTransformation, coded_size, visible_rect, natural_size, ::media::EmptyExtraData(), - ::media::Unencrypted()); + ::media::EncryptionScheme::kUnencrypted); } ::media::DemuxerStream::Type DemuxerStreamForTest::type() const {
diff --git a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc index 3eb5c38..e20fdf1a 100644 --- a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc +++ b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
@@ -137,7 +137,7 @@ ::media::AudioDecoderConfig audio_config( ::media::kCodecMP3, ::media::kSampleFormatS16, ::media::CHANNEL_LAYOUT_STEREO, 44100, ::media::EmptyExtraData(), - ::media::Unencrypted()); + ::media::EncryptionScheme::kUnencrypted); AvPipelineClient client; client.eos_cb = base::Bind(&PipelineHelper::OnEos, base::Unretained(this), STREAM_AUDIO);
diff --git a/chromecast/media/cma/test/mock_frame_provider.cc b/chromecast/media/cma/test/mock_frame_provider.cc index 6b4e19b9..b7c5568 100644 --- a/chromecast/media/cma/test/mock_frame_provider.cc +++ b/chromecast/media/cma/test/mock_frame_provider.cc
@@ -84,15 +84,12 @@ ::media::VideoDecoderConfig::AlphaMode::kIsOpaque, ::media::VideoColorSpace(), ::media::kNoTransformation, coded_size, visible_rect, natural_size, ::media::EmptyExtraData(), - ::media::Unencrypted()); + ::media::EncryptionScheme::kUnencrypted); audio_config = ::media::AudioDecoderConfig( - ::media::kCodecAAC, - ::media::kSampleFormatS16, - ::media::CHANNEL_LAYOUT_STEREO, - 44100, - ::media::EmptyExtraData(), - ::media::Unencrypted()); + ::media::kCodecAAC, ::media::kSampleFormatS16, + ::media::CHANNEL_LAYOUT_STEREO, 44100, ::media::EmptyExtraData(), + ::media::EncryptionScheme::kUnencrypted); } read_cb.Run(buffer, audio_config, video_config);
diff --git a/chromecast/renderer/media/key_systems_cast.cc b/chromecast/renderer/media/key_systems_cast.cc index 21166af..b06c086 100644 --- a/chromecast/renderer/media/key_systems_cast.cc +++ b/chromecast/renderer/media/key_systems_cast.cc
@@ -97,8 +97,8 @@ } EmeConfigRule GetEncryptionSchemeConfigRule( - ::media::EncryptionMode encryption_mode) const override { - if (encryption_mode == ::media::EncryptionMode::kCenc) + ::media::EncryptionScheme encryption_scheme) const override { + if (encryption_scheme == ::media::EncryptionScheme::kCenc) return EmeConfigRule::SUPPORTED; return EmeConfigRule::NOT_SUPPORTED; } @@ -162,8 +162,8 @@ #if BUILDFLAG(ENABLE_WIDEVINE) using Robustness = cdm::WidevineKeySystemProperties::Robustness; - base::flat_set<::media::EncryptionMode> encryption_schemes = { - ::media::EncryptionMode::kCenc, ::media::EncryptionMode::kCbcs}; + base::flat_set<::media::EncryptionScheme> encryption_schemes = { + ::media::EncryptionScheme::kCenc, ::media::EncryptionScheme::kCbcs}; key_systems_properties->emplace_back(new cdm::WidevineKeySystemProperties( codecs, // Regular codecs.
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl.cc b/chromeos/services/multidevice_setup/multidevice_setup_impl.cc index 256e47a..b8a5d755 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl.cc
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <utility> +#include <vector> + #include "chromeos/services/multidevice_setup/multidevice_setup_impl.h" #include "base/memory/ptr_util.h" @@ -182,6 +185,19 @@ std::move(callback).Run(eligible_remote_devices); } +void MultiDeviceSetupImpl::GetEligibleActiveHostDevices( + GetEligibleActiveHostDevicesCallback callback) { + std::vector<mojom::HostDevicePtr> eligible_active_hosts; + for (const auto& host_device : + eligible_host_devices_provider_->GetEligibleActiveHostDevices()) { + eligible_active_hosts.push_back( + mojom::HostDevice::New(host_device.remote_device.GetRemoteDevice(), + host_device.connectivity_status)); + } + + std::move(callback).Run(std::move(eligible_active_hosts)); +} + void MultiDeviceSetupImpl::SetHostDevice(const std::string& host_device_id, const std::string& auth_token, SetHostDeviceCallback callback) {
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl.h b/chromeos/services/multidevice_setup/multidevice_setup_impl.h index 0f01a47..89309f62 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl.h +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl.h
@@ -87,6 +87,8 @@ void AddFeatureStateObserver( mojo::PendingRemote<mojom::FeatureStateObserver> observer) override; void GetEligibleHostDevices(GetEligibleHostDevicesCallback callback) override; + void GetEligibleActiveHostDevices( + GetEligibleActiveHostDevicesCallback callback) override; void SetHostDevice(const std::string& host_device_id, const std::string& auth_token, SetHostDeviceCallback callback) override;
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc b/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc index 2d40700..10d3fd2 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc
@@ -633,6 +633,20 @@ return eligible_devices_list; } + std::vector<mojom::HostDevicePtr> CallGetEligibleActiveHostDevices() { + base::RunLoop run_loop; + multidevice_setup_->GetEligibleActiveHostDevices(base::BindOnce( + &MultiDeviceSetupImplTest::OnEligibleActiveHostDevicesFetched, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + + std::vector<mojom::HostDevicePtr> eligible_devices_list = + std::move(*last_eligible_active_devices_list_); + last_eligible_active_devices_list_.reset(); + + return eligible_devices_list; + } + bool CallSetHostDevice(const std::string& host_device_id, const std::string& auth_token) { base::RunLoop run_loop; @@ -810,6 +824,15 @@ std::move(quit_closure).Run(); } + void OnEligibleActiveHostDevicesFetched( + base::OnceClosure quit_closure, + std::vector<mojom::HostDevicePtr> eligible_active_devices_list) { + EXPECT_FALSE(last_eligible_active_devices_list_); + last_eligible_active_devices_list_ = + std::move(eligible_active_devices_list); + std::move(quit_closure).Run(); + } + void OnSetHostDeviceResult(base::OnceClosure quit_closure, bool success) { EXPECT_FALSE(last_set_host_success_); last_set_host_success_ = success; @@ -899,6 +922,8 @@ base::Optional<bool> last_debug_event_success_; base::Optional<multidevice::RemoteDeviceList> last_eligible_devices_list_; + base::Optional<std::vector<mojom::HostDevicePtr>> + last_eligible_active_devices_list_; base::Optional<bool> last_set_host_success_; base::Optional<bool> last_set_host_without_auth_success_; base::Optional< @@ -1181,6 +1206,29 @@ fake_host_backend_delegate()->NotifyHostChangedOnBackend(base::nullopt); } +TEST_F(MultiDeviceSetupImplTest, TestGetEligibleActiveHosts) { + // Start with no eligible devices. + EXPECT_TRUE(CallGetEligibleActiveHostDevices().empty()); + + multidevice::DeviceWithConnectivityStatusList host_device_list; + for (auto remote_device_ref : test_devices()) { + host_device_list.emplace_back(multidevice::DeviceWithConnectivityStatus( + remote_device_ref, cryptauthv2::ConnectivityStatus::ONLINE)); + } + // Simulate a sync occurring; now, all of the test devices are eligible hosts. + fake_eligible_host_devices_provider()->set_eligible_active_host_devices( + host_device_list); + + std::vector<mojom::HostDevicePtr> result_hosts = + CallGetEligibleActiveHostDevices(); + for (size_t i = 0; i < kNumTestDevices; i++) { + EXPECT_EQ(*GetMutableRemoteDevice(test_devices()[i]), + result_hosts[i]->remote_device); + EXPECT_EQ(cryptauthv2::ConnectivityStatus::ONLINE, + result_hosts[i]->connectivity_status); + } +} + TEST_F(MultiDeviceSetupImplTest, TestSetHostDevice_InvalidAuthToken) { // Start valid eligible host devices. fake_eligible_host_devices_provider()->set_eligible_host_devices(
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc b/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc index d7f2506..cb03408b 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <utility> + #include "chromeos/services/multidevice_setup/multidevice_setup_initializer.h" #include "base/logging.h" @@ -138,6 +140,16 @@ pending_get_eligible_hosts_args_.push_back(std::move(callback)); } +void MultiDeviceSetupInitializer::GetEligibleActiveHostDevices( + GetEligibleActiveHostDevicesCallback callback) { + if (multidevice_setup_impl_) { + multidevice_setup_impl_->GetEligibleActiveHostDevices(std::move(callback)); + return; + } + + pending_get_eligible_active_hosts_args_.push_back(std::move(callback)); +} + void MultiDeviceSetupInitializer::SetHostDevice( const std::string& host_device_id, const std::string& auth_token, @@ -326,6 +338,12 @@ } pending_get_eligible_hosts_args_.clear(); + for (auto& get_eligible_callback : pending_get_eligible_active_hosts_args_) { + multidevice_setup_impl_->GetEligibleActiveHostDevices( + std::move(get_eligible_callback)); + } + pending_get_eligible_active_hosts_args_.clear(); + for (auto& get_host_callback : pending_get_host_args_) multidevice_setup_impl_->GetHostStatus(std::move(get_host_callback)); pending_get_host_args_.clear();
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_initializer.h b/chromeos/services/multidevice_setup/multidevice_setup_initializer.h index 642bf8b..d213a12 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_initializer.h +++ b/chromeos/services/multidevice_setup/multidevice_setup_initializer.h
@@ -95,6 +95,8 @@ void AddFeatureStateObserver( mojo::PendingRemote<mojom::FeatureStateObserver> observer) override; void GetEligibleHostDevices(GetEligibleHostDevicesCallback callback) override; + void GetEligibleActiveHostDevices( + GetEligibleActiveHostDevicesCallback callback) override; void SetHostDevice(const std::string& host_device_id, const std::string& auth_token, SetHostDeviceCallback callback) override; @@ -140,6 +142,8 @@ std::vector<mojo::PendingRemote<mojom::FeatureStateObserver>> pending_feature_state_observers_; std::vector<GetEligibleHostDevicesCallback> pending_get_eligible_hosts_args_; + std::vector<GetEligibleActiveHostDevicesCallback> + pending_get_eligible_active_hosts_args_; std::vector<GetHostStatusCallback> pending_get_host_args_; std::vector<std::tuple<mojom::Feature, bool,
diff --git a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc index 3363734..d1c451ba 100644 --- a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc +++ b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <utility> + #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h" #include "base/containers/flat_map.h" @@ -22,6 +24,13 @@ std::move(get_eligible_hosts_arg).Run(multidevice::RemoteDeviceList()); } + for (auto& get_eligible_active_hosts_arg : get_eligible_active_hosts_args_) { + if (get_eligible_active_hosts_arg) { + std::move(get_eligible_active_hosts_arg) + .Run(std::vector<mojom::HostDevicePtr>()); + } + } + for (auto& set_host_arg : set_host_args_) { if (std::get<2>(set_host_arg)) std::move(std::get<2>(set_host_arg)).Run(false /* success */); @@ -115,6 +124,11 @@ get_eligible_hosts_args_.push_back(std::move(callback)); } +void FakeMultiDeviceSetup::GetEligibleActiveHostDevices( + GetEligibleActiveHostDevicesCallback callback) { + get_eligible_active_hosts_args_.push_back(std::move(callback)); +} + void FakeMultiDeviceSetup::SetHostDevice(const std::string& host_device_id, const std::string& auth_token, SetHostDeviceCallback callback) {
diff --git a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h index 7ff757b..0a418dc6 100644 --- a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h +++ b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h
@@ -94,6 +94,8 @@ void AddFeatureStateObserver( mojo::PendingRemote<mojom::FeatureStateObserver> observer) override; void GetEligibleHostDevices(GetEligibleHostDevicesCallback callback) override; + void GetEligibleActiveHostDevices( + GetEligibleActiveHostDevicesCallback callback) override; void SetHostDevice(const std::string& host_device_id, const std::string& auth_token, SetHostDeviceCallback callback) override; @@ -120,6 +122,8 @@ mojo::RemoteSet<mojom::FeatureStateObserver> feature_state_observers_; std::vector<GetEligibleHostDevicesCallback> get_eligible_hosts_args_; + std::vector<GetEligibleActiveHostDevicesCallback> + get_eligible_active_hosts_args_; std::vector<std::tuple<std::string, std::string, SetHostDeviceCallback>> set_host_args_; size_t num_remove_host_calls_ = 0u;
diff --git a/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom b/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom index 2421ba5..e7566188 100644 --- a/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom +++ b/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom
@@ -5,6 +5,7 @@ module chromeos.multidevice_setup.mojom; import "chromeos/components/multidevice/mojom/multidevice_types.mojom"; +import "chromeos/services/device_sync/public/mojom/device_sync.mojom"; // Enumeration of event types which can be dispatched. Only used for debugging // purposes. @@ -91,6 +92,13 @@ kFurtherSetupRequired = 8, }; +// Metadata describing a device that can used as the host for multidevice +// features. +struct HostDevice { + chromeos.multidevice.mojom.RemoteDevice remote_device; + chromeos.device_sync.mojom.ConnectivityStatus connectivity_status; +}; + interface AccountStatusChangeDelegate { // Callback which indicates that one or more MultiDevice host phones are // available for setup with the MultiDevice setup flow. This function is only @@ -154,6 +162,12 @@ GetEligibleHostDevices() => (array<chromeos.multidevice.mojom.RemoteDevice> eligible_host_devices); + // Provides a list of all active eligible host devices (i.e., those which + // can be passed to SetHostDevice()) sorted by last usage as determined by + // the server. + GetEligibleActiveHostDevices() => + (array<HostDevice> eligible_host_devices); + // Sets the host associated with the provided device ID as the host device // for this account. The provided auth token must be valid in order to prove // that the user is authenticated. If called when there is no current host or
diff --git a/components/arc/bluetooth/bluetooth_type_converters.cc b/components/arc/bluetooth/bluetooth_type_converters.cc index cba30eb..1a149ce 100644 --- a/components/arc/bluetooth/bluetooth_type_converters.cc +++ b/components/arc/bluetooth/bluetooth_type_converters.cc
@@ -12,10 +12,9 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" -#include "base/stl_util.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "components/arc/bluetooth/bluetooth_type_converters.h" +#include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_gatt_service.h" #include "device/bluetooth/public/cpp/bluetooth_uuid.h" @@ -31,16 +30,6 @@ constexpr uint16_t kBluetoothProfileDescriptorList = 0x0009; constexpr uint16_t kServiceName = 0x0100; -bool IsNonHex(char c) { - return !isxdigit(c); -} - -std::string StripNonHex(const std::string& str) { - std::string result = str; - base::EraseIf(result, IsNonHex); - return result; -} - } // namespace namespace mojo { @@ -52,7 +41,10 @@ arc::mojom::BluetoothAddressPtr mojo_addr = arc::mojom::BluetoothAddress::New(); - base::HexStringToBytes(StripNonHex(address), &mojo_addr->address); + + mojo_addr->address.resize(kAddressSize); + if (!device::BluetoothDevice::ParseAddress(address, mojo_addr->address)) + mojo_addr->address.clear(); return mojo_addr; }
diff --git a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java index 8229aae0..2d619f6a 100644 --- a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java +++ b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java
@@ -13,6 +13,7 @@ // BackgroundTaskSchedulerUma#toUmaEnumValueFromTaskId(int) method. Also, if the new task id // is related to a BackgroundTask class in //chrome, remember to update // ChromeBackgroundTaskFactory#getBackgroundTaskFromTaskId(int). + // Id from 111000000 to 111999999 are reserved for internal usage. public static final int TEST = 0x00008378; public static final int OMAHA_JOB_ID = 0x00011684;
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc index 3e5f4ff3..1e1c3fce 100644 --- a/components/bookmarks/browser/bookmark_model.cc +++ b/components/bookmarks/browser/bookmark_model.cc
@@ -205,6 +205,7 @@ DCHECK(parent); size_t index = size_t{parent->GetIndexOf(node)}; DCHECK_NE(size_t{-1}, index); + DCHECK(!is_permanent_node(node)); for (BookmarkModelObserver& observer : observers_) observer.OnWillRemoveBookmarks(this, parent, index, node);
diff --git a/components/bookmarks/browser/bookmark_model.h b/components/bookmarks/browser/bookmark_model.h index 568e9b41..073f137d 100644 --- a/components/bookmarks/browser/bookmark_model.h +++ b/components/bookmarks/browser/bookmark_model.h
@@ -126,7 +126,8 @@ bool IsDoingExtensiveChanges() const { return extensive_changes_ > 0; } // Removes |node| from the model and deletes it. Removing a folder node - // recursively removes all nodes. Observers are notified immediately. + // recursively removes all nodes. Observers are notified immediately. |node| + // must not be a permanent node. void Remove(const BookmarkNode* node); // Removes all the non-permanent bookmark nodes that are editable by the user.
diff --git a/components/cdm/renderer/android_key_systems.cc b/components/cdm/renderer/android_key_systems.cc index ccfcca0..4065088b 100644 --- a/components/cdm/renderer/android_key_systems.cc +++ b/components/cdm/renderer/android_key_systems.cc
@@ -61,8 +61,8 @@ } EmeConfigRule GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_scheme) const override { - return encryption_scheme == media::EncryptionMode::kCenc + media::EncryptionScheme encryption_scheme) const override { + return encryption_scheme == media::EncryptionScheme::kCenc ? EmeConfigRule::SUPPORTED : EmeConfigRule::NOT_SUPPORTED; } @@ -140,10 +140,10 @@ if (codecs != media::EME_CODEC_NONE) { DVLOG(3) << __func__ << " Widevine supported."; - base::flat_set<media::EncryptionMode> encryption_schemes = { - media::EncryptionMode::kCenc}; + base::flat_set<media::EncryptionScheme> encryption_schemes = { + media::EncryptionScheme::kCenc}; if (response.is_cbcs_encryption_supported) { - encryption_schemes.insert(media::EncryptionMode::kCbcs); + encryption_schemes.insert(media::EncryptionScheme::kCbcs); } concrete_key_systems->emplace_back(new WidevineKeySystemProperties(
diff --git a/components/cdm/renderer/external_clear_key_key_system_properties.cc b/components/cdm/renderer/external_clear_key_key_system_properties.cc index 3a38719..0998dd5 100644 --- a/components/cdm/renderer/external_clear_key_key_system_properties.cc +++ b/components/cdm/renderer/external_clear_key_key_system_properties.cc
@@ -35,12 +35,12 @@ } media::EmeConfigRule ExternalClearKeyProperties::GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_scheme) const { + media::EncryptionScheme encryption_scheme) const { switch (encryption_scheme) { - case media::EncryptionMode::kCenc: - case media::EncryptionMode::kCbcs: + case media::EncryptionScheme::kCenc: + case media::EncryptionScheme::kCbcs: return media::EmeConfigRule::SUPPORTED; - case media::EncryptionMode::kUnencrypted: + case media::EncryptionScheme::kUnencrypted: break; } NOTREACHED();
diff --git a/components/cdm/renderer/external_clear_key_key_system_properties.h b/components/cdm/renderer/external_clear_key_key_system_properties.h index 6fe015f..4e6389c 100644 --- a/components/cdm/renderer/external_clear_key_key_system_properties.h +++ b/components/cdm/renderer/external_clear_key_key_system_properties.h
@@ -23,7 +23,7 @@ bool IsSupportedInitDataType( media::EmeInitDataType init_data_type) const override; media::EmeConfigRule GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_scheme) const override; + media::EncryptionScheme encryption_scheme) const override; media::SupportedCodecs GetSupportedCodecs() const override; media::EmeConfigRule GetRobustnessConfigRule( media::EmeMediaType media_type,
diff --git a/components/cdm/renderer/widevine_key_system_properties.cc b/components/cdm/renderer/widevine_key_system_properties.cc index f316475..553ac49 100644 --- a/components/cdm/renderer/widevine_key_system_properties.cc +++ b/components/cdm/renderer/widevine_key_system_properties.cc
@@ -44,9 +44,9 @@ WidevineKeySystemProperties::WidevineKeySystemProperties( media::SupportedCodecs codecs, - base::flat_set<media::EncryptionMode> encryption_schemes, + base::flat_set<media::EncryptionScheme> encryption_schemes, media::SupportedCodecs hw_secure_codecs, - base::flat_set<media::EncryptionMode> hw_secure_encryption_schemes, + base::flat_set<media::EncryptionScheme> hw_secure_encryption_schemes, Robustness max_audio_robustness, Robustness max_video_robustness, media::EmeSessionTypeSupport persistent_license_support, @@ -84,7 +84,7 @@ } EmeConfigRule WidevineKeySystemProperties::GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_scheme) const { + media::EncryptionScheme encryption_scheme) const { bool is_supported = encryption_schemes_.count(encryption_scheme); bool is_hw_secure_supported = hw_secure_encryption_schemes_.count(encryption_scheme);
diff --git a/components/cdm/renderer/widevine_key_system_properties.h b/components/cdm/renderer/widevine_key_system_properties.h index fa51638..cc29ee9 100644 --- a/components/cdm/renderer/widevine_key_system_properties.h +++ b/components/cdm/renderer/widevine_key_system_properties.h
@@ -30,9 +30,9 @@ WidevineKeySystemProperties( media::SupportedCodecs codecs, - base::flat_set<media::EncryptionMode> encryption_schemes, + base::flat_set<media::EncryptionScheme> encryption_schemes, media::SupportedCodecs hw_secure_codecs, - base::flat_set<media::EncryptionMode> hw_secure_encryption_schemes, + base::flat_set<media::EncryptionScheme> hw_secure_encryption_schemes, Robustness max_audio_robustness, Robustness max_video_robustness, media::EmeSessionTypeSupport persistent_license_support, @@ -45,7 +45,7 @@ bool IsSupportedInitDataType( media::EmeInitDataType init_data_type) const override; media::EmeConfigRule GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_scheme) const override; + media::EncryptionScheme encryption_scheme) const override; media::SupportedCodecs GetSupportedCodecs() const override; media::SupportedCodecs GetSupportedHwSecureCodecs() const override; media::EmeConfigRule GetRobustnessConfigRule( @@ -60,9 +60,9 @@ private: const media::SupportedCodecs codecs_; - const base::flat_set<media::EncryptionMode> encryption_schemes_; + const base::flat_set<media::EncryptionScheme> encryption_schemes_; const media::SupportedCodecs hw_secure_codecs_; - const base::flat_set<media::EncryptionMode> hw_secure_encryption_schemes_; + const base::flat_set<media::EncryptionScheme> hw_secure_encryption_schemes_; const Robustness max_audio_robustness_; const Robustness max_video_robustness_; const media::EmeSessionTypeSupport persistent_license_support_;
diff --git a/components/crash/OWNERS b/components/crash/OWNERS index dc5fda6..ea972c3 100644 --- a/components/crash/OWNERS +++ b/components/crash/OWNERS
@@ -1,8 +1,6 @@ -cpu@chromium.org jochen@chromium.org mark@chromium.org rsesek@chromium.org -scottmg@chromium.org thestig@chromium.org # For Android-specific changes:
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc index 3358aa8c..af66c13 100644 --- a/components/network_session_configurator/browser/network_session_configurator.cc +++ b/components/network_session_configurator/browser/network_session_configurator.cc
@@ -151,12 +151,15 @@ GetVariationParam(http2_trial_params, "http2_grease_frame_type") == "true") { const uint8_t type = 0x0b + 0x1f * base::RandGenerator(8); - const uint8_t flags = - base::RandGenerator(std::numeric_limits<uint8_t>::max() + 1); + + uint8_t flags; + base::RandBytes(&flags, /* output_length = */ sizeof(flags)); + const size_t length = base::RandGenerator(7); // RandBytesAsString() does not support zero length. const std::string payload = (length > 0) ? base::RandBytesAsString(length) : std::string(); + params->greased_http2_frame = base::Optional<net::SpdySessionPool::GreasedHttp2Frame>( {type, flags, payload});
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index 3ff4762..7450f24 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -281,9 +281,19 @@ OmniboxEventProto::PageClassification current_page_classification, DemotionMultipliers* demotions_by_type) { demotions_by_type->clear(); + + // Explicitly check whether the feature is enabled before calling + // |GetValueForRuleInContextByFeature| because it is possible for + // |GetValueForRuleInContextByFeature| to return an empty string even if the + // feature is enabled, and we don't want to fallback to + // |GetValueForRuleInContext| in this case. std::string demotion_rule = - OmniboxFieldTrial::internal::GetValueForRuleInContext( - kDemoteByTypeRule, current_page_classification); + base::FeatureList::IsEnabled(omnibox::kOmniboxDemoteByType) + ? OmniboxFieldTrial::internal::GetValueForRuleInContextByFeature( + omnibox::kOmniboxDemoteByType, kDemoteByTypeRule, + current_page_classification) + : OmniboxFieldTrial::internal::GetValueForRuleInContext( + kDemoteByTypeRule, current_page_classification); // If there is no demotion rule for this context, then use the default // value for that context. if (demotion_rule.empty()) {
diff --git a/components/omnibox/browser/on_device_head_provider.cc b/components/omnibox/browser/on_device_head_provider.cc index 628b6356..7079414 100644 --- a/components/omnibox/browser/on_device_head_provider.cc +++ b/components/omnibox/browser/on_device_head_provider.cc
@@ -148,9 +148,6 @@ if (minimal_changes) return; - // Load the new model first before fulfilling the request if it's available. - MaybeResetServingInstanceFromNewModel(); - matches_.clear(); if (!input.text().empty() && serving_) { done_ = false; @@ -199,18 +196,21 @@ void OnDeviceHeadProvider::OnModelUpdate( const std::string& new_model_filename) { if (new_model_filename != current_model_filename_ && - new_model_filename_.empty()) - new_model_filename_ = new_model_filename; + !new_model_filename.empty()) { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&OnDeviceHeadProvider::ResetServingInstanceFromNewModel, + weak_ptr_factory_.GetWeakPtr(), new_model_filename)); + } } -void OnDeviceHeadProvider::MaybeResetServingInstanceFromNewModel() { - if (new_model_filename_.empty()) +void OnDeviceHeadProvider::ResetServingInstanceFromNewModel( + const std::string& new_model_filename) { + if (new_model_filename.empty()) return; - - serving_ = - OnDeviceHeadServing::Create(new_model_filename_, provider_max_matches_); - current_model_filename_ = new_model_filename_; - new_model_filename_.clear(); + current_model_filename_ = new_model_filename; + serving_ = OnDeviceHeadServing::Create(current_model_filename_, + provider_max_matches_); } void OnDeviceHeadProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
diff --git a/components/omnibox/browser/on_device_head_provider.h b/components/omnibox/browser/on_device_head_provider.h index d0af01a..6202db53 100644 --- a/components/omnibox/browser/on_device_head_provider.h +++ b/components/omnibox/browser/on_device_head_provider.h
@@ -64,7 +64,7 @@ // Resets |serving_| if new model is available and cleans up the old model if // it exists. - void MaybeResetServingInstanceFromNewModel(); + void ResetServingInstanceFromNewModel(const std::string& new_model_filename); AutocompleteProviderClient* client_; AutocompleteProviderListener* listener_; @@ -73,8 +73,9 @@ // suggestions matching the Autocomplete input. std::unique_ptr<OnDeviceHeadServing> serving_; - // The task runner instance where asynchronous searches to the head model will - // be run. + // The task runner instance where asynchronous operations using |serving_| + // will be run. Note that SequencedTaskRunner guarantees that operations will + // be executed in sequence so we don't need to apply a lock to |serving_|. scoped_refptr<base::SequencedTaskRunner> task_runner_; // The request id used to trace current request to the on device head model. @@ -85,9 +86,6 @@ // The filename for the on device model currently being used. std::string current_model_filename_; - // The filename for the new model updated by Component Updater. - std::string new_model_filename_; - // Owns the subscription after adding the model update callback to the // listener such that the callback can be removed automatically from the // listener on provider's deconstruction.
diff --git a/components/omnibox/browser/on_device_head_provider_unittest.cc b/components/omnibox/browser/on_device_head_provider_unittest.cc index 41b8215..fce8888 100644 --- a/components/omnibox/browser/on_device_head_provider_unittest.cc +++ b/components/omnibox/browser/on_device_head_provider_unittest.cc
@@ -59,7 +59,6 @@ if (provider_) { provider_->serving_.reset(); provider_->current_model_filename_.clear(); - provider_->new_model_filename_.clear(); } }
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index 1cab7451..993eeb6 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -288,6 +288,12 @@ "OmniboxPreserveDefaultMatchAgainstAsyncUpdate", base::FEATURE_DISABLED_BY_DEFAULT}; +// Demotes the relevance scores when comparing suggestions based on the +// suggestion's |AutocompleteMatchType| and the user's |PageClassification|. +// This feature's main job is to contain the DemoteByType parameter. +const base::Feature kOmniboxDemoteByType{"OmniboxDemoteByType", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Feature to configure on-focus suggestions provided by ZeroSuggestProvider. // This feature's main job is to contain some field trial parameters such as: // - "ZeroSuggestVariant" configures the per-page-classification mode of
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index 659de92..831fb41 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -53,6 +53,7 @@ // TODO(tommycli): There are more flags above that belong in this category. extern const base::Feature kOmniboxPreserveDefaultMatchScore; extern const base::Feature kOmniboxPreserveDefaultMatchAgainstAsyncUpdate; +extern const base::Feature kOmniboxDemoteByType; // On-Focus Suggestions a.k.a. ZeroSuggest. extern const base::Feature kOnFocusSuggestions;
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn index 0d8e13c1..279844b 100644 --- a/components/performance_manager/BUILD.gn +++ b/components/performance_manager/BUILD.gn
@@ -4,6 +4,7 @@ static_library("performance_manager") { sources = [ + "frame_priority/boosting_vote_aggregator.cc", "frame_priority/frame_priority.cc", "frame_priority/max_vote_aggregator.cc", "frame_priority/override_vote_aggregator.cc", @@ -47,6 +48,7 @@ "performance_manager_tab_helper.h", "process_node_source.cc", "process_node_source.h", + "public/frame_priority/boosting_vote_aggregator.h", "public/frame_priority/frame_priority.h", "public/frame_priority/max_vote_aggregator.h", "public/frame_priority/override_vote_aggregator.h", @@ -87,6 +89,7 @@ testonly = true sources = [ + "frame_priority/boosting_vote_aggregator_unittest.cc", "frame_priority/frame_priority_unittest.cc", "frame_priority/max_vote_aggregator_unittest.cc", "frame_priority/override_vote_aggregator_unittest.cc",
diff --git a/components/performance_manager/frame_priority/boosting_vote_aggregator.cc b/components/performance_manager/frame_priority/boosting_vote_aggregator.cc new file mode 100644 index 0000000..bbe5caf --- /dev/null +++ b/components/performance_manager/frame_priority/boosting_vote_aggregator.cc
@@ -0,0 +1,758 @@ +// 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_PUBLIC_FRAME_PRIORITY_BOOSTING_VOTE_AGGREGATOR_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_FRAME_PRIORITY_BOOSTING_VOTE_AGGREGATOR_H_ + +#include "components/performance_manager/public/frame_priority/boosting_vote_aggregator.h" + +#include <algorithm> +#include <tuple> +#include <utility> + +#include "base/stl_util.h" +#include "components/performance_manager/public/graph/frame_node.h" + +// This voter allows expressing "priority boosts" which are used to resolve +// priority inversions. These priority inversions are a result of resource +// contention. For example, consider frames f0 and f1, where f0 holds a WebLock +// and f1 is waiting to acquire that WebLock. If the priority of f0 is below +// that of frame f1 then its priority needs to be boosted in order to prevent +// a priority inversion. +// +// We represent this resource contention relationship with a directed edge from +// f1 -> f0, which expresses the fact that f1 is waiting on a resource held by +// f0. We instrument APIs that provide shared access to resources (WebLocks, +// IndexedDB, etc) and they serve as factories of edges, expressing their "wait +// lists" to the BoostingVoteAggregator. This graph will in general be quite +// sparse and consist of directed acyclic components (one per shared resource), +// but in theory it may be fully connected and cyclic. (A cycle in the graph +// effectively indicates web content that has expressed a dead lock, so while +// possible it is unlikely.) +// +// Nodes in the graph represent frames, which themselves have baseline +// priorities that are calculated based on a variety of factors (visibility, +// type of content, ...). These priorities flow along edges if the next node has +// a lower priority, "boosting" the priority of the destination node in order to +// resolve priority inversions. Since the graph is finite and the flow is in one +// direction only this process is guaranteed to converge for any given graph and +// set of baseline priorities. We call this graph the "priority flow graph". +// +// We break this down into a separate graph problem per priority level. We +// define a virtual "source" node, and create directed edges from that source +// node to each node that has received an explicit vote. Finding the set of all +// nodes that are supported at that priority level then becomes one of +// reachability from a single source node, which is trivially O(|edges|) using +// a depth-first search. +// +// We wish to maintain this graph in the face of edge additions and removals +// (both direct priority votes and priority boosts are expressed as edges in +// this representation). To make this simpler we actually maintain a +// reachability spanning tree. That is, every reachable node has exactly one +// "active" (part of the spanning tree) incoming edge. The tree can be +// maintained as follows: +// +// Adding an edge: +// +// - Add the edge to the graph and mark it as inactive. +// - If the destination node is already active, we're done. +// - If the source node is inactive (and so is the destination node at this +// point), then there is no possible path to the node, thus we're done. +// - At this point the source node is active, and the destination is inactive. +// We mark the edge and the destination node as active, and recursively +// investigate outbound edges to see if other nodes are now reachable. Since +// edges are only ever marked active if they are from an active node to an +// inactive node, this can occur once per node, thus each active node has +// exactly one incoming edge, and the entire set of active edges and nodes +// forms a directed tree. +// +// Removing an edge: +// +// - If the edge is inactive, simply remove it and return. +// - If the edge is active, then recurse on the subtree hanging off the +// destination node, marking all of the associated edges and nodes as +// inactive, while simultaneously maintaining a set of the nodes that have +// been marked as inactive. +// - For each node that was just marked inactive, traverse inactive back-edges +// and find an active ancestor node if possible. Collect these active +// ancestors as part of a search front. +// - Launch a search from the search front, extending the tree of active nodes +// by traversing inactive edges and marking them and the destination node as +// active. +// - The 2-pass approach of first marking the subtree as inactive and *then* +// extending the tree is necessary. If these 2 steps were mingled, then when +// traversing the subtree and inspecting a node it would be possible to +// identify an inactive edge from an ancestor that is actually a descendant +// of the current node. The first pass serves to effectively split the tree +// into ancestors and descendants so that future edge activations can maintain +// the tree relationship rather than creating simple cycles. + +namespace performance_manager { +namespace frame_priority { + +namespace { + +// Converts a non-default priority level to a zero-based index. +constexpr size_t PriorityToIndex(base::TaskPriority priority) { + DCHECK_NE(base::TaskPriority::LOWEST, priority); + return static_cast<size_t>(static_cast<int>(priority) - + static_cast<int>(base::TaskPriority::LOWEST)) - + 1; +} + +// Converts a priority level to a bit in an |active_layers| variable. +constexpr uint32_t PriorityToBit(base::TaskPriority priority) { + return 1 << PriorityToIndex(priority); +} + +static constexpr uint32_t kFirstLayerBit = 1; +static constexpr uint32_t kLastLayerBit = + PriorityToBit(base::TaskPriority::HIGHEST); +static_assert(kFirstLayerBit < kLastLayerBit, "expect more than 1 layer"); + +static const FrameNode* kMaxFrameNode = + reinterpret_cast<const FrameNode*>(static_cast<uintptr_t>(0) - 1); + +} // namespace + +BoostingVote::BoostingVote(BoostingVoteAggregator* aggregator, + const FrameNode* input_frame, + const FrameNode* output_frame, + const char* reason) + : aggregator_(aggregator), + input_frame_(input_frame), + output_frame_(output_frame), + reason_(reason) { + aggregator_->SubmitBoostingVote(this); +} + +BoostingVote::BoostingVote(BoostingVote&& rhs) { + *this = std::move(rhs); +} + +BoostingVote& BoostingVote::operator=(BoostingVote&& rhs) { + // Reset the current BoostingVote first, as it is about to be overwritten. + Reset(); + + // Take the aggregator. + aggregator_ = std::exchange(rhs.aggregator_, nullptr); + input_frame_ = std::exchange(rhs.input_frame_, nullptr); + output_frame_ = std::exchange(rhs.output_frame_, nullptr); + reason_ = std::exchange(rhs.reason_, nullptr); + + return *this; +} + +BoostingVote::~BoostingVote() { + Reset(); +} + +void BoostingVote::Reset() { + if (aggregator_) { + aggregator_->CancelBoostingVote(this); + aggregator_ = nullptr; + } +} + +bool BoostingVoteAggregator::ActiveLayers::IsActive(uint32_t layer_bit) const { + return active_layers_ & layer_bit; +} + +void BoostingVoteAggregator::ActiveLayers::SetActive(uint32_t layer_bit) { + active_layers_ |= layer_bit; +} + +void BoostingVoteAggregator::ActiveLayers::SetInactive(uint32_t layer_bit) { + active_layers_ &= ~layer_bit; +} + +base::TaskPriority BoostingVoteAggregator::NodeData::GetEffectivePriorityLevel() + const { + if (IsActive(PriorityToBit(base::TaskPriority::HIGHEST))) + return base::TaskPriority::HIGHEST; + if (IsActive(PriorityToBit(base::TaskPriority::USER_VISIBLE))) + return base::TaskPriority::USER_VISIBLE; + return base::TaskPriority::LOWEST; +} + +void BoostingVoteAggregator::NodeData::IncrementEdgeCount() { + ++edge_count_; +} + +void BoostingVoteAggregator::NodeData::DecrementEdgeCount() { + DCHECK_LT(0u, edge_count_); + --edge_count_; +} + +VoteReceipt BoostingVoteAggregator::NodeData::SetIncomingVote( + VoteConsumer* consumer, + VoterId voter_id, + const Vote& vote) { + incoming_ = AcceptedVote(consumer, voter_id, vote); + return incoming_.IssueReceipt(); +} + +BoostingVoteAggregator::EdgeData::EdgeData() = default; + +BoostingVoteAggregator::EdgeData::EdgeData(EdgeData&&) = default; + +BoostingVoteAggregator::EdgeData& BoostingVoteAggregator::EdgeData::operator=( + EdgeData&&) = default; + +BoostingVoteAggregator::EdgeData::~EdgeData() = default; + +void BoostingVoteAggregator::EdgeData::AddReason(const char* reason) { + reasons_.push_back(reason); +} + +bool BoostingVoteAggregator::EdgeData::RemoveReason(const char* reason) { + // Special case: there's only one reason. + if (reasons_.size() == 1) { + DCHECK_EQ(reason, reasons_[0]); + reasons_.clear(); + return true; + } + + bool active_reason_changed = false; + + // Look for the reason to be erased anywhere but in the first position. This + // is so that we can avoid causing an active reason change when possible. + auto it = std::find(reasons_.begin() + 1, reasons_.end(), reason); + + // If the reason being deleted is the sole instance of the active reason (we + // didn't find another instance in our search above), then there's no way to + // avoid propagating a reason change. + if (it == reasons_.end()) { + DCHECK_EQ(reason, reasons_[0]); + it = reasons_.begin(); + active_reason_changed = true; + } + + // Replace the element being erased with the last one in the array. If it was + // already the last one in the array this is a nop. + *it = reasons_.back(); + reasons_.pop_back(); + + return active_reason_changed; +} + +const char* BoostingVoteAggregator::EdgeData::GetActiveReason() const { + DCHECK(!reasons_.empty()); + return reasons_[0]; +} + +BoostingVoteAggregator::BoostingVoteAggregator() : factory_(this) {} + +BoostingVoteAggregator::~BoostingVoteAggregator() { + DCHECK(forward_edges_.empty()); + DCHECK(reverse_edges_.empty()); +} + +VotingChannel BoostingVoteAggregator::GetVotingChannel() { + DCHECK(nodes_.empty()); + DCHECK_EQ(kInvalidVoterId, input_voter_id_); + DCHECK_GT(1u, factory_.voting_channels_issued()); + auto channel = factory_.BuildVotingChannel(); + input_voter_id_ = channel.voter_id(); + return channel; +} + +void BoostingVoteAggregator::SetUpstreamVotingChannel(VotingChannel&& channel) { + DCHECK(channel.IsValid()); + DCHECK(nodes_.empty()); + DCHECK(!channel_.IsValid()); + channel_ = std::move(channel); +} + +bool BoostingVoteAggregator::IsSetup() const { + return input_voter_id_ != kInvalidVoterId && channel_.IsValid(); +} + +void BoostingVoteAggregator::SubmitBoostingVote( + const BoostingVote* boosting_vote) { + bool is_new_edge = false; + + // Ensure an entry exists in the edge map. + EdgeData* edge_data = nullptr; + ForwardEdge fwd_edge(boosting_vote); + auto it = forward_edges_.lower_bound(fwd_edge); + if (it == forward_edges_.end() || it->first != fwd_edge) { + is_new_edge = true; + edge_data = + &forward_edges_.insert(it, std::make_pair(fwd_edge, EdgeData())) + ->second; + reverse_edges_.insert( + std::make_pair(ReverseEdge(boosting_vote), edge_data)); + } else { + edge_data = &it->second; + } + + // Update the list of reasons. + edge_data->AddReason(boosting_vote->reason()); + + // If this is not a new edge, then the priority flow graph result doesn't + // change. + if (!is_new_edge) + return; + + auto src_node_data_it = FindOrCreateNodeData(boosting_vote->input_frame()); + auto dst_node_data_it = FindOrCreateNodeData(boosting_vote->output_frame()); + src_node_data_it->second.IncrementEdgeCount(); + dst_node_data_it->second.IncrementEdgeCount(); + + // Update the reachability spanning tree for each priority layer. + NodeDataPtrSet changes; + for (uint32_t layer_bit = kFirstLayerBit; layer_bit <= kLastLayerBit; + layer_bit <<= 1) { + // If the source node is inactive, then there's no way this edge can be part + // of the spanning tree. + if (!src_node_data_it->second.IsActive(layer_bit)) + continue; + + // If the destination node is active, then there's no way this edge can be + // part of the spanning tree. + if (dst_node_data_it->second.IsActive(layer_bit)) + continue; + + // At this point we've added an edge from an active source node to an + // inactive destination node. The spanning tree needs to be extended. + NodeDataPtrSet active_search_front; + active_search_front.insert(&(*dst_node_data_it)); + changes.insert(&(*dst_node_data_it)); + edge_data->SetActive(layer_bit); + dst_node_data_it->second.SetActive(layer_bit); + MarkNodesActiveFromSearchFront(layer_bit, &active_search_front, &changes); + } + + UpstreamChanges(changes); +} + +void BoostingVoteAggregator::CancelBoostingVote( + const BoostingVote* boosting_vote) { + // Find the edge and remove the reason from it; it's possible that this reason + // was the 'active' reason associated with the edge, in which case upstream + // votes may need to be changed. + auto fwd_edge_it = forward_edges_.find(ForwardEdge(boosting_vote)); + bool active_reason_changed = + fwd_edge_it->second.RemoveReason(boosting_vote->reason()); + + auto src_node_data_it = FindNodeData(boosting_vote->input_frame()); + auto dst_node_data_it = FindNodeData(boosting_vote->output_frame()); + + // If the edge's active reason changed, and the edge is active in any layer, + // then the destination node might need to have its vote updated. + NodeDataPtrSet changes; + if (active_reason_changed && fwd_edge_it->second.IsActiveInAnyLayer()) + changes.insert(&(*dst_node_data_it)); + + // If the reasons are now empty, then this is the last occurrence of the + // edge. Remove it entirely. + bool edge_removed = (fwd_edge_it->second.GetReasonCount() == 0); + if (edge_removed) { + // Remember the active layer information associated with this edge, as its + // needed to decide if the reachability spanning tree needs to be updated. + ActiveLayers old_edge_layers = fwd_edge_it->second; + + // Delete the edge from both the forward and reverse map, updating edge + // counts. + forward_edges_.erase(fwd_edge_it); + auto rev_edge_it = reverse_edges_.find(ReverseEdge(boosting_vote)); + reverse_edges_.erase(rev_edge_it); + src_node_data_it->second.DecrementEdgeCount(); + dst_node_data_it->second.DecrementEdgeCount(); + + // Repair the reachability spanning tree for each layer. + for (uint32_t layer_bit = kFirstLayerBit; layer_bit <= kLastLayerBit; + layer_bit <<= 1) { + // If the edge was inactive in this layer, then the layer won't change. + if (!old_edge_layers.IsActive(layer_bit)) + continue; + + // The edge was active in this layer, so the reachability spanning tree + // needs repairing. + ReprocessSubtree(layer_bit, &(*dst_node_data_it), &changes); + } + } + + UpstreamChanges(changes); + + // Since an edge was removed the nodes might also be eligible for removal. + // This is done after changes are upstreamed so that votes have a chance to + // be canceled first. + if (edge_removed) { + MaybeRemoveNode(src_node_data_it); + MaybeRemoveNode(dst_node_data_it); + } +} + +VoteReceipt BoostingVoteAggregator::SubmitVote(VoterId voter_id, + const Vote& vote) { + DCHECK(IsSetup()); + DCHECK_EQ(input_voter_id_, voter_id); + DCHECK(vote.IsValid()); + + // Store the vote. + auto node_data_it = FindOrCreateNodeData(vote.frame_node()); + VoteReceipt receipt = + node_data_it->second.SetIncomingVote(this, voter_id, vote); + + NodeDataPtrSet changes; + + // Update the reachability tree for the new vote if necessary. + if (vote.priority() != base::TaskPriority::LOWEST) { + uint32_t layer_bit = PriorityToBit(vote.priority()); + OnVoteAdded(layer_bit, &(*node_data_it), &changes); + } + + UpstreamChanges(changes); + + return receipt; +} + +VoteReceipt BoostingVoteAggregator::ChangeVote(VoteReceipt receipt, + AcceptedVote* old_vote, + const Vote& new_vote) { + // Remember the old and new priorities before committing any changes. + base::TaskPriority old_priority = old_vote->vote().priority(); + base::TaskPriority new_priority = new_vote.priority(); + + // Update the vote in place. + auto node_data_it = GetNodeDataByVote(old_vote); + auto* node_data = &(*node_data_it); + old_vote->UpdateVote(new_vote); + + NodeDataPtrSet changes; + changes.insert(node_data); // This node is changing regardless. + + // Update the reachability tree for the old vote if necessary. + if (old_priority != base::TaskPriority::LOWEST) { + uint32_t layer_bit = PriorityToBit(old_priority); + OnVoteRemoved(layer_bit, node_data, &changes); + } + + // Update the reachability tree for the new vote if necessary. + if (new_priority != base::TaskPriority::LOWEST) { + uint32_t layer_bit = PriorityToBit(new_priority); + OnVoteAdded(layer_bit, node_data, &changes); + } + + UpstreamChanges(changes); + + // Return the original receipt, as its still valid. + return receipt; +} + +void BoostingVoteAggregator::VoteInvalidated(AcceptedVote* vote) { + auto node_data_it = GetNodeDataByVote(vote); + base::TaskPriority old_priority = vote->vote().priority(); + + NodeDataPtrSet changes; + + // Update the reachability tree for the old vote if necessary. + if (old_priority != base::TaskPriority::LOWEST) { + uint32_t layer_bit = PriorityToBit(old_priority); + OnVoteRemoved(layer_bit, &(*node_data_it), &changes); + } + + UpstreamChanges(changes); + + // The node may be eligible for removal after its incoming vote has been + // canceled. + MaybeRemoveNode(node_data_it); + + return; +} + +template <typename Function> +void BoostingVoteAggregator::ForEachIncomingEdge(const FrameNode* node, + Function&& function) { + auto edges_begin = reverse_edges_.lower_bound(ReverseEdge(nullptr, node)); + auto edges_end = reverse_edges_.upper_bound(ReverseEdge(kMaxFrameNode, node)); + for (auto edge_it = edges_begin; edge_it != edges_end; ++edge_it) { + if (!function(edge_it)) + return; + } +} + +template <typename Function> +void BoostingVoteAggregator::ForEachOutgoingEdge(const FrameNode* node, + Function&& function) { + auto edges_begin = forward_edges_.lower_bound(ForwardEdge(node, nullptr)); + auto edges_end = forward_edges_.upper_bound(ForwardEdge(node, kMaxFrameNode)); + for (auto edge_it = edges_begin; edge_it != edges_end; ++edge_it) { + if (!function(edge_it)) + return; + } +} + +BoostingVoteAggregator::NodeDataMap::iterator +BoostingVoteAggregator::GetNodeDataByVote(AcceptedVote* vote) { + // The vote being retrieved should have us as its consumer, and have been + // emitted by our known voter. + DCHECK(vote); + DCHECK_EQ(this, vote->consumer()); + DCHECK(vote->voter_id() == input_voter_id_); + DCHECK(IsSetup()); + + auto it = nodes_.find(vote->vote().frame_node()); + DCHECK(it != nodes_.end()); + DCHECK_EQ(vote, &it->second.incoming()); + return it; +} + +BoostingVoteAggregator::NodeDataMap::iterator +BoostingVoteAggregator::FindOrCreateNodeData(const FrameNode* frame_node) { + auto it = nodes_.lower_bound(frame_node); + if (it->first == frame_node) + return it; + it = nodes_.insert(it, std::make_pair(frame_node, NodeData())); + return it; +} + +BoostingVoteAggregator::NodeDataMap::iterator +BoostingVoteAggregator::FindNodeData(const FrameNode* frame_node) { + auto it = nodes_.lower_bound(frame_node); + DCHECK(it != nodes_.end()); + return it; +} + +const char* BoostingVoteAggregator::GetVoteReason( + const NodeDataMap::value_type* node) { + const NodeData& node_data = node->second; + auto priority = node_data.GetEffectivePriorityLevel(); + uint32_t layer_bit = PriorityToBit(priority); + + // No reason is needed for the lowest priority. + if (priority == base::TaskPriority::LOWEST) + return nullptr; + + // If a vote has been expressed for this node at the given priority level then + // preferentially use that reason. + if (node_data.HasIncomingVote()) { + const Vote& incoming = node_data.incoming().vote(); + if (priority == incoming.priority()) { + // This node will not have an active incoming edge in this case. + DCHECK(GetActiveInboundEdge(layer_bit, node) == reverse_edges_.end()); + return incoming.reason(); + } + } + + // Otherwise, this node has inherited its priority. Find the active incoming + // edge and use the active reason for that edge. + auto edge_it = GetActiveInboundEdge(layer_bit, node); + DCHECK(edge_it != reverse_edges_.end()); + DCHECK(edge_it->second->GetReasonCount()); + return edge_it->second->GetActiveReason(); +} + +void BoostingVoteAggregator::UpstreamVoteIfNeeded( + NodeDataMap::value_type* node) { + const FrameNode* frame_node = node->first; + NodeData* node_data = &node->second; + auto priority = node_data->GetEffectivePriorityLevel(); + + // We specifically don't upstream lowest priority votes, as that is the + // default priority level of every frame in the absence of any specific higher + // votes. + if (priority == base::TaskPriority::LOWEST) { + if (node_data->HasOutgoingVote()) + node_data->CancelOutgoingVote(); + return; + } + + // Get the reason for this vote. + const char* reason = GetVoteReason(node); + + // If the node already has a vote, then change it. This is a nop if the vote + // details are identical. + if (node_data->HasOutgoingVote()) { + node_data->ChangeOutgoingVote(priority, reason); + return; + } + + // Create an outgoing vote. + node_data->SetOutgoingVoteReceipt( + channel_.SubmitVote(Vote(frame_node, priority, reason))); +} + +void BoostingVoteAggregator::UpstreamChanges(const NodeDataPtrSet& changes) { + for (auto* node : changes) + UpstreamVoteIfNeeded(node); +} + +void BoostingVoteAggregator::MaybeRemoveNode( + NodeDataMap::iterator node_data_it) { + const NodeData& node = node_data_it->second; + if (!node.HasEdges() && !node.HasIncomingVote()) + nodes_.erase(node_data_it); +} + +void BoostingVoteAggregator::MarkSubtreeInactive(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* deactivated) { + std::deque<NodeDataMap::value_type*> to_visit; + to_visit.push_back(node); + while (!to_visit.empty()) { + auto* current_node = to_visit.front(); + to_visit.pop_front(); + DCHECK(current_node->second.IsActive(layer_bit)); + current_node->second.SetInactive(layer_bit); + deactivated->insert(current_node); + + ForEachOutgoingEdge( + current_node->first, [&](ForwardEdges::iterator edge_it) { + // Skip over inactive edges. + if (!edge_it->second.IsActive(layer_bit)) + return true; + + // Mark the edge inactive. + edge_it->second.SetInactive(layer_bit); + + // Schedule the node to be visited. + auto dst_node_data_it = FindNodeData(edge_it->first.dst()); + to_visit.push_back(&(*dst_node_data_it)); + + return true; + }); + } +} + +BoostingVoteAggregator::ReverseEdges::iterator +BoostingVoteAggregator::GetActiveInboundEdge( + uint32_t layer_bit, + const NodeDataMap::value_type* node) { + ReverseEdges::iterator active_edge = reverse_edges_.end(); + ForEachIncomingEdge(node->first, [&](ReverseEdges::iterator edge_it) -> bool { + if (!edge_it->second->IsActive(layer_bit)) + return true; + + active_edge = edge_it; + return false; + }); + + return active_edge; +} + +BoostingVoteAggregator::NodeDataMap::value_type* +BoostingVoteAggregator::GetNearestActiveAncestor( + uint32_t layer_bit, + const NodeDataMap::value_type* deactivated_node) { + DCHECK(!deactivated_node->second.IsActive(layer_bit)); + + NodeDataMap::value_type* active_ancestor = nullptr; + ForEachIncomingEdge(deactivated_node->first, + [&](ReverseEdges::iterator edge_it) -> bool { + // None of the edges should be active, by definition. + DCHECK(!edge_it->second->IsActive(layer_bit)); + const FrameNode* src_node = edge_it->first.src(); + auto src_node_it = FindNodeData(src_node); + + if (!src_node_it->second.IsActive(layer_bit)) + return true; + + // Return the first active immediate ancestor we + // encounter. + active_ancestor = &(*src_node_it); + return false; + }); + + return active_ancestor; +} + +void BoostingVoteAggregator::GetNearestActiveAncestors( + uint32_t layer_bit, + const NodeDataPtrSet& deactivated, + NodeDataPtrSet* active_ancestors) { + for (const auto* node : deactivated) { + auto* ancestor = GetNearestActiveAncestor(layer_bit, node); + if (ancestor) + active_ancestors->insert(ancestor); + } +} + +void BoostingVoteAggregator::MarkNodesActiveFromSearchFront( + uint32_t layer_bit, + NodeDataPtrSet* active_search_front, + NodeDataPtrSet* activated) { + while (!active_search_front->empty()) { + auto* current_node = *active_search_front->begin(); + active_search_front->erase(active_search_front->begin()); + DCHECK(current_node->second.IsActive(layer_bit)); + + ForEachOutgoingEdge(current_node->first, + [&](ForwardEdges::iterator edge_it) -> bool { + // Ignore active edges. + if (edge_it->second.IsActive(layer_bit)) + return true; + + // Ignore active destination nodes. + const FrameNode* dst_node = edge_it->first.dst(); + auto dst_node_it = FindNodeData(dst_node); + if (dst_node_it->second.IsActive(layer_bit)) + return true; + + // Mark the edge and the node as active, and add the + // node both to the search front and to the set of + // nodes that became active as a part of this search. + edge_it->second.SetActive(layer_bit); + dst_node_it->second.SetActive(layer_bit); + active_search_front->insert(&(*dst_node_it)); + activated->insert(&(*dst_node_it)); + return true; + }); + } +} + +void BoostingVoteAggregator::ReprocessSubtree(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* changes) { + MarkSubtreeInactive(layer_bit, node, changes); + + NodeDataPtrSet active_ancestors; + GetNearestActiveAncestors(layer_bit, *changes, &active_ancestors); + + MarkNodesActiveFromSearchFront(layer_bit, &active_ancestors, changes); +} + +void BoostingVoteAggregator::OnVoteAdded(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* changes) { + changes->insert(node); + + // If the node is already active then it must be active due to another + // inbound edge. In this case the reachability spanning tree doesn't need + // updating, but we do deactivate the incoming edge so as to always favor the + // explicit vote edge (and its reason). This is guaranteed not to introduce + // cycles as there is no inbound edge to the imaginary "root" node from which + // all votes flow (ie, we're simply rehoming a subtree to hang directly off + // the root). + if (node->second.IsActive(layer_bit)) { + auto edge_it = GetActiveInboundEdge(layer_bit, node); + edge_it->second->SetInactive(layer_bit); + return; + } + + // Otherwise this node is now supported by a direct vote when it wasn't + // previously supported by anything. Extend the reachability spanning tree. + NodeDataPtrSet active_search_front; + active_search_front.insert(node); + node->second.SetActive(layer_bit); + MarkNodesActiveFromSearchFront(layer_bit, &active_search_front, changes); +} + +void BoostingVoteAggregator::OnVoteRemoved(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* changes) { + // The node should *not* have an active inbound edge, as we always prefer a + // direct vote over an inferred priority boost. + DCHECK(GetActiveInboundEdge(layer_bit, node) == reverse_edges_.end()); + + // Reprocess the subtree hanging off this node. + ReprocessSubtree(layer_bit, node, changes); +} + +} // namespace frame_priority +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_FRAME_PRIORITY_OVERRIDE_VOTE_AGGREGATOR_H_
diff --git a/components/performance_manager/frame_priority/boosting_vote_aggregator_unittest.cc b/components/performance_manager/frame_priority/boosting_vote_aggregator_unittest.cc new file mode 100644 index 0000000..248af97 --- /dev/null +++ b/components/performance_manager/frame_priority/boosting_vote_aggregator_unittest.cc
@@ -0,0 +1,603 @@ +// 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/performance_manager/public/frame_priority/boosting_vote_aggregator.h" + +#include "components/performance_manager/test_support/frame_priority.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager { +namespace frame_priority { + +namespace { + +// Some dummy frames. +const FrameNode* kFrame0 = reinterpret_cast<const FrameNode*>(0xF5A33000); +const FrameNode* kFrame1 = reinterpret_cast<const FrameNode*>(0xF5A33001); +const FrameNode* kFrame2 = reinterpret_cast<const FrameNode*>(0xF5A33002); +const FrameNode* kFrame3 = reinterpret_cast<const FrameNode*>(0xF5A33003); +const FrameNode* kFrame4 = reinterpret_cast<const FrameNode*>(0xF5A33004); + +static constexpr base::TaskPriority kPriority0 = base::TaskPriority::LOWEST; +static constexpr base::TaskPriority kPriority1 = + base::TaskPriority::USER_VISIBLE; +static constexpr base::TaskPriority kPriority2 = base::TaskPriority::HIGHEST; + +static_assert(kPriority0 < kPriority1 && kPriority1 < kPriority2, + "priorities must be well ordered"); + +static const char kReason0[] = "a reason"; +static const char kReason1[] = "another reason"; +static const char kReason2[] = "yet another reason"; +static const char kReasonBoost[] = "boosted!"; + +class TestBoostingVoteAggregator : public BoostingVoteAggregator { + public: + using BoostingVoteAggregator::forward_edges_; + using BoostingVoteAggregator::NodeData; + using BoostingVoteAggregator::nodes_; + using BoostingVoteAggregator::reverse_edges_; +}; + +using NodeData = TestBoostingVoteAggregator::NodeData; + +class BoostingVoteAggregatorTest : public testing::Test { + public: + void SetUp() override { + // Set up the chain such that |voter_| provides votes to |agg_|, which + // upstreams them to |consumer_|. + auto channel = consumer_.voting_channel_factory_.BuildVotingChannel(); + voter_id_ = channel.voter_id(); + agg_.SetUpstreamVotingChannel(std::move(channel)); + voter_.SetVotingChannel(agg_.GetVotingChannel()); + EXPECT_TRUE(agg_.nodes_.empty()); + EXPECT_TRUE(agg_.forward_edges_.empty()); + EXPECT_TRUE(agg_.reverse_edges_.empty()); + } + + void ExpectEdges(size_t count) { + EXPECT_EQ(count, agg_.forward_edges_.size()); + EXPECT_EQ(count, agg_.reverse_edges_.size()); + } + + void ExpectIsActive(const NodeData& node_data, + bool mid_priority, + bool high_priority) { + EXPECT_EQ(mid_priority, node_data.IsActive(1)); + EXPECT_EQ(high_priority, node_data.IsActive(2)); + } + + // The id of |agg_| as seen by its upstream |consumer_|. + VoterId voter_id_ = 0; + test::DummyVoteConsumer consumer_; + TestBoostingVoteAggregator agg_; + test::DummyVoter voter_; +}; + +} // namespace + +TEST_F(BoostingVoteAggregatorTest, VotesUpstreamingWorks) { + // Submit a default vote to the boosting aggregator, and expect it not to be + // upstreamed. + voter_.EmitVote(kFrame0, kPriority0, kReason0); + EXPECT_EQ(1u, agg_.nodes_.size()); + EXPECT_TRUE(voter_.receipts_[0].HasVote()); + ExpectEdges(0); + EXPECT_TRUE(consumer_.votes_.empty()); + + // Submit a non-default vote to the boosting aggregator, and expect it to be + // upstreamed. + voter_.EmitVote(kFrame1, kPriority1, kReason1); + EXPECT_EQ(2u, agg_.nodes_.size()); + EXPECT_TRUE(voter_.receipts_[0].HasVote()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); + ExpectEdges(0); + EXPECT_EQ(1u, consumer_.votes_.size()); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReason1); + + // Make vote 0 non-default and expect it to be upstreamed. + voter_.receipts_[0].ChangeVote(kPriority2, kReason2); + EXPECT_EQ(2u, agg_.nodes_.size()); + EXPECT_TRUE(voter_.receipts_[0].HasVote()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); + ExpectEdges(0); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReason1); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority2, kReason2); + + // Make vote 1 default and expect the upstream vote to be canceled. + voter_.receipts_[1].ChangeVote(kPriority0, kReason0); + EXPECT_EQ(2u, agg_.nodes_.size()); + EXPECT_TRUE(voter_.receipts_[0].HasVote()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); + ExpectEdges(0); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectInvalidVote(0); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority2, kReason2); + + // Change the reason but not the priority of vote 0 and expect the upstream + // vote to change as well. + voter_.receipts_[0].ChangeVote(kPriority2, kReason0); + EXPECT_EQ(2u, agg_.nodes_.size()); + EXPECT_TRUE(voter_.receipts_[0].HasVote()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); + ExpectEdges(0); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectInvalidVote(0); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority2, kReason0); + + // Cancel vote 0 and expect it to be canceled upstream. + voter_.receipts_[0].Reset(); + EXPECT_EQ(1u, agg_.nodes_.size()); + EXPECT_FALSE(voter_.receipts_[0].HasVote()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); + ExpectEdges(0); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectInvalidVote(0); + consumer_.ExpectInvalidVote(1); + + // Cancel vote 1 and expect no change to the upstream votes. + voter_.receipts_[1].Reset(); + EXPECT_EQ(0u, agg_.nodes_.size()); + EXPECT_FALSE(voter_.receipts_[0].HasVote()); + EXPECT_FALSE(voter_.receipts_[1].HasVote()); + ExpectEdges(0); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectInvalidVote(0); + consumer_.ExpectInvalidVote(1); +} + +TEST_F(BoostingVoteAggregatorTest, BoostingWorks) { + // Add a boosting vote, with no actual incoming votes. This should produce + // the two nodes associated with the edge but not upstream any votes. + BoostingVote boost01a(&agg_, kFrame0, kFrame1, kReasonBoost); + const auto& data0 = agg_.nodes_.find(kFrame0)->second; + const auto& data1 = agg_.nodes_.find(kFrame1)->second; + EXPECT_TRUE(voter_.receipts_.empty()); + EXPECT_EQ(2u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_TRUE(consumer_.votes_.empty()); + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + ExpectIsActive(data0, false, false); + ExpectIsActive(data1, false, false); + + // Create a second boosting vote. This duplicates the edge. + BoostingVote boost01b(&agg_, kFrame0, kFrame1, kReasonBoost); + EXPECT_TRUE(voter_.receipts_.empty()); + EXPECT_EQ(2u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_TRUE(consumer_.votes_.empty()); + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + ExpectIsActive(data0, false, false); + ExpectIsActive(data1, false, false); + + // Create a mid priority vote for frame 1. This should cause a single vote + // to be emitted for that frame. + voter_.EmitVote(kFrame1, kPriority1, kReason1); + EXPECT_EQ(1u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[0].HasVote()); // kFrame1. + EXPECT_EQ(2u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_EQ(1u, consumer_.votes_.size()); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReason1); + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + ExpectIsActive(data0, false, false); + ExpectIsActive(data1, true, false); + + // Create a mid priority vote for frame 0. This should cause another vote to + // be emitted. + voter_.EmitVote(kFrame0, kPriority1, kReason1); + EXPECT_EQ(2u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_TRUE(voter_.receipts_[0].HasVote()); // kFrame1. + EXPECT_EQ(2u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReason1); + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data1, true, false); + + // Cancel the priority 1 vote for frame 1. The boosting should maintain the + // output priority for that node. + voter_.receipts_[0].Reset(); // kFrame1. + EXPECT_EQ(2u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_EQ(2u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReasonBoost); + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data1, true, false); + + // Create a default vote for a third frame. Other than creating the node data + // and the vote this shouldn't do anything. + voter_.EmitVote(kFrame2, kPriority0, kReason0); + const auto& data2 = agg_.nodes_.find(kFrame2)->second; + EXPECT_EQ(3u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_TRUE(voter_.receipts_[2].HasVote()); // kFrame2. + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReasonBoost); + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + EXPECT_EQ(0u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data1, true, false); + ExpectIsActive(data2, false, false); + + // Create a boosting vote from frame 2 to frame 0. This should create an edge. + BoostingVote boost20(&agg_, kFrame2, kFrame0, kReasonBoost); + EXPECT_EQ(3u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_TRUE(voter_.receipts_[2].HasVote()); // kFrame2. + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectEdges(2); + EXPECT_EQ(2u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReasonBoost); + EXPECT_EQ(2u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data1, true, false); + ExpectIsActive(data2, false, false); + + // Emit a highest priority vote for frame 2. This should boost frames 0 and + // 1 as well. + voter_.receipts_[2].ChangeVote(kPriority2, kReason2); // kFrame2. + EXPECT_EQ(3u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_TRUE(voter_.receipts_[2].HasVote()); // kFrame2. + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectEdges(2); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority2, kReasonBoost); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority2, kReasonBoost); + consumer_.ExpectValidVote(2, voter_id_, kFrame2, kPriority2, kReason2); + EXPECT_EQ(2u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, true); + ExpectIsActive(data1, true, true); + ExpectIsActive(data2, false, true); + + // Emit a highest priority vote for frame 1. This should change the vote + // reason. + voter_.EmitVote(kFrame1, kPriority2, kReason2); + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_TRUE(voter_.receipts_[3].HasVote()); // kFrame1. + EXPECT_TRUE(voter_.receipts_[2].HasVote()); // kFrame2. + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectEdges(2); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority2, + kReasonBoost); // kFrame0. + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority2, + kReason2); // kFrame1. + consumer_.ExpectValidVote(2, voter_id_, kFrame2, kPriority2, + kReason2); // kFrame2. + EXPECT_EQ(2u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, true); + ExpectIsActive(data1, true, true); + ExpectIsActive(data2, false, true); + + // Kill the vote for frame 2. This should kill the upstream vote for frame 2 + // entirely, reduce the priority of frame 0, and keep frame 1 the same. + voter_.receipts_[2].Reset(); // kFrame2. + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_TRUE(voter_.receipts_[3].HasVote()); // kFrame1. + EXPECT_FALSE(voter_.receipts_[2].HasVote()); // Old kFrame2. + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectEdges(2); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority2, kReason2); + consumer_.ExpectInvalidVote(2); // Old kFrame2. + EXPECT_EQ(2u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data1, true, true); + ExpectIsActive(data2, false, false); + + // Kill the direct vote for frame 1 so it goes back to being boosted by + // frame 0. + voter_.receipts_[3].Reset(); + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[3].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[2].HasVote()); // Old kFrame2. + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectEdges(2); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReasonBoost); + consumer_.ExpectInvalidVote(2); // Old kFrame2. + EXPECT_EQ(2u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data1, true, false); + ExpectIsActive(data2, false, false); + + // Kill the first boosting vote from 0 to 1. This should do nothing but change + // edge the multiplicity of the edge. + boost01a.Reset(); + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[3].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[2].HasVote()); // Old kFrame2. + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectEdges(2); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectValidVote(0, voter_id_, kFrame1, kPriority1, kReasonBoost); + consumer_.ExpectInvalidVote(2); // Old kFrame2. + EXPECT_EQ(2u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data1.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data1, true, false); + ExpectIsActive(data2, false, false); + + // Kill the second boosting vote from 0 to 1. This should change edge counts, + // and remove both the vote and the node data. The variable |data1| is now + // invalid. + boost01b.Reset(); + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[3].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[2].HasVote()); // Old kFrame2. + EXPECT_EQ(2u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectInvalidVote(0); // Old kFrame1. + consumer_.ExpectInvalidVote(2); // Old kFrame2. + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data2, false, false); + + // Move the boosting vote. The move should not cause any outwardly visible + // changes. + BoostingVote boost20b(std::move(boost20)); + EXPECT_EQ(&agg_, boost20b.aggregator()); + EXPECT_EQ(kFrame2, boost20b.input_frame()); + EXPECT_EQ(kFrame0, boost20b.output_frame()); + EXPECT_EQ(kReasonBoost, boost20b.reason()); + EXPECT_FALSE(boost20.aggregator()); + EXPECT_FALSE(boost20.input_frame()); + EXPECT_FALSE(boost20.output_frame()); + EXPECT_FALSE(boost20.reason()); + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[3].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[2].HasVote()); // Old kFrame2. + EXPECT_EQ(2u, agg_.nodes_.size()); + ExpectEdges(1); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectInvalidVote(0); // Old kFrame1. + consumer_.ExpectInvalidVote(2); // Old kFrame2. + EXPECT_EQ(1u, data0.edge_count_for_testing()); + EXPECT_EQ(1u, data2.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + ExpectIsActive(data2, false, false); + + // Remove the boosting vote from 2 to 0. This should change edge counts, and + // also remove the node data associated with node 2. |data2| is now invalid. + boost20b.Reset(); + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_TRUE(voter_.receipts_[1].HasVote()); // kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[3].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[2].HasVote()); // Old kFrame2. + EXPECT_EQ(1u, agg_.nodes_.size()); + ExpectEdges(0); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectValidVote(1, voter_id_, kFrame0, kPriority1, kReason1); + consumer_.ExpectInvalidVote(0); // Old kFrame1. + consumer_.ExpectInvalidVote(2); // Old kFrame2. + EXPECT_EQ(0u, data0.edge_count_for_testing()); + ExpectIsActive(data0, true, false); + + // Finally remove the last vote. The aggregator should effectively be empty at + // this point. |data0| also becomes invalid after this. + voter_.receipts_[1].Reset(); + EXPECT_EQ(4u, voter_.receipts_.size()); + EXPECT_FALSE(voter_.receipts_[1].HasVote()); // Old kFrame0. + EXPECT_FALSE(voter_.receipts_[0].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[3].HasVote()); // Old kFrame1. + EXPECT_FALSE(voter_.receipts_[2].HasVote()); // Old kFrame2. + EXPECT_EQ(0u, agg_.nodes_.size()); + ExpectEdges(0); + EXPECT_EQ(3u, consumer_.votes_.size()); + consumer_.ExpectInvalidVote(1); // Old kFrame0. + consumer_.ExpectInvalidVote(0); // Old kFrame1. + consumer_.ExpectInvalidVote(2); // Old kFrame2. +} + +TEST_F(BoostingVoteAggregatorTest, DiamondPattern) { + // Create a diamond boosting vote pattern: + // + // 1 + // / \ + // 0 3 + // \ / + // 2 + BoostingVote boost01(&agg_, kFrame0, kFrame1, kReasonBoost); + BoostingVote boost02(&agg_, kFrame0, kFrame2, kReasonBoost); + BoostingVote boost13(&agg_, kFrame1, kFrame3, kReasonBoost); + BoostingVote boost23(&agg_, kFrame2, kFrame3, kReasonBoost); + + const auto& data0 = agg_.nodes_.find(kFrame0)->second; + const auto& data1 = agg_.nodes_.find(kFrame1)->second; + const auto& data2 = agg_.nodes_.find(kFrame2)->second; + const auto& data3 = agg_.nodes_.find(kFrame3)->second; + ExpectIsActive(data0, false, false); + ExpectIsActive(data1, false, false); + ExpectIsActive(data2, false, false); + ExpectIsActive(data3, false, false); + + // Add a vote to node 0. This should cause all nodes to be boosted. + voter_.EmitVote(kFrame0, kPriority2, kReason2); + ExpectIsActive(data0, false, true); + ExpectIsActive(data1, false, true); + ExpectIsActive(data2, false, true); + ExpectIsActive(data3, false, true); + + // Cancel the vote. All boosting should disappear. + voter_.receipts_.clear(); + ExpectIsActive(data0, false, false); + ExpectIsActive(data1, false, false); + ExpectIsActive(data2, false, false); + ExpectIsActive(data3, false, false); +} + +TEST_F(BoostingVoteAggregatorTest, DiamondPatternMultipleVotes) { + // Create another diamond boosting vote pattern: + // + // 1 + // / \ + // 4 - 0 3 + // \ / + // 2 + BoostingVote boost01(&agg_, kFrame0, kFrame1, kReasonBoost); + BoostingVote boost02(&agg_, kFrame0, kFrame2, kReasonBoost); + BoostingVote boost13(&agg_, kFrame1, kFrame3, kReasonBoost); + BoostingVote boost23(&agg_, kFrame2, kFrame3, kReasonBoost); + + const auto& data0 = agg_.nodes_.find(kFrame0)->second; + const auto& data1 = agg_.nodes_.find(kFrame1)->second; + const auto& data2 = agg_.nodes_.find(kFrame2)->second; + const auto& data3 = agg_.nodes_.find(kFrame3)->second; + ExpectIsActive(data0, false, false); + ExpectIsActive(data1, false, false); + ExpectIsActive(data2, false, false); + ExpectIsActive(data3, false, false); + + // Add a vote to node 0. This should cause all downstream nodes to be boosted. + voter_.EmitVote(kFrame0, kPriority2, kReason2); + ExpectIsActive(data0, false, true); + ExpectIsActive(data1, false, true); + ExpectIsActive(data2, false, true); + ExpectIsActive(data3, false, true); + + // Add a lower vote to frame0 via frame4. This should also propagate through + // the network in a similar way. + BoostingVote boost40(&agg_, kFrame4, kFrame0, kReasonBoost); + const auto& data4 = agg_.nodes_.find(kFrame4)->second; + voter_.EmitVote(kFrame4, kPriority1, kReason1); + ExpectIsActive(data0, true, true); + ExpectIsActive(data1, true, true); + ExpectIsActive(data2, true, true); + ExpectIsActive(data3, true, true); + ExpectIsActive(data4, true, false); +} + +TEST_F(BoostingVoteAggregatorTest, RemoveEdgeFromCycle) { + BoostingVote boost01(&agg_, kFrame0, kFrame1, kReasonBoost); + BoostingVote boost12(&agg_, kFrame1, kFrame2, kReasonBoost); + BoostingVote boost23(&agg_, kFrame2, kFrame3, kReasonBoost); + BoostingVote boost30(&agg_, kFrame3, kFrame0, kReasonBoost); + + const auto& data0 = agg_.nodes_.find(kFrame0)->second; + const auto& data1 = agg_.nodes_.find(kFrame1)->second; + const auto& data2 = agg_.nodes_.find(kFrame2)->second; + const auto& data3 = agg_.nodes_.find(kFrame3)->second; + ExpectIsActive(data0, false, false); + ExpectIsActive(data1, false, false); + ExpectIsActive(data2, false, false); + ExpectIsActive(data3, false, false); + + // Add a vote to node 0. + voter_.EmitVote(kFrame0, kPriority2, kReason2); + ExpectIsActive(data0, false, true); + ExpectIsActive(data1, false, true); + ExpectIsActive(data2, false, true); + ExpectIsActive(data3, false, true); + + // Remove an edge from the cycle. The first half of the cycle should still + // be boosted, the second half should not. + boost12.Reset(); + ExpectIsActive(data0, false, true); + ExpectIsActive(data1, false, true); + ExpectIsActive(data2, false, false); + ExpectIsActive(data3, false, false); +} + +TEST_F(BoostingVoteAggregatorTest, MoveCancelsPreviousBoostingVote) { + BoostingVote boost01(&agg_, kFrame0, kFrame1, kReasonBoost); + BoostingVote boost12(&agg_, kFrame1, kFrame2, kReasonBoost); + + // Expect nodes to have been created for all nodes involved in boosting votes. + EXPECT_TRUE(agg_.nodes_.count(kFrame0)); + EXPECT_TRUE(agg_.nodes_.count(kFrame1)); + EXPECT_TRUE(agg_.nodes_.count(kFrame2)); + + // Move one boosting vote into the other. This should cause the latter to be + // canceled. In this case that means node0 should be removed. + boost01 = std::move(boost12); + EXPECT_FALSE(agg_.nodes_.count(kFrame0)); + EXPECT_TRUE(agg_.nodes_.count(kFrame1)); + EXPECT_TRUE(agg_.nodes_.count(kFrame2)); +} + +TEST_F(BoostingVoteAggregatorTest, BoostingVoteAfterNormalVotes) { + voter_.EmitVote(kFrame0, kPriority2, kReason2); + EXPECT_TRUE(agg_.nodes_.count(kFrame0)); + EXPECT_EQ(1u, agg_.nodes_.size()); + const auto& data0 = agg_.nodes_.find(kFrame0)->second; + ExpectIsActive(data0, false, true); + + BoostingVote boost12(&agg_, kFrame1, kFrame2, kReasonBoost); + EXPECT_TRUE(agg_.nodes_.count(kFrame0)); + EXPECT_TRUE(agg_.nodes_.count(kFrame1)); + EXPECT_TRUE(agg_.nodes_.count(kFrame2)); + EXPECT_EQ(3u, agg_.nodes_.size()); + const auto& data1 = agg_.nodes_.find(kFrame1)->second; + const auto& data2 = agg_.nodes_.find(kFrame2)->second; + ExpectIsActive(data0, false, true); + ExpectIsActive(data1, false, false); + ExpectIsActive(data2, false, false); + + BoostingVote boost01(&agg_, kFrame0, kFrame1, kReasonBoost); + EXPECT_TRUE(agg_.nodes_.count(kFrame0)); + EXPECT_TRUE(agg_.nodes_.count(kFrame1)); + EXPECT_TRUE(agg_.nodes_.count(kFrame2)); + EXPECT_EQ(3u, agg_.nodes_.size()); + ExpectIsActive(data0, false, true); + ExpectIsActive(data1, false, true); + ExpectIsActive(data2, false, true); +} + +} // namespace frame_priority +} // namespace performance_manager
diff --git a/components/performance_manager/public/frame_priority/boosting_vote_aggregator.h b/components/performance_manager/public/frame_priority/boosting_vote_aggregator.h new file mode 100644 index 0000000..e844023b --- /dev/null +++ b/components/performance_manager/public/frame_priority/boosting_vote_aggregator.h
@@ -0,0 +1,384 @@ +// 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_PERFORMANCE_MANAGER_PUBLIC_FRAME_PRIORITY_BOOSTING_VOTE_AGGREGATOR_H_ +#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_FRAME_PRIORITY_BOOSTING_VOTE_AGGREGATOR_H_ + +#include <map> +#include <set> + +#include "base/containers/flat_map.h" +#include "base/task/task_traits.h" +#include "components/performance_manager/public/frame_priority/frame_priority.h" + +namespace performance_manager { +namespace frame_priority { + +class BoostingVoteAggregator; + +// A BoostingVote is a special kind of relative vote that allows a voter to +// express that "frame X should have the same or greater priority than frame Y". +// It allows implementing priority boost semantics to avoid priority inversions +// for access to shared resources. BoostingVotes must be registered with a +// BoostingVoteAggregator. Similar to a VoteReceipt, they are a move-only type +// and their vote will be removed with their destruction. +// +// A BoostingVote is considered "active" if it is associated with an aggregator +// (the result of calling "aggregator()" is non-null). +// +// See comments in the implementation for details on how the algorithm works. +class BoostingVote { + public: + // Registers a relative vote with the provided |aggregator|, that ensures that + // the priority of |output_frame| will be at least as high as that of + // |input_frame|. + BoostingVote(BoostingVoteAggregator* aggregator, + const FrameNode* input_frame, + const FrameNode* output_frame, + const char* reason); + BoostingVote(const BoostingVote& rhs) = delete; + BoostingVote(BoostingVote&& rhs); + BoostingVote& operator=(const BoostingVote& rhs) = delete; + BoostingVote& operator=(BoostingVote&& rhs); + ~BoostingVote(); + + BoostingVoteAggregator* aggregator() const { return aggregator_; } + const FrameNode* input_frame() const { return input_frame_; } + const FrameNode* output_frame() const { return output_frame_; } + const char* reason() const { return reason_; } + + // Detaches this BoostingVote from its aggregator. After calling this + // |aggregator_| will be nullptr and the vote will no longer be active. + void Reset(); + + private: + BoostingVoteAggregator* aggregator_ = nullptr; + const FrameNode* input_frame_ = nullptr; + const FrameNode* output_frame_ = nullptr; + const char* reason_ = nullptr; +}; + +// The BoostingVoteAggregator allows for incoming votes to be modified via a +// collection of registered "relative boosting votes" that express relationships +// such as "frame X should have the same or greater priority than frame Y". +// It is intended to serve as the root of a tree of voters and aggregators, +// allowing priority boost semantics to be implemented. This class must outlive +// all boosting votes registered with it. +class BoostingVoteAggregator : public VoteConsumer { + public: + BoostingVoteAggregator(); + ~BoostingVoteAggregator() override; + + // Both of these must be called in order for the aggregator to be setup + // ("IsSetup" will return true). Both of these should be called exactly once. + VotingChannel GetVotingChannel(); + void SetUpstreamVotingChannel(VotingChannel&& channel); + + bool IsSetup() const; + + protected: + friend class BoostingVote; + + // We currently require that base::TaskPriority be zero-based, and + // consecutive. These static asserts ensure that we revisit this code if the + // base::TaskPriority enum ever changes. + static_assert(static_cast<int>(base::TaskPriority::LOWEST) == 0, + "expect 0-based priorities"); + static_assert(static_cast<int>(base::TaskPriority::HIGHEST) == 2, + "expect 3 priority levels"); + + using NodePriorityMap = std::map<const FrameNode*, base::TaskPriority>; + + // Small helper class used to endow both edges and nodes with "active" bits + // for each priority layer. + class ActiveLayers { + public: + // Returns true if any layer is active. + bool IsActiveInAnyLayer() const { return active_layers_ != 0; } + + // Returns the "active" state of this node for the given |layer_bit|. + bool IsActive(uint32_t layer_bit) const; + + // Sets the active state for this node in the given |layer_bit|. + void SetActive(uint32_t layer_bit); + void SetInactive(uint32_t layer_bit); + + private: + // A bit-set corresponding to the priority layers in which this object is + // active. + uint32_t active_layers_ = 0; + }; + + // This is move-only because all of its members are move-only. + // An instance of this will exist for any node that is referenced, either by a + // direct Vote for that node, or as an input or output of a BoostedVote. + class NodeData : public ActiveLayers { + public: + NodeData() = default; + NodeData(const NodeData& rhs) = delete; + NodeData(NodeData&& rhs) = default; + NodeData& operator=(const NodeData& rhs) = delete; + NodeData& operator=(NodeData&& rhs) = default; + ~NodeData() = default; + + const AcceptedVote& incoming() const { return incoming_; } + const VoteReceipt& receipt() const { return receipt_; } + + // For modifying |incoming_|. + VoteReceipt SetIncomingVote(VoteConsumer* consumer, + VoterId voter_id, + const Vote& vote); + void UpdateIncomingVote(const Vote& vote) { incoming_.UpdateVote(vote); } + + // For modifying |receipt_|. + void ChangeOutgoingVote(base::TaskPriority priority, const char* reason) { + receipt_.ChangeVote(priority, reason); + } + void CancelOutgoingVote() { receipt_.Reset(); } + void SetOutgoingVoteReceipt(VoteReceipt&& receipt) { + receipt_ = std::move(receipt); + } + + // Returns true if this node has an active |incoming| vote. If false that + // means this node exists only because it is referenced by a BoostedVote. + // Same as |incoming_.IsValid()|, but more readable. + bool HasIncomingVote() const { return incoming_.IsValid(); } + + // Returns true if this node has an active outgoing vote. Sam as + // |receipt_.HasVote()|, but more readable. + bool HasOutgoingVote() const { return receipt_.HasVote(); } + + // Returns true if this node is involved in any edges. + bool HasEdges() const { return edge_count_ > 0; } + + // Returns the effective priority of this node based on the highest of the + // values in |supporting_node_count_|. + base::TaskPriority GetEffectivePriorityLevel() const; + + // For keeping track of the number of edges in which this node is involved. + void IncrementEdgeCount(); + void DecrementEdgeCount(); + + size_t edge_count_for_testing() const { return edge_count_; } + + private: + // Counts the number of edges involving this node, both input and output. + // When this goes to zero the node no longer needs an explicit + // representation. + size_t edge_count_ = 0; + + // The input vote we've received, if any. + AcceptedVote incoming_; + + // The receipt for the vote we've upstreamed, if any. + VoteReceipt receipt_; + }; + + // NOTE: It is important that NodeDataMap preserve pointers to NodeData + // through insertions and deletions in the map, as we take raw pointers to + // objects in the map. + using NodeDataMap = std::map<const FrameNode*, NodeData>; + using NodeDataPtrSet = std::set<NodeDataMap::value_type*>; + + // For any given edge, this maintains the metadata associated with that + // particular edge. + class EdgeData : public ActiveLayers { + public: + EdgeData(); + EdgeData(const EdgeData&) = delete; + EdgeData(EdgeData&&); + EdgeData& operator=(const EdgeData&) = delete; + EdgeData& operator=(EdgeData&&); + ~EdgeData(); + + // Adds a reason to the set of reasons associated with this edge. + void AddReason(const char* reason); + + // Removes a reason from this edge. Returns true if this was the active + // selected reason that had been forwarded, indicating that a new reason + // needs to be chosen. + bool RemoveReason(const char* reason); + + // Returns the active reason for this edge. + const char* GetActiveReason() const; + + // Returns the total number of reasons associated with this edge. This is + // effectively the multiplicity of the edge in the dependency graph. + size_t GetReasonCount() const { return reasons_.size(); } + + private: + // The reasons associated with this particular edge (one contribution per + // BoostingVote). We really don't expect many multiple edges so a vector is + // used to reduce allocations. This is semantically a multi-set. + std::vector<const char*> reasons_; + }; + + // A helper for storing edges with different sort orders. Templated so that it + // is strongly typed. + template <bool kForward> + class Edge { + public: + Edge(const FrameNode* src, const FrameNode* dst) : src_(src), dst_(dst) {} + explicit Edge(const BoostingVote* boosting_vote) + : src_(boosting_vote->input_frame()), + dst_(boosting_vote->output_frame()) {} + Edge(const Edge&) = default; + ~Edge() {} + + Edge& operator=(const Edge&) = default; + Edge& operator=(Edge&&) = delete; + + bool operator==(const Edge& rhs) const { + return std::tie(src_, dst_) == std::tie(rhs.src_, rhs.dst_); + } + + bool operator!=(const Edge& rhs) const { return !(*this == rhs); } + + // Forward edges sort by (src, dst), while reverse edges sort by (dst, src). + bool operator<(const Edge& rhs) const { + if (kForward) + return std::tie(src_, dst_) < std::tie(rhs.src_, rhs.dst_); + return std::tie(dst_, src_) < std::tie(rhs.dst_, rhs.src_); + } + + const FrameNode* src() const { return src_; } + const FrameNode* dst() const { return dst_; } + + private: + const FrameNode* src_ = nullptr; + const FrameNode* dst_ = nullptr; + }; + using ForwardEdge = Edge<true>; + using ReverseEdge = Edge<false>; + + // EdgeData is stored in the forward map, and a pointer to that data is + // included in the reverse edge map. + using ForwardEdges = std::map<ForwardEdge, EdgeData>; + using ReverseEdges = std::map<ReverseEdge, EdgeData*>; + + // To be called by BoostingVote. + void SubmitBoostingVote(const BoostingVote* boosting_vote); + void CancelBoostingVote(const BoostingVote* boosting_vote); + + // VoteConsumer implementation: + VoteReceipt SubmitVote(VoterId voter_id, const Vote& vote) override; + VoteReceipt ChangeVote(VoteReceipt receipt, + AcceptedVote* old_vote, + const Vote& new_vote) override; + void VoteInvalidated(AcceptedVote* vote) override; + + // Helper functions for enumerating over incoming and outgoing edges. + // |function| should accept a single input parameter that is a + // ForwardEdge::iterator or ReverseEdge::iterator, as appropriate, and which + // returns a bool. Returning true indicates the iteration should continue, + // returning false indicates it should terminate. + template <typename Function> + void ForEachIncomingEdge(const FrameNode* node, Function&& function); + template <typename Function> + void ForEachOutgoingEdge(const FrameNode* node, Function&& function); + + // Looks up the NodeData associated with the provided |vote|. The data is + // expected to already exist (enforced by a DCHECK). + NodeDataMap::iterator GetNodeDataByVote(AcceptedVote* vote); + + // Finds or creates the node data associated with the given node. + NodeDataMap::iterator FindOrCreateNodeData(const FrameNode* frame_node); + NodeDataMap::iterator FindNodeData(const FrameNode* frame_node); + + // Returns the vote reason that should be associated with the given + // node. This will preferentially select the reason that comes with a direct + // vote if any is present; otherwise, it will select the active reason of the + // active edge that causes the node itself to be active. Complexity is + // O(|inbound edge count| + lg |total edge count|). This can return nullptr if + // no non-null reasons have been provided. + const char* GetVoteReason(const NodeDataMap::value_type* node_data_value); + + // Upstreams the vote for this |frame_node| via its associated NodeData. + void UpstreamVoteIfNeeded(NodeDataMap::value_type* node_data_value); + + // Upstreams changes that have been made to the provided set of nodes. This + // takes care of deleted nodes if they no longer need to be represented in + // the priority flow graph. + void UpstreamChanges(const NodeDataPtrSet& changes); + + // Helper for removing a node from the NodeDataMap. + void MaybeRemoveNode(NodeDataMap::iterator node_data_it); + + // Marks sub-tree rooted at |node| as inactive, and returns the nodes that + // were deactivated in the provided output set. + void MarkSubtreeInactive(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* deactivated); + + // Determines if the given node has an inbound active edge, returning an + // iterator to it if there is one. + ReverseEdges::iterator GetActiveInboundEdge( + uint32_t layer_bit, + const NodeDataMap::value_type* node); + + // Gets the nearest active ancestor of a given deactivated node. Returns + // nullptr if there is none. + NodeDataMap::value_type* GetNearestActiveAncestor( + uint32_t layer_bit, + const NodeDataMap::value_type* deactivated_node); + + // Given a set of inactive nodes, returns a search front corresponding to + // all of their nearest active ancestors. + void GetNearestActiveAncestors(uint32_t layer_bit, + const NodeDataPtrSet& deactivated, + NodeDataPtrSet* active_ancestors); + + // Given a search front of active nodes, explores outwards from those nodes + // in order to generate a reachability spanning tree. Empties the + // |active_search_front| as the search progresses, and populates |changes| + // with the set of nodes that were made active as a result of the search. + void MarkNodesActiveFromSearchFront(uint32_t layer_bit, + NodeDataPtrSet* active_search_front, + NodeDataPtrSet* activated); + + // Reprocesses the subtree rooted at the provided |node|. This is used to + // repair the reachability spanning tree when the active edge inbound to + // |node| is deleted. The set of nodes that have seen an active state toggle + // or a change in vote reason are stored in |changes|, for use with + // "UpstreamChanges". + void ReprocessSubtree(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* changes); + + // Used by SubmitVote/ChangeVote and VoteInvalidated. + void OnVoteAdded(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* changes); + void OnVoteRemoved(uint32_t layer_bit, + NodeDataMap::value_type* node, + NodeDataPtrSet* changes); + + // Our input voter. We'll only accept votes from this voter otherwise we'll + // DCHECK. + VoterId input_voter_id_ = kInvalidVoterId; + + // Our channel for upstreaming our votes. + VotingChannel channel_; + + // Our VotingChannelFactory for providing a VotingChannel to our input voter. + VotingChannelFactory factory_; + + // Nodes and associated metadata in the "priority flow graph". An entry exists + // in this map for any node that has an active non-default vote, or for any + // node that is referenced by the "priority flow graph". + NodeDataMap nodes_; + + // The collection of know BoostingVotes, describing the edges in the + // "priority flow graph" as adjacency lists. Nodes are stored as instances of + // NodeData. + ForwardEdges forward_edges_; + ReverseEdges reverse_edges_; + + DISALLOW_COPY_AND_ASSIGN(BoostingVoteAggregator); +}; + +} // namespace frame_priority +} // namespace performance_manager + +#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_FRAME_PRIORITY_BOOSTING_VOTE_AGGREGATOR_H_
diff --git a/components/performance_manager/test_support/frame_priority.cc b/components/performance_manager/test_support/frame_priority.cc index 865712f..73799c9 100644 --- a/components/performance_manager/test_support/frame_priority.cc +++ b/components/performance_manager/test_support/frame_priority.cc
@@ -53,6 +53,13 @@ --valid_vote_count_; } +void DummyVoteConsumer::ExpectInvalidVote(size_t index) { + EXPECT_LT(index, votes_.size()); + const AcceptedVote& accepted_vote = votes_[index]; + EXPECT_EQ(this, accepted_vote.consumer()); + EXPECT_FALSE(accepted_vote.IsValid()); +} + void DummyVoteConsumer::ExpectValidVote(size_t index, VoterId voter_id, const FrameNode* frame_node,
diff --git a/components/performance_manager/test_support/frame_priority.h b/components/performance_manager/test_support/frame_priority.h index 01882a95..a1a6c2c8 100644 --- a/components/performance_manager/test_support/frame_priority.h +++ b/components/performance_manager/test_support/frame_priority.h
@@ -28,6 +28,8 @@ const Vote& new_vote) override; void VoteInvalidated(AcceptedVote* vote) override; + void ExpectInvalidVote(size_t index); + // Checks that the vote at position |index| is valid, and has the // corresponding |voter|, |frame_node| and |priority|. If |reason| is non-null // then it will be validated as well.
diff --git a/components/test/data/payments/empty_parameters.js b/components/test/data/payments/empty_parameters.js new file mode 100644 index 0000000..45e3ebc --- /dev/null +++ b/components/test/data/payments/empty_parameters.js
@@ -0,0 +1,26 @@ +/* + * 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. + */ + +/** + * Queries Payment Request with some empty parameters. + * Regression test for: https://crbug.com/1022810 + * @return {Promise<boolean>} - Whether a payment can be made. + */ +async function runTest() { // eslint-disable-line no-unused-vars + return new PaymentRequest([{supportedMethods: 'basic-card'}], { + displayItems: [], + id: '', + modifiers: [], + shippingOptions: [], + total: { + label: 'Subscription', + amount: { + value: '1.00', + currency: 'USD', + }, + }, + }).canMakePayment(); +}
diff --git a/components/test/data/payments/empty_parameters_test.html b/components/test/data/payments/empty_parameters_test.html new file mode 100644 index 0000000..65a7665 --- /dev/null +++ b/components/test/data/payments/empty_parameters_test.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<!-- +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. +--> +<html> +<head> +<title>Empty Parameters Test</title> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1"> +<link rel="stylesheet" type="text/css" href="style.css"> +</head> +<body> +<p>Regression test for <a href="https://crbug.com/1022810">Issue 1022810</a>.</p> +<div><button onclick="runTest()" id="runTest">Run Test</button></div> +<script src="empty_parameters.js"></script> +</body> +</html>
diff --git a/components/viz/common/gpu/metal_api_proxy.mm b/components/viz/common/gpu/metal_api_proxy.mm index 98a9629..f273a1d 100644 --- a/components/viz/common/gpu/metal_api_proxy.mm +++ b/components/viz/common/gpu/metal_api_proxy.mm
@@ -382,6 +382,7 @@ dispatch_data_t, error, __autoreleasing NSError**) + - (nullable id<MTLLibrary>) newLibraryWithSource:(NSString*)source options:(nullable MTLCompileOptions*)options @@ -549,6 +550,7 @@ PROXY_METHOD1_SLOW(nullable id<MTLArgumentEncoder>, newArgumentEncoderWithArguments, NSArray<MTLArgumentDescriptor*>*) + #if defined(MAC_OS_X_VERSION_10_14) PROXY_METHOD1_SLOW(nullable id<MTLTexture>, newSharedTextureWithDescriptor, @@ -573,6 +575,27 @@ PROXY_METHOD1(nullable id<MTLSharedEvent>, newSharedEventWithHandle, MTLSharedEventHandle*) -#endif +#endif // MAC_OS_X_VERSION_10_14 + +#if defined(MAC_OS_X_VERSION_10_15) +PROXY_METHOD0(BOOL, hasUnifiedMemory) +PROXY_METHOD0(MTLDeviceLocation, location) +PROXY_METHOD0(NSUInteger, locationNumber) +PROXY_METHOD0(uint64_t, maxTransferRate) +PROXY_METHOD0(BOOL, areBarycentricCoordsSupported) +PROXY_METHOD0(BOOL, supportsShaderBarycentricCoordinates) +PROXY_METHOD0(uint64_t, peerGroupID) +PROXY_METHOD0(uint32_t, peerIndex) +PROXY_METHOD0(uint32_t, peerCount) +PROXY_METHOD0(nullable NSArray<id<MTLCounterSet>>*, counterSets) +PROXY_METHOD1(BOOL, supportsFamily, MTLGPUFamily) +PROXY_METHOD2_SLOW(nullable id<MTLCounterSampleBuffer>, + newCounterSampleBufferWithDescriptor, + MTLCounterSampleBufferDescriptor*, + error, + NSError**) +PROXY_METHOD2(void, sampleTimestamps, NSUInteger*, gpuTimestamp, NSUInteger*) +#endif // MAC_OS_X_VERSION_10_15 + #pragma clang diagnostic pop @end
diff --git a/content/browser/accessibility/accessibility_auralinux_browsertest.cc b/content/browser/accessibility/accessibility_auralinux_browsertest.cc index 91b3500..c40504b 100644 --- a/content/browser/accessibility/accessibility_auralinux_browsertest.cc +++ b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
@@ -186,6 +186,61 @@ } IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest, + TestMultilingualTextAtOffsetWithBoundaryCharacter) { + AtkText* atk_text = SetUpInputField(); + ASSERT_NE(nullptr, atk_text); + AccessibilityNotificationWaiter waiter(shell()->web_contents(), + ui::kAXModeComplete, + ax::mojom::Event::kValueChanged); + // Place an e acute, and two emoticons in the text field. + ExecuteScript(base::UTF8ToUTF16(R"SCRIPT( + const input = document.querySelector('input'); + input.value = + 'e\u0301\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69\uD83D\uDC36'; + )SCRIPT")); + waiter.WaitForNotification(); + + int character_count = atk_text_get_character_count(atk_text); + // "character_count" is the number of actual characters, not the number of + // UTF16 code units. + // + // Currently, this doesn't properly count grapheme clusters, but it does + // handle surrogate pairs. + // TODO(nektar): Implement support for base::OffsetAdjuster in AXPosition. + ASSERT_EQ(9, character_count); + + // The expected text consists of an e acute, and two emoticons, but + // not every multi-byte character is a surrogate pair. + CheckTextAtOffset(atk_text, 0, ATK_TEXT_BOUNDARY_CHAR, 0, 2, + base::WideToUTF8(L"e\x0301").c_str()); + CheckTextAtOffset(atk_text, 1, ATK_TEXT_BOUNDARY_CHAR, 0, 2, + base::WideToUTF8(L"e\x0301").c_str()); + CheckTextAtOffset(atk_text, 2, ATK_TEXT_BOUNDARY_CHAR, 2, 8, + "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2" + "\x80\x8D\xF0\x9F\x91\xA9"); + CheckTextAtOffset(atk_text, 3, ATK_TEXT_BOUNDARY_CHAR, 2, 8, + "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2" + "\x80\x8D\xF0\x9F\x91\xA9"); + CheckTextAtOffset(atk_text, 4, ATK_TEXT_BOUNDARY_CHAR, 2, 8, + "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2" + "\x80\x8D\xF0\x9F\x91\xA9"); + CheckTextAtOffset(atk_text, 5, ATK_TEXT_BOUNDARY_CHAR, 2, 8, + "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2" + "\x80\x8D\xF0\x9F\x91\xA9"); + CheckTextAtOffset(atk_text, 6, ATK_TEXT_BOUNDARY_CHAR, 2, 8, + "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2" + "\x80\x8D\xF0\x9F\x91\xA9"); + CheckTextAtOffset(atk_text, 7, ATK_TEXT_BOUNDARY_CHAR, 2, 8, + "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2" + "\x80\x8D\xF0\x9F\x91\xA9"); + CheckTextAtOffset(atk_text, 8, ATK_TEXT_BOUNDARY_CHAR, 8, 9, + "\xF0\x9F\x90\xB6"); + CheckTextAtOffset(atk_text, 9, ATK_TEXT_BOUNDARY_CHAR, 0, 0, nullptr); + + g_object_unref(atk_text); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest, TestTextAtOffsetWithBoundaryLine) { AtkText* atk_text = SetUpInputField();
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index af04bfe..61b0d9f 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -5,6 +5,7 @@ #include <objbase.h> #include <stddef.h> #include <stdint.h> +#include <string.h> #include <wrl/client.h> #include <memory> @@ -3065,6 +3066,51 @@ } IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, + TestMultilingualTextAtOffsetWithBoundaryCharacter) { + Microsoft::WRL::ComPtr<IAccessibleText> input_text; + SetUpInputField(&input_text); + AccessibilityNotificationWaiter waiter(shell()->web_contents(), + ui::kAXModeComplete, + ax::mojom::Event::kValueChanged); + // Place an e acute, and two emoticons in the text field. + ExecuteScript(base::UTF8ToUTF16(R"SCRIPT( + const input = document.querySelector('input'); + input.value = + 'e\u0301\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69\uD83D\uDC36'; + )SCRIPT")); + waiter.WaitForNotification(); + + LONG n_characters; + ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters)); + // "n_characters" is the number of valid text offsets. + // + // Ordinarily, the number of valid text offsets should equal the number of + // actual characters which are only three in this case. However, this is + // harder to implement given our current UTF16-based representation of IA2 + // hyptertext. + // TODO(nektar): Implement support for base::OffsetAdjuster in AXPosition. + ASSERT_EQ(12, n_characters); + + // The expected text consists of an e acute, and two emoticons. + const std::vector<std::wstring> expected_text = { + L"e\x0301", L"\xD83D\xDC69\x200D\x2764\xFE0F\x200D\xD83D\xDC69", + L"\xD83D\xDC36"}; + LONG offset = 0; + for (const std::wstring& expected_character : expected_text) { + LONG expected_start_offset = offset; + LONG expected_end_offset = + expected_start_offset + LONG{expected_character.length()}; + for (size_t code_unit_offset = 0; + code_unit_offset < expected_character.length(); ++code_unit_offset) { + CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR, + expected_start_offset, expected_end_offset, + expected_character); + ++offset; + } + } +} + +IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestTextAtOffsetWithBoundaryWord) { Microsoft::WRL::ComPtr<IAccessibleText> input_text; SetUpInputField(&input_text);
diff --git a/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc index 5dccd2f..54281f8 100644 --- a/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc +++ b/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc
@@ -1723,6 +1723,30 @@ } IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest, + EntireMarkupSuccessiveMoveByCharacter) { + AssertMoveByUnitForMarkup( + TextUnit_Character, "Test ing.", + {L"T", L"e", L"s", L"t", L" ", L"i", L"n", L"g", L"."}); + + // The text consists of an e acute, and two emoticons. + const std::string html = R"HTML(<!DOCTYPE html> + <html> + <body> + <input type="text" value=""> + <script> + document.querySelector('input').value = 'e\u0301' + + '\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69' + + '\uD83D\uDC36'; + </script> + </body> + </html>)HTML"; + AssertMoveByUnitForMarkup( + TextUnit_Character, html, + {L"e\x0301", L"\xD83D\xDC69\x200D\x2764\xFE0F\x200D\xD83D\xDC69", + L"\xD83D\xDC36"}); +} + +IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest, EntireMarkupSuccessiveMoveByWord) { AssertMoveByUnitForMarkup(TextUnit_Word, "this is a test.", {L"this ", L"is ", L"a ", L"test."});
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index f30b96b..ddf44cab9 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -1373,13 +1373,8 @@ // On Windows and Linux ATK, it is standard text navigation behavior to stop // if we are searching in the backwards direction and the current position is // already at the required text boundary. - if (direction == ui::AXTextBoundaryDirection::kBackwards) { - // AXPosition disallows ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary when - // used on character boundaries because it would be non-sensical. - if (boundary == ui::AXTextBoundary::kCharacter) - return offset; + if (direction == ui::AXTextBoundaryDirection::kBackwards) boundary_behavior = ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary; - } return GetBoundaryTextOffsetInsideBaseAnchor( direction, position,
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 5d17142c..4b10657 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -3800,34 +3800,4 @@ FROM_HERE); } -IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, WebMidiNotCached) { - ASSERT_TRUE(embedded_test_server()->Start()); - GURL url_a(embedded_test_server()->GetURL("/title1.html")); - GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); - - // 1) Navigate to A. - ASSERT_TRUE(NavigateToURL(shell(), url_a)); - RenderFrameHostImpl* rfh_a = current_frame_host(); - RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a); - - // - Wait until requestMIDIAccess() promise is resolved. - EXPECT_TRUE(ExecJs(rfh_a, "navigator.requestMIDIAccess()")); - - // 2) Navigate to B. - ASSERT_TRUE(NavigateToURL(shell(), url_b)); - - // - Page A should not be in the cache. - EXPECT_TRUE(delete_observer_rfh_a.deleted()); - - // 3) Go back. - web_contents()->GetController().GoBack(); - EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); - ExpectNotRestored( - {BackForwardCacheMetrics::NotRestoredReason::kBlocklistedFeatures}, - FROM_HERE); - ExpectBlocklistedFeature( - blink::scheduler::WebSchedulerTrackedFeature::kRequestedMIDIPermission, - FROM_HERE); -} - } // namespace content
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc index 579d5d4..b0bae88 100644 --- a/content/browser/frame_host/frame_tree.cc +++ b/content/browser/frame_host/frame_tree.cc
@@ -272,6 +272,17 @@ } } + // Check whether we're in an inner delegate and |site_instance| corresponds + // to the outer delegate. Subframe proxies aren't needed if this is the + // case. + bool is_site_instance_for_outer_delegate = false; + RenderFrameProxyHost* outer_delegate_proxy = + root()->render_manager()->GetProxyToOuterDelegate(); + if (outer_delegate_proxy) { + is_site_instance_for_outer_delegate = + (site_instance == outer_delegate_proxy->GetSiteInstance()); + } + // Proxies are created in the FrameTree in response to a node navigating to a // new SiteInstance. Since |source|'s navigation will replace the currently // loaded document, the entire subtree under |source| will be removed, and @@ -299,6 +310,14 @@ // race described above not possible. continue; } + + // Do not create proxies for subframes in the outer delegate's + // SiteInstance, since there is no need to expose these subframes to the + // outer delegate. See also comments in CreateProxiesForChildFrame() and + // https://crbug.com/1013553. + if (!node->IsMainFrame() && is_site_instance_for_outer_delegate) + continue; + node->render_manager()->CreateRenderFrameProxy(site_instance); } }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index f8924d67..0df4b5d 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -995,10 +995,6 @@ const url::Origin& source_origin, const base::Optional<url::Origin>& target_origin); - // mojom::FrameHost: - void VisibilityChanged(blink::mojom::FrameVisibility) override; - void DidChangeThemeColor(const base::Optional<SkColor>& theme_color) override; - blink::mojom::FrameVisibility visibility() const { return visibility_; } // A CommitCallbackInterceptor is used to modify parameters for or cancel a @@ -1206,6 +1202,10 @@ void DidDisplayInsecureContent() override; void DidContainInsecureFormAction() override; void SetNeedsOcclusionTracking(bool needs_tracking) override; + void LifecycleStateChanged(blink::mojom::FrameLifecycleState state) override; + void EvictFromBackForwardCache() override; + void VisibilityChanged(blink::mojom::FrameVisibility) override; + void DidChangeThemeColor(const base::Optional<SkColor>& theme_color) override; protected: friend class RenderFrameHostFactory; @@ -1457,7 +1457,6 @@ validated_params, mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) override; - void EvictFromBackForwardCache() override; // This function mimics DidCommitProvisionalLoad but is a direct mojo // callback from NavigationClient::CommitNavigation. @@ -1494,7 +1493,6 @@ void CancelInitialHistoryLoad() override; void UpdateEncoding(const std::string& encoding) override; void FrameSizeChanged(const gfx::Size& frame_size) override; - void LifecycleStateChanged(blink::mojom::FrameLifecycleState state) override; void DocumentOnLoadCompleted() override; void UpdateActiveSchedulerTrackedFeatures(uint64_t features_mask) override; void DidAddMessageToConsole(blink::mojom::ConsoleMessageLevel log_level,
diff --git a/content/browser/indexed_db/leveldb/transactional_leveldb_iterator.cc b/content/browser/indexed_db/leveldb/transactional_leveldb_iterator.cc index 08f109b..4ebc9b35 100644 --- a/content/browser/indexed_db/leveldb/transactional_leveldb_iterator.cc +++ b/content/browser/indexed_db/leveldb/transactional_leveldb_iterator.cc
@@ -146,11 +146,14 @@ if (!s.ok()) return s; - // Exit early if not valid. + // If invalid, that means the current key has been deleted AND it was at the + // end of the database. In this case, seeking to the last item is the same as + // 'Prev'-ing from the deleted item. if (!IsValid()) - return WrappedIteratorStatus(); + iterator_->SeekToLast(); + else + iterator_->Prev(); - iterator_->Prev(); PrevPastScopesMetadata(); return WrappedIteratorStatus(); }
diff --git a/content/browser/indexed_db/leveldb/transactional_leveldb_transaction_unittest.cc b/content/browser/indexed_db/leveldb/transactional_leveldb_transaction_unittest.cc index 5679199f..b767202 100644 --- a/content/browser/indexed_db/leveldb/transactional_leveldb_transaction_unittest.cc +++ b/content/browser/indexed_db/leveldb/transactional_leveldb_transaction_unittest.cc
@@ -924,4 +924,74 @@ EXPECT_TRUE(KeysEqual(it->Key(), key2)) << it->Key() << ", " << key2; } +TEST_F(TransactionalLevelDBTransactionTest, + IteratorPrevAfterRemovingCurrentKeyAtDatabaseEnd) { + SetUpRealDatabase(); + SetupLevelDBDatabase(); + + // This tests that the iterator reloading logic correctly handles not calling + // Next when it reloads after the current key was removed. + + const std::string key1("b-key1"); + const std::string key2("b-key2"); + const std::string value("value"); + + Put(key1, value); + Put(key2, value); + + scoped_refptr<TransactionalLevelDBTransaction> transaction = + CreateTransaction(); + std::unique_ptr<TransactionalLevelDBIterator> it = + transaction->CreateIterator(); + + leveldb::Status s = it->Seek(std::string("b-key2")); + ASSERT_TRUE(it->IsValid()); + EXPECT_TRUE(s.ok()); + + // Make sure the iterator is detached, and remove the current key. + it->EvictLevelDBIterator(); + TransactionRemove(transaction.get(), key2); + + // This call reloads the iterator at key "b-key2", which is now deleted. It + // should seek to the end of the database instead, which is "b-key1" + s = it->Prev(); + ASSERT_TRUE(it->IsValid()); + EXPECT_TRUE(s.ok()); + EXPECT_TRUE(KeysEqual(it->Key(), key1)) << it->Key() << ", " << key1; +} + +TEST_F(TransactionalLevelDBTransactionTest, + IteratorPrevAfterRemovingCurrentKeyAtDatabaseStart) { + SetUpRealDatabase(); + SetupLevelDBDatabase(); + + // This tests that the iterator reloading logic correctly handles not calling + // Next when it reloads after the current key was removed. + + const std::string key1("b-key1"); + const std::string key2("b-key2"); + const std::string value("value"); + + Put(key1, value); + Put(key2, value); + + scoped_refptr<TransactionalLevelDBTransaction> transaction = + CreateTransaction(); + std::unique_ptr<TransactionalLevelDBIterator> it = + transaction->CreateIterator(); + + leveldb::Status s = it->Seek(std::string("b-key1")); + ASSERT_TRUE(it->IsValid()); + EXPECT_TRUE(s.ok()); + + // Make sure the iterator is detached, and remove the current key. + it->EvictLevelDBIterator(); + TransactionRemove(transaction.get(), key1); + + // This call reloads the iterator at key "b-key1", which is now deleted. Since + // there is no key before it, it should be invalid. + s = it->Prev(); + ASSERT_FALSE(it->IsValid()); +} + } // namespace content
diff --git a/content/browser/media/cdm_registry_impl_unittest.cc b/content/browser/media/cdm_registry_impl_unittest.cc index e3e197b..e919de1 100644 --- a/content/browser/media/cdm_registry_impl_unittest.cc +++ b/content/browser/media/cdm_registry_impl_unittest.cc
@@ -25,7 +25,7 @@ namespace { using VideoCodec = media::VideoCodec; -using EncryptionMode = media::EncryptionMode; +using EncryptionScheme = media::EncryptionScheme; using CdmSessionType = media::CdmSessionType; using CdmProxy = media::CdmProxy; @@ -76,7 +76,7 @@ kTestCdmName, kTestCdmGuid, base::Version(kVersion1), base::FilePath::FromUTF8Unsafe(kTestPath), kTestFileSystemId, CdmCapability( - {media::kCodecVP8, media::kCodecVP9}, {EncryptionMode::kCenc}, + {media::kCodecVP8, media::kCodecVP9}, {EncryptionScheme::kCenc}, {CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense}, {CdmProxy::Protocol::kIntel}), kTestKeySystem, /*supports_sub_key_systems=*/true); @@ -118,7 +118,7 @@ EXPECT_EQ(kTestPath, cdm.path.MaybeAsASCII()); EXPECT_EQ(kTestFileSystemId, cdm.file_system_id); EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9); - EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc); + EXPECT_ENCRYPTION_SCHEMES(EncryptionScheme::kCenc); EXPECT_SESSION_TYPES(CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense); EXPECT_CDM_PROXY_PROTOCOLS(CdmProxy::Protocol::kIntel); @@ -172,14 +172,14 @@ TEST_F(CdmRegistryImplTest, SupportedEncryptionSchemes) { auto cdm_info = GetTestCdmInfo(); - cdm_info.capability.encryption_schemes = {EncryptionMode::kCenc, - EncryptionMode::kCbcs}; + cdm_info.capability.encryption_schemes = {EncryptionScheme::kCenc, + EncryptionScheme::kCbcs}; Register(cdm_info); std::vector<CdmInfo> cdms = cdm_registry_.GetAllRegisteredCdms(); ASSERT_EQ(1u, cdms.size()); const CdmInfo& cdm = cdms[0]; - EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc, EncryptionMode::kCbcs); + EXPECT_ENCRYPTION_SCHEMES(EncryptionScheme::kCenc, EncryptionScheme::kCbcs); } } // namespace content
diff --git a/content/browser/media/key_system_support_impl.cc b/content/browser/media/key_system_support_impl.cc index 854ddd9c..93de83d 100644 --- a/content/browser/media/key_system_support_impl.cc +++ b/content/browser/media/key_system_support_impl.cc
@@ -45,7 +45,7 @@ // be modified. bool IsHardwareSecureCodecsOverriddenFromCommandLine( std::vector<media::VideoCodec>* video_codecs, - std::vector<media::EncryptionMode>* encryption_schemes) { + std::vector<media::EncryptionScheme>* encryption_schemes) { DCHECK(video_codecs->empty()); DCHECK(encryption_schemes->empty()); @@ -73,7 +73,7 @@ // Codecs enabled from command line assumes CENC support. if (!video_codecs->empty()) - encryption_schemes->push_back(media::EncryptionMode::kCenc); + encryption_schemes->push_back(media::EncryptionScheme::kCenc); return true; } @@ -82,7 +82,7 @@ const std::string& key_system, const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols, std::vector<media::VideoCodec>* video_codecs, - std::vector<media::EncryptionMode>* encryption_schemes) { + std::vector<media::EncryptionScheme>* encryption_schemes) { DCHECK(video_codecs->empty()); DCHECK(encryption_schemes->empty()); @@ -122,7 +122,7 @@ #endif base::flat_set<media::VideoCodec> video_codec_set; - base::flat_set<media::EncryptionMode> encryption_scheme_set; + base::flat_set<media::EncryptionScheme> encryption_scheme_set; GetContentClient()->browser()->GetHardwareSecureDecryptionCaps( key_system, cdm_proxy_protocols, &video_codec_set,
diff --git a/content/browser/media/key_system_support_impl_unittest.cc b/content/browser/media/key_system_support_impl_unittest.cc index 660f21a..e687ae11 100644 --- a/content/browser/media/key_system_support_impl_unittest.cc +++ b/content/browser/media/key_system_support_impl_unittest.cc
@@ -25,7 +25,7 @@ namespace { using VideoCodec = media::VideoCodec; -using EncryptionMode = media::EncryptionMode; +using EncryptionScheme = media::EncryptionScheme; using CdmSessionType = media::CdmSessionType; const base::Token kTestCdmGuid{1234, 5678}; @@ -68,7 +68,7 @@ CdmCapability GetTestCdmCapability() { return CdmCapability( {VideoCodec::kCodecVP8, VideoCodec::kCodecVP9}, - {EncryptionMode::kCenc, EncryptionMode::kCbcs}, + {EncryptionScheme::kCenc, EncryptionScheme::kCbcs}, {CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense}, {}); } @@ -114,7 +114,7 @@ EXPECT_TRUE(IsSupported("KeySystem2")); EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9); - EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc, EncryptionMode::kCbcs); + EXPECT_ENCRYPTION_SCHEMES(EncryptionScheme::kCenc, EncryptionScheme::kCbcs); EXPECT_SESSION_TYPES(CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense); }
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc index dd15f1d9..019a8f0 100644 --- a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc +++ b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
@@ -19,6 +19,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/video_capture/public/cpp/receiver_media_to_mojo_adapter.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" namespace content { @@ -118,7 +119,8 @@ std::make_unique<media::VideoFrameReceiverOnTaskRunner>( std::move(receiver), base::CreateSingleThreadTaskRunner({BrowserThread::IO}))); - mojo::PendingRemote<video_capture::mojom::Receiver> pending_remote_proxy; + mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> + pending_remote_proxy; mojo::MakeSelfOwnedReceiver( std::move(receiver_adapter), pending_remote_proxy.InitWithNewPipeAndPassReceiver());
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc b/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc index f621c16..a6d96dfa 100644 --- a/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc +++ b/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
@@ -19,6 +19,7 @@ #include "services/video_capture/public/cpp/mock_push_subscription.h" #include "services/video_capture/public/cpp/mock_video_source.h" #include "services/video_capture/public/cpp/mock_video_source_provider.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -94,15 +95,15 @@ ON_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _)) .WillByDefault(Invoke( - [this]( - mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, - const media::VideoCaptureParams& requested_settings, - bool force_reopen_with_new_settings, - mojo::PendingReceiver< - video_capture::mojom::PushVideoStreamSubscription> - subscription, - video_capture::mojom::VideoSource:: - CreatePushSubscriptionCallback& callback) { + [this](mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> + subscriber, + const media::VideoCaptureParams& requested_settings, + bool force_reopen_with_new_settings, + mojo::PendingReceiver< + video_capture::mojom::PushVideoStreamSubscription> + subscription, + video_capture::mojom::VideoSource:: + CreatePushSubscriptionCallback& callback) { subscription_receivers_.Add(&mock_subscription_, std::move(subscription)); std::move(callback).Run( @@ -205,7 +206,8 @@ .WillOnce(Invoke( [&create_push_subscription_success_answer_cb, &step_1_run_loop, service_result_code]( - mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, + mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> + subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver< @@ -261,7 +263,8 @@ EXPECT_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _)) .WillOnce(Invoke( - [](mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, + [](mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> + subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver< @@ -274,8 +277,8 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce( - [](mojo::PendingRemote<video_capture::mojom::Receiver> - subscriber, + [](mojo::PendingRemote< + video_capture::mojom::VideoFrameHandler> subscriber, const media::VideoCaptureParams& requested_settings, mojo::PendingReceiver< video_capture::mojom::PushVideoStreamSubscription> @@ -342,7 +345,8 @@ EXPECT_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _)) .WillOnce(Invoke( [&create_subscription_cb]( - mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, + mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> + subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver<
diff --git a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc index 880a793..5f6d392 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc +++ b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
@@ -25,6 +25,7 @@ #include "services/video_capture/public/cpp/mock_video_source_provider.h" #include "services/video_capture/public/mojom/producer.mojom.h" #include "services/video_capture/public/mojom/video_capture_service.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -106,15 +107,15 @@ ON_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _)) .WillByDefault(Invoke( - [this]( - mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, - const media::VideoCaptureParams& requested_settings, - bool force_reopen_with_new_settings, - mojo::PendingReceiver< - video_capture::mojom::PushVideoStreamSubscription> - subscription, - video_capture::mojom::VideoSource:: - CreatePushSubscriptionCallback& callback) { + [this](mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> + subscriber, + const media::VideoCaptureParams& requested_settings, + bool force_reopen_with_new_settings, + mojo::PendingReceiver< + video_capture::mojom::PushVideoStreamSubscription> + subscription, + video_capture::mojom::VideoSource:: + CreatePushSubscriptionCallback& callback) { subscription_receivers_.Add(&mock_subscription_, std::move(subscription)); std::move(callback).Run(
diff --git a/content/browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc b/content/browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc index 6929ccc..7b1a57ae 100644 --- a/content/browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc +++ b/content/browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc
@@ -15,9 +15,10 @@ #include "media/base/media_switches.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" #include "services/video_capture/public/mojom/device.mojom.h" #include "services/video_capture/public/mojom/device_factory.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/video_source.mojom.h" #include "services/video_capture/public/mojom/video_source_provider.mojom.h" #include "testing/gmock/include/gmock/gmock.h" @@ -125,12 +126,14 @@ void Initialize() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); main_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - mock_receiver_ = std::make_unique<video_capture::MockReceiver>( - subscriber_.InitWithNewPipeAndPassReceiver()); + mock_video_frame_handler_ = + std::make_unique<video_capture::MockVideoFrameHandler>( + subscriber_.InitWithNewPipeAndPassReceiver()); } scoped_refptr<base::TaskRunner> main_task_runner_; - std::unique_ptr<video_capture::MockReceiver> mock_receiver_; + std::unique_ptr<video_capture::MockVideoFrameHandler> + mock_video_frame_handler_; private: void OnDeviceInfosReceived( @@ -203,7 +206,7 @@ mojo::Remote<video_capture::mojom::VideoSource> video_source_; mojo::Remote<video_capture::mojom::PushVideoStreamSubscription> subscription_; - mojo::PendingRemote<video_capture::mojom::Receiver> subscriber_; + mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> subscriber_; base::WeakPtrFactory<WebRtcVideoCaptureSharedDeviceBrowserTest> weak_factory_{ this}; @@ -220,13 +223,13 @@ base::RunLoop receive_frame_from_service_wait_loop; auto expected_buffer_handle_tag = GetParam().GetExpectedBufferHandleTag(); - ON_CALL(*mock_receiver_, DoOnNewBuffer(_, _)) + ON_CALL(*mock_video_frame_handler_, DoOnNewBuffer(_, _)) .WillByDefault(Invoke( [expected_buffer_handle_tag]( int32_t, media::mojom::VideoBufferHandlePtr* buffer_handle) { ASSERT_EQ(expected_buffer_handle_tag, (*buffer_handle)->which()); })); - EXPECT_CALL(*mock_receiver_, DoOnFrameReadyInBuffer(_, _, _, _)) + EXPECT_CALL(*mock_video_frame_handler_, DoOnFrameReadyInBuffer(_, _, _, _)) .WillOnce(InvokeWithoutArgs([&receive_frame_from_service_wait_loop]() { receive_frame_from_service_wait_loop.Quit(); })) @@ -235,7 +238,8 @@ OpenDeviceViaService(); // Note, if we do not wait for the first frame to arrive before opening the // device in the Renderer, it could happen that the Renderer takes ove access - // to the device before a first frame is received by mock_receiver_. + // to the device before a first frame is received by + // mock_video_frame_handler_. receive_frame_from_service_wait_loop.Run(); OpenDeviceInRendererAndWaitForPlaying(); @@ -251,13 +255,13 @@ base::RunLoop receive_frame_from_service_wait_loop; auto expected_buffer_handle_tag = GetParam().GetExpectedBufferHandleTag(); - ON_CALL(*mock_receiver_, DoOnNewBuffer(_, _)) + ON_CALL(*mock_video_frame_handler_, DoOnNewBuffer(_, _)) .WillByDefault(Invoke( [expected_buffer_handle_tag]( int32_t, media::mojom::VideoBufferHandlePtr* buffer_handle) { ASSERT_EQ(expected_buffer_handle_tag, (*buffer_handle)->which()); })); - EXPECT_CALL(*mock_receiver_, DoOnFrameReadyInBuffer(_, _, _, _)) + EXPECT_CALL(*mock_video_frame_handler_, DoOnFrameReadyInBuffer(_, _, _, _)) .WillOnce(InvokeWithoutArgs([&receive_frame_from_service_wait_loop]() { receive_frame_from_service_wait_loop.Quit(); }))
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index e062802..a92a595 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -22,7 +22,6 @@ import "services/network/public/mojom/url_loader_factory.mojom"; import "services/service_manager/public/mojom/interface_provider.mojom"; import "services/viz/public/mojom/compositing/surface_id.mojom"; -import "skia/public/mojom/skcolor.mojom"; import "third_party/blink/public/mojom/blob/blob_url_store.mojom"; import "third_party/blink/public/mojom/commit_result/commit_result.mojom"; import "third_party/blink/public/mojom/devtools/console_message.mojom"; @@ -513,7 +512,4 @@ // Sent by the renderer when the frame becomes focused. FrameFocused(); - - // Notifies the browser that the current frame has changed theme color. - DidChangeThemeColor(skia.mojom.SkColor? theme_color); };
diff --git a/content/common/media/cdm_info.cc b/content/common/media/cdm_info.cc index b1844062..c5480ec 100644 --- a/content/common/media/cdm_info.cc +++ b/content/common/media/cdm_info.cc
@@ -12,7 +12,7 @@ CdmCapability::CdmCapability( std::vector<media::VideoCodec> video_codecs, - base::flat_set<media::EncryptionMode> encryption_schemes, + base::flat_set<media::EncryptionScheme> encryption_schemes, base::flat_set<media::CdmSessionType> session_types, base::flat_set<media::CdmProxy::Protocol> cdm_proxy_protocols) : video_codecs(std::move(video_codecs)),
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index b50b87e4..227d4d91 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -230,7 +230,7 @@ const std::string& key_system, const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols, base::flat_set<media::VideoCodec>* video_codecs, - base::flat_set<media::EncryptionMode>* encryption_schemes) {} + base::flat_set<media::EncryptionScheme>* encryption_schemes) {} bool ContentBrowserClient::ShouldAssignSiteForURL(const GURL& url) { return true;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 3ff6710..f1c1cacb 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -87,7 +87,7 @@ namespace media { class AudioLogFactory; class AudioManager; -enum class EncryptionMode; +enum class EncryptionScheme; } // namespace media namespace network { @@ -1130,7 +1130,7 @@ const std::string& key_system, const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols, base::flat_set<media::VideoCodec>* video_codecs, - base::flat_set<media::EncryptionMode>* encryption_schemes); + base::flat_set<media::EncryptionScheme>* encryption_schemes); // Populates |mappings| with all files that need to be mapped before launching // a child process.
diff --git a/content/public/common/cdm_info.h b/content/public/common/cdm_info.h index 39b8da2..f8bcf527 100644 --- a/content/public/common/cdm_info.h +++ b/content/public/common/cdm_info.h
@@ -14,9 +14,7 @@ #include "base/version.h" #include "content/common/content_export.h" #include "media/base/content_decryption_module.h" -// TODO(crbug.com/825041): Move EncryptionMode out of decrypt_config and -// rename it to EncryptionScheme. -#include "media/base/decrypt_config.h" +#include "media/base/encryption_scheme.h" #include "media/base/video_codecs.h" #include "media/cdm/cdm_proxy.h" @@ -26,7 +24,7 @@ struct CONTENT_EXPORT CdmCapability { CdmCapability(); CdmCapability(std::vector<media::VideoCodec> video_codecs, - base::flat_set<media::EncryptionMode> encryption_schemes, + base::flat_set<media::EncryptionScheme> encryption_schemes, base::flat_set<media::CdmSessionType> session_types, base::flat_set<media::CdmProxy::Protocol> cdm_proxy_protocols); CdmCapability(const CdmCapability& other); @@ -46,7 +44,7 @@ bool supports_vp9_profile2 = false; // List of encryption schemes supported by the CDM (e.g. cenc). - base::flat_set<media::EncryptionMode> encryption_schemes; + base::flat_set<media::EncryptionScheme> encryption_schemes; // List of session types supported by the CDM. base::flat_set<media::CdmSessionType> session_types;
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc index 55886b2..48f18297 100644 --- a/content/renderer/pepper/video_decoder_shim.cc +++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -895,7 +895,7 @@ gfx::Size(32, 24), // Small sizes that won't fail. gfx::Rect(32, 24), gfx::Size(32, 24), // TODO(bbudge): Verify extra data isn't needed. - media::EmptyExtraData(), media::Unencrypted()); + media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted); media_task_runner_->PostTask( FROM_HERE, base::BindOnce(&VideoDecoderShim::DecoderImpl::Initialize,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 4d83bfa..0860a47a 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -4837,13 +4837,6 @@ render_view_->StartNavStateSyncTimerIfNecessary(this); } -void RenderFrameImpl::DidChangeThemeColor() { - if (frame_->Parent()) - return; - - GetFrameHost()->DidChangeThemeColor(frame_->GetDocument().ThemeColor()); -} - void RenderFrameImpl::ForwardResourceTimingToParent( const blink::WebResourceTimingInfo& info) { Send(new FrameHostMsg_ForwardResourceTimingToParent(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 07d02f7..b265913c 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -739,7 +739,6 @@ blink::WebHistoryCommitType commit_type, bool content_initiated) override; void DidUpdateCurrentHistoryItem() override; - void DidChangeThemeColor() override; void ForwardResourceTimingToParent( const blink::WebResourceTimingInfo& info) override; void DispatchLoad() override;
diff --git a/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win7.txt b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win7.txt new file mode 100644 index 0000000..583c4bb --- /dev/null +++ b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win7.txt
@@ -0,0 +1,5 @@ +document +++tree Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false +++++treeitem Name='card content' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false +++++group +++++treeitem Name='card content' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false \ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 97fe0a6..314eb2a 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -396,6 +396,9 @@ crbug.com/965209 [ mac nvidia-0xfe9 ] conformance2/samplers/multi-context-sampler-test.html [ RetryOnFailure ] crbug.com/756537 [ mac nvidia ] deqp/functional/gles3/shaderoperator/* [ Failure ] crbug.com/907599 [ mac nvidia debug ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ] +crbug.com/1022831 [ mac nvidia-0xfe9 ] deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html [ RetryOnFailure ] +crbug.com/1022831 [ mac nvidia-0xfe9 ] deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html [ RetryOnFailure ] +crbug.com/1022831 [ mac nvidia-0xfe9 ] deqp/functional/gles3/shaderloop_while.html [ RetryOnFailure ] # Mac AMD # TODO(kbr): uncomment the following two exepectations after test
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index c4d7a49..446aedc 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -194,9 +194,6 @@ void UpdateUserGestureCarryoverInfo() override {} #endif - void DidChangeThemeColor( - const base::Optional<::SkColor>& theme_color) override {} - private: std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> last_commit_params_;
diff --git a/device/vr/android/gvr/gvr_device.cc b/device/vr/android/gvr/gvr_device.cc index c1c7e59..b793ff71 100644 --- a/device/vr/android/gvr/gvr_device.cc +++ b/device/vr/android/gvr/gvr_device.cc
@@ -32,12 +32,11 @@ namespace { -// Default downscale factor for computing the recommended WebVR/WebXR +// Default downscale factor for computing the recommended WebXR // render_width/render_height from the 1:1 pixel mapped size. Using a rather // aggressive downscale due to the high overhead of copying pixels // twice before handing off to GVR. For comparison, the polyfill // uses approximately 0.55 on a Pixel XL. -static constexpr float kWebVrRecommendedResolutionScale = 0.5; static constexpr float kWebXrRecommendedResolutionScale = 0.7; // The scale factor for WebXR on devices that don't have shared buffer @@ -107,15 +106,6 @@ device->id = device_id; - device->capabilities = mojom::VRDisplayCapabilities::New(); - device->capabilities->has_position = false; - device->capabilities->has_external_display = false; - device->capabilities->can_present = true; - - std::string vendor = gvr_api->GetViewerVendor(); - std::string model = gvr_api->GetViewerModel(); - device->display_name = vendor + " " + model; - gvr::BufferViewportList gvr_buffer_viewports = gvr_api->CreateEmptyBufferViewportList(); gvr_buffer_viewports.SetToRecommendedBufferViewports(); @@ -135,7 +125,6 @@ device->webxr_default_framebuffer_scale = kWebXrNoSharedBufferResolutionScale; } - device->webvr_default_framebuffer_scale = kWebVrRecommendedResolutionScale; return device; } @@ -272,12 +261,6 @@ } } -void GvrDevice::EnsureInitialized(EnsureInitializedCallback callback) { - Init(base::BindOnce([](EnsureInitializedCallback callback, - bool) { std::move(callback).Run(); }, - std::move(callback))); -} - GvrDelegateProvider* GvrDevice::GetGvrDelegateProvider() { // GvrDelegateProviderFactory::Create() may return a different // pointer each time. Do not cache it.
diff --git a/device/vr/android/gvr/gvr_device.h b/device/vr/android/gvr/gvr_device.h index e44b9cb..1098092 100644 --- a/device/vr/android/gvr/gvr_device.h +++ b/device/vr/android/gvr/gvr_device.h
@@ -31,7 +31,6 @@ mojom::XRRuntime::RequestSessionCallback callback) override; void PauseTracking() override; void ResumeTracking() override; - void EnsureInitialized(EnsureInitializedCallback callback) override; void ShutdownSession(mojom::XRRuntime::ShutdownSessionCallback) override; void OnDisplayConfigurationChanged(
diff --git a/device/vr/oculus/oculus_device.cc b/device/vr/oculus/oculus_device.cc index eccbfbb..88930eb 100644 --- a/device/vr/oculus/oculus_device.cc +++ b/device/vr/oculus/oculus_device.cc
@@ -61,13 +61,6 @@ ovrSession session) { mojom::VRDisplayInfoPtr display_info = mojom::VRDisplayInfo::New(); display_info->id = id; - display_info->display_name = std::string("Oculus"); - display_info->capabilities = mojom::VRDisplayCapabilities::New(); - display_info->capabilities->has_position = true; - display_info->capabilities->has_external_display = true; - display_info->capabilities->can_present = true; - display_info->webvr_default_framebuffer_scale = 1.0; - display_info->webxr_default_framebuffer_scale = 1.0; ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); display_info->left_eye = GetEyeDetails(session, hmdDesc, ovrEye_Left); @@ -170,11 +163,6 @@ outstanding_session_requests_count_++; } -void OculusDevice::EnsureInitialized(EnsureInitializedCallback callback) { - EnsureValidDisplayInfo(); - std::move(callback).Run(); -} - bool OculusDevice::EnsureValidDisplayInfo() { // Ensure we have had a valid display_info set at least once. if (!have_real_display_info_) {
diff --git a/device/vr/oculus/oculus_device.h b/device/vr/oculus/oculus_device.h index 66c6210..87c1db7 100644 --- a/device/vr/oculus/oculus_device.h +++ b/device/vr/oculus/oculus_device.h
@@ -35,7 +35,6 @@ void RequestSession( mojom::XRRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) override; - void EnsureInitialized(EnsureInitializedCallback callback) override; void OnRequestSessionResult(mojom::XRRuntime::RequestSessionCallback callback, bool result, mojom::XRSessionPtr session);
diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc index 64af13f..62be26b02 100644 --- a/device/vr/openvr/openvr_device.cc +++ b/device/vr/openvr/openvr_device.cc
@@ -72,15 +72,6 @@ device::mojom::XRDeviceId id) { mojom::VRDisplayInfoPtr display_info = mojom::VRDisplayInfo::New(); display_info->id = id; - display_info->display_name = - GetOpenVRString(vr_system, vr::Prop_ManufacturerName_String) + " " + - GetOpenVRString(vr_system, vr::Prop_ModelNumber_String); - display_info->capabilities = mojom::VRDisplayCapabilities::New(); - display_info->capabilities->has_position = true; - display_info->capabilities->has_external_display = true; - display_info->capabilities->can_present = true; - display_info->webvr_default_framebuffer_scale = 1.0; - display_info->webxr_default_framebuffer_scale = 1.0; display_info->left_eye = mojom::VREyeParameters::New(); display_info->right_eye = mojom::VREyeParameters::New(); @@ -200,11 +191,6 @@ outstanding_session_requests_count_++; } -void OpenVRDevice::EnsureInitialized(EnsureInitializedCallback callback) { - EnsureValidDisplayInfo(); - std::move(callback).Run(); -} - bool OpenVRDevice::EnsureValidDisplayInfo() { // Ensure we have had a valid display_info set at least once. if (!have_real_display_info_) {
diff --git a/device/vr/openvr/openvr_device.h b/device/vr/openvr/openvr_device.h index 3741025..67bca0b 100644 --- a/device/vr/openvr/openvr_device.h +++ b/device/vr/openvr/openvr_device.h
@@ -38,7 +38,6 @@ void RequestSession( mojom::XRRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) override; - void EnsureInitialized(EnsureInitializedCallback callback) override; void OnPollingEvents();
diff --git a/device/vr/openxr/openxr_api_wrapper.cc b/device/vr/openxr/openxr_api_wrapper.cc index 4135a3a..98c8ef4 100644 --- a/device/vr/openxr/openxr_api_wrapper.cc +++ b/device/vr/openxr/openxr_api_wrapper.cc
@@ -21,8 +21,6 @@ namespace device { namespace { - -constexpr char kDefaultRuntimeName[] = "OpenXR"; constexpr XrSystemId kInvalidSystem = -1; // Only supported view configuration: constexpr XrViewConfigurationType kSupportedViewConfiguration = @@ -499,18 +497,6 @@ return xr_result; } -bool OpenXrApiWrapper::HasPosition() const { - DCHECK(IsInitialized()); - - XrSystemProperties system_properties = {XR_TYPE_SYSTEM_PROPERTIES}; - if (XR_SUCCEEDED( - xrGetSystemProperties(instance_, system_, &system_properties))) { - return system_properties.trackingProperties.positionTracking; - } - - return false; -} - // Returns the next predicted display time in nanoseconds. XrTime OpenXrApiWrapper::GetPredictedDisplayTime() const { DCHECK(IsInitialized()); @@ -652,17 +638,6 @@ ->recommendedSwapchainSampleCount; } -std::string OpenXrApiWrapper::GetRuntimeName() const { - DCHECK(HasInstance()); - - XrInstanceProperties instance_properties = {XR_TYPE_INSTANCE_PROPERTIES}; - if (XR_SUCCEEDED(xrGetInstanceProperties(instance_, &instance_properties))) { - return instance_properties.runtimeName; - } else { - return kDefaultRuntimeName; - } -} - // stage bounds is fixed unless we received event // XrEventDataReferenceSpaceChangePending XrResult OpenXrApiWrapper::UpdateStageBounds() {
diff --git a/device/vr/openxr/openxr_api_wrapper.h b/device/vr/openxr/openxr_api_wrapper.h index 092c2f041..f9766f0 100644 --- a/device/vr/openxr/openxr_api_wrapper.h +++ b/device/vr/openxr/openxr_api_wrapper.h
@@ -53,11 +53,9 @@ base::Optional<gfx::Point3F>* position) const; void GetHeadFromEyes(XrView* left, XrView* right) const; - bool HasPosition() const; gfx::Size GetViewSize() const; XrTime GetPredictedDisplayTime() const; XrResult GetLuid(LUID* luid) const; - std::string GetRuntimeName() const; bool GetStageParameters(XrExtent2Df* stage_bounds, gfx::Transform* local_from_stage); void RegisterInteractionProfileChangeCallback(
diff --git a/device/vr/openxr/openxr_device.cc b/device/vr/openxr/openxr_device.cc index f86d5336..f49d47b 100644 --- a/device/vr/openxr/openxr_device.cc +++ b/device/vr/openxr/openxr_device.cc
@@ -16,13 +16,6 @@ namespace { -constexpr char kDisplayName[] = "OpenXR"; - -constexpr bool kHasPosition = true; -constexpr bool kHasExternalDisplay = true; -constexpr bool kCanPresent = true; - -constexpr float kFramebufferScale = 1.0f; constexpr float kFov = 45.0f; constexpr unsigned int kRenderWidth = 1024; @@ -38,15 +31,6 @@ mojom::VRDisplayInfoPtr display_info = mojom::VRDisplayInfo::New(); display_info->id = id; - display_info->display_name = kDisplayName; - - display_info->capabilities = mojom::VRDisplayCapabilities::New(); - display_info->capabilities->has_position = kHasPosition; - display_info->capabilities->has_external_display = kHasExternalDisplay; - display_info->capabilities->can_present = kCanPresent; - - display_info->webvr_default_framebuffer_scale = kFramebufferScale; - display_info->webxr_default_framebuffer_scale = kFramebufferScale; display_info->left_eye = mojom::VREyeParameters::New(); display_info->right_eye = mojom::VREyeParameters::New();
diff --git a/device/vr/openxr/openxr_render_loop.cc b/device/vr/openxr/openxr_render_loop.cc index 34b2b4c..c49f012b 100644 --- a/device/vr/openxr/openxr_render_loop.cc +++ b/device/vr/openxr/openxr_render_loop.cc
@@ -150,22 +150,6 @@ } current_display_info_->id = device::mojom::XRDeviceId::OPENXR_DEVICE_ID; - current_display_info_->display_name = openxr_->GetRuntimeName(); - - current_display_info_->capabilities = mojom::VRDisplayCapabilities::New(); - current_display_info_->capabilities->can_provide_environment_integration = - false; - current_display_info_->capabilities->has_position = openxr_->HasPosition(); - - // OpenXR is initialized when creating the instance and getting the system - // was successful. If we are able to get a system, then we can present to - // an external display. - current_display_info_->capabilities->has_external_display = - openxr_->IsInitialized(); - current_display_info_->capabilities->can_present = openxr_->IsInitialized(); - - current_display_info_->webvr_default_framebuffer_scale = 1.0f; - current_display_info_->webxr_default_framebuffer_scale = 1.0f; gfx::Size view_size = openxr_->GetViewSize(); current_display_info_->left_eye->render_width = view_size.width();
diff --git a/device/vr/orientation/orientation_device.cc b/device/vr/orientation/orientation_device.cc index 201100d..cb959d2 100644 --- a/device/vr/orientation/orientation_device.cc +++ b/device/vr/orientation/orientation_device.cc
@@ -28,16 +28,8 @@ static constexpr int kDefaultPumpFrequencyHz = 60; mojom::VRDisplayInfoPtr CreateVRDisplayInfo(mojom::XRDeviceId id) { - static const char DEVICE_NAME[] = "VR Orientation Device"; - mojom::VRDisplayInfoPtr display_info = mojom::VRDisplayInfo::New(); display_info->id = id; - display_info->display_name = DEVICE_NAME; - display_info->capabilities = mojom::VRDisplayCapabilities::New(); - display_info->capabilities->has_position = false; - display_info->capabilities->has_external_display = false; - display_info->capabilities->can_present = false; - return display_info; }
diff --git a/device/vr/public/mojom/isolated_xr_service.mojom b/device/vr/public/mojom/isolated_xr_service.mojom index 163c9b4..53ae6eb0 100644 --- a/device/vr/public/mojom/isolated_xr_service.mojom +++ b/device/vr/public/mojom/isolated_xr_service.mojom
@@ -73,14 +73,6 @@ pending_associated_remote<XRRuntimeEventListener> listener) => (VRDisplayInfo? display_info); - // Ensure that the runtime has installed most prerequisites, and is ready to - // start. May result in updated display info being sent to registered - // listeners. RequestSession will fail if this hasn't been called. - // NOTE: When crbug.com/980000 is resolved, GvrDevice::EnsureInitialized - // won't install GVR runtime; it will be installed in - // GvrDevice::RequestSession(). - EnsureInitialized() => (); - SetInlinePosesEnabled(bool enable); };
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom index f8c86aa..32a556e 100644 --- a/device/vr/public/mojom/vr_service.mojom +++ b/device/vr/public/mojom/vr_service.mojom
@@ -223,20 +223,6 @@ gfx.mojom.Transform hit_matrix; }; -struct VRDisplayCapabilities { - bool has_position; - bool has_external_display; - - // Indicates whether the display can actively show imagery on a headset. - bool can_present; - - // Whether the display gathers data about the environment (for AR like - // planes, point clouds, meshes, etc.). The backend will decide whether - // it needs to provide camera frames or not based on whether it is a - // see-through HMD or camera-based AR system. - bool can_provide_environment_integration; -}; - // Information about the optical properties for an eye in a VRDisplay. struct VREyeParameters { VRFieldOfView field_of_view; @@ -266,14 +252,11 @@ struct VRDisplayInfo { XRDeviceId id; - string display_name; - VRDisplayCapabilities capabilities; VRStageParameters? stage_parameters; // Parameters required to distort a scene for viewing in a VR headset. Only // required for devices which have the can_present capability. VREyeParameters? left_eye; VREyeParameters? right_eye; - float webvr_default_framebuffer_scale = 1.0; float webxr_default_framebuffer_scale = 1.0; }; @@ -500,12 +483,6 @@ RequestSession(XRSessionOptions options) => (RequestSessionResult result); SupportsSession(XRSessionOptions options) => (bool supports_session); - // WebVR 1.1 functionality compatibility method. Returns VRDisplayInfo for an - // immersive session if immersive is supported. If (and only if) immersive is - // not supported, will return a nullptr. This call might cause device specific - // UI to appear. - GetImmersiveVRDisplayInfo() => (VRDisplayInfo? info); - // Shuts down an active immersive session. The callback is triggered // once teardown is complete and the system is again in a state where // a new immersive session could be started.
diff --git a/device/vr/test/fake_vr_device.cc b/device/vr/test/fake_vr_device.cc index bed7141..48fb681 100644 --- a/device/vr/test/fake_vr_device.cc +++ b/device/vr/test/fake_vr_device.cc
@@ -18,12 +18,6 @@ mojom::VRDisplayInfoPtr FakeVRDevice::InitBasicDevice() { mojom::VRDisplayInfoPtr display_info = mojom::VRDisplayInfo::New(); display_info->id = GetId(); - display_info->display_name = "FakeVRDevice"; - - display_info->capabilities = mojom::VRDisplayCapabilities::New(); - display_info->capabilities->has_position = false; - display_info->capabilities->has_external_display = false; - display_info->capabilities->can_present = false; display_info->left_eye = InitEye(45, -0.03f, 1024); display_info->right_eye = InitEye(45, 0.03f, 1024);
diff --git a/device/vr/vr_device_base.cc b/device/vr/vr_device_base.cc index dabda27..2abe5932 100644 --- a/device/vr/vr_device_base.cc +++ b/device/vr/vr_device_base.cc
@@ -80,10 +80,6 @@ return runtime_receiver_.BindNewPipeAndPassRemote(); } -void VRDeviceBase::EnsureInitialized(EnsureInitializedCallback callback) { - std::move(callback).Run(); -} - void VRDeviceBase::SetInlinePosesEnabled(bool enable) { inline_poses_enabled_ = enable; }
diff --git a/device/vr/vr_device_base.h b/device/vr/vr_device_base.h index feffa80b..c129b6e 100644 --- a/device/vr/vr_device_base.h +++ b/device/vr/vr_device_base.h
@@ -33,7 +33,6 @@ void ListenToDeviceChanges( mojo::PendingAssociatedRemote<mojom::XRRuntimeEventListener> listener, mojom::XRRuntime::ListenToDeviceChangesCallback callback) final; - void EnsureInitialized(EnsureInitializedCallback callback) override; void SetInlinePosesEnabled(bool enable) override; void ShutdownSession(mojom::XRRuntime::ShutdownSessionCallback) override;
diff --git a/device/vr/vr_device_base_unittest.cc b/device/vr/vr_device_base_unittest.cc index b1dde911..7a911a2 100644 --- a/device/vr/vr_device_base_unittest.cc +++ b/device/vr/vr_device_base_unittest.cc
@@ -79,7 +79,6 @@ mojom::VRDisplayInfoPtr MakeVRDisplayInfo(mojom::XRDeviceId device_id) { mojom::VRDisplayInfoPtr display_info = mojom::VRDisplayInfo::New(); display_info->id = device_id; - display_info->capabilities = mojom::VRDisplayCapabilities::New(); return display_info; }
diff --git a/device/vr/windows_mixed_reality/mixed_reality_device.cc b/device/vr/windows_mixed_reality/mixed_reality_device.cc index 64303fd9..fa44edd 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_device.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_device.cc
@@ -30,13 +30,6 @@ mojom::VRDisplayInfoPtr CreateFakeVRDisplayInfo(device::mojom::XRDeviceId id) { mojom::VRDisplayInfoPtr display_info = mojom::VRDisplayInfo::New(); display_info->id = id; - display_info->display_name = "Windows Mixed Reality"; - display_info->capabilities = mojom::VRDisplayCapabilities::New(); - display_info->capabilities->has_position = true; - display_info->capabilities->has_external_display = true; - display_info->capabilities->can_present = true; - display_info->webvr_default_framebuffer_scale = 1.0; - display_info->webxr_default_framebuffer_scale = 1.0; display_info->left_eye = mojom::VREyeParameters::New(); display_info->right_eye = mojom::VREyeParameters::New();
diff --git a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc index 2ca5c43..08cc332 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc
@@ -673,18 +673,6 @@ current_display_info_ = mojom::VRDisplayInfo::New(); current_display_info_->id = device::mojom::XRDeviceId::WINDOWS_MIXED_REALITY_ID; - current_display_info_->display_name = - "Windows Mixed Reality"; // TODO(billorr): share this string. - current_display_info_->capabilities = mojom::VRDisplayCapabilities::New( - true /* has_position */, true /* has_external_display */, - true /* can_present */, - false /* can_provide_environment_integration */); - - // TODO(billorr): consider scaling framebuffers after rendering support is - // added. - current_display_info_->webvr_default_framebuffer_scale = 1.0f; - current_display_info_->webxr_default_framebuffer_scale = 1.0f; - changed = true; }
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md index 556d939..dda0acc 100644 --- a/docs/windows_build_instructions.md +++ b/docs/windows_build_instructions.md
@@ -306,18 +306,29 @@ ```shell $ set NINJA_SUMMARIZE_BUILD=1 $ autoninja -C out\Default base - Longest build steps: -... - 1.2 weighted s to build base.dll, base.dll.lib, base.dll.pdb (1.2 s CPU time) - 8.5 weighted s to build obj/base/base/values.obj (30.1 s CPU time) - Time by build-step type: -... - 1.2 s weighted time to generate 1 PEFile (linking) files (1.2 s CPU time) - 30.3 s weighted time to generate 45 .obj files (688.8 s CPU time) - 31.8 s weighted time (693.8 s CPU time, 21.8x parallelism) - 86 build steps completed, average of 2.71/s +Longest build steps: + 0.1 weighted s to build obj/base/base/trace_log.obj (6.7 s elapsed time) + 0.2 weighted s to build nasm.exe, nasm.exe.pdb (0.2 s elapsed time) + 0.3 weighted s to build obj/base/base/win_util.obj (12.4 s elapsed time) + 1.2 weighted s to build base.dll, base.dll.lib (1.2 s elapsed time) +Time by build-step type: + 0.0 s weighted time to generate 6 .lib files (0.3 s elapsed time sum) + 0.1 s weighted time to generate 25 .stamp files (1.2 s elapsed time sum) + 0.2 s weighted time to generate 20 .o files (2.8 s elapsed time sum) + 1.7 s weighted time to generate 4 PEFile (linking) files (2.0 s elapsed +time sum) + 23.9 s weighted time to generate 770 .obj files (974.8 s elapsed time sum) +26.1 s weighted time (982.9 s elapsed time sum, 37.7x parallelism) +839 build steps completed, average of 32.17/s ``` +The "weighted" time is the elapsed time of each build step divided by the number +of tasks that were running in parallel. This makes it an excellent approximation +of how "important" a slow step was. A link that is entirely or mostly serialized +will have a weighted time that is the same or similar to its elapsed time. A +compile that runs in parallel with 999 other compiles will have a weighted time +that is tiny. + You can also generate these reports by manually running the script after a build: ```shell
diff --git a/extensions/common/image_util.cc b/extensions/common/image_util.cc index 0b2cd46a..e84bf58 100644 --- a/extensions/common/image_util.cc +++ b/extensions/common/image_util.cc
@@ -8,7 +8,6 @@ #include <stdint.h> #include <algorithm> -#include <vector> #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -65,9 +64,9 @@ formatted_color += color_string[i]; } } else if (color_string.length() == 7) { - formatted_color = color_string.substr(1, 6); + formatted_color.assign(color_string, 1, 6); } else if (color_string.length() == 9) { - formatted_color = color_string.substr(1, 8); + formatted_color.assign(color_string, 1, 8); } else { return false; } @@ -77,10 +76,9 @@ formatted_color += "FF"; } - // Convert the string to an integer and make sure it is in the correct value - // range. - std::vector<uint8_t> color_bytes; - if (!base::HexStringToBytes(formatted_color, &color_bytes)) + // Convert the hex string to an integer. + std::array<uint8_t, 4> color_bytes; + if (!base::HexStringToSpan(formatted_color, color_bytes)) return false; *result = SkColorSetARGB(color_bytes[3], color_bytes[0], color_bytes[1],
diff --git a/fuchsia/engine/renderer/web_engine_content_renderer_client.cc b/fuchsia/engine/renderer/web_engine_content_renderer_client.cc index c7a044b7..615b95a 100644 --- a/fuchsia/engine/renderer/web_engine_content_renderer_client.cc +++ b/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
@@ -89,8 +89,8 @@ } media::EmeConfigRule GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_mode) const override { - if (encryption_mode == ::media::EncryptionMode::kCenc) { + media::EncryptionScheme encryption_mode) const override { + if (encryption_mode == ::media::EncryptionScheme::kCenc) { return media::EmeConfigRule::SUPPORTED; } @@ -179,8 +179,8 @@ if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableWidevine)) { - base::flat_set<media::EncryptionMode> encryption_schemes{ - media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}; + base::flat_set<media::EncryptionScheme> encryption_schemes{ + media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs}; // Fuchsia always decrypts audio into clear buffers and return them back to // Chromium. Hardware secured decoders are only available for supported
diff --git a/infra/config/buckets/ci/goma.star b/infra/config/buckets/ci/goma.star index 4b2da61..6460cbc 100644 --- a/infra/config/buckets/ci/goma.star +++ b/infra/config/buckets/ci/goma.star
@@ -413,10 +413,12 @@ goma_builder( name = 'Chromium Android ARM 32-bit Goma RBE ToT', + goma_backend = goma.backend.RBE_TOT, ) goma_builder( name = 'Chromium Android ARM 32-bit Goma RBE ToT (ATS)', + goma_backend = goma.backend.RBE_TOT, goma_enable_ats = True, ) @@ -466,10 +468,12 @@ goma_builder( name = 'Chromium Linux Goma RBE ToT', + goma_backend = goma.backend.RBE_TOT, ) goma_builder( name = 'Chromium Linux Goma RBE ToT (ATS)', + goma_backend = goma.backend.RBE_TOT, goma_enable_ats = True, ) @@ -525,6 +529,7 @@ goma_mac_builder( name = 'Chromium Mac Goma RBE ToT', + goma_backend = goma.backend.RBE_TOT, ) goma_mac_builder( @@ -532,9 +537,10 @@ ) -def goma_windows_builder(*, name, goma_enable_ats=True, **kwargs): +def goma_windows_builder(*, name, goma_enable_ats=True, cores=32, **kwargs): return goma_builder( name = name, + cores = cores, goma_enable_ats = goma_enable_ats, os = os.WINDOWS_DEFAULT, **kwargs @@ -572,9 +578,11 @@ goma_windows_builder( name = 'Chromium Win Goma RBE ToT', + goma_backend = goma.backend.RBE_TOT, ) goma_windows_builder( name = 'CrWinGomaStaging', + cores = 8, goma_enable_ats = False, )
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 14057cd5..52e3a97 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -990,6 +990,7 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" + properties_j: "$build/goma:{\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.goma\"" > @@ -1009,7 +1010,7 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/goma:{\"enable_ats\":true}" + properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.goma\"" > @@ -1189,6 +1190,7 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" + properties_j: "$build/goma:{\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.goma\"" > @@ -1208,7 +1210,7 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/goma:{\"enable_ats\":true}" + properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.goma\"" > @@ -1327,7 +1329,7 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/goma:{\"jobs\":80}" + properties_j: "$build/goma:{\"jobs\":80,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.goma\"" > @@ -1360,7 +1362,7 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:Chromium Win Goma RBE Prod" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" recipe: < @@ -1380,7 +1382,7 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:Chromium Win Goma RBE Prod (clobber)" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" recipe: < @@ -1400,7 +1402,7 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:Chromium Win Goma RBE Prod (dbg)" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" recipe: < @@ -1420,7 +1422,7 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:Chromium Win Goma RBE Prod (dbg) (clobber)" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" recipe: < @@ -1440,7 +1442,7 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:Chromium Win Goma RBE Staging" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" recipe: < @@ -1460,7 +1462,7 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:Chromium Win Goma RBE Staging (clobber)" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" recipe: < @@ -1480,14 +1482,14 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:Chromium Win Goma RBE ToT" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" recipe: < name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/goma:{\"enable_ats\":true}" + properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.goma\"" >
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 639d057d..9f733a8 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -68,6 +68,10 @@ 'server_host': 'staging-goma.chromium.org', 'rpc_extra_params': '?staging', }, + RBE_TOT = { + 'server_host': 'staging-goma.chromium.org', + 'rpc_extra_params': '?tot', + }, ), jobs = struct( J50 = 50,
diff --git a/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json b/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json index b5eb025..2cc4d8b 100644 --- a/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json +++ b/ios/build/bots/chromium.fyi/ios13-sdk-simulator.json
@@ -141,22 +141,6 @@ "pool":"chromium.tests" }, { - "include": "eg_cq_tests.json", - "device type": "iPad Pro (12.9-inch)", - "os": "12.4", - "xcode build version": "11b44", - "host os": "Mac-10.14.6", - "pool":"chromium.tests" - }, - { - "include": "eg_tests.json", - "device type": "iPhone X", - "os": "12.4", - "xcode build version": "11b44", - "host os": "Mac-10.14.6", - "pool":"chromium.tests" - }, - { "include": "eg_tests.json", "device type": "iPad Air (3rd generation)", "os": "12.4",
diff --git a/ios/chrome/browser/ui/webui/BUILD.gn b/ios/chrome/browser/ui/webui/BUILD.gn index 943a0d9..2f4cf42 100644 --- a/ios/chrome/browser/ui/webui/BUILD.gn +++ b/ios/chrome/browser/ui/webui/BUILD.gn
@@ -137,11 +137,8 @@ "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support", - "//ios/web", - "//ios/web/public/test:element_selector", "//net:test_support", "//ui/base", - "//url", ] libs = [ "XCTest.framework" ] } @@ -155,15 +152,20 @@ testonly = true sources = [ "inspect/inspect_ui_egtest.mm", + "web_ui_egtest.mm", ] deps = [ "//base", + "//base/test:test_support", + "//components/strings", + "//components/version_info", "//ios/chrome/browser:chrome_url_constants", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", "//ios/web/public/test:element_selector", "//net:test_support", + "//ui/base", ] libs = [ "UIKit.framework" ] }
diff --git a/ios/chrome/browser/ui/webui/web_ui_egtest.mm b/ios/chrome/browser/ui/webui/web_ui_egtest.mm index 3f48fcb4..9621dae 100644 --- a/ios/chrome/browser/ui/webui/web_ui_egtest.mm +++ b/ios/chrome/browser/ui/webui/web_ui_egtest.mm
@@ -2,83 +2,62 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import <EarlGrey/EarlGrey.h> -#import <EarlGrey/GREYKeyboard.h> #import <XCTest/XCTest.h> #include "base/mac/foundation_util.h" #include "base/metrics/field_trial.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #import "base/test/ios/wait_util.h" +#include "components/strings/grit/components_strings.h" #include "components/version_info/version_info.h" #include "ios/chrome/browser/chrome_url_constants.h" -#include "ios/chrome/browser/system_flags.h" -#import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" -#import "ios/web/public/web_client.h" +#import "ios/testing/earl_grey/earl_grey_test.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/base/device_form_factor.h" #include "ui/base/l10n/l10n_util.h" -#include "url/scheme_host_port.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +using base::TrimPositions; using chrome_test_util::BackButton; using chrome_test_util::ForwardButton; +using chrome_test_util::OmniboxText; namespace { -// Loads WebUI page with given |host|. -void LoadWebUIUrl(const std::string& host) { - GURL web_ui_url(url::SchemeHostPort(kChromeUIScheme, host, 0).Serialize()); - [ChromeEarlGrey loadURL:web_ui_url]; +// Returns the url to the web ui page |host|. |url::SchemeHostPort| can not be +// used when this test is run using EarlGrey2 because the chrome scheme is not +// registered in the test process and |url::SchemeHostPort| will not build an +// invalid URL. +GURL WebUIPageUrlWithHost(const std::string& host) { + return GURL(base::StringPrintf("%s://%s", kChromeUIScheme, host.c_str())); } -// Adds wait for omnibox text matcher so that omnibox text can be updated. -// TODO(crbug.com/642207): This method has to be unified with the omniboxText -// matcher or resides in the same location with the omniboxText matcher. -id<GREYMatcher> WaitForOmniboxText(std::string text) { - MatchesBlock matches = ^BOOL(UIView* view) { - if (![view isKindOfClass:[OmniboxTextFieldIOS class]]) { - return NO; - } - OmniboxTextFieldIOS* omnibox = - base::mac::ObjCCast<OmniboxTextFieldIOS>(view); - GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( - base::test::ios::kWaitForUIElementTimeout, - ^{ - return base::SysNSStringToUTF8(omnibox.text) == text; - }), - @"Omnibox did not contain %@", base::SysUTF8ToNSString(text)); - return YES; - }; +// Waits for omnibox text to equal |URL| and returns true if it was found or +// false on timeout. Strips trailing URL slash if present as the omnibox does +// not display them. +bool WaitForOmniboxURLString(std::string URL) { + const std::string trimmed_URL = + base::TrimString(URL, "/", TrimPositions::TRIM_TRAILING).as_string(); - DescribeToBlock describe = ^(id<GREYDescription> description) { - [description appendText:@"omnibox text "]; - [description appendText:base::SysUTF8ToNSString(text)]; - }; - - return grey_allOf( - chrome_test_util::Omnibox(), - [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches - descriptionBlock:describe], - nil); -} - -// Validates that the experimental flags container is visible. -bool WebStateContainsChromeFlagsBody() { - NSError* error = nil; - id result = chrome_test_util::ExecuteJavaScript( - @"document.getElementById('body-container').style.visibility", &error); - if (error) - return false; - NSString* resultString = base::mac::ObjCCastStrict<NSString>(result); - return [@"visible" isEqualToString:resultString]; + // TODO(crbug.com/642207): Unify with the omniboxText matcher or move to the + // same location with the omniboxText matcher. + return base::test::ios::WaitUntilConditionOrTimeout( + base::test::ios::kWaitForUIElementTimeout, ^{ + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:OmniboxText(trimmed_URL)] + assertWithMatcher:grey_notNil() + error:&error]; + return error == nil; + }); } } // namespace @@ -92,22 +71,24 @@ // Tests that chrome://version renders and contains correct version number and // user agent string. - (void)testVersion { - LoadWebUIUrl(kChromeUIVersionHost); + [ChromeEarlGrey loadURL:WebUIPageUrlWithHost(kChromeUIVersionHost)]; // Verify that app version is present on the page. const std::string version = version_info::GetVersionNumber(); [ChromeEarlGrey waitForWebStateContainingText:version]; - // Verify that mobile User Agent string is present on the page. - const std::string userAgent = - web::GetWebClient()->GetUserAgent(web::UserAgentType::MOBILE); - [ChromeEarlGrey waitForWebStateContainingText:userAgent]; + // Verify that mobile User Agent string is present on the page. Testing for + // only a portion of the string is sufficient to ensure the value has been + // populated in the UI and it is not blank. However, the exact string value is + // not validated as this test does not have access to get the full User Agent + // string from the WebClient. + [ChromeEarlGrey waitForWebStateContainingText:"AppleWebKit"]; } // Tests that clicking on a chrome://terms link from chrome://chrome-urls // navigates to terms page. - (void)testChromeURLNavigateToTerms { - LoadWebUIUrl(kChromeUIChromeURLsHost); + [ChromeEarlGrey loadURL:WebUIPageUrlWithHost(kChromeUIChromeURLsHost)]; // Tap on chrome://terms link on the page. [ChromeEarlGrey @@ -115,8 +96,8 @@ stringWithUTF8String:kChromeUITermsHost]]; // Verify that the resulting page is chrome://terms. - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://terms")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUITermsURL), + @"Omnibox does not contain URL."); const std::string kTermsText = "Google Chrome Terms of Service"; [ChromeEarlGrey waitForWebStateContainingText:kTermsText]; } @@ -124,7 +105,7 @@ // Tests that back navigation functions properly after navigation via anchor // click. - (void)testChromeURLBackNavigationFromAnchorClick { - LoadWebUIUrl(kChromeUIChromeURLsHost); + [ChromeEarlGrey loadURL:GURL(kChromeUIChromeURLsURL)]; // Tap on chrome://version link on the page. [ChromeEarlGrey @@ -132,16 +113,15 @@ stringWithUTF8String:kChromeUIVersionHost]]; // Verify that the resulting page is chrome://version. - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://version")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), + @"Omnibox did not contain URL."); [ChromeEarlGrey waitForWebStateContainingText:"The Chromium Authors"]; // Tap the back button in the toolbar and verify that the resulting page is // the previously visited page chrome://chrome-urls. [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; - [[EarlGrey - selectElementWithMatcher:WaitForOmniboxText("chrome://chrome-urls")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIChromeURLsURL), + @"Omnibox did not contain URL."); [ChromeEarlGrey waitForWebStateContainingText:"List of Chrome URLs"]; } @@ -149,39 +129,37 @@ // properly. - (void)testChromeURLBackAndForwardAndReloadNavigation { // Navigate to the first URL chrome://version. - LoadWebUIUrl(kChromeUIVersionHost); + [ChromeEarlGrey loadURL:GURL(kChromeUIVersionURL)]; // Navigate to the second URL chrome://chrome-urls. - LoadWebUIUrl(kChromeUIChromeURLsHost); + [ChromeEarlGrey loadURL:GURL(kChromeUIChromeURLsURL)]; // Tap the back button in the toolbar and verify that the resulting page's URL // corresponds to the first URL chrome://version that was loaded. [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://version")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), + @"Omnibox did not contain URL."); // Tap the forward button in the toolbar and verify that the resulting page's // URL corresponds the second URL chrome://chrome-urls that was loaded. [[EarlGrey selectElementWithMatcher:ForwardButton()] performAction:grey_tap()]; - [[EarlGrey - selectElementWithMatcher:WaitForOmniboxText("chrome://chrome-urls")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIChromeURLsURL), + @"Omnibox did not contain URL."); // Tap the back button in the toolbar then reload, and verify that the // resulting page corresponds to the first URL. [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; [ChromeEarlGrey waitForPageToFinishLoading]; [ChromeEarlGrey reload]; - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://version")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), + @"Omnibox did not contain URL."); // Make sure forward navigation is still possible. [[EarlGrey selectElementWithMatcher:ForwardButton()] performAction:grey_tap()]; - [[EarlGrey - selectElementWithMatcher:WaitForOmniboxText("chrome://chrome-urls")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIChromeURLsURL), + @"Omnibox did not contain URL."); } // Tests that all URLs on chrome://chrome-urls page load without error. @@ -189,16 +167,15 @@ // Load WebUI pages and verify they load without any error. for (size_t i = 0; i < kNumberOfChromeHostURLs; ++i) { const char* host = kChromeHostURLs[i]; - // Exclude non-WebUI pages, as they do not go through a "loading" phase as - // expected in LoadWebUIUrl. + // Exclude non-WebUI pages, as they do not go through a "loading" phase. if (host == kChromeUINewTabHost) { continue; } - LoadWebUIUrl(host); - const std::string chrome_url_path = - url::SchemeHostPort(kChromeUIScheme, kChromeHostURLs[i], 0).Serialize(); - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText(chrome_url_path)] - assertWithMatcher:grey_notNil()]; + GURL URL = WebUIPageUrlWithHost(host); + [ChromeEarlGrey loadURL:URL]; + + GREYAssert(WaitForOmniboxURLString(URL.spec()), + @"Omnibox did not contain URL."); } } @@ -209,8 +186,8 @@ [ChromeEarlGrey loadURL:GURL(kChromeInvalidURL)]; // Verify that the resulting page is an error page. - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText(kChromeInvalidURL)] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeInvalidURL), + @"Omnibox did not contain URL."); std::string errorMessage = net::ErrorToShortString(net::ERR_INVALID_URL); [ChromeEarlGrey waitForWebStateContainingText:errorMessage]; } @@ -219,15 +196,13 @@ - (void)testBackForwardFromWebURL { GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); - // Not using kChromeUIVersionURL because it has a final "/" that is not - // displayed in Omnibox. - const char kChromeVersionURL[] = "chrome://version"; const char kChromeVersionWebText[] = "The Chromium Authors"; const char kWebPageText[] = "pony"; - LoadWebUIUrl(kChromeUIVersionHost); - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText(kChromeVersionURL)] - assertWithMatcher:grey_notNil()]; + [ChromeEarlGrey loadURL:GURL(kChromeUIVersionURL)]; + + GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), + @"Omnibox did not contain URL."); [ChromeEarlGrey waitForWebStateContainingText:kChromeVersionWebText]; GURL webURL = self.testServer->GetURL("/pony.html"); @@ -235,34 +210,35 @@ [ChromeEarlGrey waitForWebStateContainingText:kWebPageText]; [ChromeEarlGrey goBack]; - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText(kChromeVersionURL)] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), + @"Omnibox did not contain URL."); [ChromeEarlGrey waitForWebStateContainingText:kChromeVersionWebText]; [ChromeEarlGrey goForward]; [ChromeEarlGrey waitForWebStateContainingText:kWebPageText]; [ChromeEarlGrey goBack]; - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText(kChromeVersionURL)] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), + @"Omnibox did not contain URL."); [ChromeEarlGrey waitForWebStateContainingText:kChromeVersionWebText]; } - (void)testChromeFlagsOnNTP { // Start with NTP and load chrome://flags. - LoadWebUIUrl(kChromeUIFlagsHost); + [ChromeEarlGrey loadURL:GURL(kChromeUIFlagsURL)]; - // Not using kChromeUIFlagsHost because it has a final "/" that is not - // displayed in Omnibox. - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://flags")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIFlagsURL), + @"Omnibox did not contain URL."); // Validates that some of the expected text on the page exists. [ChromeEarlGrey waitForWebStateContainingText:"Experiments"]; [ChromeEarlGrey waitForWebStateContainingText:"Available"]; + // Validates that the experimental flags container is visible. - GREYAssert(WebStateContainsChromeFlagsBody(), - @"JavaScript error or body-container is not visible"); + NSString* flags_page_warning = + l10n_util::GetNSString(IDS_FLAGS_UI_PAGE_WARNING); + [ChromeEarlGrey waitForWebStateContainingText:base::SysNSStringToUTF8( + flags_page_warning)]; } - (void)testChromeFlagsOnWebsite { @@ -275,30 +251,27 @@ [ChromeEarlGrey waitForWebStateContainingText:kWebPageText]; // Then load chrome://flags in the same tab that has loaded a website. - LoadWebUIUrl(kChromeUIFlagsHost); + [ChromeEarlGrey loadURL:WebUIPageUrlWithHost(kChromeUIFlagsHost)]; - // Not using kChromeUIFlagsHost because it has a final "/" that is not - // displayed in Omnibox. - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://flags")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(kChromeUIFlagsURL), + @"Omnibox did not contain URL."); // Validates that some of the expected text on the page exists. [ChromeEarlGrey waitForWebStateContainingText:"Experiments"]; [ChromeEarlGrey waitForWebStateContainingText:"Available"]; - // Validates that the experimental flags container is visible. - GREYAssert(WebStateContainsChromeFlagsBody(), - @"JavaScript error or body-container is not visible"); + + NSString* flags_page_warning = + l10n_util::GetNSString(IDS_FLAGS_UI_PAGE_WARNING); + [ChromeEarlGrey waitForWebStateContainingText:base::SysNSStringToUTF8( + flags_page_warning)]; } - (void)testChromePasswordManagerInternalsSite { - LoadWebUIUrl(kChromeUIPasswordManagerInternalsHost); + GURL URL = WebUIPageUrlWithHost(kChromeUIPasswordManagerInternalsHost); + [ChromeEarlGrey loadURL:URL]; - // Not using kChromeUIPasswordManagerInternalsHost because it has a final "/" - // that is not displayed in Omnibox. - [[EarlGrey - selectElementWithMatcher:WaitForOmniboxText( - "chrome://password-manager-internals")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(URL.spec()), + @"Omnibox did not contain URL."); // Validates that some of the expected text on the page exists. [ChromeEarlGrey waitForWebStateContainingText:"Variations"]; @@ -306,13 +279,11 @@ } - (void)testChromeAutofillInternalsSite { - LoadWebUIUrl(kChromeUIAutofillInternalsHost); + GURL URL = WebUIPageUrlWithHost(kChromeUIAutofillInternalsHost); + [ChromeEarlGrey loadURL:URL]; - // Not using kChromeUIAutofillInternalsHost because it has a final "/" that - // is not displayed in Omnibox. - [[EarlGrey selectElementWithMatcher:WaitForOmniboxText( - "chrome://autofill-internals")] - assertWithMatcher:grey_notNil()]; + GREYAssert(WaitForOmniboxURLString(URL.spec()), + @"Omnibox did not contain URL."); // Validates that some of the expected text on the page exists. [ChromeEarlGrey waitForWebStateContainingText:"Variations"];
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 28a3bcf..5a4b392 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -150,8 +150,6 @@ "internal/language/web_view_language_model_manager_factory.mm", "internal/language/web_view_url_language_histogram_factory.h", "internal/language/web_view_url_language_histogram_factory.mm", - "internal/passwords/mock_credentials_filter.h", - "internal/passwords/mock_credentials_filter.mm", "internal/passwords/web_view_password_feature_manager.h", "internal/passwords/web_view_password_feature_manager.mm", "internal/passwords/web_view_password_manager_client.h",
diff --git a/ios/web_view/internal/app/application_context.mm b/ios/web_view/internal/app/application_context.mm index 536c6ee..cfae793 100644 --- a/ios/web_view/internal/app/application_context.mm +++ b/ios/web_view/internal/app/application_context.mm
@@ -72,7 +72,6 @@ void ApplicationContext::SaveState() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(crbug.com/723854): Commit prefs when entering background. if (local_state_) { local_state_->CommitPendingWrite(); }
diff --git a/ios/web_view/internal/autofill/cwv_credit_card_saver.mm b/ios/web_view/internal/autofill/cwv_credit_card_saver.mm index 10605849..a49f421 100644 --- a/ios/web_view/internal/autofill/cwv_credit_card_saver.mm +++ b/ios/web_view/internal/autofill/cwv_credit_card_saver.mm
@@ -113,7 +113,6 @@ _saveCompletionHandler = completionHandler; DCHECK(_uploadSaveCardCallback); - // TODO(crbug.com/993130): Provide additional card details if required. std::move(_uploadSaveCardCallback) .Run(autofill::AutofillClient::ACCEPTED, /*user_provided_card_details=*/{});
diff --git a/ios/web_view/internal/passwords/mock_credentials_filter.h b/ios/web_view/internal/passwords/mock_credentials_filter.h deleted file mode 100644 index 79f536d1..0000000 --- a/ios/web_view/internal/passwords/mock_credentials_filter.h +++ /dev/null
@@ -1,37 +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 IOS_WEB_VIEW_INTERNAL_PASSWORDS_MOCK_CREDENTIALS_FILTER_H_ -#define IOS_WEB_VIEW_INTERNAL_PASSWORDS_MOCK_CREDENTIALS_FILTER_H_ - -#include "base/macros.h" -#include "components/password_manager/core/browser/credentials_filter.h" - -namespace ios_web_view { - -// Mock of the CredentialsFilter API, to be used in tests. This filter does -// not filter out anything. -class MockCredentialsFilter : public password_manager::CredentialsFilter { - public: - MockCredentialsFilter(); - - ~MockCredentialsFilter() override; - - // CredentialsFilter - bool ShouldSave(const autofill::PasswordForm& form) const override; - bool ShouldSaveGaiaPasswordHash( - const autofill::PasswordForm& form) const override; - bool ShouldSaveEnterprisePasswordHash( - const autofill::PasswordForm& form) const override; - void ReportFormLoginSuccess( - const password_manager::PasswordFormManager& form_manager) const override; - bool IsSyncAccountEmail(const std::string& username) const override; - - private: - DISALLOW_COPY_AND_ASSIGN(MockCredentialsFilter); -}; - -} // namespace ios_web_view - -#endif // IOS_WEB_VIEW_INTERNAL_PASSWORDS_MOCK_CREDENTIALS_FILTER_H_
diff --git a/ios/web_view/internal/passwords/mock_credentials_filter.mm b/ios/web_view/internal/passwords/mock_credentials_filter.mm deleted file mode 100644 index a650253..0000000 --- a/ios/web_view/internal/passwords/mock_credentials_filter.mm +++ /dev/null
@@ -1,40 +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 "ios/web_view/internal/passwords/mock_credentials_filter.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace ios_web_view { - -MockCredentialsFilter::MockCredentialsFilter() = default; - -MockCredentialsFilter::~MockCredentialsFilter() = default; - -bool MockCredentialsFilter::ShouldSave( - const autofill::PasswordForm& form) const { - return true; -} - -bool MockCredentialsFilter::ShouldSaveGaiaPasswordHash( - const autofill::PasswordForm& form) const { - return false; -} - -bool MockCredentialsFilter::ShouldSaveEnterprisePasswordHash( - const autofill::PasswordForm& form) const { - return false; -} - -void MockCredentialsFilter::ReportFormLoginSuccess( - const password_manager::PasswordFormManager& form_manager) const {} - -bool MockCredentialsFilter::IsSyncAccountEmail( - const std::string& username) const { - return false; -} - -} // namespace ios_web_view
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.h b/ios/web_view/internal/passwords/web_view_password_manager_client.h index 7f182ff..05cc5831 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_client.h +++ b/ios/web_view/internal/passwords/web_view_password_manager_client.h
@@ -12,8 +12,8 @@ #import "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_client_helper.h" #include "components/password_manager/core/browser/password_manager_metrics_recorder.h" +#include "components/password_manager/core/browser/sync_credentials_filter.h" #include "components/prefs/pref_member.h" -#include "ios/web_view/internal/passwords/mock_credentials_filter.h" #include "ios/web_view/internal/passwords/web_view_password_feature_manager.h" namespace ios_web_view { @@ -125,8 +125,7 @@ // password_manager::prefs::kCredentialsEnableService. BooleanPrefMember saving_passwords_enabled_; - // TODO(crbug.com/867297) Replace with SyncCredentialsFilter - const MockCredentialsFilter credentials_filter_; + const password_manager::SyncCredentialsFilter credentials_filter_; std::unique_ptr<autofill::LogManager> log_manager_;
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.mm b/ios/web_view/internal/passwords/web_view_password_manager_client.mm index a8c25de89..bb28e55 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_client.mm +++ b/ios/web_view/internal/passwords/web_view_password_manager_client.mm
@@ -21,6 +21,8 @@ #include "ios/web_view/internal/app/application_context.h" #import "ios/web_view/internal/passwords/web_view_password_manager_log_router_factory.h" #include "ios/web_view/internal/passwords/web_view_password_store_factory.h" +#include "ios/web_view/internal/signin/web_view_identity_manager_factory.h" +#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h" #include "ios/web_view/internal/web_view_browser_state.h" #include "net/cert/cert_status_flags.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -35,14 +37,24 @@ using password_manager::PasswordStore; using password_manager::SyncState; -// TODO(crbug.com/867297): Support sync service and signin manager. +namespace { + +const syncer::SyncService* GetSyncService( + ios_web_view::WebViewBrowserState* browser_state) { + return ios_web_view::WebViewProfileSyncServiceFactory::GetForBrowserState( + browser_state); +} + +} // namespace namespace ios_web_view { -// TODO(crbug.com/867297): Replace with sync credentials filter. + WebViewPasswordManagerClient::WebViewPasswordManagerClient( id<CWVPasswordManagerClientDelegate> delegate) : delegate_(delegate), - credentials_filter_(), + credentials_filter_( + this, + base::BindRepeating(&GetSyncService, delegate_.browserState)), log_manager_(autofill::LogManager::Create( ios_web_view::WebViewPasswordManagerLogRouterFactory:: GetForBrowserState(delegate_.browserState), @@ -55,9 +67,9 @@ WebViewPasswordManagerClient::~WebViewPasswordManagerClient() = default; SyncState WebViewPasswordManagerClient::GetPasswordSyncState() const { - // Disable sync for Demo. - // TODO(crbug.com/867297): Enable sync. - return password_manager::NOT_SYNCING; + const syncer::SyncService* sync_service = + GetSyncService(delegate_.browserState); + return password_manager_util::GetPasswordSyncState(sync_service); } bool WebViewPasswordManagerClient::PromptUserToChooseCredentials( @@ -204,14 +216,13 @@ } signin::IdentityManager* WebViewPasswordManagerClient::GetIdentityManager() { - NOTREACHED(); - return nullptr; + return WebViewIdentityManagerFactory::GetForBrowserState( + delegate_.browserState); } scoped_refptr<network::SharedURLLoaderFactory> WebViewPasswordManagerClient::GetURLLoaderFactory() { - NOTREACHED(); - return nullptr; + return (delegate_.browserState)->GetSharedURLLoaderFactory(); } bool WebViewPasswordManagerClient::IsIsolationForPasswordSitesEnabled() const {
diff --git a/ios/web_view/internal/sync/web_view_sync_client.mm b/ios/web_view/internal/sync/web_view_sync_client.mm index 4aa731a..76bbc72c 100644 --- a/ios/web_view/internal/sync/web_view_sync_client.mm +++ b/ios/web_view/internal/sync/web_view_sync_client.mm
@@ -135,7 +135,7 @@ syncer::DataTypeController::TypeVector WebViewSyncClient::CreateDataTypeControllers( syncer::SyncService* sync_service) { - // iOS WebView uses butter sync and so has no need to record user consents. + // //ios/web_view clients are supposed to record their own consents. syncer::DataTypeController::TypeVector type_vector = component_factory_->CreateCommonDataTypeControllers(GetDisabledTypes(), sync_service);
diff --git a/ios/web_view/internal/web_view_web_main_parts.mm b/ios/web_view/internal/web_view_web_main_parts.mm index 9860c03..1539afc 100644 --- a/ios/web_view/internal/web_view_web_main_parts.mm +++ b/ios/web_view/internal/web_view_web_main_parts.mm
@@ -50,8 +50,11 @@ #if BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); - std::string enable_features = - base::JoinString({autofill::features::kAutofillUpstream.name}, ","); + std::string enable_features = base::JoinString( + {autofill::features::kAutofillUpstream.name, + autofill::features::kAutofillNoLocalSaveOnUploadSuccess.name, + autofill::features::kAutofillNoLocalSaveOnUnmaskSuccess.name}, + ","); std::string disabled_features = base::JoinString( {// Allows form_structure.cc to run heuristics on single field forms. // This is needed to find autofillable password forms with less than 3
diff --git a/ios/web_view/shell/shell_view_controller.m b/ios/web_view/shell/shell_view_controller.m index c820966..7060648 100644 --- a/ios/web_view/shell/shell_view_controller.m +++ b/ios/web_view/shell/shell_view_controller.m
@@ -339,6 +339,10 @@ message:message preferredStyle:UIAlertControllerStyleActionSheet]; for (CWVCreditCard* creditCard in creditCards) { + // Cards from Google Play can only be deleted on the Google Pay website. + if (creditCard.fromGooglePay) { + continue; + } NSString* title = [NSString stringWithFormat:@"Delete %@", @([creditCards indexOfObject:creditCard])]; @@ -350,6 +354,27 @@ }]; [alertController addAction:action]; } + __weak ShellViewController* weakSelf = self; + [alertController + addAction:[UIAlertAction + actionWithTitle:@"Manage Google pay cards" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction* action) { + __weak ShellViewController* strongSelf = + weakSelf; + NSString* URL; + if ([CWVFlags sharedInstance] + .usesSyncAndWalletSandbox) { + URL = @"https://pay.sandbox.google.com/" + @"payments/home#paymentMethods"; + } else { + URL = @"https://pay.google.com/payments/" + @"home#paymentMethods"; + } + NSURLRequest* request = [NSURLRequest + requestWithURL:[NSURL URLWithString:URL]]; + [strongSelf.webView loadRequest:request]; + }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"Done" style:UIAlertActionStyleCancel
diff --git a/media/audio/alive_checker.cc b/media/audio/alive_checker.cc index 66dce3d9..a369d464 100644 --- a/media/audio/alive_checker.cc +++ b/media/audio/alive_checker.cc
@@ -63,16 +63,17 @@ if (power_observer_helper_factory_callback.is_null()) { power_observer_ = std::make_unique<PowerObserverHelper>( task_runner_, base::DoNothing(), - base::Bind( + base::BindRepeating( &AliveChecker::SetLastAliveNotificationTimeToNowOnTaskRunner, base::Unretained(this))); } else { power_observer_ = std::move(power_observer_helper_factory_callback) .Run(task_runner_, base::DoNothing(), - base::Bind(&AliveChecker:: - SetLastAliveNotificationTimeToNowOnTaskRunner, - base::Unretained(this))); + base::BindRepeating( + &AliveChecker:: + SetLastAliveNotificationTimeToNowOnTaskRunner, + base::Unretained(this))); } } else { // If |pause_check_during_suspend| is false, we expect an empty factory
diff --git a/media/audio/audio_debug_file_writer.cc b/media/audio/audio_debug_file_writer.cc index 2f78df5..8fd566a 100644 --- a/media/audio/audio_debug_file_writer.cc +++ b/media/audio/audio_debug_file_writer.cc
@@ -289,8 +289,9 @@ file_task_runner_->PostTask( FROM_HERE, // Callback takes ownership of |data|: - base::Bind(&AudioFileWriter::Write, base::Unretained(file_writer_.get()), - base::Owned(data.release()))); + base::BindOnce(&AudioFileWriter::Write, + base::Unretained(file_writer_.get()), + base::Owned(data.release()))); } bool AudioDebugFileWriter::WillWrite() {
diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc index 1deb93a..26060207 100644 --- a/media/audio/audio_input_device.cc +++ b/media/audio/audio_input_device.cc
@@ -256,7 +256,7 @@ const bool pause_check_during_suspend = true; #endif alive_checker_ = std::make_unique<AliveChecker>( - base::Bind(&AudioInputDevice::DetectedDeadInputStream, this), + base::BindRepeating(&AudioInputDevice::DetectedDeadInputStream, this), base::TimeDelta::FromSeconds(kCheckMissingCallbacksIntervalSeconds), base::TimeDelta::FromSeconds(kMissingCallbacksTimeBeforeErrorSeconds), stop_at_first_alive_notification, pause_check_during_suspend);
diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc index 3763e79..ea9a28a5 100644 --- a/media/audio/audio_input_unittest.cc +++ b/media/audio/audio_input_unittest.cc
@@ -85,42 +85,35 @@ } void MakeAudioInputStreamOnAudioThread() { - RunOnAudioThread( - base::Bind(&AudioInputTest::MakeAudioInputStream, - base::Unretained(this))); + RunOnAudioThread(base::BindOnce(&AudioInputTest::MakeAudioInputStream, + base::Unretained(this))); } void CloseAudioInputStreamOnAudioThread() { - RunOnAudioThread( - base::Bind(&AudioInputStream::Close, - base::Unretained(audio_input_stream_))); + RunOnAudioThread(base::BindOnce(&AudioInputStream::Close, + base::Unretained(audio_input_stream_))); audio_input_stream_ = NULL; } void OpenAndCloseAudioInputStreamOnAudioThread() { RunOnAudioThread( - base::Bind(&AudioInputTest::OpenAndClose, - base::Unretained(this))); + base::BindOnce(&AudioInputTest::OpenAndClose, base::Unretained(this))); } void OpenStopAndCloseAudioInputStreamOnAudioThread() { - RunOnAudioThread( - base::Bind(&AudioInputTest::OpenStopAndClose, - base::Unretained(this))); + RunOnAudioThread(base::BindOnce(&AudioInputTest::OpenStopAndClose, + base::Unretained(this))); } void OpenAndStartAudioInputStreamOnAudioThread( AudioInputStream::AudioInputCallback* sink) { - RunOnAudioThread( - base::Bind(&AudioInputTest::OpenAndStart, - base::Unretained(this), - sink)); + RunOnAudioThread(base::BindOnce(&AudioInputTest::OpenAndStart, + base::Unretained(this), sink)); } void StopAndCloseAudioInputStreamOnAudioThread() { RunOnAudioThread( - base::Bind(&AudioInputTest::StopAndClose, - base::Unretained(this))); + base::BindOnce(&AudioInputTest::StopAndClose, base::Unretained(this))); } void MakeAudioInputStream() { @@ -163,9 +156,9 @@ } // Synchronously runs the provided callback/closure on the audio thread. - void RunOnAudioThread(const base::Closure& closure) { + void RunOnAudioThread(base::OnceClosure closure) { DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread()); - closure.Run(); + std::move(closure).Run(); } void OnLogMessage(const std::string& message) {}
diff --git a/media/audio/audio_low_latency_input_output_unittest.cc b/media/audio/audio_low_latency_input_output_unittest.cc index c1042cc..2fb5767 100644 --- a/media/audio/audio_low_latency_input_output_unittest.cc +++ b/media/audio/audio_low_latency_input_output_unittest.cc
@@ -253,7 +253,7 @@ const AudioParameters& params) { return audio_manager->MakeAudioInputStream( params, AudioDeviceDescription::kDefaultDeviceId, - base::Bind(&OnLogMessage)); + base::BindRepeating(&OnLogMessage)); } }; @@ -269,8 +269,8 @@ static StreamType* CreateStream(AudioManager* audio_manager, const AudioParameters& params) { - return audio_manager->MakeAudioOutputStream(params, std::string(), - base::Bind(&OnLogMessage)); + return audio_manager->MakeAudioOutputStream( + params, std::string(), base::BindRepeating(&OnLogMessage)); } };
diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc index 546a58b..5959825 100644 --- a/media/audio/audio_output_resampler.cc +++ b/media/audio/audio_output_resampler.cc
@@ -184,10 +184,11 @@ output_params_(output_params), original_output_params_(output_params), device_id_(output_device_id), - reinitialize_timer_(FROM_HERE, - close_delay_, - base::Bind(&AudioOutputResampler::Reinitialize, - base::Unretained(this))), + reinitialize_timer_( + FROM_HERE, + close_delay_, + base::BindRepeating(&AudioOutputResampler::Reinitialize, + base::Unretained(this))), register_debug_recording_source_callback_( register_debug_recording_source_callback) { DCHECK(audio_manager->GetTaskRunner()->BelongsToCurrentThread());
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index 247f0f8..a4733e86 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -414,7 +414,7 @@ if (is_android) { java_cpp_enum("java_enums") { sources = [ - "decrypt_config.h", + "encryption_scheme.h", "video_codecs.h", ] }
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java index 9d87a7599f2..54386a7 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
@@ -556,16 +556,16 @@ } } - // Incoming |native| values are as defined in media/base/decrypt_config.h. Translated values + // Incoming |native| values are as defined in media/base/encryption_scheme.h. Translated values // are from MediaCodec. At present, these values are in sync. Returns // MEDIA_CODEC_UNKNOWN_CIPHER_MODE in the case of unknown incoming value. - private int translateEncryptionModeValue(int nativeValue) { + private int translateEncryptionSchemeValue(int nativeValue) { switch (nativeValue) { - case EncryptionMode.UNENCRYPTED: + case EncryptionScheme.UNENCRYPTED: return MediaCodec.CRYPTO_MODE_UNENCRYPTED; - case EncryptionMode.CENC: + case EncryptionScheme.CENC: return MediaCodec.CRYPTO_MODE_AES_CTR; - case EncryptionMode.CBCS: + case EncryptionScheme.CBCS: return MediaCodec.CRYPTO_MODE_AES_CBC; default: Log.e(TAG, "Unsupported cipher mode: " + nativeValue); @@ -579,7 +579,7 @@ int[] numBytesOfClearData, int[] numBytesOfEncryptedData, int numSubSamples, int cipherMode, int patternEncrypt, int patternSkip, long presentationTimeUs) { try { - cipherMode = translateEncryptionModeValue(cipherMode); + cipherMode = translateEncryptionSchemeValue(cipherMode); if (cipherMode == MEDIA_CODEC_UNKNOWN_CIPHER_MODE) { return MediaCodecStatus.ERROR; }
diff --git a/media/base/android/media_codec_bridge.h b/media/base/android/media_codec_bridge.h index 86b02cb..f9cb49f 100644 --- a/media/base/android/media_codec_bridge.h +++ b/media/base/android/media_codec_bridge.h
@@ -14,9 +14,10 @@ #include "base/android/jni_android.h" #include "base/android/scoped_java_ref.h" #include "base/macros.h" +#include "base/optional.h" #include "base/time/time.h" -#include "media/base/decrypt_config.h" #include "media/base/encryption_pattern.h" +#include "media/base/encryption_scheme.h" #include "media/base/media_export.h" #include "ui/gfx/geometry/size.h" @@ -93,7 +94,7 @@ const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples, - EncryptionMode encryption_scheme, + EncryptionScheme encryption_scheme, base::Optional<EncryptionPattern> encryption_pattern, base::TimeDelta presentation_time) = 0;
diff --git a/media/base/android/media_codec_bridge_impl.cc b/media/base/android/media_codec_bridge_impl.cc index a5aa079..48350424 100644 --- a/media/base/android/media_codec_bridge_impl.cc +++ b/media/base/android/media_codec_bridge_impl.cc
@@ -416,7 +416,7 @@ const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples, - EncryptionMode encryption_scheme, + EncryptionScheme encryption_scheme, base::Optional<EncryptionPattern> encryption_pattern, base::TimeDelta presentation_time) { DVLOG(3) << __func__ << " " << index << ": " << data_size;
diff --git a/media/base/android/media_codec_bridge_impl.h b/media/base/android/media_codec_bridge_impl.h index ae44336..35c224c7 100644 --- a/media/base/android/media_codec_bridge_impl.h +++ b/media/base/android/media_codec_bridge_impl.h
@@ -121,7 +121,7 @@ const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples, - EncryptionMode encryption_scheme, + EncryptionScheme encryption_scheme, base::Optional<EncryptionPattern> encryption_pattern, base::TimeDelta presentation_time) override; void QueueEOS(int input_buffer_index) override;
diff --git a/media/base/android/media_codec_bridge_impl_unittest.cc b/media/base/android/media_codec_bridge_impl_unittest.cc index 8278cf1..60328e5 100644 --- a/media/base/android/media_codec_bridge_impl_unittest.cc +++ b/media/base/android/media_codec_bridge_impl_unittest.cc
@@ -281,7 +281,8 @@ int64_t codec_delay = 0) { AudioDecoderConfig config; config.Initialize(codec, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, - extra_data, Unencrypted(), seek_preroll, codec_delay); + extra_data, EncryptionScheme::kUnencrypted, seek_preroll, + codec_delay); return config; }
diff --git a/media/base/android/media_codec_loop.cc b/media/base/android/media_codec_loop.cc index 61b9a996..5722736 100644 --- a/media/base/android/media_codec_loop.cc +++ b/media/base/android/media_codec_loop.cc
@@ -197,7 +197,7 @@ media::MediaCodecStatus status = MEDIA_CODEC_OK; - if (input_data.encryption_scheme != EncryptionMode::kUnencrypted) { + if (input_data.encryption_scheme != EncryptionScheme::kUnencrypted) { // Note that input_data might not have a valid memory ptr if this is a // re-send of a buffer that was sent before decryption keys arrived.
diff --git a/media/base/android/media_codec_loop.h b/media/base/android/media_codec_loop.h index ebb8106..3eb0d81 100644 --- a/media/base/android/media_codec_loop.h +++ b/media/base/android/media_codec_loop.h
@@ -127,7 +127,7 @@ base::TimeDelta presentation_time; bool is_eos = false; - EncryptionMode encryption_scheme = EncryptionMode::kUnencrypted; + EncryptionScheme encryption_scheme = EncryptionScheme::kUnencrypted; base::Optional<EncryptionPattern> encryption_pattern; };
diff --git a/media/base/android/mock_media_codec_bridge.h b/media/base/android/mock_media_codec_bridge.h index a2e03978..85325f56 100644 --- a/media/base/android/mock_media_codec_bridge.h +++ b/media/base/android/mock_media_codec_bridge.h
@@ -43,7 +43,7 @@ const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples, - EncryptionMode encryption_scheme, + EncryptionScheme encryption_scheme, base::Optional<EncryptionPattern> encryption_pattern, base::TimeDelta presentation_time)); MOCK_METHOD1(QueueEOS, void(int input_buffer_index));
diff --git a/media/base/audio_decoder_config.cc b/media/base/audio_decoder_config.cc index f499bc5..27351dc2 100644 --- a/media/base/audio_decoder_config.cc +++ b/media/base/audio_decoder_config.cc
@@ -12,13 +12,12 @@ AudioDecoderConfig::AudioDecoderConfig() {} -AudioDecoderConfig::AudioDecoderConfig( - AudioCodec codec, - SampleFormat sample_format, - ChannelLayout channel_layout, - int samples_per_second, - const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme) { +AudioDecoderConfig::AudioDecoderConfig(AudioCodec codec, + SampleFormat sample_format, + ChannelLayout channel_layout, + int samples_per_second, + const std::vector<uint8_t>& extra_data, + EncryptionScheme encryption_scheme) { Initialize(codec, sample_format, channel_layout, samples_per_second, extra_data, encryption_scheme, base::TimeDelta(), 0); } @@ -31,7 +30,7 @@ ChannelLayout channel_layout, int samples_per_second, const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme, + EncryptionScheme encryption_scheme, base::TimeDelta seek_preroll, int codec_delay) { codec_ = codec; @@ -71,7 +70,7 @@ (channel_layout() == config.channel_layout()) && (samples_per_second() == config.samples_per_second()) && (extra_data() == config.extra_data()) && - (encryption_scheme().Matches(config.encryption_scheme())) && + (encryption_scheme() == config.encryption_scheme()) && (sample_format() == config.sample_format()) && (seek_preroll() == config.seek_preroll()) && (codec_delay() == config.codec_delay()) && @@ -109,16 +108,17 @@ void AudioDecoderConfig::SetIsEncrypted(bool is_encrypted) { if (!is_encrypted) { - DCHECK(encryption_scheme_.is_encrypted()) << "Config is already clear."; - encryption_scheme_ = Unencrypted(); + DCHECK_NE(encryption_scheme_, EncryptionScheme::kUnencrypted) + << "Config is already clear."; + encryption_scheme_ = EncryptionScheme::kUnencrypted; } else { - DCHECK(!encryption_scheme_.is_encrypted()) + DCHECK_EQ(encryption_scheme_, EncryptionScheme::kUnencrypted) << "Config is already encrypted."; // TODO(xhwang): This is only used to guide decoder selection, so set // a common encryption scheme that should be supported by all decrypting // decoders. We should be able to remove this when we support switching // decoders at run time. See http://crbug.com/695595 - encryption_scheme_ = AesCtrEncryptionScheme(); + encryption_scheme_ = EncryptionScheme::kCenc; } }
diff --git a/media/base/audio_decoder_config.h b/media/base/audio_decoder_config.h index b251bf7..a7f294d 100644 --- a/media/base/audio_decoder_config.h +++ b/media/base/audio_decoder_config.h
@@ -35,7 +35,7 @@ ChannelLayout channel_layout, int samples_per_second, const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme); + EncryptionScheme encryption_scheme); AudioDecoderConfig(const AudioDecoderConfig& other); @@ -47,7 +47,7 @@ ChannelLayout channel_layout, int samples_per_second, const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme, + EncryptionScheme encryption_scheme, base::TimeDelta seek_preroll, int codec_delay); @@ -83,12 +83,12 @@ // Whether the audio stream is potentially encrypted. // Note that in a potentially encrypted audio stream, individual buffers // can be encrypted or not encrypted. - bool is_encrypted() const { return encryption_scheme_.is_encrypted(); } + bool is_encrypted() const { + return encryption_scheme_ != EncryptionScheme::kUnencrypted; + } // Encryption scheme used for encrypted buffers. - const EncryptionScheme& encryption_scheme() const { - return encryption_scheme_; - } + EncryptionScheme encryption_scheme() const { return encryption_scheme_; } // Sets the config to be encrypted or not encrypted manually. This can be // useful for decryptors that decrypts an encrypted stream to a clear stream. @@ -119,7 +119,7 @@ int samples_per_second_ = 0; int bytes_per_frame_ = 0; std::vector<uint8_t> extra_data_; - EncryptionScheme encryption_scheme_; + EncryptionScheme encryption_scheme_ = EncryptionScheme::kUnencrypted; // Layout and count of the *stream* being decoded. ChannelLayout channel_layout_ = CHANNEL_LAYOUT_UNSUPPORTED;
diff --git a/media/base/bitstream_buffer.h b/media/base/bitstream_buffer.h index ca5333a6..9280c80 100644 --- a/media/base/bitstream_buffer.h +++ b/media/base/bitstream_buffer.h
@@ -76,7 +76,7 @@ scoped_refptr<DecoderBuffer> ToDecoderBuffer(); // TODO(crbug.com/813845): As this is only used by Android, include - // EncryptionMode and optional EncryptionPattern when updating for Android. + // EncryptionScheme and optional EncryptionPattern when updating for Android. void SetDecryptionSettings(const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples);
diff --git a/media/base/decrypt_config.cc b/media/base/decrypt_config.cc index 385e159..ce994949 100644 --- a/media/base/decrypt_config.cc +++ b/media/base/decrypt_config.cc
@@ -13,29 +13,12 @@ namespace media { -namespace { - -const char* EncryptionModeAsString(EncryptionMode mode) { - switch (mode) { - case EncryptionMode::kUnencrypted: - return "Unencrypted"; - case EncryptionMode::kCenc: - return "CENC"; - case EncryptionMode::kCbcs: - return "CBCS"; - default: - return "Unknown"; - } -} - -} // namespace - // static std::unique_ptr<DecryptConfig> DecryptConfig::CreateCencConfig( const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples) { - return std::make_unique<DecryptConfig>(EncryptionMode::kCenc, key_id, iv, + return std::make_unique<DecryptConfig>(EncryptionScheme::kCenc, key_id, iv, subsamples, base::nullopt); } @@ -45,29 +28,29 @@ const std::string& iv, const std::vector<SubsampleEntry>& subsamples, base::Optional<EncryptionPattern> encryption_pattern) { - return std::make_unique<DecryptConfig>(EncryptionMode::kCbcs, key_id, iv, + return std::make_unique<DecryptConfig>(EncryptionScheme::kCbcs, key_id, iv, subsamples, std::move(encryption_pattern)); } DecryptConfig::DecryptConfig( - const EncryptionMode& encryption_mode, + EncryptionScheme encryption_scheme, const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples, base::Optional<EncryptionPattern> encryption_pattern) - : encryption_mode_(encryption_mode), + : encryption_scheme_(encryption_scheme), key_id_(key_id), iv_(iv), subsamples_(subsamples), encryption_pattern_(std::move(encryption_pattern)) { // Unencrypted blocks should not have a DecryptConfig. - DCHECK_NE(encryption_mode_, EncryptionMode::kUnencrypted); + DCHECK_NE(encryption_scheme_, EncryptionScheme::kUnencrypted); CHECK_GT(key_id_.size(), 0u); CHECK_EQ(iv_.size(), static_cast<size_t>(DecryptConfig::kDecryptionKeySize)); - // Pattern not allowed for non-'cbcs' modes. - DCHECK(encryption_mode_ == EncryptionMode::kCbcs || !encryption_pattern_); + // Pattern not allowed for non-'cbcs' schemes. + DCHECK(encryption_scheme_ == EncryptionScheme::kCbcs || !encryption_pattern_); } DecryptConfig::~DecryptConfig() = default; @@ -79,7 +62,7 @@ std::unique_ptr<DecryptConfig> DecryptConfig::CopyNewSubsamplesIV( const std::vector<SubsampleEntry>& subsamples, const std::string& iv) { - return std::make_unique<DecryptConfig>(encryption_mode_, key_id_, iv, + return std::make_unique<DecryptConfig>(encryption_scheme_, key_id_, iv, subsamples, encryption_pattern_); } @@ -90,7 +73,7 @@ bool DecryptConfig::Matches(const DecryptConfig& config) const { if (key_id() != config.key_id() || iv() != config.iv() || subsamples().size() != config.subsamples().size() || - encryption_mode_ != config.encryption_mode_ || + encryption_scheme_ != config.encryption_scheme_ || encryption_pattern_ != config.encryption_pattern_) { return false; } @@ -108,7 +91,7 @@ std::ostream& DecryptConfig::Print(std::ostream& os) const { os << "key_id:'" << base::HexEncode(key_id_.data(), key_id_.size()) << "'" << " iv:'" << base::HexEncode(iv_.data(), iv_.size()) << "'" - << " mode:" << EncryptionModeAsString(encryption_mode_); + << " scheme:" << encryption_scheme_; if (encryption_pattern_) { os << " pattern:" << encryption_pattern_->crypt_byte_block() << ":"
diff --git a/media/base/decrypt_config.h b/media/base/decrypt_config.h index cdc4c21..79905419 100644 --- a/media/base/decrypt_config.h +++ b/media/base/decrypt_config.h
@@ -15,21 +15,12 @@ #include "base/macros.h" #include "base/optional.h" #include "media/base/encryption_pattern.h" +#include "media/base/encryption_scheme.h" #include "media/base/media_export.h" #include "media/base/subsample_entry.h" namespace media { -// The encryption mode. The definitions are from ISO/IEC 23001-7:2016. -// TODO(crbug.com/825041): Merge this with existing media::EncryptionScheme. -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media -enum class EncryptionMode { - kUnencrypted = 0, - kCenc, // 'cenc' subsample encryption using AES-CTR mode. - kCbcs, // 'cbcs' pattern encryption using AES-CBC mode. - kMaxValue = kCbcs -}; - // Contains all information that a decryptor needs to decrypt a media sample. class MEDIA_EXPORT DecryptConfig { public: @@ -58,7 +49,7 @@ const std::vector<SubsampleEntry>& subsamples, base::Optional<EncryptionPattern> encryption_pattern); - DecryptConfig(const EncryptionMode& encryption_mode, + DecryptConfig(EncryptionScheme encryption_scheme, const std::string& key_id, const std::string& iv, const std::vector<SubsampleEntry>& subsamples, @@ -68,7 +59,7 @@ const std::string& key_id() const { return key_id_; } const std::string& iv() const { return iv_; } const std::vector<SubsampleEntry>& subsamples() const { return subsamples_; } - const EncryptionMode& encryption_mode() const { return encryption_mode_; } + EncryptionScheme encryption_scheme() const { return encryption_scheme_; } const base::Optional<EncryptionPattern>& encryption_pattern() const { return encryption_pattern_; } @@ -93,7 +84,7 @@ private: DecryptConfig(const DecryptConfig& other); - const EncryptionMode encryption_mode_; + const EncryptionScheme encryption_scheme_; const std::string key_id_; // Initialization vector.
diff --git a/media/base/decrypt_config_unittest.cc b/media/base/decrypt_config_unittest.cc index a42266d..e39d7a7 100644 --- a/media/base/decrypt_config_unittest.cc +++ b/media/base/decrypt_config_unittest.cc
@@ -26,7 +26,7 @@ EXPECT_EQ(config->key_id(), kDefaultKeyId); EXPECT_EQ(config->iv(), kDefaultIV); EXPECT_EQ(config->subsamples().size(), 0u); - EXPECT_EQ(config->encryption_mode(), EncryptionMode::kCenc); + EXPECT_EQ(config->encryption_scheme(), EncryptionScheme::kCenc); // Now with single subsample entry. config = @@ -36,7 +36,7 @@ EXPECT_EQ(config->subsamples().size(), 1u); EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u); EXPECT_EQ(config->subsamples()[0].cypher_bytes, 2u); - EXPECT_EQ(config->encryption_mode(), EncryptionMode::kCenc); + EXPECT_EQ(config->encryption_scheme(), EncryptionScheme::kCenc); // Now with multiple subsample entries. config = DecryptConfig::CreateCencConfig(kDefaultKeyId, kAlternateIV, @@ -46,7 +46,7 @@ EXPECT_EQ(config->subsamples().size(), 4u); EXPECT_EQ(config->subsamples()[1].clear_bytes, 3u); EXPECT_EQ(config->subsamples()[3].cypher_bytes, 8u); - EXPECT_EQ(config->encryption_mode(), EncryptionMode::kCenc); + EXPECT_EQ(config->encryption_scheme(), EncryptionScheme::kCenc); } TEST(DecryptConfigTest, CbcsConstruction) { @@ -55,7 +55,7 @@ EXPECT_EQ(config->key_id(), kDefaultKeyId); EXPECT_EQ(config->iv(), kDefaultIV); EXPECT_EQ(config->subsamples().size(), 0u); - EXPECT_EQ(config->encryption_mode(), EncryptionMode::kCbcs); + EXPECT_EQ(config->encryption_scheme(), EncryptionScheme::kCbcs); EXPECT_TRUE(config->HasPattern()); EXPECT_EQ(config->encryption_pattern()->crypt_byte_block(), 1u); EXPECT_EQ(config->encryption_pattern()->skip_byte_block(), 2u); @@ -71,7 +71,7 @@ EXPECT_EQ(config->subsamples()[0].cypher_bytes, 2u); EXPECT_EQ(config->subsamples()[3].clear_bytes, 7u); EXPECT_EQ(config->subsamples()[3].cypher_bytes, 8u); - EXPECT_EQ(config->encryption_mode(), EncryptionMode::kCbcs); + EXPECT_EQ(config->encryption_scheme(), EncryptionScheme::kCbcs); EXPECT_TRUE(config->HasPattern()); EXPECT_EQ(config->encryption_pattern()->crypt_byte_block(), 1u); EXPECT_EQ(config->encryption_pattern()->skip_byte_block(), 0u); @@ -84,7 +84,7 @@ EXPECT_EQ(config->subsamples().size(), 1u); EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u); EXPECT_EQ(config->subsamples()[0].cypher_bytes, 2u); - EXPECT_EQ(config->encryption_mode(), EncryptionMode::kCbcs); + EXPECT_EQ(config->encryption_scheme(), EncryptionScheme::kCbcs); EXPECT_FALSE(config->HasPattern()); }
diff --git a/media/base/encryption_scheme.cc b/media/base/encryption_scheme.cc index d20fbf4..40de184 100644 --- a/media/base/encryption_scheme.cc +++ b/media/base/encryption_scheme.cc
@@ -10,46 +10,17 @@ namespace media { -EncryptionScheme::EncryptionScheme() = default; - -EncryptionScheme::EncryptionScheme(CipherMode mode, - const EncryptionPattern& pattern) - : mode_(mode), pattern_(pattern) {} - -EncryptionScheme::~EncryptionScheme() = default; - -bool EncryptionScheme::is_encrypted() const { - return mode_ != CIPHER_MODE_UNENCRYPTED; -} - -EncryptionScheme::CipherMode EncryptionScheme::mode() const { - return mode_; -} - -const EncryptionPattern& EncryptionScheme::pattern() const { - return pattern_; -} - -bool EncryptionScheme::Matches(const EncryptionScheme& other) const { - return mode_ == other.mode_ && pattern_ == other.pattern_; -} - -std::ostream& operator<<(std::ostream& os, - const EncryptionScheme& encryption_scheme) { - if (!encryption_scheme.is_encrypted()) - return os << "Unencrypted"; - - if (encryption_scheme.mode() == EncryptionScheme::CIPHER_MODE_AES_CTR) - return os << "CENC"; - - if (encryption_scheme.mode() == EncryptionScheme::CIPHER_MODE_AES_CBC) { - return os << "CBCS with pattern (" - << encryption_scheme.pattern().crypt_byte_block() << "," - << encryption_scheme.pattern().skip_byte_block() << ")"; +std::ostream& operator<<(std::ostream& os, EncryptionScheme scheme) { + switch (scheme) { + case EncryptionScheme::kUnencrypted: + return os << "Unencrypted"; + case EncryptionScheme::kCenc: + return os << "CENC"; + case EncryptionScheme::kCbcs: + return os << "CBCS"; + default: + return os << "Unknown"; } - - NOTREACHED(); - return os << "Unknown EncryptionScheme, mode = " << encryption_scheme.mode(); } } // namespace media
diff --git a/media/base/encryption_scheme.h b/media/base/encryption_scheme.h index 420f4e7..00bd931 100644 --- a/media/base/encryption_scheme.h +++ b/media/base/encryption_scheme.h
@@ -5,51 +5,24 @@ #ifndef MEDIA_BASE_ENCRYPTION_SCHEME_H_ #define MEDIA_BASE_ENCRYPTION_SCHEME_H_ -#include <stdint.h> - #include <iosfwd> -#include "media/base/encryption_pattern.h" #include "media/base/media_export.h" namespace media { -// Specification of whether and how the stream is encrypted (in whole or part). -class MEDIA_EXPORT EncryptionScheme { - public: - // Algorithm and mode used for encryption. CIPHER_MODE_UNENCRYPTED indicates - // no encryption. - enum CipherMode { - CIPHER_MODE_UNENCRYPTED, - CIPHER_MODE_AES_CTR, - CIPHER_MODE_AES_CBC, - CIPHER_MODE_MAX = CIPHER_MODE_AES_CBC - }; - - // The default constructor makes an instance that indicates no encryption. - EncryptionScheme(); - - // This constructor allows specification of the cipher mode and the pattern. - EncryptionScheme(CipherMode mode, const EncryptionPattern& pattern); - ~EncryptionScheme(); - - bool Matches(const EncryptionScheme& other) const; - - bool is_encrypted() const; - CipherMode mode() const; - const EncryptionPattern& pattern() const; - - private: - CipherMode mode_ = CIPHER_MODE_UNENCRYPTED; - EncryptionPattern pattern_; - - // Allow copy and assignment. +// The encryption mode. The definitions are from ISO/IEC 23001-7:2016. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media +enum class EncryptionScheme { + kUnencrypted = 0, + kCenc, // 'cenc' subsample encryption using AES-CTR mode. + kCbcs, // 'cbcs' pattern encryption using AES-CBC mode. + kMaxValue = kCbcs }; // For logging use only. -MEDIA_EXPORT std::ostream& operator<<( - std::ostream& os, - const EncryptionScheme& encryption_scheme); +MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, + EncryptionScheme encryption_scheme); } // namespace media
diff --git a/media/base/fake_demuxer_stream.cc b/media/base/fake_demuxer_stream.cc index 5a6526a..dac0819 100644 --- a/media/base/fake_demuxer_stream.cc +++ b/media/base/fake_demuxer_stream.cc
@@ -165,7 +165,7 @@ VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, next_coded_size_, kVisibleRect, next_coded_size_, EmptyExtraData(), - is_encrypted_ ? AesCtrEncryptionScheme() : Unencrypted()); + is_encrypted_ ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted); next_coded_size_.Enlarge(kWidthDelta, kHeightDelta); }
diff --git a/media/base/ipc/media_param_traits.cc b/media/base/ipc/media_param_traits.cc index 64db44e7..46c977a7 100644 --- a/media/base/ipc/media_param_traits.cc +++ b/media/base/ipc/media_param_traits.cc
@@ -113,28 +113,6 @@ static void Log(const param_type& p, std::string* l); }; -void ParamTraits<media::EncryptionScheme>::Write(base::Pickle* m, - const param_type& p) { - WriteParam(m, p.mode()); - WriteParam(m, p.pattern()); -} - -bool ParamTraits<media::EncryptionScheme>::Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r) { - media::EncryptionScheme::CipherMode mode; - media::EncryptionPattern pattern; - if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &pattern)) - return false; - *r = media::EncryptionScheme(mode, pattern); - return true; -} - -void ParamTraits<media::EncryptionScheme>::Log(const param_type& p, - std::string* l) { - l->append(base::StringPrintf("<EncryptionScheme>")); -} - void ParamTraits<media::EncryptionPattern>::Write(base::Pickle* m, const param_type& p) { WriteParam(m, p.crypt_byte_block());
diff --git a/media/base/ipc/media_param_traits.h b/media/base/ipc/media_param_traits.h index b4205f5..4771d463 100644 --- a/media/base/ipc/media_param_traits.h +++ b/media/base/ipc/media_param_traits.h
@@ -11,7 +11,6 @@ namespace media { class AudioParameters; -class EncryptionScheme; } namespace IPC { @@ -36,16 +35,6 @@ static void Log(const param_type& p, std::string* l); }; -template <> -struct ParamTraits<media::EncryptionScheme> { - typedef media::EncryptionScheme param_type; - static void Write(base::Pickle* m, const param_type& p); - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r); - static void Log(const param_type& p, std::string* l); -}; - } // namespace IPC #endif // MEDIA_BASE_IPC_MEDIA_PARAM_TRAITS_H_
diff --git a/media/base/ipc/media_param_traits_macros.h b/media/base/ipc/media_param_traits_macros.h index 966177e..805726b 100644 --- a/media/base/ipc/media_param_traits_macros.h +++ b/media/base/ipc/media_param_traits_macros.h
@@ -104,11 +104,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(media::EmeInitDataType, media::EmeInitDataType::MAX) -IPC_ENUM_TRAITS_MAX_VALUE(media::EncryptionMode, - media::EncryptionMode::kMaxValue) - -IPC_ENUM_TRAITS_MAX_VALUE(media::EncryptionScheme::CipherMode, - media::EncryptionScheme::CipherMode::CIPHER_MODE_MAX) +IPC_ENUM_TRAITS_MAX_VALUE(media::EncryptionScheme, + media::EncryptionScheme::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(media::HdcpVersion, media::HdcpVersion::kHdcpVersionMax)
diff --git a/media/base/key_system_properties.h b/media/base/key_system_properties.h index c61b903..b8f1695 100644 --- a/media/base/key_system_properties.h +++ b/media/base/key_system_properties.h
@@ -28,7 +28,7 @@ // Returns the configuration rule for supporting |encryption_scheme|. virtual EmeConfigRule GetEncryptionSchemeConfigRule( - EncryptionMode encryption_scheme) const = 0; + EncryptionScheme encryption_scheme) const = 0; // Returns the codecs supported by this key system. virtual SupportedCodecs GetSupportedCodecs() const = 0;
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index 82c00b09..88cb98d 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc
@@ -134,12 +134,12 @@ } media::EmeConfigRule GetEncryptionSchemeConfigRule( - media::EncryptionMode encryption_scheme) const override { + media::EncryptionScheme encryption_scheme) const override { switch (encryption_scheme) { - case media::EncryptionMode::kCenc: - case media::EncryptionMode::kCbcs: + case media::EncryptionScheme::kCenc: + case media::EncryptionScheme::kCbcs: return media::EmeConfigRule::SUPPORTED; - case media::EncryptionMode::kUnencrypted: + case media::EncryptionScheme::kUnencrypted: break; } NOTREACHED(); @@ -251,7 +251,7 @@ EmeConfigRule GetEncryptionSchemeConfigRule( const std::string& key_system, - EncryptionMode encryption_scheme) const override; + EncryptionScheme encryption_scheme) const override; EmeConfigRule GetContentTypeConfigRule( const std::string& key_system, @@ -565,7 +565,7 @@ EmeConfigRule KeySystemsImpl::GetEncryptionSchemeConfigRule( const std::string& key_system, - EncryptionMode encryption_scheme) const { + EncryptionScheme encryption_scheme) const { DCHECK(thread_checker_.CalledOnValidThread()); auto key_system_iter = key_system_properties_map_.find(key_system);
diff --git a/media/base/key_systems.h b/media/base/key_systems.h index 645f434..c912c1bb 100644 --- a/media/base/key_systems.h +++ b/media/base/key_systems.h
@@ -42,7 +42,7 @@ // Returns the configuration rule for supporting |encryption_scheme|. virtual EmeConfigRule GetEncryptionSchemeConfigRule( const std::string& key_system, - EncryptionMode encryption_scheme) const = 0; + EncryptionScheme encryption_scheme) const = 0; // Returns the configuration rule for supporting a container and a list of // codecs.
diff --git a/media/base/key_systems_unittest.cc b/media/base/key_systems_unittest.cc index 3782240..29c042a 100644 --- a/media/base/key_systems_unittest.cc +++ b/media/base/key_systems_unittest.cc
@@ -93,9 +93,9 @@ std::string GetKeySystemName() const override { return name_; } EmeConfigRule GetEncryptionSchemeConfigRule( - EncryptionMode encryption_scheme) const override { - return (encryption_scheme == EncryptionMode::kUnencrypted || - encryption_scheme == EncryptionMode::kCenc) + EncryptionScheme encryption_scheme) const override { + return (encryption_scheme == EncryptionScheme::kUnencrypted || + encryption_scheme == EncryptionScheme::kCenc) ? EmeConfigRule::SUPPORTED : EmeConfigRule::NOT_SUPPORTED; } @@ -125,12 +125,12 @@ // Pretend clear (unencrypted) and 'cenc' content are always supported. But // 'cbcs' is not supported by hardware secure codecs. EmeConfigRule GetEncryptionSchemeConfigRule( - EncryptionMode encryption_scheme) const override { + EncryptionScheme encryption_scheme) const override { switch (encryption_scheme) { - case media::EncryptionMode::kUnencrypted: - case media::EncryptionMode::kCenc: + case media::EncryptionScheme::kUnencrypted: + case media::EncryptionScheme::kCenc: return media::EmeConfigRule::SUPPORTED; - case media::EncryptionMode::kCbcs: + case media::EncryptionScheme::kCbcs: return media::EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED; } NOTREACHED(); @@ -170,7 +170,7 @@ }; void ExpectEncryptionSchemeConfigRule(const std::string& key_system, - EncryptionMode encryption_scheme, + EncryptionScheme encryption_scheme, EmeConfigRule expected_rule) { EXPECT_EQ(expected_rule, KeySystems::GetInstance()->GetEncryptionSchemeConfigRule( @@ -626,11 +626,11 @@ TEST_F(KeySystemsTest, IsSupportedKeySystem_UsesAesDecryptor_EncryptionSchemes) { - ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionMode::kUnencrypted, + ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionScheme::kUnencrypted, EmeConfigRule::SUPPORTED); - ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionMode::kCenc, + ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionScheme::kCenc, EmeConfigRule::SUPPORTED); - ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionMode::kCbcs, + ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionScheme::kCbcs, EmeConfigRule::NOT_SUPPORTED); } @@ -760,11 +760,11 @@ if (!CanRunExternalKeySystemTests()) return; - ExpectEncryptionSchemeConfigRule(kExternal, EncryptionMode::kUnencrypted, + ExpectEncryptionSchemeConfigRule(kExternal, EncryptionScheme::kUnencrypted, EmeConfigRule::SUPPORTED); - ExpectEncryptionSchemeConfigRule(kExternal, EncryptionMode::kCenc, + ExpectEncryptionSchemeConfigRule(kExternal, EncryptionScheme::kCenc, EmeConfigRule::SUPPORTED); - ExpectEncryptionSchemeConfigRule(kExternal, EncryptionMode::kCbcs, + ExpectEncryptionSchemeConfigRule(kExternal, EncryptionScheme::kCbcs, EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED); }
diff --git a/media/base/media_util.cc b/media/base/media_util.cc index 501574d..66f23be 100644 --- a/media/base/media_util.cc +++ b/media/base/media_util.cc
@@ -5,7 +5,6 @@ #include "media/base/media_util.h" #include "base/metrics/histogram_macros.h" -#include "media/base/encryption_pattern.h" namespace media { @@ -42,15 +41,6 @@ return std::vector<uint8_t>(); } -EncryptionScheme Unencrypted() { - return EncryptionScheme(); -} - -EncryptionScheme AesCtrEncryptionScheme() { - return EncryptionScheme(EncryptionScheme::CIPHER_MODE_AES_CTR, - EncryptionPattern()); -} - void ReportPepperVideoDecoderOutputPictureCountHW(int height) { UMA_HISTOGRAM_ENUMERATION("Media.PepperVideoDecoderOutputPictureCount.HW", GetMediaVideoHeight(height));
diff --git a/media/base/media_util.h b/media/base/media_util.h index d5f2600..65aee57e 100644 --- a/media/base/media_util.h +++ b/media/base/media_util.h
@@ -9,7 +9,6 @@ #include <vector> #include "base/macros.h" -#include "media/base/encryption_scheme.h" #include "media/base/media_export.h" #include "media/base/media_log.h" @@ -19,11 +18,6 @@ // constructed with empty extra data. MEDIA_EXPORT std::vector<uint8_t> EmptyExtraData(); -// The following helper functions return new instances of EncryptionScheme that -// indicate widely used settings. -MEDIA_EXPORT EncryptionScheme Unencrypted(); -MEDIA_EXPORT EncryptionScheme AesCtrEncryptionScheme(); - // Helpers for PPAPI UMAs. There wasn't an obvious place to put them in // //content/renderer/pepper. MEDIA_EXPORT void ReportPepperVideoDecoderOutputPictureCountHW(int height);
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index c126e5d..89a53086 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc
@@ -158,6 +158,9 @@ void DestroyRenderer(); void ReportMetadata(StartType start_type); + // Returns whether there's any encrypted stream in the demuxer. + bool HasEncryptedStream(); + const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; CreateRendererCB create_renderer_cb_; @@ -192,6 +195,10 @@ // Series of tasks to Start(), Seek(), and Resume(). std::unique_ptr<SerialRunner> pending_callbacks_; + // Callback to store the |done_cb| when CreateRenderer() needs to wait for a + // CDM to be set. Should only be set in kStarting or kResuming states. + PipelineStatusCallback create_renderer_done_cb_; + // Called from non-media threads when an error occurs. PipelineStatusCB error_cb_; @@ -480,6 +487,17 @@ if (!shared_state_.renderer) { cdm_context_ = cdm_context; std::move(cdm_attached_cb).Run(true); + + if (create_renderer_done_cb_) { + DCHECK(state_ == kStarting || state_ == kResuming); + DVLOG(1) << __func__ << ": CDM set; continue pipeline start/resume."; + // Use BindToCurrentLoop to make sure OnRendererCreated() is called on the + // media task runner. + create_renderer_cb_.Run(BindToCurrentLoop(base::BindOnce( + &RendererWrapper::OnRendererCreated, weak_factory_.GetWeakPtr(), + std::move(create_renderer_done_cb_)))); + } + return; } @@ -889,6 +907,14 @@ PipelineStatusCallback done_cb) { DVLOG(1) << __func__; DCHECK(media_task_runner_->BelongsToCurrentThread()); + DCHECK(state_ == kStarting || state_ == kResuming); + + if (HasEncryptedStream() && !cdm_context_) { + DVLOG(1) << __func__ << ": Has encrypted stream but CDM is not set."; + create_renderer_done_cb_ = std::move(done_cb); + OnWaiting(WaitingReason::kNoCdm); + return; + } // Use BindToCurrentLoop to make sure OnRendererCreated() is called on the // media task runner. @@ -1016,6 +1042,21 @@ base::BindOnce(&PipelineImpl::OnSeekDone, weak_pipeline_, true)); } +bool PipelineImpl::RendererWrapper::HasEncryptedStream() { + auto streams = demuxer_->GetAllStreams(); + + for (auto* stream : streams) { + if (stream->type() == DemuxerStream::AUDIO && + stream->audio_decoder_config().is_encrypted()) + return true; + if (stream->type() == DemuxerStream::VIDEO && + stream->video_decoder_config().is_encrypted()) + return true; + } + + return false; +} + PipelineImpl::PipelineImpl( scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index 8a99a09..61dcf1f 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc
@@ -32,6 +32,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" +using ::base::test::RunClosure; using ::base::test::RunOnceCallback; using ::base::test::RunOnceClosure; using ::testing::_; @@ -97,6 +98,7 @@ MOCK_METHOD1(OnSeek, void(PipelineStatus)); MOCK_METHOD1(OnSuspend, void(PipelineStatus)); MOCK_METHOD1(OnResume, void(PipelineStatus)); + MOCK_METHOD1(OnCdmAttached, void(bool)); private: DISALLOW_COPY_AND_ASSIGN(CallbackHelper); @@ -175,7 +177,7 @@ return stream; } - // Sets up expectations to allow the video renderer to initialize. + // Sets up expectations to allow the renderer to initialize. void SetRendererExpectations() { EXPECT_CALL(*renderer_, OnInitialize(_, _, _)) .WillOnce( @@ -190,6 +192,17 @@ base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_))); } + void SetRendererPostStartExpectations() { + EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); + EXPECT_CALL(*renderer_, SetVolume(1.0f)); + EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_)) + .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH, + BUFFERING_CHANGE_REASON_UNKNOWN)); + EXPECT_CALL(callbacks_, + OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, + BUFFERING_CHANGE_REASON_UNKNOWN)); + } + // Suspension status of the pipeline post Start(). enum class PostStartStatus { kNormal, @@ -206,17 +219,8 @@ if (start_status == PIPELINE_OK) { EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); - if (post_start_status == PostStartStatus::kNormal) { - EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); - EXPECT_CALL(*renderer_, SetVolume(1.0f)); - EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_)) - .WillOnce(SetBufferingState(&renderer_client_, - BUFFERING_HAVE_ENOUGH, - BUFFERING_CHANGE_REASON_UNKNOWN)); - EXPECT_CALL(callbacks_, - OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, - BUFFERING_CHANGE_REASON_UNKNOWN)); - } + if (post_start_status == PostStartStatus::kNormal) + SetRendererPostStartExpectations(); } StartPipeline(start_type); @@ -233,15 +237,27 @@ audio_stream_ = CreateStream(DemuxerStream::AUDIO); } - void CreateVideoStream() { + void CreateVideoStream(bool is_encrypted = false) { video_stream_ = CreateStream(DemuxerStream::VIDEO); - video_stream_->set_video_decoder_config(video_decoder_config_); + video_stream_->set_video_decoder_config( + is_encrypted ? TestVideoConfig::NormalEncrypted() + : TestVideoConfig::Normal()); } - MockDemuxerStream* audio_stream() { return audio_stream_.get(); } + void CreateEncryptedVideoStream() { CreateVideoStream(true); } + MockDemuxerStream* audio_stream() { return audio_stream_.get(); } MockDemuxerStream* video_stream() { return video_stream_.get(); } + void SetCdmAndExpect(bool expected_result) { + EXPECT_CALL(*renderer_, OnSetCdm(_, _)).WillOnce(RunOnceCallback<1>(true)); + EXPECT_CALL(callbacks_, OnCdmAttached(expected_result)); + pipeline_->SetCdm(&cdm_context_, + base::BindRepeating(&CallbackHelper::OnCdmAttached, + base::Unretained(&callbacks_))); + base::RunLoop().RunUntilIdle(); + } + void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) { EXPECT_CALL(*demuxer_, AbortPendingReads()); EXPECT_CALL(*demuxer_, OnSeek(seek_time, _)) @@ -338,6 +354,7 @@ base::test::SingleThreadTaskEnvironment task_environment_; NullMediaLog media_log_; std::unique_ptr<PipelineImpl> pipeline_; + StrictMock<MockCdmContext> cdm_context_; std::unique_ptr<StrictMock<MockDemuxer>> demuxer_; DemuxerHost* demuxer_host_; @@ -531,6 +548,40 @@ EXPECT_TRUE(metadata_.has_video); } +TEST_F(PipelineImplTest, EncryptedStream_SetCdmBeforeStart) { + CreateEncryptedVideoStream(); + MockDemuxerStreamVector streams; + streams.push_back(video_stream()); + SetDemuxerExpectations(&streams); + + SetCdmAndExpect(true); + SetRendererExpectations(); + StartPipelineAndExpect(PIPELINE_OK); +} + +TEST_F(PipelineImplTest, EncryptedStream_SetCdmAfterStart) { + CreateEncryptedVideoStream(); + MockDemuxerStreamVector streams; + streams.push_back(video_stream()); + SetDemuxerExpectations(&streams); + + // Demuxer initialization and metadata reporting don't wait for CDM. + EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); + + base::RunLoop run_loop; + EXPECT_CALL(callbacks_, OnWaiting(_)) + .WillOnce(RunClosure(run_loop.QuitClosure())); + pipeline_->Start( + Pipeline::StartType::kNormal, demuxer_.get(), &callbacks_, + base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_))); + run_loop.Run(); + + SetRendererExpectations(); + EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); + SetRendererPostStartExpectations(); + SetCdmAndExpect(true); +} + TEST_F(PipelineImplTest, Seek) { CreateAudioStream(); CreateVideoStream(); @@ -685,7 +736,6 @@ SetRendererExpectations(); StartPipelineAndExpect(PIPELINE_OK); - // The ended callback shouldn't run until all renderers have ended. EXPECT_CALL(callbacks_, OnEnded()); renderer_client_->OnEnded();
diff --git a/media/base/test_helpers.cc b/media/base/test_helpers.cc index 0bc65a0..97bca27 100644 --- a/media/base/test_helpers.cc +++ b/media/base/test_helpers.cc
@@ -139,7 +139,7 @@ codec, profile, VideoDecoderConfig::AlphaMode::kIsOpaque, color_space, VideoTransformation(rotation), coded_size, visible_rect, natural_size, EmptyExtraData(), - is_encrypted ? AesCtrEncryptionScheme() : Unencrypted()); + is_encrypted ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted); } static VideoCodecProfile MinProfile(VideoCodec codec) { @@ -243,13 +243,13 @@ AudioDecoderConfig TestAudioConfig::Normal() { return AudioDecoderConfig(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); } AudioDecoderConfig TestAudioConfig::NormalEncrypted() { return AudioDecoderConfig(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, EmptyExtraData(), - AesCtrEncryptionScheme()); + EncryptionScheme::kCenc); } // static
diff --git a/media/base/video_decoder_config.cc b/media/base/video_decoder_config.cc index c98ad08..dfe1f75 100644 --- a/media/base/video_decoder_config.cc +++ b/media/base/video_decoder_config.cc
@@ -73,17 +73,16 @@ alpha_mode_(AlphaMode::kIsOpaque), transformation_(kNoTransformation) {} -VideoDecoderConfig::VideoDecoderConfig( - VideoCodec codec, - VideoCodecProfile profile, - AlphaMode alpha_mode, - const VideoColorSpace& color_space, - VideoTransformation rotation, - const gfx::Size& coded_size, - const gfx::Rect& visible_rect, - const gfx::Size& natural_size, - const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme) { +VideoDecoderConfig::VideoDecoderConfig(VideoCodec codec, + VideoCodecProfile profile, + AlphaMode alpha_mode, + const VideoColorSpace& color_space, + VideoTransformation rotation, + const gfx::Size& coded_size, + const gfx::Rect& visible_rect, + const gfx::Size& natural_size, + const std::vector<uint8_t>& extra_data, + EncryptionScheme encryption_scheme) { Initialize(codec, profile, alpha_mode, color_space, rotation, coded_size, visible_rect, natural_size, extra_data, encryption_scheme); } @@ -119,7 +118,7 @@ const gfx::Rect& visible_rect, const gfx::Size& natural_size, const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme) { + EncryptionScheme encryption_scheme) { codec_ = codec; profile_ = profile; alpha_mode_ = alpha_mode; @@ -146,7 +145,7 @@ visible_rect() == config.visible_rect() && natural_size() == config.natural_size() && extra_data() == config.extra_data() && - encryption_scheme().Matches(config.encryption_scheme()) && + encryption_scheme() == config.encryption_scheme() && color_space_info() == config.color_space_info() && hdr_metadata() == config.hdr_metadata(); } @@ -197,16 +196,17 @@ void VideoDecoderConfig::SetIsEncrypted(bool is_encrypted) { if (!is_encrypted) { - DCHECK(encryption_scheme_.is_encrypted()) << "Config is already clear."; - encryption_scheme_ = Unencrypted(); + DCHECK_NE(encryption_scheme_, EncryptionScheme::kUnencrypted) + << "Config is already clear."; + encryption_scheme_ = EncryptionScheme::kUnencrypted; } else { - DCHECK(!encryption_scheme_.is_encrypted()) + DCHECK_EQ(encryption_scheme_, EncryptionScheme::kUnencrypted) << "Config is already encrypted."; // TODO(xhwang): This is only used to guide decoder selection, so set // a common encryption scheme that should be supported by all decrypting // decoders. We should be able to remove this when we support switching // decoders at run time. See http://crbug.com/695595 - encryption_scheme_ = AesCtrEncryptionScheme(); + encryption_scheme_ = EncryptionScheme::kCenc; } }
diff --git a/media/base/video_decoder_config.h b/media/base/video_decoder_config.h index afe139a..e9ca279 100644 --- a/media/base/video_decoder_config.h +++ b/media/base/video_decoder_config.h
@@ -48,7 +48,7 @@ const gfx::Rect& visible_rect, const gfx::Size& natural_size, const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme); + EncryptionScheme encryption_scheme); VideoDecoderConfig(const VideoDecoderConfig& other); ~VideoDecoderConfig(); @@ -63,7 +63,7 @@ const gfx::Rect& visible_rect, const gfx::Size& natural_size, const std::vector<uint8_t>& extra_data, - const EncryptionScheme& encryption_scheme); + EncryptionScheme encryption_scheme); // Returns true if this object has appropriate configuration values, false // otherwise. @@ -140,12 +140,12 @@ // Whether the video stream is potentially encrypted. // Note that in a potentially encrypted video stream, individual buffers // can be encrypted or not encrypted. - bool is_encrypted() const { return encryption_scheme_.is_encrypted(); } + bool is_encrypted() const { + return encryption_scheme_ != EncryptionScheme::kUnencrypted; + } // Encryption scheme used for encrypted buffers. - const EncryptionScheme& encryption_scheme() const { - return encryption_scheme_; - } + EncryptionScheme encryption_scheme() const { return encryption_scheme_; } // Color space of the image data. void set_color_space_info(const VideoColorSpace& color_space); @@ -175,7 +175,7 @@ std::vector<uint8_t> extra_data_; - EncryptionScheme encryption_scheme_; + EncryptionScheme encryption_scheme_ = EncryptionScheme::kUnencrypted; VideoColorSpace color_space_info_; base::Optional<HDRMetadata> hdr_metadata_;
diff --git a/media/base/video_decoder_config_unittest.cc b/media/base/video_decoder_config_unittest.cc index 636e7a4..6c083a0 100644 --- a/media/base/video_decoder_config_unittest.cc +++ b/media/base/video_decoder_config_unittest.cc
@@ -19,14 +19,14 @@ VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, kNaturalSize, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); EXPECT_TRUE(config.IsValidConfig()); EXPECT_EQ(config.alpha_mode(), VideoDecoderConfig::AlphaMode::kIsOpaque); config.Initialize(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, VideoDecoderConfig::AlphaMode::kHasAlpha, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, kNaturalSize, - EmptyExtraData(), Unencrypted()); + EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_EQ(config.alpha_mode(), VideoDecoderConfig::AlphaMode::kHasAlpha); } @@ -35,7 +35,7 @@ VideoDecoderConfig config( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_FALSE(config.IsValidConfig()); } @@ -44,7 +44,7 @@ VideoDecoderConfig config( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_FALSE(config.IsValidConfig()); } @@ -53,7 +53,7 @@ VideoDecoderConfig config( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_FALSE(config.IsValidConfig()); } @@ -62,7 +62,7 @@ VideoDecoderConfig config( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_FALSE(config.IsValidConfig()); } @@ -73,7 +73,7 @@ VideoDecoderConfig config( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_FALSE(config.IsValidConfig()); } @@ -87,7 +87,7 @@ VideoDecoderConfig config( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_FALSE(config.IsValidConfig()); }
diff --git a/media/base/video_thumbnail_decoder_unittest.cc b/media/base/video_thumbnail_decoder_unittest.cc index 5cdf459e..57550ae1 100644 --- a/media/base/video_thumbnail_decoder_unittest.cc +++ b/media/base/video_thumbnail_decoder_unittest.cc
@@ -38,7 +38,7 @@ VideoDecoderConfig valid_config( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, gfx::Size(1, 1), gfx::Rect(1, 1), - gfx::Size(1, 1), EmptyExtraData(), Unencrypted()); + gfx::Size(1, 1), EmptyExtraData(), EncryptionScheme::kUnencrypted); thumbnail_decoder_ = std::make_unique<VideoThumbnailDecoder>( std::move(mock_video_decoder), valid_config, std::vector<uint8_t>{0u});
diff --git a/media/blink/key_system_config_selector.cc b/media/blink/key_system_config_selector.cc index faed6ec7f..6a98a4f1 100644 --- a/media/blink/key_system_config_selector.cc +++ b/media/blink/key_system_config_selector.cc
@@ -378,11 +378,11 @@ // compatibility and simplicity, we treat kNotSpecified the same as kCenc. case EmeEncryptionScheme::kNotSpecified: case EmeEncryptionScheme::kCenc: - return key_systems_->GetEncryptionSchemeConfigRule(key_system, - EncryptionMode::kCenc); + return key_systems_->GetEncryptionSchemeConfigRule( + key_system, EncryptionScheme::kCenc); case EmeEncryptionScheme::kCbcs: - return key_systems_->GetEncryptionSchemeConfigRule(key_system, - EncryptionMode::kCbcs); + return key_systems_->GetEncryptionSchemeConfigRule( + key_system, EncryptionScheme::kCbcs); } NOTREACHED();
diff --git a/media/blink/key_system_config_selector_unittest.cc b/media/blink/key_system_config_selector_unittest.cc index 2299401..f484498 100644 --- a/media/blink/key_system_config_selector_unittest.cc +++ b/media/blink/key_system_config_selector_unittest.cc
@@ -77,17 +77,18 @@ constexpr EncryptionScheme kDisallowHwSecureCodecEncryptionScheme = EncryptionScheme::kCbcs; -EncryptionMode ConvertEncryptionScheme(EncryptionScheme encryption_scheme) { +media::EncryptionScheme ConvertEncryptionScheme( + EncryptionScheme encryption_scheme) { switch (encryption_scheme) { case EncryptionScheme::kNotSpecified: case EncryptionScheme::kCenc: - return EncryptionMode::kCenc; + return media::EncryptionScheme::kCenc; case EncryptionScheme::kCbcs: - return EncryptionMode::kCbcs; + return media::EncryptionScheme::kCbcs; } NOTREACHED(); - return EncryptionMode::kUnencrypted; + return media::EncryptionScheme::kUnencrypted; } WebString MakeCodecs(const std::string& a, const std::string& b) { @@ -215,7 +216,7 @@ EmeConfigRule GetEncryptionSchemeConfigRule( const std::string& key_system, - EncryptionMode encryption_scheme) const override { + media::EncryptionScheme encryption_scheme) const override { if (encryption_scheme == ConvertEncryptionScheme(kSupportedEncryptionScheme)) { return EmeConfigRule::SUPPORTED;
diff --git a/media/blink/video_decode_stats_reporter_unittest.cc b/media/blink/video_decode_stats_reporter_unittest.cc index 7ce60a1..1dfba937 100644 --- a/media/blink/video_decode_stats_reporter_unittest.cc +++ b/media/blink/video_decode_stats_reporter_unittest.cc
@@ -52,7 +52,7 @@ return VideoDecoderConfig( codec, profile, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::JPEG(), kNoTransformation, coded_size, visible_rect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); } PipelineStatistics MakeStats(int frames_decoded,
diff --git a/media/blink/watch_time_reporter_unittest.cc b/media/blink/watch_time_reporter_unittest.cc index 0a12e04..4cb4b2d 100644 --- a/media/blink/watch_time_reporter_unittest.cc +++ b/media/blink/watch_time_reporter_unittest.cc
@@ -1102,8 +1102,8 @@ has_video_ ? H264PROFILE_MAIN : VIDEO_CODEC_PROFILE_UNKNOWN, has_audio_ ? "FirstAudioDecoder" : "", has_video_ ? "FirstVideoDecoder" : "", - has_audio_ ? EncryptionMode::kCenc : EncryptionMode::kUnencrypted, - has_video_ ? EncryptionMode::kCbcs : EncryptionMode::kUnencrypted, + has_audio_ ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted, + has_video_ ? EncryptionScheme::kCbcs : EncryptionScheme::kUnencrypted, has_video_ ? gfx::Size(800, 600) : gfx::Size()); // Get a pointer to our original properties since we're not allowed to use @@ -1137,7 +1137,7 @@ .Times((has_audio_ && has_video_) ? 3 : 2); wtr_->UpdateSecondaryProperties(mojom::SecondaryPlaybackProperties::New( kUnknownAudioCodec, kUnknownVideoCodec, VIDEO_CODEC_PROFILE_UNKNOWN, "", - "", EncryptionMode::kUnencrypted, EncryptionMode::kUnencrypted, + "", EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted, kSizeJustRight)); EXPECT_TRUE(IsMonitoring()); @@ -1159,7 +1159,7 @@ .Times((has_audio_ && has_video_) ? 3 : 2); wtr_->UpdateSecondaryProperties(mojom::SecondaryPlaybackProperties::New( kUnknownAudioCodec, kUnknownVideoCodec, VIDEO_CODEC_PROFILE_UNKNOWN, "", - "", EncryptionMode::kUnencrypted, EncryptionMode::kUnencrypted, + "", EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted, kSizeTooSmall)); EXPECT_WATCH_TIME_FINALIZED(); CycleReportingTimer();
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index c6c8b77..657890d0 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -172,31 +172,19 @@ // These values are persisted to UMA. Entries should not be renumbered and // numeric values should never be reused. -// TODO(crbug.com/825041): This should use EncryptionMode when kUnencrypted +// TODO(crbug.com/825041): This should use EncryptionScheme when kUnencrypted // removed. enum class EncryptionSchemeUMA { kCenc = 0, kCbcs = 1, kCount }; EncryptionSchemeUMA DetermineEncryptionSchemeUMAValue( - const EncryptionScheme& encryption_scheme) { - if (encryption_scheme.mode() == EncryptionScheme::CIPHER_MODE_AES_CBC) + EncryptionScheme encryption_scheme) { + if (encryption_scheme == EncryptionScheme::kCbcs) return EncryptionSchemeUMA::kCbcs; - DCHECK_EQ(encryption_scheme.mode(), EncryptionScheme::CIPHER_MODE_AES_CTR); + DCHECK_EQ(encryption_scheme, EncryptionScheme::kCenc); return EncryptionSchemeUMA::kCenc; } -EncryptionMode DetermineEncryptionMode( - const EncryptionScheme& encryption_scheme) { - switch (encryption_scheme.mode()) { - case EncryptionScheme::CIPHER_MODE_UNENCRYPTED: - return EncryptionMode::kUnencrypted; - case EncryptionScheme::CIPHER_MODE_AES_CTR: - return EncryptionMode::kCenc; - case EncryptionScheme::CIPHER_MODE_AES_CBC: - return EncryptionMode::kCbcs; - } -} - #if BUILDFLAG(ENABLE_FFMPEG) // Returns true if |url| represents (or is likely to) a local file. bool IsLocalFile(const GURL& url) { @@ -3206,10 +3194,8 @@ pipeline_metadata_.video_decoder_config.codec(), pipeline_metadata_.video_decoder_config.profile(), audio_decoder_name_, video_decoder_name_, - DetermineEncryptionMode( - pipeline_metadata_.audio_decoder_config.encryption_scheme()), - DetermineEncryptionMode( - pipeline_metadata_.video_decoder_config.encryption_scheme()), + pipeline_metadata_.audio_decoder_config.encryption_scheme(), + pipeline_metadata_.video_decoder_config.encryption_scheme(), pipeline_metadata_.natural_size)); } @@ -3585,11 +3571,11 @@ void WebMediaPlayerImpl::RecordEncryptionScheme( const std::string& stream_name, - const EncryptionScheme& encryption_scheme) { + EncryptionScheme encryption_scheme) { DCHECK(stream_name == "Audio" || stream_name == "Video"); // If the stream is not encrypted, don't record it. - if (encryption_scheme.mode() == EncryptionScheme::CIPHER_MODE_UNENCRYPTED) + if (encryption_scheme == EncryptionScheme::kUnencrypted) return; base::UmaHistogramEnumeration(
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 14ebb86c..2fba773 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -27,6 +27,7 @@ #include "cc/layers/surface_layer.h" #include "components/viz/common/gpu/context_provider.h" #include "media/base/cdm_config.h" +#include "media/base/encryption_scheme.h" #include "media/base/media_observer.h" #include "media/base/media_tracks.h" #include "media/base/overlay_info.h" @@ -77,7 +78,6 @@ namespace media { class CdmContextRef; class ChunkDemuxer; -class EncryptionScheme; class VideoDecodeStatsReporter; class MediaLog; class UrlIndex; @@ -594,7 +594,7 @@ // Records the encryption scheme used by the stream |stream_name|. This is // only recorded when metadata is available. void RecordEncryptionScheme(const std::string& stream_name, - const EncryptionScheme& encryption_scheme); + EncryptionScheme encryption_scheme); // Returns whether the player is currently displayed in Picture-in-Picture. // It will return true even if the player is in AutoPIP mode.
diff --git a/media/capture/video/video_frame_receiver.h b/media/capture/video/video_frame_receiver.h index aaa69b788..d06cb16 100644 --- a/media/capture/video/video_frame_receiver.h +++ b/media/capture/video/video_frame_receiver.h
@@ -16,9 +16,10 @@ // clients. On some platforms, VideoCaptureDeviceClient calls these methods from // OS or capture driver provided threads which do not have a task runner and // cannot be posted back to. The mostly equivalent interface -// video_capture::mojom::Receiver cannot be used by VideoCaptureDeviceClient -// directly, because creating a video_catpure::mojom::ScopedAccessPermissionPtr -// for passing into OnFrameReadyInBuffer() requires a thread with a task runner. +// video_capture::mojom::VideoFrameHandler cannot be used by +// VideoCaptureDeviceClient directly, because creating a +// video_catpure::mojom::ScopedAccessPermissionPtr for passing into +// OnFrameReadyInBuffer() requires a thread with a task runner. class CAPTURE_EXPORT VideoFrameReceiver { public: virtual ~VideoFrameReceiver() {}
diff --git a/media/cast/sender/h264_vt_encoder_unittest.cc b/media/cast/sender/h264_vt_encoder_unittest.cc index 3c1c7b7..5c95e614 100644 --- a/media/cast/sender/h264_vt_encoder_unittest.cc +++ b/media/cast/sender/h264_vt_encoder_unittest.cc
@@ -305,7 +305,7 @@ VideoDecoderConfig config( kCodecH264, H264PROFILE_MAIN, alpha_mode, VideoColorSpace(), kNoTransformation, frame_->coded_size(), frame_->visible_rect(), - frame_->natural_size(), EmptyExtraData(), Unencrypted()); + frame_->natural_size(), EmptyExtraData(), EncryptionScheme::kUnencrypted); scoped_refptr<EndToEndFrameChecker> checker(new EndToEndFrameChecker(config)); VideoEncoder::FrameEncodedCallback cb =
diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index 176050a..4abcdfa7 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc
@@ -155,10 +155,10 @@ CHECK(input.data_size()); CHECK(input.decrypt_config()); - if (input.decrypt_config()->encryption_mode() == EncryptionMode::kCenc) + if (input.decrypt_config()->encryption_scheme() == EncryptionScheme::kCenc) return DecryptCencBuffer(input, key); - if (input.decrypt_config()->encryption_mode() == EncryptionMode::kCbcs) + if (input.decrypt_config()->encryption_scheme() == EncryptionScheme::kCbcs) return DecryptCbcsBuffer(input, key); DVLOG(1) << "Only 'cenc' and 'cbcs' modes supported.";
diff --git a/media/cdm/cbcs_decryptor.cc b/media/cdm/cbcs_decryptor.cc index 94c18ad..10f4dfd 100644 --- a/media/cdm/cbcs_decryptor.cc +++ b/media/cdm/cbcs_decryptor.cc
@@ -126,7 +126,7 @@ const DecryptConfig* decrypt_config = input.decrypt_config(); DCHECK(decrypt_config) << "No need to call Decrypt() on unencrypted buffer."; - DCHECK_EQ(EncryptionMode::kCbcs, decrypt_config->encryption_mode()); + DCHECK_EQ(EncryptionScheme::kCbcs, decrypt_config->encryption_scheme()); DCHECK(decrypt_config->HasPattern()); const EncryptionPattern pattern =
diff --git a/media/cdm/cdm_type_conversion.cc b/media/cdm/cdm_type_conversion.cc index 159d63d2..e786316 100644 --- a/media/cdm/cdm_type_conversion.cc +++ b/media/cdm/cdm_type_conversion.cc
@@ -203,31 +203,17 @@ return cdm::kInternalError; } -cdm::EncryptionScheme ToCdmEncryptionScheme(const EncryptionScheme& scheme) { - switch (scheme.mode()) { - case EncryptionScheme::CIPHER_MODE_UNENCRYPTED: +cdm::EncryptionScheme ToCdmEncryptionScheme(EncryptionScheme scheme) { + switch (scheme) { + case EncryptionScheme::kUnencrypted: return cdm::EncryptionScheme::kUnencrypted; - case EncryptionScheme::CIPHER_MODE_AES_CTR: + case EncryptionScheme::kCenc: return cdm::EncryptionScheme::kCenc; - case EncryptionScheme::CIPHER_MODE_AES_CBC: + case EncryptionScheme::kCbcs: return cdm::EncryptionScheme::kCbcs; } - NOTREACHED() << "Unexpected EncryptionScheme mode " << scheme.mode(); - return cdm::EncryptionScheme::kUnencrypted; -} - -cdm::EncryptionScheme ToCdmEncryptionScheme(const EncryptionMode& mode) { - switch (mode) { - case EncryptionMode::kUnencrypted: - return cdm::EncryptionScheme::kUnencrypted; - case EncryptionMode::kCenc: - return cdm::EncryptionScheme::kCenc; - case EncryptionMode::kCbcs: - return cdm::EncryptionScheme::kCbcs; - } - - NOTREACHED() << "Unexpected EncryptionMode"; + NOTREACHED() << "Unexpected EncryptionScheme"; return cdm::EncryptionScheme::kUnencrypted; } @@ -626,7 +612,7 @@ input_buffer->num_subsamples = num_subsamples; input_buffer->encryption_scheme = - ToCdmEncryptionScheme(decrypt_config->encryption_mode()); + ToCdmEncryptionScheme(decrypt_config->encryption_scheme()); if (decrypt_config->HasPattern()) { input_buffer->pattern = { decrypt_config->encryption_pattern()->crypt_byte_block(),
diff --git a/media/cdm/cdm_type_conversion.h b/media/cdm/cdm_type_conversion.h index 2d9e670..d7b303a 100644 --- a/media/cdm/cdm_type_conversion.h +++ b/media/cdm/cdm_type_conversion.h
@@ -51,9 +51,7 @@ MEDIA_EXPORT cdm::KeyStatus ToCdmKeyStatus(CdmKeyInformation::KeyStatus status); MEDIA_EXPORT cdm::EncryptionScheme ToCdmEncryptionScheme( - const EncryptionScheme& scheme); -MEDIA_EXPORT cdm::EncryptionScheme ToCdmEncryptionScheme( - const EncryptionMode& mode); + EncryptionScheme scheme); MEDIA_EXPORT CdmPromise::Exception ToMediaCdmPromiseException( cdm::Exception exception);
diff --git a/media/cdm/cenc_decryptor.cc b/media/cdm/cenc_decryptor.cc index ae0442f..647362e 100644 --- a/media/cdm/cenc_decryptor.cc +++ b/media/cdm/cenc_decryptor.cc
@@ -68,7 +68,7 @@ const DecryptConfig* decrypt_config = input.decrypt_config(); DCHECK(decrypt_config) << "No need to call Decrypt() on unencrypted buffer."; - DCHECK_EQ(EncryptionMode::kCenc, decrypt_config->encryption_mode()); + DCHECK_EQ(EncryptionScheme::kCenc, decrypt_config->encryption_scheme()); const std::string& iv = decrypt_config->iv(); DCHECK_EQ(iv.size(), static_cast<size_t>(DecryptConfig::kDecryptionKeySize));
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc index 7e62ba0..0321d2d 100644 --- a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc +++ b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
@@ -59,7 +59,7 @@ gfx::Rect(coded_size), coded_size, std::vector<uint8_t>(config.extra_data, config.extra_data + config.extra_data_size), - Unencrypted()); + EncryptionScheme::kUnencrypted); return media_config; }
diff --git a/media/ffmpeg/ffmpeg_common.cc b/media/ffmpeg/ffmpeg_common.cc index 72dc400..ddce138 100644 --- a/media/ffmpeg/ffmpeg_common.cc +++ b/media/ffmpeg/ffmpeg_common.cc
@@ -26,7 +26,7 @@ EncryptionScheme GetEncryptionScheme(const AVStream* stream) { AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", nullptr, 0); - return key ? AesCtrEncryptionScheme() : Unencrypted(); + return key ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted; } } // namespace @@ -318,10 +318,9 @@ return AV_SAMPLE_FMT_NONE; } -bool AVCodecContextToAudioDecoderConfig( - const AVCodecContext* codec_context, - const EncryptionScheme& encryption_scheme, - AudioDecoderConfig* config) { +bool AVCodecContextToAudioDecoderConfig(const AVCodecContext* codec_context, + EncryptionScheme encryption_scheme, + AudioDecoderConfig* config) { DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id);
diff --git a/media/ffmpeg/ffmpeg_common.h b/media/ffmpeg/ffmpeg_common.h index 3c6c62b..fbcfa14 100644 --- a/media/ffmpeg/ffmpeg_common.h +++ b/media/ffmpeg/ffmpeg_common.h
@@ -15,6 +15,7 @@ #include "base/time/time.h" #include "media/base/audio_codecs.h" #include "media/base/channel_layout.h" +#include "media/base/encryption_scheme.h" #include "media/base/media_export.h" #include "media/base/sample_format.h" #include "media/base/video_codecs.h" @@ -43,7 +44,6 @@ constexpr int64_t kNoFFmpegTimestamp = static_cast<int64_t>(AV_NOPTS_VALUE); class AudioDecoderConfig; -class EncryptionScheme; class VideoDecoderConfig; // The following implement the deleters declared in ffmpeg_deleters.h (which @@ -114,7 +114,7 @@ // is not modified. MEDIA_EXPORT bool AVCodecContextToAudioDecoderConfig( const AVCodecContext* codec_context, - const EncryptionScheme& encryption_scheme, + EncryptionScheme encryption_scheme, AudioDecoderConfig* config); // Converts FFmpeg's channel layout to chrome's ChannelLayout. |channels| can
diff --git a/media/filters/android/media_codec_audio_decoder.cc b/media/filters/android/media_codec_audio_decoder.cc index 209d799..c88bcab 100644 --- a/media/filters/android/media_codec_audio_decoder.cc +++ b/media/filters/android/media_codec_audio_decoder.cc
@@ -314,7 +314,7 @@ input_data.key_id = decrypt_config->key_id(); input_data.iv = decrypt_config->iv(); input_data.subsamples = decrypt_config->subsamples(); - input_data.encryption_scheme = decrypt_config->encryption_mode(); + input_data.encryption_scheme = decrypt_config->encryption_scheme(); input_data.encryption_pattern = decrypt_config->encryption_pattern(); } input_data.presentation_time = decoder_buffer->timestamp();
diff --git a/media/filters/audio_decoder_unittest.cc b/media/filters/audio_decoder_unittest.cc index 62315337..ddac5fd0 100644 --- a/media/filters/audio_decoder_unittest.cc +++ b/media/filters/audio_decoder_unittest.cc
@@ -209,7 +209,8 @@ AudioDecoderConfig config; ASSERT_TRUE(AVCodecContextToAudioDecoderConfig( - reader_->codec_context_for_testing(), Unencrypted(), &config)); + reader_->codec_context_for_testing(), EncryptionScheme::kUnencrypted, + &config)); #if defined(OS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS) // MEDIA_CODEC type requires config->extra_data() for AAC codec. For ADTS @@ -224,7 +225,7 @@ &channel_layout, nullptr, nullptr, &extra_data), 0); config.Initialize(kCodecAAC, kSampleFormatS16, channel_layout, - sample_rate, extra_data, Unencrypted(), + sample_rate, extra_data, EncryptionScheme::kUnencrypted, base::TimeDelta(), 0); ASSERT_FALSE(config.extra_data().empty()); }
diff --git a/media/filters/audio_timestamp_validator_unittest.cc b/media/filters/audio_timestamp_validator_unittest.cc index 2424091..f21e28c 100644 --- a/media/filters/audio_timestamp_validator_unittest.cc +++ b/media/filters/audio_timestamp_validator_unittest.cc
@@ -63,8 +63,9 @@ TEST_P(AudioTimestampValidatorTest, WarnForEraticTimes) { AudioDecoderConfig decoder_config; decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, - kSamplesPerSecond, EmptyExtraData(), Unencrypted(), - kSeekPreroll, codec_delay_); + kSamplesPerSecond, EmptyExtraData(), + EncryptionScheme::kUnencrypted, kSeekPreroll, + codec_delay_); // Validator should fail to stabilize pattern for timestamp expectations. EXPECT_MEDIA_LOG( @@ -112,8 +113,9 @@ TEST_P(AudioTimestampValidatorTest, NoWarningForValidTimes) { AudioDecoderConfig decoder_config; decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, - kSamplesPerSecond, EmptyExtraData(), Unencrypted(), - kSeekPreroll, codec_delay_); + kSamplesPerSecond, EmptyExtraData(), + EncryptionScheme::kUnencrypted, kSeekPreroll, + codec_delay_); // Validator should quickly stabilize pattern for timestamp expectations. EXPECT_MEDIA_LOG(HasSubstr("Failed to reconcile encoded audio times " @@ -151,8 +153,9 @@ TEST_P(AudioTimestampValidatorTest, SingleWarnForSingleLargeGap) { AudioDecoderConfig decoder_config; decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, - kSamplesPerSecond, EmptyExtraData(), Unencrypted(), - kSeekPreroll, codec_delay_); + kSamplesPerSecond, EmptyExtraData(), + EncryptionScheme::kUnencrypted, kSeekPreroll, + codec_delay_); AudioTimestampValidator validator(decoder_config, &media_log_); @@ -196,8 +199,9 @@ TEST_P(AudioTimestampValidatorTest, RepeatedWarnForSlowAccumulatingDrift) { AudioDecoderConfig decoder_config; decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, - kSamplesPerSecond, EmptyExtraData(), Unencrypted(), - kSeekPreroll, codec_delay_); + kSamplesPerSecond, EmptyExtraData(), + EncryptionScheme::kUnencrypted, kSeekPreroll, + codec_delay_); AudioTimestampValidator validator(decoder_config, &media_log_);
diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc index 1932020..acb150e 100644 --- a/media/filters/decrypting_audio_decoder_unittest.cc +++ b/media/filters/decrypting_audio_decoder_unittest.cc
@@ -108,7 +108,7 @@ config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(), - AesCtrEncryptionScheme(), base::TimeDelta(), 0); + EncryptionScheme::kCenc, base::TimeDelta(), 0); InitializeAndExpectResult(config_, true); } @@ -276,7 +276,7 @@ TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) { AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat, CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(), - AesCtrEncryptionScheme()); + EncryptionScheme::kCenc); InitializeAndExpectResult(config, false); } @@ -289,7 +289,7 @@ AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, kSampleRate, - EmptyExtraData(), AesCtrEncryptionScheme()); + EmptyExtraData(), EncryptionScheme::kCenc); InitializeAndExpectResult(config, false); } @@ -297,7 +297,7 @@ SetCdmType(CDM_WITHOUT_DECRYPTOR); AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, kSampleRate, - EmptyExtraData(), AesCtrEncryptionScheme()); + EmptyExtraData(), EncryptionScheme::kCenc); InitializeAndExpectResult(config, false); } @@ -362,7 +362,7 @@ // channel layout and samples_per_second. AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16, CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(), - AesCtrEncryptionScheme()); + EncryptionScheme::kCenc); EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel()); EXPECT_NE(new_config.channel_layout(), config_.channel_layout()); EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second()); @@ -384,7 +384,7 @@ // channel layout and samples_per_second. AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16, CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel()); EXPECT_NE(new_config.channel_layout(), config_.channel_layout()); EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
diff --git a/media/filters/decrypting_demuxer_stream_unittest.cc b/media/filters/decrypting_demuxer_stream_unittest.cc index b927aa1..2d4f6931 100644 --- a/media/filters/decrypting_demuxer_stream_unittest.cc +++ b/media/filters/decrypting_demuxer_stream_unittest.cc
@@ -145,7 +145,7 @@ AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, - EmptyExtraData(), AesCtrEncryptionScheme()); + EmptyExtraData(), EncryptionScheme::kCenc); InitializeAudioAndExpectStatus(input_config, PIPELINE_OK); const AudioDecoderConfig& output_config = @@ -326,7 +326,7 @@ SetCdmType(CDM_WITHOUT_DECRYPTOR); AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, - EmptyExtraData(), AesCtrEncryptionScheme()); + EmptyExtraData(), EncryptionScheme::kCenc); InitializeAudioAndExpectStatus(input_config, DECODER_ERROR_NOT_SUPPORTED); } @@ -502,7 +502,7 @@ AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 88200, EmptyExtraData(), - AesCtrEncryptionScheme()); + EncryptionScheme::kCenc); input_audio_stream_->set_audio_decoder_config(new_config); EXPECT_CALL(*input_audio_stream_, OnRead(_))
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc index 24fe18f..5fdf779ea 100644 --- a/media/filters/ffmpeg_video_decoder_unittest.cc +++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -225,7 +225,7 @@ VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, kNaturalSize, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); InitializeWithConfigWithResult(config, false); }
diff --git a/media/filters/frame_processor_unittest.cc b/media/filters/frame_processor_unittest.cc index a907c1da..ee4dec0 100644 --- a/media/filters/frame_processor_unittest.cc +++ b/media/filters/frame_processor_unittest.cc
@@ -345,9 +345,9 @@ ASSERT_FALSE(audio_); audio_.reset( new ChunkDemuxerStream(DemuxerStream::AUDIO, MediaTrack::Id("1"))); - AudioDecoderConfig decoder_config(kCodecVorbis, kSampleFormatPlanarF32, - CHANNEL_LAYOUT_STEREO, 1000, - EmptyExtraData(), Unencrypted()); + AudioDecoderConfig decoder_config( + kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 1000, + EmptyExtraData(), EncryptionScheme::kUnencrypted); frame_processor_->OnPossibleAudioConfigUpdate(decoder_config); ASSERT_TRUE( audio_->UpdateAudioConfig(decoder_config, false, &media_log_));
diff --git a/media/filters/source_buffer_state_unittest.cc b/media/filters/source_buffer_state_unittest.cc index c0b0dba..9221b928 100644 --- a/media/filters/source_buffer_state_unittest.cc +++ b/media/filters/source_buffer_state_unittest.cc
@@ -29,7 +29,7 @@ AudioDecoderConfig CreateAudioConfig(AudioCodec codec) { return AudioDecoderConfig(codec, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); } VideoDecoderConfig CreateVideoConfig(VideoCodec codec, int w, int h) { @@ -39,7 +39,7 @@ VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, size, visible_rect, size, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); } void AddAudioTrack(std::unique_ptr<MediaTracks>& t, AudioCodec codec, int id) {
diff --git a/media/filters/source_buffer_stream_unittest.cc b/media/filters/source_buffer_stream_unittest.cc index 8364ab7d..0fd3b26 100644 --- a/media/filters/source_buffer_stream_unittest.cc +++ b/media/filters/source_buffer_stream_unittest.cc
@@ -96,9 +96,9 @@ void SetAudioStream() { video_config_ = TestVideoConfig::Invalid(); - audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, - CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(), - Unencrypted(), base::TimeDelta(), 0); + audio_config_.Initialize( + kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 1000, + EmptyExtraData(), EncryptionScheme::kUnencrypted, base::TimeDelta(), 0); ResetStream<>(audio_config_); // Equivalent to 2ms per frame. @@ -3892,7 +3892,8 @@ // Test all the valid same timestamp cases for audio. TEST_F(SourceBufferStreamTest, SameTimestamp_Audio) { AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, - 44100, EmptyExtraData(), Unencrypted()); + 44100, EmptyExtraData(), + EncryptionScheme::kUnencrypted); ResetStream<>(config); Seek(0); NewCodedFrameGroupAppend("0K 0K 30K 30K"); @@ -4518,9 +4519,9 @@ EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(1250, 250)); video_config_ = TestVideoConfig::Invalid(); - audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, - CHANNEL_LAYOUT_STEREO, 4000, EmptyExtraData(), - Unencrypted(), base::TimeDelta(), 0); + audio_config_.Initialize( + kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 4000, + EmptyExtraData(), EncryptionScheme::kUnencrypted, base::TimeDelta(), 0); ResetStream<>(audio_config_); // Equivalent to 0.5ms per frame. SetStreamInfo(2000, 2000); @@ -4553,7 +4554,7 @@ TEST_F(SourceBufferStreamTest, Audio_ConfigChangeWithPreroll) { AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_MONO, 2000, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); SetAudioStream(); Seek(0); @@ -4598,8 +4599,8 @@ video_config_ = TestVideoConfig::Invalid(); audio_config_.Initialize(kCodecOpus, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(), - Unencrypted(), base::TimeDelta::FromMilliseconds(10), - 0); + EncryptionScheme::kUnencrypted, + base::TimeDelta::FromMilliseconds(10), 0); ResetStream<>(audio_config_); // Equivalent to 1s per frame.
diff --git a/media/filters/vpx_video_decoder_fuzzertest.cc b/media/filters/vpx_video_decoder_fuzzertest.cc index b501176..d7e6b835 100644 --- a/media/filters/vpx_video_decoder_fuzzertest.cc +++ b/media/filters/vpx_video_decoder_fuzzertest.cc
@@ -92,7 +92,7 @@ : media::VideoDecoderConfig::AlphaMode::kIsOpaque, color_space, media::VideoTransformation(rotation, reflection), coded_size, visible_rect, natural_size, media::EmptyExtraData(), - media::Unencrypted()); + media::EncryptionScheme::kUnencrypted); if (!config.IsValidConfig()) return 0;
diff --git a/media/formats/mp2t/descriptors.cc b/media/formats/mp2t/descriptors.cc index a0a771e..7d06dc97 100644 --- a/media/formats/mp2t/descriptors.cc +++ b/media/formats/mp2t/descriptors.cc
@@ -114,7 +114,7 @@ bool Descriptors::HasCADescriptorCenc(int* ca_pid, int* pssh_pid, - EncryptionMode* mode) const { + EncryptionScheme* scheme) const { DCHECK(ca_pid); DCHECK(pssh_pid); int system_id; @@ -145,7 +145,7 @@ RCHECK(reader.ReadBits(13, pssh_pid)); // The pattern is actually set differently for audio and video, so OK not to // set it here. Important thing is to set the cipher mode. - *mode = EncryptionMode::kCbcs; + *scheme = EncryptionScheme::kCbcs; return true; }
diff --git a/media/formats/mp2t/descriptors.h b/media/formats/mp2t/descriptors.h index 8e444f8..ad55322 100644 --- a/media/formats/mp2t/descriptors.h +++ b/media/formats/mp2t/descriptors.h
@@ -52,7 +52,7 @@ // |pssh_pid| and |mode| are populated with the contents of the descriptor. bool HasCADescriptorCenc(int* ca_pid, int* pssh_pid, - EncryptionMode* mode) const; + EncryptionScheme* scheme) const; // Indicates whether a Private Data Indicator descriptor is present with a // particular |value|.
diff --git a/media/formats/mp2t/es_adapter_video_unittest.cc b/media/formats/mp2t/es_adapter_video_unittest.cc index 228a969..00cacb21 100644 --- a/media/formats/mp2t/es_adapter_video_unittest.cc +++ b/media/formats/mp2t/es_adapter_video_unittest.cc
@@ -35,7 +35,7 @@ return VideoDecoderConfig( kCodecH264, H264PROFILE_MAIN, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, coded_size, visible_rect, - natural_size, EmptyExtraData(), Unencrypted()); + natural_size, EmptyExtraData(), EncryptionScheme::kUnencrypted); } BufferQueue GenerateFakeBuffers(const int* frame_pts_ms,
diff --git a/media/formats/mp2t/es_parser_adts.cc b/media/formats/mp2t/es_parser_adts.cc index 1834049..63aa3acd 100644 --- a/media/formats/mp2t/es_parser_adts.cc +++ b/media/formats/mp2t/es_parser_adts.cc
@@ -217,7 +217,7 @@ CalculateSubsamplesForAdtsFrame(adts_frame, &subsamples); stream_parser_buffer->set_decrypt_config( std::make_unique<DecryptConfig>( - base_decrypt_config->encryption_mode(), + base_decrypt_config->encryption_scheme(), base_decrypt_config->key_id(), base_decrypt_config->iv(), subsamples, EncryptionPattern())); } @@ -260,11 +260,10 @@ const int extended_samples_per_second = sbr_in_mimetype_ ? std::min(2 * orig_sample_rate, 48000) : orig_sample_rate; - EncryptionScheme scheme = Unencrypted(); + EncryptionScheme scheme = EncryptionScheme::kUnencrypted; #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) if (use_hls_sample_aes_) { - scheme = EncryptionScheme(EncryptionScheme::CIPHER_MODE_AES_CBC, - EncryptionPattern()); + scheme = EncryptionScheme::kCbcs; } #endif AudioDecoderConfig audio_decoder_config(
diff --git a/media/formats/mp2t/es_parser_h264.cc b/media/formats/mp2t/es_parser_h264.cc index f48337d..fe03ac6 100644 --- a/media/formats/mp2t/es_parser_h264.cc +++ b/media/formats/mp2t/es_parser_h264.cc
@@ -418,13 +418,11 @@ const H264SPS* sps = h264_parser_->GetSPS(pps->seq_parameter_set_id); if (!sps) return false; - EncryptionScheme scheme = Unencrypted(); + EncryptionScheme scheme = EncryptionScheme::kUnencrypted; #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) if (use_hls_sample_aes_) { // Note that for SampleAES the (encrypt,skip) pattern is constant. - scheme = EncryptionScheme( - EncryptionScheme::CIPHER_MODE_AES_CBC, - EncryptionPattern(kSampleAESEncryptBlocks, kSampleAESSkipBlocks)); + scheme = EncryptionScheme::kCbcs; } #endif RCHECK(UpdateVideoDecoderConfig(sps, scheme)); @@ -465,19 +463,19 @@ stream_parser_buffer->set_timestamp(current_timing_desc.pts); #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) if (use_hls_sample_aes_ && base_decrypt_config) { - switch (base_decrypt_config->encryption_mode()) { - case EncryptionMode::kUnencrypted: + switch (base_decrypt_config->encryption_scheme()) { + case EncryptionScheme::kUnencrypted: // As |base_decrypt_config| is specified, the stream is encrypted, // so this shouldn't happen. NOTREACHED(); break; - case EncryptionMode::kCenc: + case EncryptionScheme::kCenc: stream_parser_buffer->set_decrypt_config( DecryptConfig::CreateCencConfig(base_decrypt_config->key_id(), base_decrypt_config->iv(), subsamples)); break; - case EncryptionMode::kCbcs: + case EncryptionScheme::kCbcs: // Note that for SampleAES the (encrypt,skip) pattern is constant. // If not specified in |base_decrypt_config|, use default values. stream_parser_buffer->set_decrypt_config( @@ -494,7 +492,7 @@ } bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps, - const EncryptionScheme& scheme) { + EncryptionScheme scheme) { // Set the SAR to 1 when not specified in the H264 stream. int sar_width = (sps->sar_width == 0) ? 1 : sps->sar_width; int sar_height = (sps->sar_height == 0) ? 1 : sps->sar_height;
diff --git a/media/formats/mp2t/es_parser_h264.h b/media/formats/mp2t/es_parser_h264.h index 5e22635..98e6ff0 100644 --- a/media/formats/mp2t/es_parser_h264.h +++ b/media/formats/mp2t/es_parser_h264.h
@@ -22,7 +22,6 @@ #include "media/media_buildflags.h" namespace media { -class EncryptionScheme; class H264Parser; struct H264SPS; } @@ -77,8 +76,7 @@ // Update the video decoder config based on an H264 SPS. // Return true if successful. - bool UpdateVideoDecoderConfig(const H264SPS* sps, - const EncryptionScheme& scheme); + bool UpdateVideoDecoderConfig(const H264SPS* sps, EncryptionScheme scheme); EsAdapterVideo es_adapter_;
diff --git a/media/formats/mp2t/es_parser_mpeg1audio.cc b/media/formats/mp2t/es_parser_mpeg1audio.cc index 1e1cb06..efcd7a1 100644 --- a/media/formats/mp2t/es_parser_mpeg1audio.cc +++ b/media/formats/mp2t/es_parser_mpeg1audio.cc
@@ -169,7 +169,7 @@ // field for Mpeg1 audio. If yes, we should generate this field. AudioDecoderConfig audio_decoder_config( kCodecMP3, kSampleFormatS16, header.channel_layout, header.sample_rate, - EmptyExtraData(), Unencrypted()); + EmptyExtraData(), EncryptionScheme::kUnencrypted); if (!audio_decoder_config.IsValidConfig()) { DVLOG(1) << "Invalid config: "
diff --git a/media/formats/mp2t/mp2t_stream_parser.cc b/media/formats/mp2t/mp2t_stream_parser.cc index 41621a21..1d55087 100644 --- a/media/formats/mp2t/mp2t_stream_parser.cc +++ b/media/formats/mp2t/mp2t_stream_parser.cc
@@ -429,7 +429,7 @@ // use of the encrypted parser variant so that the initial configuration // reflects the intended encryption mode (even if the initial segment itself // is not encrypted). - return initial_encryption_mode_ != EncryptionMode::kUnencrypted; + return initial_encryption_scheme_ != EncryptionScheme::kUnencrypted; } std::unique_ptr<EsParser> Mp2tStreamParser::CreateEncryptedH264Parser( @@ -833,7 +833,7 @@ std::unique_ptr<TsSection> cat_section_parser(new TsSectionCat( base::BindRepeating(&Mp2tStreamParser::RegisterCencPids, base::Unretained(this)), - base::BindRepeating(&Mp2tStreamParser::RegisterEncryptionMode, + base::BindRepeating(&Mp2tStreamParser::RegisterEncryptionScheme, base::Unretained(this)))); std::unique_ptr<PidState> cat_pid_state(new PidState( TsSection::kPidCat, PidState::kPidCat, std::move(cat_section_parser))); @@ -883,10 +883,10 @@ } } -void Mp2tStreamParser::RegisterEncryptionMode(EncryptionMode mode) { +void Mp2tStreamParser::RegisterEncryptionScheme(EncryptionScheme scheme) { // We only need to record this for the initial decoder config. if (!is_initialized_) { - initial_encryption_mode_ = mode; + initial_encryption_scheme_ = scheme; } // Reset the DecryptConfig, so that unless and until a CENC-ECM (containing // key id and IV) is seen, media data will be considered unencrypted. This is @@ -897,14 +897,14 @@ void Mp2tStreamParser::RegisterNewKeyIdAndIv(const std::string& key_id, const std::string& iv) { if (!iv.empty()) { - switch (initial_encryption_mode_) { - case EncryptionMode::kUnencrypted: + switch (initial_encryption_scheme_) { + case EncryptionScheme::kUnencrypted: decrypt_config_.reset(); break; - case EncryptionMode::kCenc: + case EncryptionScheme::kCenc: decrypt_config_ = DecryptConfig::CreateCencConfig(key_id, iv, {}); break; - case EncryptionMode::kCbcs: + case EncryptionScheme::kCbcs: decrypt_config_ = DecryptConfig::CreateCbcsConfig(key_id, iv, {}, base::nullopt); break;
diff --git a/media/formats/mp2t/mp2t_stream_parser.h b/media/formats/mp2t/mp2t_stream_parser.h index ffa5ab16a..81f127f 100644 --- a/media/formats/mp2t/mp2t_stream_parser.h +++ b/media/formats/mp2t/mp2t_stream_parser.h
@@ -122,7 +122,7 @@ // Register a default encryption mode to be used for decoder configs. This // value is only used in the absence of explicit encryption metadata, as might // be the case during an unencrypted portion of a live stream. - void RegisterEncryptionMode(EncryptionMode mode); + void RegisterEncryptionScheme(EncryptionScheme scheme); // Register the new KeyID and IV (parsed from CENC-ECM). void RegisterNewKeyIdAndIv(const std::string& key_id, const std::string& iv); @@ -171,7 +171,7 @@ TimestampUnroller timestamp_unroller_; #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) - EncryptionMode initial_encryption_mode_ = EncryptionMode::kUnencrypted; + EncryptionScheme initial_encryption_scheme_ = EncryptionScheme::kUnencrypted; // TODO(jrummell): Rather than store the key_id and iv in a DecryptConfig, // provide a better way to access the last values seen in a ECM packet.
diff --git a/media/formats/mp2t/mp2t_stream_parser_unittest.cc b/media/formats/mp2t/mp2t_stream_parser_unittest.cc index bd1590a..3119e4f 100644 --- a/media/formats/mp2t/mp2t_stream_parser_unittest.cc +++ b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
@@ -124,15 +124,15 @@ // We only support AES-CBC at this time. // For the purpose of these tests, the key id is also used as the actual key. std::string DecryptBuffer(const StreamParserBuffer& buffer, - const EncryptionScheme& scheme) { - EXPECT_TRUE(scheme.is_encrypted()); - EXPECT_TRUE(scheme.mode() == EncryptionScheme::CIPHER_MODE_AES_CBC); + EncryptionScheme scheme) { + EXPECT_EQ(scheme, EncryptionScheme::kCbcs); // Audio streams use whole block full sample encryption (so pattern = {0,0}), // so only the video stream uses pattern decryption. |has_pattern| is only // used by DecryptSampleAES(), which assumes a {1,9} pattern if // |has_pattern| = true. - bool has_pattern = scheme.pattern() == EncryptionPattern(1, 9); + bool has_pattern = + buffer.decrypt_config()->encryption_pattern() == EncryptionPattern(1, 9); std::string key; EXPECT_TRUE( @@ -472,7 +472,7 @@ parser_->Flush(); EncryptionScheme video_encryption_scheme = current_video_config_.encryption_scheme(); - EXPECT_TRUE(video_encryption_scheme.is_encrypted()); + EXPECT_NE(video_encryption_scheme, EncryptionScheme::kUnencrypted); for (const auto& buffer : video_buffer_capture_) { std::string decrypted_video_buffer = DecryptBuffer(*buffer.get(), video_encryption_scheme); @@ -480,7 +480,7 @@ } EncryptionScheme audio_encryption_scheme = current_audio_config_.encryption_scheme(); - EXPECT_TRUE(audio_encryption_scheme.is_encrypted()); + EXPECT_NE(audio_encryption_scheme, EncryptionScheme::kUnencrypted); for (const auto& buffer : audio_buffer_capture_) { std::string decrypted_audio_buffer = DecryptBuffer(*buffer.get(), audio_encryption_scheme); @@ -495,7 +495,7 @@ ParseMpeg2TsFile("bear-1280x720-hls.ts", 2048); parser_->Flush(); video_encryption_scheme = current_video_config_.encryption_scheme(); - EXPECT_FALSE(video_encryption_scheme.is_encrypted()); + EXPECT_EQ(video_encryption_scheme, EncryptionScheme::kUnencrypted); // Skip the last buffer, which may be truncated. for (size_t i = 0; i + 1 < video_buffer_capture_.size(); i++) { const auto& buffer = video_buffer_capture_[i]; @@ -504,7 +504,7 @@ EXPECT_EQ(decrypted_video_buffers[i], unencrypted_video_buffer); } audio_encryption_scheme = current_audio_config_.encryption_scheme(); - EXPECT_FALSE(audio_encryption_scheme.is_encrypted()); + EXPECT_EQ(audio_encryption_scheme, EncryptionScheme::kUnencrypted); for (size_t i = 0; i + 1 < audio_buffer_capture_.size(); i++) { const auto& buffer = audio_buffer_capture_[i]; std::string unencrypted_audio_buffer( @@ -519,10 +519,10 @@ parser_->Flush(); EncryptionScheme video_encryption_scheme = current_video_config_.encryption_scheme(); - EXPECT_TRUE(video_encryption_scheme.is_encrypted()); + EXPECT_NE(video_encryption_scheme, EncryptionScheme::kUnencrypted); EncryptionScheme audio_encryption_scheme = current_audio_config_.encryption_scheme(); - EXPECT_TRUE(audio_encryption_scheme.is_encrypted()); + EXPECT_NE(audio_encryption_scheme, EncryptionScheme::kUnencrypted); } #endif
diff --git a/media/formats/mp2t/ts_section_cat.cc b/media/formats/mp2t/ts_section_cat.cc index a9239fbd..507a789 100644 --- a/media/formats/mp2t/ts_section_cat.cc +++ b/media/formats/mp2t/ts_section_cat.cc
@@ -16,9 +16,9 @@ TsSectionCat::TsSectionCat( const RegisterCencPidsCb& register_cenc_ids_cb, - const RegisterEncryptionModeCb& register_encryption_mode_cb) + const RegisterEncryptionSchemeCb& register_encryption_scheme_cb) : register_cenc_ids_cb_(register_cenc_ids_cb), - register_encryption_mode_cb_(register_encryption_mode_cb), + register_encryption_scheme_cb_(register_encryption_scheme_cb), version_number_(-1) {} TsSectionCat::~TsSectionCat() {} @@ -58,9 +58,9 @@ Descriptors descriptors; int ca_pid, pssh_pid; - EncryptionMode mode; + EncryptionScheme scheme; RCHECK(descriptors.Read(bit_reader, section_length - 4)); - RCHECK(descriptors.HasCADescriptorCenc(&ca_pid, &pssh_pid, &mode)); + RCHECK(descriptors.HasCADescriptorCenc(&ca_pid, &pssh_pid, &scheme)); int crc32; RCHECK(bit_reader->ReadBits(32, &crc32)); @@ -76,7 +76,7 @@ // Can now register the PIDs and scheme. register_cenc_ids_cb_.Run(ca_pid, pssh_pid); - register_encryption_mode_cb_.Run(mode); + register_encryption_scheme_cb_.Run(scheme); version_number_ = version_number;
diff --git a/media/formats/mp2t/ts_section_cat.h b/media/formats/mp2t/ts_section_cat.h index 637aec8..c929fad 100644 --- a/media/formats/mp2t/ts_section_cat.h +++ b/media/formats/mp2t/ts_section_cat.h
@@ -7,7 +7,7 @@ #include "base/callback.h" #include "base/macros.h" -#include "media/base/decrypt_config.h" +#include "media/base/encryption_scheme.h" #include "media/formats/mp2t/ts_section_psi.h" namespace media { @@ -17,11 +17,11 @@ public: // RegisterCencPidsCb::Run(int ca_pid, int pssh_pid); using RegisterCencPidsCb = base::RepeatingCallback<void(int, int)>; - // RegisterEncryptionMode::Run(EncryptionMode mode); - using RegisterEncryptionModeCb = - base::RepeatingCallback<void(EncryptionMode)>; + // RegisterEncryptionScheme::Run(EncryptionScheme scheme); + using RegisterEncryptionSchemeCb = + base::RepeatingCallback<void(EncryptionScheme)>; TsSectionCat(const RegisterCencPidsCb& register_cenc_ids_cb, - const RegisterEncryptionModeCb& register_encryption_mode_cb); + const RegisterEncryptionSchemeCb& register_encryption_scheme_cb); ~TsSectionCat() override; // TsSectionPsi implementation. @@ -30,7 +30,7 @@ private: RegisterCencPidsCb register_cenc_ids_cb_; - RegisterEncryptionModeCb register_encryption_mode_cb_; + RegisterEncryptionSchemeCb register_encryption_scheme_cb_; // Parameters from the CAT. int version_number_;
diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc index 60fc9932..550b2e9 100644 --- a/media/formats/mp4/mp4_stream_parser.cc +++ b/media/formats/mp4/mp4_stream_parser.cc
@@ -42,33 +42,22 @@ const int kMaxInvalidConversionLogs = 20; const int kMaxVideoKeyframeMismatchLogs = 10; -// Caller should be prepared to handle return of Unencrypted() in case of -// unsupported scheme. -// TODO(crbug.com/825041): Remove pattern from this function. +// Caller should be prepared to handle return of EncryptionScheme::kUnencrypted +// in case of unsupported scheme. EncryptionScheme GetEncryptionScheme(const ProtectionSchemeInfo& sinf) { if (!sinf.HasSupportedScheme()) - return Unencrypted(); + return EncryptionScheme::kUnencrypted; FourCC fourcc = sinf.type.type; - EncryptionScheme::CipherMode mode = EncryptionScheme::CIPHER_MODE_UNENCRYPTED; - EncryptionPattern pattern; - bool uses_pattern_encryption = false; switch (fourcc) { case FOURCC_CENC: - mode = EncryptionScheme::CIPHER_MODE_AES_CTR; - break; + return EncryptionScheme::kCenc; case FOURCC_CBCS: - mode = EncryptionScheme::CIPHER_MODE_AES_CBC; - uses_pattern_encryption = true; - break; + return EncryptionScheme::kCbcs; default: NOTREACHED(); break; } - if (uses_pattern_encryption) { - pattern = {sinf.info.track_encryption.default_crypt_byte_block, - sinf.info.track_encryption.default_skip_byte_block}; - } - return EncryptionScheme(mode, pattern); + return EncryptionScheme::kUnencrypted; } } // namespace @@ -442,10 +431,10 @@ return false; } bool is_track_encrypted = entry.sinf.info.track_encryption.is_encrypted; - EncryptionScheme scheme = Unencrypted(); + EncryptionScheme scheme = EncryptionScheme::kUnencrypted; if (is_track_encrypted) { scheme = GetEncryptionScheme(entry.sinf); - if (!scheme.is_encrypted()) + if (scheme == EncryptionScheme::kUnencrypted) return false; } audio_config.Initialize(codec, sample_format, channel_layout, @@ -511,10 +500,10 @@ return false; } bool is_track_encrypted = entry.sinf.info.track_encryption.is_encrypted; - EncryptionScheme scheme = Unencrypted(); + EncryptionScheme scheme = EncryptionScheme::kUnencrypted; if (is_track_encrypted) { scheme = GetEncryptionScheme(entry.sinf); - if (!scheme.is_encrypted()) + if (scheme == EncryptionScheme::kUnencrypted) return false; } video_config.Initialize(entry.video_codec, entry.video_codec_profile, @@ -838,7 +827,7 @@ if (!subsamples.empty()) { // Create a new config with the updated subsamples. decrypt_config.reset( - new DecryptConfig(decrypt_config->encryption_mode(), + new DecryptConfig(decrypt_config->encryption_scheme(), decrypt_config->key_id(), decrypt_config->iv(), subsamples, decrypt_config->encryption_pattern())); }
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc index 91e0f822d..cda6de3 100644 --- a/media/formats/mp4/track_run_iterator.cc +++ b/media/formats/mp4/track_run_iterator.cc
@@ -16,6 +16,7 @@ #include "media/base/decrypt_config.h" #include "media/base/demuxer_memory_limit.h" #include "media/base/encryption_pattern.h" +#include "media/base/encryption_scheme.h" #include "media/base/media_util.h" #include "media/base/timestamp_constants.h" #include "media/formats/mp4/rcheck.h" @@ -56,7 +57,7 @@ std::vector<uint8_t> aux_info_sizes; // Populated if default_size == 0. int aux_info_total_size; - EncryptionMode encryption_mode; + EncryptionScheme encryption_scheme = EncryptionScheme::kUnencrypted; EncryptionPattern encryption_pattern; std::vector<CencSampleEncryptionInfoEntry> fragment_sample_encryption_info; @@ -372,11 +373,11 @@ } if (!sinf->HasSupportedScheme()) { - tri.encryption_mode = EncryptionMode::kUnencrypted; + tri.encryption_scheme = EncryptionScheme::kUnencrypted; } else { - tri.encryption_mode = sinf->IsCbcsEncryptionScheme() - ? EncryptionMode::kCbcs - : EncryptionMode::kCenc; + tri.encryption_scheme = sinf->IsCbcsEncryptionScheme() + ? EncryptionScheme::kCbcs + : EncryptionScheme::kCenc; tri.encryption_pattern = EncryptionPattern(track_encryption->default_crypt_byte_block, track_encryption->default_skip_byte_block); @@ -747,13 +748,13 @@ std::string iv(reinterpret_cast<const char*>( sample_encryption_entry.initialization_vector), base::size(sample_encryption_entry.initialization_vector)); - switch (run_itr_->encryption_mode) { - case EncryptionMode::kUnencrypted: + switch (run_itr_->encryption_scheme) { + case EncryptionScheme::kUnencrypted: return nullptr; - case EncryptionMode::kCenc: + case EncryptionScheme::kCenc: return DecryptConfig::CreateCencConfig( key_id, iv, sample_encryption_entry.subsamples); - case EncryptionMode::kCbcs: + case EncryptionScheme::kCbcs: return DecryptConfig::CreateCbcsConfig( key_id, iv, sample_encryption_entry.subsamples, run_itr_->encryption_pattern);
diff --git a/media/formats/mpeg/mpeg_audio_stream_parser_base.cc b/media/formats/mpeg/mpeg_audio_stream_parser_base.cc index 137bfa4..b5fed3d 100644 --- a/media/formats/mpeg/mpeg_audio_stream_parser_base.cc +++ b/media/formats/mpeg/mpeg_audio_stream_parser_base.cc
@@ -211,7 +211,7 @@ if (!config_.IsValidConfig()) { config_.Initialize(audio_codec_, kSampleFormatF32, channel_layout, - sample_rate, extra_data, Unencrypted(), + sample_rate, extra_data, EncryptionScheme::kUnencrypted, base::TimeDelta(), codec_delay_); if (audio_codec_ == kCodecAAC) config_.disable_discard_decoder_delay();
diff --git a/media/formats/webm/webm_audio_client.cc b/media/formats/webm/webm_audio_client.cc index 6eff0dd..5ac98e8e 100644 --- a/media/formats/webm/webm_audio_client.cc +++ b/media/formats/webm/webm_audio_client.cc
@@ -27,7 +27,7 @@ const std::vector<uint8_t>& codec_private, int64_t seek_preroll, int64_t codec_delay, - const EncryptionScheme& encryption_scheme, + EncryptionScheme encryption_scheme, AudioDecoderConfig* config) { DCHECK(config); SampleFormat sample_format = kSampleFormatPlanarF32;
diff --git a/media/formats/webm/webm_audio_client.h b/media/formats/webm/webm_audio_client.h index 5b3357da..ab65867 100644 --- a/media/formats/webm/webm_audio_client.h +++ b/media/formats/webm/webm_audio_client.h
@@ -11,12 +11,12 @@ #include <vector> #include "base/macros.h" +#include "media/base/encryption_scheme.h" #include "media/base/media_log.h" #include "media/formats/webm/webm_parser.h" namespace media { class AudioDecoderConfig; -class EncryptionScheme; // Helper class used to parse an Audio element inside a TrackEntry element. class WebMAudioClient : public WebMParserClient { @@ -37,7 +37,7 @@ const std::vector<uint8_t>& codec_private, const int64_t seek_preroll, const int64_t codec_delay, - const EncryptionScheme& encryption_scheme, + EncryptionScheme encryption_scheme, AudioDecoderConfig* config); private:
diff --git a/media/formats/webm/webm_tracks_parser.cc b/media/formats/webm/webm_tracks_parser.cc index 6ae7ce8..b9a1179 100644 --- a/media/formats/webm/webm_tracks_parser.cc +++ b/media/formats/webm/webm_tracks_parser.cc
@@ -205,8 +205,9 @@ content_encodings()[0]->encryption_key_id(); } - EncryptionScheme encryption_scheme = - encryption_key_id.empty() ? Unencrypted() : AesCtrEncryptionScheme(); + EncryptionScheme encryption_scheme = encryption_key_id.empty() + ? EncryptionScheme::kUnencrypted + : EncryptionScheme::kCenc; if (track_type_ == kWebMTrackTypeAudio) { detected_audio_track_count_++;
diff --git a/media/formats/webm/webm_video_client.cc b/media/formats/webm/webm_video_client.cc index 1500ff5..9eba79d 100644 --- a/media/formats/webm/webm_video_client.cc +++ b/media/formats/webm/webm_video_client.cc
@@ -53,7 +53,7 @@ bool WebMVideoClient::InitializeConfig( const std::string& codec_id, const std::vector<uint8_t>& codec_private, - const EncryptionScheme& encryption_scheme, + EncryptionScheme encryption_scheme, VideoDecoderConfig* config) { DCHECK(config);
diff --git a/media/formats/webm/webm_video_client.h b/media/formats/webm/webm_video_client.h index f245ff9..3c15c463 100644 --- a/media/formats/webm/webm_video_client.h +++ b/media/formats/webm/webm_video_client.h
@@ -11,13 +11,13 @@ #include <vector> #include "base/macros.h" +#include "media/base/encryption_scheme.h" #include "media/base/media_export.h" #include "media/base/media_log.h" #include "media/formats/webm/webm_colour_parser.h" #include "media/formats/webm/webm_parser.h" namespace media { -class EncryptionScheme; class VideoDecoderConfig; // Helper class used to parse a Video element inside a TrackEntry element. @@ -38,7 +38,7 @@ // case and should not be relied upon. bool InitializeConfig(const std::string& codec_id, const std::vector<uint8_t>& codec_private, - const EncryptionScheme& encryption_scheme, + EncryptionScheme encryption_scheme, VideoDecoderConfig* config); private:
diff --git a/media/formats/webm/webm_video_client_unittest.cc b/media/formats/webm/webm_video_client_unittest.cc index 4cc41190..cfc73ccc 100644 --- a/media/formats/webm/webm_video_client_unittest.cc +++ b/media/formats/webm/webm_video_client_unittest.cc
@@ -140,7 +140,8 @@ VideoDecoderConfig expected_config( kCodecVP9, profile, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, kCodedSize, - gfx::Rect(kCodedSize), kCodedSize, codec_private, Unencrypted()); + gfx::Rect(kCodedSize), kCodedSize, codec_private, + EncryptionScheme::kUnencrypted); EXPECT_TRUE(config.Matches(expected_config)) << "Config (" << config.AsHumanReadableString()
diff --git a/media/fuchsia/cdm/fuchsia_stream_decryptor.cc b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc index 1281e589..9c3ebb1 100644 --- a/media/fuchsia/cdm/fuchsia_stream_decryptor.cc +++ b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
@@ -25,11 +25,11 @@ // available, so it doesn't need more than one output buffer. const size_t kMinClearStreamOutputFrames = 1; -std::string GetEncryptionScheme(EncryptionMode mode) { +std::string GetEncryptionScheme(EncryptionScheme mode) { switch (mode) { - case EncryptionMode::kCenc: + case EncryptionScheme::kCenc: return fuchsia::media::ENCRYPTION_SCHEME_CENC; - case EncryptionMode::kCbcs: + case EncryptionScheme::kCbcs: return fuchsia::media::ENCRYPTION_SCHEME_CBCS; default: NOTREACHED() << "unknown encryption mode " << static_cast<int>(mode); @@ -89,13 +89,13 @@ DCHECK(config); fuchsia::media::EncryptedFormat encrypted_format; - encrypted_format.set_scheme(GetEncryptionScheme(config->encryption_mode())) + encrypted_format.set_scheme(GetEncryptionScheme(config->encryption_scheme())) .set_key_id(std::vector<uint8_t>(config->key_id().begin(), config->key_id().end())) .set_init_vector( std::vector<uint8_t>(config->iv().begin(), config->iv().end())) .set_subsamples(GetSubsamples(config->subsamples())); - if (config->encryption_mode() == EncryptionMode::kCbcs) { + if (config->encryption_scheme() == EncryptionScheme::kCbcs) { DCHECK(config->encryption_pattern().has_value()); encrypted_format.set_pattern( GetEncryptionPattern(config->encryption_pattern().value()));
diff --git a/media/gpu/android/codec_wrapper.cc b/media/gpu/android/codec_wrapper.cc index dc0037ff..a89cc16 100644 --- a/media/gpu/android/codec_wrapper.cc +++ b/media/gpu/android/codec_wrapper.cc
@@ -262,7 +262,7 @@ status = codec_->QueueSecureInputBuffer( input_buffer, buffer.data(), buffer.data_size(), decrypt_config->key_id(), decrypt_config->iv(), - decrypt_config->subsamples(), decrypt_config->encryption_mode(), + decrypt_config->subsamples(), decrypt_config->encryption_scheme(), decrypt_config->encryption_pattern(), buffer.timestamp()); } else { status = codec_->QueueInputBuffer(input_buffer, buffer.data(),
diff --git a/media/gpu/ipc/service/vda_video_decoder_unittest.cc b/media/gpu/ipc/service/vda_video_decoder_unittest.cc index b81c1c35..335f0653 100644 --- a/media/gpu/ipc/service/vda_video_decoder_unittest.cc +++ b/media/gpu/ipc/service/vda_video_decoder_unittest.cc
@@ -144,7 +144,8 @@ kCodecVP9, VP9PROFILE_PROFILE0, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, gfx::Size(1920, 1088), gfx::Rect(1920, 1080), - gfx::Size(1920, 1080), EmptyExtraData(), Unencrypted())); + gfx::Size(1920, 1080), EmptyExtraData(), + EncryptionScheme::kUnencrypted)); RunUntilIdle(); } @@ -321,7 +322,7 @@ kCodecVP9, VP9PROFILE_PROFILE0, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC601(), kNoTransformation, gfx::Size(320, 240), gfx::Rect(320, 240), gfx::Size(320, 240), EmptyExtraData(), - Unencrypted())); + EncryptionScheme::kUnencrypted)); EXPECT_CALL(init_cb_, Run(false)); RunUntilIdle(); } @@ -331,7 +332,7 @@ kCodecH264, H264PROFILE_BASELINE, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, gfx::Size(1920, 1088), gfx::Rect(1920, 1080), - gfx::Size(1920, 1080), EmptyExtraData(), Unencrypted())); + gfx::Size(1920, 1080), EmptyExtraData(), EncryptionScheme::kUnencrypted)); EXPECT_CALL(init_cb_, Run(false)); RunUntilIdle(); } @@ -342,7 +343,7 @@ kCodecVP9, VP9PROFILE_PROFILE0, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, gfx::Size(1920, 1088), gfx::Rect(1920, 1080), gfx::Size(1920, 1080), EmptyExtraData(), - Unencrypted())); + EncryptionScheme::kUnencrypted)); EXPECT_CALL(init_cb_, Run(false)); RunUntilIdle(); } @@ -425,7 +426,7 @@ kCodecVP9, VP9PROFILE_PROFILE0, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, gfx::Size(640, 480), gfx::Rect(640, 480), gfx::Size(1280, 480), EmptyExtraData(), - Unencrypted())); + EncryptionScheme::kUnencrypted)); EXPECT_CALL(init_cb_, Run(true)); RunUntilIdle();
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc index b69c904..7834f03 100644 --- a/media/gpu/video_encode_accelerator_unittest.cc +++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -1170,17 +1170,17 @@ if (IsVP8(profile_)) { config.Initialize(kCodecVP8, VP8PROFILE_ANY, alpha_mode, VideoColorSpace(), kNoTransformation, coded_size, visible_size, natural_size, - EmptyExtraData(), Unencrypted()); + EmptyExtraData(), EncryptionScheme::kUnencrypted); } else if (IsVP9(profile_)) { config.Initialize(kCodecVP9, VP9PROFILE_PROFILE0, alpha_mode, VideoColorSpace(), kNoTransformation, coded_size, visible_size, natural_size, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); } else if (IsH264(profile_)) { config.Initialize(kCodecH264, H264PROFILE_MAIN, alpha_mode, VideoColorSpace(), kNoTransformation, coded_size, visible_size, natural_size, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); } else { LOG_ASSERT(0) << "Invalid profile " << GetProfileName(profile_); }
diff --git a/media/gpu/windows/d3d11_texture_selector_unittest.cc b/media/gpu/windows/d3d11_texture_selector_unittest.cc index b24a372..84748886 100644 --- a/media/gpu/windows/d3d11_texture_selector_unittest.cc +++ b/media/gpu/windows/d3d11_texture_selector_unittest.cc
@@ -25,14 +25,11 @@ gfx::Size size, bool encrypted) { VideoDecoderConfig result; - EncryptionPattern pattern; result.Initialize( kUnknownVideoCodec, // It doesn't matter because it won't be used. profile, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, size, {}, {}, {}, - EncryptionScheme(encrypted ? EncryptionScheme::CIPHER_MODE_AES_CTR - : EncryptionScheme::CIPHER_MODE_UNENCRYPTED, - pattern)); + encrypted ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted); return result; }
diff --git a/media/mojo/clients/mojo_audio_decoder_unittest.cc b/media/mojo/clients/mojo_audio_decoder_unittest.cc index 22efe050..6946df7 100644 --- a/media/mojo/clients/mojo_audio_decoder_unittest.cc +++ b/media/mojo/clients/mojo_audio_decoder_unittest.cc
@@ -142,7 +142,7 @@ AudioDecoderConfig audio_config(kCodecVorbis, kSampleFormat, kChannelLayout, kDefaultSampleRate, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); mojo_audio_decoder_->Initialize( audio_config, nullptr,
diff --git a/media/mojo/common/media_type_converters.cc b/media/mojo/common/media_type_converters.cc index 012d818..9337748 100644 --- a/media/mojo/common/media_type_converters.cc +++ b/media/mojo/common/media_type_converters.cc
@@ -29,7 +29,7 @@ mojo_decrypt_config->key_id = input.key_id(); mojo_decrypt_config->iv = input.iv(); mojo_decrypt_config->subsamples = input.subsamples(); - mojo_decrypt_config->encryption_mode = input.encryption_mode(); + mojo_decrypt_config->encryption_scheme = input.encryption_scheme(); mojo_decrypt_config->encryption_pattern = input.encryption_pattern(); return mojo_decrypt_config; @@ -41,7 +41,7 @@ media::mojom::DecryptConfigPtr>:: Convert(const media::mojom::DecryptConfigPtr& input) { return std::make_unique<media::DecryptConfig>( - input->encryption_mode, input->key_id, input->iv, input->subsamples, + input->encryption_scheme, input->key_id, input->iv, input->subsamples, input->encryption_pattern); }
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn index 6ff84fb..bf42227 100644 --- a/media/mojo/mojom/BUILD.gn +++ b/media/mojo/mojom/BUILD.gn
@@ -131,7 +131,6 @@ sources = [ "audio_decoder_config_mojom_traits_unittest.cc", "cdm_key_information_mojom_traits_unittest.cc", - "encryption_scheme_mojom_traits_unittest.cc", "video_decoder_config_mojom_traits_unittest.cc", "video_frame_mojom_traits_unittest.cc", ]
diff --git a/media/mojo/mojom/audio_decoder_config_mojom_traits.h b/media/mojo/mojom/audio_decoder_config_mojom_traits.h index a786d24..c95d33a 100644 --- a/media/mojo/mojom/audio_decoder_config_mojom_traits.h +++ b/media/mojo/mojom/audio_decoder_config_mojom_traits.h
@@ -7,7 +7,6 @@ #include "media/base/audio_decoder_config.h" #include "media/base/ipc/media_param_traits.h" -#include "media/mojo/mojom/encryption_scheme_mojom_traits.h" #include "media/mojo/mojom/media_types.mojom.h" namespace mojo { @@ -46,7 +45,7 @@ return input.codec_delay(); } - static const media::EncryptionScheme& encryption_scheme( + static media::EncryptionScheme encryption_scheme( const media::AudioDecoderConfig& input) { return input.encryption_scheme(); }
diff --git a/media/mojo/mojom/audio_decoder_config_mojom_traits_unittest.cc b/media/mojo/mojom/audio_decoder_config_mojom_traits_unittest.cc index f04e0cb3..16ea462 100644 --- a/media/mojo/mojom/audio_decoder_config_mojom_traits_unittest.cc +++ b/media/mojo/mojom/audio_decoder_config_mojom_traits_unittest.cc
@@ -21,7 +21,8 @@ AudioDecoderConfig input; input.Initialize(kCodecAAC, kSampleFormatU8, CHANNEL_LAYOUT_SURROUND, 48000, - kExtraDataVector, Unencrypted(), base::TimeDelta(), 0); + kExtraDataVector, EncryptionScheme::kUnencrypted, + base::TimeDelta(), 0); std::vector<uint8_t> data = media::mojom::AudioDecoderConfig::Serialize(&input); AudioDecoderConfig output; @@ -34,7 +35,8 @@ ConvertAudioDecoderConfig_EmptyExtraData) { AudioDecoderConfig input; input.Initialize(kCodecAAC, kSampleFormatU8, CHANNEL_LAYOUT_SURROUND, 48000, - EmptyExtraData(), Unencrypted(), base::TimeDelta(), 0); + EmptyExtraData(), EncryptionScheme::kUnencrypted, + base::TimeDelta(), 0); std::vector<uint8_t> data = media::mojom::AudioDecoderConfig::Serialize(&input); AudioDecoderConfig output; @@ -46,8 +48,8 @@ TEST(AudioDecoderConfigStructTraitsTest, ConvertAudioDecoderConfig_Encrypted) { AudioDecoderConfig input; input.Initialize(kCodecAAC, kSampleFormatU8, CHANNEL_LAYOUT_SURROUND, 48000, - EmptyExtraData(), AesCtrEncryptionScheme(), - base::TimeDelta(), 0); + EmptyExtraData(), EncryptionScheme::kCenc, base::TimeDelta(), + 0); std::vector<uint8_t> data = media::mojom::AudioDecoderConfig::Serialize(&input); AudioDecoderConfig output;
diff --git a/media/mojo/mojom/encryption_pattern.typemap b/media/mojo/mojom/encryption_pattern.typemap new file mode 100644 index 0000000..06e07e9 --- /dev/null +++ b/media/mojo/mojom/encryption_pattern.typemap
@@ -0,0 +1,24 @@ +# Copyright 2017 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. + +mojom = "//media/mojo/mojom/media_types.mojom" + +public_headers = [ "//media/base/encryption_pattern.h" ] + +traits_headers = [ "//media/mojo/mojom/encryption_pattern_mojom_traits.h" ] + +sources = [ + "//media/mojo/mojom/encryption_pattern_mojom_traits.cc", +] + +public_deps = [ + "//media", +] + +deps = [ + "//media/base/ipc", +] + +# See media_types.typemap for enum mappings. +type_mappings = [ "media.mojom.EncryptionPattern=::media::EncryptionPattern" ]
diff --git a/media/mojo/mojom/encryption_pattern_mojom_traits.cc b/media/mojo/mojom/encryption_pattern_mojom_traits.cc new file mode 100644 index 0000000..d463132 --- /dev/null +++ b/media/mojo/mojom/encryption_pattern_mojom_traits.cc
@@ -0,0 +1,19 @@ +// Copyright 2017 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/mojo/mojom/encryption_pattern_mojom_traits.h" + +namespace mojo { + +// static +bool StructTraits<media::mojom::EncryptionPatternDataView, + media::EncryptionPattern>:: + Read(media::mojom::EncryptionPatternDataView input, + media::EncryptionPattern* output) { + *output = media::EncryptionPattern(input.crypt_byte_block(), + input.skip_byte_block()); + return true; +} + +} // namespace mojo
diff --git a/media/mojo/mojom/encryption_pattern_mojom_traits.h b/media/mojo/mojom/encryption_pattern_mojom_traits.h new file mode 100644 index 0000000..8694a4d --- /dev/null +++ b/media/mojo/mojom/encryption_pattern_mojom_traits.h
@@ -0,0 +1,31 @@ +// Copyright 2017 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_MOJO_MOJOM_ENCRYPTION_PATTERN_MOJOM_TRAITS_H_ +#define MEDIA_MOJO_MOJOM_ENCRYPTION_PATTERN_MOJOM_TRAITS_H_ + +#include "media/base/encryption_pattern.h" +#include "media/base/ipc/media_param_traits.h" +#include "media/mojo/mojom/media_types.mojom.h" + +namespace mojo { + +template <> +struct StructTraits<media::mojom::EncryptionPatternDataView, + media::EncryptionPattern> { + static uint32_t crypt_byte_block(const media::EncryptionPattern& input) { + return input.crypt_byte_block(); + } + + static uint32_t skip_byte_block(const media::EncryptionPattern& input) { + return input.skip_byte_block(); + } + + static bool Read(media::mojom::EncryptionPatternDataView input, + media::EncryptionPattern* output); +}; + +} // namespace mojo + +#endif // MEDIA_MOJO_MOJOM_ENCRYPTION_PATTERN_MOJOM_TRAITS_H_
diff --git a/media/mojo/mojom/encryption_scheme.typemap b/media/mojo/mojom/encryption_scheme.typemap deleted file mode 100644 index f942f83..0000000 --- a/media/mojo/mojom/encryption_scheme.typemap +++ /dev/null
@@ -1,30 +0,0 @@ -# Copyright 2017 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. - -mojom = "//media/mojo/mojom/media_types.mojom" - -public_headers = [ - "//media/base/encryption_scheme.h", - "//media/base/encryption_pattern.h", -] - -traits_headers = [ "//media/mojo/mojom/encryption_scheme_mojom_traits.h" ] - -sources = [ - "//media/mojo/mojom/encryption_scheme_mojom_traits.cc", -] - -public_deps = [ - "//media", -] - -deps = [ - "//media/base/ipc", -] - -# See media_types.typemap for enum mappings. -type_mappings = [ - "media.mojom.EncryptionPattern=::media::EncryptionPattern", - "media.mojom.EncryptionScheme=::media::EncryptionScheme", -]
diff --git a/media/mojo/mojom/encryption_scheme_mojom_traits.cc b/media/mojo/mojom/encryption_scheme_mojom_traits.cc deleted file mode 100644 index a379269..0000000 --- a/media/mojo/mojom/encryption_scheme_mojom_traits.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2017 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/mojo/mojom/encryption_scheme_mojom_traits.h" - -namespace mojo { - -// static -bool StructTraits<media::mojom::EncryptionPatternDataView, - media::EncryptionPattern>:: - Read(media::mojom::EncryptionPatternDataView input, - media::EncryptionPattern* output) { - *output = media::EncryptionPattern(input.crypt_byte_block(), - input.skip_byte_block()); - return true; -} - -// static -bool StructTraits< - media::mojom::EncryptionSchemeDataView, - media::EncryptionScheme>::Read(media::mojom::EncryptionSchemeDataView input, - media::EncryptionScheme* output) { - media::EncryptionScheme::CipherMode mode; - if (!input.ReadMode(&mode)) - return false; - - media::EncryptionPattern pattern; - if (!input.ReadPattern(&pattern)) - return false; - - *output = media::EncryptionScheme(mode, pattern); - - return true; -} - -} // namespace mojo \ No newline at end of file
diff --git a/media/mojo/mojom/encryption_scheme_mojom_traits.h b/media/mojo/mojom/encryption_scheme_mojom_traits.h deleted file mode 100644 index c5166e5..0000000 --- a/media/mojo/mojom/encryption_scheme_mojom_traits.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2017 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_MOJO_MOJOM_ENCRYPTION_SCHEME_MOJOM_TRAITS_H_ -#define MEDIA_MOJO_MOJOM_ENCRYPTION_SCHEME_MOJOM_TRAITS_H_ - -#include "media/base/encryption_pattern.h" -#include "media/base/encryption_scheme.h" -#include "media/base/ipc/media_param_traits.h" -#include "media/mojo/mojom/media_types.mojom.h" - -namespace mojo { - -template <> -struct StructTraits<media::mojom::EncryptionPatternDataView, - media::EncryptionPattern> { - static uint32_t crypt_byte_block(const media::EncryptionPattern& input) { - return input.crypt_byte_block(); - } - - static uint32_t skip_byte_block(const media::EncryptionPattern& input) { - return input.skip_byte_block(); - } - - static bool Read(media::mojom::EncryptionPatternDataView input, - media::EncryptionPattern* output); -}; - -template <> -struct StructTraits<media::mojom::EncryptionSchemeDataView, - media::EncryptionScheme> { - static media::EncryptionScheme::CipherMode mode( - const media::EncryptionScheme& input) { - return input.mode(); - } - - static media::EncryptionPattern pattern( - const media::EncryptionScheme& input) { - return input.pattern(); - } - - static bool Read(media::mojom::EncryptionSchemeDataView input, - media::EncryptionScheme* output); -}; - -} // namespace mojo - -#endif // MEDIA_MOJO_MOJOM_ENCRYPTION_SCHEME_MOJOM_TRAITS_H_
diff --git a/media/mojo/mojom/encryption_scheme_mojom_traits_unittest.cc b/media/mojo/mojom/encryption_scheme_mojom_traits_unittest.cc deleted file mode 100644 index 99cce07..0000000 --- a/media/mojo/mojom/encryption_scheme_mojom_traits_unittest.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2017 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/mojo/mojom/encryption_scheme_mojom_traits.h" - -#include <utility> - -#include "media/base/encryption_scheme.h" -#include "media/base/media_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -TEST(EncryptionSchemeStructTraitsTest, - ConvertEncryptionSchemeAesCbcWithPattern) { - EncryptionScheme input(EncryptionScheme::CIPHER_MODE_AES_CBC, - EncryptionPattern(1, 9)); - std::vector<uint8_t> data = media::mojom::EncryptionScheme::Serialize(&input); - - EncryptionScheme output; - EXPECT_TRUE( - media::mojom::EncryptionScheme::Deserialize(std::move(data), &output)); - EXPECT_TRUE(output.Matches(input)); - - // Verify a couple of negative cases. - EXPECT_FALSE(output.Matches(Unencrypted())); - EXPECT_FALSE(output.Matches(AesCtrEncryptionScheme())); -} - -} // namespace media
diff --git a/media/mojo/mojom/key_system_support.mojom b/media/mojo/mojom/key_system_support.mojom index 99a807d..06ede1b 100644 --- a/media/mojo/mojom/key_system_support.mojom +++ b/media/mojo/mojom/key_system_support.mojom
@@ -14,12 +14,12 @@ // Software secure codecs and encryption schemes supported by the CDM. array<VideoCodec> video_codecs; bool supports_vp9_profile2; - array<EncryptionMode> encryption_schemes; + array<EncryptionScheme> encryption_schemes; // Hardware secure codecs and encryption schemes supported by the CDM, // directly or indirectly through CdmProxy. array<VideoCodec> hw_secure_video_codecs; - array<EncryptionMode> hw_secure_encryption_schemes; + array<EncryptionScheme> hw_secure_encryption_schemes; // Session types supported in software secure mode if no // |hw_secure_video_codecs| is supported, or in both modes otherwise.
diff --git a/media/mojo/mojom/media_types.mojom b/media/mojo/mojom/media_types.mojom index 1068f46..93fb25c 100644 --- a/media/mojo/mojom/media_types.mojom +++ b/media/mojo/mojom/media_types.mojom
@@ -80,10 +80,6 @@ [Native] enum WatchTimeKey; -// See media/base/decrypt_config.h for descriptions. -[Native] -enum EncryptionMode; - // See media/base/container_names.h for descriptions. [Native] enum MediaContainerName; @@ -99,15 +95,9 @@ uint32 skip_byte_block; }; -// This defines a mojo transport format for media::EncryptionScheme. // See media/base/encryption_scheme.h for description. -struct EncryptionScheme { - [Native] - enum CipherMode; - - CipherMode mode; - EncryptionPattern pattern; -}; +[Native] +enum EncryptionScheme; // This defines a mojo transport format for media::VideoColorSpace. // See media/base/video_color_space.h for description. @@ -183,7 +173,7 @@ // This defines a mojo transport format for media::DecryptConfig. // See media/base/decrypt_config.h for descriptions. struct DecryptConfig { - EncryptionMode encryption_mode; + EncryptionScheme encryption_scheme; string key_id; string iv; array<SubsampleEntry> subsamples;
diff --git a/media/mojo/mojom/media_types.typemap b/media/mojo/mojom/media_types.typemap index 02aaa323..a24f592 100644 --- a/media/mojo/mojom/media_types.typemap +++ b/media/mojo/mojom/media_types.typemap
@@ -49,8 +49,7 @@ "media.mojom.ChannelLayout=::media::ChannelLayout", "media.mojom.ColorSpace=::media::ColorSpace", "media.mojom.DecodeStatus=::media::DecodeStatus", - "media.mojom.EncryptionMode=::media::EncryptionMode", - "media.mojom.EncryptionScheme.CipherMode=::media::EncryptionScheme::CipherMode", + "media.mojom.EncryptionScheme=::media::EncryptionScheme", "media.mojom.MediaContainerName=::media::container_names::MediaContainerName", "media.mojom.MediaLogEvent=::media::MediaLogEvent", "media.mojom.OutputDeviceStatus=::media::OutputDeviceStatus", @@ -64,6 +63,5 @@ "media.mojom.VideoTransformation=::media::VideoTransformation", "media.mojom.WaitingReason=::media::WaitingReason", "media.mojom.WatchTimeKey=::media::WatchTimeKey", - "media.mojom.EncryptionPattern=::media::EncryptionPattern", "media.mojom.MediaStatusState=::media::MediaStatus::State", ]
diff --git a/media/mojo/mojom/typemaps.gni b/media/mojo/mojom/typemaps.gni index 8dc9420..987ebfc 100644 --- a/media/mojo/mojom/typemaps.gni +++ b/media/mojo/mojom/typemaps.gni
@@ -11,7 +11,7 @@ "//media/mojo/mojom/content_decryption_module.typemap", "//media/mojo/mojom/decryptor.typemap", "//media/mojo/mojom/demuxer_stream.typemap", - "//media/mojo/mojom/encryption_scheme.typemap", + "//media/mojo/mojom/encryption_pattern.typemap", "//media/mojo/mojom/hdr_metadata.typemap", "//media/mojo/mojom/media_drm_storage.typemap", "//media/mojo/mojom/media_types.typemap",
diff --git a/media/mojo/mojom/video_decoder_config_mojom_traits.h b/media/mojo/mojom/video_decoder_config_mojom_traits.h index 05fffca..0d3f4e1 100644 --- a/media/mojo/mojom/video_decoder_config_mojom_traits.h +++ b/media/mojo/mojom/video_decoder_config_mojom_traits.h
@@ -7,7 +7,6 @@ #include "media/base/ipc/media_param_traits.h" #include "media/base/video_decoder_config.h" -#include "media/mojo/mojom/encryption_scheme_mojom_traits.h" #include "media/mojo/mojom/hdr_metadata_mojom_traits.h" #include "media/mojo/mojom/media_types.mojom.h" #include "media/mojo/mojom/video_color_space_mojom_traits.h" @@ -50,7 +49,7 @@ return input.extra_data(); } - static const media::EncryptionScheme& encryption_scheme( + static media::EncryptionScheme encryption_scheme( const media::VideoDecoderConfig& input) { return input.encryption_scheme(); }
diff --git a/media/mojo/mojom/video_decoder_config_mojom_traits_unittest.cc b/media/mojo/mojom/video_decoder_config_mojom_traits_unittest.cc index 002306a8e..2be014f 100644 --- a/media/mojo/mojom/video_decoder_config_mojom_traits_unittest.cc +++ b/media/mojo/mojom/video_decoder_config_mojom_traits_unittest.cc
@@ -28,7 +28,7 @@ VideoDecoderConfig input( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - kNaturalSize, kExtraDataVector, Unencrypted()); + kNaturalSize, kExtraDataVector, EncryptionScheme::kUnencrypted); std::vector<uint8_t> data = media::mojom::VideoDecoderConfig::Serialize(&input); VideoDecoderConfig output; @@ -42,7 +42,7 @@ VideoDecoderConfig input( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - kNaturalSize, EmptyExtraData(), Unencrypted()); + kNaturalSize, EmptyExtraData(), EncryptionScheme::kUnencrypted); std::vector<uint8_t> data = media::mojom::VideoDecoderConfig::Serialize(&input); VideoDecoderConfig output; @@ -55,7 +55,7 @@ VideoDecoderConfig input( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - kNaturalSize, EmptyExtraData(), AesCtrEncryptionScheme()); + kNaturalSize, EmptyExtraData(), EncryptionScheme::kCenc); std::vector<uint8_t> data = media::mojom::VideoDecoderConfig::Serialize(&input); VideoDecoderConfig output; @@ -73,7 +73,7 @@ VideoColorSpace::MatrixID::BT2020_CL, gfx::ColorSpace::RangeID::LIMITED), kNoTransformation, kCodedSize, kVisibleRect, kNaturalSize, - EmptyExtraData(), Unencrypted()); + EmptyExtraData(), EncryptionScheme::kUnencrypted); std::vector<uint8_t> data = media::mojom::VideoDecoderConfig::Serialize(&input); VideoDecoderConfig output; @@ -87,7 +87,7 @@ VideoDecoderConfig input( kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, - kNaturalSize, EmptyExtraData(), Unencrypted()); + kNaturalSize, EmptyExtraData(), EncryptionScheme::kUnencrypted); HDRMetadata hdr_metadata; hdr_metadata.max_frame_average_light_level = 123; hdr_metadata.max_content_light_level = 456; @@ -126,10 +126,10 @@ // Next try an non-empty invalid config. Natural size must not be zero. const gfx::Size kInvalidNaturalSize(0, 0); - input.Initialize(kCodecVP8, VP8PROFILE_ANY, - VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), - kNoTransformation, kCodedSize, kVisibleRect, - kInvalidNaturalSize, EmptyExtraData(), Unencrypted()); + input.Initialize( + kCodecVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, + VideoColorSpace(), kNoTransformation, kCodedSize, kVisibleRect, + kInvalidNaturalSize, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_FALSE(input.IsValidConfig()); // Deserialize should again fail due to invalid config.
diff --git a/media/mojo/mojom/watch_time_recorder.mojom b/media/mojo/mojom/watch_time_recorder.mojom index 8374b82..ff6737ee 100644 --- a/media/mojo/mojom/watch_time_recorder.mojom +++ b/media/mojo/mojom/watch_time_recorder.mojom
@@ -30,8 +30,8 @@ VideoCodecProfile video_codec_profile; string audio_decoder_name; string video_decoder_name; - EncryptionMode audio_encryption_scheme; - EncryptionMode video_encryption_scheme; + EncryptionScheme audio_encryption_scheme; + EncryptionScheme video_encryption_scheme; gfx.mojom.Size natural_size; // Size of video frame; (0, 0) if audio only. };
diff --git a/media/mojo/services/watch_time_recorder_unittest.cc b/media/mojo/services/watch_time_recorder_unittest.cc index 0fcdea77..1d60279 100644 --- a/media/mojo/services/watch_time_recorder_unittest.cc +++ b/media/mojo/services/watch_time_recorder_unittest.cc
@@ -170,7 +170,7 @@ mojom::SecondaryPlaybackPropertiesPtr CreateSecondaryProperties() { return mojom::SecondaryPlaybackProperties::New( kCodecAAC, kCodecH264, H264PROFILE_MAIN, "", "", - EncryptionMode::kUnencrypted, EncryptionMode::kUnencrypted, + EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted, gfx::Size(800, 600)); } @@ -590,7 +590,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties = mojom::SecondaryPlaybackProperties::New( kCodecAAC, kCodecH264, H264PROFILE_MAIN, "", "", - EncryptionMode::kCenc, EncryptionMode::kCbcs, gfx::Size(800, 600)); + EncryptionScheme::kCenc, EncryptionScheme::kCbcs, + gfx::Size(800, 600)); Initialize(properties.Clone()); wtr_->UpdateSecondaryProperties(secondary_properties.Clone()); @@ -651,7 +652,7 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties = mojom::SecondaryPlaybackProperties::New( kCodecOpus, kCodecVP9, VP9PROFILE_PROFILE0, "", "", - EncryptionMode::kUnencrypted, EncryptionMode::kUnencrypted, + EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted, gfx::Size(800, 600)); Initialize(properties.Clone()); wtr_->UpdateSecondaryProperties(secondary_properties.Clone()); @@ -952,8 +953,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 = mojom::SecondaryPlaybackProperties::New( kUnknownAudioCodec, kUnknownVideoCodec, VIDEO_CODEC_PROFILE_UNKNOWN, - "", "", EncryptionMode::kUnencrypted, EncryptionMode::kUnencrypted, - gfx::Size(800, 600)); + "", "", EncryptionScheme::kUnencrypted, + EncryptionScheme::kUnencrypted, gfx::Size(800, 600)); Initialize(properties.Clone()); wtr_->UpdateSecondaryProperties(secondary_properties1.Clone()); @@ -963,8 +964,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 = mojom::SecondaryPlaybackProperties::New( kCodecAAC, kCodecH264, H264PROFILE_MAIN, "FFmpegAudioDecoder", - "FFmpegVideoDecoder", EncryptionMode::kUnencrypted, - EncryptionMode::kUnencrypted, gfx::Size(800, 600)); + "FFmpegVideoDecoder", EncryptionScheme::kUnencrypted, + EncryptionScheme::kUnencrypted, gfx::Size(800, 600)); wtr_->UpdateSecondaryProperties(secondary_properties2.Clone()); wtr_.reset(); @@ -1015,8 +1016,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 = mojom::SecondaryPlaybackProperties::New( kCodecOpus, kCodecVP9, VP9PROFILE_PROFILE0, "MojoAudioDecoder", - "MojoVideoDecoder", EncryptionMode::kUnencrypted, - EncryptionMode::kUnencrypted, gfx::Size(400, 300)); + "MojoVideoDecoder", EncryptionScheme::kUnencrypted, + EncryptionScheme::kUnencrypted, gfx::Size(400, 300)); Initialize(properties.Clone()); wtr_->UpdateSecondaryProperties(secondary_properties1.Clone()); @@ -1035,8 +1036,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 = mojom::SecondaryPlaybackProperties::New( kCodecAAC, kCodecH264, H264PROFILE_MAIN, "FFmpegAudioDecoder", - "FFmpegVideoDecoder", EncryptionMode::kCenc, EncryptionMode::kCenc, - gfx::Size(800, 600)); + "FFmpegVideoDecoder", EncryptionScheme::kCenc, + EncryptionScheme::kCenc, gfx::Size(800, 600)); wtr_->UpdateSecondaryProperties(secondary_properties2.Clone()); constexpr base::TimeDelta kWatchTime2 = base::TimeDelta::FromSeconds(25); @@ -1140,8 +1141,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 = mojom::SecondaryPlaybackProperties::New( kCodecOpus, kCodecVP9, VP9PROFILE_PROFILE0, "MojoAudioDecoder", - "MojoVideoDecoder", EncryptionMode::kUnencrypted, - EncryptionMode::kUnencrypted, gfx::Size(400, 300)); + "MojoVideoDecoder", EncryptionScheme::kUnencrypted, + EncryptionScheme::kUnencrypted, gfx::Size(400, 300)); Initialize(properties.Clone()); wtr_->UpdateSecondaryProperties(secondary_properties1.Clone()); @@ -1160,8 +1161,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 = mojom::SecondaryPlaybackProperties::New( kCodecAAC, kCodecH264, H264PROFILE_MAIN, "FFmpegAudioDecoder", - "FFmpegVideoDecoder", EncryptionMode::kUnencrypted, - EncryptionMode::kUnencrypted, gfx::Size(800, 600)); + "FFmpegVideoDecoder", EncryptionScheme::kUnencrypted, + EncryptionScheme::kUnencrypted, gfx::Size(800, 600)); wtr_->UpdateSecondaryProperties(secondary_properties2.Clone()); // Don't record any watch time to the new record, it should report zero watch @@ -1247,7 +1248,7 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 = mojom::SecondaryPlaybackProperties::New( kCodecOpus, kCodecVP9, VP9PROFILE_PROFILE0, "MojoAudioDecoder", - "MojoVideoDecoder", EncryptionMode::kCbcs, EncryptionMode::kCbcs, + "MojoVideoDecoder", EncryptionScheme::kCbcs, EncryptionScheme::kCbcs, gfx::Size(400, 300)); Initialize(properties.Clone()); wtr_->UpdateSecondaryProperties(secondary_properties1.Clone()); @@ -1271,8 +1272,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 = mojom::SecondaryPlaybackProperties::New( kCodecAAC, kCodecH264, H264PROFILE_MAIN, "FFmpegAudioDecoder", - "FFmpegVideoDecoder", EncryptionMode::kUnencrypted, - EncryptionMode::kUnencrypted, gfx::Size(800, 600)); + "FFmpegVideoDecoder", EncryptionScheme::kUnencrypted, + EncryptionScheme::kUnencrypted, gfx::Size(800, 600)); wtr_->UpdateSecondaryProperties(secondary_properties2.Clone()); constexpr base::TimeDelta kWatchTime2 = base::TimeDelta::FromSeconds(25); @@ -1366,7 +1367,7 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 = mojom::SecondaryPlaybackProperties::New( kCodecOpus, kCodecVP9, VP9PROFILE_PROFILE0, "MojoAudioDecoder", - "MojoVideoDecoder", EncryptionMode::kCbcs, EncryptionMode::kCbcs, + "MojoVideoDecoder", EncryptionScheme::kCbcs, EncryptionScheme::kCbcs, gfx::Size(400, 300)); Initialize(properties.Clone()); wtr_->UpdateSecondaryProperties(secondary_properties1.Clone()); @@ -1384,8 +1385,8 @@ mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 = mojom::SecondaryPlaybackProperties::New( kCodecAAC, kCodecH264, H264PROFILE_MAIN, "FFmpegAudioDecoder", - "FFmpegVideoDecoder", EncryptionMode::kUnencrypted, - EncryptionMode::kUnencrypted, gfx::Size(800, 600)); + "FFmpegVideoDecoder", EncryptionScheme::kUnencrypted, + EncryptionScheme::kUnencrypted, gfx::Size(800, 600)); wtr_->UpdateSecondaryProperties(secondary_properties2.Clone()); constexpr base::TimeDelta kWatchTime2 = base::TimeDelta::FromSeconds(25);
diff --git a/media/remoting/courier_renderer_unittest.cc b/media/remoting/courier_renderer_unittest.cc index de6ed68..9f637bbb4 100644 --- a/media/remoting/courier_renderer_unittest.cc +++ b/media/remoting/courier_renderer_unittest.cc
@@ -558,9 +558,9 @@ } TEST_F(CourierRendererTest, OnAudioConfigChange) { - const AudioDecoderConfig kNewAudioConfig(kCodecVorbis, kSampleFormatPlanarF32, - CHANNEL_LAYOUT_STEREO, 44100, - EmptyExtraData(), Unencrypted()); + const AudioDecoderConfig kNewAudioConfig( + kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, + EmptyExtraData(), EncryptionScheme::kUnencrypted); InitializeRenderer(); // Make sure initial audio config does not match the one we intend to send. ASSERT_FALSE(render_client_->audio_decoder_config().Matches(kNewAudioConfig));
diff --git a/media/remoting/fake_media_resource.cc b/media/remoting/fake_media_resource.cc index 7381d167..e77cf87 100644 --- a/media/remoting/fake_media_resource.cc +++ b/media/remoting/fake_media_resource.cc
@@ -22,15 +22,17 @@ type_ = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO; if (is_audio) { audio_config_.Initialize(kCodecAAC, kSampleFormatS16, CHANNEL_LAYOUT_STEREO, - 38400, std::vector<uint8_t>(), Unencrypted(), - base::TimeDelta(), 0); + 38400, std::vector<uint8_t>(), + EncryptionScheme::kUnencrypted, base::TimeDelta(), + 0); } else { gfx::Size size(640, 480); gfx::Rect rect(0, 0, 640, 480); video_config_.Initialize(kCodecH264, H264PROFILE_BASELINE, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC601(), kNoTransformation, size, - rect, size, std::vector<uint8_t>(), Unencrypted()); + rect, size, std::vector<uint8_t>(), + EncryptionScheme::kUnencrypted); } ON_CALL(*this, Read(_)) .WillByDefault(Invoke(this, &FakeDemuxerStream::FakeRead));
diff --git a/media/remoting/proto_enum_utils.cc b/media/remoting/proto_enum_utils.cc index 807a48cf..a2313f6 100644 --- a/media/remoting/proto_enum_utils.cc +++ b/media/remoting/proto_enum_utils.cc
@@ -11,26 +11,28 @@ case OriginType::x: \ return OtherType::x -base::Optional<EncryptionScheme::CipherMode> ToMediaEncryptionSchemeCipherMode( +base::Optional<EncryptionScheme> ToMediaEncryptionScheme( pb::EncryptionScheme::CipherMode value) { - using OriginType = pb::EncryptionScheme; - using OtherType = EncryptionScheme; switch (value) { - CASE_RETURN_OTHER(CIPHER_MODE_UNENCRYPTED); - CASE_RETURN_OTHER(CIPHER_MODE_AES_CTR); - CASE_RETURN_OTHER(CIPHER_MODE_AES_CBC); + case pb::EncryptionScheme::CIPHER_MODE_UNENCRYPTED: + return EncryptionScheme::kUnencrypted; + case pb::EncryptionScheme::CIPHER_MODE_AES_CTR: + return EncryptionScheme::kCenc; + case pb::EncryptionScheme::CIPHER_MODE_AES_CBC: + return EncryptionScheme::kCbcs; } return base::nullopt; // Not a 'default' to ensure compile-time checks. } base::Optional<pb::EncryptionScheme::CipherMode> -ToProtoEncryptionSchemeCipherMode(EncryptionScheme::CipherMode value) { - using OriginType = EncryptionScheme; - using OtherType = pb::EncryptionScheme; +ToProtoEncryptionSchemeCipherMode(EncryptionScheme value) { switch (value) { - CASE_RETURN_OTHER(CIPHER_MODE_UNENCRYPTED); - CASE_RETURN_OTHER(CIPHER_MODE_AES_CTR); - CASE_RETURN_OTHER(CIPHER_MODE_AES_CBC); + case EncryptionScheme::kUnencrypted: + return pb::EncryptionScheme::CIPHER_MODE_UNENCRYPTED; + case EncryptionScheme::kCenc: + return pb::EncryptionScheme::CIPHER_MODE_AES_CTR; + case EncryptionScheme::kCbcs: + return pb::EncryptionScheme::CIPHER_MODE_AES_CBC; } return base::nullopt; // Not a 'default' to ensure compile-time checks. } @@ -561,9 +563,10 @@ return base::nullopt; // Not a 'default' to ensure compile-time checks. } -base::Optional<EncryptionMode> ToMediaEncryptionMode(pb::EncryptionMode value) { +base::Optional<EncryptionScheme> ToMediaEncryptionScheme( + pb::EncryptionMode value) { using OriginType = pb::EncryptionMode; - using OtherType = EncryptionMode; + using OtherType = EncryptionScheme; switch (value) { CASE_RETURN_OTHER(kUnencrypted); CASE_RETURN_OTHER(kCenc); @@ -572,8 +575,9 @@ return base::nullopt; // Not a 'default' to ensure compile-time checks. } -base::Optional<pb::EncryptionMode> ToProtoEncryptionMode(EncryptionMode value) { - using OriginType = EncryptionMode; +base::Optional<pb::EncryptionMode> ToProtoEncryptionMode( + EncryptionScheme value) { + using OriginType = EncryptionScheme; using OtherType = pb::EncryptionMode; switch (value) { CASE_RETURN_OTHER(kUnencrypted);
diff --git a/media/remoting/proto_enum_utils.h b/media/remoting/proto_enum_utils.h index 113cf9f..6a92c4b 100644 --- a/media/remoting/proto_enum_utils.h +++ b/media/remoting/proto_enum_utils.h
@@ -32,10 +32,10 @@ // Each returns a base::Optional value. If it is not set, that indicates the // conversion failed. -base::Optional<EncryptionScheme::CipherMode> ToMediaEncryptionSchemeCipherMode( +base::Optional<EncryptionScheme> ToMediaEncryptionScheme( pb::EncryptionScheme::CipherMode value); base::Optional<pb::EncryptionScheme::CipherMode> -ToProtoEncryptionSchemeCipherMode(EncryptionScheme::CipherMode value); +ToProtoEncryptionSchemeCipherMode(EncryptionScheme value); base::Optional<AudioCodec> ToMediaAudioCodec( pb::AudioDecoderConfig::Codec value); @@ -96,8 +96,10 @@ base::Optional<pb::DemuxerStreamReadUntilCallback::Status> ToProtoDemuxerStreamStatus(DemuxerStream::Status value); -base::Optional<EncryptionMode> ToMediaEncryptionMode(pb::EncryptionMode value); -base::Optional<pb::EncryptionMode> ToProtoEncryptionMode(EncryptionMode value); +base::Optional<EncryptionScheme> ToMediaEncryptionScheme( + pb::EncryptionMode value); +base::Optional<pb::EncryptionMode> ToProtoEncryptionMode( + EncryptionScheme value); } // namespace remoting } // namespace media
diff --git a/media/remoting/proto_utils.cc b/media/remoting/proto_utils.cc index 6d34554c..50374662 100644 --- a/media/remoting/proto_utils.cc +++ b/media/remoting/proto_utils.cc
@@ -135,7 +135,7 @@ } config_message->set_mode( - ToProtoEncryptionMode(decrypt_config.encryption_mode()).value()); + ToProtoEncryptionMode(decrypt_config.encryption_scheme()).value()); if (decrypt_config.HasPattern()) { config_message->set_crypt_byte_block( decrypt_config.encryption_pattern()->crypt_byte_block()); @@ -235,20 +235,23 @@ return buffer; } -void ConvertEncryptionSchemeToProto(const EncryptionScheme& encryption_scheme, +void ConvertEncryptionSchemeToProto(EncryptionScheme encryption_scheme, pb::EncryptionScheme* message) { DCHECK(message); + + // The remote side only cares about the cipher mode. Setting EncryptionPattern + // to (0, 0) is fine. + // TODO(crbug.com/1018923): Upgrade proto to remove EncryptionPattern from + // Audio/VideoDecoderConfig. message->set_mode( - ToProtoEncryptionSchemeCipherMode(encryption_scheme.mode()).value()); - message->set_encrypt_blocks(encryption_scheme.pattern().crypt_byte_block()); - message->set_skip_blocks(encryption_scheme.pattern().skip_byte_block()); + ToProtoEncryptionSchemeCipherMode(encryption_scheme).value()); + message->set_encrypt_blocks(0); + message->set_skip_blocks(0); } EncryptionScheme ConvertProtoToEncryptionScheme( const pb::EncryptionScheme& message) { - return EncryptionScheme( - ToMediaEncryptionSchemeCipherMode(message.mode()).value(), - EncryptionPattern(message.encrypt_blocks(), message.skip_blocks())); + return ToMediaEncryptionScheme(message.mode()).value(); } void ConvertAudioDecoderConfigToProto(const AudioDecoderConfig& audio_config, @@ -359,7 +362,6 @@ const pb::VideoDecoderConfig& video_message, VideoDecoderConfig* video_config) { DCHECK(video_config); - EncryptionScheme encryption_scheme; // TODO(hubbe): Update pb to use VideoColorSpace VideoColorSpace color_space;
diff --git a/media/remoting/proto_utils_unittest.cc b/media/remoting/proto_utils_unittest.cc index b20c4bb..4e1748a 100644 --- a/media/remoting/proto_utils_unittest.cc +++ b/media/remoting/proto_utils_unittest.cc
@@ -114,8 +114,7 @@ TEST_F(ProtoUtilsTest, AudioDecoderConfigConversionTest) { const std::string extra_data = "ACEG"; - const EncryptionScheme encryption_scheme( - EncryptionScheme::CIPHER_MODE_AES_CTR, EncryptionPattern(20, 40)); + const EncryptionScheme encryption_scheme = EncryptionScheme::kCenc; AudioDecoderConfig audio_config( kCodecAAC, kSampleFormatF32, CHANNEL_LAYOUT_MONO, 48000, std::vector<uint8_t>(extra_data.begin(), extra_data.end()),
diff --git a/media/remoting/renderer_controller_unittest.cc b/media/remoting/renderer_controller_unittest.cc index 9507195..3caf8a17 100644 --- a/media/remoting/renderer_controller_unittest.cc +++ b/media/remoting/renderer_controller_unittest.cc
@@ -288,7 +288,7 @@ TEST_F(RendererControllerTest, WithAACAudioCodec) { const AudioDecoderConfig audio_config = AudioDecoderConfig( AudioCodec::kCodecAAC, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, - 44100, EmptyExtraData(), Unencrypted()); + 44100, EmptyExtraData(), EncryptionScheme::kUnencrypted); PipelineMetadata pipeline_metadata = DefaultMetadata(VideoCodec::kCodecVP8); pipeline_metadata.audio_decoder_config = audio_config; InitializeControllerAndBecomeDominant(pipeline_metadata, @@ -316,7 +316,7 @@ TEST_F(RendererControllerTest, WithOpusAudioCodec) { const AudioDecoderConfig audio_config = AudioDecoderConfig( AudioCodec::kCodecOpus, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, - 44100, EmptyExtraData(), Unencrypted()); + 44100, EmptyExtraData(), EncryptionScheme::kUnencrypted); PipelineMetadata pipeline_metadata = DefaultMetadata(VideoCodec::kCodecVP8); pipeline_metadata.audio_decoder_config = audio_config; InitializeControllerAndBecomeDominant(pipeline_metadata,
diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc index 6ed5f91..c9ec1283 100644 --- a/media/renderers/audio_renderer_impl_unittest.cc +++ b/media/renderers/audio_renderer_impl_unittest.cc
@@ -106,7 +106,7 @@ ended_(false) { AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout, kInputSamplesPerSecond, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); demuxer_stream_.set_audio_decoder_config(audio_config); ConfigureDemuxerStream(true); @@ -218,9 +218,9 @@ hardware_params_.Reset(AudioParameters::AUDIO_BITSTREAM_EAC3, kChannelLayout, kOutputSamplesPerSecond, 512); sink_ = new FakeAudioRendererSink(hardware_params_); - AudioDecoderConfig audio_config(kCodecAC3, kSampleFormatEac3, - kChannelLayout, kInputSamplesPerSecond, - EmptyExtraData(), Unencrypted()); + AudioDecoderConfig audio_config( + kCodecAC3, kSampleFormatEac3, kChannelLayout, kInputSamplesPerSecond, + EmptyExtraData(), EncryptionScheme::kUnencrypted); demuxer_stream_.set_audio_decoder_config(audio_config); ConfigureDemuxerStream(true); @@ -565,7 +565,7 @@ EXPECT_CALL(new_stream, SupportsConfigChanges()).WillOnce(Return(false)); AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout, kInputSamplesPerSecond, EmptyExtraData(), - Unencrypted()); + EncryptionScheme::kUnencrypted); new_stream.set_audio_decoder_config(audio_config); // The renderer is now in the flushed state and can be reinitialized. @@ -586,7 +586,7 @@ // that RendererClient to be signaled with the new config. const AudioDecoderConfig kValidAudioConfig( kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, - EmptyExtraData(), Unencrypted()); + EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_TRUE(kValidAudioConfig.IsValidConfig()); EXPECT_CALL(*this, OnAudioConfigChange(DecoderConfigEq(kValidAudioConfig))); force_config_change(kValidAudioConfig); @@ -850,7 +850,7 @@ AudioDecoderConfig audio_config( kCodecOpus, kSampleFormat, CHANNEL_LAYOUT_DISCRETE, - kInputSamplesPerSecond, EmptyExtraData(), Unencrypted()); + kInputSamplesPerSecond, EmptyExtraData(), EncryptionScheme::kUnencrypted); audio_config.SetChannelsForDiscrete(audio_channels); demuxer_stream_.set_audio_decoder_config(audio_config); ConfigureDemuxerStream(true);
diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index b0a5448..262600a 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h
@@ -137,13 +137,15 @@ ~Config(); std::string AsHumanReadableString() const; - bool is_encrypted() const { return encryption_scheme.is_encrypted(); } + bool is_encrypted() const { + return encryption_scheme != EncryptionScheme::kUnencrypted; + } // The video codec and profile. VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; // Whether the stream is encrypted, and, if so, the scheme used. - EncryptionScheme encryption_scheme; + EncryptionScheme encryption_scheme = EncryptionScheme::kUnencrypted; // The CDM that the VDA should use to decode encrypted streams. Must be // set to a valid ID if |is_encrypted|.
diff --git a/net/BUILD.gn b/net/BUILD.gn index 016a2ab..c4bed84 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -3566,6 +3566,8 @@ "tools/quic/quic_simple_server_packet_writer.h", "tools/quic/quic_simple_server_session_helper.cc", "tools/quic/quic_simple_server_session_helper.h", + "tools/quic/quic_simple_server_socket.cc", + "tools/quic/quic_simple_server_socket.h", "tools/quic/synchronous_host_resolver.cc", "tools/quic/synchronous_host_resolver.h", ]
diff --git a/net/tools/quic/quic_simple_server.cc b/net/tools/quic/quic_simple_server.cc index da14e4f..9d8f58bf 100644 --- a/net/tools/quic/quic_simple_server.cc +++ b/net/tools/quic/quic_simple_server.cc
@@ -24,6 +24,7 @@ #include "net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h" #include "net/tools/quic/quic_simple_server_packet_writer.h" #include "net/tools/quic/quic_simple_server_session_helper.h" +#include "net/tools/quic/quic_simple_server_socket.h" namespace net { @@ -95,50 +96,17 @@ bool QuicSimpleServer::CreateUDPSocketAndListen( const quic::QuicSocketAddress& address) { - return Listen(ToIPEndPoint(address)) == 0; + return Listen(ToIPEndPoint(address)); } void QuicSimpleServer::HandleEventsForever() { base::RunLoop().Run(); } -int QuicSimpleServer::Listen(const IPEndPoint& address) { - std::unique_ptr<UDPServerSocket> socket( - new UDPServerSocket(nullptr, NetLogSource())); - - socket->AllowAddressReuse(); - - int rc = socket->Listen(address); - if (rc < 0) { - LOG(ERROR) << "Listen() failed: " << ErrorToString(rc); - return rc; - } - - // These send and receive buffer sizes are sized for a single connection, - // because the default usage of QuicSimpleServer is as a test server with - // one or two clients. Adjust higher for use with many clients. - rc = socket->SetReceiveBufferSize( - static_cast<int32_t>(quic::kDefaultSocketReceiveBuffer)); - if (rc < 0) { - LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc); - return rc; - } - - rc = socket->SetSendBufferSize(20 * quic::kMaxOutgoingPacketSize); - if (rc < 0) { - LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc); - return rc; - } - - rc = socket->GetLocalAddress(&server_address_); - if (rc < 0) { - LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc); - return rc; - } - - DVLOG(1) << "Listening on " << server_address_.ToString(); - - socket_.swap(socket); +bool QuicSimpleServer::Listen(const IPEndPoint& address) { + socket_ = CreateQuicSimpleServerSocket(address, &server_address_); + if (socket_ == nullptr) + return false; dispatcher_.reset(new quic::QuicSimpleDispatcher( &config_, &crypto_config_, &version_manager_, @@ -153,7 +121,7 @@ StartReading(); - return OK; + return true; } void QuicSimpleServer::Shutdown() {
diff --git a/net/tools/quic/quic_simple_server.h b/net/tools/quic/quic_simple_server.h index 8b512ff..ae8b0f7 100644 --- a/net/tools/quic/quic_simple_server.h +++ b/net/tools/quic/quic_simple_server.h
@@ -52,8 +52,8 @@ const quic::QuicSocketAddress& address) override; void HandleEventsForever() override; - // Start listening on the specified address. Returns an error code. - int Listen(const IPEndPoint& address); + // Start listening on the specified address. Returns true on success. + bool Listen(const IPEndPoint& address); // Server deletion is imminent. Start cleaning up. void Shutdown();
diff --git a/net/tools/quic/quic_simple_server_socket.cc b/net/tools/quic/quic_simple_server_socket.cc new file mode 100644 index 0000000..5680aaa3 --- /dev/null +++ b/net/tools/quic/quic_simple_server_socket.cc
@@ -0,0 +1,53 @@ +// 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 "net/tools/quic/quic_simple_server_socket.h" + +#include "net/base/net_errors.h" +#include "net/log/net_log_source.h" +#include "net/third_party/quiche/src/quic/core/quic_constants.h" + +namespace net { + +std::unique_ptr<UDPServerSocket> CreateQuicSimpleServerSocket( + const IPEndPoint& address, + IPEndPoint* server_address) { + auto socket = + std::make_unique<UDPServerSocket>(/*net_log=*/nullptr, NetLogSource()); + + socket->AllowAddressReuse(); + + int rc = socket->Listen(address); + if (rc < 0) { + LOG(ERROR) << "Listen() failed: " << ErrorToString(rc); + return nullptr; + } + + // These send and receive buffer sizes are sized for a single connection, + // because the default usage of QuicSimpleServer is as a test server with + // one or two clients. Adjust higher for use with many clients. + rc = socket->SetReceiveBufferSize( + static_cast<int32_t>(quic::kDefaultSocketReceiveBuffer)); + if (rc < 0) { + LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc); + return nullptr; + } + + rc = socket->SetSendBufferSize(20 * quic::kMaxOutgoingPacketSize); + if (rc < 0) { + LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc); + return nullptr; + } + + rc = socket->GetLocalAddress(server_address); + if (rc < 0) { + LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc); + return nullptr; + } + + VLOG(1) << "Listening on " << server_address->ToString(); + return socket; +} + +} // namespace net
diff --git a/net/tools/quic/quic_simple_server_socket.h b/net/tools/quic/quic_simple_server_socket.h new file mode 100644 index 0000000..56cf9d9 --- /dev/null +++ b/net/tools/quic/quic_simple_server_socket.h
@@ -0,0 +1,20 @@ +// 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. + +#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SOCKET_H_ +#define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SOCKET_H_ + +#include "net/base/ip_endpoint.h" +#include "net/socket/udp_server_socket.h" + +namespace net { + +// Creates a UDP server socket tuned for use in a QUIC server. +std::unique_ptr<UDPServerSocket> CreateQuicSimpleServerSocket( + const IPEndPoint& address, + IPEndPoint* server_address); + +} // namespace net + +#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SOCKET_H_
diff --git a/services/service_manager/sandbox/mac/network.sb b/services/service_manager/sandbox/mac/network.sb index ff7a3c6..e1c1d1d 100644 --- a/services/service_manager/sandbox/mac/network.sb +++ b/services/service_manager/sandbox/mac/network.sb
@@ -108,3 +108,13 @@ (allow sysctl-read (sysctl-name-regex #"^net.routetable") ) + +; Kerberos support. This should be removed after GSS is moved out of the +; network service. https://crbug.com/1017830 +(allow mach-lookup + (global-name "org.h5l.kcm") +) +(allow file-read* + (path "/private/etc/krb5.conf") + (subpath "/System/Library/KerberosPlugins/KerberosFrameworkPlugins") +)
diff --git a/services/tracing/BUILD.gn b/services/tracing/BUILD.gn index 72ad733..389a7cb 100644 --- a/services/tracing/BUILD.gn +++ b/services/tracing/BUILD.gn
@@ -16,10 +16,14 @@ sources = [ "perfetto/consumer_host.cc", "perfetto/consumer_host.h", + "perfetto/json_trace_exporter.cc", + "perfetto/json_trace_exporter.h", "perfetto/perfetto_service.cc", "perfetto/perfetto_service.h", "perfetto/producer_host.cc", "perfetto/producer_host.h", + "perfetto/track_event_json_exporter.cc", + "perfetto/track_event_json_exporter.h", "tracing_service.cc", "tracing_service.h", ] @@ -36,40 +40,31 @@ ] deps = [ - "//third_party/perfetto:libproto_to_json", - ] -} - -source_set("json_trace_exporter") { - sources = [ - "perfetto/json_trace_exporter.cc", - "perfetto/json_trace_exporter.h", - "perfetto/track_event_json_exporter.cc", - "perfetto/track_event_json_exporter.h", - ] - deps = [ - "//base", - "//third_party/perfetto:libperfetto", - "//third_party/perfetto/protos/perfetto/common:lite", - "//third_party/perfetto/protos/perfetto/trace:lite", - "//third_party/perfetto/protos/perfetto/trace/chrome:lite", "//third_party/perfetto/protos/perfetto/trace/chrome:minimal_complete_lite", - "//third_party/perfetto/protos/perfetto/trace/interned_data:lite", - "//third_party/perfetto/protos/perfetto/trace/track_event:lite", ] } executable("trace_json_exporter") { sources = [ "perfetto/json_exporter_main.cc", + "perfetto/json_trace_exporter.cc", + "perfetto/json_trace_exporter.h", + "perfetto/track_event_json_exporter.cc", + "perfetto/track_event_json_exporter.h", ] configs += [ "//build/config/compiler:rtti" ] deps = [ - ":json_trace_exporter", "//base", "//third_party/perfetto:libperfetto", + "//third_party/perfetto/include/perfetto/protozero:protozero", + "//third_party/perfetto/protos/perfetto/common:lite", + "//third_party/perfetto/protos/perfetto/trace:lite", + "//third_party/perfetto/protos/perfetto/trace/chrome:lite", + "//third_party/perfetto/protos/perfetto/trace/chrome:minimal_complete_lite", + "//third_party/perfetto/protos/perfetto/trace/interned_data:lite", + "//third_party/perfetto/protos/perfetto/trace/track_event:lite", "//third_party/perfetto/src/protozero:protozero", ] } @@ -150,7 +145,6 @@ } deps = [ - ":json_trace_exporter", ":lib", ":test_utils", "//base",
diff --git a/services/tracing/perfetto/consumer_host.cc b/services/tracing/perfetto/consumer_host.cc index ee60eaab..aa254286 100644 --- a/services/tracing/perfetto/consumer_host.cc +++ b/services/tracing/perfetto/consumer_host.cc
@@ -24,15 +24,13 @@ #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/system/wait.h" +#include "services/tracing/perfetto/json_trace_exporter.h" #include "services/tracing/perfetto/perfetto_service.h" +#include "services/tracing/perfetto/track_event_json_exporter.h" #include "services/tracing/public/cpp/trace_event_args_whitelist.h" -#include "third_party/perfetto/include/perfetto/ext/trace_processor/export_json.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/observable_events.h" -#include "third_party/perfetto/include/perfetto/ext/tracing/core/slice.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_stats.h" -#include "third_party/perfetto/include/perfetto/trace_processor/basic_types.h" -#include "third_party/perfetto/include/perfetto/trace_processor/trace_processor_storage.h" #include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" #include "third_party/perfetto/protos/perfetto/config/trace_config.pb.h" @@ -42,44 +40,6 @@ const int32_t kEnableTracingTimeoutSeconds = 10; -class JsonStringOutputWriter - : public perfetto::trace_processor::json::OutputWriter { - public: - using FlushCallback = - base::RepeatingCallback<void(std::string json, bool has_more)>; - - JsonStringOutputWriter(FlushCallback flush_callback) - : flush_callback_(std::move(flush_callback)) { - buffer_.reserve(kBufferReserveCapacity); - } - - ~JsonStringOutputWriter() override { - flush_callback_.Run(std::move(buffer_), false); - } - - perfetto::trace_processor::util::Status AppendString( - const std::string& string) override { - buffer_ += string; - if (buffer_.size() > kBufferLimitInBytes) { - flush_callback_.Run(std::move(buffer_), true); - // Reset the buffer_ after moving it above. - buffer_.clear(); - buffer_.reserve(kBufferReserveCapacity); - } - return perfetto::trace_processor::util::OkStatus(); - } - - private: - static constexpr size_t kBufferLimitInBytes = 100 * 1024; - // Since we write each string before checking the limit, we'll always go - // slightly over and hence we reserve some extra space to avoid most - // reallocs. - static constexpr size_t kBufferReserveCapacity = kBufferLimitInBytes * 5 / 4; - - FlushCallback flush_callback_; - std::string buffer_; -}; - } // namespace class ConsumerHost::StreamWriter { @@ -331,7 +291,7 @@ tracing_session_client_->OnTracingDisabled(); - if (trace_processor_) { + if (json_trace_exporter_) { host_->consumer_endpoint()->ReadBuffers(); } @@ -383,24 +343,6 @@ weak_factory_.GetWeakPtr()), base::SequencedTaskRunnerHandle::Get()); - if (privacy_filtering_enabled) { - // For filtering/whitelisting to be possible at JSON export time, - // filtering must not have been enabled during proto emission time - // (or there's nothing to pass through the whitelist). - DCHECK(!privacy_filtering_enabled_); - privacy_filtering_enabled_ = true; - } - - json_agent_label_filter_ = agent_label_filter; - - trace_processor_ = - perfetto::trace_processor::TraceProcessorStorage::CreateInstance( - perfetto::trace_processor::Config()); - - DisableTracing(); -} - -void ConsumerHost::TracingSession::ExportJson() { // In legacy backend, the trace event agent sets the predicate used by // TraceLog. For perfetto backend, ensure that predicate is always set // before creating the exporter. The agent can be created later than this @@ -414,55 +356,34 @@ base::BindRepeating(&IsMetadataWhitelisted)); } - perfetto::trace_processor::json::ArgumentFilterPredicate argument_filter; - perfetto::trace_processor::json::MetadataFilterPredicate metadata_filter; - perfetto::trace_processor::json::LabelFilterPredicate label_filter; - - if (privacy_filtering_enabled_) { + JSONTraceExporter::ArgumentFilterPredicate arg_filter_predicate; + JSONTraceExporter::MetadataFilterPredicate metadata_filter_predicate; + if (privacy_filtering_enabled) { + // For filtering/whitelisting to be possible at JSON export time, + // filtering must not have been enabled during proto emission time + // (or there's nothing to pass through the whitelist). + DCHECK(!privacy_filtering_enabled_); auto* trace_log = base::trace_event::TraceLog::GetInstance(); - base::trace_event::ArgumentFilterPredicate argument_filter_predicate = - trace_log->GetArgumentFilterPredicate(); - argument_filter = - [argument_filter_predicate]( - const char* category_group_name, const char* event_name, - perfetto::trace_processor::json::ArgumentNameFilterPredicate* - name_filter) { - base::trace_event::ArgumentNameFilterPredicate name_filter_predicate; - bool result = argument_filter_predicate.Run( - category_group_name, event_name, &name_filter_predicate); - if (name_filter_predicate) { - *name_filter = [name_filter_predicate](const char* arg_name) { - return name_filter_predicate.Run(arg_name); - }; - } - return result; - }; - base::trace_event::MetadataFilterPredicate metadata_filter_predicate = - trace_log->GetMetadataFilterPredicate(); - metadata_filter = [metadata_filter_predicate](const char* metadata_name) { - return metadata_filter_predicate.Run(metadata_name); - }; + arg_filter_predicate = trace_log->GetArgumentFilterPredicate(); + metadata_filter_predicate = trace_log->GetMetadataFilterPredicate(); } + json_trace_exporter_ = std::make_unique<TrackEventJSONExporter>( + std::move(arg_filter_predicate), std::move(metadata_filter_predicate), + base::BindRepeating(&ConsumerHost::TracingSession::OnJSONTraceData, + base::Unretained(this))); - if (!json_agent_label_filter_.empty()) { - label_filter = [this](const char* label) { - return strcmp(label, json_agent_label_filter_.c_str()) == 0; - }; - } + json_trace_exporter_->set_label_filter(agent_label_filter); - JsonStringOutputWriter output_writer(base::BindRepeating( - &ConsumerHost::TracingSession::OnJSONTraceData, base::Unretained(this))); - auto status = perfetto::trace_processor::json::ExportJson( - trace_processor_.get(), &output_writer, argument_filter, metadata_filter, - label_filter); - DCHECK(status.ok()) << status.message(); + DisableTracing(); } -void ConsumerHost::TracingSession::OnJSONTraceData(std::string json, - bool has_more) { +void ConsumerHost::TracingSession::OnJSONTraceData( + std::string* json, + base::DictionaryValue* metadata, + bool has_more) { auto slices = std::make_unique<StreamWriter::Slices>(); slices->push_back(std::string()); - slices->back().swap(json); + slices->back().swap(*json); read_buffers_stream_writer_.Post(FROM_HERE, &StreamWriter::WriteToStream, std::move(slices), has_more); @@ -475,40 +396,10 @@ std::vector<perfetto::TracePacket> packets, bool has_more) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (trace_processor_) { - // Calculate space needed for trace chunk. Each packet has a preamble and - // payload size. - size_t max_size = packets.size() * perfetto::TracePacket::kMaxPreambleBytes; - for (const auto& packet : packets) { - max_size += packet.size(); - } - - // Copy packets into a trace file chunk. - size_t position = 0; - std::unique_ptr<uint8_t[]> data(new uint8_t[max_size]); - for (perfetto::TracePacket& packet : packets) { - char* preamble; - size_t preamble_size; - std::tie(preamble, preamble_size) = packet.GetProtoPreamble(); - DCHECK_LT(position + preamble_size, max_size); - memcpy(&data[position], preamble, preamble_size); - position += preamble_size; - for (const perfetto::Slice& slice : packet.slices()) { - DCHECK_LT(position + slice.size, max_size); - memcpy(&data[position], slice.start, slice.size); - position += slice.size; - } - } - - auto status = trace_processor_->Parse(std::move(data), position); - // TODO(eseckler): There's no way to propagate this error at the moment - If - // one occurs on production builds, we silently ignore it and will end up - // producing an empty JSON result. - DCHECK(status.ok()) << status.message(); + if (json_trace_exporter_) { + json_trace_exporter_->OnTraceData(std::move(packets), has_more); if (!has_more) { - trace_processor_->NotifyEndOfFile(); - ExportJson(); - trace_processor_.reset(); + json_trace_exporter_.reset(); } return; }
diff --git a/services/tracing/perfetto/consumer_host.h b/services/tracing/perfetto/consumer_host.h index 64031683..63a400ca 100644 --- a/services/tracing/perfetto/consumer_host.h +++ b/services/tracing/perfetto/consumer_host.h
@@ -23,18 +23,17 @@ #include "third_party/perfetto/include/perfetto/ext/tracing/core/consumer.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" +namespace base { +class DictionaryValue; +} + namespace service_manager { struct BindSourceInfo; } // namespace service_manager -namespace perfetto { -namespace trace_processor { -class TraceProcessorStorage; -} // namespace trace_processor -} // namespace perfetto - namespace tracing { +class JSONTraceExporter; class PerfettoService; // This is a Mojo interface which enables any client @@ -90,8 +89,9 @@ DisableTracingAndEmitJsonCallback callback) override; private: - void ExportJson(); - void OnJSONTraceData(std::string json, bool has_more); + void OnJSONTraceData(std::string* json, + base::DictionaryValue* metadata, + bool has_more); void OnEnableTracingTimeout(); void MaybeSendEnableTracingAck(); bool IsExpectedPid(base::ProcessId pid) const; @@ -102,9 +102,7 @@ bool privacy_filtering_enabled_ = false; base::SequenceBound<StreamWriter> read_buffers_stream_writer_; RequestBufferUsageCallback request_buffer_usage_callback_; - std::unique_ptr<perfetto::trace_processor::TraceProcessorStorage> - trace_processor_; - std::string json_agent_label_filter_; + std::unique_ptr<JSONTraceExporter> json_trace_exporter_; base::OnceCallback<void(bool)> flush_callback_; const mojom::TracingClientPriority tracing_priority_; base::OnceClosure on_disabled_callback_;
diff --git a/services/video_capture/broadcasting_receiver.cc b/services/video_capture/broadcasting_receiver.cc index 7ca5b12..6dea411e 100644 --- a/services/video_capture/broadcasting_receiver.cc +++ b/services/video_capture/broadcasting_receiver.cc
@@ -65,7 +65,7 @@ } // anonymous namespace BroadcastingReceiver::ClientContext::ClientContext( - mojo::PendingRemote<mojom::Receiver> client, + mojo::PendingRemote<mojom::VideoFrameHandler> client, media::VideoCaptureBufferType target_buffer_type) : client_(std::move(client)), target_buffer_type_(target_buffer_type), @@ -242,7 +242,7 @@ } int32_t BroadcastingReceiver::AddClient( - mojo::PendingRemote<mojom::Receiver> client, + mojo::PendingRemote<mojom::VideoFrameHandler> client, media::VideoCaptureBufferType target_buffer_type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto client_id = next_client_id_++; @@ -284,7 +284,7 @@ clients_.at(client_id).set_is_suspended(false); } -mojo::Remote<mojom::Receiver> BroadcastingReceiver::RemoveClient( +mojo::Remote<mojom::VideoFrameHandler> BroadcastingReceiver::RemoveClient( int32_t client_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto client = std::move(clients_.at(client_id));
diff --git a/services/video_capture/broadcasting_receiver.h b/services/video_capture/broadcasting_receiver.h index 32f6d6ba0..99f09c2 100644 --- a/services/video_capture/broadcasting_receiver.h +++ b/services/video_capture/broadcasting_receiver.h
@@ -15,14 +15,14 @@ #include "media/capture/video_capture_types.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" #include "services/video_capture/public/mojom/scoped_access_permission.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" namespace video_capture { -// Implementation of mojom::VideoFrameReceiver that distributes frames to +// Implementation of mojom::VideoFrameHandler that distributes frames to // potentially multiple clients. -class BroadcastingReceiver : public mojom::Receiver { +class BroadcastingReceiver : public mojom::VideoFrameHandler { public: class BufferContext { public: @@ -77,14 +77,14 @@ void SetOnStoppedHandler(base::OnceClosure on_stopped_handler); // Returns a client_id that can be used for a call to Suspend/Resume/Remove. - int32_t AddClient(mojo::PendingRemote<mojom::Receiver> client, + int32_t AddClient(mojo::PendingRemote<mojom::VideoFrameHandler> client, media::VideoCaptureBufferType target_buffer_type); void SuspendClient(int32_t client_id); void ResumeClient(int32_t client_id); // Returns ownership of the client back to the caller. - mojo::Remote<mojom::Receiver> RemoveClient(int32_t client_id); + mojo::Remote<mojom::VideoFrameHandler> RemoveClient(int32_t client_id); - // video_capture::mojom::Receiver: + // video_capture::mojom::VideoFrameHandler: void OnNewBuffer(int32_t buffer_id, media::mojom::VideoBufferHandlePtr buffer_handle) override; void OnFrameReadyInBuffer( @@ -115,7 +115,7 @@ // a client is suspended. class ClientContext { public: - ClientContext(mojo::PendingRemote<mojom::Receiver> client, + ClientContext(mojo::PendingRemote<mojom::VideoFrameHandler> client, media::VideoCaptureBufferType target_buffer_type); ~ClientContext(); ClientContext(ClientContext&& other); @@ -123,7 +123,7 @@ void OnStarted(); void OnStartedUsingGpuDecode(); - mojo::Remote<mojom::Receiver>& client() { return client_; } + mojo::Remote<mojom::VideoFrameHandler>& client() { return client_; } media::VideoCaptureBufferType target_buffer_type() { return target_buffer_type_; } @@ -131,7 +131,7 @@ bool is_suspended() const { return is_suspended_; } private: - mojo::Remote<mojom::Receiver> client_; + mojo::Remote<mojom::VideoFrameHandler> client_; media::VideoCaptureBufferType target_buffer_type_; bool is_suspended_; bool on_started_has_been_called_;
diff --git a/services/video_capture/broadcasting_receiver_unittest.cc b/services/video_capture/broadcasting_receiver_unittest.cc index 65033ca..a0caa62 100644 --- a/services/video_capture/broadcasting_receiver_unittest.cc +++ b/services/video_capture/broadcasting_receiver_unittest.cc
@@ -10,7 +10,8 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/system/platform_handle.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -36,16 +37,18 @@ class BroadcastingReceiverTest : public ::testing::Test { public: void SetUp() override { - mojo::PendingRemote<mojom::Receiver> receiver_1; - mojo::PendingRemote<mojom::Receiver> receiver_2; - mock_receiver_1_ = std::make_unique<MockReceiver>( - receiver_1.InitWithNewPipeAndPassReceiver()); - mock_receiver_2_ = std::make_unique<MockReceiver>( - receiver_2.InitWithNewPipeAndPassReceiver()); - client_id_1_ = broadcaster_.AddClient( - std::move(receiver_1), media::VideoCaptureBufferType::kSharedMemory); - client_id_2_ = broadcaster_.AddClient( - std::move(receiver_2), media::VideoCaptureBufferType::kSharedMemory); + mojo::PendingRemote<mojom::VideoFrameHandler> video_frame_handler_1; + mojo::PendingRemote<mojom::VideoFrameHandler> video_frame_handler_2; + mock_video_frame_handler_1_ = std::make_unique<MockVideoFrameHandler>( + video_frame_handler_1.InitWithNewPipeAndPassReceiver()); + mock_video_frame_handler_2_ = std::make_unique<MockVideoFrameHandler>( + video_frame_handler_2.InitWithNewPipeAndPassReceiver()); + client_id_1_ = + broadcaster_.AddClient(std::move(video_frame_handler_1), + media::VideoCaptureBufferType::kSharedMemory); + client_id_2_ = + broadcaster_.AddClient(std::move(video_frame_handler_2), + media::VideoCaptureBufferType::kSharedMemory); shm_region_ = base::UnsafeSharedMemoryRegion::Create(kArbitraryDummyBufferSize); @@ -59,8 +62,8 @@ protected: BroadcastingReceiver broadcaster_; - std::unique_ptr<MockReceiver> mock_receiver_1_; - std::unique_ptr<MockReceiver> mock_receiver_2_; + std::unique_ptr<MockVideoFrameHandler> mock_video_frame_handler_1_; + std::unique_ptr<MockVideoFrameHandler> mock_video_frame_handler_2_; int32_t client_id_1_; int32_t client_id_2_; base::UnsafeSharedMemoryRegion shm_region_; @@ -70,17 +73,17 @@ TEST_F( BroadcastingReceiverTest, HoldsOnToAccessPermissionForRetiredBufferUntilLastClientFinishedConsuming) { - base::RunLoop frame_arrived_at_receiver_1; - base::RunLoop frame_arrived_at_receiver_2; - EXPECT_CALL(*mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)) - .WillOnce(InvokeWithoutArgs([&frame_arrived_at_receiver_1]() { - frame_arrived_at_receiver_1.Quit(); + base::RunLoop frame_arrived_at_video_frame_handler_1; + base::RunLoop frame_arrived_at_video_frame_handler_2; + EXPECT_CALL(*mock_video_frame_handler_1_, DoOnFrameReadyInBuffer(_, _, _, _)) + .WillOnce(InvokeWithoutArgs([&frame_arrived_at_video_frame_handler_1]() { + frame_arrived_at_video_frame_handler_1.Quit(); })); - EXPECT_CALL(*mock_receiver_2_, DoOnFrameReadyInBuffer(_, _, _, _)) - .WillOnce(InvokeWithoutArgs([&frame_arrived_at_receiver_2]() { - frame_arrived_at_receiver_2.Quit(); + EXPECT_CALL(*mock_video_frame_handler_2_, DoOnFrameReadyInBuffer(_, _, _, _)) + .WillOnce(InvokeWithoutArgs([&frame_arrived_at_video_frame_handler_2]() { + frame_arrived_at_video_frame_handler_2.Quit(); })); - mock_receiver_2_->HoldAccessPermissions(); + mock_video_frame_handler_2_->HoldAccessPermissions(); mojo::PendingRemote<mojom::ScopedAccessPermission> access_permission; bool access_permission_has_been_released = false; @@ -99,35 +102,37 @@ std::move(access_permission), std::move(frame_info)); - // mock_receiver_1_ finishes consuming immediately. - // mock_receiver_2_ continues consuming. - frame_arrived_at_receiver_1.Run(); - frame_arrived_at_receiver_2.Run(); + // mock_video_frame_handler_1_ finishes consuming immediately. + // mock_video_frame_handler_2_ continues consuming. + frame_arrived_at_video_frame_handler_1.Run(); + frame_arrived_at_video_frame_handler_2.Run(); - base::RunLoop buffer_retired_arrived_at_receiver_1; - base::RunLoop buffer_retired_arrived_at_receiver_2; - EXPECT_CALL(*mock_receiver_1_, DoOnBufferRetired(_)) - .WillOnce(InvokeWithoutArgs([&buffer_retired_arrived_at_receiver_1]() { - buffer_retired_arrived_at_receiver_1.Quit(); - })); - EXPECT_CALL(*mock_receiver_2_, DoOnBufferRetired(_)) - .WillOnce(InvokeWithoutArgs([&buffer_retired_arrived_at_receiver_2]() { - buffer_retired_arrived_at_receiver_2.Quit(); - })); + base::RunLoop buffer_retired_arrived_at_video_frame_handler_1; + base::RunLoop buffer_retired_arrived_at_video_frame_handler_2; + EXPECT_CALL(*mock_video_frame_handler_1_, DoOnBufferRetired(_)) + .WillOnce(InvokeWithoutArgs( + [&buffer_retired_arrived_at_video_frame_handler_1]() { + buffer_retired_arrived_at_video_frame_handler_1.Quit(); + })); + EXPECT_CALL(*mock_video_frame_handler_2_, DoOnBufferRetired(_)) + .WillOnce(InvokeWithoutArgs( + [&buffer_retired_arrived_at_video_frame_handler_2]() { + buffer_retired_arrived_at_video_frame_handler_2.Quit(); + })); // retire the buffer broadcaster_.OnBufferRetired(kArbiraryBufferId); // expect that both receivers get the retired event - buffer_retired_arrived_at_receiver_1.Run(); - buffer_retired_arrived_at_receiver_2.Run(); + buffer_retired_arrived_at_video_frame_handler_1.Run(); + buffer_retired_arrived_at_video_frame_handler_2.Run(); // expect that |access_permission| is still being held base::RunLoop().RunUntilIdle(); EXPECT_FALSE(access_permission_has_been_released); - // mock_receiver_2_ finishes consuming - mock_receiver_2_->ReleaseAccessPermissions(); + // mock_video_frame_handler_2_ finishes consuming + mock_video_frame_handler_2_->ReleaseAccessPermissions(); // expect that |access_permission| is released base::RunLoop().RunUntilIdle(); @@ -136,8 +141,10 @@ TEST_F(BroadcastingReceiverTest, DoesNotHoldOnToAccessPermissionWhenAllClientsAreSuspended) { - EXPECT_CALL(*mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); - EXPECT_CALL(*mock_receiver_2_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); + EXPECT_CALL(*mock_video_frame_handler_1_, DoOnFrameReadyInBuffer(_, _, _, _)) + .Times(0); + EXPECT_CALL(*mock_video_frame_handler_2_, DoOnFrameReadyInBuffer(_, _, _, _)) + .Times(0); broadcaster_.SuspendClient(client_id_1_); broadcaster_.SuspendClient(client_id_2_);
diff --git a/services/video_capture/device_media_to_mojo_adapter.cc b/services/video_capture/device_media_to_mojo_adapter.cc index 6f14e0b..b56cc785 100644 --- a/services/video_capture/device_media_to_mojo_adapter.cc +++ b/services/video_capture/device_media_to_mojo_adapter.cc
@@ -63,14 +63,17 @@ void DeviceMediaToMojoAdapter::Start( const media::VideoCaptureParams& requested_settings, - mojo::PendingRemote<mojom::Receiver> receiver_pending_remote) { + mojo::PendingRemote<mojom::VideoFrameHandler> + video_frame_handler_pending_remote) { DCHECK(thread_checker_.CalledOnValidThread()); - mojo::Remote<mojom::Receiver> receiver(std::move(receiver_pending_remote)); - receiver.set_disconnect_handler( + mojo::Remote<mojom::VideoFrameHandler> handler_remote( + std::move(video_frame_handler_pending_remote)); + handler_remote.set_disconnect_handler( base::BindOnce(&DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose, weak_factory_.GetWeakPtr())); - receiver_ = std::make_unique<ReceiverMojoToMediaAdapter>(std::move(receiver)); + receiver_ = + std::make_unique<ReceiverMojoToMediaAdapter>(std::move(handler_remote)); auto media_receiver = std::make_unique<media::VideoFrameReceiverOnTaskRunner>( receiver_->GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()); @@ -158,8 +161,8 @@ device_->StopAndDeAllocate(); // We need to post the deletion of receiver to the end of the message queue, // because |device_->StopAndDeAllocate()| may post messages (e.g. - // OnBufferRetired()) to a WeakPtr to |receiver_| to this queue, and we need - // those messages to be sent before we invalidate the WeakPtr. + // OnBufferRetired()) to a WeakPtr to |receiver_| to this queue, + // and we need those messages to be sent before we invalidate the WeakPtr. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, std::move(receiver_)); }
diff --git a/services/video_capture/device_media_to_mojo_adapter.h b/services/video_capture/device_media_to_mojo_adapter.h index b54baf74..b78c4037 100644 --- a/services/video_capture/device_media_to_mojo_adapter.h +++ b/services/video_capture/device_media_to_mojo_adapter.h
@@ -12,6 +12,7 @@ #include "media/capture/video_capture_types.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/video_capture/public/mojom/device.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #if defined(OS_CHROMEOS) #include "media/capture/video/chromeos/video_capture_device_factory_chromeos.h" @@ -38,9 +39,9 @@ ~DeviceMediaToMojoAdapter() override; // mojom::Device implementation. - void Start( - const media::VideoCaptureParams& requested_settings, - mojo::PendingRemote<mojom::Receiver> receiver_pending_remote) override; + void Start(const media::VideoCaptureParams& requested_settings, + mojo::PendingRemote<mojom::VideoFrameHandler> + handler_pending_remote) override; void MaybeSuspend() override; void Resume() override; void GetPhotoState(GetPhotoStateCallback callback) override;
diff --git a/services/video_capture/device_media_to_mojo_adapter_unittest.cc b/services/video_capture/device_media_to_mojo_adapter_unittest.cc index c8a8738..a4d469150 100644 --- a/services/video_capture/device_media_to_mojo_adapter_unittest.cc +++ b/services/video_capture/device_media_to_mojo_adapter_unittest.cc
@@ -9,7 +9,8 @@ #include "base/test/task_environment.h" #include "media/capture/video/mock_device.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -24,8 +25,8 @@ ~DeviceMediaToMojoAdapterTest() override = default; void SetUp() override { - mock_receiver_ = std::make_unique<MockReceiver>( - receiver_.InitWithNewPipeAndPassReceiver()); + mock_video_frame_handler_ = std::make_unique<MockVideoFrameHandler>( + video_frame_handler_.InitWithNewPipeAndPassReceiver()); auto mock_device = std::make_unique<media::MockDevice>(); mock_device_ptr_ = mock_device.get(); #if defined(OS_CHROMEOS) @@ -48,8 +49,8 @@ protected: media::MockDevice* mock_device_ptr_; std::unique_ptr<DeviceMediaToMojoAdapter> adapter_; - std::unique_ptr<MockReceiver> mock_receiver_; - mojo::PendingRemote<mojom::Receiver> receiver_; + std::unique_ptr<MockVideoFrameHandler> mock_video_frame_handler_; + mojo::PendingRemote<mojom::VideoFrameHandler> video_frame_handler_; base::test::TaskEnvironment task_environment_; }; @@ -63,19 +64,18 @@ std::unique_ptr<media::VideoCaptureDevice::Client>* client) { (*client)->OnStarted(); })); - EXPECT_CALL(*mock_receiver_, OnStarted()).WillOnce(Invoke([&run_loop]() { - run_loop.Quit(); - })); + EXPECT_CALL(*mock_video_frame_handler_, OnStarted()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); const media::VideoCaptureParams kArbitrarySettings; - adapter_->Start(kArbitrarySettings, std::move(receiver_)); + adapter_->Start(kArbitrarySettings, std::move(video_frame_handler_)); run_loop.Run(); } { base::RunLoop run_loop; EXPECT_CALL(*mock_device_ptr_, DoStopAndDeAllocate()) .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); - mock_receiver_.reset(); + mock_video_frame_handler_.reset(); run_loop.Run(); } } @@ -94,12 +94,11 @@ std::unique_ptr<media::VideoCaptureDevice::Client>* client) { (*client)->OnStarted(); })); - EXPECT_CALL(*mock_receiver_, OnStarted()).WillOnce(Invoke([&run_loop]() { - run_loop.Quit(); - })); + EXPECT_CALL(*mock_video_frame_handler_, OnStarted()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); const media::VideoCaptureParams kArbitrarySettings; - adapter_->Start(kArbitrarySettings, std::move(receiver_)); + adapter_->Start(kArbitrarySettings, std::move(video_frame_handler_)); run_loop.Run(); } @@ -108,7 +107,7 @@ // This posts invocation of the error event handler to the end of the // current sequence. - mock_receiver_.reset(); + mock_video_frame_handler_.reset(); // This destroys the DeviceMediaToMojoAdapter, which in turn posts a // DeleteSoon in ~ReceiverOnTaskRunner() to the end of the current sequence.
diff --git a/services/video_capture/public/cpp/BUILD.gn b/services/video_capture/public/cpp/BUILD.gn index 98462de..83f37e5 100644 --- a/services/video_capture/public/cpp/BUILD.gn +++ b/services/video_capture/public/cpp/BUILD.gn
@@ -32,10 +32,10 @@ "mock_producer.h", "mock_push_subscription.cc", "mock_push_subscription.h", - "mock_receiver.cc", - "mock_receiver.h", "mock_video_capture_service.cc", "mock_video_capture_service.h", + "mock_video_frame_handler.cc", + "mock_video_frame_handler.h", "mock_video_source.cc", "mock_video_source.h", "mock_video_source_provider.cc",
diff --git a/services/video_capture/public/cpp/mock_receiver.cc b/services/video_capture/public/cpp/mock_video_frame_handler.cc similarity index 66% rename from services/video_capture/public/cpp/mock_receiver.cc rename to services/video_capture/public/cpp/mock_video_frame_handler.cc index 386903e..faafe864 100644 --- a/services/video_capture/public/cpp/mock_receiver.cc +++ b/services/video_capture/public/cpp/mock_video_frame_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" #include "base/stl_util.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -10,25 +10,26 @@ namespace video_capture { -MockReceiver::MockReceiver() - : receiver_(this), should_store_access_permissions_(false) {} +MockVideoFrameHandler::MockVideoFrameHandler() + : video_frame_handler_(this), should_store_access_permissions_(false) {} -MockReceiver::MockReceiver(mojo::PendingReceiver<mojom::Receiver> receiver) - : receiver_(this, std::move(receiver)), +MockVideoFrameHandler::MockVideoFrameHandler( + mojo::PendingReceiver<mojom::VideoFrameHandler> handler) + : video_frame_handler_(this, std::move(handler)), should_store_access_permissions_(false) {} -MockReceiver::~MockReceiver() = default; +MockVideoFrameHandler::~MockVideoFrameHandler() = default; -void MockReceiver::HoldAccessPermissions() { +void MockVideoFrameHandler::HoldAccessPermissions() { should_store_access_permissions_ = true; } -void MockReceiver::ReleaseAccessPermissions() { +void MockVideoFrameHandler::ReleaseAccessPermissions() { should_store_access_permissions_ = false; access_permissions_.clear(); } -void MockReceiver::OnNewBuffer( +void MockVideoFrameHandler::OnNewBuffer( int32_t buffer_id, media::mojom::VideoBufferHandlePtr buffer_handle) { CHECK(!base::Contains(known_buffer_ids_, buffer_id)); @@ -36,7 +37,7 @@ DoOnNewBuffer(buffer_id, &buffer_handle); } -void MockReceiver::OnFrameReadyInBuffer( +void MockVideoFrameHandler::OnFrameReadyInBuffer( int32_t buffer_id, int32_t frame_feedback_id, mojo::PendingRemote<mojom::ScopedAccessPermission> access_permission, @@ -47,7 +48,7 @@ access_permissions_.emplace_back(std::move(access_permission)); } -void MockReceiver::OnBufferRetired(int32_t buffer_id) { +void MockVideoFrameHandler::OnBufferRetired(int32_t buffer_id) { auto iter = std::find(known_buffer_ids_.begin(), known_buffer_ids_.end(), buffer_id); CHECK(iter != known_buffer_ids_.end());
diff --git a/services/video_capture/public/cpp/mock_receiver.h b/services/video_capture/public/cpp/mock_video_frame_handler.h similarity index 77% rename from services/video_capture/public/cpp/mock_receiver.h rename to services/video_capture/public/cpp/mock_video_frame_handler.h index 7761106..a38f5b6 100644 --- a/services/video_capture/public/cpp/mock_receiver.h +++ b/services/video_capture/public/cpp/mock_video_frame_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_RECEIVER_H_ -#define SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_RECEIVER_H_ +#ifndef SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_VIDEO_FRAME_HANDLER_H_ +#define SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_VIDEO_FRAME_HANDLER_H_ #include <vector> @@ -11,17 +11,18 @@ #include "media/mojo/mojom/media_types.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" #include "services/video_capture/public/mojom/scoped_access_permission.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "testing/gmock/include/gmock/gmock.h" namespace video_capture { -class MockReceiver : public mojom::Receiver { +class MockVideoFrameHandler : public mojom::VideoFrameHandler { public: - MockReceiver(); - explicit MockReceiver(mojo::PendingReceiver<mojom::Receiver> receiver); - ~MockReceiver() override; + MockVideoFrameHandler(); + explicit MockVideoFrameHandler( + mojo::PendingReceiver<mojom::VideoFrameHandler> handler); + ~MockVideoFrameHandler() override; void HoldAccessPermissions(); void ReleaseAccessPermissions(); @@ -52,7 +53,7 @@ MOCK_METHOD0(OnStopped, void()); private: - const mojo::Receiver<mojom::Receiver> receiver_; + const mojo::Receiver<mojom::VideoFrameHandler> video_frame_handler_; std::vector<int32_t> known_buffer_ids_; bool should_store_access_permissions_; std::vector<mojom::ScopedAccessPermissionPtr> access_permissions_; @@ -60,4 +61,4 @@ } // namespace video_capture -#endif // SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_RECEIVER_H_ +#endif // SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_VIDEO_FRAME_HANDLER_H_
diff --git a/services/video_capture/public/cpp/mock_video_source.cc b/services/video_capture/public/cpp/mock_video_source.cc index 33d49fc..2fcc498 100644 --- a/services/video_capture/public/cpp/mock_video_source.cc +++ b/services/video_capture/public/cpp/mock_video_source.cc
@@ -11,7 +11,7 @@ MockVideoSource::~MockVideoSource() = default; void MockVideoSource::CreatePushSubscription( - mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, + mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver<video_capture::mojom::PushVideoStreamSubscription>
diff --git a/services/video_capture/public/cpp/mock_video_source.h b/services/video_capture/public/cpp/mock_video_source.h index de9c48bd..ea65c82f 100644 --- a/services/video_capture/public/cpp/mock_video_source.h +++ b/services/video_capture/public/cpp/mock_video_source.h
@@ -6,7 +6,7 @@ #define SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_VIDEO_SOURCE_H_ #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/video_source.mojom.h" #include "testing/gmock/include/gmock/gmock.h" @@ -18,7 +18,7 @@ ~MockVideoSource() override; void CreatePushSubscription( - mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, + mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver<video_capture::mojom::PushVideoStreamSubscription> @@ -27,7 +27,8 @@ MOCK_METHOD5( DoCreatePushSubscription, - void(mojo::PendingRemote<video_capture::mojom::Receiver> subscriber, + void(mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> + subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver<
diff --git a/services/video_capture/public/cpp/receiver_media_to_mojo_adapter.h b/services/video_capture/public/cpp/receiver_media_to_mojo_adapter.h index 25afe1469..1c913be 100644 --- a/services/video_capture/public/cpp/receiver_media_to_mojo_adapter.h +++ b/services/video_capture/public/cpp/receiver_media_to_mojo_adapter.h
@@ -7,19 +7,19 @@ #include "media/capture/video/video_frame_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" namespace video_capture { // Adapter that allows a media::VideoFrameReceiver to be used in place of -// a mojom::VideoFrameReceiver. -class ReceiverMediaToMojoAdapter : public mojom::Receiver { +// a mojom::VideoFrameHandler. +class ReceiverMediaToMojoAdapter : public mojom::VideoFrameHandler { public: ReceiverMediaToMojoAdapter( std::unique_ptr<media::VideoFrameReceiver> receiver); ~ReceiverMediaToMojoAdapter() override; - // video_capture::mojom::Receiver: + // video_capture::mojom::VideoFrameHandler: void OnNewBuffer(int32_t buffer_id, media::mojom::VideoBufferHandlePtr buffer_handle) override; void OnFrameReadyInBuffer(
diff --git a/services/video_capture/public/mojom/BUILD.gn b/services/video_capture/public/mojom/BUILD.gn index 74cabff..4807a00 100644 --- a/services/video_capture/public/mojom/BUILD.gn +++ b/services/video_capture/public/mojom/BUILD.gn
@@ -10,10 +10,10 @@ "device_factory.mojom", "devices_changed_observer.mojom", "producer.mojom", - "receiver.mojom", "scoped_access_permission.mojom", "testing_controls.mojom", "video_capture_service.mojom", + "video_frame_handler.mojom", "video_source.mojom", "video_source_provider.mojom", "virtual_device.mojom",
diff --git a/services/video_capture/public/mojom/device.mojom b/services/video_capture/public/mojom/device.mojom index 9dae2f1..cc8c868 100644 --- a/services/video_capture/public/mojom/device.mojom +++ b/services/video_capture/public/mojom/device.mojom
@@ -6,18 +6,18 @@ import "media/capture/mojom/video_capture_types.mojom"; import "media/capture/mojom/image_capture.mojom"; -import "services/video_capture/public/mojom/receiver.mojom"; +import "services/video_capture/public/mojom/video_frame_handler.mojom"; -// Represents access to a video capture device available on the machine. -// The device is stopped automatically when the message pipe corresponding to -// either the Device or the given |receiver| is closed. Note that as a response -// to stopping the device, the service may still need to send out events such as -// Receiver.OnBufferRetired() to |receiver|. The service will send a final event -// Receiver.OnStopped() to indicate that stopping has completed and no further -// events are going to be sent to |receiver|. +// Represents access to a video capture device available on the machine. The +// device is stopped automatically when the message pipe corresponding to either +// the Device or the given |handler| is closed. Note that as a response to +// stopping the device, the service may still need to send out events such as +// VideoFrameHandler.OnBufferRetired() to |handler|. The service will send a +// final event VideoFrameHandler.OnStopped() to indicate that stopping has +// completed and no further events are going to be sent to |handler|. interface Device { Start(media.mojom.VideoCaptureParams requested_settings, - pending_remote<Receiver> receiver); + pending_remote<VideoFrameHandler> handler); MaybeSuspend(); Resume(); GetPhotoState()
diff --git a/services/video_capture/public/mojom/receiver.mojom b/services/video_capture/public/mojom/video_frame_handler.mojom similarity index 75% rename from services/video_capture/public/mojom/receiver.mojom rename to services/video_capture/public/mojom/video_frame_handler.mojom index b9f3274c..d9e6bd94 100644 --- a/services/video_capture/public/mojom/receiver.mojom +++ b/services/video_capture/public/mojom/video_frame_handler.mojom
@@ -10,32 +10,31 @@ // Callback interface for receiving data and messages from a // video_capture.mojom.Device or // video_capture.mojom.PushVideoStreamSubscription. -// TODO: Rename to VideoFrameHandler to avoid confusion with the new Mojo types -// e.g. when currently declaring a mojo::Remote<video_capture::mojom::Receiver>. -interface Receiver { +interface VideoFrameHandler { // Indicates that the producer is going to subsequently use the provided // buffer as one of possibly many for frame delivery via // OnFrameReadyInBuffer(). Note, that a call to this method does not mean that - // the caller allows the receiver to read from or write to the buffer just - // yet. Temporary permission to read will be given with subsequent calls to + // the caller allows the handler to read from or write to the buffer just yet. + // Temporary permission to read will be given with subsequent calls to // OnFrameReadyInBuffer(). OnNewBuffer(int32 buffer_id, media.mojom.VideoBufferHandle buffer_handle); // Indicates that a new frame is ready for consumption in the buffer with id // |buffer_id| and allows it to read the data from the buffer. The producer // guarantees that the buffer and its contents stay alive and unchanged until - // VideoFrameReceiver releases the given |access_permission|. + // VideoFrameHandler releases the given |access_permission|. OnFrameReadyInBuffer(int32 buffer_id, int32 frame_feedback_id, pending_remote<ScopedAccessPermission> access_permission, media.mojom.VideoFrameInfo frame_info); // Indicates that the producer is no longer going to use the buffer with id - // |buffer_id| for frame delivery. This may be called even while the receiver + // |buffer_id| for frame delivery. This may be called even while the handler // is still holding |access_permission| from a call to OnFrameReadInBuffer() // for the same buffer. In that case, it means that the caller is asking the - // VideoFrameReceiver to release the read permission and buffer handle at its - // earliest convenience. After this call, a producer may immediately reuse - // the retired |buffer_id| with a new buffer via a call to OnNewBuffer(). + // VideoFrameHaVideoFrameReceiverndler to release the read permission and + // buffer handle at its earliest convenience. After this call, a producer may + // immediately reuse the retired |buffer_id| with a new buffer via a call to + // OnNewBuffer(). OnBufferRetired(int32 buffer_id); // Indicates that an error occurred on the producer side. @@ -51,6 +50,6 @@ OnStartedUsingGpuDecode(); // Indicates that the producer side has stopped and is not going to make any - // further calls to this Receiver. + // further calls to this VideoFrameHandler. OnStopped(); };
diff --git a/services/video_capture/public/mojom/video_source.mojom b/services/video_capture/public/mojom/video_source.mojom index 6a6cdc75..bbbdac7 100644 --- a/services/video_capture/public/mojom/video_source.mojom +++ b/services/video_capture/public/mojom/video_source.mojom
@@ -6,7 +6,7 @@ import "media/capture/mojom/image_capture.mojom"; import "media/capture/mojom/video_capture_types.mojom"; -import "services/video_capture/public/mojom/receiver.mojom"; +import "services/video_capture/public/mojom/video_frame_handler.mojom"; enum CreatePushSubscriptionResultCode { kCreatedWithRequestedSettings, @@ -81,7 +81,7 @@ // potentially briefly interrupt the video stream received by other // subscribers. CreatePushSubscription( - pending_remote<Receiver> subscriber, + pending_remote<VideoFrameHandler> subscriber, media.mojom.VideoCaptureParams requested_settings, bool force_reopen_with_new_settings, pending_receiver<PushVideoStreamSubscription> subscription)
diff --git a/services/video_capture/push_video_stream_subscription_impl.cc b/services/video_capture/push_video_stream_subscription_impl.cc index c26a62b..ebdcb01 100644 --- a/services/video_capture/push_video_stream_subscription_impl.cc +++ b/services/video_capture/push_video_stream_subscription_impl.cc
@@ -13,7 +13,7 @@ PushVideoStreamSubscriptionImpl::PushVideoStreamSubscriptionImpl( mojo::PendingReceiver<mojom::PushVideoStreamSubscription> subscription_receiver, - mojo::PendingRemote<mojom::Receiver> subscriber, + mojo::PendingRemote<mojom::VideoFrameHandler> subscriber, const media::VideoCaptureParams& requested_settings, mojom::VideoSource::CreatePushSubscriptionCallback creation_callback, BroadcastingReceiver* broadcaster,
diff --git a/services/video_capture/push_video_stream_subscription_impl.h b/services/video_capture/push_video_stream_subscription_impl.h index 8040bd43..febad473 100644 --- a/services/video_capture/push_video_stream_subscription_impl.h +++ b/services/video_capture/push_video_stream_subscription_impl.h
@@ -9,7 +9,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/video_capture/public/mojom/device.mojom.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/video_source.mojom.h" namespace video_capture { @@ -22,7 +22,7 @@ PushVideoStreamSubscriptionImpl( mojo::PendingReceiver<mojom::PushVideoStreamSubscription> subscription_receiver, - mojo::PendingRemote<mojom::Receiver> subscriber, + mojo::PendingRemote<mojom::VideoFrameHandler> subscriber, const media::VideoCaptureParams& requested_settings, mojom::VideoSource::CreatePushSubscriptionCallback creation_callback, BroadcastingReceiver* broadcaster, @@ -58,7 +58,7 @@ void OnConnectionLost(); mojo::Receiver<mojom::PushVideoStreamSubscription> receiver_; - mojo::PendingRemote<mojom::Receiver> subscriber_; + mojo::PendingRemote<mojom::VideoFrameHandler> subscriber_; const media::VideoCaptureParams requested_settings_; mojom::VideoSource::CreatePushSubscriptionCallback creation_callback_; BroadcastingReceiver* const broadcaster_;
diff --git a/services/video_capture/receiver_mojo_to_media_adapter.cc b/services/video_capture/receiver_mojo_to_media_adapter.cc index db9797e..4205ae6b 100644 --- a/services/video_capture/receiver_mojo_to_media_adapter.cc +++ b/services/video_capture/receiver_mojo_to_media_adapter.cc
@@ -10,8 +10,8 @@ namespace video_capture { ReceiverMojoToMediaAdapter::ReceiverMojoToMediaAdapter( - mojo::Remote<mojom::Receiver> receiver) - : receiver_(std::move(receiver)) {} + mojo::Remote<mojom::VideoFrameHandler> handler) + : video_frame_handler_(std::move(handler)) {} ReceiverMojoToMediaAdapter::~ReceiverMojoToMediaAdapter() = default; @@ -23,7 +23,7 @@ void ReceiverMojoToMediaAdapter::OnNewBuffer( int buffer_id, media::mojom::VideoBufferHandlePtr buffer_handle) { - receiver_->OnNewBuffer(buffer_id, std::move(buffer_handle)); + video_frame_handler_->OnNewBuffer(buffer_id, std::move(buffer_handle)); } void ReceiverMojoToMediaAdapter::OnFrameReadyInBuffer( @@ -38,38 +38,38 @@ std::make_unique<ScopedAccessPermissionMediaToMojoAdapter>( std::move(access_permission)), access_permission_proxy.InitWithNewPipeAndPassReceiver()); - receiver_->OnFrameReadyInBuffer(buffer_id, frame_feedback_id, - std::move(access_permission_proxy), - std::move(frame_info)); + video_frame_handler_->OnFrameReadyInBuffer(buffer_id, frame_feedback_id, + std::move(access_permission_proxy), + std::move(frame_info)); } void ReceiverMojoToMediaAdapter::OnBufferRetired(int buffer_id) { - receiver_->OnBufferRetired(buffer_id); + video_frame_handler_->OnBufferRetired(buffer_id); } void ReceiverMojoToMediaAdapter::OnError(media::VideoCaptureError error) { - receiver_->OnError(error); + video_frame_handler_->OnError(error); } void ReceiverMojoToMediaAdapter::OnFrameDropped( media::VideoCaptureFrameDropReason reason) { - receiver_->OnFrameDropped(reason); + video_frame_handler_->OnFrameDropped(reason); } void ReceiverMojoToMediaAdapter::OnLog(const std::string& message) { - receiver_->OnLog(message); + video_frame_handler_->OnLog(message); } void ReceiverMojoToMediaAdapter::OnStarted() { - receiver_->OnStarted(); + video_frame_handler_->OnStarted(); } void ReceiverMojoToMediaAdapter::OnStartedUsingGpuDecode() { - receiver_->OnStartedUsingGpuDecode(); + video_frame_handler_->OnStartedUsingGpuDecode(); } void ReceiverMojoToMediaAdapter::OnStopped() { - receiver_->OnStopped(); + video_frame_handler_->OnStopped(); } } // namespace video_capture
diff --git a/services/video_capture/receiver_mojo_to_media_adapter.h b/services/video_capture/receiver_mojo_to_media_adapter.h index ee4f2a3..88c6a92 100644 --- a/services/video_capture/receiver_mojo_to_media_adapter.h +++ b/services/video_capture/receiver_mojo_to_media_adapter.h
@@ -8,7 +8,7 @@ #include "base/single_thread_task_runner.h" #include "media/capture/video/video_frame_receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" namespace video_capture { @@ -16,7 +16,7 @@ // a media::VideoFrameReceiver. class ReceiverMojoToMediaAdapter : public media::VideoFrameReceiver { public: - ReceiverMojoToMediaAdapter(mojo::Remote<mojom::Receiver> receiver); + ReceiverMojoToMediaAdapter(mojo::Remote<mojom::VideoFrameHandler> handler); ~ReceiverMojoToMediaAdapter() override; base::WeakPtr<media::VideoFrameReceiver> GetWeakPtr(); @@ -40,7 +40,7 @@ void OnStopped() override; private: - mojo::Remote<mojom::Receiver> receiver_; + mojo::Remote<mojom::VideoFrameHandler> video_frame_handler_; base::WeakPtrFactory<ReceiverMojoToMediaAdapter> weak_factory_{this}; };
diff --git a/services/video_capture/scoped_access_permission_media_to_mojo_adapter.h b/services/video_capture/scoped_access_permission_media_to_mojo_adapter.h index e0c4e33..10c39973 100644 --- a/services/video_capture/scoped_access_permission_media_to_mojo_adapter.h +++ b/services/video_capture/scoped_access_permission_media_to_mojo_adapter.h
@@ -6,7 +6,6 @@ #define SERVICES_VIDEO_CAPTURE_SCOPED_ACCESS_PERMISSION_MEDIA_TO_MOJO_ADAPTER_H_ #include "media/capture/video/video_capture_device_client.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" #include "services/video_capture/public/mojom/scoped_access_permission.mojom.h" namespace video_capture {
diff --git a/services/video_capture/shared_memory_virtual_device_mojo_adapter.cc b/services/video_capture/shared_memory_virtual_device_mojo_adapter.cc index a3f60d7..6067b0d 100644 --- a/services/video_capture/shared_memory_virtual_device_mojo_adapter.cc +++ b/services/video_capture/shared_memory_virtual_device_mojo_adapter.cc
@@ -74,8 +74,8 @@ known_buffer_ids_.erase(entry_iter); if (producer_.is_bound()) producer_->OnBufferRetired(buffer_id_to_drop); - if (receiver_.is_bound()) { - receiver_->OnBufferRetired(buffer_id_to_drop); + if (video_frame_handler_.is_bound()) { + video_frame_handler_->OnBufferRetired(buffer_id_to_drop); } } } @@ -87,12 +87,12 @@ } if (!base::Contains(known_buffer_ids_, buffer_id)) { - if (receiver_.is_bound()) { + if (video_frame_handler_.is_bound()) { media::mojom::VideoBufferHandlePtr buffer_handle = media::mojom::VideoBufferHandle::New(); buffer_handle->set_shared_buffer_handle( buffer_pool_->DuplicateAsMojoBuffer(buffer_id)); - receiver_->OnNewBuffer(buffer_id, std::move(buffer_handle)); + video_frame_handler_->OnNewBuffer(buffer_id, std::move(buffer_handle)); } known_buffer_ids_.push_back(buffer_id); @@ -132,7 +132,7 @@ } // Notify receiver if there is one. - if (receiver_.is_bound()) { + if (video_frame_handler_.is_bound()) { buffer_pool_->HoldForConsumers(buffer_id, 1 /* num_clients */); auto access_permission = std::make_unique< media::ScopedBufferPoolReservation<media::ConsumerReleaseTraits>>( @@ -142,22 +142,22 @@ std::make_unique<ScopedAccessPermissionMediaToMojoAdapter>( std::move(access_permission)), access_permission_proxy.InitWithNewPipeAndPassReceiver()); - receiver_->OnFrameReadyInBuffer(buffer_id, 0 /* frame_feedback_id */, - std::move(access_permission_proxy), - std::move(frame_info)); + video_frame_handler_->OnFrameReadyInBuffer( + buffer_id, 0 /* frame_feedback_id */, + std::move(access_permission_proxy), std::move(frame_info)); } buffer_pool_->RelinquishProducerReservation(buffer_id); } void SharedMemoryVirtualDeviceMojoAdapter::Start( const media::VideoCaptureParams& requested_settings, - mojo::PendingRemote<mojom::Receiver> receiver) { + mojo::PendingRemote<mojom::VideoFrameHandler> handler) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - receiver_.Bind(std::move(receiver)); - receiver_.set_disconnect_handler(base::BindOnce( + video_frame_handler_.Bind(std::move(handler)); + video_frame_handler_.set_disconnect_handler(base::BindOnce( &SharedMemoryVirtualDeviceMojoAdapter::OnReceiverConnectionErrorOrClose, base::Unretained(this))); - receiver_->OnStarted(); + video_frame_handler_->OnStarted(); // Notify receiver of known buffers */ for (auto buffer_id : known_buffer_ids_) { @@ -165,7 +165,7 @@ media::mojom::VideoBufferHandle::New(); buffer_handle->set_shared_buffer_handle( buffer_pool_->DuplicateAsMojoBuffer(buffer_id)); - receiver_->OnNewBuffer(buffer_id, std::move(buffer_handle)); + video_frame_handler_->OnNewBuffer(buffer_id, std::move(buffer_handle)); } } @@ -196,15 +196,15 @@ void SharedMemoryVirtualDeviceMojoAdapter::Stop() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!receiver_.is_bound()) + if (!video_frame_handler_.is_bound()) return; // Unsubscribe from connection error callbacks. - receiver_.set_disconnect_handler(base::OnceClosure()); + video_frame_handler_.set_disconnect_handler(base::OnceClosure()); // Send out OnBufferRetired events and OnStopped. for (auto buffer_id : known_buffer_ids_) - receiver_->OnBufferRetired(buffer_id); - receiver_->OnStopped(); - receiver_.reset(); + video_frame_handler_->OnBufferRetired(buffer_id); + video_frame_handler_->OnStopped(); + video_frame_handler_.reset(); } void SharedMemoryVirtualDeviceMojoAdapter::OnReceiverConnectionErrorOrClose() {
diff --git a/services/video_capture/shared_memory_virtual_device_mojo_adapter.h b/services/video_capture/shared_memory_virtual_device_mojo_adapter.h index 792a954e..c1f86f2 100644 --- a/services/video_capture/shared_memory_virtual_device_mojo_adapter.h +++ b/services/video_capture/shared_memory_virtual_device_mojo_adapter.h
@@ -12,7 +12,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/video_capture/public/mojom/device.mojom.h" #include "services/video_capture/public/mojom/producer.mojom.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/virtual_device.mojom.h" namespace video_capture { @@ -37,7 +37,7 @@ // mojom::Device implementation. void Start(const media::VideoCaptureParams& requested_settings, - mojo::PendingRemote<mojom::Receiver> receiver) override; + mojo::PendingRemote<mojom::VideoFrameHandler> receiver) override; void MaybeSuspend() override; void Resume() override; void GetPhotoState(GetPhotoStateCallback callback) override; @@ -54,7 +54,7 @@ private: void OnReceiverConnectionErrorOrClose(); - mojo::Remote<mojom::Receiver> receiver_; + mojo::Remote<mojom::VideoFrameHandler> video_frame_handler_; mojo::Remote<mojom::Producer> producer_; const bool send_buffer_handles_to_producer_as_raw_file_descriptors_; scoped_refptr<media::VideoCaptureBufferPool> buffer_pool_;
diff --git a/services/video_capture/test/fake_device_descriptor_unittest.cc b/services/video_capture/test/fake_device_descriptor_unittest.cc index 5fe588cc..5cb1ee29 100644 --- a/services/video_capture/test/fake_device_descriptor_unittest.cc +++ b/services/video_capture/test/fake_device_descriptor_unittest.cc
@@ -7,8 +7,9 @@ #include "base/run_loop.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" #include "services/video_capture/public/mojom/device.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/test/fake_device_descriptor_test.h" using testing::_; @@ -120,10 +121,11 @@ media::PowerLineFrequency::FREQUENCY_DEFAULT; base::RunLoop wait_loop_2; - mojo::PendingRemote<mojom::Receiver> subscriber; - MockReceiver receiver(subscriber.InitWithNewPipeAndPassReceiver()); - EXPECT_CALL(receiver, DoOnNewBuffer(_, _)).Times(AtLeast(1)); - EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _)) + mojo::PendingRemote<mojom::VideoFrameHandler> subscriber; + MockVideoFrameHandler video_frame_handler( + subscriber.InitWithNewPipeAndPassReceiver()); + EXPECT_CALL(video_frame_handler, DoOnNewBuffer(_, _)).Times(AtLeast(1)); + EXPECT_CALL(video_frame_handler, DoOnFrameReadyInBuffer(_, _, _, _)) .WillRepeatedly( InvokeWithoutArgs([&wait_loop_2]() { wait_loop_2.Quit(); }));
diff --git a/services/video_capture/test/fake_device_unittest.cc b/services/video_capture/test/fake_device_unittest.cc index 442ae9b5..f2b280d 100644 --- a/services/video_capture/test/fake_device_unittest.cc +++ b/services/video_capture/test/fake_device_unittest.cc
@@ -10,9 +10,10 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/video_capture/broadcasting_receiver.h" #include "services/video_capture/device_media_to_mojo_adapter.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" #include "services/video_capture/public/mojom/constants.mojom.h" #include "services/video_capture/public/mojom/device_factory.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/test/fake_device_test.h" using testing::_; @@ -33,10 +34,11 @@ // https://social.msdn.microsoft.com/Forums/SqlServer/4abf18bd-4ae4-4c72-ba3e-3b13e7909d5f static const int kNumFramesToWaitFor = 3; int num_frames_arrived = 0; - mojo::PendingRemote<mojom::Receiver> receiver_proxy; - MockReceiver receiver(receiver_proxy.InitWithNewPipeAndPassReceiver()); - EXPECT_CALL(receiver, DoOnNewBuffer(_, _)).Times(AtLeast(1)); - EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _)) + mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote; + MockVideoFrameHandler video_frame_handler( + handler_remote.InitWithNewPipeAndPassReceiver()); + EXPECT_CALL(video_frame_handler, DoOnNewBuffer(_, _)).Times(AtLeast(1)); + EXPECT_CALL(video_frame_handler, DoOnFrameReadyInBuffer(_, _, _, _)) .WillRepeatedly(InvokeWithoutArgs([&wait_loop, &num_frames_arrived]() { num_frames_arrived += 1; if (num_frames_arrived >= kNumFramesToWaitFor) { @@ -45,7 +47,7 @@ })); i420_fake_device_remote_->Start(requestable_settings_, - std::move(receiver_proxy)); + std::move(handler_remote)); wait_loop.Run(); } @@ -58,20 +60,21 @@ // https://social.msdn.microsoft.com/Forums/SqlServer/4abf18bd-4ae4-4c72-ba3e-3b13e7909d5f static const int kNumFramesToWaitFor = 3; int num_frames_arrived = 0; - mojo::PendingRemote<mojom::Receiver> receiver_proxy; - MockReceiver receiver(receiver_proxy.InitWithNewPipeAndPassReceiver()); - EXPECT_CALL(receiver, DoOnNewBuffer(_, _)).Times(AtLeast(1)); - EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _)) + mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote; + MockVideoFrameHandler video_frame_handler( + handler_remote.InitWithNewPipeAndPassReceiver()); + EXPECT_CALL(video_frame_handler, DoOnNewBuffer(_, _)).Times(AtLeast(1)); + EXPECT_CALL(video_frame_handler, DoOnFrameReadyInBuffer(_, _, _, _)) .WillRepeatedly(InvokeWithoutArgs([&wait_loop, &num_frames_arrived]() { num_frames_arrived += 1; if (num_frames_arrived >= kNumFramesToWaitFor) { wait_loop.Quit(); } })); - EXPECT_CALL(receiver, OnStartedUsingGpuDecode()).Times(0); + EXPECT_CALL(video_frame_handler, OnStartedUsingGpuDecode()).Times(0); mjpeg_fake_device_remote_->Start(requestable_settings_, - std::move(receiver_proxy)); + std::move(handler_remote)); wait_loop.Run(); } @@ -87,12 +90,13 @@ static const int kNumFramesToWaitFor = kMaxBufferPoolBuffers + 3; int num_buffers_created = 0; int num_frames_arrived = 0; - mojo::PendingRemote<mojom::Receiver> receiver_proxy; - MockReceiver receiver(receiver_proxy.InitWithNewPipeAndPassReceiver()); - EXPECT_CALL(receiver, DoOnNewBuffer(_, _)) + mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote; + MockVideoFrameHandler video_frame_handler( + handler_remote.InitWithNewPipeAndPassReceiver()); + EXPECT_CALL(video_frame_handler, DoOnNewBuffer(_, _)) .WillRepeatedly(InvokeWithoutArgs( [&num_buffers_created]() { num_buffers_created++; })); - EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _)) + EXPECT_CALL(video_frame_handler, DoOnFrameReadyInBuffer(_, _, _, _)) .WillRepeatedly(InvokeWithoutArgs([&wait_loop, &num_frames_arrived]() { if (++num_frames_arrived >= kNumFramesToWaitFor) { wait_loop.Quit(); @@ -100,7 +104,7 @@ })); i420_fake_device_remote_->Start(requestable_settings_, - std::move(receiver_proxy)); + std::move(handler_remote)); wait_loop.Run(); ASSERT_LT(num_buffers_created, num_frames_arrived); @@ -114,15 +118,16 @@ static const int kNumFramesToWaitFor = 2; std::vector<int32_t> known_buffer_ids; int num_frames_arrived = 0; - mojo::PendingRemote<mojom::Receiver> receiver_proxy; - MockReceiver receiver(receiver_proxy.InitWithNewPipeAndPassReceiver()); - EXPECT_CALL(receiver, DoOnNewBuffer(_, _)) + mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote; + MockVideoFrameHandler video_frame_handler( + handler_remote.InitWithNewPipeAndPassReceiver()); + EXPECT_CALL(video_frame_handler, DoOnNewBuffer(_, _)) .WillRepeatedly( Invoke([&known_buffer_ids](int32_t buffer_id, media::mojom::VideoBufferHandlePtr*) { known_buffer_ids.push_back(buffer_id); })); - EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _)) + EXPECT_CALL(video_frame_handler, DoOnFrameReadyInBuffer(_, _, _, _)) .WillRepeatedly( InvokeWithoutArgs([&wait_for_frames_loop, &num_frames_arrived]() { if (++num_frames_arrived >= kNumFramesToWaitFor) { @@ -131,18 +136,18 @@ })); i420_fake_device_remote_->Start(requestable_settings_, - std::move(receiver_proxy)); + std::move(handler_remote)); wait_for_frames_loop.Run(); base::RunLoop wait_for_on_stopped_loop; - EXPECT_CALL(receiver, DoOnBufferRetired(_)) + EXPECT_CALL(video_frame_handler, DoOnBufferRetired(_)) .WillRepeatedly(Invoke([&known_buffer_ids](int32_t buffer_id) { auto iter = std::find(known_buffer_ids.begin(), known_buffer_ids.end(), buffer_id); ASSERT_TRUE(iter != known_buffer_ids.end()); known_buffer_ids.erase(iter); })); - EXPECT_CALL(receiver, OnStopped()) + EXPECT_CALL(video_frame_handler, OnStopped()) .WillOnce(Invoke( [&wait_for_on_stopped_loop]() { wait_for_on_stopped_loop.Quit(); })); @@ -161,9 +166,10 @@ static const int kNumFramesToWaitFor = 3; int num_frames_arrived = 0; std::map<int32_t, media::mojom::VideoBufferHandlePtr> buffers_by_id; - mojo::PendingRemote<mojom::Receiver> receiver_proxy; - MockReceiver receiver(receiver_proxy.InitWithNewPipeAndPassReceiver()); - EXPECT_CALL(receiver, DoOnNewBuffer(_, _)) + mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote; + MockVideoFrameHandler video_frame_handler( + handler_remote.InitWithNewPipeAndPassReceiver()); + EXPECT_CALL(video_frame_handler, DoOnNewBuffer(_, _)) .Times(AtLeast(1)) .WillRepeatedly(Invoke( [&buffers_by_id](int32_t buffer_id, @@ -172,8 +178,8 @@ (*buffer_handle)->is_shared_memory_via_raw_file_descriptor()); // |buffer_handle| is a |VideoBufferHandlePtr*| only because gmock // doesn't handle move-only types. Because |buffer_handle| is not - // used in the MockReceiver implementation of |OnNewBuffer|, it is - // safe to move the reference. + // used in the MockVideoFrameHandler implementation of + // |OnNewBuffer|, it is safe to move the reference. BroadcastingReceiver::BufferContext context( buffer_id, std::move(*buffer_handle)); // Use |context| to convert the raw file descriptor handle to a @@ -184,7 +190,7 @@ media::VideoCaptureBufferType::kSharedMemory))); })); bool found_unexpected_all_zero_frame = false; - EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _)) + EXPECT_CALL(video_frame_handler, DoOnFrameReadyInBuffer(_, _, _, _)) .WillRepeatedly( Invoke([&wait_loop, &num_frames_arrived, &buffers_by_id, &found_unexpected_all_zero_frame]( @@ -221,7 +227,7 @@ settings_to_request.buffer_type = media::VideoCaptureBufferType::kSharedMemoryViaRawFileDescriptor; i420_fake_device_remote_->Start(settings_to_request, - std::move(receiver_proxy)); + std::move(handler_remote)); wait_loop.Run(); EXPECT_FALSE(found_unexpected_all_zero_frame); }
diff --git a/services/video_capture/test/mock_device_shared_access_unittest.cc b/services/video_capture/test/mock_device_shared_access_unittest.cc index 89133bf..04ea779 100644 --- a/services/video_capture/test/mock_device_shared_access_unittest.cc +++ b/services/video_capture/test/mock_device_shared_access_unittest.cc
@@ -16,8 +16,9 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/video_capture/device_factory_media_to_mojo_adapter.h" #include "services/video_capture/device_media_to_mojo_adapter.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" #include "services/video_capture/public/mojom/video_capture_service.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/video_source.mojom.h" #include "services/video_capture/video_source_provider_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,8 +34,10 @@ class MockDeviceSharedAccessTest : public ::testing::Test { public: MockDeviceSharedAccessTest() - : mock_receiver_1_(receiver_1_.InitWithNewPipeAndPassReceiver()), - mock_receiver_2_(receiver_2_.InitWithNewPipeAndPassReceiver()), + : mock_video_frame_handler_1_( + video_frame_handler_1_.InitWithNewPipeAndPassReceiver()), + mock_video_frame_handler_2_( + video_frame_handler_2_.InitWithNewPipeAndPassReceiver()), next_arbitrary_frame_feedback_id_(123) {} ~MockDeviceSharedAccessTest() override {} @@ -84,7 +87,7 @@ void LetClient1ConnectWithRequestableSettingsAndExpectToGetThem() { base::RunLoop run_loop; source_->CreatePushSubscription( - std::move(receiver_1_), requestable_settings_, + std::move(video_frame_handler_1_), requestable_settings_, false /*force_reopen_with_new_settings*/, subscription_1_.BindNewPipeAndPassReceiver(), base::BindOnce( @@ -114,7 +117,7 @@ mojom::CreatePushSubscriptionResultCode expected_result_code) { base::RunLoop run_loop; source_->CreatePushSubscription( - std::move(receiver_2_), requestable_settings_, + std::move(video_frame_handler_2_), requestable_settings_, force_reopen_with_new_settings, subscription_2_.BindNewPipeAndPassReceiver(), base::BindOnce( @@ -151,7 +154,7 @@ base::RunLoop run_loop_1; base::RunLoop run_loop_2; source_->CreatePushSubscription( - std::move(receiver_1_), requestable_settings_, + std::move(video_frame_handler_1_), requestable_settings_, false /*force_reopen_with_new_settings*/, subscription_1_.BindNewPipeAndPassReceiver(), base::BindOnce( @@ -174,7 +177,7 @@ ASSERT_FALSE(requestable_settings_ == different_settings); source_->CreatePushSubscription( - std::move(receiver_2_), different_settings, + std::move(video_frame_handler_2_), different_settings, false /*force_reopen_with_new_settings*/, subscription_2_.BindNewPipeAndPassReceiver(), base::BindOnce( @@ -200,19 +203,19 @@ next_arbitrary_frame_feedback_id_++; const int32_t kArbitraryRotation = 0; base::RunLoop wait_loop_1; - EXPECT_CALL(mock_receiver_1_, + EXPECT_CALL(mock_video_frame_handler_1_, DoOnFrameReadyInBuffer(_, kArbitraryFrameFeedbackId, _, _)) .WillOnce(InvokeWithoutArgs([&wait_loop_1]() { wait_loop_1.Quit(); })); base::RunLoop wait_loop_2; - EXPECT_CALL(mock_receiver_2_, + EXPECT_CALL(mock_video_frame_handler_2_, DoOnFrameReadyInBuffer(_, kArbitraryFrameFeedbackId, _, _)) .WillOnce(InvokeWithoutArgs([&wait_loop_2]() { wait_loop_2.Quit(); })); mock_device_.SendStubFrame(requestable_settings_.requested_format, kArbitraryRotation, kArbitraryFrameFeedbackId); wait_loop_1.Run(); wait_loop_2.Run(); - Mock::VerifyAndClearExpectations(&mock_receiver_1_); - Mock::VerifyAndClearExpectations(&mock_receiver_2_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_1_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_2_); } void SendFrameAndExpectToArriveOnlyAtSubscriber1() { @@ -221,15 +224,16 @@ const int32_t kArbitraryRotation = 0; base::RunLoop wait_loop; - EXPECT_CALL(mock_receiver_1_, + EXPECT_CALL(mock_video_frame_handler_1_, DoOnFrameReadyInBuffer(_, kArbitraryFrameFeedbackId, _, _)) .WillOnce(InvokeWithoutArgs([&wait_loop]() { wait_loop.Quit(); })); - EXPECT_CALL(mock_receiver_2_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); + EXPECT_CALL(mock_video_frame_handler_2_, DoOnFrameReadyInBuffer(_, _, _, _)) + .Times(0); mock_device_.SendStubFrame(requestable_settings_.requested_format, kArbitraryRotation, kArbitraryFrameFeedbackId); wait_loop.Run(); - Mock::VerifyAndClearExpectations(&mock_receiver_1_); - Mock::VerifyAndClearExpectations(&mock_receiver_2_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_1_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_2_); } void SendFrameAndExpectToArriveOnlyAtSubscriber2() { @@ -238,15 +242,16 @@ const int32_t kArbitraryRotation = 0; base::RunLoop wait_loop; - EXPECT_CALL(mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); - EXPECT_CALL(mock_receiver_2_, + EXPECT_CALL(mock_video_frame_handler_1_, DoOnFrameReadyInBuffer(_, _, _, _)) + .Times(0); + EXPECT_CALL(mock_video_frame_handler_2_, DoOnFrameReadyInBuffer(_, kArbitraryFrameFeedbackId, _, _)) .WillOnce(InvokeWithoutArgs([&wait_loop]() { wait_loop.Quit(); })); mock_device_.SendStubFrame(requestable_settings_.requested_format, kArbitraryRotation, kArbitraryFrameFeedbackId); wait_loop.Run(); - Mock::VerifyAndClearExpectations(&mock_receiver_1_); - Mock::VerifyAndClearExpectations(&mock_receiver_2_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_1_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_2_); } protected: @@ -259,11 +264,11 @@ media::VideoCaptureParams requestable_settings_; mojo::Remote<mojom::PushVideoStreamSubscription> subscription_1_; - mojo::PendingRemote<mojom::Receiver> receiver_1_; - MockReceiver mock_receiver_1_; + mojo::PendingRemote<mojom::VideoFrameHandler> video_frame_handler_1_; + MockVideoFrameHandler mock_video_frame_handler_1_; mojo::Remote<mojom::PushVideoStreamSubscription> subscription_2_; - mojo::PendingRemote<mojom::Receiver> receiver_2_; - MockReceiver mock_receiver_2_; + mojo::PendingRemote<mojom::VideoFrameHandler> video_frame_handler_2_; + MockVideoFrameHandler mock_video_frame_handler_2_; int32_t next_arbitrary_frame_feedback_id_; @@ -318,12 +323,12 @@ TEST_F(MockVideoCaptureDeviceSharedAccessTest, InternalDeviceRestartIsTransparentToExistingSubscribers) { LetClient1ConnectWithRequestableSettingsAndExpectToGetThem(); - EXPECT_CALL(mock_receiver_1_, DoOnNewBuffer(_, _)).Times(1); - EXPECT_CALL(mock_receiver_1_, OnStarted()).Times(1); + EXPECT_CALL(mock_video_frame_handler_1_, DoOnNewBuffer(_, _)).Times(1); + EXPECT_CALL(mock_video_frame_handler_1_, OnStarted()).Times(1); subscription_1_->Activate(); mock_device_.SendOnStarted(); SendFrameAndExpectToArriveOnlyAtSubscriber1(); - Mock::VerifyAndClearExpectations(&mock_receiver_1_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_1_); auto previously_requested_settings = requestable_settings_; // Change something arbitrary @@ -332,11 +337,11 @@ { testing::InSequence s; - EXPECT_CALL(mock_receiver_1_, DoOnBufferRetired(_)).Times(1); - EXPECT_CALL(mock_receiver_1_, DoOnNewBuffer(_, _)).Times(1); + EXPECT_CALL(mock_video_frame_handler_1_, DoOnBufferRetired(_)).Times(1); + EXPECT_CALL(mock_video_frame_handler_1_, DoOnNewBuffer(_, _)).Times(1); } - EXPECT_CALL(mock_receiver_1_, OnStopped()).Times(0); - EXPECT_CALL(mock_receiver_1_, OnStarted()).Times(0); + EXPECT_CALL(mock_video_frame_handler_1_, OnStopped()).Times(0); + EXPECT_CALL(mock_video_frame_handler_1_, OnStarted()).Times(0); LetClient2ConnectWithRequestableSettings( true /*force_reopen_with_new_settings*/, @@ -345,7 +350,7 @@ mock_device_.SendOnStarted(); SendFrameAndExpectToArriveAtBothSubscribers(); - Mock::VerifyAndClearExpectations(&mock_receiver_1_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_1_); } TEST_F(MockVideoCaptureDeviceSharedAccessTest, @@ -383,9 +388,10 @@ subscription_2_.reset(); wait_loop.Run(); - // DeviceMediaToMojoAdapter::Stop() issues a DeleteSoon for its |receiver_| - // on the current sequence. Wait for this before exiting the test in order to - // avoid leaked object failing ASAN tests. See also https://crbug.com/961066. + // DeviceMediaToMojoAdapter::Stop() issues a DeleteSoon for its + // |video_frame_handler_| on the current sequence. Wait for this before + // exiting the test in order to avoid leaked object failing ASAN tests. See + // also https://crbug.com/961066. base::RunLoop().RunUntilIdle(); } @@ -401,9 +407,10 @@ source_.reset(); wait_loop.Run(); - // DeviceMediaToMojoAdapter::Stop() issues a DeleteSoon for its |receiver_| - // on the current sequence. Wait for this before exiting the test in order to - // avoid leaked object failing ASAN tests. See also https://crbug.com/961066. + // DeviceMediaToMojoAdapter::Stop() issues a DeleteSoon for its + // |video_frame_handler_| on the current sequence. Wait for this before + // exiting the test in order to avoid leaked object failing ASAN tests. See + // also https://crbug.com/961066. base::RunLoop().RunUntilIdle(); } @@ -454,7 +461,8 @@ [](base::RunLoop* wait_loop) { wait_loop->Quit(); }, &wait_loop)); wait_loop.Run(); } - EXPECT_CALL(mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); + EXPECT_CALL(mock_video_frame_handler_1_, DoOnFrameReadyInBuffer(_, _, _, _)) + .Times(0); // Send a couple of frames. We want to send at least as many frames as // the maximum buffer count in the video frame pool to make sure that @@ -470,7 +478,7 @@ // We need to wait until the frame has arrived at BroadcastingReceiver base::RunLoop().RunUntilIdle(); } - Mock::VerifyAndClearExpectations(&mock_receiver_1_); + Mock::VerifyAndClearExpectations(&mock_video_frame_handler_1_); subscription_1_->Resume(); subscription_1_.FlushForTesting();
diff --git a/services/video_capture/test/mock_device_test.cc b/services/video_capture/test/mock_device_test.cc index 4b9637df..65f4bf81 100644 --- a/services/video_capture/test/mock_device_test.cc +++ b/services/video_capture/test/mock_device_test.cc
@@ -68,7 +68,7 @@ requested_settings_.power_line_frequency = media::PowerLineFrequency::FREQUENCY_DEFAULT; - mock_receiver_ = std::make_unique<MockReceiver>( + mock_video_frame_handler_ = std::make_unique<MockVideoFrameHandler>( mock_subscriber_.InitWithNewPipeAndPassReceiver()); }
diff --git a/services/video_capture/test/mock_device_test.h b/services/video_capture/test/mock_device_test.h index 3370f60..0a08dc8 100644 --- a/services/video_capture/test/mock_device_test.h +++ b/services/video_capture/test/mock_device_test.h
@@ -13,9 +13,10 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/video_capture/device_factory_media_to_mojo_adapter.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" #include "services/video_capture/public/mojom/device.mojom.h" #include "services/video_capture/public/mojom/video_capture_service.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -44,9 +45,9 @@ device_infos_receiver_; media::MockDevice mock_device_; - std::unique_ptr<MockReceiver> mock_receiver_; + std::unique_ptr<MockVideoFrameHandler> mock_video_frame_handler_; mojo::Remote<mojom::Device> device_remote_; - mojo::PendingRemote<mojom::Receiver> mock_subscriber_; + mojo::PendingRemote<mojom::VideoFrameHandler> mock_subscriber_; media::VideoCaptureParams requested_settings_; private:
diff --git a/services/video_capture/test/mock_device_unittest.cc b/services/video_capture/test/mock_device_unittest.cc index 16ada4a..32e61f9 100644 --- a/services/video_capture/test/mock_device_unittest.cc +++ b/services/video_capture/test/mock_device_unittest.cc
@@ -47,7 +47,7 @@ .WillOnce(Invoke([&wait_loop]() { wait_loop.Quit(); })); device_remote_->Start(requested_settings_, std::move(mock_subscriber_)); - mock_receiver_.reset(); + mock_video_frame_handler_.reset(); wait_loop.Run(); }
diff --git a/services/video_capture/test/service_lifecycle_unittest.cc b/services/video_capture/test/service_lifecycle_unittest.cc index 39ec466..89a7a78b 100644 --- a/services/video_capture/test/service_lifecycle_unittest.cc +++ b/services/video_capture/test/service_lifecycle_unittest.cc
@@ -11,10 +11,11 @@ #include "media/base/media_switches.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" #include "services/video_capture/public/mojom/constants.mojom.h" #include "services/video_capture/public/mojom/device.mojom.h" #include "services/video_capture/public/mojom/video_capture_service.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/video_source_provider.mojom.h" #include "services/video_capture/video_capture_service_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -172,12 +173,13 @@ })); media::VideoCaptureParams requestable_settings; requestable_settings.requested_format = fake_device_info.supported_formats[0]; - mojo::PendingRemote<mojom::Receiver> receiver_proxy; - MockReceiver mock_receiver(receiver_proxy.InitWithNewPipeAndPassReceiver()); - fake_device->Start(requestable_settings, std::move(receiver_proxy)); + mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote; + MockVideoFrameHandler mock_video_frame_handler( + handler_remote.InitWithNewPipeAndPassReceiver()); + fake_device->Start(requestable_settings, std::move(handler_remote)); { base::RunLoop wait_loop; - EXPECT_CALL(mock_receiver, OnStarted()).WillOnce([&wait_loop]() { + EXPECT_CALL(mock_video_frame_handler, OnStarted()).WillOnce([&wait_loop]() { wait_loop.Quit(); }); wait_loop.Run();
diff --git a/services/video_capture/test/virtual_device_unittest.cc b/services/video_capture/test/virtual_device_unittest.cc index f3fbb91..2f9ab38 100644 --- a/services/video_capture/test/virtual_device_unittest.cc +++ b/services/video_capture/test/virtual_device_unittest.cc
@@ -10,7 +10,8 @@ #include "media/capture/video/video_capture_device_info.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/video_capture/public/cpp/mock_producer.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/shared_memory_virtual_device_mojo_adapter.h" #include "testing/gtest/include/gtest/gtest.h" @@ -131,24 +132,25 @@ // Release all buffers back to consumer, then back to the pool // after |Receiver::OnFrameReadyInBuffer| is invoked. base::RunLoop wait_loop; - mojo::PendingRemote<mojom::Receiver> receiver_proxy; - MockReceiver receiver(receiver_proxy.InitWithNewPipeAndPassReceiver()); - EXPECT_CALL(receiver, OnStarted()); - EXPECT_CALL(receiver, DoOnNewBuffer(_, _)) + mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote; + MockVideoFrameHandler video_frame_handler( + handler_remote.InitWithNewPipeAndPassReceiver()); + EXPECT_CALL(video_frame_handler, OnStarted()); + EXPECT_CALL(video_frame_handler, DoOnNewBuffer(_, _)) .Times( SharedMemoryVirtualDeviceMojoAdapter::max_buffer_pool_buffer_count()); - EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _)) + EXPECT_CALL(video_frame_handler, DoOnFrameReadyInBuffer(_, _, _, _)) .Times( SharedMemoryVirtualDeviceMojoAdapter::max_buffer_pool_buffer_count()); device_adapter_->Start(media::VideoCaptureParams(), - std::move(receiver_proxy)); + std::move(handler_remote)); for (auto buffer_id : received_buffer_ids_) { media::mojom::VideoFrameInfoPtr info = media::mojom::VideoFrameInfo::New(); info->metadata = base::Value(base::Value::Type::DICTIONARY); device_adapter_->OnFrameReadyInBuffer(buffer_id, std::move(info)); } wait_loop.RunUntilIdle(); - Mock::VerifyAndClearExpectations(&receiver); + Mock::VerifyAndClearExpectations(&video_frame_handler); // Verify that requesting a buffer doesn't create a new one, will reuse // the available buffer in the pool. @@ -172,10 +174,10 @@ base::RunLoop wait_for_stopped_loop; { testing::InSequence s; - EXPECT_CALL(receiver, DoOnBufferRetired(_)) + EXPECT_CALL(video_frame_handler, DoOnBufferRetired(_)) .Times(SharedMemoryVirtualDeviceMojoAdapter:: max_buffer_pool_buffer_count()); - EXPECT_CALL(receiver, OnStopped()) + EXPECT_CALL(video_frame_handler, OnStopped()) .WillOnce(Invoke( [&wait_for_stopped_loop]() { wait_for_stopped_loop.Quit(); })); }
diff --git a/services/video_capture/texture_virtual_device_mojo_adapter.cc b/services/video_capture/texture_virtual_device_mojo_adapter.cc index 57e7751..8248e4f7 100644 --- a/services/video_capture/texture_virtual_device_mojo_adapter.cc +++ b/services/video_capture/texture_virtual_device_mojo_adapter.cc
@@ -36,12 +36,12 @@ known_buffer_handles_.insert( std::make_pair(buffer_id, mailbox_handles->Clone())); - if (!receiver_.is_bound()) + if (!video_frame_handler_.is_bound()) return; media::mojom::VideoBufferHandlePtr buffer_handle = media::mojom::VideoBufferHandle::New(); buffer_handle->set_mailbox_handles(std::move(mailbox_handles)); - receiver_->OnNewBuffer(buffer_id, std::move(buffer_handle)); + video_frame_handler_->OnNewBuffer(buffer_id, std::move(buffer_handle)); } void TextureVirtualDeviceMojoAdapter::OnFrameReadyInBuffer( @@ -49,37 +49,37 @@ mojo::PendingRemote<mojom::ScopedAccessPermission> access_permission, media::mojom::VideoFrameInfoPtr frame_info) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!receiver_.is_bound()) + if (!video_frame_handler_.is_bound()) return; - receiver_->OnFrameReadyInBuffer(buffer_id, 0 /* frame_feedback_id */, - std::move(access_permission), - std::move(frame_info)); + video_frame_handler_->OnFrameReadyInBuffer( + buffer_id, 0 /* frame_feedback_id */, std::move(access_permission), + std::move(frame_info)); } void TextureVirtualDeviceMojoAdapter::OnBufferRetired(int buffer_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); known_buffer_handles_.erase(buffer_id); - if (!receiver_.is_bound()) + if (!video_frame_handler_.is_bound()) return; - receiver_->OnBufferRetired(buffer_id); + video_frame_handler_->OnBufferRetired(buffer_id); } void TextureVirtualDeviceMojoAdapter::Start( const media::VideoCaptureParams& requested_settings, - mojo::PendingRemote<mojom::Receiver> receiver) { + mojo::PendingRemote<mojom::VideoFrameHandler> handler) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - receiver_.Bind(std::move(receiver)); - receiver_.set_disconnect_handler(base::BindOnce( + video_frame_handler_.Bind(std::move(handler)); + video_frame_handler_.set_disconnect_handler(base::BindOnce( &TextureVirtualDeviceMojoAdapter::OnReceiverConnectionErrorOrClose, base::Unretained(this))); - receiver_->OnStarted(); + video_frame_handler_->OnStarted(); // Notify receiver of known buffer handles */ for (auto& entry : known_buffer_handles_) { media::mojom::VideoBufferHandlePtr buffer_handle = media::mojom::VideoBufferHandle::New(); buffer_handle->set_mailbox_handles(entry.second->Clone()); - receiver_->OnNewBuffer(entry.first, std::move(buffer_handle)); + video_frame_handler_->OnNewBuffer(entry.first, std::move(buffer_handle)); } } @@ -109,15 +109,15 @@ void TextureVirtualDeviceMojoAdapter::Stop() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!receiver_.is_bound()) + if (!video_frame_handler_.is_bound()) return; // Unsubscribe from connection error callbacks. - receiver_.set_disconnect_handler(base::OnceClosure()); + video_frame_handler_.set_disconnect_handler(base::OnceClosure()); // Send out OnBufferRetired events and OnStopped. for (const auto& entry : known_buffer_handles_) - receiver_->OnBufferRetired(entry.first); - receiver_->OnStopped(); - receiver_.reset(); + video_frame_handler_->OnBufferRetired(entry.first); + video_frame_handler_->OnStopped(); + video_frame_handler_.reset(); } void TextureVirtualDeviceMojoAdapter::OnReceiverConnectionErrorOrClose() {
diff --git a/services/video_capture/texture_virtual_device_mojo_adapter.h b/services/video_capture/texture_virtual_device_mojo_adapter.h index 4690fe8c..f7608012 100644 --- a/services/video_capture/texture_virtual_device_mojo_adapter.h +++ b/services/video_capture/texture_virtual_device_mojo_adapter.h
@@ -12,7 +12,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/video_capture/public/mojom/device.mojom.h" #include "services/video_capture/public/mojom/producer.mojom.h" -#include "services/video_capture/public/mojom/receiver.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/virtual_device.mojom.h" namespace video_capture { @@ -37,7 +37,7 @@ // mojom::Device implementation. void Start(const media::VideoCaptureParams& requested_settings, - mojo::PendingRemote<mojom::Receiver> receiver) override; + mojo::PendingRemote<mojom::VideoFrameHandler> handler) override; void MaybeSuspend() override; void Resume() override; void GetPhotoState(GetPhotoStateCallback callback) override; @@ -51,7 +51,7 @@ void OnReceiverConnectionErrorOrClose(); base::OnceClosure optional_receiver_disconnected_callback_; - mojo::Remote<mojom::Receiver> receiver_; + mojo::Remote<mojom::VideoFrameHandler> video_frame_handler_; std::unordered_map<int32_t, media::mojom::MailboxBufferHandleSetPtr> known_buffer_handles_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/services/video_capture/texture_virtual_device_mojo_adapter_unittest.cc b/services/video_capture/texture_virtual_device_mojo_adapter_unittest.cc index e50fae3..75f28d3 100644 --- a/services/video_capture/texture_virtual_device_mojo_adapter_unittest.cc +++ b/services/video_capture/texture_virtual_device_mojo_adapter_unittest.cc
@@ -7,7 +7,8 @@ #include "base/run_loop.h" #include "base/test/task_environment.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/video_capture/public/cpp/mock_receiver.h" +#include "services/video_capture/public/cpp/mock_video_frame_handler.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,10 +22,10 @@ TextureVirtualDeviceMojoAdapterTest() = default; void SetUp() override { - mock_receiver_1_ = std::make_unique<MockReceiver>( - receiver_1_.InitWithNewPipeAndPassReceiver()); - mock_receiver_2_ = std::make_unique<MockReceiver>( - receiver_2_.InitWithNewPipeAndPassReceiver()); + mock_video_frame_handler_1_ = std::make_unique<MockVideoFrameHandler>( + video_frame_handler_1_.InitWithNewPipeAndPassReceiver()); + mock_video_frame_handler_2_ = std::make_unique<MockVideoFrameHandler>( + video_frame_handler_2_.InitWithNewPipeAndPassReceiver()); adapter_ = std::make_unique<TextureVirtualDeviceMojoAdapter>(); } @@ -42,29 +43,31 @@ void Receiver1Connects() { const media::VideoCaptureParams kArbitraryRequestedSettings; - adapter_->Start(kArbitraryRequestedSettings, std::move(receiver_1_)); + adapter_->Start(kArbitraryRequestedSettings, + std::move(video_frame_handler_1_)); } void Receiver2Connects() { const media::VideoCaptureParams kArbitraryRequestedSettings; - adapter_->Start(kArbitraryRequestedSettings, std::move(receiver_2_)); + adapter_->Start(kArbitraryRequestedSettings, + std::move(video_frame_handler_2_)); } void Receiver1Disconnects() { base::RunLoop wait_loop; adapter_->SetReceiverDisconnectedCallback(wait_loop.QuitClosure()); - mock_receiver_1_.reset(); + mock_video_frame_handler_1_.reset(); wait_loop.Run(); } - std::unique_ptr<MockReceiver> mock_receiver_1_; - std::unique_ptr<MockReceiver> mock_receiver_2_; + std::unique_ptr<MockVideoFrameHandler> mock_video_frame_handler_1_; + std::unique_ptr<MockVideoFrameHandler> mock_video_frame_handler_2_; private: base::test::TaskEnvironment task_environment_; std::unique_ptr<TextureVirtualDeviceMojoAdapter> adapter_; - mojo::PendingRemote<mojom::Receiver> receiver_1_; - mojo::PendingRemote<mojom::Receiver> receiver_2_; + mojo::PendingRemote<mojom::VideoFrameHandler> video_frame_handler_1_; + mojo::PendingRemote<mojom::VideoFrameHandler> video_frame_handler_2_; }; // Tests that when buffer handles are shared by the producer before a receiver @@ -79,13 +82,15 @@ base::RunLoop wait_loop; int buffer_received_count = 0; - EXPECT_CALL(*mock_receiver_1_, DoOnNewBuffer(kArbitraryBufferId1, _)) + EXPECT_CALL(*mock_video_frame_handler_1_, + DoOnNewBuffer(kArbitraryBufferId1, _)) .WillOnce(InvokeWithoutArgs([&wait_loop, &buffer_received_count]() { buffer_received_count++; if (buffer_received_count == 2) wait_loop.Quit(); })); - EXPECT_CALL(*mock_receiver_1_, DoOnNewBuffer(kArbitraryBufferId2, _)) + EXPECT_CALL(*mock_video_frame_handler_1_, + DoOnNewBuffer(kArbitraryBufferId2, _)) .WillOnce(InvokeWithoutArgs([&wait_loop, &buffer_received_count]() { buffer_received_count++; if (buffer_received_count == 2) @@ -110,7 +115,8 @@ ProducerRetiresBufferHandle(kArbitraryBufferId1); base::RunLoop wait_loop; - EXPECT_CALL(*mock_receiver_2_, DoOnNewBuffer(kArbitraryBufferId2, _)) + EXPECT_CALL(*mock_video_frame_handler_2_, + DoOnNewBuffer(kArbitraryBufferId2, _)) .WillOnce(InvokeWithoutArgs([&wait_loop]() { wait_loop.Quit(); })); Receiver2Connects(); wait_loop.Run();
diff --git a/services/video_capture/video_source_impl.cc b/services/video_capture/video_source_impl.cc index 21863fd7..a19d6ed4 100644 --- a/services/video_capture/video_source_impl.cc +++ b/services/video_capture/video_source_impl.cc
@@ -36,7 +36,7 @@ } void VideoSourceImpl::CreatePushSubscription( - mojo::PendingRemote<mojom::Receiver> subscriber, + mojo::PendingRemote<mojom::VideoFrameHandler> subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver<mojom::PushVideoStreamSubscription> @@ -105,9 +105,10 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); switch (result_code) { case mojom::DeviceAccessResultCode::SUCCESS: { - broadcaster_receiver_.reset(); - device_->Start(device_start_settings_, - broadcaster_receiver_.BindNewPipeAndPassRemote()); + broadcaster_video_frame_handler_.reset(); + device_->Start( + device_start_settings_, + broadcaster_video_frame_handler_.BindNewPipeAndPassRemote()); device_status_ = DeviceStatus::kStarted; if (push_subscriptions_.empty()) { StopDeviceAsynchronously();
diff --git a/services/video_capture/video_source_impl.h b/services/video_capture/video_source_impl.h index 7fd377d..7a8379be 100644 --- a/services/video_capture/video_source_impl.h +++ b/services/video_capture/video_source_impl.h
@@ -18,6 +18,7 @@ #include "services/video_capture/broadcasting_receiver.h" #include "services/video_capture/device_factory_media_to_mojo_adapter.h" #include "services/video_capture/public/mojom/device.mojom.h" +#include "services/video_capture/public/mojom/video_frame_handler.mojom.h" #include "services/video_capture/public/mojom/video_source.mojom.h" #include "services/video_capture/public/mojom/video_source_provider.mojom.h" @@ -36,7 +37,7 @@ // mojom::VideoSource implementation. void CreatePushSubscription( - mojo::PendingRemote<mojom::Receiver> subscriber, + mojo::PendingRemote<mojom::VideoFrameHandler> subscriber, const media::VideoCaptureParams& requested_settings, bool force_reopen_with_new_settings, mojo::PendingReceiver<mojom::PushVideoStreamSubscription> subscription, @@ -70,7 +71,8 @@ std::unique_ptr<PushVideoStreamSubscriptionImpl>> push_subscriptions_; BroadcastingReceiver broadcaster_; - mojo::Receiver<mojom::Receiver> broadcaster_receiver_{&broadcaster_}; + mojo::Receiver<mojom::VideoFrameHandler> broadcaster_video_frame_handler_{ + &broadcaster_}; DeviceStatus device_status_; mojo::Remote<mojom::Device> device_; media::VideoCaptureParams device_start_settings_;
diff --git a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json index 92920d4..f8a9720 100644 --- a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json +++ b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json
@@ -16,7 +16,7 @@ "avg": 17.918, "ci_095": 3.238 }, - "runway": { + "runway_2019": { "avg": 28.237, "ci_095": 28.279 },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 969b9c1..f8284f0 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5898,6 +5898,26 @@ ] } ], + "SplitCacheByNetworkIsolationKey": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SplitCacheByNetworkIsolationKey" + ] + } + ] + } + ], "SqlSkipPreload": [ { "platforms": [ @@ -6620,6 +6640,27 @@ ] } ], + "UmaAndUkmDemographics": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows", + "ios" + ], + "experiments": [ + { + "name": "UKM_Enabled", + "enable_features": [ + "DemographicMetricsReporting", + "UkmReportNoisedUserBirthYearAndGender" + ] + } + ] + } + ], "UnifiedAutoplay": [ { "platforms": [
diff --git a/third_party/blink/public/blink_resources.grd b/third_party/blink/public/blink_resources.grd index c503bc46..d2c2a80 100644 --- a/third_party/blink/public/blink_resources.grd +++ b/third_party/blink/public/blink_resources.grd
@@ -25,6 +25,7 @@ <include name="IDR_UASTYLE_THEME_FORCED_COLORS_CSS" file="../renderer/core/html/resources/forced_colors.css" type="BINDATA" compress="gzip"/> <include name="IDR_UASTYLE_SVG_CSS" file="../renderer/core/css/svg.css" type="BINDATA" compress="gzip"/> <include name="IDR_UASTYLE_MATHML_CSS" file="../renderer/core/css/mathml.css" type="BINDATA" compress="gzip"/> + <include name="IDR_UASTYLE_MATHML_FALLBACK_CSS" file="../renderer/core/css/mathml-fallback.css" type="BINDATA" compress="gzip"/> <include name="IDR_UASTYLE_FULLSCREEN_CSS" file="../renderer/core/css/fullscreen.css" type="BINDATA" compress="gzip"/> <include name="IDR_UASTYLE_XHTMLMP_CSS" file="../renderer/core/css/xhtmlmp.css" type="BINDATA" compress="gzip"/> <include name="IDR_UASTYLE_VIEWPORT_ANDROID_CSS" file="../renderer/core/css/viewportAndroid.css" type="BINDATA" compress="gzip"/>
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index da5d918d..a125444 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -6,6 +6,7 @@ import "cc/mojom/touch_action.mojom"; import "mojo/public/mojom/base/string16.mojom"; +import "skia/public/mojom/skcolor.mojom"; import "third_party/blink/public/mojom/devtools/console_message.mojom"; import "third_party/blink/public/mojom/frame/fullscreen.mojom"; import "third_party/blink/public/mojom/frame/lifecycle.mojom"; @@ -74,6 +75,12 @@ // of the viewport, or the need for a layout object changes, e.g. if the // frame owner assigns a display: none style. VisibilityChanged(blink.mojom.FrameVisibility visibility); + + // Notifies the browser that the associated frame has changed theme color. + // This will only be called on main-frames only. |theme_color| is optional + // and indicates if a theme color has been specified or not, e.g. removal + // of a theme color meta tag will generate a null value. + DidChangeThemeColor(skia.mojom.SkColor? theme_color); }; // Implemented in Blink, this interface defines frame-specific methods that will
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 6794708d..e72f8ba 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -471,9 +471,6 @@ // WARNING: This method may be called very frequently. virtual void DidUpdateCurrentHistoryItem() {} - // The frame's theme color has changed. - virtual void DidChangeThemeColor() {} - // Called to report resource timing information for this frame to the parent. // Only used when the parent frame is remote. virtual void ForwardResourceTimingToParent(const WebResourceTimingInfo&) {}
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS index 1558f23..aa6d0214 100644 --- a/third_party/blink/renderer/core/DEPS +++ b/third_party/blink/renderer/core/DEPS
@@ -66,7 +66,7 @@ "+services/network/public/cpp/shared_url_loader_factory.h", "+services/resource_coordinator/public/mojom/coordination_unit.mojom-blink.h", "+services/service_manager/public", - "+skia/public/mojom/bitmap_skbitmap_mojom_traits.h", + "+skia/public/mojom", "+skia/ext/image_operations.h", "+skia/ext/skia_utils_mac.h", "+third_party/blink/public/common",
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.cc b/third_party/blink/renderer/core/css/css_default_style_sheets.cc index 8eb2d6c..49217ef 100644 --- a/third_party/blink/renderer/core/css/css_default_style_sheets.cc +++ b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
@@ -215,8 +215,10 @@ // FIXME: We should assert that the sheet only styles MathML elements. if (element.namespaceURI() == mathml_names::kNamespaceURI && !mathml_style_sheet_) { - mathml_style_sheet_ = - ParseUASheet(UncompressResourceAsASCIIString(IDR_UASTYLE_MATHML_CSS)); + mathml_style_sheet_ = ParseUASheet( + RuntimeEnabledFeatures::MathMLCoreEnabled() + ? UncompressResourceAsASCIIString(IDR_UASTYLE_MATHML_CSS) + : UncompressResourceAsASCIIString(IDR_UASTYLE_MATHML_FALLBACK_CSS)); default_style_->AddRulesFromSheet(MathmlStyleSheet(), ScreenEval()); default_print_style_->AddRulesFromSheet(MathmlStyleSheet(), PrintEval()); changed_default_style = true;
diff --git a/third_party/blink/renderer/core/css/mathml-fallback.css b/third_party/blink/renderer/core/css/mathml-fallback.css new file mode 100644 index 0000000..a9ea84ca --- /dev/null +++ b/third_party/blink/renderer/core/css/mathml-fallback.css
@@ -0,0 +1,49 @@ +/* + * The default style sheet used to render MathML (MathMLCore disabled). + * + * Copyright (C) 2014 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@namespace "http://www.w3.org/1998/Math/MathML"; + +/* By default, we only display the MathML formulas without any formatting other than the one specified by the display attribute. */ +math { + display: inline; +} + +math[display="block"] { + display: block; + text-align: center; +} + +/* We hide the PresentationExpression constructions that are children of a <semantics> element. + http://www.w3.org/TR/MathML/appendixa.html#parsing_PresentationExpression */ +semantics > mi, semantics > mn, semantics > mo, semantics > mtext, semantics > mspace, semantics > ms, semantics > maligngroup, semantics > malignmark, semantics > mrow, semantics > mfrac, semantics > msqrt, semantics > mroot, semantics > mstyle, semantics > merror, semantics > mpadded, semantics > mphantom, semantics > mfenced, semantics > menclose, semantics > msub, semantics > msup, semantics > msubsup, semantics > munder, semantics > mover, semantics > munderover, semantics > mmultiscripts, semantics > mtable, semantics > mstack, semantics > mlongdiv, semantics > maction { + display: none; +} + +/* However, we display all the annotations. */ +annotation, annotation-xml { + display: inline-block; +}
diff --git a/third_party/blink/renderer/core/css/mathml.css b/third_party/blink/renderer/core/css/mathml.css index cef10e3f..1260f32 100644 --- a/third_party/blink/renderer/core/css/mathml.css +++ b/third_party/blink/renderer/core/css/mathml.css
@@ -1,5 +1,5 @@ /* - * The default style sheet used to render MathML. + * The default style sheet used to render MathML (MathMLCore enabled). * * Copyright (C) 2014 Google Inc. All rights reserved. *
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 41ef375..8c4c45d 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
@@ -462,11 +462,6 @@ web_frame_->DidFinish(); } -void LocalFrameClientImpl::DispatchDidChangeThemeColor() { - if (web_frame_->Client()) - web_frame_->Client()->DidChangeThemeColor(); -} - void LocalFrameClientImpl::BeginNavigation( const ResourceRequest& request, network::mojom::RequestContextFrameType frame_type,
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 8ba32f2..77c62f9f 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
@@ -112,7 +112,6 @@ void DispatchDidFinishDocumentLoad() override; void DispatchDidFinishLoad() override; - void DispatchDidChangeThemeColor() override; void BeginNavigation( const ResourceRequest&, network::mojom::RequestContextFrameType,
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 76ea7a0..71b65dc 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -42,6 +42,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "skia/public/mojom/skcolor.mojom-blink.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/context_menu_data/edit_flags.h" @@ -8750,64 +8751,73 @@ frame->PrintEnd(); } -class ThemeColorTestWebFrameClient - : public frame_test_helpers::TestWebFrameClient { +class ThemeColorTestLocalFrameHost : public FakeLocalFrameHost { public: - ThemeColorTestWebFrameClient() : did_notify_(false) {} - ~ThemeColorTestWebFrameClient() override = default; + ThemeColorTestLocalFrameHost() = default; + ~ThemeColorTestLocalFrameHost() override = default; void Reset() { did_notify_ = false; } bool DidNotify() const { return did_notify_; } private: - // frame_test_helpers::TestWebFrameClient: - void DidChangeThemeColor() override { did_notify_ = true; } + // FakeLocalFrameHost: + void DidChangeThemeColor( + const base::Optional<::SkColor>& theme_color) override { + did_notify_ = true; + } - bool did_notify_; + bool did_notify_ = false; }; TEST_F(WebFrameTest, ThemeColor) { RegisterMockedHttpURLLoad("theme_color_test.html"); - ThemeColorTestWebFrameClient client; + ThemeColorTestLocalFrameHost host; + frame_test_helpers::TestWebFrameClient client; + host.Init(client.GetRemoteNavigationAssociatedInterfaces()); frame_test_helpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "theme_color_test.html", &client); - EXPECT_TRUE(client.DidNotify()); + EXPECT_TRUE(host.DidNotify()); WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame(); EXPECT_EQ(Color(0, 0, 255), frame->GetDocument().ThemeColor()); // Change color by rgb. - client.Reset(); + host.Reset(); frame->ExecuteScript( WebScriptSource("document.getElementById('tc1').setAttribute('content', " "'rgb(0, 0, 0)');")); - EXPECT_TRUE(client.DidNotify()); + RunPendingTasks(); + EXPECT_TRUE(host.DidNotify()); EXPECT_EQ(Color::kBlack, frame->GetDocument().ThemeColor()); // Change color by hsl. - client.Reset(); + host.Reset(); frame->ExecuteScript( WebScriptSource("document.getElementById('tc1').setAttribute('content', " "'hsl(240,100%, 50%)');")); - EXPECT_TRUE(client.DidNotify()); + RunPendingTasks(); + EXPECT_TRUE(host.DidNotify()); EXPECT_EQ(Color(0, 0, 255), frame->GetDocument().ThemeColor()); // Change of second theme-color meta tag will not change frame's theme // color. - client.Reset(); + host.Reset(); frame->ExecuteScript(WebScriptSource( "document.getElementById('tc2').setAttribute('content', '#00FF00');")); - EXPECT_TRUE(client.DidNotify()); + RunPendingTasks(); + EXPECT_TRUE(host.DidNotify()); EXPECT_EQ(Color(0, 0, 255), frame->GetDocument().ThemeColor()); // Remove the first theme-color meta tag to apply the second. - client.Reset(); + host.Reset(); frame->ExecuteScript( WebScriptSource("document.getElementById('tc1').remove();")); - EXPECT_TRUE(client.DidNotify()); + RunPendingTasks(); + EXPECT_TRUE(host.DidNotify()); EXPECT_EQ(Color(0, 255, 0), frame->GetDocument().ThemeColor()); // Remove the name attribute of the remaining meta. - client.Reset(); + host.Reset(); frame->ExecuteScript(WebScriptSource( "document.getElementById('tc2').removeAttribute('name');")); - EXPECT_TRUE(client.DidNotify()); + RunPendingTasks(); + EXPECT_TRUE(host.DidNotify()); EXPECT_EQ(base::nullopt, frame->GetDocument().ThemeColor()); }
diff --git a/third_party/blink/renderer/core/frame/hosts_using_features.cc b/third_party/blink/renderer/core/frame/hosts_using_features.cc index 81c07e5..cc91ef2f 100644 --- a/third_party/blink/renderer/core/frame/hosts_using_features.cc +++ b/third_party/blink/renderer/core/frame/hosts_using_features.cc
@@ -129,12 +129,6 @@ } void HostsUsingFeatures::Value::RecordHostToRappor(const String& host) { - if (Get(Feature::kDeviceMotionInsecureHost)) - Platform::Current()->RecordRappor( - "PowerfulFeatureUse.Host.DeviceMotion.Insecure", host); - if (Get(Feature::kDeviceOrientationInsecureHost)) - Platform::Current()->RecordRappor( - "PowerfulFeatureUse.Host.DeviceOrientation.Insecure", host); if (Get(Feature::kFullscreenInsecureHost)) Platform::Current()->RecordRappor( "PowerfulFeatureUse.Host.Fullscreen.Insecure", host);
diff --git a/third_party/blink/renderer/core/frame/hosts_using_features.h b/third_party/blink/renderer/core/frame/hosts_using_features.h index f773348f..ce681b51 100644 --- a/third_party/blink/renderer/core/frame/hosts_using_features.h +++ b/third_party/blink/renderer/core/frame/hosts_using_features.h
@@ -30,8 +30,8 @@ kElementCreateShadowRoot_Unused, kDocumentRegisterElement_Unused, kEventPath_Unused, - kDeviceMotionInsecureHost, - kDeviceOrientationInsecureHost, + kDeviceMotionInsecureHost_Unused, + kDeviceOrientationInsecureHost_Unused, kFullscreenInsecureHost, kGeolocationInsecureHost, kGetUserMediaInsecureHost,
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 3640a0c..ab831fd 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -36,6 +36,7 @@ #include "services/network/public/cpp/features.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "skia/public/mojom/skcolor.mojom-blink.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/frame/blocked_navigation_types.h" @@ -562,6 +563,18 @@ owner_element); } +void LocalFrame::DidChangeThemeColor() { + if (Tree().Parent()) + return; + + base::Optional<Color> color = GetDocument()->ThemeColor(); + base::Optional<SkColor> sk_color; + if (color) + sk_color = color->Rgb(); + + GetLocalFrameHostRemote().DidChangeThemeColor(sk_color); +} + LocalFrame& LocalFrame::LocalFrameRoot() const { const LocalFrame* cur_frame = this; while (cur_frame && IsA<LocalFrame>(cur_frame->Tree().Parent()))
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 75cb56b5..02a1b084 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -154,6 +154,8 @@ ScrollGranularity granularity, Frame* child) override; + void DidChangeThemeColor(); + void DetachChildren(); // After Document is attached, resets state related to document, and sets // context to the current document.
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 41e8871..2f0052e 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -146,7 +146,6 @@ WebHistoryCommitType) = 0; virtual void DispatchDidFinishDocumentLoad() = 0; virtual void DispatchDidFinishLoad() = 0; - virtual void DispatchDidChangeThemeColor() = 0; virtual void BeginNavigation( const ResourceRequest&,
diff --git a/third_party/blink/renderer/core/html/html_meta_element.cc b/third_party/blink/renderer/core/html/html_meta_element.cc index 91bc896..8ceb36a2 100644 --- a/third_party/blink/renderer/core/html/html_meta_element.cc +++ b/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -480,7 +480,7 @@ return; if (EqualIgnoringASCIICase(name_value, "theme-color") && GetDocument().GetFrame()) { - GetDocument().GetFrame()->Client()->DispatchDidChangeThemeColor(); + GetDocument().GetFrame()->DidChangeThemeColor(); } else if (EqualIgnoringASCIICase(name_value, "color-scheme")) { GetDocument().ColorSchemeMetaChanged(); } @@ -557,7 +557,7 @@ if (EqualIgnoringASCIICase(name_value, "theme-color") && GetDocument().GetFrame()) { - GetDocument().GetFrame()->Client()->DispatchDidChangeThemeColor(); + GetDocument().GetFrame()->DidChangeThemeColor(); return; } if (EqualIgnoringASCIICase(name_value, "color-scheme")) {
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc index 4e8e678..f3107a3 100644 --- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc +++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
@@ -76,9 +76,13 @@ void LayoutNGListItem::OrdinalValueChanged() { if (marker_type_ == kOrdinalValue && is_marker_text_updated_) { is_marker_text_updated_ = false; - DCHECK(marker_); - marker_->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( - layout_invalidation_reason::kListValueChange); + + // |marker_| can be a nullptr, for example, in the case of :after list item + // elements. + if (marker_) { + marker_->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( + layout_invalidation_reason::kListValueChange); + } } }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc index 7a1cc31..e568317 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
@@ -223,6 +223,7 @@ space_builder.SetAvailableSize(content_box_size_); space_builder.SetPercentageResolutionSize(child_percentage_size_); + space_builder.SetTextDirection(child_style.Direction()); return space_builder.ToConstraintSpace(); } @@ -534,6 +535,8 @@ /* is_new_fc */ true); SetOrthogonalFallbackInlineSizeIfNeeded(Style(), flex_item.ng_input_node, &space_builder); + space_builder.SetTextDirection( + flex_item.ng_input_node.Style().Direction()); LogicalSize available_size; if (is_column_) { @@ -622,6 +625,7 @@ space_builder.SetIsFixedBlockSizeIndefinite(true); } } + space_builder.SetTextDirection(flex_item.ng_input_node.Style().Direction()); space_builder.SetAvailableSize(available_size); space_builder.SetPercentageResolutionSize(child_percentage_size_); space_builder.SetIsFixedInlineSize(true);
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index 098703b..8c43163 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -285,7 +285,6 @@ WebHistoryCommitType) override {} void DispatchDidFinishDocumentLoad() override {} void DispatchDidFinishLoad() override {} - void DispatchDidChangeThemeColor() override {} void BeginNavigation( const ResourceRequest&,
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc index e3af385..33f415a 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/testing/fake_local_frame_host.h" +#include "skia/public/mojom/skcolor.mojom-blink.h" #include "third_party/blink/public/mojom/frame/fullscreen.mojom-blink.h" namespace blink { @@ -45,6 +46,9 @@ void FakeLocalFrameHost::VisibilityChanged( mojom::blink::FrameVisibility visibility) {} +void FakeLocalFrameHost::DidChangeThemeColor( + const base::Optional<::SkColor>& theme_color) {} + void FakeLocalFrameHost::BindFrameHostReceiver( mojo::ScopedInterfaceEndpointHandle handle) { receiver_.Bind(mojo::PendingAssociatedReceiver<mojom::blink::LocalFrameHost>(
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/third_party/blink/renderer/core/testing/fake_local_frame_host.h index b803afa0..f4aa5ff 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.h +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.h
@@ -37,6 +37,8 @@ void LifecycleStateChanged(mojom::blink::FrameLifecycleState state) override; void EvictFromBackForwardCache() override; void VisibilityChanged(mojom::blink::FrameVisibility visibility) override; + void DidChangeThemeColor( + const base::Optional<::SkColor>& theme_color) override; private: void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl index e50f610..6555d4c 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
@@ -23,6 +23,8 @@ void translate(unrestricted double x, unrestricted double y); void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); + [RaisesException] void setTransform(optional DOMMatrix2DInit transform); + DOMMatrix getTransform(); void resetTransform(); // compositing
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc index 12e78284..de87c33 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -942,7 +942,7 @@ EXPECT_EQ(stats->Timestamp(), 2.0); std::set<webrtc::RTCStatsMemberInterface::Type> members; for (size_t i = 0; i < stats->MembersCount(); ++i) { - std::unique_ptr<blink::WebRTCStatsMember> member = stats->GetMember(i); + std::unique_ptr<RTCStatsMember> member = stats->GetMember(i); // TODO(hbos): A WebRTC-change is adding new members, this would cause // not all members to be defined. This if-statement saves Chromium from // crashing. As soon as the change has been rolled in, I will update @@ -971,7 +971,7 @@ EXPECT_EQ(member->ValueDouble(), 42.0); break; case webrtc::RTCStatsMemberInterface::kString: - EXPECT_EQ(member->ValueString(), blink::WebString::FromUTF8("42")); + EXPECT_EQ(member->ValueString(), "42"); break; case webrtc::RTCStatsMemberInterface::kSequenceBool: ExpectSequenceEquals(member->ValueSequenceBool(), 1); @@ -997,7 +997,7 @@ break; case webrtc::RTCStatsMemberInterface::kSequenceString: ExpectSequenceEquals(member->ValueSequenceString(), - blink::WebString::FromUTF8("42")); + String::FromUTF8("42")); break; default: NOTREACHED();
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc index e985bcd..3efe7eb 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
@@ -31,7 +31,7 @@ }; for (size_t i = 0; i < stats->MembersCount(); ++i) { - std::unique_ptr<WebRTCStatsMember> member = stats->GetMember(i); + std::unique_ptr<RTCStatsMember> member = stats->GetMember(i); if (!member->IsDefined()) continue; WebString name = member->GetName();
diff --git a/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc b/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc index 810e91b..7902b3a0 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc
@@ -31,9 +31,9 @@ Platform::ContextType context_type, bool support_own_offscreen_surface) { Platform::ContextAttributes result; - // Must keep the meaning of the "default" GPU choice in sync with the code - // below, in PowerPreferenceToGpuPreference. - result.prefer_low_power_gpu = attrs.power_preference == "low-power"; + result.prefer_low_power_gpu = + (PowerPreferenceToGpuPreference(attrs.power_preference) == + gl::GpuPreference::kLowPower); result.fail_if_major_performance_caveat = attrs.fail_if_major_performance_caveat; result.context_type = context_type; @@ -49,8 +49,7 @@ } gl::GpuPreference PowerPreferenceToGpuPreference(String power_preference) { - // Must keep the interpretation of the "default" GPU in sync with the code - // above which sets the prefer_low_power_gpu attribute. + // This code determines the handling of the "default" power preference. if (power_preference == "low-power") return gl::GpuPreference::kLowPower; return gl::GpuPreference::kHighPerformance;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index a3420be..84a58f78 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -841,6 +841,7 @@ UpdateNumberOfUserAllocatedMultisampledRenderbuffers(int delta) { DCHECK(delta >= -1 && delta <= 1); number_of_user_allocated_multisampled_renderbuffers_ += delta; + DCHECK_GE(number_of_user_allocated_multisampled_renderbuffers_, 0); } namespace {
diff --git a/third_party/blink/renderer/modules/xr/xr.cc b/third_party/blink/renderer/modules/xr/xr.cc index a29117d..261a0b9b 100644 --- a/third_party/blink/renderer/modules/xr/xr.cc +++ b/third_party/blink/renderer/modules/xr/xr.cc
@@ -1001,15 +1001,8 @@ // immersive sessions must supply display info. DCHECK(session_ptr->display_info); - // If the session supports environment integration, ensure the device does - // as well. - DCHECK(!environment_integration || session_ptr->display_info->capabilities - ->can_provide_environment_integration); DVLOG(2) << __func__ - << ": environment_integration=" << environment_integration - << "can_provide_environment_integration=" - << session_ptr->display_info->capabilities - ->can_provide_environment_integration; + << ": environment_integration=" << environment_integration; // TODO(https://crbug.com/944936): The blend mode could be "additive". XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque;
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc index a4b8313..38c6bc7 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -535,12 +535,11 @@ // Image is written to shared buffer already. Just submit with a // placeholder. scoped_refptr<Image> image_ref = nullptr; - bool needs_copy = false; DVLOG(3) << __FUNCTION__ << ": FrameSubmit for SharedBuffer mode"; - frame_transport_->FrameSubmit( - immersive_presentation_provider_.get(), webgl_context->ContextGL(), - webgl_context, std::move(image_ref), std::move(image_release_callback), - frame_id_, needs_copy); + frame_transport_->FrameSubmit(immersive_presentation_provider_.get(), + webgl_context->ContextGL(), webgl_context, + std::move(image_ref), + std::move(image_release_callback), frame_id_); return; } @@ -557,14 +556,10 @@ return; } - // TODO(bajones): Remove this when the Windows path has been updated to no - // longer require a texture copy. - bool needs_copy = immersive_session_->External(); - - frame_transport_->FrameSubmit( - immersive_presentation_provider_.get(), webgl_context->ContextGL(), - webgl_context, std::move(image_ref), std::move(image_release_callback), - frame_id_, needs_copy); + frame_transport_->FrameSubmit(immersive_presentation_provider_.get(), + webgl_context->ContextGL(), webgl_context, + std::move(image_ref), + std::move(image_release_callback), frame_id_); // Reset our frame id, since anything we'd want to do (resizing/etc) can // no-longer happen to this frame.
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index 8ce7b82..9ad0039 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -1556,7 +1556,6 @@ display_info_id_++; display_info_ = std::move(display_info); - is_external_ = display_info_->capabilities->has_external_display; } WTF::Vector<XRViewData>& XRSession::views() {
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h index 41581e1..c880f85 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.h +++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -233,7 +233,6 @@ const device::mojom::blink::VREyeParametersPtr& right_eye); void UpdateStageParameters( const device::mojom::blink::VRStageParametersPtr& stage_parameters); - bool External() const { return is_external_; } // Incremented every time display_info_ is changed, so that other objects that // depend on it can know when they need to update. unsigned int DisplayInfoPtrId() const { return display_info_id_; } @@ -386,7 +385,6 @@ HeapHashSet<Member<ScriptPromiseResolver>> request_hit_test_source_promises_; HeapVector<Member<XRReferenceSpace>> reference_spaces_; - bool is_external_ = false; unsigned int display_info_id_ = 0; unsigned int stage_parameters_id_ = 0; device::mojom::blink::VRDisplayInfoPtr display_info_;
diff --git a/third_party/blink/renderer/platform/exported/web_rtc_stats.cc b/third_party/blink/renderer/platform/exported/web_rtc_stats.cc index f871cdb..52175634 100644 --- a/third_party/blink/renderer/platform/exported/web_rtc_stats.cc +++ b/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
@@ -6,6 +6,4 @@ namespace blink { -WebRTCStatsMember::~WebRTCStatsMember() = default; - } // namespace blink
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 e599e2e..63b92488 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
@@ -102,16 +102,13 @@ DrawingBuffer::Client* drawing_buffer_client, scoped_refptr<Image> image_ref, std::unique_ptr<viz::SingleReleaseCallback> release_callback, - int16_t vr_frame_id, - bool needs_copy) { + int16_t vr_frame_id) { DCHECK(transport_options_); if (transport_options_->transport_method == device::mojom::blink::XRPresentationTransportMethod:: SUBMIT_AS_TEXTURE_HANDLE) { #if defined(OS_WIN) - // Currently, we assume that this transport needs a copy. - DCHECK(needs_copy); TRACE_EVENT0("gpu", "XRFrameTransport::CopyImage"); // Update last_transfer_succeeded_ value. This should usually complete // without waiting. @@ -152,10 +149,6 @@ } else if (transport_options_->transport_method == device::mojom::blink::XRPresentationTransportMethod:: SUBMIT_AS_MAILBOX_HOLDER) { - // Currently, this transport assumes we don't need to make a separate copy - // of the canvas content. - DCHECK(!needs_copy); - // The AcceleratedStaticBitmapImage must be kept alive until the // mailbox is used via createAndConsumeTextureCHROMIUM, the mailbox // itself does not keep it alive. We must keep a reference to the
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 4bd1027..f0fa052 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
@@ -53,8 +53,7 @@ DrawingBuffer::Client*, scoped_refptr<Image> image_ref, std::unique_ptr<viz::SingleReleaseCallback>, - int16_t vr_frame_id, - bool needs_copy); + int16_t vr_frame_id); void FrameSubmitMissing(device::mojom::blink::XRPresentationProvider*, gpu::gles2::GLES2Interface*,
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index 3d7b47d8a..252a80da 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -1078,6 +1078,21 @@ DCHECK(!static_persistents_.Contains(persistent_node)); } +void ThreadState::RegisterPreFinalizer(void* object, + PreFinalizerCallback callback) { +#if DCHECK_IS_ON() + DCHECK(CheckThread()); +#endif + DCHECK(!SweepForbidden()); + + HeapObjectHeader* header = HeapObjectHeader::FromInnerAddress(object); + DCHECK(ordered_pre_finalizers_.end() == + std::find(ordered_pre_finalizers_.begin(), + ordered_pre_finalizers_.end(), + PreFinalizer{header, object, callback})); + ordered_pre_finalizers_.push_back(PreFinalizer{header, object, callback}); +} + void ThreadState::InvokePreFinalizers() { DCHECK(CheckThread()); DCHECK(!SweepForbidden()); @@ -1085,23 +1100,22 @@ ThreadHeapStatsCollector::Scope stats_scope( Heap().stats_collector(), ThreadHeapStatsCollector::kInvokePreFinalizers); SweepForbiddenScope sweep_forbidden(this); - // Pre finalizers are forbidden from allocating objects + // Pre finalizers are forbidden from allocating objects. NoAllocationScope no_allocation_scope(this); // Call the prefinalizers in the opposite order to their registration. - // - // LinkedHashSet does not support modification during iteration, so - // copy items first. - // - // The prefinalizer callback wrapper returns |true| when its associated - // object is unreachable garbage and the prefinalizer callback has run. - // The registered prefinalizer entry must then be removed and deleted. Deque<PreFinalizer> remaining_ordered_pre_finalizers; for (auto rit = ordered_pre_finalizers_.rbegin(); rit != ordered_pre_finalizers_.rend(); ++rit) { const PreFinalizer& pre_finalizer = *rit; - if (!(pre_finalizer.second)(pre_finalizer.first)) + // Check if pre-finalizer should be executed. + if (pre_finalizer.header->IsMarked()) { + // Re-queue for checking in next garbage collection. remaining_ordered_pre_finalizers.push_front(pre_finalizer); + } else { + // Execute pre-finalizer. + pre_finalizer.callback(pre_finalizer.object); + } } ordered_pre_finalizers_ = std::move(remaining_ordered_pre_finalizers);
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index b443861..88cbe4fb 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -62,6 +62,7 @@ } // namespace incremental_marking_test class CancelableTaskScheduler; +class HeapObjectHeader; class MarkingVisitor; class PersistentNode; class PersistentRegion; @@ -93,17 +94,13 @@ // Member<Bar> bar_; // }; #define USING_PRE_FINALIZER(Class, preFinalizer) \ - public: \ - static bool InvokePreFinalizer(void* object) { \ - Class* self = reinterpret_cast<Class*>(object); \ - if (ThreadHeap::IsHeapObjectAlive(self)) \ - return false; \ - self->Class::preFinalizer(); \ - return true; \ + private: \ + static void PreFinalizerDispatch(void* object) { \ + reinterpret_cast<Class*>(object)->Class::preFinalizer(); \ } \ \ - private: \ - ThreadState::PrefinalizerRegistration<Class> prefinalizer_dummy_{this}; \ + friend class ThreadState::PreFinalizerRegistration<Class>; \ + ThreadState::PreFinalizerRegistration<Class> prefinalizer_dummy_{this}; \ using UsingPreFinalizerMacroNeedsTrailingSemiColon = char class PLATFORM_EXPORT BlinkGCObserver { @@ -133,24 +130,16 @@ // Register the pre-finalizer for the |self| object. The class T be using // USING_PRE_FINALIZER() macro. template <typename T> - class PrefinalizerRegistration final { + class PreFinalizerRegistration final { DISALLOW_NEW(); public: - PrefinalizerRegistration(T* self) { - static_assert(sizeof(&T::InvokePreFinalizer) > 0, + PreFinalizerRegistration(T* self) { + static_assert(sizeof(&T::PreFinalizerDispatch) > 0, "USING_PRE_FINALIZER(T) must be defined."); ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); -#if DCHECK_IS_ON() - DCHECK(state->CheckThread()); -#endif - DCHECK(!state->SweepForbidden()); - DCHECK(std::find(state->ordered_pre_finalizers_.begin(), - state->ordered_pre_finalizers_.end(), - PreFinalizer(self, T::InvokePreFinalizer)) == - state->ordered_pre_finalizers_.end()); - state->ordered_pre_finalizers_.emplace_back(self, T::InvokePreFinalizer); + state->RegisterPreFinalizer(self, T::PreFinalizerDispatch); } }; @@ -385,6 +374,17 @@ private: class IncrementalMarkingScheduler; + using PreFinalizerCallback = void (*)(void*); + struct PreFinalizer { + HeapObjectHeader* header; + void* object; + PreFinalizerCallback callback; + + bool operator==(const PreFinalizer& other) const { + return object == other.object && callback == other.callback; + } + }; + // 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. static constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration = @@ -509,6 +509,7 @@ void SynchronizeAndFinishConcurrentSweeping(); + void RegisterPreFinalizer(void*, PreFinalizerCallback); void InvokePreFinalizers(); // Adds the given observer to the ThreadState's observer list. This doesn't @@ -557,9 +558,6 @@ BlinkGC::GCReason reason_for_scheduled_gc_ = BlinkGC::GCReason::kForcedGCForTesting; - using PreFinalizerCallback = bool (*)(void*); - using PreFinalizer = std::pair<void*, PreFinalizerCallback>; - // Pre-finalizers are called in the reverse order in which they are // registered by the constructors (including constructors of Mixin objects) // for an object, by processing the ordered_pre_finalizers_ back-to-front. @@ -607,7 +605,7 @@ friend class IncrementalMarkingTestDriver; friend class HeapAllocator; template <typename T> - friend class PrefinalizerRegistration; + friend class PreFinalizerRegistration; friend class TestGCScope; friend class ThreadStateSchedulingTest; friend class UnifiedHeapController;
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc index 9619bce..6093874 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
@@ -138,7 +138,7 @@ } std::unique_ptr<RTCStats> RTCStatsReportPlatform::GetStats( - blink::WebString id) const { + const String& id) const { const webrtc::RTCStats* stats = stats_report_->Get(id.Utf8()); if (!stats || !IsWhitelistedStats(*stats)) return std::unique_ptr<RTCStats>(); @@ -175,12 +175,12 @@ RTCStats::~RTCStats() {} -blink::WebString RTCStats::Id() const { - return blink::WebString::FromUTF8(stats_->id()); +String RTCStats::Id() const { + return String::FromUTF8(stats_->id()); } -blink::WebString RTCStats::GetType() const { - return blink::WebString::FromUTF8(stats_->type()); +String RTCStats::GetType() const { + return String::FromUTF8(stats_->type()); } double RTCStats::Timestamp() const { @@ -192,15 +192,9 @@ return stats_members_.size(); } -std::unique_ptr<blink::WebRTCStatsMember> RTCStats::GetMember(size_t i) const { +std::unique_ptr<RTCStatsMember> RTCStats::GetMember(size_t i) const { DCHECK_LT(i, stats_members_.size()); - return CreateRTCStatsMember(stats_owner_, stats_members_[i]); -} - -std::unique_ptr<blink::WebRTCStatsMember> CreateRTCStatsMember( - const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner, - const webrtc::RTCStatsMemberInterface* member) { - return std::make_unique<RTCStatsMember>(std::move(stats_owner), member); + return std::make_unique<RTCStatsMember>(stats_owner_, stats_members_[i]); } RTCStatsMember::RTCStatsMember( @@ -213,8 +207,8 @@ RTCStatsMember::~RTCStatsMember() {} -blink::WebString RTCStatsMember::GetName() const { - return blink::WebString::FromUTF8(member_->name()); +String RTCStatsMember::GetName() const { + return String::FromUTF8(member_->name()); } webrtc::RTCStatsMemberInterface::Type RTCStatsMember::GetType() const { @@ -255,9 +249,9 @@ return *member_->cast_to<webrtc::RTCStatsMember<double>>(); } -blink::WebString RTCStatsMember::ValueString() const { +String RTCStatsMember::ValueString() const { DCHECK(IsDefined()); - return blink::WebString::FromUTF8( + return String::FromUTF8( *member_->cast_to<webrtc::RTCStatsMember<std::string>>()); } @@ -303,13 +297,13 @@ *member_->cast_to<webrtc::RTCStatsMember<std::vector<double>>>()); } -blink::WebVector<blink::WebString> RTCStatsMember::ValueSequenceString() const { +blink::WebVector<String> RTCStatsMember::ValueSequenceString() const { DCHECK(IsDefined()); const std::vector<std::string>& sequence = *member_->cast_to<webrtc::RTCStatsMember<std::vector<std::string>>>(); - blink::WebVector<blink::WebString> web_sequence(sequence.size()); + blink::WebVector<String> web_sequence(sequence.size()); for (size_t i = 0; i < sequence.size(); ++i) - web_sequence[i] = blink::WebString::FromUTF8(sequence[i]); + web_sequence[i] = String::FromUTF8(sequence[i]); return web_sequence; }
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h index 9e3087c4..e518f20 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
@@ -9,6 +9,7 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/web_rtc_stats.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/webrtc/api/stats/rtc_stats.h" #include "third_party/webrtc/api/stats/rtc_stats_collector_callback.h" #include "third_party/webrtc/api/stats/rtc_stats_report.h" @@ -16,6 +17,7 @@ namespace blink { class RTCStats; +class RTCStatsMember; // Wrapper around a webrtc::RTCStatsReport. Filters out any stats objects that // aren't whitelisted. |filter| controls whether to include only standard @@ -26,8 +28,7 @@ // |RTCStatsReport|, from renderer/modules/peerconnection/rtc_stats_report.cc|h. // // TODO(crbug.com/787254): Switch over the classes below from using WebVector -// and WebString to WTF::Vector and WTF::String, when their respective parent -// classes are gone. +// to WTF::Vector, when their respective parent classes are gone. class PLATFORM_EXPORT RTCStatsReportPlatform { public: RTCStatsReportPlatform( @@ -40,7 +41,7 @@ std::unique_ptr<RTCStatsReportPlatform> CopyHandle() const; // Gets stats object by |id|, or null if no stats with that |id| exists. - std::unique_ptr<RTCStats> GetStats(blink::WebString id) const; + std::unique_ptr<RTCStats> GetStats(const String& id) const; // The next stats object, or null if the end has been reached. std::unique_ptr<RTCStats> Next(); @@ -65,12 +66,12 @@ const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids); virtual ~RTCStats(); - blink::WebString Id() const; - blink::WebString GetType() const; + String Id() const; + String GetType() const; double Timestamp() const; size_t MembersCount() const; - std::unique_ptr<blink::WebRTCStatsMember> GetMember(size_t i) const; + std::unique_ptr<RTCStatsMember> GetMember(size_t i) const; private: // Reference to keep the report that owns |stats_| alive. @@ -81,30 +82,30 @@ const std::vector<const webrtc::RTCStatsMemberInterface*> stats_members_; }; -class PLATFORM_EXPORT RTCStatsMember : public blink::WebRTCStatsMember { +class PLATFORM_EXPORT RTCStatsMember { public: RTCStatsMember(const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner, const webrtc::RTCStatsMemberInterface* member); - ~RTCStatsMember() override; + virtual ~RTCStatsMember(); - blink::WebString GetName() const override; - webrtc::RTCStatsMemberInterface::Type GetType() const override; - bool IsDefined() const override; + String GetName() const; + webrtc::RTCStatsMemberInterface::Type GetType() const; + bool IsDefined() const; - bool ValueBool() const override; - int32_t ValueInt32() const override; - uint32_t ValueUint32() const override; - int64_t ValueInt64() const override; - uint64_t ValueUint64() const override; - double ValueDouble() const override; - blink::WebString ValueString() const override; - blink::WebVector<int> ValueSequenceBool() const override; - blink::WebVector<int32_t> ValueSequenceInt32() const override; - blink::WebVector<uint32_t> ValueSequenceUint32() const override; - blink::WebVector<int64_t> ValueSequenceInt64() const override; - blink::WebVector<uint64_t> ValueSequenceUint64() const override; - blink::WebVector<double> ValueSequenceDouble() const override; - blink::WebVector<blink::WebString> ValueSequenceString() const override; + bool ValueBool() const; + int32_t ValueInt32() const; + uint32_t ValueUint32() const; + int64_t ValueInt64() const; + uint64_t ValueUint64() const; + double ValueDouble() const; + String ValueString() const; + blink::WebVector<int> ValueSequenceBool() const; + blink::WebVector<int32_t> ValueSequenceInt32() const; + blink::WebVector<uint32_t> ValueSequenceUint32() const; + blink::WebVector<int64_t> ValueSequenceInt64() const; + blink::WebVector<uint64_t> ValueSequenceUint64() const; + blink::WebVector<double> ValueSequenceDouble() const; + blink::WebVector<String> ValueSequenceString() const; private: // Reference to keep the report that owns |member_|'s stats object alive.
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc index 8e05e2c..12678fb 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
@@ -26,8 +26,8 @@ new webrtc::RTCPeerConnectionStats(whitelisted_id, 42))); RTCStatsReportPlatform report(webrtc_report.get(), {}); - EXPECT_FALSE(report.GetStats(blink::WebString::FromUTF8(not_whitelisted_id))); - EXPECT_TRUE(report.GetStats(blink::WebString::FromUTF8(whitelisted_id))); + EXPECT_FALSE(report.GetStats(not_whitelisted_id)); + EXPECT_TRUE(report.GetStats(whitelisted_id)); } TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_Iteration) {
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc index 55ec5e8..59f7558 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
@@ -154,7 +154,8 @@ GuessVideoCodecProfile(format), media::VideoDecoderConfig::AlphaMode::kIsOpaque, media::VideoColorSpace(), media::kNoTransformation, kDefaultSize, gfx::Rect(kDefaultSize), - kDefaultSize, media::EmptyExtraData(), media::Unencrypted()); + kDefaultSize, media::EmptyExtraData(), + media::EncryptionScheme::kUnencrypted); if (!gpu_factories->IsDecoderConfigSupported(kImplementation, config)) return nullptr;
diff --git a/third_party/blink/tools/blinkpy/common/host.py b/third_party/blink/tools/blinkpy/common/host.py index e624503..604ee03 100644 --- a/third_party/blink/tools/blinkpy/common/host.py +++ b/third_party/blink/tools/blinkpy/common/host.py
@@ -31,7 +31,7 @@ from blinkpy.common.checkout.git import Git from blinkpy.common.net import web -from blinkpy.common.net.buildbot import BuildBot +from blinkpy.common.net.results_fetcher import TestResultsFetcher from blinkpy.common.system.system_host import SystemHost from blinkpy.web_tests.builder_list import BuilderList from blinkpy.web_tests.port.factory import PortFactory @@ -49,7 +49,7 @@ self._git = None # Everything below this line is WebKit-specific and belongs on a higher-level object. - self.buildbot = BuildBot() + self.results_fetcher = TestResultsFetcher() # FIXME: Unfortunately Port objects are currently the central-dispatch objects of the NRWT world. # In order to instantiate a port correctly, we have to pass it at least an executive, user, git, and filesystem
diff --git a/third_party/blink/tools/blinkpy/common/host_mock.py b/third_party/blink/tools/blinkpy/common/host_mock.py index b76978f6..05b23c4 100644 --- a/third_party/blink/tools/blinkpy/common/host_mock.py +++ b/third_party/blink/tools/blinkpy/common/host_mock.py
@@ -27,7 +27,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from blinkpy.common.checkout.git_mock import MockGit -from blinkpy.common.net.buildbot_mock import MockBuildBot +from blinkpy.common.net.results_fetcher_mock import MockTestResultsFetcher from blinkpy.common.net.web_mock import MockWeb from blinkpy.common.path_finder import PathFinder from blinkpy.common.system.system_host_mock import MockSystemHost @@ -59,7 +59,7 @@ self.web = web or MockWeb() self._git = git - self.buildbot = MockBuildBot() + self.results_fetcher = MockTestResultsFetcher() # Note: We're using a real PortFactory here. Tests which don't wish to depend # on the list of known ports should override this with a MockPortFactory.
diff --git a/third_party/blink/tools/blinkpy/common/net/git_cl.py b/third_party/blink/tools/blinkpy/common/net/git_cl.py index 2caf360..23d868e 100644 --- a/third_party/blink/tools/blinkpy/common/net/git_cl.py +++ b/third_party/blink/tools/blinkpy/common/net/git_cl.py
@@ -14,7 +14,7 @@ import re from blinkpy.common.checkout.git import Git -from blinkpy.common.net.buildbot import Build, filter_latest_builds +from blinkpy.common.net.results_fetcher import Build, filter_latest_builds from blinkpy.common.net.luci_auth import LuciAuth
diff --git a/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py b/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py index 06f76d22..bd2a171 100644 --- a/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py +++ b/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py
@@ -5,7 +5,7 @@ import unittest from blinkpy.common.host_mock import MockHost -from blinkpy.common.net.buildbot import Build +from blinkpy.common.net.results_fetcher import Build from blinkpy.common.net.git_cl import CLStatus from blinkpy.common.net.git_cl import GitCL from blinkpy.common.net.git_cl import SEARCHBUILDS_RESPONSE_PREFIX
diff --git a/third_party/blink/tools/blinkpy/common/net/buildbot.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py similarity index 98% rename from third_party/blink/tools/blinkpy/common/net/buildbot.py rename to third_party/blink/tools/blinkpy/common/net/results_fetcher.py index b9fa6cec..d73e5d1ce 100644 --- a/third_party/blink/tools/blinkpy/common/net/buildbot.py +++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
@@ -53,8 +53,8 @@ return super(Build, cls).__new__(cls, builder_name, build_number) -class BuildBot(object): - """This class represents an interface to BuildBot-related functionality. +class TestResultsFetcher(object): + """This class represents an interface to test results for particular builds. This includes fetching web test results from Google Storage; for more information about the web test result format, see:
diff --git a/third_party/blink/tools/blinkpy/common/net/buildbot_mock.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py similarity index 92% rename from third_party/blink/tools/blinkpy/common/net/buildbot_mock.py rename to third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py index 2ca7f49..cf0bbad 100644 --- a/third_party/blink/tools/blinkpy/common/net/buildbot_mock.py +++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py
@@ -26,14 +26,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from blinkpy.common.net.buildbot import BuildBot +from blinkpy.common.net.results_fetcher import TestResultsFetcher + # TODO(qyearsley): To be consistent with other fake ("mock") classes, this -# could be changed so it's not a subclass of BuildBot. -class MockBuildBot(BuildBot): +# could be changed so it's not a subclass of TestResultsFetcher. +class MockTestResultsFetcher(TestResultsFetcher): def __init__(self): - super(MockBuildBot, self).__init__() + super(MockTestResultsFetcher, self).__init__() self._canned_results = {} self._canned_retry_summary_json = {} self._webdriver_results = {}
diff --git a/third_party/blink/tools/blinkpy/common/net/buildbot_unittest.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher_test.py similarity index 80% rename from third_party/blink/tools/blinkpy/common/net/buildbot_unittest.py rename to third_party/blink/tools/blinkpy/common/net/results_fetcher_test.py index deb460a..a706d2d 100644 --- a/third_party/blink/tools/blinkpy/common/net/buildbot_unittest.py +++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher_test.py
@@ -30,7 +30,7 @@ import logging import unittest -from blinkpy.common.net.buildbot import BuildBot, Build, filter_latest_builds +from blinkpy.common.net.results_fetcher import TestResultsFetcher, Build, filter_latest_builds from blinkpy.common.net.web_mock import MockWeb from blinkpy.common.system.log_testing import LoggingTestCase @@ -42,39 +42,39 @@ def test_results_url_no_build_number(self): self.assertEqual( - BuildBot().results_url('Test Builder'), + TestResultsFetcher().results_url('Test Builder'), 'https://test-results.appspot.com/data/layout_results/Test_Builder/results/layout-test-results') def test_results_url_with_build_number(self): self.assertEqual( - BuildBot().results_url('Test Builder', 10), + TestResultsFetcher().results_url('Test Builder', 10), 'https://test-results.appspot.com/data/layout_results/Test_Builder/10/layout-test-results') def test_results_url_with_build_number_step_name(self): self.assertEqual( - BuildBot().results_url('Test Builder', 10, + TestResultsFetcher().results_url('Test Builder', 10, 'webkit_layout_tests (with patch)'), 'https://test-results.appspot.com/data/layout_results/Test_Builder' '/10/webkit_layout_tests%20%28with%20patch%29/layout-test-results') def test_results_url_with_non_numeric_build_number(self): with self.assertRaisesRegexp(AssertionError, 'expected numeric build number'): - BuildBot().results_url('Test Builder', 'ba5eba11') + TestResultsFetcher().results_url('Test Builder', 'ba5eba11') def test_builder_results_url_base(self): self.assertEqual( - BuildBot().builder_results_url_base('WebKit Mac10.8 (dbg)'), + TestResultsFetcher().builder_results_url_base('WebKit Mac10.8 (dbg)'), 'https://test-results.appspot.com/data/layout_results/WebKit_Mac10_8__dbg_') def test_accumulated_results_url(self): self.assertEqual( - BuildBot().accumulated_results_url_base('WebKit Mac10.8 (dbg)'), + TestResultsFetcher().accumulated_results_url_base('WebKit Mac10.8 (dbg)'), 'https://test-results.appspot.com/data/layout_results/WebKit_Mac10_8__dbg_/results/layout-test-results') def test_fetch_web_test_results_with_no_results_fetched(self): - buildbot = BuildBot() - buildbot.web = MockWeb() - results = buildbot.fetch_web_test_results(buildbot.results_url('B')) + fetcher = TestResultsFetcher() + fetcher.web = MockWeb() + results = fetcher.fetch_web_test_results(fetcher.results_url('B')) self.assertIsNone(results) self.assertLog([ 'DEBUG: Got 404 response from:\n' @@ -82,8 +82,8 @@ ]) def test_fetch_results_with_weird_step_name(self): - buildbot = BuildBot() - buildbot.web = MockWeb(urls={ + fetcher = TestResultsFetcher() + fetcher.web = MockWeb(urls={ 'https://test-results.appspot.com/testfile?buildnumber=123&' 'callback=ADD_RESULTS&builder=builder&name=full_results.json': 'ADD_RESULTS(%s);' % (json.dumps( @@ -94,19 +94,19 @@ 'layout-test-results/failing_results.json': json.dumps({'passed': True}), }) - results = buildbot.fetch_results(Build('builder', 123)) + results = fetcher.fetch_results(Build('builder', 123)) self.assertEqual(results._results, { # pylint: disable=protected-access 'passed': True }) self.assertLog([]) def test_fetch_results_without_build_number(self): - buildbot = BuildBot() - self.assertIsNone(buildbot.fetch_results(Build('builder', None))) + fetcher = TestResultsFetcher() + self.assertIsNone(fetcher.fetch_results(Build('builder', None))) def test_get_step_name(self): - buildbot = BuildBot() - buildbot.web = MockWeb(urls={ + fetcher = TestResultsFetcher() + fetcher.web = MockWeb(urls={ 'https://test-results.appspot.com/testfile?buildnumber=5&' 'callback=ADD_RESULTS&builder=foo&name=full_results.json': 'ADD_RESULTS(%s);' % (json.dumps( @@ -115,33 +115,33 @@ {"TestType": "webkit_layout_tests (retry with patch)"}, {"TestType": "base_unittests (with patch)"}])) }) - step_name = buildbot.get_layout_test_step_name(Build('foo', 5)) + step_name = fetcher.get_layout_test_step_name(Build('foo', 5)) self.assertEqual(step_name, 'webkit_layout_tests (with patch)') self.assertLog([]) def test_get_step_name_without_build_number(self): - buildbot = BuildBot() + fetcher = TestResultsFetcher() self.assertIsNone( - buildbot.get_layout_test_step_name(Build('builder', None))) + fetcher.get_layout_test_step_name(Build('builder', None))) def test_fetch_webdriver_results_without_build_number(self): - buildbot = BuildBot() - self.assertIsNone(buildbot.fetch_webdriver_test_results( + fetcher = TestResultsFetcher() + self.assertIsNone(fetcher.fetch_webdriver_test_results( Build('builder', None), 'bar')) self.assertLog( ['DEBUG: Builder name or build number or master is None\n']) def test_fetch_webdriver_results_without_master(self): - buildbot = BuildBot() - self.assertIsNone(buildbot.fetch_webdriver_test_results( + fetcher = TestResultsFetcher() + self.assertIsNone(fetcher.fetch_webdriver_test_results( Build('builder', 1), '')) self.assertLog( ['DEBUG: Builder name or build number or master is None\n']) def test_fetch_webdriver_test_results_with_no_results(self): - buildbot = BuildBot() - buildbot.web = MockWeb() - results = buildbot.fetch_webdriver_test_results( + fetcher = TestResultsFetcher() + fetcher.web = MockWeb() + results = fetcher.fetch_webdriver_test_results( Build('bar-rel', 123), 'foo.chrome') self.assertIsNone(results) self.assertLog([ @@ -152,15 +152,15 @@ ]) def test_fetch_webdriver_results_success(self): - buildbot = BuildBot() - buildbot.web = MockWeb(urls={ + fetcher = TestResultsFetcher() + fetcher.web = MockWeb(urls={ 'https://test-results.appspot.com/testfile?buildnumber=123&' 'master=foo.chrome&builder=bar-rel&' 'testtype=webdriver_tests_suite+%28with+patch%29&' 'name=full_results.json': json.dumps({'passed': True}), }) - results = buildbot.fetch_webdriver_test_results( + results = fetcher.fetch_webdriver_test_results( Build('bar-rel', 123), 'foo.chrome') self.assertEqual(results._results, { # pylint: disable=protected-access 'passed': True @@ -168,7 +168,7 @@ self.assertLog([]) -class BuildBotHelperFunctionTest(unittest.TestCase): +class TestResultsFetcherHelperFunctionTest(unittest.TestCase): def test_filter_latest_jobs_empty(self): self.assertEqual(filter_latest_builds([]), [])
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py index d3b6973..3b57d39 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py +++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py
@@ -34,7 +34,7 @@ from blinkpy.common.path_finder import WEB_TESTS_LAST_COMPONENT from blinkpy.common.memoized import memoized -from blinkpy.common.net.buildbot import Build +from blinkpy.common.net.results_fetcher import Build from blinkpy.tool.commands.command import Command from blinkpy.web_tests.models import test_failures from blinkpy.web_tests.models.test_expectations import TestExpectations @@ -312,7 +312,7 @@ if options.results_directory: args.extend(['--results-directory', options.results_directory]) - step_name = self._tool.buildbot.get_layout_test_step_name(build) + step_name = self._tool.results_fetcher.get_layout_test_step_name(build) if step_name: args.extend(['--step-name', step_name]) @@ -512,7 +512,7 @@ def _result_for_test(self, test, build): # We need full results to know if a test passed or was skipped. # TODO(robertma): Make memoized support kwargs, and use full=True here. - results = self._tool.buildbot.fetch_results(build, True) + results = self._tool.results_fetcher.fetch_results(build, True) if not results: _log.debug('No results found for build %s', build) return None
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py index 595b989eb..5b664cd 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py +++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
@@ -218,7 +218,7 @@ Returns: A dict mapping Build to WebTestResults for all completed jobs. """ - buildbot = self._tool.buildbot + results_fetcher = self._tool.results_fetcher results = {} for build, status in jobs.iteritems(): if status == TryJobStatus('COMPLETED', 'SUCCESS'): @@ -230,8 +230,8 @@ # Only completed failed builds will contain actual failed # web tests to download baselines for. continue - results_url = buildbot.results_url(build.builder_name, build.build_number) - web_test_results = buildbot.fetch_results(build) + results_url = results_fetcher.results_url(build.builder_name, build.build_number) + web_test_results = results_fetcher.fetch_results(build) if web_test_results is None: _log.info('Failed to fetch results for "%s".', build.builder_name) _log.info('Results URL: %s/results.html', results_url) @@ -345,8 +345,8 @@ If the list of new failures could not be obtained, this returns None. """ - buildbot = self._tool.buildbot - content = buildbot.fetch_retry_summary_json(build) + results_fetcher = self._tool.results_fetcher + content = results_fetcher.fetch_retry_summary_json(build) if content is None: return None try:
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py index 78ddd92..b5865320 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py +++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py
@@ -7,9 +7,9 @@ import textwrap from blinkpy.common.checkout.git_mock import MockGit -from blinkpy.common.net.buildbot import Build from blinkpy.common.net.git_cl import TryJobStatus from blinkpy.common.net.git_cl_mock import MockGitCL +from blinkpy.common.net.results_fetcher import Build from blinkpy.common.net.web_test_results import WebTestResults from blinkpy.common.path_finder import RELATIVE_WEB_TESTS from blinkpy.common.system.log_testing import LoggingTestCase @@ -95,8 +95,8 @@ }) for build in builds: - self.tool.buildbot.set_results(build, web_test_results) - self.tool.buildbot.set_retry_sumary_json(build, json.dumps({ + self.tool.results_fetcher.set_results(build, web_test_results) + self.tool.results_fetcher.set_retry_sumary_json(build, json.dumps({ 'failures': [ 'one/flaky-fail.html', 'one/missing.html', @@ -344,7 +344,7 @@ Build('MOCK Try Linux', 6000): TryJobStatus('COMPLETED', 'FAILURE'), } for build in builds: - self.tool.buildbot.set_retry_sumary_json(build, json.dumps({ + self.tool.results_fetcher.set_retry_sumary_json(build, json.dumps({ 'failures': ['one/text-fail.html'], 'ignored': ['two/image-fail.html'], })) @@ -358,7 +358,7 @@ def test_execute_with_no_retry_summary_downloaded(self): # In this example, the retry summary could not be downloaded, so # a warning is printed and all tests are rebaselined. - self.tool.buildbot.set_retry_sumary_json( + self.tool.results_fetcher.set_retry_sumary_json( Build('MOCK Try Win', 5000), None) exit_code = self.command.execute(self.command_options(), [], self.tool) self.assertEqual(exit_code, 0) @@ -427,7 +427,7 @@ ]) def test_execute_missing_results_with_no_fill_missing_prompts(self): - self.tool.buildbot.set_results(Build('MOCK Try Win', 5000), None) + self.tool.results_fetcher.set_results(Build('MOCK Try Win', 5000), None) exit_code = self.command.execute(self.command_options(), [], self.tool) self.assertEqual(exit_code, 1) self.assertLog([ @@ -442,7 +442,7 @@ ]) def test_execute_missing_results_with_fill_missing_continues(self): - self.tool.buildbot.set_results(Build('MOCK Try Win', 5000), None) + self.tool.results_fetcher.set_results(Build('MOCK Try Win', 5000), None) exit_code = self.command.execute( self.command_options(fill_missing=True), ['one/flaky-fail.html'], self.tool)
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py index 55821b3..88f884b 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py +++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py
@@ -35,7 +35,7 @@ if options.results_directory: results_url = 'file://' + options.results_directory else: - results_url = self._tool.buildbot.results_url( + results_url = self._tool.results_fetcher.results_url( options.builder, build_number=options.build_number, step_name=options.step_name)
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py index 4afc49d4..88ad5a4f 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py +++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py
@@ -6,7 +6,7 @@ import optparse import unittest -from blinkpy.common.net.buildbot import Build +from blinkpy.common.net.results_fetcher import Build from blinkpy.common.net.web_test_results import WebTestResults from blinkpy.common.path_finder import RELATIVE_WEB_TESTS from blinkpy.common.system.executive_mock import MockExecutive @@ -89,7 +89,7 @@ def _setup_mock_build_data(self): for builder in ['MOCK Win7', 'MOCK Win7 (dbg)', 'MOCK Mac10.11']: - self.tool.buildbot.set_results(Build(builder), WebTestResults({ + self.tool.results_fetcher.set_results(Build(builder), WebTestResults({ 'tests': { 'userscripts': { 'first-test.html': { @@ -190,7 +190,7 @@ }, **kwargs)) def test_rebaseline_test_passes_on_all_builders(self): - self.tool.buildbot.set_results(Build('MOCK Win7'), WebTestResults({ + self.tool.results_fetcher.set_results(Build('MOCK Win7'), WebTestResults({ 'tests': { 'userscripts': { 'first-test.html': { @@ -482,7 +482,7 @@ ('Bug(x) [ Mac ] userscripts/skipped-test.html [ WontFix ]\n' 'Bug(y) [ Win ] userscripts/skipped-test.html [ Skip ]\n')) self._write('userscripts/skipped-test.html', 'Dummy test contents') - self.tool.buildbot.set_results(Build('MOCK Mac10.11'), WebTestResults({ + self.tool.results_fetcher.set_results(Build('MOCK Mac10.11'), WebTestResults({ 'tests': { 'userscripts': { 'skipped-test.html': { @@ -492,7 +492,7 @@ } } })) - self.tool.buildbot.set_results(Build('MOCK Win7'), WebTestResults({ + self.tool.results_fetcher.set_results(Build('MOCK Win7'), WebTestResults({ 'tests': { 'userscripts': { 'skipped-test.html': { @@ -519,7 +519,7 @@ # Flaky expectations should be kept even if the test passes. self._write(self.test_expectations_path, 'Bug(x) userscripts/flaky-test.html [ Pass Failure ]\n') self._write('userscripts/flaky-test.html', 'Dummy test contents') - self.tool.buildbot.set_results(Build('MOCK Mac10.11'), WebTestResults({ + self.tool.results_fetcher.set_results(Build('MOCK Mac10.11'), WebTestResults({ 'tests': { 'userscripts': { 'flaky-test.html': { @@ -545,7 +545,7 @@ self._write(self.test_expectations_path, 'Bug(foo) userscripts/all-pass.html [ Failure ]\n') self._write('userscripts/all-pass.html', 'Dummy test contents') test_baseline_set = TestBaselineSet(self.tool) - self.tool.buildbot.set_results(Build('MOCK Mac10.11'), WebTestResults({ + self.tool.results_fetcher.set_results(Build('MOCK Mac10.11'), WebTestResults({ 'tests': { 'userscripts': { 'all-pass.html': { @@ -572,7 +572,7 @@ self._write('userscripts/all-pass.html', 'Dummy test contents') test_baseline_set = TestBaselineSet(self.tool) for builder in ['MOCK Win7', 'MOCK Win10', 'MOCK Mac10.10', 'MOCK Mac10.11', 'MOCK Precise', 'MOCK Trusty']: - self.tool.buildbot.set_results(Build(builder), WebTestResults({ + self.tool.results_fetcher.set_results(Build(builder), WebTestResults({ 'tests': { 'userscripts': { 'all-pass.html': { @@ -599,7 +599,7 @@ self._write(self.test_expectations_path, 'Bug(foo) userscripts/all-pass.html [ Failure ]\n') self._write('userscripts/all-pass.html', 'Dummy test contents') test_baseline_set = TestBaselineSet(self.tool) - self.tool.buildbot.set_results(Build('MOCK Mac10.11'), WebTestResults({ + self.tool.results_fetcher.set_results(Build('MOCK Mac10.11'), WebTestResults({ 'tests': { 'userscripts': { 'all-pass.html': {
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py index ef9bd83..60d218a 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -17,9 +17,9 @@ import logging import re -from blinkpy.common.net.buildbot import current_build_link from blinkpy.common.net.git_cl import GitCL from blinkpy.common.net.network_transaction import NetworkTimeout +from blinkpy.common.net.results_fetcher import current_build_link from blinkpy.common.path_finder import PathFinder from blinkpy.common.system.executive import ScriptError from blinkpy.common.system.log_utils import configure_logging
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py index e3d78bd..19d8ba2d 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -7,11 +7,11 @@ from blinkpy.common.checkout.git_mock import MockGit from blinkpy.common.host_mock import MockHost -from blinkpy.common.net.buildbot import Build from blinkpy.common.net.git_cl import CLStatus from blinkpy.common.net.git_cl import TryJobStatus from blinkpy.common.net.git_cl_mock import MockGitCL from blinkpy.common.net.network_transaction import NetworkTimeout +from blinkpy.common.net.results_fetcher import Build from blinkpy.common.path_finder import RELATIVE_WEB_TESTS from blinkpy.common.system.executive_mock import MockCall from blinkpy.common.system.executive_mock import MockExecutive
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py index ca00808..edde8b43 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
@@ -131,14 +131,14 @@ # All tests passed, so there should be no failing results. return {} - test_result_list = [self.host.buildbot.fetch_results(build)] + test_result_list = [self.host.results_fetcher.fetch_results(build)] has_webdriver_tests = self.host.builders.has_webdriver_tests_for_builder( build.builder_name) if has_webdriver_tests: master = self.host.builders.master_for_builder( build.builder_name) test_result_list.append( - self.host.buildbot.fetch_webdriver_test_results(build, master)) + self.host.results_fetcher.fetch_webdriver_test_results(build, master)) test_result_list = filter(None, test_result_list) if not test_result_list:
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py index 3bf488c..5f7c6724 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
@@ -6,10 +6,10 @@ import json from blinkpy.common.host_mock import MockHost -from blinkpy.common.net.buildbot import Build -from blinkpy.common.net.buildbot_mock import MockBuildBot from blinkpy.common.net.git_cl import TryJobStatus from blinkpy.common.net.git_cl_mock import MockGitCL +from blinkpy.common.net.results_fetcher import Build +from blinkpy.common.net.results_fetcher_mock import MockTestResultsFetcher from blinkpy.common.net.web_test_results import WebTestResult, WebTestResults from blinkpy.common.system.executive import ScriptError from blinkpy.common.system.log_testing import LoggingTestCase @@ -107,7 +107,7 @@ # results are for the other builders since we shouldn't need to even # fetch results, since the try job status already tells us that all # of the tests passed. - host.buildbot.set_results( + host.results_fetcher.set_results( Build('MOCK Try Mac10.10', 333), WebTestResults({ 'tests': { @@ -127,7 +127,7 @@ self.assertEqual(0, updater.run(args=[])) # Results are only fetched for failing builds. - self.assertEqual(host.buildbot.fetched_builds, [Build('MOCK Try Mac10.10', 333)]) + self.assertEqual(host.results_fetcher.fetched_builds, [Build('MOCK Try Mac10.10', 333)]) self.assertEqual( host.filesystem.read_text_file(expectations_path), @@ -136,7 +136,7 @@ def test_get_failing_results_dict_only_passing_results(self): host = self.mock_host() - host.buildbot.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ + host.results_fetcher.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ 'tests': { 'external': { 'wpt': { @@ -156,7 +156,7 @@ def test_get_failing_results_dict_unexpected_pass(self): host = self.mock_host() - host.buildbot.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ + host.results_fetcher.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ 'tests': { 'external': { 'wpt': { @@ -177,15 +177,15 @@ def test_get_failing_results_dict_no_results(self): host = self.mock_host() - host.buildbot = MockBuildBot() - host.buildbot.set_results(Build('MOCK Try Mac10.10', 123), None) + host.results_fetcher = MockTestResultsFetcher() + host.results_fetcher.set_results(Build('MOCK Try Mac10.10', 123), None) updater = WPTExpectationsUpdater(host) self.assertEqual( updater.get_failing_results_dict(Build('MOCK Try Mac10.10', 123)), {}) def test_get_failing_results_dict_some_failing_results(self): host = self.mock_host() - host.buildbot.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ + host.results_fetcher.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ 'tests': { 'external': { 'wpt': { @@ -216,7 +216,7 @@ def test_get_failing_results_dict_non_wpt_test(self): host = self.mock_host() - host.buildbot.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ + host.results_fetcher.set_results(Build('MOCK Try Mac10.10', 123), WebTestResults({ 'tests': { 'x': { 'failing-test.html': { @@ -233,7 +233,7 @@ def test_get_failing_results_dict_webdriver_failing_results_(self): host = self.mock_host() - host.buildbot.set_results(Build('MOCK Try Trusty', 123), WebTestResults({ + host.results_fetcher.set_results(Build('MOCK Try Trusty', 123), WebTestResults({ 'tests': { 'external': { 'wpt': { @@ -249,7 +249,7 @@ }, })) - host.buildbot.set_webdriver_test_results(Build('MOCK Try Trusty', 123), "tryserver.blink", WebTestResults({ + host.results_fetcher.set_webdriver_test_results(Build('MOCK Try Trusty', 123), "tryserver.blink", WebTestResults({ 'tests': { 'external': { 'wpt': {
diff --git a/third_party/blink/tools/blinkpy/web_tests/builder_list.py b/third_party/blink/tools/blinkpy/web_tests/builder_list.py index b4aa967..7826ad2 100644 --- a/third_party/blink/tools/blinkpy/web_tests/builder_list.py +++ b/third_party/blink/tools/blinkpy/web_tests/builder_list.py
@@ -48,14 +48,14 @@ Valid values for the version specifier can be found in TestExpectationsParser._configuration_tokens_list, and valid values for the build type specifier include "Release" and "Debug". - "is_try_builder": Whether the builder is a try bot. + "is_try_builder": Whether the builder is a trybot. "master": The master name of the builder. It is deprecated, but still required by test-results.appspot.com API." "has_webdriver_tests": Whether webdriver_tests_suite runs on this builder. Possible refactoring note: Potentially, it might make sense to use - blinkpy.common.buildbot.Builder and add port_name and specifiers - properties to that class. + blinkpy.common.net.results_fetcher.Builder and add port_name and + specifiers properties to that class. """ self._builders = builders_dict for builder in builders_dict:
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py index 8879f61f..dafaf0a 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -33,6 +33,7 @@ """ import collections +import itertools import json import logging import optparse @@ -809,9 +810,10 @@ tests.extend(self._wpt_test_urls_matching_paths(paths)) else: tests.extend(self._all_virtual_tests()) - tests.extend([wpt_path + self.TEST_PATH_SEPARATOR + test for wpt_path in self.WPT_DIRS + # '/' is used instead of filesystem.sep as the WPT manifest always + # uses '/' for paths (it is not OS dependent). + tests.extend([wpt_path + '/' + test for wpt_path in self.WPT_DIRS for test in self.wpt_manifest(wpt_path).all_urls()]) - return tests def real_tests(self, paths): @@ -1665,9 +1667,33 @@ def _all_virtual_tests(self): tests = [] + + # The set of paths to find tests for each virtual test suite. + suite_paths = [] + # For each path, a map functor that converts the test path to be under + # the virtual test suite. + suite_prefixes = [] for suite in self.virtual_test_suites(): - self._populate_virtual_suite(suite) - tests.extend(suite.tests.keys()) + for b in suite.bases: + suite_paths.append(b) + suite_prefixes.append(suite.full_prefix) + + # TODO(crbug.com/982208): If we can pass in the set of paths and + # maps then this could be more efficient. + if suite.bases: + tests.extend(map(lambda x : suite.full_prefix + x, self.real_tests(suite.bases))) + + if suite_paths: + tests.extend(self._wpt_test_urls_matching_paths(suite_paths, suite_prefixes)) + return tests + + def _all_virtual_tests_for_suite(self, suite): + if not suite.bases: + return [] + tests = [] + tests.extend(map(lambda x : suite.full_prefix + x, self.real_tests(suite.bases))) + tests.extend(self._wpt_test_urls_matching_paths(suite.bases, + [suite.full_prefix] * len(suite.bases))) return tests def _virtual_tests_matching_paths(self, paths): @@ -1676,8 +1702,7 @@ for suite in self.virtual_test_suites(): if not any(p.startswith(suite.full_prefix) for p in normalized_paths): continue - self._populate_virtual_suite(suite) - for test in suite.tests: + for test in self._all_virtual_tests_for_suite(suite): if any(test.startswith(p) for p in normalized_paths): tests.append(test) @@ -1689,58 +1714,89 @@ def _path_has_wildcard(self, path): return '*' in path - def _wpt_test_urls_matching_paths(self, paths): - # This is to make sure "external[\\/]?" can also match to external/wpt. - # TODO(robertma): Remove this special case when external/wpt is moved to wpt. - paths = [self._filesystem.join(path, 'wpt') if path.rstrip('\\/').endswith('external') - else path for path in paths] - # '/' is used throughout this function instead of filesystem.sep as the WPT manifest always - # uses '/' for paths (it is not OS dependent). - if self._filesystem.sep != '/': - paths = [path.replace(self._filesystem.sep, '/') for path in paths] + def _wpt_test_urls_matching_paths(self, filter_paths, virtual_prefixes=[]): + """Returns a set of paths that are tests to be run from the + web-platform-test manifest files. + + filter_paths: A list of strings that are prefix matched against the + list of tests in the WPT manifests. Only tests that match are returned. + virtual_prefixes: A list of prefixes corresponding to paths in |filter_paths|. + If present, each test path output should have its virtual prefix + prepended to the resulting path to the test. + """ + # Generate the manifest files if needed and then read them. Do this once + # for this whole method as the file is large and generation/loading is + # slow. + wpts = [(wpt_path, self.wpt_manifest(wpt_path)) for wpt_path in self.WPT_DIRS] + + _log.debug("Finding WPT tests that match %d path prefixes", len(filter_paths)); tests = [] - for wpt_path in self.WPT_DIRS: - tests += self._wpt_test_urls(wpt_path, paths) - return tests + # This walks through the set of paths where we should look for tests. + # For each path, a map can be provided that we replace 'path' with in + # the result. + for filter_path, virtual_prefix in itertools.izip_longest(filter_paths, virtual_prefixes): + # This is to make sure "external[\\/]?" can also match to + # external/wpt. + # TODO(robertma): Remove this special case when external/wpt is + # moved to wpt. + if filter_path.rstrip('\\/').endswith('external'): + filter_path = self._filesystem.join(filter_path, 'wpt') + # '/' is used throughout this function instead of filesystem.sep as + # the WPT manifest always uses '/' for paths (it is not OS + # dependent). + if self._filesystem.sep != '/': + filter_path = filter_path.replace(self._filesystem.sep, '/') - def _wpt_test_urls(self, wpt_path, paths): - tests = [] - for test_url_path in self.wpt_manifest(wpt_path).all_urls(): - assert not test_url_path.startswith('/') - full_test_url_path = wpt_path + '/' + test_url_path + # Drop empty path components. + filter_path = filter_path.replace('//', '/') - for path in paths: - if not path.startswith(wpt_path): + # We now have in |filter_path| a path to an actual test directory or file + # on disk, in unix format, relative to the root of the web_tests + # directory. + + for wpt_path, wpt_manifest in wpts: + # If the |filter_path| is not inside a WPT dir, then we will + # match no tests in the manifest. + if not filter_path.startswith(wpt_path): continue + # Drop the WPT prefix (including the joining '/') from |path|. + filter_path_from_wpt = filter_path[len(wpt_path) + 1:] - # Also remove the slash after wpt_path, if any. - path_in_wpt = path[len(wpt_path) + 1:] + # An empty filter matches everything. + if filter_path_from_wpt: + # If the filter is to a specific test file that ends with .js, + # we match that against tests with any extension by dropping + # the extension from the filter. + # + # Else, when matching a directory, ensure the filter ends in '/' + # to only match the exact directory name and not directories + # with the filter as a prefix. + if wpt_manifest.is_test_file(filter_path_from_wpt): + filter_path_from_wpt = re.sub(r'\.js$', '.', filter_path_from_wpt) + elif not wpt_manifest.is_test_url(filter_path_from_wpt): + filter_path_from_wpt = filter_path_from_wpt.rstrip('/') + '/' - # When `test_url_path` is test.any.html etc., and `path_in_wpt` is test.any.js: - matches_any_js_test = ( - self.wpt_manifest(wpt_path).is_test_file(path_in_wpt) - and test_url_path.startswith(re.sub(r'\.js$', '', path_in_wpt)) - ) + # We now have a path to an actual test directory or file on + # disk, in unix format, relative to the WPT directory. + # + # Look for all tests in the manifest that are under the relative + # |filter_path_from_wpt|. + for test_path_from_wpt in wpt_manifest.all_urls(): + assert not test_path_from_wpt.startswith('/') + assert not test_path_from_wpt.endswith('/') - # For all other path matches within WPT: - # Get a list of directories for both paths, filter empty strings. - full_test_url_directories = filter(None, full_test_url_path.split('/')) - path_directories = filter(None, path.split('/')) - test_is_in_path = path_directories == full_test_url_directories[0:len(path_directories)] + # Drop empty path components. + test_path_from_wpt = test_path_from_wpt.replace('//', '/') - if matches_any_js_test or test_is_in_path: - tests.append(full_test_url_path) + if test_path_from_wpt.startswith(filter_path_from_wpt): + # The result is a test path from the root web test + # directory. If a |virtual_prefix| was given, we prepend + # that to the result. + prefix = virtual_prefix if virtual_prefix else '' + tests.append(prefix + wpt_path + '/' + test_path_from_wpt) return tests - def _populate_virtual_suite(self, suite): - if not suite.tests: - base_tests = self.real_tests(suite.bases) if suite.bases else [] - base_tests.extend(self._wpt_test_urls_matching_paths(suite.bases)) - suite.tests = {} - for test in base_tests: - suite.tests[suite.full_prefix + test] = test - def _lookup_virtual_suite(self, test_name): for suite in self.virtual_test_suites(): if test_name.startswith(suite.full_prefix): @@ -1870,7 +1926,6 @@ self.full_prefix = 'virtual/' + prefix + '/' self.bases = bases self.args = args - self.tests = {} def __repr__(self): return "VirtualTestSuite('%s', %s, %s)" % (self.full_prefix, self.bases, self.args)
diff --git a/third_party/blink/tools/blinkpy/web_tests/try_flag.py b/third_party/blink/tools/blinkpy/web_tests/try_flag.py index 0060996b..ac00830 100644 --- a/third_party/blink/tools/blinkpy/web_tests/try_flag.py +++ b/third_party/blink/tools/blinkpy/web_tests/try_flag.py
@@ -118,12 +118,12 @@ self._host.print_('Fetching results...') # TODO: Get jobs from the _tryflag branch. Current branch for now. jobs = self._git_cl.latest_try_jobs(builder_names=BUILDER_CONFIGS.keys()) - buildbot = self._host.buildbot + results_fetcher = self._host.results_fetcher for build in sorted(jobs): self._host.print_('-- %s: %s/results.html' % ( BUILDER_CONFIGS[build.builder_name].version, - buildbot.results_url(build.builder_name, build.build_number))) - results = buildbot.fetch_results(build, True) + results_fetcher.results_url(build.builder_name, build.build_number))) + results = results_fetcher.fetch_results(build, True) results.for_each_test( lambda result, b=build: self._process_result(b, result))
diff --git a/third_party/blink/tools/blinkpy/web_tests/try_flag_unittest.py b/third_party/blink/tools/blinkpy/web_tests/try_flag_unittest.py index 62e53fe..3a810ab 100644 --- a/third_party/blink/tools/blinkpy/web_tests/try_flag_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/try_flag_unittest.py
@@ -5,9 +5,9 @@ import unittest from blinkpy.common.host_mock import MockHost -from blinkpy.common.net.buildbot import Build from blinkpy.common.net.git_cl import TryJobStatus from blinkpy.common.net.git_cl_mock import MockGitCL +from blinkpy.common.net.results_fetcher import Build from blinkpy.common.net.web_test_results import WebTestResults from blinkpy.common.path_finder import PathFinder from blinkpy.web_tests.try_flag import TryFlag @@ -68,8 +68,8 @@ self._run_trigger_test(regenerate=False) self._run_trigger_test(regenerate=True) - def _setup_mock_results(self, buildbot): - buildbot.set_results(self.linux_build, WebTestResults({ + def _setup_mock_results(self, results_fetcher): + results_fetcher.set_results(self.linux_build, WebTestResults({ 'tests': { 'something': { 'fail-everywhere.html': { @@ -85,7 +85,7 @@ } } })) - buildbot.set_results(self.win_build, WebTestResults({ + results_fetcher.set_results(self.win_build, WebTestResults({ 'tests': { 'something': { 'fail-everywhere.html': { @@ -101,7 +101,7 @@ } } })) - buildbot.set_results(self.mac_build, WebTestResults({ + results_fetcher.set_results(self.mac_build, WebTestResults({ 'tests': { 'something': { 'pass-unexpectedly-mac.html': { @@ -129,7 +129,7 @@ flag_expectations_file, 'something/pass-unexpectedly-mac.html [ Fail ]') - self._setup_mock_results(host.buildbot) + self._setup_mock_results(host.results_fetcher) cmd = ['update', '--flag=--foo'] TryFlag(cmd, host, MockGitCL(host, self.mock_try_results)).run() @@ -163,7 +163,7 @@ finder = PathFinder(filesystem) flag_expectations_file = finder.path_from_web_tests( 'FlagExpectations', 'foo') - self._setup_mock_results(host.buildbot) + self._setup_mock_results(host.results_fetcher) cmd = ['update', '--flag=--foo'] # Unexpected passes that don't have flag-specific failure expectations
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index e7f620bb..b1a92b1 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1387,11 +1387,9 @@ crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/auto-height-column-with-border-and-padding.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-align-vertical-writing-mode.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-align.html [ Failure ] -crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-flow-2.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-flow-border.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-flow-margins-auto-size.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-flow-padding.html [ Failure ] -crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-flow.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flex-order.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flexbox-baseline-margins.html [ Failure ] crbug.com/591099 virtual/layout_ng_flex_box/css3/flexbox/flexbox-baseline.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/2dcontext/transformations/2d.transformation.getTransform.html b/third_party/blink/web_tests/external/wpt/2dcontext/transformations/2d.transformation.getTransform.html new file mode 100644 index 0000000..664efd5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/2dcontext/transformations/2d.transformation.getTransform.html
@@ -0,0 +1,39 @@ +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +// Ensure that context2d.getTransform works +const epsilon = 1e-5; +const canvas = document.createElement('canvas'); +const ctx = canvas.getContext('2d'); + +test(function(t) { + assert_array_equals(ctx.getTransform().toFloat32Array(), + [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], + "Assert that an untransformed matrix is identity"); + + ctx.scale(2, 3); + transform = ctx.getTransform(); + assert_array_equals(ctx.getTransform().toFloat32Array(), + [2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], + "Assert that context2d scaling works"); + + ctx.rotate(Math.PI/2); + transform = ctx.getTransform(); + assert_array_approx_equals(ctx.getTransform().toFloat32Array(), + [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], epsilon, + "Assert that context2d rotate works"); + + ctx.translate(1, -1); + transform = ctx.getTransform(); + assert_array_approx_equals(ctx.getTransform().toFloat32Array(), + [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 1], epsilon, + "Assert context2d translate works."); + + ctx.resetTransform(); + assert_array_equals(ctx.getTransform().toFloat32Array(), + [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], + "Assert that a reset matrix is identity"); +}, 'This test ensures that getTransform works correctly.'); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idbindex_reverse_cursor.any.js b/third_party/blink/web_tests/external/wpt/IndexedDB/idbindex_reverse_cursor.any.js new file mode 100644 index 0000000..0b3c767f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idbindex_reverse_cursor.any.js
@@ -0,0 +1,60 @@ +// META: title=Reverse Cursor Validity +// META: script=support-promises.js + +async function iterateAndReturnAllCursorResult(testCase, cursor) { + return new Promise((resolve, reject) => { + let results = []; + cursor.onsuccess = testCase.step_func(function(e) { + let cursor = e.target.result; + if (!cursor) { + resolve(results); + return; + } + results.push(cursor.value); + cursor.continue(); + }); + cursor.onerror = reject; + }); +} + +promise_test(async testCase => { + const db = await createDatabase(testCase, db => { + db.createObjectStore('objectStore', {keyPath: 'key'}) + .createIndex('index', 'indexedOn'); + }); + const txn1 = db.transaction(['objectStore'], 'readwrite'); + txn1.objectStore('objectStore').add({'key': 'firstItem', 'indexedOn': 3}); + const txn2 = db.transaction(['objectStore'], 'readwrite'); + txn2.objectStore('objectStore').put({'key': 'firstItem', 'indexedOn': -1}); + const txn3= db.transaction(['objectStore'], 'readwrite'); + txn3.objectStore('objectStore').add({'key': 'secondItem', 'indexedOn': 2}); + + const txn4 = db.transaction(['objectStore'], 'readonly'); + cursor = txn4.objectStore('objectStore').index('index').openCursor(IDBKeyRange.bound(0, 10), "prev"); + let results = await iterateAndReturnAllCursorResult(testCase, cursor); + + assert_equals(results.length, 1); + + await promiseForTransaction(testCase, txn4); + db.close(); +}, 'Reverse cursor sees update from separate transactions.'); + +promise_test(async testCase => { + const db = await createDatabase(testCase, db => { + db.createObjectStore('objectStore', {keyPath: 'key'}) + .createIndex('index', 'indexedOn'); + }); + const txn = db.transaction(['objectStore'], 'readwrite'); + txn.objectStore('objectStore').add({'key': '1', 'indexedOn': 2}); + txn.objectStore('objectStore').put({'key': '1', 'indexedOn': -1}); + txn.objectStore('objectStore').add({'key': '2', 'indexedOn': 1}); + + const txn2 = db.transaction(['objectStore'], 'readonly'); + cursor = txn2.objectStore('objectStore').index('index').openCursor(IDBKeyRange.bound(0, 10), "prev"); + let results = await iterateAndReturnAllCursorResult(testCase, cursor); + + assert_equals(1, results.length); + + await promiseForTransaction(testCase, txn2); + db.close(); +}, 'Reverse cursor sees in-transaction update.');
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/ol-change-display-type-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/ol-change-display-type-ref.html new file mode 100644 index 0000000..a10bc17 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/ol-change-display-type-ref.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel=help href="https://crbug.com/1020669"> +<style> + .item { + display: list-item; + } + .item:after { + content: counter(section); + display: list-item; + } + .table-header { + display: table-header-group; + } +</style> +<body> + <ol reversed="reversed"> + <span class="table-header"> + <figure class="item"></figure> + </span> + </ol> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/ol-change-display-type.html b/third_party/blink/web_tests/external/wpt/css/css-lists/ol-change-display-type.html new file mode 100644 index 0000000..e711cfe --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/ol-change-display-type.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Lists: Change display type of reverse ol list element.</title> +<link rel=help href="https://crbug.com/1020669"> +<link rel=match href="ol-change-display-type-ref.html"> +<style> + .item { + display: list-item; + } + .item:after { + content: counter(section); + display: list-item; + } + .table-header { + display: table-header-group; + } +</style> +<body> + <ol reversed="reversed"> + <span id="span"> + <figure class="item"></figure> + </span> + </ol> +</body> +<script> + document.body.offsetTop; + document.getElementById('span').setAttribute('class', 'table-header'); +</script> +</html>
diff --git "a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_exclude=\050Document_Window_HTML._\051-expected.txt" "b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_exclude=\050Document_Window_HTML._\051-expected.txt" index 3b82a104..819e356 100644 --- "a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_exclude=\050Document_Window_HTML._\051-expected.txt" +++ "b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_exclude=\050Document_Window_HTML._\051-expected.txt"
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 1397 tests; 1354 PASS, 43 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 1397 tests; 1357 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface Document: original interface defined @@ -715,9 +715,9 @@ PASS OffscreenCanvasRenderingContext2D interface: operation rotate(unrestricted double) PASS OffscreenCanvasRenderingContext2D interface: operation translate(unrestricted double, unrestricted double) PASS OffscreenCanvasRenderingContext2D interface: operation transform(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double) -FAIL OffscreenCanvasRenderingContext2D interface: operation getTransform() assert_own_property: interface prototype object missing non-static operation expected property "getTransform" missing -FAIL OffscreenCanvasRenderingContext2D interface: operation setTransform(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double) assert_equals: property has wrong .length expected 0 but got 6 -FAIL OffscreenCanvasRenderingContext2D interface: operation setTransform(DOMMatrix2DInit) assert_equals: property has wrong .length expected 0 but got 6 +PASS OffscreenCanvasRenderingContext2D interface: operation getTransform() +PASS OffscreenCanvasRenderingContext2D interface: operation setTransform(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double) +PASS OffscreenCanvasRenderingContext2D interface: operation setTransform(DOMMatrix2DInit) PASS OffscreenCanvasRenderingContext2D interface: operation resetTransform() PASS OffscreenCanvasRenderingContext2D interface: attribute globalAlpha PASS OffscreenCanvasRenderingContext2D interface: attribute globalCompositeOperation
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt index 544c738..88f80ee 100644 --- a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 790 tests; 770 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 790 tests; 773 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface Document: original interface defined @@ -339,9 +339,9 @@ PASS OffscreenCanvasRenderingContext2D interface: operation rotate(unrestricted double) PASS OffscreenCanvasRenderingContext2D interface: operation translate(unrestricted double, unrestricted double) PASS OffscreenCanvasRenderingContext2D interface: operation transform(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double) -FAIL OffscreenCanvasRenderingContext2D interface: operation getTransform() assert_own_property: interface prototype object missing non-static operation expected property "getTransform" missing -FAIL OffscreenCanvasRenderingContext2D interface: operation setTransform(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double) assert_equals: property has wrong .length expected 0 but got 6 -FAIL OffscreenCanvasRenderingContext2D interface: operation setTransform(DOMMatrix2DInit) assert_equals: property has wrong .length expected 0 but got 6 +PASS OffscreenCanvasRenderingContext2D interface: operation getTransform() +PASS OffscreenCanvasRenderingContext2D interface: operation setTransform(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double) +PASS OffscreenCanvasRenderingContext2D interface: operation setTransform(DOMMatrix2DInit) PASS OffscreenCanvasRenderingContext2D interface: operation resetTransform() PASS OffscreenCanvasRenderingContext2D interface: attribute globalAlpha PASS OffscreenCanvasRenderingContext2D interface: attribute globalCompositeOperation
diff --git a/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.html b/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.html index 9aa437c..6715257 100644 --- a/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.html +++ b/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.html
@@ -30,7 +30,6 @@ assert_throws(new TypeError(), function() { ctx.transform(1, 0, 0, 1, 0); }); } if (ctx.setTransform) { - assert_throws(new TypeError(), function() { ctx.setTransform(); }); assert_throws(new TypeError(), function() { ctx.setTransform(1); }); assert_throws(new TypeError(), function() { ctx.setTransform(1, 0); }); assert_throws(new TypeError(), function() { ctx.setTransform(1, 0, 0); });
diff --git a/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.worker.js b/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.worker.js index 8f8d00e..755e881e 100644 --- a/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.worker.js +++ b/third_party/blink/web_tests/external/wpt/offscreen-canvas/conformance-requirements/2d.missingargs.worker.js
@@ -26,7 +26,6 @@ assert_throws(new TypeError(), function() { ctx.transform(1, 0, 0, 1, 0); }); } if (ctx.setTransform) { - assert_throws(new TypeError(), function() { ctx.setTransform(); }); assert_throws(new TypeError(), function() { ctx.setTransform(1); }); assert_throws(new TypeError(), function() { ctx.setTransform(1, 0); }); assert_throws(new TypeError(), function() { ctx.setTransform(1, 0, 0); });
diff --git a/third_party/blink/web_tests/external/wpt/offscreen-canvas/transformations/2d.transformation.getTransform.html b/third_party/blink/web_tests/external/wpt/offscreen-canvas/transformations/2d.transformation.getTransform.html new file mode 100644 index 0000000..b3b70ac --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/offscreen-canvas/transformations/2d.transformation.getTransform.html
@@ -0,0 +1,40 @@ +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +// Ensure that context2d.getTransform works +const epsilon = 1e-5; +const canvas = new OffscreenCanvas(300, 150); +const ctx = canvas.getContext('2d'); + +test(function(t) { + + assert_array_equals(ctx.getTransform().toFloat32Array(), + [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], + "Assert that an untransformed matrix is identity"); + + ctx.scale(2, 3); + transform = ctx.getTransform(); + assert_array_equals(ctx.getTransform().toFloat32Array(), + [2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], + "Assert that context2d scaling works"); + + ctx.rotate(Math.PI/2); + transform = ctx.getTransform(); + assert_array_approx_equals(ctx.getTransform().toFloat32Array(), + [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], epsilon, + "Assert that context2d rotate works"); + + ctx.translate(1, -1); + transform = ctx.getTransform(); + assert_array_approx_equals(ctx.getTransform().toFloat32Array(), + [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 1], epsilon, + "Assert context2d translate works."); + + ctx.resetTransform(); + assert_array_equals(ctx.getTransform().toFloat32Array(), + [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], + "Assert that a reset matrix is identity"); +}, 'This test ensures that getTransform works correctly.'); +</script> +</body>
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 12996e81..c8e88fbe 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
@@ -990,6 +990,7 @@ method fillText method getImageData method getLineDash + method getTransform method isPointInPath method isPointInStroke method lineTo
diff --git a/third_party/blink/web_tests/inspector-protocol/timeline/timeline-layout.js b/third_party/blink/web_tests/inspector-protocol/timeline/timeline-layout.js index 9507a16..d9dc48c 100644 --- a/third_party/blink/web_tests/inspector-protocol/timeline/timeline-layout.js +++ b/third_party/blink/web_tests/inspector-protocol/timeline/timeline-layout.js
@@ -21,21 +21,23 @@ await tracingHelper.invokeAsyncWithTracing(performActions); var schedRecalc = tracingHelper.findEvent('ScheduleStyleRecalculation', 'I'); - var recalc = tracingHelper.findEvent('UpdateLayoutTree', 'X'); - testRunner.log('UpdateLayoutTree frames match: ' + (schedRecalc.args.data.frame === recalc.args.beginData.frame)); - testRunner.log('UpdateLayoutTree elementCount > 0: ' + (recalc.args.elementCount > 0)); + var recalcBegin = tracingHelper.findEvent('UpdateLayoutTree', 'B'); + var recalcEnd = tracingHelper.findEvent('UpdateLayoutTree', 'E'); + testRunner.log('UpdateLayoutTree frames match: ' + (schedRecalc.args.data.frame === recalcBegin.args.beginData.frame)); + testRunner.log('UpdateLayoutTree elementCount > 0: ' + (recalcEnd.args.elementCount > 0)); var invalidate = tracingHelper.findEvent('InvalidateLayout', 'I'); - var layout = tracingHelper.findEvent('Layout', 'X'); + var layoutBegin = tracingHelper.findEvent('Layout', 'B'); + var layoutEnd = tracingHelper.findEvent('Layout', 'E'); - testRunner.log('InvalidateLayout frames match: ' + (recalc.args.beginData.frame === invalidate.args.data.frame)); + testRunner.log('InvalidateLayout frames match: ' + (recalcBegin.args.beginData.frame === invalidate.args.data.frame)); - var beginData = layout.args.beginData; + var beginData = layoutBegin.args.beginData; testRunner.log('Layout frames match: ' + (invalidate.args.data.frame === beginData.frame)); testRunner.log('dirtyObjects > 0: ' + (beginData.dirtyObjects > 0)); testRunner.log('totalObjects > 0: ' + (beginData.totalObjects > 0)); - var endData = layout.args.endData; + var endData = layoutEnd.args.endData; testRunner.log('has rootNode id: ' + (endData.rootNode > 0)); testRunner.log('has root quad: ' + !!endData.root);
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index e9c65a5a..6b37168b 100644 --- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -821,6 +821,7 @@ method fillText method getImageData method getLineDash + method getTransform method isPointInPath method isPointInStroke method lineTo
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt index c2efd05..4f6b1bb 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -773,6 +773,7 @@ [Worker] method fillText [Worker] method getImageData [Worker] method getLineDash +[Worker] method getTransform [Worker] method isPointInPath [Worker] method isPointInStroke [Worker] method lineTo
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 2365233..dc5bc65ec 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -4509,6 +4509,7 @@ method fillText method getImageData method getLineDash + method getTransform method isPointInPath method isPointInStroke method lineTo
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index 84ada2d..33d2887 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -768,6 +768,7 @@ [Worker] method fillText [Worker] method getImageData [Worker] method getLineDash +[Worker] method getTransform [Worker] method isPointInPath [Worker] method isPointInStroke [Worker] method lineTo
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 37974b2..d85b359 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
@@ -956,6 +956,7 @@ [Worker] method fillText [Worker] method getImageData [Worker] method getLineDash +[Worker] method getTransform [Worker] method isPointInPath [Worker] method isPointInStroke [Worker] method lineTo
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 b1d280a4..c339c82 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
@@ -5395,6 +5395,7 @@ method fillText method getImageData method getLineDash + method getTransform method isPointInPath method isPointInStroke method lineTo
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 f9e3191..3860279 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
@@ -938,6 +938,7 @@ [Worker] method fillText [Worker] method getImageData [Worker] method getLineDash +[Worker] method getTransform [Worker] method isPointInPath [Worker] method isPointInStroke [Worker] method lineTo
diff --git a/third_party/webxr_test_pages/.gitignore b/third_party/webxr_test_pages/.gitignore index c59768b..3a52d57 100644 --- a/third_party/webxr_test_pages/.gitignore +++ b/third_party/webxr_test_pages/.gitignore
@@ -1 +1,2 @@ -media/ \ No newline at end of file +media/ +webxr-samples-staging/
diff --git a/third_party/webxr_test_pages/webxr-samples/index.published.html b/third_party/webxr_test_pages/webxr-samples/index.published.html index 3ed2391..524418e 100644 --- a/third_party/webxr_test_pages/webxr-samples/index.published.html +++ b/third_party/webxr_test_pages/webxr-samples/index.published.html
@@ -87,8 +87,11 @@ </header> <main class='main' id='main'> - <p>Sample pages demonstrating how to use various aspects of the WebXR API <b><em>as implemented in Chrome versions 76-77.</b></em><br/> - Note: these samples will only work when visiting this site securely (https://).</p> + <p> + <b><em>THESE SAMPLES ARE DEPRECATED - DO NOT USE WITH CHROME 78+</b></em> + <br/> + For Chrome 78 and later, please use <a href="https://immersive-web.github.io/webxr-samples">these samples</a>, maintained by the Immersive Web Working Group. + </p> <script> let pages = [
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index bfb9443..b338915 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -83,22 +83,28 @@ "includes": [11000], "structures": [11800], }, + "chrome/browser/resources/bookmarks/bookmarks_resources.grd": { + "structures": [11830], + }, + "chrome/browser/resources/bookmarks/bookmarks_resources_vulcanized.grd": { + "structures": [11880], + }, "chrome/browser/resources/chromeos/camera/camera_resources.grd": { - "includes": [11870], - "structures": [11930], + "includes": [11890], + "structures": [11950], }, "chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd": { - "messages": [11970], + "messages": [12000], }, "chrome/browser/resources/chromeos/cellular_setup/cellular_setup_resources.grd": { - "structures": [12040], + "structures": [12080], }, "chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_resources.grd": { - "structures": [12050], + "structures": [12090], }, "chrome/browser/resources/component_extension_resources.grd": { - "includes": [12060], - "structures": [12200], + "includes": [12100], + "structures": [12230], }, "chrome/browser/resources/downloads/downloads_resources_vulcanized.grd": { "includes": [12240], @@ -342,7 +348,7 @@ "messages": [23125], }, "ash/components/ash_components_strings.grd": { - "messages": [23740], + "messages": [23800], }, "ash/keyboard/ui/keyboard_resources.grd": { "includes": [23960],
diff --git a/tools/measure_page_load_time/ff_ext/chrome.manifest b/tools/measure_page_load_time/ff_ext/chrome.manifest deleted file mode 100644 index 9e1d73d4..0000000 --- a/tools/measure_page_load_time/ff_ext/chrome.manifest +++ /dev/null
@@ -1,2 +0,0 @@ -content measurepageloadtimeextension content/ -overlay chrome://browser/content/browser.xul chrome://measurepageloadtimeextension/content/firefoxOverlay.xul
diff --git a/tools/measure_page_load_time/ff_ext/content/firefoxOverlay.xul b/tools/measure_page_load_time/ff_ext/content/firefoxOverlay.xul deleted file mode 100644 index 1c5529ea..0000000 --- a/tools/measure_page_load_time/ff_ext/content/firefoxOverlay.xul +++ /dev/null
@@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?xml-stylesheet href="chrome://measurepageloadtimeextension/skin/overlay.css" type="text/css"?> -<!DOCTYPE overlay SYSTEM "chrome://measurepageloadtimeextension/locale/measurepageloadtimeextension.dtd"> -<overlay id="measurepageloadtimeextension-overlay" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - <script src="measure_page_load_time.js"/> -</overlay>
diff --git a/tools/measure_page_load_time/ff_ext/content/measure_page_load_time.js b/tools/measure_page_load_time/ff_ext/content/measure_page_load_time.js deleted file mode 100644 index 44473cc..0000000 --- a/tools/measure_page_load_time/ff_ext/content/measure_page_load_time.js +++ /dev/null
@@ -1,209 +0,0 @@ -// Copyright (c) 2012 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. - -/** - * @fileoverview measure_page_load_time.js implements a Firefox extension - * for measuring how long a page takes to load. It waits on TCP port - * 42492 for connections, then accepts URLs and returns strings of the - * form url,time, where "time" is the load time in milliseconds or the - * string "timeout" or "error". Load time is measured from the call to - * loadURI until the load event fires, or until the status changes to - * STATUS_STOP if the load event doesn't fire (there's an error.) - * @author jhaas@google.com (Jonathan Haas) */ - -// Shorthand reference to nsIWebProgress[Listener] interfaces -var IWP = Components.interfaces.nsIWebProgress; -var IWPL = Components.interfaces.nsIWebProgressListener; - - -var MPLT = { - /** - * Constants - */ - PORT_NUMBER : 42492, // port to listen for connections on - TIME_OUT : 4 * 60 * 1000, // timeout in 4 minutes - - /** - * Incoming URL buffer - * @type {string} - */ - textBuffer : '', - - /** - * URL we're currently visiting - * @type {string} - */ - URL : '', - - /** - * Listener to accept incoming connections - * @type {nsIServerSocketListener} - */ - acceptListener : - { - onSocketAccepted : function(serverSocket, transport) - { - MPLT.streamInput = transport.openInputStream(0,0,0); - MPLT.streamOutput = transport.openOutputStream(0,0,0); - - MPLT.scriptStream = Components.classes['@mozilla.org/scriptableinputstream;1'] - .createInstance(Components.interfaces.nsIScriptableInputStream); - MPLT.scriptStream.init(MPLT.streamInput); - MPLT.pump = Components.classes['@mozilla.org/network/input-stream-pump;1'] - .createInstance(Components.interfaces.nsIInputStreamPump); - MPLT.pump.init(MPLT.streamInput, -1, -1, 0, 0, false); - MPLT.pump.asyncRead(MPLT.dataListener,null); - }, - - onStopListening : function(){} - }, - - /** - * Listener for network input - * @type {nsIStreamListener} - */ - dataListener : - { - onStartRequest: function(){}, - onStopRequest: function(){}, - onDataAvailable: function(request, context, inputStream, offset, count){ - // Add the received data to the buffer, then process it - // Change CRLF to newline while we're at it - MPLT.textBuffer += MPLT.scriptStream.read(count).replace('\r\n', '\n'); - - MPLT.process(); - } - }, - - /** - * Process the incoming data buffer - */ - process : function() - { - // If we're waiting for a page to finish loading, wait - if (MPLT.timeLoadStarted) - return; - - // Look for a carriage return - var firstCR = MPLT.textBuffer.indexOf('\n'); - - // If we haven't received a carriage return yet, wait - if (firstCR < 0) - return; - - // If the first character was a carriage return, we're done! - if (firstCR == 0) { - MPLT.textBuffer = ''; - MPLT.streamInput.close(); - MPLT.streamOutput.close(); - - return; - } - - // Remove the URL from the buffer - MPLT.URL = MPLT.textBuffer.substr(0, firstCR); - MPLT.textBuffer = MPLT.textBuffer.substr(firstCR + 1); - - // Remember the current time and navigate to the new URL - MPLT.timeLoadStarted = new Date(); - gBrowser.loadURIWithFlags(MPLT.URL, gBrowser.LOAD_FLAGS_BYPASS_CACHE); - setTimeout('MPLT.onTimeOut()', MPLT.TIME_OUT); - }, - - /** - * Page load completion handler - */ - onPageLoad : function(e) { - // Ignore loads of non-HTML documents - if (!(e.originalTarget instanceof HTMLDocument)) - return; - - // Also ignore subframe loads - if (e.originalTarget.defaultView.frameElement) - return; - - clearTimeout(); - var timeElapsed = new Date() - MPLT.timeLoadStarted; - - MPLT.outputResult(timeElapsed); - }, - - /** - * Timeout handler - */ - onTimeOut : function() { - gBrowser.stop(); - - MPLT.outputResult('timeout'); - }, - - - /** - * Sends a properly-formatted result to the client - * @param {string} result The value to send along with the URL - */ - outputResult : function(result) { - - if (MPLT.URL) { - var outputString = MPLT.URL + ',' + result + '\n'; - MPLT.streamOutput.write(outputString, outputString.length); - MPLT.URL = ''; - } - - MPLT.timeLoadStarted = null; - MPLT.process(); - }, - - /** - * Time the page load started. If null, we're waiting for the - * initial page load, or otherwise don't care about the page - * that's currently loading - * @type {number} - */ - timeLoadStarted : null, - - /* - * TODO(jhaas): add support for nsIWebProgressListener - * If the URL being visited died as part of a network error - * (host not found, connection reset by peer, etc), the onload - * event doesn't fire. The only way to catch it would be in - * a web progress listener. However, nsIWebProgress is not - * behaving according to documentation. More research is needed. - * For now, omitting it means that if any of our URLs are "dirty" - * (do not point to real web servers with real responses), we'll log - * them as timeouts. This doesn't affect pages where the server - * exists but returns an error code. - */ - - /** - * Initialize the plugin, create the socket and listen - */ - initialize: function() { - // Register for page load events - gBrowser.addEventListener('load', this.onPageLoad, true); - - // Set a timeout to wait for the initial page to load - MPLT.timeLoadStarted = new Date(); - setTimeout('MPLT.onTimeOut()', MPLT.TIME_OUT); - - // Create the listening socket - MPLT.serverSocket = Components.classes['@mozilla.org/network/server-socket;1'] - .createInstance(Components.interfaces.nsIServerSocket); - - MPLT.serverSocket.init(MPLT.PORT_NUMBER, true, 1); - MPLT.serverSocket.asyncListen(this.acceptListener); - }, - - /** - * Close the socket(s) - */ - deinitialize: function() { - if (MPLT.streamInput) MPLT.streamInput.close(); - if (MPLT.streamOutput) MPLT.streamOutput.close(); - if (MPLT.serverSocket) MPLT.serverSocket.close(); - } -}; - -window.addEventListener('load', function(e) { MPLT.initialize(); }, false); -window.addEventListener('unload', function(e) { MPLT.deinitialize(); }, false);
diff --git a/tools/measure_page_load_time/ff_ext/install.rdf b/tools/measure_page_load_time/ff_ext/install.rdf deleted file mode 100644 index c79d24e..0000000 --- a/tools/measure_page_load_time/ff_ext/install.rdf +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:em="http://www.mozilla.org/2004/em-rdf#"> - <Description about="urn:mozilla:install-manifest"> - <em:id>measurepageloadtimeextension@google.com</em:id> - <em:name>MeasurePageLoadTime</em:name> - <em:version>1.0</em:version> - <em:creator>Jonathan Haas</em:creator> - <em:targetApplication> - <Description> - <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox --> - <em:minVersion>1.5</em:minVersion> - <em:maxVersion>3.0.*</em:maxVersion> - </Description> - </em:targetApplication> - </Description> -</RDF>
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.cpp b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.cpp deleted file mode 100644 index d3a8d54..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.cpp +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright (c) 2012 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. - -// MeasurePageLoadTime.cpp : Implementation of DLL Exports. - -#include "stdafx.h" -#include "resource.h" -#include "MeasurePageLoadTime.h" - - -class CMeasurePageLoadTimeModule : public CAtlDllModuleT< CMeasurePageLoadTimeModule > -{ -public : - DECLARE_LIBID(LIBID_MeasurePageLoadTimeLib) - DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MEASUREPAGELOADTIME, "{56C6D9F9-643C-4F6E-906C-5F7CECB23C24}") -}; - -CMeasurePageLoadTimeModule _AtlModule; - - -#ifdef _MANAGED -#pragma managed(push, off) -#endif - -// DLL Entry Point -extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) -{ - if (dwReason == DLL_PROCESS_ATTACH) - { - DisableThreadLibraryCalls(hInstance); - } - return _AtlModule.DllMain(dwReason, lpReserved); -} - -#ifdef _MANAGED -#pragma managed(pop) -#endif - - - - -// Used to determine whether the DLL can be unloaded by OLE -STDAPI DllCanUnloadNow(void) -{ - return _AtlModule.DllCanUnloadNow(); -} - - -// Returns a class factory to create an object of the requested type -STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) -{ - return _AtlModule.DllGetClassObject(rclsid, riid, ppv); -} - - -// DllRegisterServer - Adds entries to the system registry -STDAPI DllRegisterServer(void) -{ - // registers object, typelib and all interfaces in typelib - HRESULT hr = _AtlModule.DllRegisterServer(); - return hr; -} - - -// DllUnregisterServer - Removes entries from the system registry -STDAPI DllUnregisterServer(void) -{ - HRESULT hr = _AtlModule.DllUnregisterServer(); - return hr; -} -
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.def b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.def deleted file mode 100644 index 55529233..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.def +++ /dev/null
@@ -1,9 +0,0 @@ -; MeasurePageLoadTime.def : Declares the module parameters. - -LIBRARY "MeasurePageLoadTime.DLL" - -EXPORTS - DllCanUnloadNow PRIVATE - DllGetClassObject PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.idl b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.idl deleted file mode 100644 index d2f98da3..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.idl +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2012 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. - -// MeasurePageLoadTime.idl : IDL source for MeasurePageLoadTime -// - -// This file will be processed by the MIDL tool to -// produce the type library (MeasurePageLoadTime.tlb) and marshalling code. - -import "oaidl.idl"; -import "ocidl.idl"; - -[ - object, - uuid(019637EB-B865-485B-9A66-419477EE55A0), - dual, - nonextensible, - helpstring("IMeasurePageLoadTimeBHO Interface"), - pointer_default(unique) -] -interface IMeasurePageLoadTimeBHO : IDispatch{ -}; -[ - uuid(61AC7AC4-B715-4955-A238-5F9AEA80DF4B), - version(1.0), - helpstring("MeasurePageLoadTime 1.0 Type Library") -] -library MeasurePageLoadTimeLib -{ - importlib("stdole2.tlb"); - [ - uuid(807E68BC-238F-4163-AE4B-0A3604F3E145), - helpstring("MeasurePageLoadTimeBHO Class") - ] - coclass MeasurePageLoadTimeBHO - { - [default] interface IMeasurePageLoadTimeBHO; - }; -};
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.rc b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.rc deleted file mode 100644 index 9285a705..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.rc +++ /dev/null
@@ -1,121 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "1 TYPELIB ""MeasurePageLoadTime.tlb""\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "Google" - VALUE "FileDescription", "Measures page load times" - VALUE "FileVersion", "1.0.0.1" - VALUE "LegalCopyright", "(c) 2008 Google. All rights reserved." - VALUE "InternalName", "MeasurePageLoadTime.dll" - VALUE "OriginalFilename", "MeasurePageLoadTime.dll" - VALUE "ProductName", "MeasurePageLoadTime" - VALUE "ProductVersion", "1.0.0.1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// REGISTRY -// - -IDR_MEASUREPAGELOADTIME REGISTRY "MeasurePageLoadTime.rgs" -IDR_MEASUREPAGELOADTIMEBHO REGISTRY "MeasurePageLoadTimeBHO.rgs" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_PROJNAME "MeasurePageLoadTime" -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// -1 TYPELIB "MeasurePageLoadTime.tlb" - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED -
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.rgs b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.rgs deleted file mode 100644 index 98e7f783..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.rgs +++ /dev/null
@@ -1,29 +0,0 @@ -HKCR -{ - NoRemove AppID - { - '%APPID%' = s 'MeasurePageLoadTime' - 'MeasurePageLoadTime.DLL' - { - val AppID = s '%APPID%' - } - } -} - -HKLM { - NoRemove SOFTWARE { - NoRemove Microsoft { - NoRemove Windows { - NoRemove CurrentVersion { - NoRemove Explorer { - NoRemove 'Browser Helper Objects' { - ForceRemove '{807E68BC-238F-4163-AE4B-0A3604F3E145}' = s 'MeasurePageLoadTimeBHO' { - val 'NoExplorer' = d '1' - } - } - } - } - } - } - } -}
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.vcproj b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.vcproj deleted file mode 100644 index 9ed8327..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTime.vcproj +++ /dev/null
@@ -1,320 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="MeasurePageLoadTime" - ProjectGUID="{151243DF-25BE-4A88-B566-8B7AE8970E86}" - RootNamespace="MeasurePageLoadTime" - Keyword="AtlProj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="2" - UseOfATL="2" - ATLMinimizesCRunTimeLibraryUsage="false" - CharacterSet="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - PreprocessorDefinitions="_DEBUG" - MkTypLibCompatible="false" - TargetEnvironment="1" - GenerateStublessProxies="true" - TypeLibraryName="$(IntDir)/MeasurePageLoadTime.tlb" - HeaderFileName="MeasurePageLoadTime.h" - DLLDataFileName="" - InterfaceIdentifierFileName="MeasurePageLoadTime_i.c" - ProxyFileName="MeasurePageLoadTime_p.c" - ValidateParameters="false" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="3" - UsePrecompiledHeader="2" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="4" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="_DEBUG" - Culture="1033" - AdditionalIncludeDirectories="$(IntDir)" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - RegisterOutput="true" - IgnoreImportLibrary="true" - AdditionalDependencies="ws2_32.lib" - LinkIncremental="2" - ModuleDefinitionFile=".\MeasurePageLoadTime.def" - GenerateDebugInformation="true" - SubSystem="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="2" - UseOfATL="1" - ATLMinimizesCRunTimeLibraryUsage="false" - CharacterSet="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - PreprocessorDefinitions="NDEBUG" - MkTypLibCompatible="false" - TargetEnvironment="1" - GenerateStublessProxies="true" - TypeLibraryName="$(IntDir)/MeasurePageLoadTime.tlb" - HeaderFileName="MeasurePageLoadTime.h" - DLLDataFileName="" - InterfaceIdentifierFileName="MeasurePageLoadTime_i.c" - ProxyFileName="MeasurePageLoadTime_p.c" - ValidateParameters="false" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL" - RuntimeLibrary="0" - UsePrecompiledHeader="2" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="3" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="NDEBUG" - Culture="1033" - AdditionalIncludeDirectories="$(IntDir)" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - RegisterOutput="true" - IgnoreImportLibrary="true" - AdditionalDependencies="ws2_32.lib" - LinkIncremental="1" - ModuleDefinitionFile=".\MeasurePageLoadTime.def" - GenerateDebugInformation="true" - SubSystem="2" - OptimizeReferences="2" - EnableCOMDATFolding="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" - > - <File - RelativePath=".\MeasurePageLoadTime.cpp" - > - </File> - <File - RelativePath=".\MeasurePageLoadTime.def" - > - </File> - <File - RelativePath=".\MeasurePageLoadTime.idl" - > - </File> - <File - RelativePath=".\MeasurePageLoadTimeBHO.cpp" - > - </File> - <File - RelativePath=".\stdafx.cpp" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="1" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="1" - /> - </FileConfiguration> - </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" - > - <File - RelativePath=".\MeasurePageLoadTimeBHO.h" - > - </File> - <File - RelativePath=".\stdafx.h" - > - </File> - </Filter> - <Filter - Name="Resource Files" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" - > - <File - RelativePath=".\MeasurePageLoadTime.rc" - > - </File> - <File - RelativePath=".\MeasurePageLoadTime.rgs" - > - </File> - <File - RelativePath=".\MeasurePageLoadTimeBHO.rgs" - > - </File> - </Filter> - <Filter - Name="Generated Files" - SourceControlFiles="false" - > - <File - RelativePath=".\MeasurePageLoadTime.h" - > - </File> - <File - RelativePath=".\MeasurePageLoadTime_i.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - /> - </FileConfiguration> - </File> - </Filter> - <File - RelativePath=".\ReadMe.txt" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject>
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.cpp b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.cpp deleted file mode 100644 index 3de87f3..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.cpp +++ /dev/null
@@ -1,292 +0,0 @@ -// Copyright (c) 2012 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. - -// Implements a Browser Helper Object (BHO) which opens a socket -// and waits to receive URLs over it. Visits those URLs, measuring -// how long it takes between the start of navigation and the -// DocumentComplete event, and returns the time in milliseconds as -// a string to the caller. - -#include "stdafx.h" -#include "MeasurePageLoadTimeBHO.h" - -#define MAX_URL 1024 // size of URL buffer -#define MAX_PAGELOADTIME (4*60*1000) // assume all pages take < 4 minutes -#define PORT 42492 // port to listen on. Also jhaas's - // old MSFT employee number - - -// Static function to serve as thread entry point, takes a "this" -// pointer as pParam and calls the method in the object -static DWORD WINAPI ProcessPageTimeRequests(LPVOID pThis) { - reinterpret_cast<CMeasurePageLoadTimeBHO*>(pThis)->ProcessPageTimeRequests(); - - return 0; -} - - -STDMETHODIMP CMeasurePageLoadTimeBHO::SetSite(IUnknown* pUnkSite) -{ - if (pUnkSite != NULL) - { - // Cache the pointer to IWebBrowser2. - HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser); - if (SUCCEEDED(hr)) - { - // Register to sink events from DWebBrowserEvents2. - hr = DispEventAdvise(m_spWebBrowser); - if (SUCCEEDED(hr)) - { - m_fAdvised = TRUE; - } - - // Stash the interface in the global interface table - CComGITPtr<IWebBrowser2> git(m_spWebBrowser); - m_dwCookie = git.Detach(); - - // Create the event to be signaled when navigation completes. - // Start it in nonsignaled state, and allow it to be triggered - // when the initial page load is done. - m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - - // Create a thread to wait on the socket - HANDLE hThread = CreateThread(NULL, 0, ::ProcessPageTimeRequests, this, 0, NULL); - } - } - else - { - // Unregister event sink. - if (m_fAdvised) - { - DispEventUnadvise(m_spWebBrowser); - m_fAdvised = FALSE; - } - - // Release cached pointers and other resources here. - m_spWebBrowser.Release(); - } - - // Call base class implementation. - return IObjectWithSiteImpl<CMeasurePageLoadTimeBHO>::SetSite(pUnkSite); -} - - -void STDMETHODCALLTYPE CMeasurePageLoadTimeBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL) -{ - if (pDisp == m_spWebBrowser) - { - // Fire the event when the page is done loading - // to unblock the other thread. - SetEvent(m_hEvent); - } -} - - -void CMeasurePageLoadTimeBHO::ProcessPageTimeRequests() -{ - CoInitialize(NULL); - - // The event will start in nonsignaled state, meaning that - // the initial page load isn't done yet. Wait for that to - // finish before doing anything. - // - // It seems to be the case that the BHO will get loaded - // and SetSite called always before the initial page load - // even begins, but just to be on the safe side, we won't - // wait indefinitely. - WaitForSingleObject(m_hEvent, MAX_PAGELOADTIME); - - // Retrieve the web browser interface from the global table - CComGITPtr<IWebBrowser2> git(m_dwCookie); - IWebBrowser2* browser; - git.CopyTo(&browser); - - // Create a listening socket - m_sockListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (m_sockListen == SOCKET_ERROR) - ErrorExit(); - - BOOL on = TRUE; - if (setsockopt(m_sockListen, SOL_SOCKET, SO_REUSEADDR, - (const char*)&on, sizeof(on))) - ErrorExit(); - - // Bind the listening socket - SOCKADDR_IN addrBind; - - addrBind.sin_family = AF_INET; - addrBind.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addrBind.sin_port = htons(PORT); - - if (bind(m_sockListen, (sockaddr*)&addrBind, sizeof(addrBind))) - ErrorExit(); - - // Listen for incoming connections - if (listen(m_sockListen, 1)) - ErrorExit(); - - // Ensure the socket is blocking... it should be by default, but - // it can't hurt to make sure - unsigned long nNonblocking = 0; - if (ioctlsocket(m_sockListen, FIONBIO, &nNonblocking)) - ErrorExit(); - - m_sockTransport = 0; - - // Loop indefinitely waiting for connections - while(1) - { - SOCKADDR_IN addrConnected; - int sConnected = sizeof(addrConnected); - - // Wait for a client to connect and send a URL - m_sockTransport = accept( - m_sockListen, (sockaddr*)&addrConnected, &sConnected); - - if (m_sockTransport == SOCKET_ERROR) - ErrorExit(); - - char pbBuffer[MAX_URL], strURL[MAX_URL]; - DWORD cbRead, cbWritten; - - bool fDone = false; - - // Loop until we're done with this client - while (!fDone) - { - *strURL = '\0'; - bool fReceivedCR = false; - - do - { - // Only receive up to the first carriage return - cbRead = recv(m_sockTransport, pbBuffer, MAX_URL-1, MSG_PEEK); - - // An error on read most likely means that the remote peer - // closed the connection. Go back to waiting - if (cbRead == 0) - { - fDone = true; - break; - } - - // Null terminate the received characters so strchr() is safe - pbBuffer[cbRead] = '\0'; - - if(char* pchFirstCR = strchr(pbBuffer, '\n')) - { - cbRead = (DWORD)(pchFirstCR - pbBuffer + 1); - fReceivedCR = true; - } - - // The below call will not block, since we determined with - // MSG_PEEK that at least cbRead bytes are in the TCP receive buffer - recv(m_sockTransport, pbBuffer, cbRead, 0); - pbBuffer[cbRead] = '\0'; - - strcat_s(strURL, sizeof(strURL), pbBuffer); - } while (!fReceivedCR); - - // If an error occurred while reading, exit this loop - if (fDone) - break; - - // Strip the trailing CR and/or LF - int i; - for (i = (int)strlen(strURL)-1; i >= 0 && isspace(strURL[i]); i--) - { - strURL[i] = '\0'; - } - - if (i < 0) - { - // Sending a carriage return on a line by itself means that - // the client is done making requests - fDone = true; - } - else - { - // Send the browser to the requested URL - CComVariant vNavFlags( navNoReadFromCache ); - CComVariant vTargetFrame("_self"); - CComVariant vPostData(""); - CComVariant vHTTPHeaders(""); - - ResetEvent(m_hEvent); - DWORD dwStartTime = GetTickCount(); - - HRESULT hr = browser->Navigate( - CComBSTR(strURL), - &vNavFlags, - &vTargetFrame, // TargetFrameName - &vPostData, // PostData - &vHTTPHeaders // Headers - ); - - // The main browser thread will call OnDocumentComplete() when - // the page is done loading, which will in turn trigger - // m_hEvent. Wait here until then; the event will reset itself - // once this thread is released - if (WaitForSingleObject(m_hEvent, MAX_PAGELOADTIME) == WAIT_TIMEOUT) - { - sprintf_s(pbBuffer, sizeof(pbBuffer), "%s,timeout\n", strURL); - - browser->Stop(); - } - else - { - // Format the elapsed time as a string - DWORD dwLoadTime = GetTickCount() - dwStartTime; - sprintf_s( - pbBuffer, sizeof(pbBuffer), "%s,%d\n", strURL, dwLoadTime); - } - - // Send the result. Just in case the TCP buffer can't handle - // the whole thing, send in parts if necessary - char *chSend = pbBuffer; - - while (*chSend) - { - cbWritten = send( - m_sockTransport, chSend, (int)strlen(chSend), 0); - - // Error on send probably means connection reset by peer - if (cbWritten == 0) - { - fDone = true; - break; - } - - chSend += cbWritten; - } - } - } - - // Close the transport socket and wait for another connection - closesocket(m_sockTransport); - m_sockTransport = 0; - } -} - - -void CMeasurePageLoadTimeBHO::ErrorExit() -{ - // Unlink from IE, close the sockets, then terminate this - // thread - SetSite(NULL); - - if (m_sockTransport && m_sockTransport != SOCKET_ERROR) - { - closesocket(m_sockTransport); - m_sockTransport = 0; - } - - if (m_sockListen && m_sockListen != SOCKET_ERROR) - { - closesocket(m_sockListen); - m_sockListen = 0; - } - - TerminateThread(GetCurrentThread(), -1); -}
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.h b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.h deleted file mode 100644 index cabb0240..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.h +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright (c) 2006-2008 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. - -// MeasurePageLoadTimeBHO.h : Declaration of the CMeasurePageLoadTimeBHO - -#include "resource.h" // main symbols - -#include <shlguid.h> // IID_IWebBrowser2, DIID_DWebBrowserEvents2, et -#include <exdispid.h> // DISPID_DOCUMENTCOMPLETE, etc. - -#include <string> - -#include "MeasurePageLoadTime.h" - - -#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) -#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM objects and allow use of its single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms." -#endif - - - -// CMeasurePageLoadTimeBHO - -class ATL_NO_VTABLE CMeasurePageLoadTimeBHO : - public CComObjectRootEx<CComSingleThreadModel>, - public CComCoClass<CMeasurePageLoadTimeBHO, &CLSID_MeasurePageLoadTimeBHO>, - public IObjectWithSiteImpl<CMeasurePageLoadTimeBHO>, - public IDispatchImpl<IMeasurePageLoadTimeBHO, &IID_IMeasurePageLoadTimeBHO, &LIBID_MeasurePageLoadTimeLib, /*wMajor =*/ 1, /*wMinor =*/ 0>, - public IDispEventImpl<1, CMeasurePageLoadTimeBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1> -{ -public: - CMeasurePageLoadTimeBHO() - { - } - -DECLARE_REGISTRY_RESOURCEID(IDR_MEASUREPAGELOADTIMEBHO) - -DECLARE_NOT_AGGREGATABLE(CMeasurePageLoadTimeBHO) - -BEGIN_COM_MAP(CMeasurePageLoadTimeBHO) - COM_INTERFACE_ENTRY(IMeasurePageLoadTimeBHO) - COM_INTERFACE_ENTRY(IDispatch) - COM_INTERFACE_ENTRY(IObjectWithSite) -END_COM_MAP() - -BEGIN_SINK_MAP(CMeasurePageLoadTimeBHO) - SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete) -END_SINK_MAP() - - // DWebBrowserEvents2 - void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL); - STDMETHOD(SetSite)(IUnknown *pUnkSite); - - DECLARE_PROTECT_FINAL_CONSTRUCT() - - HRESULT FinalConstruct() - { - return S_OK; - } - - void FinalRelease() - { - } - - void ProcessPageTimeRequests(void); - void VisitNextURL(void); - void ErrorExit(void); - -private: - CComPtr<IWebBrowser2> m_spWebBrowser; - BOOL m_fAdvised; - - // Handle to global interface table - DWORD m_dwCookie; - - // Handle to event to signal when navigation completes - HANDLE m_hEvent; - - // Socket for accepting incoming connections - SOCKET m_sockListen; - - // Socket for communicating with remote peers - SOCKET m_sockTransport; -}; - -OBJECT_ENTRY_AUTO(__uuidof(MeasurePageLoadTimeBHO), CMeasurePageLoadTimeBHO)
diff --git a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.rgs b/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.rgs deleted file mode 100644 index 907015f..0000000 --- a/tools/measure_page_load_time/ie_bho/MeasurePageLoadTimeBHO.rgs +++ /dev/null
@@ -1,27 +0,0 @@ -HKCR -{ - MeasurePageLoadTime.MeasurePageLoadTi.1 = s 'MeasurePageLoadTimeBHO Class' - { - CLSID = s '{807E68BC-238F-4163-AE4B-0A3604F3E145}' - } - MeasurePageLoadTime.MeasurePageLoadTime = s 'MeasurePageLoadTimeBHO Class' - { - CLSID = s '{807E68BC-238F-4163-AE4B-0A3604F3E145}' - CurVer = s 'MeasurePageLoadTime.MeasurePageLoadTi.1' - } - NoRemove CLSID - { - ForceRemove {807E68BC-238F-4163-AE4B-0A3604F3E145} = s 'MeasurePageLoadTimeBHO Class' - { - ProgID = s 'MeasurePageLoadTime.MeasurePageLoadTi.1' - VersionIndependentProgID = s 'MeasurePageLoadTime.MeasurePageLoadTime' - ForceRemove 'Programmable' - InprocServer32 = s '%MODULE%' - { - val ThreadingModel = s 'Apartment' - } - val AppID = s '%APPID%' - 'TypeLib' = s '{61AC7AC4-B715-4955-A238-5F9AEA80DF4B}' - } - } -}
diff --git a/tools/measure_page_load_time/ie_bho/resource.h b/tools/measure_page_load_time/ie_bho/resource.h deleted file mode 100644 index 38dc825..0000000 --- a/tools/measure_page_load_time/ie_bho/resource.h +++ /dev/null
@@ -1,18 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by MeasurePageLoadTime.rc -// -#define IDS_PROJNAME 100 -#define IDR_MEASUREPAGELOADTIME 101 -#define IDR_MEASUREPAGELOADTIMEBHO 102 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 201 -#define _APS_NEXT_COMMAND_VALUE 32768 -#define _APS_NEXT_CONTROL_VALUE 201 -#define _APS_NEXT_SYMED_VALUE 103 -#endif -#endif
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 04333c0f..42f8d7be 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -6340,6 +6340,22 @@ </summary> </histogram> +<histogram name="Apps.ScrollableShelf.AnimationSmoothness" units="%" + expires_after="2020-11-06"> +<!-- Name completed by histogram suffixes + name="HomeLauncherVisibility" --> + + <owner>anasalazar@chromium.org</owner> + <owner>newcomer@chromium.org</owner> + <summary> + Relative smoothness of animations of the scrollable shelf when scrolling. + 100% represents ideally smooth 60 frames per second. 50% represents only 30 + frames per second is achieved during the animations. 0% should not happen. + This metric is recorded exactly once when the user scrolls over the + scrollable shelf. + </summary> +</histogram> + <histogram name="Apps.StateTransition.AnimationSmoothness" units="%" expires_after="2020-03-22"> <!-- Name completed by histogram_suffixes @@ -29533,6 +29549,9 @@ <histogram name="DataReductionProxy.Protocol.AcceptTransform" enum="DataReductionProxyProtocolAcceptTransformEvent" expires_after="2019-12-12"> + <obsolete> + Obsolete as of 10/2018. + </obsolete> <owner>dougarnett@chromium.org</owner> <summary> Records the sending of accepted transform headers to the data reduction @@ -172273,6 +172292,14 @@ <affected-histogram name="Histogram.InconsistentSnapshotBrowser"/> </histogram_suffixes> +<histogram_suffixes name="HomeLauncherVisibility" separator="."> + <suffix name="LauncherHidden" + label="Home Launcher was hidden during this animation."/> + <suffix name="LauncherVisible" + label="Home Launcher was visible during this animation."/> + <affected-histogram name="Apps.ScrollableShelf.AnimationSmoothness"/> +</histogram_suffixes> + <histogram_suffixes name="HstsState" separator="."> <suffix name="HSTSNotEnabled" label="The HSTS is not enabled."/> <suffix name="WithHSTSEnabled" label="The HSTS is enabled."/>
diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml index 292703b..bc680dd4 100644 --- a/tools/metrics/rappor/rappor.xml +++ b/tools/metrics/rappor/rappor.xml
@@ -110,15 +110,6 @@ </summary> </rappor-metric> -<rappor-metric name="ContentSettings.Plugins.AddedAllowException" - type="ETLD_PLUS_ONE"> - <owner>tommycli@chromium.org</owner> - <summary> - The eTLD+1 of a URL that the user added to the ALLOW site exceptions for the - Plugins Content Setting. - </summary> -</rappor-metric> - <rappor-metric name="CustomTabs.ServiceClient.PackageName" type="UMA_RAPPOR_TYPE"> <owner>yusufo@chromium.org</owner> @@ -214,23 +205,6 @@ </summary> </rappor-metric> -<rappor-metric name="PowerfulFeatureUse.Host.DeviceMotion.Insecure" - type="ETLD_PLUS_ONE"> - <owner>jww@chromium.org</owner> - <summary> - The host of the URL that uses the device motion API from an insecure origin. - </summary> -</rappor-metric> - -<rappor-metric name="PowerfulFeatureUse.Host.DeviceOrientation.Insecure" - type="ETLD_PLUS_ONE"> - <owner>jww@chromium.org</owner> - <summary> - The host of the URL that uses the device orientation API from an insecure - origin. - </summary> -</rappor-metric> - <rappor-metric name="PowerfulFeatureUse.Host.Fullscreen.Insecure" type="ETLD_PLUS_ONE"> <owner>jww@chromium.org</owner>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 05aa905..e39c20c 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -224,7 +224,6 @@ crbug.com/1000473 [ win ] rendering.desktop/balls_svg_animations [ Skip ] crbug.com/1017244 [ desktop ] rendering.desktop/youtube_2018 [ Skip ] crbug.com/1017244 [ desktop ] rendering.desktop/youtube_pinch_2018 [ Skip ] -crbug.com/1021682 [ desktop ] rendering.desktop/runway [ Skip ] # Benchmark: rendering.mobile crbug.com/785485 [ android-webview ] rendering.mobile/kevs_3d [ Skip ] @@ -269,7 +268,6 @@ crbug.com/967809 [ android-webview ] rendering.mobile/microsoft_video_city [ Skip ] crbug.com/1000473 [ android ] rendering.mobile/balls_svg_animations [ Skip ] crbug.com/1017244 [ mobile ] rendering.mobile/youtube_2018 [ Skip ] -crbug.com/1021682 [ mobile ] rendering.mobile/runway [ Skip ] # Benchmark: rasterize_and_record_micro.top_25 crbug.com/764543 rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ]
diff --git a/tools/perf/page_sets/data/rendering_desktop.json b/tools/perf/page_sets/data/rendering_desktop.json index 0f8182d..599106b 100644 --- a/tools/perf/page_sets/data/rendering_desktop.json +++ b/tools/perf/page_sets/data/rendering_desktop.json
@@ -270,8 +270,8 @@ "repaint_yahoo_homepage_2018": { "DEFAULT": "rendering_desktop_fdde4c2d8b.wprgo" }, - "runway": { - "DEFAULT": "rendering_desktop_004.wprgo" + "runway_2019": { + "DEFAULT": "rendering_desktop_00acdd603b.wprgo" }, "san_angeles": { "DEFAULT": "rendering_desktop_011.wprgo"
diff --git a/tools/perf/page_sets/data/rendering_desktop_00acdd603b.wprgo.sha1 b/tools/perf/page_sets/data/rendering_desktop_00acdd603b.wprgo.sha1 new file mode 100644 index 0000000..0856c7b0 --- /dev/null +++ b/tools/perf/page_sets/data/rendering_desktop_00acdd603b.wprgo.sha1
@@ -0,0 +1 @@ +00acdd603bf569fb0800fa41c0c0cf0cb334ed6f \ No newline at end of file
diff --git a/tools/perf/page_sets/data/rendering_mobile.json b/tools/perf/page_sets/data/rendering_mobile.json index 815ae4b..c1943ab10 100644 --- a/tools/perf/page_sets/data/rendering_mobile.json +++ b/tools/perf/page_sets/data/rendering_mobile.json
@@ -513,8 +513,8 @@ "reddit_mobile_2018": { "DEFAULT": "rendering_mobile_011.wprgo" }, - "runway": { - "DEFAULT": "rendering_mobile_004.wprgo" + "runway_2019": { + "DEFAULT": "rendering_mobile_4596353b1a.wprgo" }, "san_angeles": { "DEFAULT": "rendering_mobile_026.wprgo"
diff --git a/tools/perf/page_sets/data/rendering_mobile_4596353b1a.wprgo.sha1 b/tools/perf/page_sets/data/rendering_mobile_4596353b1a.wprgo.sha1 new file mode 100644 index 0000000..afdb8a7 --- /dev/null +++ b/tools/perf/page_sets/data/rendering_mobile_4596353b1a.wprgo.sha1
@@ -0,0 +1 @@ +4596353b1aeb5ae76f17dac2d23d660179ab0f67 \ No newline at end of file
diff --git a/tools/perf/page_sets/rendering/tough_canvas_cases.py b/tools/perf/page_sets/rendering/tough_canvas_cases.py index 1306c4e..f696d0f 100644 --- a/tools/perf/page_sets/rendering/tough_canvas_cases.py +++ b/tools/perf/page_sets/rendering/tough_canvas_cases.py
@@ -46,6 +46,7 @@ class RunwayPage(ToughCanvasPage): BASE_NAME = 'runway' URL = 'http://runway.countlessprojects.com/prototype/performance_test.html' + YEAR = '2019' TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_WIN_DESKTOP]
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc index a18dc39..cecb303 100644 --- a/ui/accessibility/ax_node_position_unittest.cc +++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -198,6 +198,7 @@ // different language. std::unique_ptr<AXTree> CreateMultilingualDocument( std::vector<int>* text_offsets) { + EXPECT_NE(nullptr, text_offsets); text_offsets->push_back(0); base::string16 english_text; @@ -212,8 +213,8 @@ base::string16 hindi_text; for (int i = 3; i < 5; ++i) { base::string16 grapheme = base::WideToUTF16(kGraphemeClusters[i]); - EXPECT_LE(2u, grapheme.length()) - << "All Hindi characters should be two or more UTF16 code units."; + EXPECT_LE(2u, grapheme.length()) << "All Hindi characters should be two " + "or more UTF16 code units in length."; text_offsets->push_back(text_offsets->back() + int{grapheme.length()}); hindi_text.append(grapheme); } @@ -222,7 +223,7 @@ for (int i = 5; i < 8; ++i) { base::string16 grapheme = base::WideToUTF16(kGraphemeClusters[i]); EXPECT_LT(0u, grapheme.length()) - << "One of the Thai characters should be one UTF16 code units, " + << "One of the Thai characters should be one UTF16 code unit, " "whilst others should be two or more."; text_offsets->push_back(text_offsets->back() + int{grapheme.length()}); thai_text.append(grapheme); @@ -2089,7 +2090,6 @@ new_tree->data().tree_id, new_tree->root()->id(), 10 /* text_offset */, ax::mojom::TextAffinity::kUpstream); ASSERT_NE(nullptr, test_position); - ASSERT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); EXPECT_EQ(10, test_position->text_offset()); @@ -3747,6 +3747,12 @@ ASSERT_TRUE(text_position->IsTextPosition()); TestPositionType test_position = text_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box1_.id, test_position->anchor_id()); + EXPECT_EQ(4, test_position->text_offset()); + test_position = text_position->CreateNextCharacterPosition( AXBoundaryBehavior::CrossBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -3772,6 +3778,12 @@ ASSERT_TRUE(text_position->IsTextPosition()); test_position = text_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box1_.id, test_position->anchor_id()); + EXPECT_EQ(5, test_position->text_offset()); + test_position = text_position->CreateNextCharacterPosition( AXBoundaryBehavior::CrossBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -3797,6 +3809,12 @@ ASSERT_TRUE(text_position->IsTextPosition()); test_position = text_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box1_.id, test_position->anchor_id()); + EXPECT_EQ(6, test_position->text_offset()); + test_position = text_position->CreateNextCharacterPosition( AXBoundaryBehavior::CrossBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -3826,6 +3844,12 @@ EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsNullPosition()); test_position = text_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + EXPECT_EQ(6, test_position->text_offset()); + test_position = text_position->CreateNextCharacterPosition( AXBoundaryBehavior::StopAtAnchorBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -3851,6 +3875,12 @@ EXPECT_EQ(inline_box1_.id, test_position->anchor_id()); EXPECT_EQ(1, test_position->text_offset()); test_position = text_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(check_box_.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + test_position = text_position->CreateNextCharacterPosition( AXBoundaryBehavior::StopAtAnchorBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -3903,7 +3933,13 @@ TestPositionType test_position = text_position->CreatePreviousCharacterPosition( - AXBoundaryBehavior::CrossBoundary); + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + EXPECT_EQ(5, test_position->text_offset()); + test_position = text_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::CrossBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); @@ -3928,6 +3964,12 @@ ASSERT_TRUE(text_position->IsTextPosition()); test_position = text_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + EXPECT_EQ(1, test_position->text_offset()); + test_position = text_position->CreatePreviousCharacterPosition( AXBoundaryBehavior::CrossBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -3953,6 +3995,12 @@ ASSERT_TRUE(text_position->IsTextPosition()); test_position = text_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + test_position = text_position->CreatePreviousCharacterPosition( AXBoundaryBehavior::CrossBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -3982,6 +4030,12 @@ EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsNullPosition()); test_position = text_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box1_.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + test_position = text_position->CreatePreviousCharacterPosition( AXBoundaryBehavior::StopAtAnchorBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -4005,6 +4059,12 @@ EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsNullPosition()); test_position = text_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(check_box_.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + test_position = text_position->CreatePreviousCharacterPosition( AXBoundaryBehavior::StopAtAnchorBoundary); EXPECT_NE(nullptr, test_position); EXPECT_TRUE(test_position->IsTextPosition()); @@ -4062,6 +4122,51 @@ EXPECT_EQ(text_offset, test_position->text_offset()); EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); } + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 3 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + test_position = test_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(3, test_position->text_offset()); + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 4 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + test_position = test_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(5, test_position->text_offset()); + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 9 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + test_position = test_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(9, test_position->text_offset()); + EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, test_position->affinity()); + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 10 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + test_position = test_position->CreateNextCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(12, test_position->text_offset()); + // Affinity should have been reset to downstream because there was a move. + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); } TEST_F(AXPositionTest, CreatePreviousCharacterPositionAtGraphemeBoundary) { @@ -4094,6 +4199,51 @@ EXPECT_EQ(text_offset, test_position->text_offset()); EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); } + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 3 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + test_position = test_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(3, test_position->text_offset()); + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 4 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + test_position = test_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(3, test_position->text_offset()); + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 9 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + test_position = test_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(9, test_position->text_offset()); + EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, test_position->affinity()); + + test_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, new_tree->root()->id(), 10 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + test_position = test_position->CreatePreviousCharacterPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + ASSERT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(new_tree->root()->id(), test_position->anchor_id()); + EXPECT_EQ(9, test_position->text_offset()); + // Affinity should have been reset to downstream because there was a move. + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); } TEST_F(AXPositionTest, ReciprocalCreateNextAndPreviousCharacterPosition) {
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index 6143953..d53d8e8 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -1541,8 +1541,6 @@ // See also http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries AXPositionInstance CreateNextCharacterPosition( AXBoundaryBehavior boundary_behavior) const { - DCHECK_NE(boundary_behavior, AXBoundaryBehavior::StopIfAlreadyAtBoundary) - << "StopIfAlreadyAtBoundary is unreasonable for character boundaries."; if (boundary_behavior == AXBoundaryBehavior::StopAtAnchorBoundary && AtEndOfAnchor()) { return Clone(); @@ -1553,11 +1551,18 @@ // There is no next character position. if (text_position->IsNullPosition()) { - if (boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary) + if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary || + boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary) { text_position = Clone(); + } return text_position; } + if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary && + *text_position == *this) { + return Clone(); + } + DCHECK_LT(text_position->text_offset_, text_position->MaxTextOffset()); std::unique_ptr<base::i18n::BreakIterator> grapheme_iterator = text_position->GetGraphemeIterator(); @@ -1598,8 +1603,6 @@ // grapheme cluster. AXPositionInstance CreatePreviousCharacterPosition( AXBoundaryBehavior boundary_behavior) const { - DCHECK_NE(boundary_behavior, AXBoundaryBehavior::StopIfAlreadyAtBoundary) - << "StopIfAlreadyAtBoundary is unreasonable for character boundaries."; if (boundary_behavior == AXBoundaryBehavior::StopAtAnchorBoundary && AtStartOfAnchor()) { return Clone(); @@ -1610,11 +1613,18 @@ // There is no previous character position. if (text_position->IsNullPosition()) { - if (boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary) + if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary || + boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary) { text_position = Clone(); + } return text_position; } + if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary && + *text_position == *this) { + return Clone(); + } + DCHECK_GT(text_position->text_offset_, 0); std::unique_ptr<base::i18n::BreakIterator> grapheme_iterator = text_position->GetGraphemeIterator(); @@ -2600,7 +2610,7 @@ // platform's text representation. Some platforms use an embedded object // character that replaces the text coming from each child node. // - // Similar to "text_offset_", the length of the text is in Unicode code units, + // Similar to "text_offset_", the length of the text is in UTF16 code units, // not in grapheme clusters. virtual int MaxTextOffset() const { if (IsNullPosition()) @@ -3214,7 +3224,7 @@ // For text positions, |child_index_| is initially set to |-1| and only // computed on demand. The same with tree positions and |text_offset_|. int child_index_; - // "text_offset_" represents the number of Unicode code units before this + // "text_offset_" represents the number of UTF16 code units before this // position. It doesn't count grapheme clusters. int text_offset_;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 241412e..c431d1e 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -982,10 +982,6 @@ AtkTextBoundary atk_boundary, int* start_offset, int* end_offset) { - if (atk_boundary == ATK_TEXT_BOUNDARY_CHAR) { - return GetCharacter(atk_text, offset, start_offset, end_offset); - } - AXTextBoundary boundary = FromAtkTextBoundary(atk_boundary); return GetTextWithBoundaryType(atk_text, offset, boundary, start_offset, end_offset); @@ -1130,10 +1126,6 @@ *start_offset = -1; *end_offset = -1; - if (atk_granularity == ATK_TEXT_GRANULARITY_CHAR) { - return GetCharacter(atk_text, offset, start_offset, end_offset); - } - AXTextBoundary boundary = FromAtkTextGranularity(atk_granularity); return GetTextWithBoundaryType(atk_text, offset, boundary, start_offset, end_offset);
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc index fe973d51..145c045 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -1105,8 +1105,8 @@ }; verify_text_at_offset("d", 2, 2, 3); - verify_text_at_offset(nullptr, -1, -1, -1); - verify_text_at_offset(nullptr, 42342, -1, -1); + verify_text_at_offset(nullptr, -1, 0, 0); + verify_text_at_offset(nullptr, 42342, 0, 0); verify_text_at_offset("\xE2\x98\xBA", 23, 23, 24); verify_text_at_offset(" ", 24, 24, 25);
diff --git a/ui/views/color_chooser/color_chooser_view.cc b/ui/views/color_chooser/color_chooser_view.cc index 3427ed0d..18664492 100644 --- a/ui/views/color_chooser/color_chooser_view.cc +++ b/ui/views/color_chooser/color_chooser_view.cc
@@ -56,8 +56,8 @@ std::string input = base::UTF16ToUTF8((text.size() == 6) ? text : text.substr(1)); - std::vector<uint8_t> hex; - if (!base::HexStringToBytes(input, &hex)) + std::array<uint8_t, 3> hex; + if (!base::HexStringToSpan(input, hex)) return false; *result = SkColorSetRGB(hex[0], hex[1], hex[2]);
diff --git a/ui/views/style/platform_style.cc b/ui/views/style/platform_style.cc index ec2a05cf..6aa6dc4 100644 --- a/ui/views/style/platform_style.cc +++ b/ui/views/style/platform_style.cc
@@ -49,7 +49,7 @@ const bool PlatformStyle::kUseRipples = true; const bool PlatformStyle::kTextfieldScrollsToStartOnFocusChange = false; const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = true; -const bool PlatformStyle::kPreferFocusRings = false; +const bool PlatformStyle::kPreferFocusRings = true; const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = false; // static
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/fake_mojo_service.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/fake_mojo_service.js index ee018bb..801feec 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/fake_mojo_service.js +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/fake_mojo_service.js
@@ -52,6 +52,21 @@ } /** @override */ + getEligibleActiveHostDevices() { + const deviceNames = ['Pixel', 'Pixel XL', 'Nexus 5', 'Nexus 6P']; + const devices = []; + for (let i = 0; i < this.deviceCount; i++) { + const deviceName = deviceNames[i % 4]; + devices.push({ + remoteDevice: {deviceName: deviceName, deviceId: deviceName + '--' + i} + }); + } + return new Promise(function(resolve, reject) { + resolve({eligibleHostDevices: devices}); + }); + } + + /** @override */ setHostDevice(deviceId) { if (this.shouldSetHostSucceed) { console.log(
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn index 86884bd..4e1b9bf 100644 --- a/weblayer/browser/java/BUILD.gn +++ b/weblayer/browser/java/BUILD.gn
@@ -73,10 +73,6 @@ # Needed for android.webkit.WebView(Delegate|Factory) alternative_android_sdk_dep = "//third_party/android_sdk:public_framework_system_java" - - # TODO(timvolodine): once the downstream implementation of GmsBridgeImpl.java - # lands make sure to exclude this when "enable_chrome_android_internal" is true. - deps += [ ":gms_bridge_upstream_impl_java" ] } generate_jni("jni") {
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java index a5d7e70..8ece480 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
@@ -74,6 +74,32 @@ void surfaceDestroyed(boolean cacheBackBuffer); } + private final ArrayList<TrackedRunnable> mPendingRunnables = new ArrayList<>(); + + // Runnables posted via View.postOnAnimation may not run after the view is detached, + // if nothing else causes animation. However a pending runnable may held by a GC root + // from the thread itself, and thus can cause leaks. This class here is so ensure that + // on destroy, all pending tasks are run immediately so they do not lead to leaks. + private abstract class TrackedRunnable implements Runnable { + private boolean mHasRun; + public TrackedRunnable() { + mPendingRunnables.add(this); + } + + @Override + public final void run() { + // View.removeCallbacks is not always reliable, and may run the callback even + // after it has been removed. + if (mHasRun) return; + assert mPendingRunnables.contains(this); + mPendingRunnables.remove(this); + mHasRun = true; + doRun(); + } + + protected abstract void doRun(); + } + // Non-static implementation of SurfaceEventListener that forward calls to native Compositor. // It is also responsible for updating |mRequested| and |mCurrent|. private class SurfaceEventListenerImpl implements SurfaceEventListener { @@ -122,7 +148,7 @@ // Abstract differences between SurfaceView and TextureView behind this class. // Also responsible for holding and calling callbacks. - private static class SurfaceData implements SurfaceEventListener { + private class SurfaceData implements SurfaceEventListener { private class TextureViewWithInvalidate extends TextureView { public TextureViewWithInvalidate(Context context) { super(context); @@ -213,16 +239,19 @@ } // This postOnAnimation is to avoid manipulating the view tree inside layout or draw. - parent.postOnAnimation(() -> { - if (mMarkedForDestroy) return; - View view = (mMode == MODE_SURFACE_VIEW) ? mSurfaceView : mTextureView; - assert view != null; - // Always insert view for new surface below the existing view to avoid artifacts - // during surface swaps. Index 0 is the lowest child. - mParent.addView(view, 0, - new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.MATCH_PARENT)); - mParent.invalidate(); + parent.postOnAnimation(new TrackedRunnable() { + @Override + protected void doRun() { + if (mMarkedForDestroy) return; + View view = (mMode == MODE_SURFACE_VIEW) ? mSurfaceView : mTextureView; + assert view != null; + // Always insert view for new surface below the existing view to avoid artifacts + // during surface swaps. Index 0 is the lowest child. + mParent.addView(view, 0, + new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT)); + mParent.invalidate(); + } }); } @@ -272,34 +301,47 @@ assert mMarkedForDestroy; runCallbacks(); // This postOnAnimation is to avoid manipulating the view tree inside layout or draw. - mParent.postOnAnimation(() -> { - if (mMode == MODE_SURFACE_VIEW) { - // Detaching a SurfaceView causes a flicker because the SurfaceView tears down - // the Surface in SurfaceFlinger before removing its hole in the view tree. - // This is a complicated heuristics to avoid this. It first moves the - // SurfaceView behind the new View. Then wait two frames before detaching - // the SurfaceView. Waiting for a single frame still causes flickers on - // high end devices like Pixel 3. - moveChildToBackWithoutDetach(mParent, mSurfaceView); - mParent.postOnAnimation(() -> mParent.postOnAnimation(() -> { - mParent.removeView(mSurfaceView); - mParent.invalidate(); - if (mCachedSurfaceNeedsEviction) { - mEvict.run(); - mCachedSurfaceNeedsEviction = false; - } + mParent.postOnAnimation(new TrackedRunnable() { + @Override + protected void doRun() { + if (mMode == MODE_SURFACE_VIEW) { + // Detaching a SurfaceView causes a flicker because the SurfaceView tears + // down the Surface in SurfaceFlinger before removing its hole in the view + // tree. This is a complicated heuristics to avoid this. It first moves the + // SurfaceView behind the new View. Then wait two frames before detaching + // the SurfaceView. Waiting for a single frame still causes flickers on + // high end devices like Pixel 3. + moveChildToBackWithoutDetach(mParent, mSurfaceView); + TrackedRunnable inner = new TrackedRunnable() { + @Override + public void doRun() { + mParent.removeView(mSurfaceView); + mParent.invalidate(); + if (mCachedSurfaceNeedsEviction) { + mEvict.run(); + mCachedSurfaceNeedsEviction = false; + } + runCallbackOnNextSurfaceData(); + } + }; + TrackedRunnable outer = new TrackedRunnable() { + @Override + public void doRun() { + mParent.postOnAnimation(inner); + } + }; + mParent.postOnAnimation(outer); + } else if (mMode == MODE_TEXTURE_VIEW) { + mParent.removeView(mTextureView); runCallbackOnNextSurfaceData(); - })); - } else if (mMode == MODE_TEXTURE_VIEW) { - mParent.removeView(mTextureView); - runCallbackOnNextSurfaceData(); - } else { - assert false; + } else { + assert false; + } } }); } - private static void moveChildToBackWithoutDetach(ViewGroup parent, View child) { + private void moveChildToBackWithoutDetach(ViewGroup parent, View child) { final int numberOfChildren = parent.getChildCount(); final int childIndex = parent.indexOfChild(child); if (childIndex <= 0) return; @@ -593,6 +635,13 @@ mCurrent = null; mWindowAndroid = null; + + while (!mPendingRunnables.isEmpty()) { + TrackedRunnable runnable = mPendingRunnables.get(0); + removeCallbacks(runnable); + runnable.run(); + assert !mPendingRunnables.contains(runnable); + } ContentViewRenderViewJni.get().destroy(mNativeContentViewRenderView); mNativeContentViewRenderView = 0; }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java index e3579fa..79aafa4 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java
@@ -14,6 +14,7 @@ import org.chromium.weblayer_private.interfaces.INavigation; import org.chromium.weblayer_private.interfaces.INavigationControllerClient; +import java.util.Arrays; import java.util.List; @JNINamespace("weblayer") @@ -51,7 +52,8 @@ @Override public List<String> getRedirectChain() { throwIfNativeDestroyed(); - return NavigationImplJni.get().getRedirectChain(mNativeNavigationImpl, NavigationImpl.this); + return Arrays.asList(NavigationImplJni.get().getRedirectChain( + mNativeNavigationImpl, NavigationImpl.this)); } @Override @@ -77,7 +79,7 @@ void setJavaNavigation(long nativeNavigationImpl, NavigationImpl caller); int getState(long nativeNavigationImpl, NavigationImpl caller); String getUri(long nativeNavigationImpl, NavigationImpl caller); - List<String> getRedirectChain(long nativeNavigationImpl, NavigationImpl caller); + String[] getRedirectChain(long nativeNavigationImpl, NavigationImpl caller); boolean isSameDocument(long nativeNavigationImpl, NavigationImpl caller); } }
diff --git a/weblayer/browser/navigation_impl.cc b/weblayer/browser/navigation_impl.cc index aa9069a..073f043d 100644 --- a/weblayer/browser/navigation_impl.cc +++ b/weblayer/browser/navigation_impl.cc
@@ -45,7 +45,7 @@ base::android::ConvertUTF8ToJavaString(env, GetURL().spec())); } -ScopedJavaLocalRef<jobject> NavigationImpl::GetRedirectChain( +ScopedJavaLocalRef<jobjectArray> NavigationImpl::GetRedirectChain( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj) { std::vector<std::string> jni_redirects;
diff --git a/weblayer/browser/navigation_impl.h b/weblayer/browser/navigation_impl.h index 3ce76982..362c0c4 100644 --- a/weblayer/browser/navigation_impl.h +++ b/weblayer/browser/navigation_impl.h
@@ -34,7 +34,7 @@ base::android::ScopedJavaLocalRef<jstring> GetUri( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - base::android::ScopedJavaLocalRef<jobject> GetRedirectChain( + base::android::ScopedJavaLocalRef<jobjectArray> GetRedirectChain( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); bool IsSameDocument(JNIEnv* env,
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn index 7028929..fc311d2 100644 --- a/weblayer/shell/android/BUILD.gn +++ b/weblayer/shell/android/BUILD.gn
@@ -165,6 +165,10 @@ "//mojo/public/java:system_java", "//net/android:net_java", ] + + # default upstream safebrowsing related classes + deps += [ "//weblayer/browser/java:gms_bridge_upstream_impl_java" ] + apk_name = "WebLayerSupport" android_manifest = weblayer_support_manifest min_sdk_version = 21
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java index 622c1e6..a03b913 100644 --- a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java +++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java
@@ -28,6 +28,7 @@ import org.chromium.weblayer.shell.InstrumentationActivity; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeoutException; @@ -50,15 +51,12 @@ public static class NavigationCallbackHelper extends CallbackHelper { private Uri mUri; private boolean mIsSameDocument; + private List<Uri> mRedirectChain; - public void notifyCalled(Uri uri) { - mUri = uri; - notifyCalled(); - } - - public void notifyCalled(Uri uri, boolean isSameDocument) { - mUri = uri; - mIsSameDocument = isSameDocument; + public void notifyCalled(Navigation navigation) { + mUri = navigation.getUri(); + mIsSameDocument = navigation.isSameDocument(); + mRedirectChain = navigation.getRedirectChain(); notifyCalled(); } @@ -73,6 +71,12 @@ assertEquals(mUri.toString(), uri); assertEquals(mIsSameDocument, isSameDocument); } + + public void assertCalledWith(int currentCallCount, List<Uri> redirectChain) + throws TimeoutException { + waitForCallback(currentCallCount); + assertEquals(mRedirectChain, redirectChain); + } } public static class NavigationCallbackValueRecorder { @@ -101,8 +105,10 @@ } public NavigationCallbackHelper onStartedCallback = new NavigationCallbackHelper(); + public NavigationCallbackHelper onRedirectedCallback = new NavigationCallbackHelper(); public NavigationCallbackHelper onReadyToCommitCallback = new NavigationCallbackHelper(); public NavigationCallbackHelper onCompletedCallback = new NavigationCallbackHelper(); + public NavigationCallbackHelper onFailedCallback = new NavigationCallbackHelper(); public NavigationCallbackValueRecorder loadStateChangedCallback = new NavigationCallbackValueRecorder(); public NavigationCallbackValueRecorder loadProgressChangedCallback = @@ -111,17 +117,27 @@ @Override public void onNavigationStarted(Navigation navigation) { - onStartedCallback.notifyCalled(navigation.getUri()); + onStartedCallback.notifyCalled(navigation); + } + + @Override + public void onNavigationRedirected(Navigation navigation) { + onRedirectedCallback.notifyCalled(navigation); } @Override public void onReadyToCommitNavigation(Navigation navigation) { - onReadyToCommitCallback.notifyCalled(navigation.getUri()); + onReadyToCommitCallback.notifyCalled(navigation); } @Override public void onNavigationCompleted(Navigation navigation) { - onCompletedCallback.notifyCalled(navigation.getUri(), navigation.isSameDocument()); + onCompletedCallback.notifyCalled(navigation); + } + + @Override + public void onNavigationFailed(Navigation navigation) { + onFailedCallback.notifyCalled(navigation); } @Override @@ -248,6 +264,83 @@ curCompletedCount, "data:text,foo#bar", true); } + @Test + @SmallTest + public void testReload() throws Exception { + InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(URL1); + setNavigationCallback(activity); + + navigateAndWaitForCompletion( + URL1, () -> { activity.getTab().getNavigationController().reload(); }); + } + + @Test + @SmallTest + public void testStop() throws Exception { + InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(URL1); + setNavigationCallback(activity); + + int curFailedCount = mCallback.onFailedCallback.getCallCount(); + + runOnUiThreadBlocking(() -> { + NavigationController navigationController = activity.getTab().getNavigationController(); + navigationController.registerNavigationCallback(new NavigationCallback() { + @Override + public void onNavigationStarted(Navigation navigation) { + navigationController.stop(); + } + }); + navigationController.navigate(Uri.parse(URL2)); + }); + + mCallback.onFailedCallback.assertCalledWith(curFailedCount, URL2); + } + + @Test + @SmallTest + public void testRedirect() throws Exception { + InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(URL1); + setNavigationCallback(activity); + + int curRedirectedCount = mCallback.onRedirectedCallback.getCallCount(); + + String finalUrl = mActivityTestRule.getTestServer().getURL("/echo"); + String url = mActivityTestRule.getTestServer().getURL("/server-redirect?" + finalUrl); + navigateAndWaitForCompletion(finalUrl, + () -> { activity.getTab().getNavigationController().navigate(Uri.parse(url)); }); + + mCallback.onRedirectedCallback.assertCalledWith( + curRedirectedCount, Arrays.asList(Uri.parse(url), Uri.parse(finalUrl))); + } + + @Test + @SmallTest + public void testNavigationList() throws Exception { + InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(URL1); + setNavigationCallback(activity); + + mActivityTestRule.navigateAndWait(URL2); + mActivityTestRule.navigateAndWait(URL3); + + NavigationController navigationController = + runOnUiThreadBlocking(() -> activity.getTab().getNavigationController()); + + runOnUiThreadBlocking(() -> { + assertEquals(3, navigationController.getNavigationListSize()); + assertEquals(2, navigationController.getNavigationListCurrentIndex()); + assertEquals(URL1, navigationController.getNavigationEntryDisplayUri(0).toString()); + assertEquals(URL2, navigationController.getNavigationEntryDisplayUri(1).toString()); + assertEquals(URL3, navigationController.getNavigationEntryDisplayUri(2).toString()); + }); + + navigateAndWaitForCompletion(URL2, () -> { navigationController.goBack(); }); + + runOnUiThreadBlocking(() -> { + assertEquals(3, navigationController.getNavigationListSize()); + assertEquals(1, navigationController.getNavigationListCurrentIndex()); + }); + } + private void setNavigationCallback(InstrumentationActivity activity) { runOnUiThreadBlocking( ()
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/SmokeTest.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/SmokeTest.java index 6d532857c..f7a0d56 100644 --- a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/SmokeTest.java +++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/SmokeTest.java
@@ -12,9 +12,14 @@ import org.junit.runner.RunWith; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.content_public.browser.test.util.Criteria; +import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.weblayer.shell.InstrumentationActivity; +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; import java.util.concurrent.CountDownLatch; @RunWith(BaseJUnit4ClassRunner.class) @@ -48,4 +53,34 @@ } mActivityTestRule.navigateAndWait(url); } + + @Test + @SmallTest + public void testActivityShouldNotLeak() { + ReferenceQueue<InstrumentationActivity> referenceQueue = new ReferenceQueue<>(); + PhantomReference<InstrumentationActivity> reference; + { + InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank"); + mActivityTestRule.recreateActivity(); + boolean destroyed = + TestThreadUtils.runOnUiThreadBlockingNoException(() -> activity.isDestroyed()); + Assert.assertTrue(destroyed); + + reference = new PhantomReference<>(activity, referenceQueue); + } + + Runtime.getRuntime().gc(); + CriteriaHelper.pollInstrumentationThread(new Criteria() { + @Override + public boolean isSatisfied() { + Reference enqueuedReference = referenceQueue.poll(); + if (enqueuedReference == null) { + Runtime.getRuntime().gc(); + return false; + } + Assert.assertEquals(reference, enqueuedReference); + return true; + } + }); + } }
diff --git a/weblayer/test/BUILD.gn b/weblayer/test/BUILD.gn index db48205..815e774 100644 --- a/weblayer/test/BUILD.gn +++ b/weblayer/test/BUILD.gn
@@ -122,7 +122,11 @@ # Needed for WebLayerImpl. "//weblayer/browser/java", + + # default upstream safebrowsing related classes + "//weblayer/browser/java:gms_bridge_upstream_impl_java", ] + android_manifest = "${target_gen_dir}/weblayer_browsertests_manifest/AndroidManifest.xml" android_manifest_dep = ":weblayer_browsertests_manifest"