Flutter Windows Embedder
cursor_handler_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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.
5 
6 #include <memory>
7 #include <vector>
8 
9 #include "flutter/fml/macros.h"
14 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
15 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
16 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
17 #include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
18 #include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
19 #include "flutter/shell/platform/windows/testing/windows_test.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 
23 namespace flutter {
24 namespace testing {
25 
26 namespace {
27 using ::testing::_;
28 using ::testing::IsNull;
29 using ::testing::NotNull;
30 using ::testing::Return;
31 
32 static constexpr char kChannelName[] = "flutter/mousecursor";
33 
34 static constexpr char kActivateSystemCursorMethod[] = "activateSystemCursor";
35 static constexpr char kCreateCustomCursorMethod[] =
36  "createCustomCursor/windows";
37 static constexpr char kSetCustomCursorMethod[] = "setCustomCursor/windows";
38 static constexpr char kDeleteCustomCursorMethod[] =
39  "deleteCustomCursor/windows";
40 
41 void SimulateCursorMessage(TestBinaryMessenger* messenger,
42  const std::string& method_name,
43  std::unique_ptr<EncodableValue> arguments,
44  MethodResult<EncodableValue>* result_handler) {
45  MethodCall<> call(method_name, std::move(arguments));
46 
48 
49  EXPECT_TRUE(messenger->SimulateEngineMessage(
50  kChannelName, message->data(), message->size(),
51  [&result_handler](const uint8_t* reply, size_t reply_size) {
52  StandardMethodCodec::GetInstance().DecodeAndProcessResponseEnvelope(
53  reply, reply_size, result_handler);
54  }));
55 }
56 
57 } // namespace
58 
59 class CursorHandlerTest : public WindowsTest {
60  public:
61  CursorHandlerTest() = default;
62  virtual ~CursorHandlerTest() = default;
63 
64  protected:
65  FlutterWindowsEngine* engine() { return engine_.get(); }
66  FlutterWindowsView* view() { return view_.get(); }
67  MockWindowBindingHandler* window() { return window_; }
68  MockWindowsProcTable* proc_table() { return windows_proc_table_.get(); }
69 
71  FlutterWindowsEngineBuilder builder{GetContext()};
72 
73  engine_ = builder.Build();
74  }
75 
77  windows_proc_table_ = std::make_shared<MockWindowsProcTable>();
78 
79  FlutterWindowsEngineBuilder builder{GetContext()};
80  builder.SetWindowsProcTable(windows_proc_table_);
81 
82  auto window = std::make_unique<MockWindowBindingHandler>();
83  EXPECT_CALL(*window.get(), SetView).Times(1);
84  EXPECT_CALL(*window.get(), GetWindowHandle).WillRepeatedly(Return(nullptr));
85 
86  window_ = window.get();
87  engine_ = builder.Build();
88  view_ = engine_->CreateView(std::move(window));
89  }
90 
91  private:
92  std::unique_ptr<FlutterWindowsEngine> engine_;
93  std::unique_ptr<FlutterWindowsView> view_;
94  MockWindowBindingHandler* window_;
95  std::shared_ptr<MockWindowsProcTable> windows_proc_table_;
96 
97  FML_DISALLOW_COPY_AND_ASSIGN(CursorHandlerTest);
98 };
99 
100 TEST_F(CursorHandlerTest, ActivateSystemCursor) {
101  UseEngineWithView();
102 
103  TestBinaryMessenger messenger;
104  CursorHandler cursor_handler(&messenger, engine());
105 
106  EXPECT_CALL(*proc_table(), LoadCursor(IsNull(), IDC_HAND)).Times(1);
107  EXPECT_CALL(*proc_table(), SetCursor).Times(1);
108 
109  bool success = false;
110  MethodResultFunctions<> result_handler(
111  [&success](const EncodableValue* result) {
112  success = true;
113  EXPECT_EQ(result, nullptr);
114  },
115  nullptr, nullptr);
116 
117  SimulateCursorMessage(&messenger, kActivateSystemCursorMethod,
118  std::make_unique<EncodableValue>(EncodableMap{
119  {EncodableValue("device"), EncodableValue(0)},
120  {EncodableValue("kind"), EncodableValue("click")},
121  }),
122  &result_handler);
123 
124  EXPECT_TRUE(success);
125 }
126 
127 TEST_F(CursorHandlerTest, CreateCustomCursor) {
128  UseEngineWithView();
129 
130  TestBinaryMessenger messenger;
131  CursorHandler cursor_handler(&messenger, engine());
132 
133  // Create a 4x4 raw BGRA test cursor buffer.
134  std::vector<uint8_t> buffer(4 * 4 * 4, 0);
135 
136  bool success = false;
137  MethodResultFunctions<> result_handler(
138  [&success](const EncodableValue* result) {
139  success = true;
140  EXPECT_EQ(std::get<std::string>(*result), "hello");
141  },
142  nullptr, nullptr);
143 
144  SimulateCursorMessage(&messenger, kCreateCustomCursorMethod,
145  std::make_unique<EncodableValue>(EncodableMap{
146  {EncodableValue("name"), EncodableValue("hello")},
147  {EncodableValue("buffer"), EncodableValue(buffer)},
148  {EncodableValue("width"), EncodableValue(4)},
149  {EncodableValue("height"), EncodableValue(4)},
150  {EncodableValue("hotX"), EncodableValue(0.0)},
151  {EncodableValue("hotY"), EncodableValue(0.0)},
152  }),
153  &result_handler);
154 
155  EXPECT_TRUE(success);
156 }
157 
158 TEST_F(CursorHandlerTest, SetCustomCursor) {
159  UseEngineWithView();
160 
161  TestBinaryMessenger messenger;
162  CursorHandler cursor_handler(&messenger, engine());
163 
164  // Create a 4x4 raw BGRA test cursor buffer.
165  std::vector<uint8_t> buffer(4 * 4 * 4, 0);
166 
167  bool success = false;
168  MethodResultFunctions<> create_result_handler(nullptr, nullptr, nullptr);
169  MethodResultFunctions<> set_result_handler(
170  [&success](const EncodableValue* result) {
171  success = true;
172  EXPECT_EQ(result, nullptr);
173  },
174  nullptr, nullptr);
175 
176  EXPECT_CALL(*proc_table(), LoadCursor).Times(0);
177  EXPECT_CALL(*proc_table(), SetCursor(NotNull())).Times(1);
178 
179  SimulateCursorMessage(&messenger, kCreateCustomCursorMethod,
180  std::make_unique<EncodableValue>(EncodableMap{
181  {EncodableValue("name"), EncodableValue("hello")},
182  {EncodableValue("buffer"), EncodableValue(buffer)},
183  {EncodableValue("width"), EncodableValue(4)},
184  {EncodableValue("height"), EncodableValue(4)},
185  {EncodableValue("hotX"), EncodableValue(0.0)},
186  {EncodableValue("hotY"), EncodableValue(0.0)},
187  }),
188  &create_result_handler);
189 
190  SimulateCursorMessage(&messenger, kSetCustomCursorMethod,
191  std::make_unique<EncodableValue>(EncodableMap{
192  {EncodableValue("name"), EncodableValue("hello")},
193  }),
194  &set_result_handler);
195 
196  EXPECT_TRUE(success);
197 }
198 
199 TEST_F(CursorHandlerTest, SetNonexistentCustomCursor) {
200  UseEngineWithView();
201 
202  TestBinaryMessenger messenger;
203  CursorHandler cursor_handler(&messenger, engine());
204 
205  bool error = false;
206  MethodResultFunctions<> result_handler(
207  nullptr,
208  [&error](const std::string& error_code, const std::string& error_message,
209  const EncodableValue* value) {
210  error = true;
211  EXPECT_EQ(
212  error_message,
213  "The custom cursor identified by the argument key cannot be found");
214  },
215  nullptr);
216 
217  EXPECT_CALL(*proc_table(), LoadCursor).Times(0);
218  EXPECT_CALL(*proc_table(), SetCursor).Times(0);
219 
220  SimulateCursorMessage(&messenger, kSetCustomCursorMethod,
221  std::make_unique<EncodableValue>(EncodableMap{
222  {EncodableValue("name"), EncodableValue("hello")},
223  }),
224  &result_handler);
225 
226  EXPECT_TRUE(error);
227 }
228 
229 TEST_F(CursorHandlerTest, DeleteCustomCursor) {
230  UseEngineWithView();
231 
232  TestBinaryMessenger messenger;
233  CursorHandler cursor_handler(&messenger, engine());
234 
235  // Create a 4x4 raw BGRA test cursor buffer.
236  std::vector<uint8_t> buffer(4 * 4 * 4, 0);
237 
238  bool success = false;
239  MethodResultFunctions<> create_result_handler(nullptr, nullptr, nullptr);
240  MethodResultFunctions<> delete_result_handler(
241  [&success](const EncodableValue* result) {
242  success = true;
243  EXPECT_EQ(result, nullptr);
244  },
245  nullptr, nullptr);
246 
247  SimulateCursorMessage(&messenger, kCreateCustomCursorMethod,
248  std::make_unique<EncodableValue>(EncodableMap{
249  {EncodableValue("name"), EncodableValue("hello")},
250  {EncodableValue("buffer"), EncodableValue(buffer)},
251  {EncodableValue("width"), EncodableValue(4)},
252  {EncodableValue("height"), EncodableValue(4)},
253  {EncodableValue("hotX"), EncodableValue(0.0)},
254  {EncodableValue("hotY"), EncodableValue(0.0)},
255  }),
256  &create_result_handler);
257 
258  SimulateCursorMessage(&messenger, kDeleteCustomCursorMethod,
259  std::make_unique<EncodableValue>(EncodableMap{
260  {EncodableValue("name"), EncodableValue("hello")},
261  }),
262  &delete_result_handler);
263 
264  EXPECT_TRUE(success);
265 }
266 
267 TEST_F(CursorHandlerTest, DeleteNonexistentCustomCursor) {
268  UseEngineWithView();
269 
270  TestBinaryMessenger messenger;
271  CursorHandler cursor_handler(&messenger, engine());
272 
273  bool success = false;
274  MethodResultFunctions<> result_handler(
275  [&success](const EncodableValue* result) {
276  success = true;
277  EXPECT_EQ(result, nullptr);
278  },
279  nullptr, nullptr);
280 
281  SimulateCursorMessage(&messenger, kDeleteCustomCursorMethod,
282  std::make_unique<EncodableValue>(EncodableMap{
283  {EncodableValue("name"), EncodableValue("fake")},
284  }),
285  &result_handler);
286 
287  EXPECT_TRUE(success);
288 }
289 
290 } // namespace testing
291 } // namespace flutter
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCall(const MethodCall< T > &method_call) const
Definition: method_codec.h:48
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
static constexpr char kDeleteCustomCursorMethod[]
static constexpr char kActivateSystemCursorMethod[]
static constexpr char kChannelName[]
static constexpr char kCreateCustomCursorMethod[]
static constexpr char kSetCustomCursorMethod[]
Win32Message message
TEST_F(CompositorOpenGLTest, CreateBackingStore)
std::map< EncodableValue, EncodableValue > EncodableMap