| Flutter Windows Embedder |

platform_handler.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.
4
5 #include "flutter/shell/platform/windows/platform_handler.h"
6
7 #include <windows.h>
8
9 #include <cstring>
10 #include <optional>
11
12 #include "flutter/fml/logging.h"
13 #include "flutter/fml/macros.h"
14 #include "flutter/fml/platform/win/wstring_conversion.h"
15 #include "flutter/shell/platform/common/client_wrapper/include/flutter/method_result_functions.h"
16 #include "flutter/shell/platform/common/json_method_codec.h"
17 #include "flutter/shell/platform/windows/flutter_windows_view.h"
18
19 static constexpr char kChannelName[] = "flutter/platform";
20
21 static constexpr char kGetClipboardDataMethod[] = "Clipboard.getData";
22 static constexpr char kHasStringsClipboardMethod[] = "Clipboard.hasStrings";
23 static constexpr char kSetClipboardDataMethod[] = "Clipboard.setData";
24 static constexpr char kExitApplicationMethod[] = "System.exitApplication";
25 static constexpr char kRequestAppExitMethod[] = "System.requestAppExit";
26 static constexpr char kInitializationCompleteMethod[] =
27 "System.initializationComplete";
28 static constexpr char kPlaySoundMethod[] = "SystemSound.play";
29
30 static constexpr char kExitCodeKey[] = "exitCode";
31
32 static constexpr char kExitTypeKey[] = "type";
33
34 static constexpr char kExitResponseKey[] = "response";
35 static constexpr char kExitResponseCancel[] = "cancel";
36 static constexpr char kExitResponseExit[] = "exit";
37
38 static constexpr char kTextPlainFormat[] = "text/plain";
39 static constexpr char kTextKey[] = "text";
40 static constexpr char kUnknownClipboardFormatMessage[] =
41 "Unknown clipboard format";
42
43 static constexpr char kValueKey[] = "value";
44 static constexpr int kAccessDeniedErrorCode = 5;
45 static constexpr int kErrorSuccess = 0;
46
47 static constexpr char kExitRequestError[] = "ExitApplication error";
48 static constexpr char kInvalidExitRequestMessage[] =
49 "Invalid application exit request";
50
51 namespace flutter {
52
53 namespace {
54
55 static const std::wstring kWindowClassName = L"FlutterPlatformHandler";
56
57 // A scoped wrapper for GlobalAlloc/GlobalFree.
58 class ScopedGlobalMemory {
59 public:
60 // Allocates |bytes| bytes of global memory with the given flags.
61 ScopedGlobalMemory(unsigned int flags, size_t bytes) {
62 memory_ = ::GlobalAlloc(flags, bytes);
63 if (!memory_) {
64 FML_LOG(ERROR) << "Unable to allocate global memory: "
65 << static_cast<int>(::GetLastError());
66 }
67 }
68
69 ~ScopedGlobalMemory() {
70 if (memory_) {
71 if (::GlobalFree(memory_) != nullptr) {
72 FML_LOG(ERROR) << "Failed to free global allocation: "
73 << static_cast<int>(::GetLastError());
74 }
75 }
76 }
77
78 // Returns the memory pointer, which will be nullptr if allocation failed.
79 void* get() { return memory_; }
80
81 void* release() {
82 void* memory = memory_;
83 memory_ = nullptr;
84 return memory;
85 }
86
87 private:
88 HGLOBAL memory_;
89
90 FML_DISALLOW_COPY_AND_ASSIGN(ScopedGlobalMemory);
91 };
92
93 // A scoped wrapper for GlobalLock/GlobalUnlock.
94 class ScopedGlobalLock {
95 public:
96 // Attempts to acquire a global lock on |memory| for the life of this object.
97 ScopedGlobalLock(HGLOBAL memory) {
98 source_ = memory;
99 if (memory) {
100 locked_memory_ = ::GlobalLock(memory);
101 if (!locked_memory_) {
102 FML_LOG(ERROR) << "Unable to acquire global lock: " << ::GetLastError();
103 }
104 }
105 }
106
107 ~ScopedGlobalLock() {
108 if (locked_memory_) {
109 if (!::GlobalUnlock(source_)) {
110 DWORD error = ::GetLastError();
111 if (error != NO_ERROR) {
112 FML_LOG(ERROR) << "Unable to release global lock: "
113 << ::GetLastError();
114 }
115 }
116 }
117 }
118
119 // Returns the locked memory pointer, which will be nullptr if acquiring the
120 // lock failed.
121 void* get() { return locked_memory_; }
122
123 private:
124 HGLOBAL source_;
125 void* locked_memory_;
126
127 FML_DISALLOW_COPY_AND_ASSIGN(ScopedGlobalLock);
128 };
129
130 // A Clipboard wrapper that automatically closes the clipboard when it goes out
131 // of scope.
132 class ScopedClipboard : public ScopedClipboardInterface {
133 public:
134 ScopedClipboard();
135 virtual ~ScopedClipboard();
136
137 int Open(HWND window) override;
138
139 bool HasString() override;
140
141 std::variant<std::wstring, int> GetString() override;
142
143 int SetString(const std::wstring string) override;
144
145 private:
146 bool opened_ = false;
147
148 FML_DISALLOW_COPY_AND_ASSIGN(ScopedClipboard);
149 };
150
151 ScopedClipboard::ScopedClipboard() {}
152
153 ScopedClipboard::~ScopedClipboard() {
154 if (opened_) {
155 ::CloseClipboard();
156 }
157 }
158
159 int ScopedClipboard::Open(HWND window) {
160 opened_ = ::OpenClipboard(window);
161
162 if (!opened_) {
163 return ::GetLastError();
164 }
165
166 return kErrorSuccess;
167 }
168
169 bool ScopedClipboard::HasString() {
170 // Allow either plain text format, since getting data will auto-interpolate.
171 return ::IsClipboardFormatAvailable(CF_UNICODETEXT) ||
172 ::IsClipboardFormatAvailable(CF_TEXT);
173 }
174
175 std::variant<std::wstring, int> ScopedClipboard::GetString() {
176 FML_DCHECK(opened_) << "Called GetString when clipboard is closed";
177
178 HANDLE data = ::GetClipboardData(CF_UNICODETEXT);
179 if (data == nullptr) {
180 return static_cast<int>(::GetLastError());
181 }
182 ScopedGlobalLock locked_data(data);
183
184 if (!locked_data.get()) {
185 return static_cast<int>(::GetLastError());
186 }
187 return static_cast<wchar_t*>(locked_data.get());
188 }
189
190 int ScopedClipboard::SetString(const std::wstring string) {
191 FML_DCHECK(opened_) << "Called GetString when clipboard is closed";
192 if (!::EmptyClipboard()) {
193 return ::GetLastError();
194 }
195 size_t null_terminated_byte_count =
196 sizeof(decltype(string)::traits_type::char_type) * (string.size() + 1);
197 ScopedGlobalMemory destination_memory(GMEM_MOVEABLE,
198 null_terminated_byte_count);
199 ScopedGlobalLock locked_memory(destination_memory.get());
200 if (!locked_memory.get()) {
201 return ::GetLastError();
202 }
203 memcpy(locked_memory.get(), string.c_str(), null_terminated_byte_count);
204 if (!::SetClipboardData(CF_UNICODETEXT, locked_memory.get())) {
205 return ::GetLastError();
206 }
207 // The clipboard now owns the global memory.
208 destination_memory.release();
209 return kErrorSuccess;
210 }
211
212 } // namespace
213
214 static AppExitType StringToAppExitType(const std::string& string) {
215 if (string.compare(PlatformHandler::kExitTypeRequired) == 0) {
216 return AppExitType::required;
217 } else if (string.compare(PlatformHandler::kExitTypeCancelable) == 0) {
218 return AppExitType::cancelable;
219 }
220 FML_LOG(ERROR) << string << " is not recognized as a valid exit type.";
221 return AppExitType::required;
222 }
223
224 PlatformHandler::PlatformHandler(
225 BinaryMessenger* messenger,
226 FlutterWindowsEngine* engine,
227 std::optional<std::function<std::unique_ptr<ScopedClipboardInterface>()>>
228 scoped_clipboard_provider)
229 : channel_(std::make_unique<MethodChannel<rapidjson::Document>>(
230 messenger,
231 kChannelName,
232 &JsonMethodCodec::GetInstance())),
233 engine_(engine) {
234 channel_->SetMethodCallHandler(
235 [this](const MethodCall<rapidjson::Document>& call,
236 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
237 HandleMethodCall(call, std::move(result));
238 });
239 if (scoped_clipboard_provider.has_value()) {
240 scoped_clipboard_provider_ = scoped_clipboard_provider.value();
241 } else {
242 scoped_clipboard_provider_ = []() {
243 return std::make_unique<ScopedClipboard>();
244 };
245 }
246
247 WNDCLASS window_class = RegisterWindowClass();
248 window_handle_ =
249 CreateWindowEx(0, window_class.lpszClassName, L"", 0, 0, 0, 0, 0,
250 HWND_MESSAGE, nullptr, window_class.hInstance, nullptr);
251
252 if (window_handle_) {
253 SetWindowLongPtr(window_handle_, GWLP_USERDATA,
254 reinterpret_cast<LONG_PTR>(this));
255 } else {
256 auto error = GetLastError();
257 LPWSTR message = nullptr;
258 size_t size = FormatMessageW(
259 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
260 FORMAT_MESSAGE_IGNORE_INSERTS,
261 NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
262 reinterpret_cast<LPWSTR>(&message), 0, NULL);
263 OutputDebugString(message);
264 LocalFree(message);
265 }
266 }
267
268 PlatformHandler::~PlatformHandler() {
269 if (window_handle_) {
270 DestroyWindow(window_handle_);
271 window_handle_ = nullptr;
272 }
273 UnregisterClass(kWindowClassName.c_str(), nullptr);
274 }
275
276 void PlatformHandler::GetPlainText(
277 std::unique_ptr<MethodResult<rapidjson::Document>> result,
278 std::string_view key) {
279 std::unique_ptr<ScopedClipboardInterface> clipboard =
280 scoped_clipboard_provider_();
281
282 int open_result = clipboard->Open(window_handle_);
283 if (open_result != kErrorSuccess) {
284 rapidjson::Document error_code;
285 error_code.SetInt(open_result);
286 result->Error(kClipboardError, "Unable to open clipboard", error_code);
287 return;
288 }
289 if (!clipboard->HasString()) {
290 result->Success(rapidjson::Document());
291 return;
292 }
293 std::variant<std::wstring, int> get_string_result = clipboard->GetString();
294 if (std::holds_alternative<int>(get_string_result)) {
295 rapidjson::Document error_code;
296 error_code.SetInt(std::get<int>(get_string_result));
297 result->Error(kClipboardError, "Unable to get clipboard data", error_code);
298 return;
299 }
300
301 rapidjson::Document document;
302 document.SetObject();
303 rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
304 document.AddMember(
305 rapidjson::Value(key.data(), allocator),
306 rapidjson::Value(
307 fml::WideStringToUtf8(std::get<std::wstring>(get_string_result)),
308 allocator),
309 allocator);
310 result->Success(document);
311 }
312
313 void PlatformHandler::GetHasStrings(
314 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
315 std::unique_ptr<ScopedClipboardInterface> clipboard =
316 scoped_clipboard_provider_();
317
318 bool hasStrings;
319 int open_result = clipboard->Open(window_handle_);
320 if (open_result != kErrorSuccess) {
321 // Swallow errors of type ERROR_ACCESS_DENIED. These happen when the app is
322 // not in the foreground and GetHasStrings is irrelevant.
323 // See https://github.com/flutter/flutter/issues/95817.
324 if (open_result != kAccessDeniedErrorCode) {
325 rapidjson::Document error_code;
326 error_code.SetInt(open_result);
327 result->Error(kClipboardError, "Unable to open clipboard", error_code);
328 return;
329 }
330 hasStrings = false;
331 } else {
332 hasStrings = clipboard->HasString();
333 }
334
335 rapidjson::Document document;
336 document.SetObject();
337 rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
338 document.AddMember(rapidjson::Value(kValueKey, allocator),
339 rapidjson::Value(hasStrings), allocator);
340 result->Success(document);
341 }
342
343 void PlatformHandler::SetPlainText(
344 const std::string& text,
345 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
346 std::unique_ptr<ScopedClipboardInterface> clipboard =
347 scoped_clipboard_provider_();
348
349 int open_result = clipboard->Open(window_handle_);
350 if (open_result != kErrorSuccess) {
351 rapidjson::Document error_code;
352 error_code.SetInt(open_result);
353 result->Error(kClipboardError, "Unable to open clipboard", error_code);
354 return;
355 }
356 int set_result = clipboard->SetString(fml::Utf8ToWideString(text));
357 if (set_result != kErrorSuccess) {
358 rapidjson::Document error_code;
359 error_code.SetInt(set_result);
360 result->Error(kClipboardError, "Unable to set clipboard data", error_code);
361 return;
362 }
363 result->Success();
364 }
365
366 void PlatformHandler::SystemSoundPlay(
367 const std::string& sound_type,
368 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
369 if (sound_type.compare(kSoundTypeAlert) == 0) {
370 MessageBeep(MB_OK);
371 result->Success();
372 } else if (sound_type.compare(kSoundTypeClick) == 0) {
373 // No-op, as there is no system sound for key presses.
374 result->Success();
375 } else if (sound_type.compare(kSoundTypeTick) == 0) {
376 // No-op, as there is no system sound for ticks.
377 result->Success();
378 } else {
379 result->NotImplemented();
380 }
381 }
382
383 void PlatformHandler::SystemExitApplication(
384 AppExitType exit_type,
385 UINT exit_code,
386 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
387 rapidjson::Document result_doc;
388 result_doc.SetObject();
389 if (exit_type == AppExitType::required) {
390 QuitApplication(std::nullopt, std::nullopt, std::nullopt, exit_code);
391 result_doc.GetObjectW().AddMember(kExitResponseKey, kExitResponseExit,
392 result_doc.GetAllocator());
393 result->Success(result_doc);
394 } else {
395 RequestAppExit(std::nullopt, std::nullopt, std::nullopt, exit_type,
396 exit_code);
397 result_doc.GetObjectW().AddMember(kExitResponseKey, kExitResponseCancel,
398 result_doc.GetAllocator());
399 result->Success(result_doc);
400 }
401 }
402
403 // Indicates whether an exit request may be canceled by the framework.
404 // These values must be kept in sync with ExitType in platform_handler.h
405 static constexpr const char* kExitTypeNames[] = {
406 PlatformHandler::kExitTypeRequired, PlatformHandler::kExitTypeCancelable};
407
408 void PlatformHandler::RequestAppExit(std::optional<HWND> hwnd,
409 std::optional<WPARAM> wparam,
410 std::optional<LPARAM> lparam,
411 AppExitType exit_type,
412 UINT exit_code) {
413 auto callback = std::make_unique<MethodResultFunctions<rapidjson::Document>>(
414 [this, exit_code, hwnd, wparam,
415 lparam](const rapidjson::Document* response) {
416 RequestAppExitSuccess(hwnd, wparam, lparam, response, exit_code);
417 },
418 nullptr, nullptr);
419 auto args = std::make_unique<rapidjson::Document>();
420 args->SetObject();
421 args->GetObjectW().AddMember(
422 kExitTypeKey, std::string(kExitTypeNames[static_cast<int>(exit_type)]),
423 args->GetAllocator());
424 channel_->InvokeMethod(kRequestAppExitMethod, std::move(args),
425 std::move(callback));
426 }
427
428 void PlatformHandler::RequestAppExitSuccess(std::optional<HWND> hwnd,
429 std::optional<WPARAM> wparam,
430 std::optional<LPARAM> lparam,
431 const rapidjson::Document* result,
432 UINT exit_code) {
433 rapidjson::Value::ConstMemberIterator itr =
434 result->FindMember(kExitResponseKey);
435 if (itr == result->MemberEnd() || !itr->value.IsString()) {
436 FML_LOG(ERROR) << "Application request response did not contain a valid "
437 "response value";
438 return;
439 }
440 const std::string& exit_type = itr->value.GetString();
441
442 if (exit_type.compare(kExitResponseExit) == 0) {
443 QuitApplication(hwnd, wparam, lparam, exit_code);
444 }
445 }
446
447 void PlatformHandler::QuitApplication(std::optional<HWND> hwnd,
448 std::optional<WPARAM> wparam,
449 std::optional<LPARAM> lparam,
450 UINT exit_code) {
451 engine_->OnQuit(hwnd, wparam, lparam, exit_code);
452 }
453
454 void PlatformHandler::HandleMethodCall(
455 const MethodCall<rapidjson::Document>& method_call,
456 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
457 const std::string& method = method_call.method_name();
458 if (method.compare(kExitApplicationMethod) == 0) {
459 const rapidjson::Value& arguments = method_call.arguments()[0];
460
461 rapidjson::Value::ConstMemberIterator itr =
462 arguments.FindMember(kExitTypeKey);
463 if (itr == arguments.MemberEnd() || !itr->value.IsString()) {
464 result->Error(kExitRequestError, kInvalidExitRequestMessage);
465 return;
466 }
467 const std::string& exit_type = itr->value.GetString();
468
469 itr = arguments.FindMember(kExitCodeKey);
470 if (itr == arguments.MemberEnd() || !itr->value.IsInt()) {
471 result->Error(kExitRequestError, kInvalidExitRequestMessage);
472 return;
473 }
474 UINT exit_code = arguments[kExitCodeKey].GetInt();
475
476 SystemExitApplication(StringToAppExitType(exit_type), exit_code,
477 std::move(result));
478 } else if (method.compare(kGetClipboardDataMethod) == 0) {
479 // Only one string argument is expected.
480 const rapidjson::Value& format = method_call.arguments()[0];
481
482 if (strcmp(format.GetString(), kTextPlainFormat) != 0) {
483 result->Error(kClipboardError, kUnknownClipboardFormatMessage);
484 return;
485 }
486 GetPlainText(std::move(result), kTextKey);
487 } else if (method.compare(kHasStringsClipboardMethod) == 0) {
488 // Only one string argument is expected.
489 const rapidjson::Value& format = method_call.arguments()[0];
490
491 if (strcmp(format.GetString(), kTextPlainFormat) != 0) {
492 result->Error(kClipboardError, kUnknownClipboardFormatMessage);
493 return;
494 }
495 GetHasStrings(std::move(result));
496 } else if (method.compare(kSetClipboardDataMethod) == 0) {
497 const rapidjson::Value& document = *method_call.arguments();
498 rapidjson::Value::ConstMemberIterator itr = document.FindMember(kTextKey);
499 if (itr == document.MemberEnd()) {
500 result->Error(kClipboardError, kUnknownClipboardFormatMessage);
501 return;
502 }
503 if (!itr->value.IsString()) {
504 result->Error(kClipboardError, kUnknownClipboardFormatMessage);
505 return;
506 }
507 SetPlainText(itr->value.GetString(), std::move(result));
508 } else if (method.compare(kPlaySoundMethod) == 0) {
509 // Only one string argument is expected.
510 const rapidjson::Value& sound_type = method_call.arguments()[0];
511
512 SystemSoundPlay(sound_type.GetString(), std::move(result));
513 } else if (method.compare(kInitializationCompleteMethod) == 0) {
514 // Deprecated but should not cause an error.
515 result->Success();
516 } else {
517 result->NotImplemented();
518 }
519 }
520
521 WNDCLASS PlatformHandler::RegisterWindowClass() {
522 WNDCLASS window_class{};
523 window_class.hCursor = nullptr;
524 window_class.lpszClassName = kWindowClassName.c_str();
525 window_class.style = 0;
526 window_class.cbClsExtra = 0;
527 window_class.cbWndExtra = 0;
528 window_class.hInstance = GetModuleHandle(nullptr);
529 window_class.hIcon = nullptr;
530 window_class.hbrBackground = 0;
531 window_class.lpszMenuName = nullptr;
532 window_class.lpfnWndProc = WndProc;
533 RegisterClass(&window_class);
534 return window_class;
535 }
536
537 LRESULT PlatformHandler::WndProc(HWND const window,
538 UINT const message,
539 WPARAM const wparam,
540 LPARAM const lparam) noexcept {
541 return DefWindowProc(window, message, wparam, lparam);
542 }
543
544 } // namespace flutter
flutter::BinaryMessenger
Definition: binary_messenger.h:29
flutter::FlutterWindowsEngine
Definition: flutter_windows_engine.h:92
flutter::FlutterWindowsEngine::OnQuit
void OnQuit(std::optional< HWND > hwnd, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, UINT exit_code)
Definition: flutter_windows_engine.cc:1051
flutter::JsonMethodCodec
Definition: json_method_codec.h:16
flutter::MethodCall
Definition: method_call.h:18
flutter::MethodCall::method_name
const std::string & method_name() const
Definition: method_call.h:31
flutter::MethodCall::arguments
const T * arguments() const
Definition: method_call.h:34
flutter::MethodChannel
Definition: method_channel.h:34
flutter::MethodResult
Definition: method_result.h:17
flutter::PlatformHandler::QuitApplication
virtual void QuitApplication(std::optional< HWND > hwnd, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, UINT exit_code)
Definition: platform_handler.cc:447
flutter::PlatformHandler::GetHasStrings
virtual void GetHasStrings(std::unique_ptr< MethodResult< rapidjson::Document >> result)
Definition: platform_handler.cc:313
flutter::PlatformHandler::kSoundTypeTick
static constexpr char kSoundTypeTick[]
Definition: platform_handler.h:108
flutter::PlatformHandler::RequestAppExitSuccess
virtual void RequestAppExitSuccess(std::optional< HWND > hwnd, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, const rapidjson::Document *result, UINT exit_code)
Definition: platform_handler.cc:428
flutter::PlatformHandler::kClipboardError
static constexpr char kClipboardError[]
Definition: platform_handler.h:104
flutter::PlatformHandler::PlatformHandler
PlatformHandler(BinaryMessenger *messenger, FlutterWindowsEngine *engine, std::optional< std::function< std::unique_ptr< ScopedClipboardInterface >()>> scoped_clipboard_provider=std::nullopt)
Definition: platform_handler.cc:224
flutter::PlatformHandler::kSoundTypeClick
static constexpr char kSoundTypeClick[]
Definition: platform_handler.h:107
flutter::PlatformHandler::SystemSoundPlay
virtual void SystemSoundPlay(const std::string &sound_type, std::unique_ptr< MethodResult< rapidjson::Document >> result)
Definition: platform_handler.cc:366
flutter::PlatformHandler::kExitTypeCancelable
static constexpr char kExitTypeCancelable[]
Definition: platform_handler.h:44
flutter::PlatformHandler::SystemExitApplication
virtual void SystemExitApplication(AppExitType exit_type, UINT exit_code, std::unique_ptr< MethodResult< rapidjson::Document >> result)
Definition: platform_handler.cc:383
flutter::PlatformHandler::GetPlainText
virtual void GetPlainText(std::unique_ptr< MethodResult< rapidjson::Document >> result, std::string_view key)
Definition: platform_handler.cc:276
flutter::PlatformHandler::~PlatformHandler
virtual ~PlatformHandler()
Definition: platform_handler.cc:268
flutter::PlatformHandler::RequestAppExit
virtual void RequestAppExit(std::optional< HWND > hwnd, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, AppExitType exit_type, UINT exit_code)
Definition: platform_handler.cc:408
flutter::PlatformHandler::kExitTypeRequired
static constexpr char kExitTypeRequired[]
Definition: platform_handler.h:45
flutter::PlatformHandler::kSoundTypeAlert
static constexpr char kSoundTypeAlert[]
Definition: platform_handler.h:106
flutter::PlatformHandler::SetPlainText
virtual void SetPlainText(const std::string &text, std::unique_ptr< MethodResult< rapidjson::Document >> result)
Definition: platform_handler.cc:343
flutter_windows_view.h
callback
FlutterDesktopBinaryReply callback
Definition: flutter_windows_view_unittests.cc:52
json_method_codec.h
key
int key
Definition: keyboard_key_handler_unittests.cc:114
text
std::u16string text
Definition: keyboard_unittests.cc:332
message
Win32Message message
Definition: keyboard_unittests.cc:137
method_result_functions.h
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::AppExitType
AppExitType
Definition: platform_handler.h:27
flutter::AppExitType::required
@ required
flutter::AppExitType::cancelable
@ cancelable
flutter::kExitTypeNames
static constexpr const char * kExitTypeNames[]
Definition: platform_handler.cc:405
flutter::StringToAppExitType
static AppExitType StringToAppExitType(const std::string &string)
Definition: platform_handler.cc:214
kValueKey
static constexpr char kValueKey[]
Definition: platform_handler.cc:43
kInitializationCompleteMethod
static constexpr char kInitializationCompleteMethod[]
Definition: platform_handler.cc:26
kInvalidExitRequestMessage
static constexpr char kInvalidExitRequestMessage[]
Definition: platform_handler.cc:48
kGetClipboardDataMethod
static constexpr char kGetClipboardDataMethod[]
Definition: platform_handler.cc:21
kChannelName
static constexpr char kChannelName[]
Definition: platform_handler.cc:19
kHasStringsClipboardMethod
static constexpr char kHasStringsClipboardMethod[]
Definition: platform_handler.cc:22
kExitApplicationMethod
static constexpr char kExitApplicationMethod[]
Definition: platform_handler.cc:24
kExitResponseExit
static constexpr char kExitResponseExit[]
Definition: platform_handler.cc:36
kExitCodeKey
static constexpr char kExitCodeKey[]
Definition: platform_handler.cc:30
kErrorSuccess
static constexpr int kErrorSuccess
Definition: platform_handler.cc:45
kRequestAppExitMethod
static constexpr char kRequestAppExitMethod[]
Definition: platform_handler.cc:25
kUnknownClipboardFormatMessage
static constexpr char kUnknownClipboardFormatMessage[]
Definition: platform_handler.cc:40
kExitResponseKey
static constexpr char kExitResponseKey[]
Definition: platform_handler.cc:34
kPlaySoundMethod
static constexpr char kPlaySoundMethod[]
Definition: platform_handler.cc:28
kAccessDeniedErrorCode
static constexpr int kAccessDeniedErrorCode
Definition: platform_handler.cc:44
kExitResponseCancel
static constexpr char kExitResponseCancel[]
Definition: platform_handler.cc:35
kExitTypeKey
static constexpr char kExitTypeKey[]
Definition: platform_handler.cc:32
kTextPlainFormat
static constexpr char kTextPlainFormat[]
Definition: platform_handler.cc:38
kTextKey
static constexpr char kTextKey[]
Definition: platform_handler.cc:39
kSetClipboardDataMethod
static constexpr char kSetClipboardDataMethod[]
Definition: platform_handler.cc:23
kExitRequestError
static constexpr char kExitRequestError[]
Definition: platform_handler.cc:47
platform_handler.h