Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1198,15 +1198,28 @@ FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
FILE: ../../../flutter/shell/platform/linux/fl_json_message_codec.cc
FILE: ../../../flutter/shell/platform/linux/fl_json_message_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_json_method_codec.cc
FILE: ../../../flutter/shell/platform/linux/fl_json_method_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_message_codec.cc
FILE: ../../../flutter/shell/platform/linux/fl_message_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_call.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_call_private.h
FILE: ../../../flutter/shell/platform/linux/fl_method_channel.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_channel_private.h
FILE: ../../../flutter/shell/platform/linux/fl_method_codec.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_codec_private.h
FILE: ../../../flutter/shell/platform/linux/fl_method_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_response.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_response_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_renderer.cc
FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
FILE: ../../../flutter/shell/platform/linux/fl_standard_message_codec.cc
FILE: ../../../flutter/shell/platform/linux/fl_standard_message_codec_private.h
FILE: ../../../flutter/shell/platform/linux/fl_standard_message_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_standard_method_codec.cc
FILE: ../../../flutter/shell/platform/linux/fl_standard_method_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_string_codec.cc
FILE: ../../../flutter/shell/platform/linux/fl_string_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_value.cc
Expand All @@ -1218,8 +1231,14 @@ FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messe
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_message_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_call.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_response.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_value.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
Expand Down
16 changes: 16 additions & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,14 @@ _public_headers = [
"public/flutter_linux/fl_dart_project.h",
"public/flutter_linux/fl_engine.h",
"public/flutter_linux/fl_json_message_codec.h",
"public/flutter_linux/fl_json_method_codec.h",
"public/flutter_linux/fl_message_codec.h",
"public/flutter_linux/fl_method_call.h",
"public/flutter_linux/fl_method_channel.h",
"public/flutter_linux/fl_method_codec.h",
"public/flutter_linux/fl_method_response.h",
"public/flutter_linux/fl_standard_message_codec.h",
"public/flutter_linux/fl_standard_method_codec.h",
"public/flutter_linux/fl_string_codec.h",
"public/flutter_linux/fl_value.h",
"public/flutter_linux/fl_view.h",
Expand All @@ -72,10 +78,16 @@ source_set("flutter_linux") {
"fl_dart_project.cc",
"fl_engine.cc",
"fl_json_message_codec.cc",
"fl_json_method_codec.cc",
"fl_message_codec.cc",
"fl_method_call.cc",
"fl_method_channel.cc",
"fl_method_codec.cc",
"fl_method_response.cc",
"fl_renderer.cc",
"fl_renderer_x11.cc",
"fl_standard_message_codec.cc",
"fl_standard_method_codec.cc",
"fl_string_codec.cc",
"fl_value.cc",
"fl_view.cc",
Expand Down Expand Up @@ -107,8 +119,12 @@ executable("flutter_linux_unittests") {
"fl_binary_codec_test.cc",
"fl_dart_project_test.cc",
"fl_json_message_codec_test.cc",
"fl_json_method_codec_test.cc",
"fl_message_codec_test.cc",
"fl_method_codec_test.cc",
"fl_method_response_test.cc",
"fl_standard_message_codec_test.cc",
"fl_standard_method_codec_test.cc",
"fl_string_codec_test.cc",
"fl_value_test.cc",
"testing/fl_test.cc",
Expand Down
205 changes: 205 additions & 0 deletions shell/platform/linux/fl_json_method_codec.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// 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/linux/public/flutter_linux/fl_json_method_codec.h"

#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"

#include <gmodule.h>

static constexpr char kMethodKey[] = "method";
static constexpr char kArgsKey[] = "args";

struct _FlJsonMethodCodec {
FlMethodCodec parent_instance;

FlJsonMessageCodec* codec;
};

G_DEFINE_TYPE(FlJsonMethodCodec,
fl_json_method_codec,
fl_method_codec_get_type())

static void fl_json_method_codec_dispose(GObject* object) {
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(object);

g_clear_object(&self->codec);

G_OBJECT_CLASS(fl_json_method_codec_parent_class)->dispose(object);
}

// Implements FlMethodCodec::encode_method_call
static GBytes* fl_json_method_codec_encode_method_call(FlMethodCodec* codec,
const gchar* name,
FlValue* args,
GError** error) {
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);

g_autoptr(FlValue) message = fl_value_new_map();
fl_value_set_take(message, fl_value_new_string(kMethodKey),
fl_value_new_string(name));
fl_value_set_take(message, fl_value_new_string(kArgsKey),
args != nullptr ? fl_value_ref(args) : fl_value_new_null());

return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
error);
}

// Implements FlMethodCodec::decode_method_call
static gboolean fl_json_method_codec_decode_method_call(FlMethodCodec* codec,
GBytes* message,
gchar** name,
FlValue** args,
GError** error) {
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);

g_autoptr(FlValue) value = fl_message_codec_decode_message(
FL_MESSAGE_CODEC(self->codec), message, error);
if (value == nullptr)
return FALSE;

if (fl_value_get_type(value) != FL_VALUE_TYPE_MAP) {
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
"Expected JSON map in method resonse, got %d instead",
fl_value_get_type(value));
return FALSE;
}

