+/**
+ * @description
+ *
+ * DirectReading module requests reading of a given text via dbus.
+ * It communicates with dbus by sending textual representations of signals
+ * to org.tizen.DirectReading interface.
+ */
+
+#include "screen_reader.h"
+
#ifndef DBUS_DIRECT_READING_ADAPTER_H_
#define DBUS_DIRECT_READING_ADAPTER_H_
const char *get_signal_name(const Signal signal);
-int dbus_direct_reading_init(void);
+/**
+ * @brief Initialize bus connection.
+ *
+ * Function registers on dbus the "org.tizen.DirectReading" stateful interface
+ * on "/org/tizen/DirectReading" path. New requests are queued on dbus
+ * in order to prevent reading few elements at the same time.
+ *
+ * @return Reading_Adapter pointer on success, else NULL
+ */
+
+
+Reading_Adapter *dbus_direct_reading_init(void);
+
+ /**
+ * @brief Shutdown eldbus.
+ *
+ * Function unregisters all intefaces of the object and decrements
+ * connection reference count.
+ *
+ * @param Reading_Adapter pointer
+ */
+
+void dbus_direct_reading_shutdown(Reading_Adapter *ra_data);
-void dbus_direct_reading_shutdown(void);
+/**
+ * @brief Sends a signal to org.tizen.DirectReading interface.
+ *
+ * Function gets textual representation of a signal
+ * and sends it to org.tizen.DirectReading interface.
+ *
+ * @param signal
+ * @param *data
+ * @param *ra_data
+ */
-int dbus_direct_reading_adapter_emit(const Signal signal, int command_id);
+int dbus_direct_reading_adapter_emit(const Signal signal, const void *data, Reading_Adapter *ra_data);
#endif
#define PATH "/org/tizen/DirectReading"
#define INTERFACE "org.tizen.DirectReading"
-static Eldbus_Connection *conn;
-static Eldbus_Service_Interface *iface;
+struct _direct_reading_data {
+ Eldbus_Connection *conn;
+ Eldbus_Service_Interface *iface;
+ Eldbus_Connection *session;
+ Eldbus_Message *msg;
+};
const char *get_signal_name(const Signal signal) {
switch (signal) {
case READING_STARTED:
- { return "ReadingStarted";}
+ { return "ReadingStarted"; }
case READING_STOPPED:
- { return "ReadingStopped";}
+ { return "ReadingStopped"; }
case READING_CANCELLED:
- { return "ReadingCancelled";}
+ { return "ReadingCancelled"; }
case READING_SKIPPED:
- { return "ReadingSkipped";}
+ { return "ReadingSkipped"; }
default:
- { return "UnknownSignal";}
+ { return "UnknownSignal"; }
}
}
static const Eldbus_Signal _signals[] = {
- [0] = {"ReadingStateChanged", ELDBUS_ARGS({"is", NULL}), 0},
- { }
+ [0] = {"ReadingStateChanged", ELDBUS_ARGS({"is", NULL}), 0},
+ { }
};
static Eldbus_Message *
ERROR("eldbus_message_arguments_get() failed to parse arguments of type String and Boolean from message msg=%p", msg);
} else {
DEBUG("RECIVED DBUS MESSAGE WITH ARGS: text(%s), discardable(%d)", text, discardable);
- Read_Command *command = tts_speak_customized(text, EINA_TRUE, discardable, NULL);
- if (command) rc_id = command->command_id;
+ Read_Command *command = tts_speak_customized(text, EINA_TRUE, discardable, NULL);
+ if (command) rc_id = command->command_id;
}
if (!eldbus_message_arguments_append(reply, "sbi", text, discardable, rc_id))
ERROR("eldbus_message_arguments_append() has failed to append arguments to reply message reply=%p", reply);
assert(msg);
const char *sock_addr;
const char *errname, *errmsg;
- Eldbus_Connection *session = data;
+ Reading_Adapter *ra_data = (Reading_Adapter *)data;
+
+ if (ra_data == NULL) {
+ ERROR("NULL context parameter");
+ return;
+ }
DEBUG("[START]");
- conn = NULL;
+ ra_data->conn = NULL;
if (eldbus_message_error_get(msg, &errname, &errmsg)) {
ERROR("GetAddress failed: %s %s", errname, errmsg);
if (eldbus_message_arguments_get(msg, "s", &sock_addr) && sock_addr) {
DEBUG("A11 socket %s", sock_addr);
- if ((conn = eldbus_address_connection_get(sock_addr))) {
- iface = eldbus_service_interface_register(conn, PATH, &iface_desc);
- if (iface) {
+ if ((ra_data->conn = eldbus_address_connection_get(sock_addr))) {
+ ra_data->iface = eldbus_service_interface_register(ra_data->conn, PATH, &iface_desc);
+ if (ra_data->iface) {
DEBUG("RequestName start");
- eldbus_name_request(conn, BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
- on_name_request, NULL);
+ eldbus_name_request(ra_data->conn, BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
+ on_name_request, NULL);
DEBUG("RequestName end");
} else {
ERROR("Failed to register %s interface", INTERFACE);
ERROR("Could not get A11Y Bus socket address.");
}
- if (iface == NULL && conn != NULL) {
- eldbus_connection_unref(conn);
- conn = NULL;
+ if (ra_data->iface == NULL && ra_data->conn != NULL) {
+ eldbus_connection_unref(ra_data->conn);
+ ra_data->conn = NULL;
}
- if (session != NULL)
- eldbus_connection_unref(session);
+ if (ra_data->session != NULL)
+ eldbus_connection_unref(ra_data->session);
DEBUG("[END]");
}
-int dbus_direct_reading_init(void)
+Reading_Adapter *dbus_direct_reading_init(void)
{
- Eldbus_Connection *session = NULL;
- Eldbus_Message *msg = NULL;
int ret = -1;
+ Reading_Adapter *ra_data = calloc(1, sizeof(Reading_Adapter));
+ if (ra_data == NULL) {
+ ERROR("NULL context parameter");
+ free(ra_data);
+ return NULL;
+ }
DEBUG("[START]");
if (eldbus_init() == 0) {
ERROR("Unable to initialize eldbus module");
- return ret;
+ free(ra_data);
+ return NULL;
};
- session = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
- if (session) {
- msg = eldbus_message_method_call_new("org.a11y.Bus", "/org/a11y/bus", "org.a11y.Bus", "GetAddress");
- if (msg) {
- if (eldbus_connection_send(session, msg, _get_a11y_address, session, -1)) {
+ ra_data->session = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
+ if (ra_data->session) {
+ ra_data->msg = eldbus_message_method_call_new("org.a11y.Bus", "/org/a11y/bus", "org.a11y.Bus", "GetAddress");
+ if (ra_data->msg) {
+ if (eldbus_connection_send(ra_data->session, ra_data->msg, _get_a11y_address, ra_data, -1)) {
ret = 0;
} else {
ERROR("Message send failed");
}
}
// successfull call of eldbus_connection_send should already release resources
- if (msg != NULL && ret != 0)
- eldbus_message_unref(msg);
- if (session != NULL && ret != 0)
- eldbus_connection_unref(session);
- return ret;
+ if (ra_data->msg != NULL && ret != 0)
+ eldbus_message_unref(ra_data->msg);
+ if (ra_data->session != NULL && ret != 0)
+ eldbus_connection_unref(ra_data->session);
+
+ if(ret == 0)
+ return ra_data;
+ else {
+ free(ra_data);
+ return NULL;
+ }
}
-void dbus_direct_reading_shutdown(void)
+void dbus_direct_reading_shutdown(Reading_Adapter *ra_data)
{
+ if (ra_data == NULL)
+ ERROR("NULL context parameter");
+
DEBUG("[START]");
- if (iface)
- eldbus_service_object_unregister(iface);
- if (conn)
- eldbus_connection_unref(conn);
+ if (ra_data->iface)
+ eldbus_service_object_unregister(ra_data->iface);
+ if (ra_data->conn)
+ eldbus_connection_unref(ra_data->conn);
- conn = NULL;
- iface = NULL;
+ free(ra_data);
DEBUG("[END]");
eldbus_shutdown();
}
-
-int dbus_direct_reading_adapter_emit(const Signal signal, int command_id)
+int dbus_direct_reading_adapter_emit(const Signal signal, const void *data, Reading_Adapter *ra_data)
{
- if (!iface) {
+ Read_Command *command = (Read_Command *)data;
+
+ if (command == NULL || ra_data == NULL) {
+ ERROR("NULL context parameter");
+ return -1;
+ }
+ if (!ra_data->iface) {
ERROR("Interface: %s not found on dbus", INTERFACE);
return -1;
}
ERROR("Trying to emit unknown signal(%d)", signal);
return -1;
}
- if (command_id <= 0) {
+ if (command->command_id <= 0) {
ERROR("Trying to emit signal: %s which is not associated with any reading command", get_signal_name(signal));
return -1;
}
- if (!eldbus_service_signal_emit(iface, 0, command_id, get_signal_name(signal))) {
+ if (!eldbus_service_signal_emit(ra_data->iface, 0, command->command_id, get_signal_name(signal))) {
ERROR("Unable to send %s signal", get_signal_name(signal));
return -1;
} else {
static void _reading_status_notify(Signal signal, Read_Command *command)
{
DEBUG("[START] reading status notify for LAST_READ_COMMAND: %p", command);
+ Service_Data *sd = get_pointer_to_service_data_struct();
if (command) {
if (command->obj) {
//do AT-SPI action
get_signal_name(signal), command, command->obj);
} else {
//broadcast dbus signal
- if (dbus_direct_reading_adapter_emit(signal, command->command_id) != 0)
+ if (dbus_direct_reading_adapter_emit(signal, command, sd->reading_adapter_data) != 0)
ERROR("Failed to broadcast dbus signal:%d for read command:%p", signal, command);
}
}
//TODO: consider handling the case of discarding well-formed read command by subsequent malformed command
static Read_Command *get_read_command_from_queue(Eina_List **command_queue_list) {
if (command_queue_list == NULL || *command_queue_list == NULL) return NULL;
+ Service_Data *sd = get_pointer_to_service_data_struct();
Eina_List *command_queue = *command_queue_list;
DEBUG("CLEAN UP THE QUEUE HEAD(%p) # of elements in queue:%d", command_queue, eina_list_count(command_queue));
get_signal_name(READING_SKIPPED), command, command->obj);
} else {
//broadcast dbus signal
- if (dbus_direct_reading_adapter_emit(READING_SKIPPED, command->command_id) != 0)
+ if (dbus_direct_reading_adapter_emit(READING_SKIPPED, command, sd->reading_adapter_data) != 0)
ERROR("Failed to broadcast dbus signal:%d for read command:%p", READING_SKIPPED, command);
}
free(command);