flutter_flutter/shell/platform/windows/platform_handler.cc
stuartmorgan 08ae3bb63e
Remove JSON codec from C++ client wrapper (#17312)
The JSON codec is awkward to use in the wrapper (since the client has to build and link one of the JSON libraries to do so). Since it would be very cumbersome to wrap in a C API, and there's essentially no reason to use it instead of the standard codec, this removes it from the wrapper entirely.

Since some system channels (internal to the engine) still use it, it's moved into common/cpp instead of being eliminated entirely. Internally we always use RapidJSON though, so the jsoncpp implementation is removed. Also adds some unit test coverage, since there wasn't any.

Fixes #30669
2020-04-02 14:57:46 -07:00

123 lines
3.7 KiB
C++

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/windows/platform_handler.h"
#include <windows.h>
#include <iostream>
#include "flutter/shell/platform/common/cpp/json_method_codec.h"
static constexpr char kChannelName[] = "flutter/platform";
static constexpr char kGetClipboardDataMethod[] = "Clipboard.getData";
static constexpr char kSetClipboardDataMethod[] = "Clipboard.setData";
static constexpr char kTextPlainFormat[] = "text/plain";
static constexpr char kTextKey[] = "text";
static constexpr char kUnknownClipboardFormatError[] =
"Unknown clipboard format error";
namespace flutter {
PlatformHandler::PlatformHandler(flutter::BinaryMessenger* messenger,
Win32FlutterWindow* window)
: channel_(std::make_unique<flutter::MethodChannel<rapidjson::Document>>(
messenger,
kChannelName,
&flutter::JsonMethodCodec::GetInstance())),
window_(window) {
channel_->SetMethodCallHandler(
[this](
const flutter::MethodCall<rapidjson::Document>& call,
std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result) {
HandleMethodCall(call, std::move(result));
});
}
void PlatformHandler::HandleMethodCall(
const flutter::MethodCall<rapidjson::Document>& method_call,
std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result) {
const std::string& method = method_call.method_name();
if (method.compare(kGetClipboardDataMethod) == 0) {
// Only one string argument is expected.
const rapidjson::Value& format = method_call.arguments()[0];
if (strcmp(format.GetString(), kTextPlainFormat) != 0) {
result->Error(kUnknownClipboardFormatError,
"Windows clipboard API only supports text.");
return;
}
auto clipboardData = GetClipboardString();
if (clipboardData.empty()) {
result->Error(kUnknownClipboardFormatError,
"Failed to retrieve clipboard data from win32 api.");
return;
}
rapidjson::Document document;
document.SetObject();
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
document.AddMember(rapidjson::Value(kTextKey, allocator),
rapidjson::Value(clipboardData, allocator), allocator);
result->Success(&document);
} else if (method.compare(kSetClipboardDataMethod) == 0) {
const rapidjson::Value& document = *method_call.arguments();
rapidjson::Value::ConstMemberIterator itr = document.FindMember(kTextKey);
if (itr == document.MemberEnd()) {
result->Error(kUnknownClipboardFormatError,
"Missing text to store on clipboard.");
return;
}
SetClipboardString(std::string(itr->value.GetString()));
result->Success();
} else {
result->NotImplemented();
}
}
std::string PlatformHandler::GetClipboardString() {
if (!OpenClipboard(nullptr)) {
return nullptr;
}
HANDLE data = GetClipboardData(CF_TEXT);
if (data == nullptr) {
CloseClipboard();
return nullptr;
}
const char* clipboardData = static_cast<char*>(GlobalLock(data));
if (clipboardData == nullptr) {
CloseClipboard();
return nullptr;
}
auto result = std::string(clipboardData);
GlobalUnlock(data);
CloseClipboard();
return result;
}
void PlatformHandler::SetClipboardString(std::string data) {
if (!OpenClipboard(nullptr)) {
return;
}
auto htext = GlobalAlloc(GMEM_MOVEABLE, data.size());
memcpy(GlobalLock(htext), data.c_str(), data.size());
SetClipboardData(CF_TEXT, htext);
CloseClipboard();
}
} // namespace flutter