FlValue* method_value = fl_value_lookup_string(value, kMethodKey);
if (method_value == nullptr) {
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
"Missing JSON method field in method resonse");
return FALSE;
}
if (fl_value_get_type(method_value) != FL_VALUE_TYPE_STRING) {
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
"Expected JSON string for method name, got %d instead",
fl_value_get_type(method_value));
return FALSE;
}
FlValue* args_value = fl_value_lookup_string(value, kArgsKey);

*name = g_strdup(fl_value_get_string(method_value));
*args = args_value != nullptr ? fl_value_ref(args_value) : nullptr;

return TRUE;
}

// Implements FlMethodCodec::encode_success_envelope
static GBytes* fl_json_method_codec_encode_success_envelope(
FlMethodCodec* codec,
FlValue* result,
GError** error) {
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);

g_autoptr(FlValue) message = fl_value_new_list();
fl_value_append_take(
message, result != nullptr ? fl_value_ref(result) : fl_value_new_null());

return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
error);
}

// Implements FlMethodCodec::encode_error_envelope
static GBytes* fl_json_method_codec_encode_error_envelope(
FlMethodCodec* codec,
const gchar* code,
const gchar* error_message,
FlValue* details,
GError** error) {
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);

g_autoptr(FlValue) message = fl_value_new_list();
fl_value_append_take(message, fl_value_new_string(code));
fl_value_append_take(message, error_message != nullptr
? fl_value_new_string(error_message)
: fl_value_new_null());
fl_value_append_take(message, details != nullptr ? fl_value_ref(details)
: fl_value_new_null());

return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
error);
}

// Implements FlMethodCodec::decode_response
static FlMethodResponse* fl_json_method_codec_decode_response(
FlMethodCodec* codec,
GBytes* message,
GError** error) {
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);

g_autoptr(FlValue) value = fl_message_codec_decode_message(
FL_MESSAGE_CODEC(self->codec), message, error);
if (value == nullptr)
return nullptr;

if (fl_value_get_type(value) != FL_VALUE_TYPE_LIST) {
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
"Expected JSON list in method resonse, got %d instead",
fl_value_get_type(value));
return nullptr;
}

size_t length = fl_value_get_length(value);
if (length == 1) {
return FL_METHOD_RESPONSE(
fl_method_success_response_new(fl_value_get_list_value(value, 0)));
} else if (length == 3) {
FlValue* code_value = fl_value_get_list_value(value, 0);
if (fl_value_get_type(code_value) != FL_VALUE_TYPE_STRING) {
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
"Error code wrong type");
return nullptr;
}
const gchar* code = fl_value_get_string(code_value);

FlValue* message_value = fl_value_get_list_value(value, 1);
if (fl_value_get_type(message_value) != FL_VALUE_TYPE_STRING &&
fl_value_get_type(message_value) != FL_VALUE_TYPE_NULL) {
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
"Error message wrong type");
return nullptr;
}
const gchar* message =
fl_value_get_type(message_value) == FL_VALUE_TYPE_STRING
? fl_value_get_string(message_value)
: nullptr;

FlValue* args = fl_value_get_list_value(value, 2);
if (fl_value_get_type(args) == FL_VALUE_TYPE_NULL)
args = nullptr;

return FL_METHOD_RESPONSE(
fl_method_error_response_new(code, message, args));
} else {
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
"Got response envelope of length %zi, expected 1 (success) or "
"3 (error)",
length);
return nullptr;
}
}

static void fl_json_method_codec_class_init(FlJsonMethodCodecClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_json_method_codec_dispose;
FL_METHOD_CODEC_CLASS(klass)->encode_method_call =
fl_json_method_codec_encode_method_call;
FL_METHOD_CODEC_CLASS(klass)->decode_method_call =
fl_json_method_codec_decode_method_call;
FL_METHOD_CODEC_CLASS(klass)->encode_success_envelope =
fl_json_method_codec_encode_success_envelope;
FL_METHOD_CODEC_CLASS(klass)->encode_error_envelope =
fl_json_method_codec_encode_error_envelope;
FL_METHOD_CODEC_CLASS(klass)->decode_response =
fl_json_method_codec_decode_response;
}

static void fl_json_method_codec_init(FlJsonMethodCodec* self) {
self->codec = fl_json_message_codec_new();
}

G_MODULE_EXPORT FlJsonMethodCodec* fl_json_method_codec_new() {
return static_cast<FlJsonMethodCodec*>(
g_object_new(fl_json_method_codec_get_type(), nullptr));
}
Loading