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

Unified Diff: media/gpu/android_video_surface_chooser_impl_unittest.cc

Issue 2813303003: Add AndroidVideoSurfaceChooser to manage overlays. (Closed)
Patch Set: fixed dereference of base::Optional Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/gpu/android_video_surface_chooser_impl.cc ('k') | media/gpu/avda_codec_allocator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/gpu/android_video_surface_chooser_impl_unittest.cc
diff --git a/media/gpu/android_video_surface_chooser_impl_unittest.cc b/media/gpu/android_video_surface_chooser_impl_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b30cfbfeadb3986f885512fcdf724dcdd7c23620
--- /dev/null
+++ b/media/gpu/android_video_surface_chooser_impl_unittest.cc
@@ -0,0 +1,330 @@
+// 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_video_surface_chooser_impl.h"
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "media/base/android/android_overlay_factory.h"
+#include "media/base/android/mock_android_overlay.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::NiceMock;
+using ::testing::NotNull;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace {
+using ::media::AndroidOverlay;
+using ::media::AndroidOverlayFactory;
+using ::media::MockAndroidOverlay;
+
+class MockClient {
+ public:
+ MOCK_METHOD1(UseOverlay, void(AndroidOverlay*));
+
+ void UseOverlayImpl(std::unique_ptr<AndroidOverlay> overlay) {
+ UseOverlay(overlay.get());
+
+ // Also take ownership of the overlay, so that it's not destroyed.
+ overlay_ = std::move(overlay);
+ }
+
+ // Note that this won't clear |overlay_|, which is helpful.
+ MOCK_METHOD0(UseSurfaceTexture, void(void));
+ MOCK_METHOD1(StopUsingOverlayImmediately, void(AndroidOverlay*));
+
+ private:
+ std::unique_ptr<AndroidOverlay> overlay_;
+};
+
+// Mock factory which will return one overlay.
+class MockAndroidOverlayFactory : public AndroidOverlayFactory {
+ public:
+ MockAndroidOverlayFactory()
+ : overlay_(base::MakeUnique<MockAndroidOverlay>()),
+ weak_this_factory_(this) {}
+
+ // Called by CreateOverlay.
+ MOCK_METHOD0(MockCreateOverlay, void());
+
+ std::unique_ptr<AndroidOverlay> CreateOverlay(
+ const AndroidOverlay::Config& config) override {
+ MockCreateOverlay();
+
+ // Notify the overlay about the config that was used to create it. We
+ // can't do this during overlay construction since we might want the
+ // overlay to set test expectations.
+ if (overlay_)
+ overlay_->SetConfig(config);
+
+ return std::move(overlay_);
+ }
+
+ // Return the overlay, if we still own it. One the client creates an
+ // overlay, we'll re-assign ownership.
+ MockAndroidOverlay* overlay() { return overlay_.get(); }
+
+ // Set the overlay that we'll provide next, or nullptr.
+ void SetOverlay(std::unique_ptr<MockAndroidOverlay> overlay) {
+ overlay_ = std::move(overlay);
+ }
+
+ base::WeakPtr<MockAndroidOverlayFactory> GetWeakPtr() {
+ return weak_this_factory_.GetWeakPtr();
+ }
+
+ private:
+ std::unique_ptr<MockAndroidOverlay> overlay_;
+
+ base::WeakPtrFactory<MockAndroidOverlayFactory> weak_this_factory_;
+};
+} // namespace
+
+namespace media {
+
+// Unit tests for AndroidVideoSurfaceChooserImpl
+class AndroidVideoSurfaceChooserImplTest : public testing::Test {
+ public:
+ ~AndroidVideoSurfaceChooserImplTest() override {}
+
+ void SetUp() override {
+ chooser_ = base::MakeUnique<AndroidVideoSurfaceChooserImpl>();
+ factory_ = base::MakeUnique<NiceMock<MockAndroidOverlayFactory>>();
+ factory_weak_ = factory_->GetWeakPtr();
+
+ // We create a destruction observer. By default, the overlay must not be
+ // destroyed until the test completes. Of course, the test may ask the
+ // observer to expect something else.
+ destruction_observer_ = factory_->overlay()->CreateDestructionObserver();
+ destruction_observer_->DoNotAllowDestruction();
+ overlay_callbacks_ = factory_->overlay()->GetCallbacks();
+ }
+
+ void TearDown() override {
+ // If we get this far, the assume that whatever |destruction_observer_|
+ // was looking for should have already happened. We don't want the
+ // lifetime of the observer to matter with respect to the overlay when
+ // checking expectations.
+ // Note that it might already be null.
+ destruction_observer_ = nullptr;
+ }
+
+ void StartHelper(std::unique_ptr<MockAndroidOverlayFactory> factory) {
+ chooser_->Initialize(
+ base::Bind(&MockClient::UseOverlayImpl, base::Unretained(&client_)),
+ base::Bind(&MockClient::UseSurfaceTexture, base::Unretained(&client_)),
+ base::Bind(&MockClient::StopUsingOverlayImmediately,
+ base::Unretained(&client_)),
+ std::move(factory));
+ }
+
+ std::unique_ptr<AndroidVideoSurfaceChooserImpl> chooser_;
+ StrictMock<MockClient> client_;
+ std::unique_ptr<NiceMock<MockAndroidOverlayFactory>> factory_;
+ base::WeakPtr<MockAndroidOverlayFactory> factory_weak_;
+
+ // Callbacks to control the overlay that will be vended by |factory_|
+ MockAndroidOverlay::Callbacks overlay_callbacks_;
+
+ std::unique_ptr<MockAndroidOverlay::DestructionObserver>
+ destruction_observer_;
+};
+
+TEST_F(AndroidVideoSurfaceChooserImplTest,
+ InitializeWithoutFactoryUsesSurfaceTexture) {
+ // Calling Initialize() with no factory should result in a callback to use
+ // surface texture.
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ StartHelper(nullptr);
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest, ProvideInitialOverlaySuccessfully) {
+ // Providing a factory at startup should result in a switch to overlay. It
+ // should not switch to SurfaceTexture initially, since pre-M requires it.
+ // Note that post-M (especially DS), it might be fine to start with ST. We
+ // just don't differentiate those cases yet in the impl.
+
+ EXPECT_CALL(client_, UseSurfaceTexture()).Times(0);
+ StartHelper(std::move(factory_));
+
+ // Notify the chooser that the overlay is ready. Expect that |client_| will
+ // be told to use it.
+ EXPECT_CALL(client_, UseOverlay(NotNull()));
+ overlay_callbacks_.OverlayReady.Run();
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest,
+ InitializingWithFactoryCreatesOverlay) {
+ // Providing a factory at startup should result in a switch to overlay. It
+ // should not switch to SurfaceTexture initially, since pre-M requires it.
+ // Note that post-M (especially DS), it might be fine to start with ST. We
+ // just don't differentiate those cases yet in the impl.
+
+ // Initially, there should be no callback into |client_|, since we haven't
+ // told |chooser_| that the overlay is ready. It should, however, request the
+ // overlay from |factory_|.
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ StartHelper(std::move(factory_));
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest,
+ NullInitialOverlayUsesSurfaceTexture) {
+ // If we provide a factory, but it fails to create an overlay, then |client_|
+ // should be notified to use a surface texture.
+
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ // Replacing the overlay with null will destroy it.
+ destruction_observer_->ExpectDestruction();
+ factory_->SetOverlay(nullptr);
+ StartHelper(std::move(factory_));
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest,
+ FailedInitialOverlayUsesSurfaceTexture) {
+ // If we provide a factory, but the overlay that it provides returns 'failed',
+ // then |client_| should use surface texture.
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ StartHelper(std::move(factory_));
+
+ testing::Mock::VerifyAndClearExpectations(&client_);
+ testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
+
+ // The overlay may be destroyed at any time after we send OverlayFailed. It
+ // doesn't have to be destroyed. We just care that it hasn't been destroyed
+ // before now.
+ destruction_observer_ = nullptr;
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ overlay_callbacks_.OverlayFailed.Run();
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest,
+ OnSurfaceDestroyedSendsNotification) {
+ // If |chooser_| is notified about OnSurfaceDestroyed, then |client_| should
+ // also be notified.
+
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ StartHelper(std::move(factory_));
+ EXPECT_CALL(client_, UseOverlay(NotNull()));
+ overlay_callbacks_.OverlayReady.Run();
+
+ testing::Mock::VerifyAndClearExpectations(&client_);
+ testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
+
+ // Switch to a surface texture. OnSurfaceDestroyed should still be sent.
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ chooser_->ReplaceOverlayFactory(nullptr);
+ testing::Mock::VerifyAndClearExpectations(&client_);
+
+ EXPECT_CALL(client_, StopUsingOverlayImmediately(NotNull()));
+ overlay_callbacks_.SurfaceDestroyed.Run();
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest,
+ OnSurfaceDestroyedSendsNotificationAfterSwitch) {
+ // This tests two things. First:
+ // If |chooser_| is notified about OnSurfaceDestroyed, then |client_| should
+ // also be notified even if |chooser_| has already told |client_| to
+ // transition to SurfaceTexture. It has no idea if |client_| has actually
+ // transitioned, so it has to notify it to stop immediately, in case it
+ // hasn't. Second: |chooser_| should notify |client_| to switch to surface
+ // texture if it provided an overlay, and the factory is changed. This
+ // indicates that whoever provided the factory is revoking it, so we shouldn't
+ // be using overlays from that factory anymore. We specifically test overlay
+ // => no factory, since |chooser_| could elide multiple calls to switch to
+ // surface texture.
+ //
+ // We test these together, since switching the factory is the only way we have
+ // to make |chooser_| transition to SurfaceTexture without sending destroyed.
+
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ StartHelper(std::move(factory_));
+ EXPECT_CALL(client_, UseOverlay(NotNull()));
+ overlay_callbacks_.OverlayReady.Run();
+
+ testing::Mock::VerifyAndClearExpectations(&client_);
+ testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
+
+ // Switch factories, to notify the client back to switch to SurfaceTexture.
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ chooser_->ReplaceOverlayFactory(nullptr);
+ testing::Mock::VerifyAndClearExpectations(&client_);
+
+ // Destroy the original surface.
+ EXPECT_CALL(client_, StopUsingOverlayImmediately(NotNull()));
+ overlay_callbacks_.SurfaceDestroyed.Run();
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest, NullLaterOverlayUsesSurfaceTexture) {
+ // If an overlay factory is provided after startup that returns a null overlay
+ // from CreateOverlay, |chooser_| should, at most, notify |client_| to use
+ // SurfaceTexture zero or more times.
+
+ // Start with SurfaceTexture.
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ StartHelper(nullptr);
+ testing::Mock::VerifyAndClearExpectations(&client_);
+
+ // Provide a factory that will return a null overlay.
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ EXPECT_CALL(client_, UseSurfaceTexture()).Times(AnyNumber());
+ chooser_->ReplaceOverlayFactory(std::move(factory_));
+ factory_weak_->SetOverlay(nullptr);
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest, FailedLaterOverlayDoesNothing) {
+ // If we send an overlay factory that returns an overlay, and that overlay
+ // fails, then the client should not be notified except for zero or more
+ // callbacks to switch to surface texture.
+
+ // Start with SurfaceTexture.
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ StartHelper(nullptr);
+ testing::Mock::VerifyAndClearExpectations(&client_);
+
+ // Provide a factory.
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ EXPECT_CALL(client_, UseSurfaceTexture()).Times(AnyNumber());
+ chooser_->ReplaceOverlayFactory(std::move(factory_));
+ testing::Mock::VerifyAndClearExpectations(&client_);
+
+ // Fail the overlay. We don't care if it's destroyed after that, as long as
+ // it hasn't been destroyed yet.
+ destruction_observer_ = nullptr;
+ overlay_callbacks_.OverlayFailed.Run();
+}
+
+TEST_F(AndroidVideoSurfaceChooserImplTest,
+ SuccessfulLaterOverlayNotifiesClient) {
+ // |client_| is notified if we provide a factory that gets an overlay.
+
+ // Start with SurfaceTexture.
+ EXPECT_CALL(client_, UseSurfaceTexture());
+ StartHelper(nullptr);
+ testing::Mock::VerifyAndClearExpectations(&client_);
+
+ // Provide a factory. |chooser_| should try to create an overlay. We don't
+ // care if a call to UseSurfaceTexture is elided or not. Note that AVDA will
+ // ignore duplicate calls anyway (MultipleSurfaceTextureCallbacksAreIgnored).
+ EXPECT_CALL(*factory_, MockCreateOverlay());
+ EXPECT_CALL(client_, UseSurfaceTexture()).Times(AnyNumber());
+ chooser_->ReplaceOverlayFactory(std::move(factory_));
+ testing::Mock::VerifyAndClearExpectations(&client_);
+ testing::Mock::VerifyAndClearExpectations(factory_weak_.get());
+
+ // Notify |chooser_| that the overlay is ready.
+ EXPECT_CALL(client_, UseOverlay(NotNull()));
+ overlay_callbacks_.OverlayReady.Run();
+}
+
+} // namespace media
« no previous file with comments | « media/gpu/android_video_surface_chooser_impl.cc ('k') | media/gpu/avda_codec_allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698