Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b6fd490

Browse files
committed
Add FlJsonMethodCodec
1 parent 19500c9 commit b6fd490

File tree

6 files changed

+641
-0
lines changed

6 files changed

+641
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,8 @@ FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
11951195
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
11961196
FILE: ../../../flutter/shell/platform/linux/fl_json_message_codec.cc
11971197
FILE: ../../../flutter/shell/platform/linux/fl_json_message_codec_test.cc
1198+
FILE: ../../../flutter/shell/platform/linux/fl_json_method_codec.cc
1199+
FILE: ../../../flutter/shell/platform/linux/fl_json_method_codec_test.cc
11981200
FILE: ../../../flutter/shell/platform/linux/fl_message_codec.cc
11991201
FILE: ../../../flutter/shell/platform/linux/fl_message_codec_test.cc
12001202
FILE: ../../../flutter/shell/platform/linux/fl_method_channel.cc
@@ -1222,6 +1224,7 @@ FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messe
12221224
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
12231225
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
12241226
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h
1227+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h
12251228
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_message_codec.h
12261229
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h
12271230
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h

shell/platform/linux/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ _public_headers = [
4949
"public/flutter_linux/fl_dart_project.h",
5050
"public/flutter_linux/fl_engine.h",
5151
"public/flutter_linux/fl_json_message_codec.h",
52+
"public/flutter_linux/fl_json_method_codec.h",
5253
"public/flutter_linux/fl_message_codec.h",
5354
"public/flutter_linux/fl_method_channel.h",
5455
"public/flutter_linux/fl_method_codec.h",
@@ -74,6 +75,7 @@ source_set("flutter_linux") {
7475
"fl_dart_project.cc",
7576
"fl_engine.cc",
7677
"fl_json_message_codec.cc",
78+
"fl_json_method_codec.cc",
7779
"fl_message_codec.cc",
7880
"fl_method_channel.cc",
7981
"fl_method_codec.cc",
@@ -112,6 +114,7 @@ executable("flutter_linux_unittests") {
112114
"fl_binary_codec_test.cc",
113115
"fl_dart_project_test.cc",
114116
"fl_json_message_codec_test.cc",
117+
"fl_json_method_codec_test.cc",
115118
"fl_message_codec_test.cc",
116119
"fl_method_codec_test.cc",
117120
"fl_method_response_test.cc",
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
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/linux/public/flutter_linux/fl_json_method_codec.h"
6+
7+
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
8+
9+
#include <gmodule.h>
10+
11+
struct _FlJsonMethodCodec {
12+
FlMethodCodec parent_instance;
13+
14+
FlJsonMessageCodec* codec;
15+
};
16+
17+
G_DEFINE_TYPE(FlJsonMethodCodec,
18+
fl_json_method_codec,
19+
fl_method_codec_get_type())
20+
21+
static void fl_json_method_codec_dispose(GObject* object) {
22+
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(object);
23+
24+
g_clear_object(&self->codec);
25+
26+
G_OBJECT_CLASS(fl_json_method_codec_parent_class)->dispose(object);
27+
}
28+
29+
// Implements FlMethodCodec::encode_method_call
30+
static GBytes* fl_json_method_codec_encode_method_call(FlMethodCodec* codec,
31+
const gchar* name,
32+
FlValue* args,
33+
GError** error) {
34+
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
35+
36+
g_autoptr(FlValue) message = fl_value_new_map();
37+
fl_value_set_take(message, fl_value_new_string("method"),
38+
fl_value_new_string(name));
39+
fl_value_set_take(message, fl_value_new_string("args"),
40+
args != nullptr ? fl_value_ref(args) : fl_value_new_null());
41+
42+
return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
43+
error);
44+
}
45+
46+
// Implements FlMethodCodec::decode_method_call
47+
static gboolean fl_json_method_codec_decode_method_call(FlMethodCodec* codec,
48+
GBytes* message,
49+
gchar** name,
50+
FlValue** args,
51+
GError** error) {
52+
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
53+
54+
g_autoptr(FlValue) value = fl_message_codec_decode_message(
55+
FL_MESSAGE_CODEC(self->codec), message, error);
56+
if (value == nullptr)
57+
return FALSE;
58+
59+
if (fl_value_get_type(value) != FL_VALUE_TYPE_MAP) {
60+
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
61+
"Expected JSON map in method resonse, got %d instead",
62+
fl_value_get_type(value));
63+
return FALSE;
64+
}
65+
66+
FlValue* method_value = fl_value_lookup_string(value, "method");
67+
if (method_value == nullptr) {
68+
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
69+
"Missing JSON method field in method resonse");
70+
return FALSE;
71+
}
72+
if (fl_value_get_type(method_value) != FL_VALUE_TYPE_STRING) {
73+
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
74+
"Expected JSON string for method name, got %d instead",
75+
fl_value_get_type(method_value));
76+
return FALSE;
77+
}
78+
FlValue* args_value = fl_value_lookup_string(value, "args");
79+
80+
*name = g_strdup(fl_value_get_string(method_value));
81+
*args = args_value != nullptr ? fl_value_ref(args_value) : nullptr;
82+
83+
return TRUE;
84+
}
85+
86+
// Implements FlMethodCodec::encode_success_envelope
87+
static GBytes* fl_json_method_codec_encode_success_envelope(
88+
FlMethodCodec* codec,
89+
FlValue* result,
90+
GError** error) {
91+
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
92+
93+
g_autoptr(FlValue) message = fl_value_new_list();
94+
fl_value_append_take(
95+
message, result != nullptr ? fl_value_ref(result) : fl_value_new_null());
96+
97+
return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
98+
error);
99+
}
100+
101+
// Implements FlMethodCodec::encode_error_envelope
102+
static GBytes* fl_json_method_codec_encode_error_envelope(
103+
FlMethodCodec* codec,
104+
const gchar* code,
105+
const gchar* error_message,
106+
FlValue* details,
107+
GError** error) {
108+
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
109+
110+
g_autoptr(FlValue) message = fl_value_new_list();
111+
fl_value_append_take(message, fl_value_new_string(code));
112+
fl_value_append_take(message, error_message != nullptr
113+
? fl_value_new_string(error_message)
114+
: fl_value_new_null());
115+
fl_value_append_take(message, details != nullptr ? fl_value_ref(details)
116+
: fl_value_new_null());
117+
118+
return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
119+
error);
120+
}
121+
122+
// Implements FlMethodCodec::decode_response
123+
static FlMethodResponse* fl_json_method_codec_decode_response(
124+
FlMethodCodec* codec,
125+
GBytes* message,
126+
GError** error) {
127+
FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
128+
129+
g_autoptr(FlValue) value = fl_message_codec_decode_message(
130+
FL_MESSAGE_CODEC(self->codec), message, error);
131+
if (value == nullptr)
132+
return nullptr;
133+
134+
if (fl_value_get_type(value) != FL_VALUE_TYPE_LIST) {
135+
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
136+
"Expected JSON list in method resonse, got %d instead",
137+
fl_value_get_type(value));
138+
return nullptr;
139+
}
140+
141+
size_t length = fl_value_get_length(value);
142+
if (length == 1) {
143+
return FL_METHOD_RESPONSE(
144+
fl_method_success_response_new(fl_value_get_list_value(value, 0)));
145+
} else if (length == 3) {
146+
FlValue* code_value = fl_value_get_list_value(value, 0);
147+
if (fl_value_get_type(code_value) != FL_VALUE_TYPE_STRING) {
148+
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
149+
"Error code wrong type");
150+
return nullptr;
151+
}
152+
const gchar* code = fl_value_get_string(code_value);
153+
154+
FlValue* message_value = fl_value_get_list_value(value, 1);
155+
if (fl_value_get_type(message_value) != FL_VALUE_TYPE_STRING &&
156+
fl_value_get_type(message_value) != FL_VALUE_TYPE_NULL) {
157+
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
158+
"Error message wrong type");
159+
return nullptr;
160+
}
161+
const gchar* message =
162+
fl_value_get_type(message_value) == FL_VALUE_TYPE_STRING
163+
? fl_value_get_string(message_value)
164+
: nullptr;
165+
166+
FlValue* args = fl_value_get_list_value(value, 2);
167+
if (fl_value_get_type(args) == FL_VALUE_TYPE_NULL)
168+
args = nullptr;
169+
170+
return FL_METHOD_RESPONSE(
171+
fl_method_error_response_new(code, message, args));
172+
} else {
173+
g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
174+
"Got response envelope of length %zi, expected 1 (success) or "
175+
"3 (error)",
176+
length);
177+
return nullptr;
178+
}
179+
}
180+
181+
static void fl_json_method_codec_class_init(FlJsonMethodCodecClass* klass) {
182+
G_OBJECT_CLASS(klass)->dispose = fl_json_method_codec_dispose;
183+
FL_METHOD_CODEC_CLASS(klass)->encode_method_call =
184+
fl_json_method_codec_encode_method_call;
185+
FL_METHOD_CODEC_CLASS(klass)->decode_method_call =
186+
fl_json_method_codec_decode_method_call;
187+
FL_METHOD_CODEC_CLASS(klass)->encode_success_envelope =
188+
fl_json_method_codec_encode_success_envelope;
189+
FL_METHOD_CODEC_CLASS(klass)->encode_error_envelope =
190+
fl_json_method_codec_encode_error_envelope;
191+
FL_METHOD_CODEC_CLASS(klass)->decode_response =
192+
fl_json_method_codec_decode_response;
193+
}
194+
195+
static void fl_json_method_codec_init(FlJsonMethodCodec* self) {
196+
self->codec = fl_json_message_codec_new();
197+
}
198+
199+
G_MODULE_EXPORT FlJsonMethodCodec* fl_json_method_codec_new() {
200+
return static_cast<FlJsonMethodCodec*>(
201+
g_object_new(fl_json_method_codec_get_type(), nullptr));
202+
}

0 commit comments

Comments
 (0)