in shell/platform/fuchsia/flutter/platform_view.cc [663:834]
bool PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage(
std::unique_ptr<flutter::PlatformMessage> message) {
FML_DCHECK(message->channel() == kFlutterPlatformViewsChannel);
const auto& data = message->data();
rapidjson::Document document;
document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
data.GetSize());
if (document.HasParseError() || !document.IsObject()) {
FML_LOG(ERROR) << "Could not parse document";
return false;
}
auto root = document.GetObject();
auto method_member = root.FindMember("method");
if (method_member == root.MemberEnd() || !method_member->value.IsString()) {
return false;
}
std::string method(method_member->value.GetString());
if (method == "View.enableWireframe") {
auto args_it = root.FindMember("args");
if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
FML_LOG(ERROR) << "No arguments found.";
return false;
}
const auto& args = args_it->value;
auto enable = args.FindMember("enable");
if (!enable->value.IsBool()) {
FML_LOG(ERROR) << "Argument 'enable' is not a bool";
return false;
}
wireframe_enabled_callback_(enable->value.GetBool());
} else if (method == "View.create") {
auto args_it = root.FindMember("args");
if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
FML_LOG(ERROR) << "No arguments found.";
return false;
}
const auto& args = args_it->value;
auto view_id = args.FindMember("viewId");
if (!view_id->value.IsUint64()) {
FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
return false;
}
auto hit_testable = args.FindMember("hitTestable");
if (!hit_testable->value.IsBool()) {
FML_LOG(ERROR) << "Argument 'hitTestable' is not a bool";
return false;
}
auto focusable = args.FindMember("focusable");
if (!focusable->value.IsBool()) {
FML_LOG(ERROR) << "Argument 'focusable' is not a bool";
return false;
}
auto on_view_created = fml::MakeCopyable(
[platform_task_runner = task_runners_.GetPlatformTaskRunner(),
message = std::move(message)]() {
// The client is waiting for view creation. Send an empty response
// back to signal the view was created.
if (message->response()) {
message->response()->Complete(std::make_unique<fml::DataMapping>(
std::vector<uint8_t>({'[', '0', ']'})));
}
});
OnCreateView(std::move(on_view_created), view_id->value.GetUint64(),
hit_testable->value.GetBool(), focusable->value.GetBool());
return true;
} else if (method == "View.update") {
auto args_it = root.FindMember("args");
if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
FML_LOG(ERROR) << "No arguments found.";
return false;
}
const auto& args = args_it->value;
auto view_id = args.FindMember("viewId");
if (!view_id->value.IsUint64()) {
FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
return false;
}
auto hit_testable = args.FindMember("hitTestable");
if (!hit_testable->value.IsBool()) {
FML_LOG(ERROR) << "Argument 'hitTestable' is not a bool";
return false;
}
auto focusable = args.FindMember("focusable");
if (!focusable->value.IsBool()) {
FML_LOG(ERROR) << "Argument 'focusable' is not a bool";
return false;
}
SkRect view_occlusion_hint_raw = SkRect::MakeEmpty();
auto view_occlusion_hint = args.FindMember("viewOcclusionHintLTRB");
if (view_occlusion_hint != args.MemberEnd()) {
if (view_occlusion_hint->value.IsArray()) {
const auto& view_occlusion_hint_array =
view_occlusion_hint->value.GetArray();
if (view_occlusion_hint_array.Size() == 4) {
bool parse_error = false;
for (int i = 0; i < 4; i++) {
auto& array_val = view_occlusion_hint_array[i];
if (!array_val.IsDouble()) {
FML_LOG(ERROR) << "Argument 'viewOcclusionHintLTRB' element " << i
<< " is not a double";
parse_error = true;
break;
}
}
if (!parse_error) {
view_occlusion_hint_raw =
SkRect::MakeLTRB(view_occlusion_hint_array[0].GetDouble(),
view_occlusion_hint_array[1].GetDouble(),
view_occlusion_hint_array[2].GetDouble(),
view_occlusion_hint_array[3].GetDouble());
}
} else {
FML_LOG(ERROR)
<< "Argument 'viewOcclusionHintLTRB' expected size 4; got "
<< view_occlusion_hint_array.Size();
}
} else {
FML_LOG(ERROR)
<< "Argument 'viewOcclusionHintLTRB' is not a double array";
}
} else {
FML_LOG(WARNING) << "Argument 'viewOcclusionHintLTRB' is missing";
}
on_update_view_callback_(
view_id->value.GetUint64(), view_occlusion_hint_raw,
hit_testable->value.GetBool(), focusable->value.GetBool());
if (message->response()) {
message->response()->Complete(std::make_unique<fml::DataMapping>(
std::vector<uint8_t>({'[', '0', ']'})));
return true;
}
} else if (method == "View.dispose") {
auto args_it = root.FindMember("args");
if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
FML_LOG(ERROR) << "No arguments found.";
return false;
}
const auto& args = args_it->value;
auto view_id = args.FindMember("viewId");
if (!view_id->value.IsUint64()) {
FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
return false;
}
OnDisposeView(view_id->value.GetUint64());
if (message->response()) {
message->response()->Complete(std::make_unique<fml::DataMapping>(
std::vector<uint8_t>({'[', '0', ']'})));
return true;
}
} else if (method.rfind("View.focus", 0) == 0) {
return focus_delegate_->HandlePlatformMessage(root, message->response());
} else {
FML_DLOG(ERROR) << "Unknown " << message->channel() << " method " << method;
}
// Complete with an empty response by default.
return false;
}