| Flutter Linux Embedder |

fl_json_method_codec.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/linux/public/flutter_linux/fl_json_method_codec.h"
6
7 #include <gmodule.h>
8
9 #include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
10
11 static constexpr char kMethodKey[] = "method";
12 static constexpr char kArgsKey[] = "args";
13
14 struct _FlJsonMethodCodec {
15 FlMethodCodec parent_instance;
16
17 FlJsonMessageCodec* codec;
18 };
19
20 G_DEFINE_TYPE(FlJsonMethodCodec,
21 fl_json_method_codec,
22 fl_method_codec_get_type())
23
24 static void fl_json_method_codec_dispose(GObject* object) {
25 FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(object);
26
27 g_clear_object(&self->codec);
28
29 G_OBJECT_CLASS(fl_json_method_codec_parent_class)->dispose(object);
30 }
31
32 // Implements FlMethodCodec::encode_method_call.
33 static GBytes* fl_json_method_codec_encode_method_call(FlMethodCodec* codec,
34 const gchar* name,
35 FlValue* args,
36 GError** error) {
37 FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
38
39 g_autoptr(FlValue) message = fl_value_new_map();
40 fl_value_set_take(message, fl_value_new_string(kMethodKey),
41 fl_value_new_string(name));
42 fl_value_set_take(message, fl_value_new_string(kArgsKey),
43 args != nullptr ? fl_value_ref(args) : fl_value_new_null());
44
45 return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
46 error);
47 }
48
49 // Implements FlMethodCodec::decode_method_call.
50 static gboolean fl_json_method_codec_decode_method_call(FlMethodCodec* codec,
51 GBytes* message,
52 gchar** name,
53 FlValue** args,
54 GError** error) {
55 FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
56
57 g_autoptr(FlValue) value = fl_message_codec_decode_message(
58 FL_MESSAGE_CODEC(self->codec), message, error);
59 if (value == nullptr) {
60 return FALSE;
61 }
62
63 if (fl_value_get_type(value) != FL_VALUE_TYPE_MAP) {
64 g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
65 "Expected JSON map in method response, got %d instead",
66 fl_value_get_type(value));
67 return FALSE;
68 }
69
70 FlValue* method_value = fl_value_lookup_string(value, kMethodKey);
71 if (method_value == nullptr) {
72 g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
73 "Missing JSON method field in method response");
74 return FALSE;
75 }
76 if (fl_value_get_type(method_value) != FL_VALUE_TYPE_STRING) {
77 g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
78 "Expected JSON string for method name, got %d instead",
79 fl_value_get_type(method_value));
80 return FALSE;
81 }
82 FlValue* args_value = fl_value_lookup_string(value, kArgsKey);
83
84 *name = g_strdup(fl_value_get_string(method_value));
85 *args = args_value != nullptr ? fl_value_ref(args_value) : nullptr;
86
87 return TRUE;
88 }
89
90 // Implements FlMethodCodec::encode_success_envelope.
91 static GBytes* fl_json_method_codec_encode_success_envelope(
92 FlMethodCodec* codec,
93 FlValue* result,
94 GError** error) {
95 FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
96
97 g_autoptr(FlValue) message = fl_value_new_list();
98 fl_value_append_take(
99 message, result != nullptr ? fl_value_ref(result) : fl_value_new_null());
100
101 return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
102 error);
103 }
104
105 // Implements FlMethodCodec::encode_error_envelope.
106 static GBytes* fl_json_method_codec_encode_error_envelope(
107 FlMethodCodec* codec,
108 const gchar* code,
109 const gchar* error_message,
110 FlValue* details,
111 GError** error) {
112 FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
113
114 g_autoptr(FlValue) message = fl_value_new_list();
115 fl_value_append_take(message, fl_value_new_string(code));
116 fl_value_append_take(message, error_message != nullptr
117 ? fl_value_new_string(error_message)
118 : fl_value_new_null());
119 fl_value_append_take(message, details != nullptr ? fl_value_ref(details)
120 : fl_value_new_null());
121
122 return fl_message_codec_encode_message(FL_MESSAGE_CODEC(self->codec), message,
123 error);
124 }
125
126 // Implements FlMethodCodec::decode_response.
127 static FlMethodResponse* fl_json_method_codec_decode_response(
128 FlMethodCodec* codec,
129 GBytes* message,
130 GError** error) {
131 FlJsonMethodCodec* self = FL_JSON_METHOD_CODEC(codec);
132
133 g_autoptr(FlValue) value = fl_message_codec_decode_message(
134 FL_MESSAGE_CODEC(self->codec), message, error);
135 if (value == nullptr) {
136 return nullptr;
137 }
138
139 if (fl_value_get_type(value) != FL_VALUE_TYPE_LIST) {
140 g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
141 "Expected JSON list in method response, got %d instead",
142 fl_value_get_type(value));
143 return nullptr;
144 }
145
146 size_t length = fl_value_get_length(value);
147 if (length == 1) {
148 return FL_METHOD_RESPONSE(
149 fl_method_success_response_new(fl_value_get_list_value(value, 0)));
150 } else if (length == 3) {
151 FlValue* code_value = fl_value_get_list_value(value, 0);
152 if (fl_value_get_type(code_value) != FL_VALUE_TYPE_STRING) {
153 g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
154 "Error code wrong type");
155 return nullptr;
156 }
157 const gchar* code = fl_value_get_string(code_value);
158
159 FlValue* message_value = fl_value_get_list_value(value, 1);
160 if (fl_value_get_type(message_value) != FL_VALUE_TYPE_STRING &&
161 fl_value_get_type(message_value) != FL_VALUE_TYPE_NULL) {
162 g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
163 "Error message wrong type");
164 return nullptr;
165 }
166 const gchar* message =
167 fl_value_get_type(message_value) == FL_VALUE_TYPE_STRING
168 ? fl_value_get_string(message_value)
169 : nullptr;
170
171 FlValue* args = fl_value_get_list_value(value, 2);
172 if (fl_value_get_type(args) == FL_VALUE_TYPE_NULL) {
173 args = nullptr;
174 }
175
176 return FL_METHOD_RESPONSE(
177 fl_method_error_response_new(code, message, args));
178 } else {
179 g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
180 "Got response envelope of length %zi, expected 1 (success) or "
181 "3 (error)",
182 length);
183 return nullptr;
184 }
185 }
186
187 static void fl_json_method_codec_class_init(FlJsonMethodCodecClass* klass) {
188 G_OBJECT_CLASS(klass)->dispose = fl_json_method_codec_dispose;
189 FL_METHOD_CODEC_CLASS(klass)->encode_method_call =
190 fl_json_method_codec_encode_method_call;
191 FL_METHOD_CODEC_CLASS(klass)->decode_method_call =
192 fl_json_method_codec_decode_method_call;
193 FL_METHOD_CODEC_CLASS(klass)->encode_success_envelope =
194 fl_json_method_codec_encode_success_envelope;
195 FL_METHOD_CODEC_CLASS(klass)->encode_error_envelope =
196 fl_json_method_codec_encode_error_envelope;
197 FL_METHOD_CODEC_CLASS(klass)->decode_response =
198 fl_json_method_codec_decode_response;
199 }
200
201 static void fl_json_method_codec_init(FlJsonMethodCodec* self) {
202 self->codec = fl_json_message_codec_new();
203 }
204
205 G_MODULE_EXPORT FlJsonMethodCodec* fl_json_method_codec_new() {
206 return static_cast<FlJsonMethodCodec*>(
207 g_object_new(fl_json_method_codec_get_type(), nullptr));
208 }
fl_json_method_codec_decode_response
static FlMethodResponse * fl_json_method_codec_decode_response(FlMethodCodec *codec, GBytes *message, GError **error)
Definition: fl_json_method_codec.cc:127
fl_json_method_codec_new
G_MODULE_EXPORT FlJsonMethodCodec * fl_json_method_codec_new()
Definition: fl_json_method_codec.cc:205
FL_VALUE_TYPE_MAP
@ FL_VALUE_TYPE_MAP
Definition: fl_value.h:75
kMethodKey
static constexpr char kMethodKey[]
Definition: fl_json_method_codec.cc:11
fl_method_error_response_new
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
Definition: fl_method_response.cc:144
fl_json_method_codec_init
static void fl_json_method_codec_init(FlJsonMethodCodec *self)
Definition: fl_json_method_codec.cc:201
fl_json_method_codec_decode_method_call
static gboolean fl_json_method_codec_decode_method_call(FlMethodCodec *codec, GBytes *message, gchar **name, FlValue **args, GError **error)
Definition: fl_json_method_codec.cc:50
fl_value_new_list
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition: fl_value.cc:349
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
fl_json_message_codec_new
G_MODULE_EXPORT FlJsonMessageCodec * fl_json_message_codec_new()
Definition: fl_json_message_codec.cc:306
fl_json_message_codec.h
fl_value_set_take
G_MODULE_EXPORT void fl_value_set_take(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:618
fl_value_new_null
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:251
FL_VALUE_TYPE_LIST
@ FL_VALUE_TYPE_LIST
Definition: fl_value.h:74
fl_value_lookup_string
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition: fl_value.cc:811
fl_value_get_string
const G_MODULE_EXPORT gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:682
_FlJsonMethodCodec::codec
FlJsonMessageCodec * codec
Definition: fl_json_method_codec.cc:17
fl_method_success_response_new
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
Definition: fl_method_response.cc:126
FL_VALUE_TYPE_NULL
@ FL_VALUE_TYPE_NULL
Definition: fl_value.h:65
fl_value_ref
G_MODULE_EXPORT FlValue * fl_value_ref(FlValue *self)
Definition: fl_value.cc:394
fl_message_codec_decode_message
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, GError **error)
Definition: fl_message_codec.cc:33
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
fl_value_get_type
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
fl_value_get_list_value
G_MODULE_EXPORT FlValue * fl_value_get_list_value(FlValue *self, size_t index)
Definition: fl_value.cc:776
FL_VALUE_TYPE_STRING
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:69
G_DEFINE_TYPE
G_DEFINE_TYPE(FlJsonMethodCodec, fl_json_method_codec, fl_method_codec_get_type()) static void fl_json_method_codec_dispose(GObject *object)
Definition: fl_json_method_codec.cc:20
fl_json_method_codec_encode_success_envelope
static GBytes * fl_json_method_codec_encode_success_envelope(FlMethodCodec *codec, FlValue *result, GError **error)
Definition: fl_json_method_codec.cc:91
_FlJsonMethodCodec
Definition: fl_json_method_codec.cc:14
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
_FlJsonMethodCodec::parent_instance
FlMethodCodec parent_instance
Definition: fl_json_method_codec.cc:15
FL_MESSAGE_CODEC_ERROR_FAILED
@ FL_MESSAGE_CODEC_ERROR_FAILED
Definition: fl_message_codec.h:34
fl_value_append_take
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition: fl_value.cc:600
fl_value_get_length
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
Definition: fl_value.cc:724
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
fl_json_method_codec_encode_method_call
static GBytes * fl_json_method_codec_encode_method_call(FlMethodCodec *codec, const gchar *name, FlValue *args, GError **error)
Definition: fl_json_method_codec.cc:33
args
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: fl_event_channel.h:89
kArgsKey
static constexpr char kArgsKey[]
Definition: fl_json_method_codec.cc:12
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_json_method_codec_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)
Definition: fl_json_method_codec.cc:106
fl_message_codec_encode_message
G_MODULE_EXPORT GBytes * fl_message_codec_encode_message(FlMessageCodec *self, FlValue *message, GError **error)
Definition: fl_message_codec.cc:17
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
length
size_t length
Definition: fl_standard_message_codec_test.cc:1113
fl_json_method_codec_class_init
static void fl_json_method_codec_class_init(FlJsonMethodCodecClass *klass)
Definition: fl_json_method_codec.cc:187
fl_json_method_codec.h
fl_value_new_string
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
FL_MESSAGE_CODEC_ERROR
#define FL_MESSAGE_CODEC_ERROR
Definition: fl_message_codec.h:30