Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: media/gpu/android_video_surface_chooser_impl_unittest.cc

Issue 2813303003: Add AndroidVideoSurfaceChooser to manage overlays. (Closed)
Patch Set: cl feedback Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
5 #include "media/gpu/android_video_surface_chooser_impl.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10
11 #include "base/bind.h"
12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h"
14 #include "media/base/android/android_overlay_factory.h"
15 #include "media/base/android/mock_android_overlay.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using ::testing::_;
20 using ::testing::AnyNumber;
21 using ::testing::NiceMock;
22 using ::testing::NotNull;
23 using ::testing::Return;
24 using ::testing::StrictMock;
25
26 namespace {
27 using ::media::AndroidOverlay;
28 using ::media::AndroidOverlayFactory;
29 using ::media::MockAndroidOverlay;
30
31 class MockClient {
32 public:
33 MOCK_METHOD1(UseOverlay, void(AndroidOverlay*));
34
35 void UseOverlayImpl(std::unique_ptr<AndroidOverlay> overlay) {
36 UseOverlay(overlay.get());
37
38 // Also take ownership of the overlay, so that it's not destroyed.
39 overlay_ = std::move(overlay);
40 }
41
42 // Note that this won't clear |overlay_|, which is helpful.
43 MOCK_METHOD0(UseSurfaceTexture, void(void));
44 MOCK_METHOD1(StopUsingOverlayImmediately, void(AndroidOverlay*));
45
46 private:
47 std::unique_ptr<AndroidOverlay> overlay_;
48 };
49
50 // Mock factory which will return one overlay.
51 class MockAndroidOverlayFactory : public AndroidOverlayFactory {
52 public:
53 MockAndroidOverlayFactory()
54 : overlay_(base::MakeUnique<MockAndroidOverlay>()),
55 weak_this_factory_(this) {}
56
57 // Called by CreateOverlay.
58 MOCK_METHOD0(MockCreateOverlay, void());
59
60 std::unique_ptr<AndroidOverlay> CreateOverlay(
61 const AndroidOverlay::Config& config) override {
62 MockCreateOverlay();
63
64 // Notify the overlay about the config that was used to create it. We
65 // can't do this during overlay construction since we might want the
66 // overlay to set test expectations.
67 if (overlay_)
68 overlay_->SetConfig(config);
69
70 return std::move(overlay_);
71 }
72
73 // Return the overlay, if we still own it. One the client creates an
74 // overlay, we'll re-assign ownership.
75 MockAndroidOverlay* overlay() { return overlay_.get(); }
76
77 // Set the overlay that we'll provide next, or nullptr.
78 void SetOverlay(std::unique_ptr<MockAndroidOverlay> overlay) {
79 overlay_ = std::move(overlay);
80 }
81
82 base::WeakPtr<MockAndroidOverlayFactory> GetWeakPtr() {
83 return weak_this_factory_.GetWeakPtr();
84 }
85
86 private:
87 std::unique_ptr<MockAndroidOverlay> overlay_;
88
89 base::WeakPtrFactory<MockAndroidOverlayFactory> weak_this_factory_;
90 };
91 } // namespace
92
93 namespace media {
94
95 // Unit tests for AndroidVideoSurfaceChooserImpl
96 class AndroidVideoSurfaceChooserImplTest : public testing::Test {
97 public:
98 ~AndroidVideoSurfaceChooserImplTest() override {}
99
100 void SetUp() override {
101 helper_ = base::MakeUnique<AndroidVideoSurfaceChooserImpl>();
102 factory_ = base::MakeUnique<NiceMock<MockAndroidOverlayFactory>>();
103 factory_weak_ = factory_->GetWeakPtr();
104
105 // We create a destruction observer. By default, the overlay must not be
106 // destroyed until the test completes. Of course, the test may ask the
107 // observer to expect something else.
108 destruction_observer_ = factory_->overlay()->CreateDestructionObserver();
109 destruction_observer_->DoNotAllowDestruction();
110 overlay_callbacks_ = factory_->overlay()->GetCallbacks();
111 }
112
113 void TearDown() override {
114 // If we get this far, the assume that whatever |destruction_observer_|
115 // was looking for should have already happened. We don't want the
116 // lifetime of the observer to matter with respect to the overlay when
117 // checking expectations.
118 // Note that it might already be null.
119 destruction_observer_ = nullptr;
120 }
121
122 void StartHelper(std::unique_ptr<MockAndroidOverlayFactory> factory) {
watk 2017/05/02 22:04:31 many instances of helper
liberato (no reviews please) 2017/05/02 22:31:37 Done.
123 helper_->Initialize(
124 base::Bind(&MockClient::UseOverlayImpl, base::Unretained(&client_)),
125 base::Bind(&MockClient::UseSurfaceTexture, base::Unretained(&client_)),
126 base::Bind(&MockClient::StopUsingOverlayImmediately,
127 base::Unretained(&client_)),
128 std::move(factory));
129 }
130
131 std::unique_ptr<AndroidVideoSurfaceChooserImpl> helper_;
132 StrictMock<MockClient> client_;
133 std::unique_ptr<NiceMock<MockAndroidOverlayFactory>> factory_;
134 base::WeakPtr<MockAndroidOverlayFactory> factory_weak_;
135
136 // Callbacks to control the overlay that will be vended by |factory_|
137 MockAndroidOverlay::Callbacks overlay_callbacks_;
138
139 std::unique_ptr<MockAndroidOverlay::DestructionObserver>
140 destruction_observer_;
141 };
142
143 TEST_F(AndroidVideoSurfaceChooserImplTest,
144 InitializeWithoutFactoryUsesSurfaceTexture) {
145 // Calling Initialize() with no factory should result in a callback to use
146 // surface texture.
147 EXPECT_CALL(client_, UseSurfaceTexture());
148 StartHelper(nullptr);
149 }
150
151 TEST_F(AndroidVideoSurfaceChooserImplTest, ProvideInitialOverlaySuccessfully) {
152 // Providing a factory at startup should result in a switch to overlay. It
153 // should not switch to SurfaceTexture initially, since pre-M requires it.
154 // Note that post-M (especially DS), it might be fine to start with ST. We
155 // just don't differentiate those cases yet in the impl.
156
157 EXPECT_CALL(client_, UseSurfaceTexture()).Times(0);
158 StartHelper(std::move(factory_));
159
160 // Notify the helper that the overlay is ready. Expect that |client_| will
161 // be told to use it.
162 EXPECT_CALL(client_, UseOverlay(NotNull()));
163 overlay_callbacks_.OverlayReady.Run();
164 }
165
166 TEST_F(AndroidVideoSurfaceChooserImplTest,
167 InitializingWithFactoryCreatesOverlay) {
168 // Providing a factory at startup should result in a switch to overlay. It
169 // should not switch to SurfaceTexture initially, since pre-M requires it.
170 // Note that post-M (especially DS), it might be fine to start with ST. We
171 // just don't differentiate those cases yet in the impl.
172
173 // Initially, there should be no callback into |client_|, since we haven't
174 // told |helper_| that the overlay is ready. It should, however, request the
175 // overlay from |factory_|.
176 EXPECT_CALL(*factory_, MockCreateOverlay());
177 StartHelper(std::move(factory_));
178 }
179
180 TEST_F(AndroidVideoSurfaceChooserImplTest,
181 NullInitialOverlayUsesSurfaceTexture) {
182 // If we provide a factory, but it fails to create an overlay, then |client_|
183 // should be notified to use a surface texture.
184
185 EXPECT_CALL(*factory_, MockCreateOverlay());
186 EXPECT_CALL(client_, UseSurfaceTexture());
187 // Replacing the overlay with null will destroy it.
188 destruction_observer_->ExpectDestruction();
189 factory_->SetOverlay(nullptr);
190 StartHelper(std::move(factory_));
191 }
192
193 TEST_F(AndroidVideoSurfaceChooserImplTest,
194 FailedInitialOverlayUsesSurfaceTexture) {
195 // If we provide a factory, but the overlay that it provides returns 'failed',
196 // then |client_| should use surface texture.
197 EXPECT_CALL(*factory_, MockCreateOverlay());
198 StartHelper(std::move(factory_));
199
200 testing::Mock::VerifyAndClearExpectations(&client_);
201 testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
202
203 // The overlay may be destroyed at any time after we send OverlayFailed. It
204 // doesn't have to be destroyed. We just care that it hasn't been destroyed
205 // before now.
206 destruction_observer_ = nullptr;
207 EXPECT_CALL(client_, UseSurfaceTexture());
208 overlay_callbacks_.OverlayFailed.Run();
209 }
210
211 TEST_F(AndroidVideoSurfaceChooserImplTest,
212 OnSurfaceDestroyedSendsNotification) {
213 // If |helper_| is notified about OnSurfaceDestroyed, then |client_| should
214 // also be notified.
215
216 EXPECT_CALL(*factory_, MockCreateOverlay());
217 StartHelper(std::move(factory_));
218 EXPECT_CALL(client_, UseOverlay(NotNull()));
219 overlay_callbacks_.OverlayReady.Run();
220
221 testing::Mock::VerifyAndClearExpectations(&client_);
222 testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
223
224 // Switch to a surface texture. OnSurfaceDestroyed should still be sent.
225 EXPECT_CALL(client_, UseSurfaceTexture());
226 helper_->ReplaceOverlayFactory(nullptr);
227 testing::Mock::VerifyAndClearExpectations(&client_);
228
229 EXPECT_CALL(client_, StopUsingOverlayImmediately(NotNull()));
230 overlay_callbacks_.SurfaceDestroyed.Run();
231 }
232
233 TEST_F(AndroidVideoSurfaceChooserImplTest,
234 OnSurfaceDestroyedSendsNotificationAfterSwitch) {
235 // This tests two things. First:
236 // If |helper_| is notified about OnSurfaceDestroyed, then |client_| should
237 // also be notified even if |helper_| has already told |client_| to transition
238 // to SurfaceTexture. It has no idea if |client_| has actually transitioned,
239 // so it has to notify it to stop immediately, in case it hasn't.
240 // Second:
241 // |helper_| should notify |client_| to switch to surface texture if it
242 // provided an overlay, and the factory is changed. This indicates that
243 // whoever provided the factory is revoking it, so we shouldn't be using
244 // overlays from that factory anymore.
245 // We specifically test overlay => no factory, since |helper_| could elide
246 // multiple calls to switch to surface texture.
247 //
248 // We test these together, since switching the factory is the only way we have
249 // to make |helper_| transition to SurfaceTexture without sending destroyed.
250
251 EXPECT_CALL(*factory_, MockCreateOverlay());
252 StartHelper(std::move(factory_));
253 EXPECT_CALL(client_, UseOverlay(NotNull()));
254 overlay_callbacks_.OverlayReady.Run();
255
256 testing::Mock::VerifyAndClearExpectations(&client_);
257 testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
258
259 // Switch factories, to notify the client back to switch to SurfaceTexture.
260 EXPECT_CALL(client_, UseSurfaceTexture());
261 helper_->ReplaceOverlayFactory(nullptr);
262 testing::Mock::VerifyAndClearExpectations(&client_);
263
264 // Destroy the original surface.
265 EXPECT_CALL(client_, StopUsingOverlayImmediately(NotNull()));
266 overlay_callbacks_.SurfaceDestroyed.Run();
267 }
268
269 TEST_F(AndroidVideoSurfaceChooserImplTest, NullLaterOverlayUsesSurfaceTexture) {
270 // If an overlay factory is provided after startup that returns a null overlay
271 // from CreateOverlay, |helper_| should, at most, notify |client_| to use
272 // SurfaceTexture zero or more times.
273
274 // Start with SurfaceTexture.
275 EXPECT_CALL(client_, UseSurfaceTexture());
276 StartHelper(nullptr);
277 testing::Mock::VerifyAndClearExpectations(&client_);
278
279 // Provide a factory that will return a null overlay.
280 EXPECT_CALL(*factory_, MockCreateOverlay());
281 EXPECT_CALL(client_, UseSurfaceTexture()).Times(AnyNumber());
282 helper_->ReplaceOverlayFactory(std::move(factory_));
283 factory_weak_->SetOverlay(nullptr);
284 }
285
286 TEST_F(AndroidVideoSurfaceChooserImplTest, FailedLaterOverlayDoesNothing) {
287 // If we send an overlay factory that returns an overlay, and that overlay
288 // fails, then the client should not be notified except for zero or more
289 // callbacks to switch to surface texture.
290
291 // Start with SurfaceTexture.
292 EXPECT_CALL(client_, UseSurfaceTexture());
293 StartHelper(nullptr);
294 testing::Mock::VerifyAndClearExpectations(&client_);
295
296 // Provide a factory.
297 EXPECT_CALL(*factory_, MockCreateOverlay());
298 EXPECT_CALL(client_, UseSurfaceTexture()).Times(AnyNumber());
299 helper_->ReplaceOverlayFactory(std::move(factory_));
300 testing::Mock::VerifyAndClearExpectations(&client_);
301
302 // Fail the overlay. We don't care if it's destroyed after that, as long as
303 // it hasn't been destroyed yet.
304 destruction_observer_ = nullptr;
305 overlay_callbacks_.OverlayFailed.Run();
306 }
307
308 TEST_F(AndroidVideoSurfaceChooserImplTest,
309 SuccessfulLaterOverlayNotifiesClient) {
310 // |client_| is notified if we provide a factory that gets an overlay.
311
312 // Start with SurfaceTexture.
313 EXPECT_CALL(client_, UseSurfaceTexture());
314 StartHelper(nullptr);
315 testing::Mock::VerifyAndClearExpectations(&client_);
316
317 // Provide a factory. |helper_| should try to create an overlay. We don't
318 // care if a call to UseSurfaceTexture is elided or not. Note that AVDA will
319 // ignore duplicate calls anyway (MultipleSurfaceTextureCallbacksAreIgnored).
320 EXPECT_CALL(*factory_, MockCreateOverlay());
321 EXPECT_CALL(client_, UseSurfaceTexture()).Times(AnyNumber());
322 helper_->ReplaceOverlayFactory(std::move(factory_));
323 testing::Mock::VerifyAndClearExpectations(&client_);
324 testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
325
326 // Notify |helper_| that the overlay is ready.
327 EXPECT_CALL(client_, UseOverlay(NotNull()));
328 overlay_callbacks_.OverlayReady.Run();
329 }
330
331 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698