Fix TC-2372 Dialer crashes when BT phone is offline
[profile/ivi/lemolo.git] / messages / rc.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include <Elementary.h>
5 #include <Eldbus.h>
6
7 #include "log.h"
8 #include "gui.h"
9 #include "ofono.h"
10
11 static Eldbus_Connection *bus_conn = NULL;
12 static Eldbus_Service_Interface *bus_iface = NULL;
13
14 #define RC_IFACE "org.tizen.messages.Control"
15 #define RC_PATH "/"
16
17 static const char *rc_service = NULL;
18 static OFono_Callback_List_Modem_Node *modem_changed_node = NULL;
19 static Eldbus_Message *pending_send = NULL;
20
21 static void _send_message(const char *number, const char *message,
22                                 Eina_Bool do_auto)
23 {
24         INF("send '%s' '%s' auto=%d!", number, message, do_auto);
25         gui_activate();
26         gui_send(number, message, do_auto);
27 }
28
29 static void _modem_changed_cb(void *data __UNUSED__)
30 {
31         const char *number, *message;
32         Eina_Bool do_auto;
33         Eldbus_Message *reply;
34
35         if (!ofono_voice_is_online() || !pending_send)
36                 return;
37
38         if (!eldbus_message_arguments_get(pending_send, "ssb", &number, &message, &do_auto)) {
39                 ERR("Could not get pending send arguments");
40                 reply = eldbus_message_error_new(pending_send, "Pending send", "Invalid argument");
41                 goto reply_send;
42         }
43
44         _send_message(number, message, do_auto);
45         reply = eldbus_message_method_return_new(pending_send);
46 reply_send:
47         eldbus_connection_send(bus_conn, reply, NULL, NULL, -1);
48         eldbus_message_unref(pending_send);
49         pending_send = NULL;
50 }
51
52 static Eldbus_Message *
53 _rc_activate(Eldbus_Object *obj __UNUSED__, Eldbus_Message *msg)
54 {
55         INF("Remotely activated!");
56         gui_activate();
57         return eldbus_message_method_return_new(msg);
58 }
59
60 static Eldbus_Message *
61 _rc_send(Eldbus_Object *obj __UNUSED__, Eldbus_Message *msg)
62 {
63         Eina_Bool do_auto;
64         const char *number, *message;
65
66         if (!ofono_voice_is_online()) {
67                 if (pending_send)
68                         eldbus_message_unref(pending_send);
69                 pending_send = eldbus_message_ref(msg);
70                 return NULL;
71         }
72
73         if (!eldbus_message_arguments_get(msg, "ssb", &number, &message, &do_auto)) {
74                 ERR("Could not get pending send arguments");
75                 return eldbus_message_error_new(pending_send, "Pending send", "Invalid argument");
76         }
77
78         _send_message(number, message, do_auto);
79         return eldbus_message_method_return_new(msg);
80 }
81
82 static const Eldbus_Method rc_methods[] = {
83         { "Activate", NULL, NULL, _rc_activate, },
84         { "Send", NULL, ELDBUS_ARGS(
85                 {"s", "number"},
86                 {"s", "message"},
87                 {"b", "do_auto"}),      _rc_send, ELDBUS_METHOD_FLAG_DEPRECATED },
88         { }
89 };
90
91 static const Eldbus_Service_Interface_Desc rc_iface_desc = {
92    RC_IFACE, rc_methods, NULL, NULL, NULL, NULL
93 };
94
95 static void _rc_object_register(void)
96 {
97         bus_iface = eldbus_service_interface_register(bus_conn, RC_PATH, &rc_iface_desc);
98 }
99
100 static void _rc_activate_existing_reply(void *data __UNUSED__, const Eldbus_Message *msg,
101                                                 Eldbus_Pending *pending __UNUSED__)
102 {
103         const char *err_name, *err_message;
104
105         if (eldbus_message_error_get(msg, &err_name, &err_message)) {
106                 CRITICAL("Failed to activate existing messages: %s: %s", err_name, err_message);
107                 _app_exit_code = EXIT_FAILURE;
108                 ecore_main_loop_quit();
109                 return;
110         }
111
112         INF("Activated the existing messages!");
113         ecore_main_loop_quit();
114 }
115
116 static void _rc_activate_existing(void)
117 {
118         Eldbus_Message *msg = eldbus_message_method_call_new(
119                 rc_service, RC_PATH, RC_IFACE, "Activate");
120         eldbus_connection_send(bus_conn, msg,  _rc_activate_existing_reply, NULL, -1);
121 }
122
123 static void _rc_request_name_reply(void *data __UNUSED__, Eldbus_Message *msg,
124                                                 Eldbus_Pending *pending __UNUSED__)
125 {
126         int t;
127         const char *err_name, *err_message;
128
129         if (eldbus_message_error_get(msg, &err_name, &err_message)) {
130                 ERR("Failed to request name: %s: %s", err_name, err_message);
131                 return;
132         }
133
134         if (!eldbus_message_arguments_get(msg, "u", &t)) {
135                 ERR("Could not get request name arguments");
136                 _rc_activate_existing();
137                 return;
138         }
139
140         if (t == ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER) {
141                 _rc_object_register();
142                 gui_activate();
143         } else {
144                 WRN("Messages already running! Activate it!");
145                 _rc_activate_existing();
146         }
147 }
148
149 Eina_Bool rc_init(const char *service)
150 {
151         rc_service = service;
152
153         if (!elm_need_eldbus()) {
154                 CRITICAL("Elementary does not support DBus.");
155                 return EINA_FALSE;
156         }
157
158         INF("Running on Session bus");
159         bus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
160
161         if (!bus_conn) {
162                 CRITICAL("Could not get DBus Bus");
163                 return EINA_FALSE;
164         }
165
166         eldbus_name_request(bus_conn, rc_service, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
167                                 _rc_request_name_reply, NULL);
168
169         modem_changed_node = ofono_modem_changed_cb_add(_modem_changed_cb,
170                                                         NULL);
171
172         return EINA_TRUE;
173 }
174
175 void rc_shutdown(void)
176 {
177         if (bus_iface)
178                 eldbus_service_interface_unregister(bus_iface);
179
180         ofono_modem_changed_cb_del(modem_changed_node);
181
182         if (pending_send)
183                 eldbus_message_unref(pending_send);
184
185         bus_conn = NULL;
186 }