| Index: blimp/client/core/contents/blimp_contents_impl_unittest.cc
|
| diff --git a/blimp/client/core/contents/blimp_contents_impl_unittest.cc b/blimp/client/core/contents/blimp_contents_impl_unittest.cc
|
| index 98fa2066246edf05c0c085cd0116196bd5a7edec..64bad1cf9cc5c53b4875ff3b263f63693e146030 100644
|
| --- a/blimp/client/core/contents/blimp_contents_impl_unittest.cc
|
| +++ b/blimp/client/core/contents/blimp_contents_impl_unittest.cc
|
| @@ -5,11 +5,19 @@
|
| #include "blimp/client/core/contents/blimp_contents_impl.h"
|
|
|
| #include "base/message_loop/message_loop.h"
|
| -#include "blimp/client/core/contents/blimp_contents_impl.h"
|
| +#include "blimp/client/core/compositor/compositor_deps_provider.h"
|
| #include "blimp/client/core/contents/fake_navigation_feature.h"
|
| +#include "blimp/client/core/render_widget/blimp_render_widget.h"
|
| +#include "blimp/client/core/render_widget/render_widget_feature.h"
|
| #include "blimp/client/public/contents/blimp_contents_observer.h"
|
| +#include "cc/proto/compositor_message.pb.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| +#include "third_party/WebKit/public/web/WebInputEvent.h"
|
| +
|
| +using testing::_;
|
| +using testing::InSequence;
|
| +using testing::Sequence;
|
|
|
| namespace blimp {
|
| namespace client {
|
| @@ -31,36 +39,201 @@ class MockBlimpContentsObserver : public BlimpContentsObserver {
|
| DISALLOW_COPY_AND_ASSIGN(MockBlimpContentsObserver);
|
| };
|
|
|
| -TEST(BlimpContentsImplTest, LoadURLAndNotifyObservers) {
|
| - base::MessageLoop loop;
|
| - BlimpContentsImpl blimp_contents(kDummyTabId);
|
| +class MockRenderWidgetFeature : public RenderWidgetFeature {
|
| + public:
|
| + MOCK_METHOD3(SendCompositorMessage,
|
| + void(const int, const int, const cc::proto::CompositorMessage&));
|
| + MOCK_METHOD3(SendInputEvent,
|
| + void(const int, const int, const blink::WebInputEvent&));
|
| + MOCK_METHOD2(SetDelegate, void(int, RenderWidgetFeatureDelegate*));
|
| + MOCK_METHOD1(RemoveDelegate, void(const int));
|
| +};
|
| +
|
| +class MockRenderWidget : public BlimpRenderWidget {
|
| + public:
|
| + MockRenderWidget(int32_t render_widget_id,
|
| + CompositorDepsProvider* compositor_deps_provider,
|
| + BlimpRenderWidgetDelegate* delegate)
|
| + : BlimpRenderWidget(render_widget_id,
|
| + compositor_deps_provider,
|
| + delegate) {}
|
| +
|
| + MOCK_METHOD1(SetVisible, void(bool));
|
| + MOCK_METHOD1(SetAcceleratedWidget, void(gfx::AcceleratedWidget));
|
| +
|
| + void OnCompositorMessageReceived(
|
| + std::unique_ptr<cc::proto::CompositorMessage> message) override {
|
| + MockableOnCompositorMessageReceived(*message);
|
| + }
|
| + MOCK_METHOD1(MockableOnCompositorMessageReceived,
|
| + void(const cc::proto::CompositorMessage&));
|
| +};
|
| +
|
| +class BlimpContentsImplForTesting : public BlimpContentsImpl {
|
| + public:
|
| + BlimpContentsImplForTesting(int id,
|
| + CompositorDepsProvider* compositor_deps_provider,
|
| + RenderWidgetFeature* render_widget_feature)
|
| + : BlimpContentsImpl(id, compositor_deps_provider, render_widget_feature) {
|
| + }
|
| +
|
| + protected:
|
| + std::unique_ptr<BlimpRenderWidget> CreateBlimpRenderWidget(
|
| + int32_t render_widget_id,
|
| + CompositorDepsProvider* compositor_deps_provider,
|
| + BlimpRenderWidgetDelegate* delegate) override {
|
| + return base::MakeUnique<MockRenderWidget>(
|
| + render_widget_id, compositor_deps_provider, delegate);
|
| + }
|
| +};
|
| +
|
| +class BlimpContentsImplTest : public testing::Test {
|
| + public:
|
| + BlimpContentsImplTest() : widget1_(nullptr), widget2_(nullptr) {}
|
| +
|
| + void SetUpBlimpContents(bool use_direct_rendering) {
|
| + compositor_deps_provider_ =
|
| + base::MakeUnique<CompositorDepsProvider>(use_direct_rendering);
|
| + image_serialization_processor_ =
|
| + base::MakeUnique<BlobImageSerializationProcessor>();
|
| + blimp_contents_ = base::MakeUnique<BlimpContentsImplForTesting>(
|
| + kDummyTabId, compositor_deps_provider_.get(), &render_widget_feature_);
|
| + }
|
| +
|
| + void SetUpWidgets() {
|
| + blimp_contents_->OnRenderWidgetCreated(1);
|
| + blimp_contents_->OnRenderWidgetCreated(2);
|
| +
|
| + widget1_ =
|
| + static_cast<MockRenderWidget*>(blimp_contents_->GetWidgetForId(1));
|
| + widget2_ =
|
| + static_cast<MockRenderWidget*>(blimp_contents_->GetWidgetForId(2));
|
| +
|
| + EXPECT_NE(widget1_, nullptr);
|
| + EXPECT_NE(widget2_, nullptr);
|
| + }
|
| +
|
| + void TearDown() override {
|
| + blimp_contents_.reset();
|
| + compositor_deps_provider_.reset();
|
| + image_serialization_processor_.reset();
|
| + widget1_ = nullptr;
|
| + widget2_ = nullptr;
|
| + }
|
| +
|
| + base::MessageLoop loop_;
|
| + std::unique_ptr<BlimpContentsImpl> blimp_contents_;
|
| + std::unique_ptr<CompositorDepsProvider> compositor_deps_provider_;
|
| + std::unique_ptr<BlobImageSerializationProcessor>
|
| + image_serialization_processor_;
|
| + MockRenderWidgetFeature render_widget_feature_;
|
| +
|
| + MockRenderWidget* widget1_;
|
| + MockRenderWidget* widget2_;
|
| +};
|
| +
|
| +TEST_F(BlimpContentsImplTest, LoadURLAndNotifyObservers) {
|
| + SetUpBlimpContents(true);
|
|
|
| BlimpNavigationControllerImpl& navigation_controller =
|
| - blimp_contents.GetNavigationController();
|
| + blimp_contents_->GetNavigationController();
|
| FakeNavigationFeature feature;
|
| feature.SetDelegate(1, &navigation_controller);
|
| navigation_controller.SetNavigationFeatureForTesting(&feature);
|
|
|
| - testing::StrictMock<MockBlimpContentsObserver> observer1(&blimp_contents);
|
| - testing::StrictMock<MockBlimpContentsObserver> observer2(&blimp_contents);
|
| + testing::StrictMock<MockBlimpContentsObserver> observer1(
|
| + blimp_contents_.get());
|
| + testing::StrictMock<MockBlimpContentsObserver> observer2(
|
| + blimp_contents_.get());
|
|
|
| EXPECT_CALL(observer1, OnNavigationStateChanged());
|
| EXPECT_CALL(observer2, OnNavigationStateChanged()).Times(2);
|
|
|
| navigation_controller.LoadURL(GURL(kExampleURL));
|
| - loop.RunUntilIdle();
|
| + loop_.RunUntilIdle();
|
|
|
| EXPECT_EQ(kExampleURL, navigation_controller.GetURL().spec());
|
|
|
| // Observer should no longer receive callbacks.
|
| - blimp_contents.RemoveObserver(&observer1);
|
| + blimp_contents_->RemoveObserver(&observer1);
|
|
|
| navigation_controller.LoadURL(GURL(kOtherExampleURL));
|
| - loop.RunUntilIdle();
|
| + loop_.RunUntilIdle();
|
|
|
| EXPECT_EQ(kOtherExampleURL, navigation_controller.GetURL().spec());
|
| }
|
|
|
| +TEST_F(BlimpContentsImplTest, ForwardsMessagesToCorrectWidget) {
|
| + SetUpBlimpContents(true);
|
| + SetUpWidgets();
|
| +
|
| + // Ensure that the compositor messages for a render widget are forwarded to
|
| + // the correct blimp render widget.
|
| + EXPECT_CALL(*widget1_, MockableOnCompositorMessageReceived(_)).Times(2);
|
| + EXPECT_CALL(*widget2_, MockableOnCompositorMessageReceived(_)).Times(1);
|
| + EXPECT_CALL(*widget1_, SetVisible(false)).Times(1);
|
| + EXPECT_CALL(*widget1_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget))
|
| + .Times(1);
|
| +
|
| + blimp_contents_->OnCompositorMessageReceived(
|
| + widget1_->GetId(), base::WrapUnique(new cc::proto::CompositorMessage));
|
| + blimp_contents_->OnRenderWidgetInitialized(widget1_->GetId());
|
| + EXPECT_EQ(widget1_, blimp_contents_->GetActiveWidget());
|
| +
|
| + blimp_contents_->OnCompositorMessageReceived(
|
| + widget1_->GetId(), base::WrapUnique(new cc::proto::CompositorMessage));
|
| + blimp_contents_->OnCompositorMessageReceived(
|
| + widget2_->GetId(), base::WrapUnique(new cc::proto::CompositorMessage));
|
| +
|
| + int32_t deleted_id = widget1_->GetId();
|
| + blimp_contents_->OnRenderWidgetDeleted(deleted_id);
|
| + EXPECT_EQ(blimp_contents_->GetWidgetForId(deleted_id), nullptr);
|
| +}
|
| +
|
| +TEST_F(BlimpContentsImplTest, ForwardsViewEventsToCorrectWidget) {
|
| + InSequence sequence;
|
| + SetUpBlimpContents(true);
|
| + SetUpWidgets();
|
| +
|
| + // Called when the first widget is intialized.
|
| + EXPECT_CALL(*widget1_, SetVisible(true));
|
| + EXPECT_CALL(*widget1_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget));
|
| +
|
| + // Called when the second widget is initialized.
|
| + EXPECT_CALL(*widget1_, SetVisible(false));
|
| + EXPECT_CALL(*widget1_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget));
|
| + EXPECT_CALL(*widget2_, SetVisible(true));
|
| + EXPECT_CALL(*widget2_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget));
|
| +
|
| + // Called when the visibility is toggled after the second widget is
|
| + // initialized.
|
| + EXPECT_CALL(*widget2_, SetVisible(false));
|
| +
|
| + // Make the BlimpContents visible while we don't have any render widget
|
| + // initialized.
|
| + blimp_contents_->SetVisible(true);
|
| + blimp_contents_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
| +
|
| + // Initialize the first render widget. This should propagate the visibility
|
| + // and the accelerated widget to the corresponding widget.
|
| + blimp_contents_->OnRenderWidgetInitialized(widget1_->GetId());
|
| +
|
| + // Now initialize the second render widget. This should swap the widget
|
| + // and make the first one invisible and release the accelerated widget.
|
| + blimp_contents_->OnRenderWidgetInitialized(widget2_->GetId());
|
| +
|
| + // Now make the BlimpContents invisible. This should make the current render
|
| + // widget invisible.
|
| + blimp_contents_->SetVisible(false);
|
| +
|
| + // Destroy all the widgets. We should not be receiving any calls for the view
|
| + // events forwarded after this.
|
| + blimp_contents_->OnRenderWidgetDeleted(widget1_->GetId());
|
| + blimp_contents_->OnRenderWidgetDeleted(widget2_->GetId());
|
| +
|
| + blimp_contents_->SetVisible(true);
|
| +}
|
| +
|
| } // namespace
|
| } // namespace client
|
| } // namespace blimp
|
|
|