PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/media/gpu/android/surface_chooser_helper_unittest.cc

http://github.com/chromium/chromium
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
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/gpu/android/surface_chooser_helper.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include "base/bind.h"
  8. #include "base/test/simple_test_tick_clock.h"
  9. #include "media/gpu/android/mock_android_video_surface_chooser.h"
  10. #include "media/gpu/android/mock_promotion_hint_aggregator.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. using base::TimeDelta;
  13. using testing::_;
  14. using testing::AtLeast;
  15. namespace media {
  16. // Unit tests for PromotionHintAggregatorImplTest
  17. class SurfaceChooserHelperTest : public testing::Test {
  18. public:
  19. ~SurfaceChooserHelperTest() override {}
  20. void SetUp() override {
  21. // Create a default helper.
  22. ReplaceHelper(false, false);
  23. }
  24. void TearDown() override {}
  25. void ReplaceHelper(bool is_overlay_required,
  26. bool promote_aggressively,
  27. bool always_use_texture_owner = false) {
  28. // Advance the clock so that time 0 isn't recent.
  29. tick_clock_.Advance(TimeDelta::FromSeconds(10000));
  30. std::unique_ptr<MockAndroidVideoSurfaceChooser> chooser =
  31. std::make_unique<MockAndroidVideoSurfaceChooser>();
  32. chooser_ = chooser.get();
  33. std::unique_ptr<MockPromotionHintAggregator> aggregator =
  34. std::make_unique<MockPromotionHintAggregator>();
  35. aggregator_ = aggregator.get();
  36. helper_ = std::make_unique<SurfaceChooserHelper>(
  37. std::move(chooser), is_overlay_required, promote_aggressively,
  38. always_use_texture_owner, std::move(aggregator), &tick_clock_);
  39. }
  40. // Convenience function.
  41. void UpdateChooserState() {
  42. EXPECT_CALL(*chooser_, MockUpdateState());
  43. helper_->UpdateChooserState(base::Optional<AndroidOverlayFactoryCB>());
  44. }
  45. base::SimpleTestTickClock tick_clock_;
  46. MockPromotionHintAggregator* aggregator_ = nullptr;
  47. MockAndroidVideoSurfaceChooser* chooser_ = nullptr;
  48. std::unique_ptr<SurfaceChooserHelper> helper_;
  49. };
  50. TEST_F(SurfaceChooserHelperTest, SetIsFullscreen) {
  51. // Entering fullscreen should expect relayout.
  52. helper_->SetIsFullscreen(true);
  53. UpdateChooserState();
  54. ASSERT_TRUE(chooser_->current_state_.is_fullscreen);
  55. ASSERT_TRUE(chooser_->current_state_.is_expecting_relayout);
  56. // Exiting fullscreen should not reset the expecting layout flag.
  57. helper_->SetIsFullscreen(false);
  58. UpdateChooserState();
  59. ASSERT_FALSE(chooser_->current_state_.is_fullscreen);
  60. // We don't really care if it sets expecting_relayout, clears it, or not.
  61. }
  62. TEST_F(SurfaceChooserHelperTest, SetVideoRotation) {
  63. // VideoRotation should be forwarded to the chooser.
  64. helper_->SetVideoRotation(VIDEO_ROTATION_90);
  65. UpdateChooserState();
  66. ASSERT_EQ(chooser_->current_state_.video_rotation, VIDEO_ROTATION_90);
  67. }
  68. TEST_F(SurfaceChooserHelperTest, SetIsPersistentVideo) {
  69. helper_->SetIsPersistentVideo(true);
  70. UpdateChooserState();
  71. ASSERT_TRUE(chooser_->current_state_.is_persistent_video);
  72. helper_->SetIsPersistentVideo(false);
  73. UpdateChooserState();
  74. ASSERT_FALSE(chooser_->current_state_.is_persistent_video);
  75. }
  76. TEST_F(SurfaceChooserHelperTest, SetIsOverlayRequired) {
  77. // The default helper was created without |is_required|, so verify that.
  78. UpdateChooserState();
  79. ASSERT_FALSE(chooser_->current_state_.is_required);
  80. ReplaceHelper(true, false);
  81. UpdateChooserState();
  82. ASSERT_TRUE(chooser_->current_state_.is_required);
  83. }
  84. TEST_F(SurfaceChooserHelperTest, SetInsecureSurface) {
  85. helper_->SetSecureSurfaceMode(
  86. SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
  87. UpdateChooserState();
  88. ASSERT_FALSE(chooser_->current_state_.is_secure);
  89. ASSERT_FALSE(chooser_->current_state_.is_required);
  90. }
  91. TEST_F(SurfaceChooserHelperTest, SetRequestedSecureSurface) {
  92. helper_->SetSecureSurfaceMode(
  93. SurfaceChooserHelper::SecureSurfaceMode::kRequested);
  94. UpdateChooserState();
  95. ASSERT_TRUE(chooser_->current_state_.is_secure);
  96. ASSERT_FALSE(chooser_->current_state_.is_required);
  97. }
  98. TEST_F(SurfaceChooserHelperTest, SetRequiredSecureSurface) {
  99. helper_->SetSecureSurfaceMode(
  100. SurfaceChooserHelper::SecureSurfaceMode::kRequired);
  101. UpdateChooserState();
  102. ASSERT_TRUE(chooser_->current_state_.is_secure);
  103. ASSERT_TRUE(chooser_->current_state_.is_required);
  104. // Also check that removing kRequired puts |is_required| back, since that has
  105. // special processing for "always required".
  106. helper_->SetSecureSurfaceMode(
  107. SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
  108. UpdateChooserState();
  109. ASSERT_FALSE(chooser_->current_state_.is_required);
  110. }
  111. TEST_F(SurfaceChooserHelperTest, StillRequiredAfterClearingSecure) {
  112. // Verify that setting then clearing kRequired doesn't make |is_required|
  113. // false if overlays were required during construction.
  114. ReplaceHelper(true, false);
  115. helper_->SetSecureSurfaceMode(
  116. SurfaceChooserHelper::SecureSurfaceMode::kRequired);
  117. UpdateChooserState();
  118. ASSERT_TRUE(chooser_->current_state_.is_required);
  119. helper_->SetSecureSurfaceMode(
  120. SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
  121. UpdateChooserState();
  122. // Should still be true.
  123. ASSERT_TRUE(chooser_->current_state_.is_required);
  124. }
  125. TEST_F(SurfaceChooserHelperTest, SetPromoteAggressively) {
  126. UpdateChooserState();
  127. ASSERT_FALSE(chooser_->current_state_.promote_aggressively);
  128. ReplaceHelper(false, true);
  129. UpdateChooserState();
  130. ASSERT_TRUE(chooser_->current_state_.promote_aggressively);
  131. }
  132. TEST_F(SurfaceChooserHelperTest, SetAlwaysUseTextureOwner) {
  133. UpdateChooserState();
  134. ASSERT_FALSE(chooser_->current_state_.always_use_texture_owner);
  135. ReplaceHelper(false, true, true);
  136. UpdateChooserState();
  137. ASSERT_TRUE(chooser_->current_state_.always_use_texture_owner);
  138. }
  139. TEST_F(SurfaceChooserHelperTest, PromotionHintsForwardsHint) {
  140. // Make sure that NotifyPromotionHint relays the hint to the aggregator.
  141. PromotionHintAggregator::Hint hint(gfx::Rect(1, 2, 3, 4), false);
  142. EXPECT_CALL(*aggregator_, NotifyPromotionHint(hint));
  143. helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
  144. }
  145. TEST_F(SurfaceChooserHelperTest, PromotionHintsRelayPosition) {
  146. // Make sure that the overlay position is sent to the chooser.
  147. gfx::Rect rect(0, 1, 2, 3);
  148. // Send an unpromotable hint and verify that the state reflects it. We set
  149. // it to be promotable so that it notifies the chooser.
  150. helper_->NotifyPromotionHintAndUpdateChooser(
  151. PromotionHintAggregator::Hint(rect, true), false);
  152. ASSERT_EQ(chooser_->current_state_.initial_position, rect);
  153. }
  154. TEST_F(SurfaceChooserHelperTest, PromotionHintsRelayPromotable) {
  155. // Make sure that the promotability state is forwarded to the chooser.
  156. EXPECT_CALL(*chooser_, MockUpdateState()).Times(AtLeast(1));
  157. PromotionHintAggregator::Hint hint(gfx::Rect(), false);
  158. // Send a hint while the aggregator says it's unpromotable, and verify that
  159. // the state reflects it.
  160. helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
  161. ASSERT_FALSE(chooser_->current_state_.is_compositor_promotable);
  162. // Send a promotable hint and check the state. Note that the hint has nothing
  163. // to do with it; it's the aggregator's state.
  164. aggregator_->SetIsSafeToPromote(true);
  165. helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
  166. ASSERT_TRUE(chooser_->current_state_.is_compositor_promotable);
  167. }
  168. TEST_F(SurfaceChooserHelperTest, PromotionHintsClearRelayoutFlag) {
  169. // Set fullscreen to enable relayout.
  170. helper_->SetIsFullscreen(true);
  171. UpdateChooserState();
  172. ASSERT_TRUE(chooser_->current_state_.is_expecting_relayout);
  173. // Send a bunch of hints.
  174. EXPECT_CALL(*chooser_, MockUpdateState()).Times(AtLeast(1));
  175. for (int i = 0; i < 15; i++) {
  176. PromotionHintAggregator::Hint hint(gfx::Rect(), false);
  177. helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
  178. }
  179. // It should no longer be expecting fs.
  180. ASSERT_FALSE(chooser_->current_state_.is_expecting_relayout);
  181. }
  182. TEST_F(SurfaceChooserHelperTest, PromotionHintsUpdateChooserStatePeriodically) {
  183. // Verify that, if enough time passes, we'll get chooser updates if we want
  184. // and overlay but don't have one.
  185. PromotionHintAggregator::Hint hint(gfx::Rect(), false);
  186. // Sending the first hint should update the chooser, since we're becoming
  187. // safe to promote.
  188. aggregator_->SetIsSafeToPromote(true);
  189. EXPECT_CALL(*chooser_, MockUpdateState()).Times(1);
  190. helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
  191. // Sending an additional hint should not, whether or not we're using an
  192. // overlay currently.
  193. EXPECT_CALL(*chooser_, MockUpdateState()).Times(0);
  194. helper_->NotifyPromotionHintAndUpdateChooser(hint, true);
  195. EXPECT_CALL(*chooser_, MockUpdateState()).Times(0);
  196. helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
  197. // Advancing the time and using an overlay should not send a hint.
  198. tick_clock_.Advance(base::TimeDelta::FromSeconds(10));
  199. EXPECT_CALL(*chooser_, MockUpdateState()).Times(0);
  200. helper_->NotifyPromotionHintAndUpdateChooser(hint, true);
  201. // If we're not using an overlay, then it should update the chooser to see
  202. // if it's willing to try for one now.
  203. EXPECT_CALL(*chooser_, MockUpdateState()).Times(1);
  204. helper_->NotifyPromotionHintAndUpdateChooser(hint, false);
  205. }
  206. TEST_F(SurfaceChooserHelperTest, FrameInformationIsCorrectForL1) {
  207. // Verify L1 cases.
  208. helper_->SetSecureSurfaceMode(
  209. SurfaceChooserHelper::SecureSurfaceMode::kRequired);
  210. ASSERT_EQ(SurfaceChooserHelper::FrameInformation::OVERLAY_L1,
  211. helper_->ComputeFrameInformation(true));
  212. // We don't check the "not using overlay" case; it's unclear what we should be
  213. // doing in this case anyway.
  214. }
  215. TEST_F(SurfaceChooserHelperTest, FrameInformationIsCorrectForL3) {
  216. // Verify L3 cases.
  217. helper_->SetSecureSurfaceMode(
  218. SurfaceChooserHelper::SecureSurfaceMode::kRequested);
  219. ASSERT_EQ(SurfaceChooserHelper::FrameInformation::OVERLAY_L3,
  220. helper_->ComputeFrameInformation(true));
  221. ASSERT_EQ(SurfaceChooserHelper::FrameInformation::NON_OVERLAY_L3,
  222. helper_->ComputeFrameInformation(false));
  223. }
  224. TEST_F(SurfaceChooserHelperTest, FrameInformationIsCorrectForInsecure) {
  225. // Verify insecure cases.
  226. helper_->SetSecureSurfaceMode(
  227. SurfaceChooserHelper::SecureSurfaceMode::kInsecure);
  228. // Not using an overlay should be NON_OVERLAY_INSECURE
  229. ASSERT_EQ(SurfaceChooserHelper::FrameInformation::NON_OVERLAY_INSECURE,
  230. helper_->ComputeFrameInformation(false));
  231. // Fullscreen state should affect the result, so that we can tell the
  232. // difference between player-element-fs and div-fs (custom controls).
  233. helper_->SetIsFullscreen(true);
  234. ASSERT_EQ(SurfaceChooserHelper::FrameInformation::
  235. OVERLAY_INSECURE_PLAYER_ELEMENT_FULLSCREEN,
  236. helper_->ComputeFrameInformation(true));
  237. helper_->SetIsFullscreen(false);
  238. ASSERT_EQ(SurfaceChooserHelper::FrameInformation::
  239. OVERLAY_INSECURE_NON_PLAYER_ELEMENT_FULLSCREEN,
  240. helper_->ComputeFrameInformation(true));
  241. }
  242. } // namespace media