9 #include "flutter/fml/macros.h"
12 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
13 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
14 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
15 #include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
16 #include "flutter/shell/platform/windows/testing/windows_test.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
19 #include "rapidjson/document.h"
26 using ::testing::NiceMock;
27 using ::testing::Return;
29 static constexpr
char kChannelName[] =
"flutter/platform";
31 static constexpr
char kClipboardGetDataMessage[] =
32 "{\"method\":\"Clipboard.getData\",\"args\":\"text/plain\"}";
33 static constexpr
char kClipboardGetDataFakeContentTypeMessage[] =
34 "{\"method\":\"Clipboard.getData\",\"args\":\"text/madeupcontenttype\"}";
35 static constexpr
char kClipboardHasStringsMessage[] =
36 "{\"method\":\"Clipboard.hasStrings\",\"args\":\"text/plain\"}";
37 static constexpr
char kClipboardHasStringsFakeContentTypeMessage[] =
38 "{\"method\":\"Clipboard.hasStrings\",\"args\":\"text/madeupcontenttype\"}";
39 static constexpr
char kClipboardSetDataMessage[] =
40 "{\"method\":\"Clipboard.setData\",\"args\":{\"text\":\"hello\"}}";
41 static constexpr
char kClipboardSetDataNullTextMessage[] =
42 "{\"method\":\"Clipboard.setData\",\"args\":{\"text\":null}}";
43 static constexpr
char kClipboardSetDataUnknownTypeMessage[] =
44 "{\"method\":\"Clipboard.setData\",\"args\":{\"madeuptype\":\"hello\"}}";
45 static constexpr
char kSystemSoundTypeAlertMessage[] =
46 "{\"method\":\"SystemSound.play\",\"args\":\"SystemSoundType.alert\"}";
47 static constexpr
char kSystemExitApplicationRequiredMessage[] =
48 "{\"method\":\"System.exitApplication\",\"args\":{\"type\":\"required\","
50 static constexpr
char kSystemExitApplicationCancelableMessage[] =
51 "{\"method\":\"System.exitApplication\",\"args\":{\"type\":\"cancelable\","
53 static constexpr
char kExitResponseCancelMessage[] =
54 "[{\"response\":\"cancel\"}]";
55 static constexpr
char kExitResponseExitMessage[] =
"[{\"response\":\"exit\"}]";
59 static constexpr
int kArbitraryErrorCode = 1;
63 class MockPlatformHandler :
public PlatformHandler {
65 explicit MockPlatformHandler(
66 BinaryMessenger* messenger,
67 FlutterWindowsEngine* engine,
68 std::optional<std::function<std::unique_ptr<ScopedClipboardInterface>()>>
69 scoped_clipboard_provider = std::nullopt)
70 : PlatformHandler(messenger, engine, scoped_clipboard_provider) {}
72 virtual ~MockPlatformHandler() =
default;
76 (std::unique_ptr<MethodResult<rapidjson::Document>>,
77 std::string_view
key),
81 (std::unique_ptr<MethodResult<rapidjson::Document>>),
86 std::unique_ptr<MethodResult<rapidjson::Document>>),
91 std::unique_ptr<MethodResult<rapidjson::Document>>),
96 (std::optional<HWND> hwnd,
97 std::optional<WPARAM> wparam,
98 std::optional<LPARAM> lparam,
103 FML_DISALLOW_COPY_AND_ASSIGN(MockPlatformHandler);
107 class MockScopedClipboard :
public ScopedClipboardInterface {
109 MockScopedClipboard() =
default;
110 virtual ~MockScopedClipboard() =
default;
112 MOCK_METHOD(
int, Open, (HWND window), (
override));
113 MOCK_METHOD(
bool, HasString, (), (
override));
114 MOCK_METHOD((std::variant<std::wstring, int>), GetString, (), (
override));
115 MOCK_METHOD(
int, SetString, (
const std::wstring
string), (
override));
118 FML_DISALLOW_COPY_AND_ASSIGN(MockScopedClipboard);
121 std::string SimulatePlatformMessage(TestBinaryMessenger* messenger,
124 EXPECT_TRUE(messenger->SimulateEngineMessage(
127 [result = &result](
const uint8_t* reply,
size_t reply_size) {
128 std::string response(reinterpret_cast<const char*>(reply), reply_size);
147 FlutterWindowsEngineBuilder builder{GetContext()};
149 engine_ = builder.Build();
153 FlutterWindowsEngineBuilder builder{GetContext()};
155 auto window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
157 engine_ = builder.Build();
158 view_ = std::make_unique<FlutterWindowsView>(
kImplicitViewId, engine_.get(),
161 EngineModifier modifier{engine_.get()};
162 modifier.SetImplicitView(view_.get());
166 std::unique_ptr<FlutterWindowsEngine> engine_;
167 std::unique_ptr<FlutterWindowsView> view_;
175 TestBinaryMessenger messenger;
177 auto clipboard = std::make_unique<MockScopedClipboard>();
179 EXPECT_CALL(*clipboard.get(), Open)
182 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
true));
183 EXPECT_CALL(*clipboard.get(), GetString)
185 .WillOnce(Return(std::wstring(L
"Hello world")));
191 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
193 EXPECT_EQ(result,
"[{\"text\":\"Hello world\"}]");
199 TestBinaryMessenger messenger;
203 std::string result = SimulatePlatformMessage(
204 &messenger, kClipboardGetDataFakeContentTypeMessage);
206 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
212 TestBinaryMessenger messenger;
216 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
219 "[\"Clipboard error\",\"Clipboard is not available in "
220 "Windows headless mode\",null]");
226 TestBinaryMessenger messenger;
228 auto clipboard = std::make_unique<MockScopedClipboard>();
230 EXPECT_CALL(*clipboard.get(), Open)
232 .WillOnce(Return(kArbitraryErrorCode));
238 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
240 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to open clipboard\",1]");
246 TestBinaryMessenger messenger;
248 auto clipboard = std::make_unique<MockScopedClipboard>();
250 EXPECT_CALL(*clipboard.get(), Open)
253 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
true));
254 EXPECT_CALL(*clipboard.get(), GetString)
256 .WillOnce(Return(kArbitraryErrorCode));
262 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
264 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to get clipboard data\",1]");
270 TestBinaryMessenger messenger;
272 auto clipboard = std::make_unique<MockScopedClipboard>();
274 EXPECT_CALL(*clipboard.get(), Open)
277 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
true));
283 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
285 EXPECT_EQ(result,
"[{\"value\":true}]");
291 TestBinaryMessenger messenger;
293 auto clipboard = std::make_unique<MockScopedClipboard>();
295 EXPECT_CALL(*clipboard.get(), Open)
298 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
false));
304 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
306 EXPECT_EQ(result,
"[{\"value\":false}]");
312 TestBinaryMessenger messenger;
315 std::string result = SimulatePlatformMessage(
316 &messenger, kClipboardHasStringsFakeContentTypeMessage);
318 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
324 TestBinaryMessenger messenger;
328 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
331 "[\"Clipboard error\",\"Clipboard is not available in Windows "
332 "headless mode\",null]");
339 TestBinaryMessenger messenger;
341 auto clipboard = std::make_unique<MockScopedClipboard>();
343 EXPECT_CALL(*clipboard.get(), Open)
351 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
353 EXPECT_EQ(result,
"[{\"value\":false}]");
359 TestBinaryMessenger messenger;
361 auto clipboard = std::make_unique<MockScopedClipboard>();
363 EXPECT_CALL(*clipboard.get(), Open)
365 .WillOnce(Return(kArbitraryErrorCode));
371 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
373 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to open clipboard\",1]");
379 TestBinaryMessenger messenger;
381 auto clipboard = std::make_unique<MockScopedClipboard>();
383 EXPECT_CALL(*clipboard.get(), Open)
386 EXPECT_CALL(*clipboard.get(), SetString)
388 .WillOnce([](std::wstring
string) {
389 EXPECT_EQ(
string, L
"hello");
397 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
399 EXPECT_EQ(result,
"[null]");
406 TestBinaryMessenger messenger;
410 SimulatePlatformMessage(&messenger, kClipboardSetDataNullTextMessage);
412 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
418 TestBinaryMessenger messenger;
422 SimulatePlatformMessage(&messenger, kClipboardSetDataUnknownTypeMessage);
424 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
430 TestBinaryMessenger messenger;
434 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
437 "[\"Clipboard error\",\"Clipboard is not available in Windows "
438 "headless mode\",null]");
444 TestBinaryMessenger messenger;
446 auto clipboard = std::make_unique<MockScopedClipboard>();
448 EXPECT_CALL(*clipboard.get(), Open)
450 .WillOnce(Return(kArbitraryErrorCode));
456 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
458 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to open clipboard\",1]");
464 TestBinaryMessenger messenger;
466 auto clipboard = std::make_unique<MockScopedClipboard>();
468 EXPECT_CALL(*clipboard.get(), Open)
471 EXPECT_CALL(*clipboard.get(), SetString)
473 .WillOnce(Return(kArbitraryErrorCode));
479 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
481 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to set clipboard data\",1]");
487 TestBinaryMessenger messenger;
488 MockPlatformHandler platform_handler(&messenger, engine());
490 EXPECT_CALL(platform_handler, SystemSoundPlay(
"SystemSoundType.alert", _))
491 .WillOnce([](
const std::string& sound,
497 SimulatePlatformMessage(&messenger, kSystemSoundTypeAlertMessage);
499 EXPECT_EQ(result,
"[null]");
506 TestBinaryMessenger messenger([](
const std::string& channel,
507 const uint8_t*
message,
size_t size,
509 MockPlatformHandler platform_handler(&messenger, engine());
511 ON_CALL(platform_handler, QuitApplication)
512 .WillByDefault([&exit_code](std::optional<HWND> hwnd,
513 std::optional<WPARAM> wparam,
514 std::optional<LPARAM> lparam,
515 UINT ec) { exit_code = ec; });
516 EXPECT_CALL(platform_handler, QuitApplication).Times(1);
518 std::string result = SimulatePlatformMessage(
519 &messenger, kSystemExitApplicationRequiredMessage);
520 EXPECT_EQ(result,
"[{\"response\":\"exit\"}]");
521 EXPECT_EQ(exit_code, 1);
526 bool called_cancel =
false;
528 TestBinaryMessenger messenger(
529 [&called_cancel](
const std::string& channel,
const uint8_t*
message,
531 reply(
reinterpret_cast<const uint8_t*
>(kExitResponseCancelMessage),
532 sizeof(kExitResponseCancelMessage));
533 called_cancel =
true;
535 MockPlatformHandler platform_handler(&messenger, engine());
537 EXPECT_CALL(platform_handler, QuitApplication).Times(0);
539 std::string result = SimulatePlatformMessage(
540 &messenger, kSystemExitApplicationCancelableMessage);
541 EXPECT_EQ(result,
"[{\"response\":\"cancel\"}]");
542 EXPECT_TRUE(called_cancel);
547 bool called_cancel =
false;
550 TestBinaryMessenger messenger(
551 [&called_cancel](
const std::string& channel,
const uint8_t*
message,
553 reply(
reinterpret_cast<const uint8_t*
>(kExitResponseExitMessage),
554 sizeof(kExitResponseExitMessage));
555 called_cancel =
true;
557 MockPlatformHandler platform_handler(&messenger, engine());
559 ON_CALL(platform_handler, QuitApplication)
560 .WillByDefault([&exit_code](std::optional<HWND> hwnd,
561 std::optional<WPARAM> wparam,
562 std::optional<LPARAM> lparam,
563 UINT ec) { exit_code = ec; });
564 EXPECT_CALL(platform_handler, QuitApplication).Times(1);
566 std::string result = SimulatePlatformMessage(
567 &messenger, kSystemExitApplicationCancelableMessage);
568 EXPECT_EQ(result,
"[{\"response\":\"cancel\"}]");
569 EXPECT_TRUE(called_cancel);
570 EXPECT_EQ(exit_code, 2);