OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "blimp/client/core/contents/blimp_contents_impl.h" | 5 #include "blimp/client/core/contents/blimp_contents_impl.h" |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "blimp/client/core/contents/blimp_contents_impl.h" | 8 #include "blimp/client/core/compositor/compositor_deps_provider.h" |
9 #include "blimp/client/core/contents/fake_navigation_feature.h" | 9 #include "blimp/client/core/contents/fake_navigation_feature.h" |
| 10 #include "blimp/client/core/render_widget/blimp_render_widget.h" |
| 11 #include "blimp/client/core/render_widget/render_widget_feature.h" |
10 #include "blimp/client/public/contents/blimp_contents_observer.h" | 12 #include "blimp/client/public/contents/blimp_contents_observer.h" |
| 13 #include "cc/proto/compositor_message.pb.h" |
11 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 17 |
| 18 using testing::_; |
| 19 using testing::InSequence; |
| 20 using testing::Sequence; |
13 | 21 |
14 namespace blimp { | 22 namespace blimp { |
15 namespace client { | 23 namespace client { |
16 namespace { | 24 namespace { |
17 | 25 |
18 const char kExampleURL[] = "https://www.example.com/"; | 26 const char kExampleURL[] = "https://www.example.com/"; |
19 const char kOtherExampleURL[] = "https://www.otherexample.com/"; | 27 const char kOtherExampleURL[] = "https://www.otherexample.com/"; |
20 const int kDummyTabId = 0; | 28 const int kDummyTabId = 0; |
21 | 29 |
22 class MockBlimpContentsObserver : public BlimpContentsObserver { | 30 class MockBlimpContentsObserver : public BlimpContentsObserver { |
23 public: | 31 public: |
24 explicit MockBlimpContentsObserver(BlimpContents* blimp_contents) | 32 explicit MockBlimpContentsObserver(BlimpContents* blimp_contents) |
25 : BlimpContentsObserver(blimp_contents) {} | 33 : BlimpContentsObserver(blimp_contents) {} |
26 ~MockBlimpContentsObserver() override = default; | 34 ~MockBlimpContentsObserver() override = default; |
27 | 35 |
28 MOCK_METHOD0(OnNavigationStateChanged, void()); | 36 MOCK_METHOD0(OnNavigationStateChanged, void()); |
29 | 37 |
30 private: | 38 private: |
31 DISALLOW_COPY_AND_ASSIGN(MockBlimpContentsObserver); | 39 DISALLOW_COPY_AND_ASSIGN(MockBlimpContentsObserver); |
32 }; | 40 }; |
33 | 41 |
34 TEST(BlimpContentsImplTest, LoadURLAndNotifyObservers) { | 42 class MockRenderWidgetFeature : public RenderWidgetFeature { |
35 base::MessageLoop loop; | 43 public: |
36 BlimpContentsImpl blimp_contents(kDummyTabId); | 44 MOCK_METHOD3(SendCompositorMessage, |
| 45 void(const int, const int, const cc::proto::CompositorMessage&)); |
| 46 MOCK_METHOD3(SendInputEvent, |
| 47 void(const int, const int, const blink::WebInputEvent&)); |
| 48 MOCK_METHOD2(SetDelegate, void(int, RenderWidgetFeatureDelegate*)); |
| 49 MOCK_METHOD1(RemoveDelegate, void(const int)); |
| 50 }; |
| 51 |
| 52 class MockRenderWidget : public BlimpRenderWidget { |
| 53 public: |
| 54 MockRenderWidget(int32_t render_widget_id, |
| 55 CompositorDepsProvider* compositor_deps_provider, |
| 56 BlimpRenderWidgetDelegate* delegate) |
| 57 : BlimpRenderWidget(render_widget_id, |
| 58 compositor_deps_provider, |
| 59 delegate) {} |
| 60 |
| 61 MOCK_METHOD1(SetVisible, void(bool)); |
| 62 MOCK_METHOD1(SetAcceleratedWidget, void(gfx::AcceleratedWidget)); |
| 63 |
| 64 void OnCompositorMessageReceived( |
| 65 std::unique_ptr<cc::proto::CompositorMessage> message) override { |
| 66 MockableOnCompositorMessageReceived(*message); |
| 67 } |
| 68 MOCK_METHOD1(MockableOnCompositorMessageReceived, |
| 69 void(const cc::proto::CompositorMessage&)); |
| 70 }; |
| 71 |
| 72 class BlimpContentsImplForTesting : public BlimpContentsImpl { |
| 73 public: |
| 74 BlimpContentsImplForTesting(int id, |
| 75 CompositorDepsProvider* compositor_deps_provider, |
| 76 RenderWidgetFeature* render_widget_feature) |
| 77 : BlimpContentsImpl(id, compositor_deps_provider, render_widget_feature) { |
| 78 } |
| 79 |
| 80 protected: |
| 81 std::unique_ptr<BlimpRenderWidget> CreateBlimpRenderWidget( |
| 82 int32_t render_widget_id, |
| 83 CompositorDepsProvider* compositor_deps_provider, |
| 84 BlimpRenderWidgetDelegate* delegate) override { |
| 85 return base::MakeUnique<MockRenderWidget>( |
| 86 render_widget_id, compositor_deps_provider, delegate); |
| 87 } |
| 88 }; |
| 89 |
| 90 class BlimpContentsImplTest : public testing::Test { |
| 91 public: |
| 92 BlimpContentsImplTest() : widget1_(nullptr), widget2_(nullptr) {} |
| 93 |
| 94 void SetUpBlimpContents(bool use_direct_rendering) { |
| 95 compositor_deps_provider_ = |
| 96 base::MakeUnique<CompositorDepsProvider>(use_direct_rendering); |
| 97 image_serialization_processor_ = |
| 98 base::MakeUnique<BlobImageSerializationProcessor>(); |
| 99 blimp_contents_ = base::MakeUnique<BlimpContentsImplForTesting>( |
| 100 kDummyTabId, compositor_deps_provider_.get(), &render_widget_feature_); |
| 101 } |
| 102 |
| 103 void SetUpWidgets() { |
| 104 blimp_contents_->OnRenderWidgetCreated(1); |
| 105 blimp_contents_->OnRenderWidgetCreated(2); |
| 106 |
| 107 widget1_ = |
| 108 static_cast<MockRenderWidget*>(blimp_contents_->GetWidgetForId(1)); |
| 109 widget2_ = |
| 110 static_cast<MockRenderWidget*>(blimp_contents_->GetWidgetForId(2)); |
| 111 |
| 112 EXPECT_NE(widget1_, nullptr); |
| 113 EXPECT_NE(widget2_, nullptr); |
| 114 } |
| 115 |
| 116 void TearDown() override { |
| 117 blimp_contents_.reset(); |
| 118 compositor_deps_provider_.reset(); |
| 119 image_serialization_processor_.reset(); |
| 120 widget1_ = nullptr; |
| 121 widget2_ = nullptr; |
| 122 } |
| 123 |
| 124 base::MessageLoop loop_; |
| 125 std::unique_ptr<BlimpContentsImpl> blimp_contents_; |
| 126 std::unique_ptr<CompositorDepsProvider> compositor_deps_provider_; |
| 127 std::unique_ptr<BlobImageSerializationProcessor> |
| 128 image_serialization_processor_; |
| 129 MockRenderWidgetFeature render_widget_feature_; |
| 130 |
| 131 MockRenderWidget* widget1_; |
| 132 MockRenderWidget* widget2_; |
| 133 }; |
| 134 |
| 135 TEST_F(BlimpContentsImplTest, LoadURLAndNotifyObservers) { |
| 136 SetUpBlimpContents(true); |
37 | 137 |
38 BlimpNavigationControllerImpl& navigation_controller = | 138 BlimpNavigationControllerImpl& navigation_controller = |
39 blimp_contents.GetNavigationController(); | 139 blimp_contents_->GetNavigationController(); |
40 FakeNavigationFeature feature; | 140 FakeNavigationFeature feature; |
41 feature.SetDelegate(1, &navigation_controller); | 141 feature.SetDelegate(1, &navigation_controller); |
42 navigation_controller.SetNavigationFeatureForTesting(&feature); | 142 navigation_controller.SetNavigationFeatureForTesting(&feature); |
43 | 143 |
44 testing::StrictMock<MockBlimpContentsObserver> observer1(&blimp_contents); | 144 testing::StrictMock<MockBlimpContentsObserver> observer1( |
45 testing::StrictMock<MockBlimpContentsObserver> observer2(&blimp_contents); | 145 blimp_contents_.get()); |
| 146 testing::StrictMock<MockBlimpContentsObserver> observer2( |
| 147 blimp_contents_.get()); |
46 | 148 |
47 EXPECT_CALL(observer1, OnNavigationStateChanged()); | 149 EXPECT_CALL(observer1, OnNavigationStateChanged()); |
48 EXPECT_CALL(observer2, OnNavigationStateChanged()).Times(2); | 150 EXPECT_CALL(observer2, OnNavigationStateChanged()).Times(2); |
49 | 151 |
50 navigation_controller.LoadURL(GURL(kExampleURL)); | 152 navigation_controller.LoadURL(GURL(kExampleURL)); |
51 loop.RunUntilIdle(); | 153 loop_.RunUntilIdle(); |
52 | 154 |
53 EXPECT_EQ(kExampleURL, navigation_controller.GetURL().spec()); | 155 EXPECT_EQ(kExampleURL, navigation_controller.GetURL().spec()); |
54 | 156 |
55 // Observer should no longer receive callbacks. | 157 // Observer should no longer receive callbacks. |
56 blimp_contents.RemoveObserver(&observer1); | 158 blimp_contents_->RemoveObserver(&observer1); |
57 | 159 |
58 navigation_controller.LoadURL(GURL(kOtherExampleURL)); | 160 navigation_controller.LoadURL(GURL(kOtherExampleURL)); |
59 loop.RunUntilIdle(); | 161 loop_.RunUntilIdle(); |
60 | 162 |
61 EXPECT_EQ(kOtherExampleURL, navigation_controller.GetURL().spec()); | 163 EXPECT_EQ(kOtherExampleURL, navigation_controller.GetURL().spec()); |
62 } | 164 } |
63 | 165 |
| 166 TEST_F(BlimpContentsImplTest, ForwardsMessagesToCorrectWidget) { |
| 167 SetUpBlimpContents(true); |
| 168 SetUpWidgets(); |
| 169 |
| 170 // Ensure that the compositor messages for a render widget are forwarded to |
| 171 // the correct blimp render widget. |
| 172 EXPECT_CALL(*widget1_, MockableOnCompositorMessageReceived(_)).Times(2); |
| 173 EXPECT_CALL(*widget2_, MockableOnCompositorMessageReceived(_)).Times(1); |
| 174 EXPECT_CALL(*widget1_, SetVisible(false)).Times(1); |
| 175 EXPECT_CALL(*widget1_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget)) |
| 176 .Times(1); |
| 177 |
| 178 blimp_contents_->OnCompositorMessageReceived( |
| 179 widget1_->GetId(), base::WrapUnique(new cc::proto::CompositorMessage)); |
| 180 blimp_contents_->OnRenderWidgetInitialized(widget1_->GetId()); |
| 181 EXPECT_EQ(widget1_, blimp_contents_->GetActiveWidget()); |
| 182 |
| 183 blimp_contents_->OnCompositorMessageReceived( |
| 184 widget1_->GetId(), base::WrapUnique(new cc::proto::CompositorMessage)); |
| 185 blimp_contents_->OnCompositorMessageReceived( |
| 186 widget2_->GetId(), base::WrapUnique(new cc::proto::CompositorMessage)); |
| 187 |
| 188 int32_t deleted_id = widget1_->GetId(); |
| 189 blimp_contents_->OnRenderWidgetDeleted(deleted_id); |
| 190 EXPECT_EQ(blimp_contents_->GetWidgetForId(deleted_id), nullptr); |
| 191 } |
| 192 |
| 193 TEST_F(BlimpContentsImplTest, ForwardsViewEventsToCorrectWidget) { |
| 194 InSequence sequence; |
| 195 SetUpBlimpContents(true); |
| 196 SetUpWidgets(); |
| 197 |
| 198 // Called when the first widget is intialized. |
| 199 EXPECT_CALL(*widget1_, SetVisible(true)); |
| 200 EXPECT_CALL(*widget1_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget)); |
| 201 |
| 202 // Called when the second widget is initialized. |
| 203 EXPECT_CALL(*widget1_, SetVisible(false)); |
| 204 EXPECT_CALL(*widget1_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget)); |
| 205 EXPECT_CALL(*widget2_, SetVisible(true)); |
| 206 EXPECT_CALL(*widget2_, SetAcceleratedWidget(gfx::kNullAcceleratedWidget)); |
| 207 |
| 208 // Called when the visibility is toggled after the second widget is |
| 209 // initialized. |
| 210 EXPECT_CALL(*widget2_, SetVisible(false)); |
| 211 |
| 212 // Make the BlimpContents visible while we don't have any render widget |
| 213 // initialized. |
| 214 blimp_contents_->SetVisible(true); |
| 215 blimp_contents_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); |
| 216 |
| 217 // Initialize the first render widget. This should propagate the visibility |
| 218 // and the accelerated widget to the corresponding widget. |
| 219 blimp_contents_->OnRenderWidgetInitialized(widget1_->GetId()); |
| 220 |
| 221 // Now initialize the second render widget. This should swap the widget |
| 222 // and make the first one invisible and release the accelerated widget. |
| 223 blimp_contents_->OnRenderWidgetInitialized(widget2_->GetId()); |
| 224 |
| 225 // Now make the BlimpContents invisible. This should make the current render |
| 226 // widget invisible. |
| 227 blimp_contents_->SetVisible(false); |
| 228 |
| 229 // Destroy all the widgets. We should not be receiving any calls for the view |
| 230 // events forwarded after this. |
| 231 blimp_contents_->OnRenderWidgetDeleted(widget1_->GetId()); |
| 232 blimp_contents_->OnRenderWidgetDeleted(widget2_->GetId()); |
| 233 |
| 234 blimp_contents_->SetVisible(true); |
| 235 } |
| 236 |
64 } // namespace | 237 } // namespace |
65 } // namespace client | 238 } // namespace client |
66 } // namespace blimp | 239 } // namespace blimp |
OLD | NEW |