| // 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_method_call.h" |
| #include "flutter/shell/platform/linux/fl_method_call_private.h" |
| #include "flutter/shell/platform/linux/fl_method_channel_private.h" |
| |
| #include <gmodule.h> |
| |
| struct _FlMethodCall { |
| GObject parent_instance; |
| |
| // Name of method being called. |
| gchar* name; |
| |
| // Arguments provided to method call. |
| FlValue* args; |
| |
| // Channel to respond on. |
| FlMethodChannel* channel; |
| FlBinaryMessengerResponseHandle* response_handle; |
| }; |
| |
| G_DEFINE_TYPE(FlMethodCall, fl_method_call, G_TYPE_OBJECT) |
| |
| static void fl_method_call_dispose(GObject* object) { |
| FlMethodCall* self = FL_METHOD_CALL(object); |
| |
| g_clear_pointer(&self->name, g_free); |
| g_clear_pointer(&self->args, fl_value_unref); |
| g_clear_object(&self->channel); |
| g_clear_object(&self->response_handle); |
| |
| G_OBJECT_CLASS(fl_method_call_parent_class)->dispose(object); |
| } |
| |
| static void fl_method_call_class_init(FlMethodCallClass* klass) { |
| G_OBJECT_CLASS(klass)->dispose = fl_method_call_dispose; |
| } |
| |
| static void fl_method_call_init(FlMethodCall* self) {} |
| |
| FlMethodCall* fl_method_call_new( |
| const gchar* name, |
| FlValue* args, |
| FlMethodChannel* channel, |
| FlBinaryMessengerResponseHandle* response_handle) { |
| g_return_val_if_fail(name != nullptr, nullptr); |
| g_return_val_if_fail(args != nullptr, nullptr); |
| g_return_val_if_fail(FL_IS_METHOD_CHANNEL(channel), nullptr); |
| g_return_val_if_fail(FL_IS_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle), |
| nullptr); |
| |
| FlMethodCall* self = |
| FL_METHOD_CALL(g_object_new(fl_method_call_get_type(), nullptr)); |
| |
| self->name = g_strdup(name); |
| self->args = fl_value_ref(args); |
| self->channel = FL_METHOD_CHANNEL(g_object_ref(channel)); |
| self->response_handle = |
| FL_BINARY_MESSENGER_RESPONSE_HANDLE(g_object_ref(response_handle)); |
| |
| return self; |
| } |
| |
| G_MODULE_EXPORT const gchar* fl_method_call_get_name(FlMethodCall* self) { |
| g_return_val_if_fail(FL_IS_METHOD_CALL(self), nullptr); |
| return self->name; |
| } |
| |
| G_MODULE_EXPORT FlValue* fl_method_call_get_args(FlMethodCall* self) { |
| g_return_val_if_fail(FL_IS_METHOD_CALL(self), nullptr); |
| return self->args; |
| } |
| |
| G_MODULE_EXPORT gboolean fl_method_call_respond(FlMethodCall* self, |
| FlMethodResponse* response, |
| GError** error) { |
| g_return_val_if_fail(FL_IS_METHOD_CALL(self), FALSE); |
| g_return_val_if_fail(FL_IS_METHOD_RESPONSE(response), FALSE); |
| |
| g_autoptr(GError) local_error = nullptr; |
| if (!fl_method_channel_respond(self->channel, self->response_handle, response, |
| &local_error)) { |
| // If the developer chose not to handle the error then log it so it's not |
| // missed. |
| if (error == nullptr) { |
| g_warning("Failed to send method call response: %s", |
| local_error->message); |
| } |
| |
| g_propagate_error(error, local_error); |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| G_MODULE_EXPORT gboolean fl_method_call_respond_success(FlMethodCall* self, |
| FlValue* result, |
| GError** error) { |
| g_return_val_if_fail(FL_IS_METHOD_CALL(self), FALSE); |
| |
| g_autoptr(FlMethodResponse) response = |
| FL_METHOD_RESPONSE(fl_method_success_response_new(result)); |
| return fl_method_channel_respond(self->channel, self->response_handle, |
| response, error); |
| } |
| |
| G_MODULE_EXPORT gboolean fl_method_call_respond_error(FlMethodCall* self, |
| const gchar* code, |
| const gchar* message, |
| FlValue* details, |
| GError** error) { |
| g_return_val_if_fail(FL_IS_METHOD_CALL(self), FALSE); |
| g_return_val_if_fail(code != nullptr, FALSE); |
| |
| g_autoptr(FlMethodResponse) response = |
| FL_METHOD_RESPONSE(fl_method_error_response_new(code, message, details)); |
| return fl_method_channel_respond(self->channel, self->response_handle, |
| response, error); |
| } |
| |
| G_MODULE_EXPORT gboolean |
| fl_method_call_respond_not_implemented(FlMethodCall* self, GError** error) { |
| g_return_val_if_fail(FL_IS_METHOD_CALL(self), FALSE); |
| |
| g_autoptr(FlMethodResponse) response = |
| FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); |
| return fl_method_channel_respond(self->channel, self->response_handle, |
| response, error); |
| } |