/media/gpu/android/surface_chooser_helper_unittest.cc
C++ | 297 lines | 196 code | 55 blank | 46 comment | 1 complexity | 326f194ab4f51446b49cac4a8b2051b0 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.0, BSD-2-Clause, LGPL-2.1, MPL-2.0, 0BSD, EPL-1.0, MPL-2.0-no-copyleft-exception, GPL-2.0, BitTorrent-1.0, CPL-1.0, LGPL-3.0, Unlicense, BSD-3-Clause, CC0-1.0, JSON, MIT, GPL-3.0, CC-BY-SA-3.0, AGPL-1.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/gpu/android/surface_chooser_helper.h"
- #include <stdint.h>
- #include <memory>
- #include "base/bind.h"
- #include "base/test/simple_test_tick_clock.h"
- #include "media/gpu/android/mock_android_video_surface_chooser.h"
- #include "media/gpu/android/mock_promotion_hint_aggregator.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using base::TimeDelta;
- using testing::_;
- using testing::AtLeast;
- namespace media {
- // Unit tests for PromotionHintAggregatorImplTest
- class SurfaceChooserHelperTest : public testing::Test {
- public:
- ~SurfaceChooserHelperTest() override {}
- void SetUp() override {
- // Create a default helper.
- ReplaceHelper(false, false);
- }
- void TearDown() override {}
- void ReplaceHelper(bool is_overlay_required,
- bool promote_aggressively,
- bool always_use_texture_owner = false) {
- // Advance the clock so that time 0 isn't recent.
- tick_clock_.Advance(TimeDelta::FromSeconds(10000));
- std::unique_ptr<MockAndroidVideoSurfaceChooser> chooser =
- std::make_unique<MockAndroidVideoSurfaceChooser>();
- chooser_ = chooser.get();
- std::unique_ptr<MockPromotionHintAggregator> aggregator =
- std::make_unique<MockPromotionHintAggregator>();
- aggregator_ = aggregator.get();
- helper_ = std::make_unique<SurfaceChooserHelper>(
- std::move(chooser), is_overlay_required, promote_aggressively,
- always_use_texture_owner, std::move(aggregator), &tick_clock_);
- }
- // Convenience function.
- void UpdateChooserState() {
- EXPECT_CALL(*chooser_, MockUpdateState());
- helper_->UpdateChooserState(base::Optional<AndroidOverlayFactoryCB>());
- }
- base::SimpleTestTickClock tick_clock_;
- MockPromotionHintAggregator* aggregator_ = nullptr;
- MockAndroidVideoSurfaceChooser* chooser_ = nullptr;
- std::unique_ptr<SurfaceChooserHelper> helper_;
- };
- TEST_F(SurfaceChooserHelperTest, SetIsFullscreen) {
- // Entering fullscreen should expect relayout.
- helper_->SetIsFullscreen(true);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.is_fullscreen);
- ASSERT_TRUE(chooser_->current_state_.is_expecting_relayout);
- // Exiting fullscreen should not reset the expecting layout flag.
- helper_->SetIsFullscreen(false);
- UpdateChooserState();
- ASSERT_FALSE(chooser_->current_state_.is_fullscreen);
- // We don't really care if it sets expecting_relayout, clears it, or not.
- }
- TEST_F(SurfaceChooserHelperTest, SetVideoRotation) {
- // VideoRotation should be forwarded to the chooser.
- helper_->SetVideoRotation(VIDEO_ROTATION_90);
- UpdateChooserState();
- ASSERT_EQ(chooser_->current_state_.video_rotation, VIDEO_ROTATION_90);
- }
- TEST_F(SurfaceChooserHelperTest, SetIsPersistentVideo) {
- helper_->SetIsPersistentVideo(true);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.is_persistent_video);
- helper_->SetIsPersistentVideo(false);
- UpdateChooserState();
- ASSERT_FALSE(chooser_->current_state_.is_persistent_video);
- }
- TEST_F(SurfaceChooserHelperTest, SetIsOverlayRequired) {
- // The default helper was created without |is_required|, so verify that.
- UpdateChooserState();
- ASSERT_FALSE(chooser_->current_state_.is_required);
- ReplaceHelper(true, false);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.is_required);
- }
- TEST_F(SurfaceChooserHelperTest, SetInsecureSurface) {
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
- UpdateChooserState();
- ASSERT_FALSE(chooser_->current_state_.is_secure);
- ASSERT_FALSE(chooser_->current_state_.is_required);
- }
- TEST_F(SurfaceChooserHelperTest, SetRequestedSecureSurface) {
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kRequested);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.is_secure);
- ASSERT_FALSE(chooser_->current_state_.is_required);
- }
- TEST_F(SurfaceChooserHelperTest, SetRequiredSecureSurface) {
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kRequired);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.is_secure);
- ASSERT_TRUE(chooser_->current_state_.is_required);
- // Also check that removing kRequired puts |is_required| back, since that has
- // special processing for "always required".
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
- UpdateChooserState();
- ASSERT_FALSE(chooser_->current_state_.is_required);
- }
- TEST_F(SurfaceChooserHelperTest, StillRequiredAfterClearingSecure) {
- // Verify that setting then clearing kRequired doesn't make |is_required|
- // false if overlays were required during construction.
- ReplaceHelper(true, false);
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kRequired);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.is_required);
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
- UpdateChooserState();
- // Should still be true.
- ASSERT_TRUE(chooser_->current_state_.is_required);
- }
- TEST_F(SurfaceChooserHelperTest, SetPromoteAggressively) {
- UpdateChooserState();
- ASSERT_FALSE(chooser_->current_state_.promote_aggressively);
- ReplaceHelper(false, true);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.promote_aggressively);
- }
- TEST_F(SurfaceChooserHelperTest, SetAlwaysUseTextureOwner) {
- UpdateChooserState();
- ASSERT_FALSE(chooser_->current_state_.always_use_texture_owner);
- ReplaceHelper(false, true, true);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.always_use_texture_owner);
- }
- TEST_F(SurfaceChooserHelperTest, PromotionHintsForwardsHint) {
- // Make sure that NotifyPromotionHint relays the hint to the aggregator.
- PromotionHintAggregator::Hint hint(gfx::Rect(1, 2, 3, 4), false);
- EXPECT_CALL(*aggregator_, NotifyPromotionHint(hint));
- helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
- }
- TEST_F(SurfaceChooserHelperTest, PromotionHintsRelayPosition) {
- // Make sure that the overlay position is sent to the chooser.
- gfx::Rect rect(0, 1, 2, 3);
- // Send an unpromotable hint and verify that the state reflects it. We set
- // it to be promotable so that it notifies the chooser.
- helper_->NotifyPromotionHintAndUpdateChooser(
- PromotionHintAggregator::Hint(rect, true), false);
- ASSERT_EQ(chooser_->current_state_.initial_position, rect);
- }
- TEST_F(SurfaceChooserHelperTest, PromotionHintsRelayPromotable) {
- // Make sure that the promotability state is forwarded to the chooser.
- EXPECT_CALL(*chooser_, MockUpdateState()).Times(AtLeast(1));
- PromotionHintAggregator::Hint hint(gfx::Rect(), false);
- // Send a hint while the aggregator says it's unpromotable, and verify that
- // the state reflects it.
- helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
- ASSERT_FALSE(chooser_->current_state_.is_compositor_promotable);
- // Send a promotable hint and check the state. Note that the hint has nothing
- // to do with it; it's the aggregator's state.
- aggregator_->SetIsSafeToPromote(true);
- helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
- ASSERT_TRUE(chooser_->current_state_.is_compositor_promotable);
- }
- TEST_F(SurfaceChooserHelperTest, PromotionHintsClearRelayoutFlag) {
- // Set fullscreen to enable relayout.
- helper_->SetIsFullscreen(true);
- UpdateChooserState();
- ASSERT_TRUE(chooser_->current_state_.is_expecting_relayout);
- // Send a bunch of hints.
- EXPECT_CALL(*chooser_, MockUpdateState()).Times(AtLeast(1));
- for (int i = 0; i < 15; i++) {
- PromotionHintAggregator::Hint hint(gfx::Rect(), false);
- helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
- }
- // It should no longer be expecting fs.
- ASSERT_FALSE(chooser_->current_state_.is_expecting_relayout);
- }
- TEST_F(SurfaceChooserHelperTest, PromotionHintsUpdateChooserStatePeriodically) {
- // Verify that, if enough time passes, we'll get chooser updates if we want
- // and overlay but don't have one.
- PromotionHintAggregator::Hint hint(gfx::Rect(), false);
- // Sending the first hint should update the chooser, since we're becoming
- // safe to promote.
- aggregator_->SetIsSafeToPromote(true);
- EXPECT_CALL(*chooser_, MockUpdateState()).Times(1);
- helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
- // Sending an additional hint should not, whether or not we're using an
- // overlay currently.
- EXPECT_CALL(*chooser_, MockUpdateState()).Times(0);
- helper_->NotifyPromotionHintAndUpdateChooser(hint, true);
- EXPECT_CALL(*chooser_, MockUpdateState()).Times(0);
- helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
- // Advancing the time and using an overlay should not send a hint.
- tick_clock_.Advance(base::TimeDelta::FromSeconds(10));
- EXPECT_CALL(*chooser_, MockUpdateState()).Times(0);
- helper_->NotifyPromotionHintAndUpdateChooser(hint, true);
- // If we're not using an overlay, then it should update the chooser to see
- // if it's willing to try for one now.
- EXPECT_CALL(*chooser_, MockUpdateState()).Times(1);
- helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
- }
- TEST_F(SurfaceChooserHelperTest, FrameInformationIsCorrectForL1) {
- // Verify L1 cases.
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kRequired);
- ASSERT_EQ(SurfaceChooserHelper::FrameInformation::OVERLAY_L1,
- helper_->ComputeFrameInformation(true));
- // We don't check the "not using overlay" case; it's unclear what we should be
- // doing in this case anyway.
- }
- TEST_F(SurfaceChooserHelperTest, FrameInformationIsCorrectForL3) {
- // Verify L3 cases.
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kRequested);
- ASSERT_EQ(SurfaceChooserHelper::FrameInformation::OVERLAY_L3,
- helper_->ComputeFrameInformation(true));
- ASSERT_EQ(SurfaceChooserHelper::FrameInformation::NON_OVERLAY_L3,
- helper_->ComputeFrameInformation(false));
- }
- TEST_F(SurfaceChooserHelperTest, FrameInformationIsCorrectForInsecure) {
- // Verify insecure cases.
- helper_->SetSecureSurfaceMode(
- SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
- // Not using an overlay should be NON_OVERLAY_INSECURE
- ASSERT_EQ(SurfaceChooserHelper::FrameInformation::NON_OVERLAY_INSECURE,
- helper_->ComputeFrameInformation(false));
- // Fullscreen state should affect the result, so that we can tell the
- // difference between player-element-fs and div-fs (custom controls).
- helper_->SetIsFullscreen(true);
- ASSERT_EQ(SurfaceChooserHelper::FrameInformation::
- OVERLAY_INSECURE_PLAYER_ELEMENT_FULLSCREEN,
- helper_->ComputeFrameInformation(true));
- helper_->SetIsFullscreen(false);
- ASSERT_EQ(SurfaceChooserHelper::FrameInformation::
- OVERLAY_INSECURE_NON_PLAYER_ELEMENT_FULLSCREEN,
- helper_->ComputeFrameInformation(true));
- }
- } // namespace media