5#include "flutter/shell/platform/windows/platform_handler.h"
9#include "flutter/fml/macros.h"
10#include "flutter/shell/platform/common/json_method_codec.h"
11#include "flutter/shell/platform/windows/flutter_windows_view.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"
26using ::testing::NiceMock;
27using ::testing::Return;
29static constexpr char kChannelName[] =
"flutter/platform";
31static constexpr char kClipboardGetDataMessage[] =
32 "{\"method\":\"Clipboard.getData\",\"args\":\"text/plain\"}";
33static constexpr char kClipboardGetDataFakeContentTypeMessage[] =
34 "{\"method\":\"Clipboard.getData\",\"args\":\"text/madeupcontenttype\"}";
35static constexpr char kClipboardHasStringsMessage[] =
36 "{\"method\":\"Clipboard.hasStrings\",\"args\":\"text/plain\"}";
37static constexpr char kClipboardHasStringsFakeContentTypeMessage[] =
38 "{\"method\":\"Clipboard.hasStrings\",\"args\":\"text/madeupcontenttype\"}";
39static constexpr char kClipboardSetDataMessage[] =
40 "{\"method\":\"Clipboard.setData\",\"args\":{\"text\":\"hello\"}}";
41static constexpr char kClipboardSetDataNullTextMessage[] =
42 "{\"method\":\"Clipboard.setData\",\"args\":{\"text\":null}}";
43static constexpr char kClipboardSetDataUnknownTypeMessage[] =
44 "{\"method\":\"Clipboard.setData\",\"args\":{\"madeuptype\":\"hello\"}}";
45static constexpr char kSystemSoundTypeAlertMessage[] =
46 "{\"method\":\"SystemSound.play\",\"args\":\"SystemSoundType.alert\"}";
47static constexpr char kSystemExitApplicationRequiredMessage[] =
48 "{\"method\":\"System.exitApplication\",\"args\":{\"type\":\"required\","
50static constexpr char kSystemExitApplicationCancelableMessage[] =
51 "{\"method\":\"System.exitApplication\",\"args\":{\"type\":\"cancelable\","
53static constexpr char kExitResponseCancelMessage[] =
54 "[{\"response\":\"cancel\"}]";
55static constexpr char kExitResponseExitMessage[] =
"[{\"response\":\"exit\"}]";
59static constexpr int kArbitraryErrorCode = 1;
63class 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,
107class 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));
121std::string SimulatePlatformMessage(TestBinaryMessenger* messenger,
127 [
result = &
result](
const uint8_t* reply,
size_t reply_size) {
128 std::string response(reinterpret_cast<const char*>(reply), reply_size);
155 auto window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
158 view_ = std::make_unique<FlutterWindowsView>(
kImplicitViewId, 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,
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\"}]");
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\"}]");
570 EXPECT_EQ(exit_code, 2);
WindowsTestContext & GetContext()
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Dart_NativeFunction function
TEST_F(DisplayListTest, Defaults)
constexpr int64_t kImplicitViewId
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
#define EXPECT_TRUE(handle)