blob: 35fcd24c57f45720b06f4ea9d44f06792a93f03e [file] [log] [blame]
// 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);
}