Flutter Engine
The Flutter Engine
fl_standard_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_standard_method_codec.h"
6
7#include <gmodule.h>
8
9#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
10
11// See lib/src/services/message_codecs.dart in Flutter source for description of
12// encoding.
13
14// Envelope codes.
15static constexpr guint8 kEnvelopeTypeSuccess = 0;
16static constexpr guint8 kEnvelopeTypeError = 1;
17
19 FlMethodCodec parent_instance;
20
21 FlStandardMessageCodec* message_codec;
22};
23
25
26G_DEFINE_TYPE(FlStandardMethodCodec,
27 fl_standard_method_codec,
28 fl_method_codec_get_type())
29
30static void fl_standard_method_codec_set_property(GObject* object,
31 guint prop_id,
32 const GValue* value,
33 GParamSpec* pspec) {
34 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(object);
35
36 switch (prop_id) {
38 g_set_object(&self->message_codec,
39 FL_STANDARD_MESSAGE_CODEC(g_value_get_object(value)));
40 break;
41 default:
42 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
43 break;
44 }
45}
46
47static void fl_standard_method_codec_get_property(GObject* object,
48 guint prop_id,
49 GValue* value,
50 GParamSpec* pspec) {
51 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(object);
52
53 switch (prop_id) {
55 g_value_set_object(value, self->message_codec);
56 break;
57 default:
58 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
59 break;
60 }
61}
62
63static void fl_standard_method_codec_dispose(GObject* object) {
64 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(object);
65
66 g_clear_object(&self->message_codec);
67
68 G_OBJECT_CLASS(fl_standard_method_codec_parent_class)->dispose(object);
69}
70
71// Implements FlMethodCodec::encode_method_call.
72static GBytes* fl_standard_method_codec_encode_method_call(FlMethodCodec* codec,
73 const gchar* name,
75 GError** error) {
76 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
77
78 g_autoptr(GByteArray) buffer = g_byte_array_new();
79 g_autoptr(FlValue) name_value = fl_value_new_string(name);
81 name_value, error)) {
82 return nullptr;
83 }
85 error)) {
86 return nullptr;
87 }
88
89 return g_byte_array_free_to_bytes(
90 static_cast<GByteArray*>(g_steal_pointer(&buffer)));
91}
92
93// Implements FlMethodCodec::decode_method_call.
95 FlMethodCodec* codec,
96 GBytes* message,
97 gchar** name,
98 FlValue** args,
99 GError** error) {
100 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
101
102 size_t offset = 0;
103 g_autoptr(FlValue) name_value = fl_standard_message_codec_read_value(
104 self->message_codec, message, &offset, error);
105 if (name_value == nullptr) {
106 return FALSE;
107 }
108 if (fl_value_get_type(name_value) != FL_VALUE_TYPE_STRING) {
110 "Method call name wrong type");
111 return FALSE;
112 }
113
114 g_autoptr(FlValue) args_value = fl_standard_message_codec_read_value(
115 self->message_codec, message, &offset, error);
116 if (args_value == nullptr) {
117 return FALSE;
118 }
119
120 if (offset != g_bytes_get_size(message)) {
122 "Unexpected extra data");
123 return FALSE;
124 }
125
126 *name = g_strdup(fl_value_get_string(name_value));
127 *args = fl_value_ref(args_value);
128
129 return TRUE;
130}
131
132// Implements FlMethodCodec::encode_success_envelope.
134 FlMethodCodec* codec,
136 GError** error) {
137 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
138
139 g_autoptr(GByteArray) buffer = g_byte_array_new();
140 guint8 type = kEnvelopeTypeSuccess;
143 result, error)) {
144 return nullptr;
145 }
146
147 return g_byte_array_free_to_bytes(
148 static_cast<GByteArray*>(g_steal_pointer(&buffer)));
149}
150
151// Implements FlMethodCodec::encode_error_envelope.
153 FlMethodCodec* codec,
154 const gchar* code,
155 const gchar* message,
156 FlValue* details,
157 GError** error) {
158 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
159
160 g_autoptr(GByteArray) buffer = g_byte_array_new();
161 guint8 type = kEnvelopeTypeError;
163 g_autoptr(FlValue) code_value = fl_value_new_string(code);
165 code_value, error)) {
166 return nullptr;
167 }
168 g_autoptr(FlValue) message_value =
169 message != nullptr ? fl_value_new_string(message) : nullptr;
171 message_value, error)) {
172 return nullptr;
173 }
175 details, error)) {
176 return nullptr;
177 }
178
179 return g_byte_array_free_to_bytes(
180 static_cast<GByteArray*>(g_steal_pointer(&buffer)));
181}
182
183// Implements FlMethodCodec::encode_decode_response.
185 FlMethodCodec* codec,
186 GBytes* message,
187 GError** error) {
188 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
189
190 if (g_bytes_get_size(message) == 0) {
191 g_set_error(error, FL_MESSAGE_CODEC_ERROR,
192 FL_MESSAGE_CODEC_ERROR_OUT_OF_DATA, "Empty response");
193 return nullptr;
194 }
195
196 // First byte is response type.
197 const guint8* data =
198 static_cast<const guint8*>(g_bytes_get_data(message, nullptr));
199 guint8 type = data[0];
200 size_t offset = 1;
201
202 g_autoptr(FlMethodResponse) response = nullptr;
203 if (type == kEnvelopeTypeError) {
205 self->message_codec, message, &offset, error);
206 if (code == nullptr) {
207 return nullptr;
208 }
211 "Error code wrong type");
212 return nullptr;
213 }
214
215 g_autoptr(FlValue) error_message = fl_standard_message_codec_read_value(
216 self->message_codec, message, &offset, error);
217 if (error_message == nullptr) {
218 return nullptr;
219 }
220 if (fl_value_get_type(error_message) != FL_VALUE_TYPE_STRING &&
221 fl_value_get_type(error_message) != FL_VALUE_TYPE_NULL) {
223 "Error message wrong type");
224 return nullptr;
225 }
226
228 self->message_codec, message, &offset, error);
229 if (details == nullptr) {
230 return nullptr;
231 }
232
233 response = FL_METHOD_RESPONSE(fl_method_error_response_new(
236 ? fl_value_get_string(error_message)
237 : nullptr,
238 fl_value_get_type(details) != FL_VALUE_TYPE_NULL ? details : nullptr));
239 } else if (type == kEnvelopeTypeSuccess) {
241 self->message_codec, message, &offset, error);
242
243 if (result == nullptr) {
244 return nullptr;
245 }
246
247 response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
248 } else {
250 "Unknown envelope type %02x", type);
251 return nullptr;
252 }
253
254 if (offset != g_bytes_get_size(message)) {
256 "Unexpected extra data");
257 return nullptr;
258 }
259
260 return FL_METHOD_RESPONSE(g_object_ref(response));
261}
262
264 FlStandardMethodCodecClass* klass) {
265 G_OBJECT_CLASS(klass)->set_property = fl_standard_method_codec_set_property;
266 G_OBJECT_CLASS(klass)->get_property = fl_standard_method_codec_get_property;
267 G_OBJECT_CLASS(klass)->dispose = fl_standard_method_codec_dispose;
268
269 FL_METHOD_CODEC_CLASS(klass)->encode_method_call =
271 FL_METHOD_CODEC_CLASS(klass)->decode_method_call =
273 FL_METHOD_CODEC_CLASS(klass)->encode_success_envelope =
275 FL_METHOD_CODEC_CLASS(klass)->encode_error_envelope =
277 FL_METHOD_CODEC_CLASS(klass)->decode_response =
279
280 g_object_class_install_property(
281 G_OBJECT_CLASS(klass), kPropMessageCodec,
282 g_param_spec_object(
283 "message-codec", "message-codec", "Message codec to use",
284 fl_message_codec_get_type(),
285 static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
286 G_PARAM_STATIC_STRINGS)));
287}
288
289static void fl_standard_method_codec_init(FlStandardMethodCodec* self) {}
290
291G_MODULE_EXPORT FlStandardMethodCodec* fl_standard_method_codec_new() {
292 g_autoptr(FlStandardMessageCodec) message_codec =
295}
296
297G_MODULE_EXPORT FlStandardMethodCodec*
299 FlStandardMessageCodec* message_codec) {
300 return FL_STANDARD_METHOD_CODEC(
301 g_object_new(fl_standard_method_codec_get_type(), "message-codec",
302 message_codec, nullptr));
303}
GLenum type
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
@ FL_MESSAGE_CODEC_ERROR_OUT_OF_DATA
@ FL_MESSAGE_CODEC_ERROR_FAILED
#define FL_MESSAGE_CODEC_ERROR
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
const uint8_t uint32_t uint32_t GError ** error
G_MODULE_EXPORT gboolean fl_standard_message_codec_write_value(FlStandardMessageCodec *self, GByteArray *buffer, FlValue *value, GError **error)
G_MODULE_EXPORT FlValue * fl_standard_message_codec_read_value(FlStandardMessageCodec *self, GBytes *buffer, size_t *offset, GError **error)
G_MODULE_EXPORT FlStandardMessageCodec * fl_standard_message_codec_new()
g_byte_array_append(buffer, &type, sizeof(uint8_t))
static constexpr guint8 kEnvelopeTypeError
static void fl_standard_method_codec_dispose(GObject *object)
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new_with_message_codec(FlStandardMessageCodec *message_codec)
static void fl_standard_method_codec_class_init(FlStandardMethodCodecClass *klass)
static void fl_standard_method_codec_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static FlMethodResponse * fl_standard_method_codec_decode_response(FlMethodCodec *codec, GBytes *message, GError **error)
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new()
static gboolean fl_standard_method_codec_decode_method_call(FlMethodCodec *codec, GBytes *message, gchar **name, FlValue **args, GError **error)
static constexpr guint8 kEnvelopeTypeSuccess
guint const GValue * value
guint prop_id
static GBytes * fl_standard_method_codec_encode_method_call(FlMethodCodec *codec, const gchar *name, FlValue *args, GError **error)
static void fl_standard_method_codec_init(FlStandardMethodCodec *self)
guint const GValue GParamSpec * pspec
static GBytes * fl_standard_method_codec_encode_success_envelope(FlMethodCodec *codec, FlValue *result, GError **error)
G_DEFINE_TYPE(FlStandardMethodCodec, fl_standard_method_codec, fl_method_codec_get_type()) static void fl_standard_method_codec_set_property(GObject *object
static GBytes * fl_standard_method_codec_encode_error_envelope(FlMethodCodec *codec, const gchar *code, const gchar *message, FlValue *details, GError **error)
GAsyncResult * result
G_MODULE_EXPORT FlValue * fl_value_ref(FlValue *self)
Definition: fl_value.cc:394
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:682
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:69
@ FL_VALUE_TYPE_NULL
Definition: fl_value.h:65
Win32Message message
return FALSE
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
SeparatedVector2 offset
FlStandardMessageCodec * message_codec
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63