blob: 9082b9d50ae7c736f4c1b511e81a8112638f6b1f [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_response.h"
#include <gmodule.h>
G_DEFINE_QUARK(fl_method_response_error_quark, fl_method_response_error)
struct _FlMethodSuccessResponse {
FlMethodResponse parent_instance;
FlValue* result;
};
struct _FlMethodErrorResponse {
FlMethodResponse parent_instance;
gchar* code;
gchar* message;
FlValue* details;
};
struct _FlMethodNotImplementedResponse {
FlMethodResponse parent_instance;
};
G_DEFINE_TYPE(FlMethodResponse, fl_method_response, G_TYPE_OBJECT)
G_DEFINE_TYPE(FlMethodSuccessResponse,
fl_method_success_response,
fl_method_response_get_type())
G_DEFINE_TYPE(FlMethodErrorResponse,
fl_method_error_response,
fl_method_response_get_type())
G_DEFINE_TYPE(FlMethodNotImplementedResponse,
fl_method_not_implemented_response,
fl_method_response_get_type())
static void fl_method_response_class_init(FlMethodResponseClass* klass) {}
static void fl_method_response_init(FlMethodResponse* self) {}
static void fl_method_success_response_dispose(GObject* object) {
FlMethodSuccessResponse* self = FL_METHOD_SUCCESS_RESPONSE(object);
g_clear_pointer(&self->result, fl_value_unref);
G_OBJECT_CLASS(fl_method_success_response_parent_class)->dispose(object);
}
static void fl_method_success_response_class_init(
FlMethodSuccessResponseClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_method_success_response_dispose;
}
static void fl_method_success_response_init(FlMethodSuccessResponse* self) {}
static void fl_method_error_response_dispose(GObject* object) {
FlMethodErrorResponse* self = FL_METHOD_ERROR_RESPONSE(object);
g_clear_pointer(&self->code, g_free);
g_clear_pointer(&self->message, g_free);
g_clear_pointer(&self->details, fl_value_unref);
G_OBJECT_CLASS(fl_method_error_response_parent_class)->dispose(object);
}
static void fl_method_error_response_class_init(
FlMethodErrorResponseClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_method_error_response_dispose;
}
static void fl_method_error_response_init(FlMethodErrorResponse* self) {}
static void fl_method_not_implemented_response_class_init(
FlMethodNotImplementedResponseClass* klass) {}
static void fl_method_not_implemented_response_init(
FlMethodNotImplementedResponse* self) {}
G_MODULE_EXPORT FlValue* fl_method_response_get_result(FlMethodResponse* self,
GError** error) {
if (FL_IS_METHOD_SUCCESS_RESPONSE(self))
return fl_method_success_response_get_result(
FL_METHOD_SUCCESS_RESPONSE(self));
if (FL_IS_METHOD_ERROR_RESPONSE(self)) {
const gchar* code =
fl_method_error_response_get_code(FL_METHOD_ERROR_RESPONSE(self));
const gchar* message =
fl_method_error_response_get_message(FL_METHOD_ERROR_RESPONSE(self));
FlValue* details =
fl_method_error_response_get_details(FL_METHOD_ERROR_RESPONSE(self));
g_autofree gchar* details_text = nullptr;
if (details != nullptr) {
// TODO(robert-ancell): Update this when we have fl_value_to_string()
}
g_autoptr(GString) error_message = g_string_new("");
g_string_append_printf(error_message, "Remote code returned error %s",
code);
if (message != nullptr)
g_string_append_printf(error_message, ": %s", message);
if (details_text != nullptr)
g_string_append_printf(error_message, " %s", details_text);
g_set_error_literal(error, FL_METHOD_RESPONSE_ERROR,
FL_METHOD_RESPONSE_ERROR_REMOTE_ERROR,
error_message->str);
return nullptr;
} else if (FL_IS_METHOD_NOT_IMPLEMENTED_RESPONSE(self)) {
g_set_error(error, FL_METHOD_RESPONSE_ERROR,
FL_METHOD_RESPONSE_ERROR_NOT_IMPLEMENTED,
"Requested method is not implemented");
return nullptr;
} else {
g_set_error(error, FL_METHOD_RESPONSE_ERROR,
FL_METHOD_RESPONSE_ERROR_FAILED, "Unknown response type");
return nullptr;
}
}
G_MODULE_EXPORT FlMethodSuccessResponse* fl_method_success_response_new(
FlValue* result) {
FlMethodSuccessResponse* self = FL_METHOD_SUCCESS_RESPONSE(
g_object_new(fl_method_success_response_get_type(), nullptr));
if (result != nullptr)
self->result = fl_value_ref(result);
return self;
}
G_MODULE_EXPORT FlValue* fl_method_success_response_get_result(
FlMethodSuccessResponse* self) {
g_return_val_if_fail(FL_IS_METHOD_SUCCESS_RESPONSE(self), nullptr);
return self->result;
}
G_MODULE_EXPORT FlMethodErrorResponse* fl_method_error_response_new(
const gchar* code,
const gchar* message,
FlValue* details) {
g_return_val_if_fail(code != nullptr, nullptr);
FlMethodErrorResponse* self = FL_METHOD_ERROR_RESPONSE(
g_object_new(fl_method_error_response_get_type(), nullptr));
self->code = g_strdup(code);
self->message = g_strdup(message);
self->details = details != nullptr ? fl_value_ref(details) : nullptr;
return self;
}
G_MODULE_EXPORT const gchar* fl_method_error_response_get_code(
FlMethodErrorResponse* self) {
g_return_val_if_fail(FL_IS_METHOD_ERROR_RESPONSE(self), nullptr);
return self->code;
}
G_MODULE_EXPORT const gchar* fl_method_error_response_get_message(
FlMethodErrorResponse* self) {
g_return_val_if_fail(FL_IS_METHOD_ERROR_RESPONSE(self), nullptr);
return self->message;
}
G_MODULE_EXPORT FlValue* fl_method_error_response_get_details(
FlMethodErrorResponse* self) {
g_return_val_if_fail(FL_IS_METHOD_ERROR_RESPONSE(self), nullptr);
return self->details;
}
G_MODULE_EXPORT FlMethodNotImplementedResponse*
fl_method_not_implemented_response_new() {
return FL_METHOD_NOT_IMPLEMENTED_RESPONSE(
g_object_new(fl_method_not_implemented_response_get_type(), nullptr));
}