9 #include <Elementary.h>
14 #include <vconf-keys.h>
20 #define APP_NAME "org.tizen.answer"
21 #define BUS_NAME "org.tizen.dialer"
23 #define RC_IFACE "org.tizen.dialer.Control"
24 #define FREEDESKTOP_IFACE "org.freedesktop.DBus"
26 static int _log_domain = -1;
27 #define ERR(...) EINA_LOG_DOM_ERR(_log_domain, __VA_ARGS__)
28 #define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
29 #define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
31 static Eldbus_Connection *bus_conn = NULL;
33 typedef struct _Call {
34 const char *line_id, *img, *type, *name;
37 typedef struct _Call_Screen {
38 Evas_Object *win, *layout;
40 Eina_Bool screen_visible;
41 Eldbus_Signal_Handler *sig_call_add;
42 Eldbus_Signal_Handler *sig_call_removed;
43 Eldbus_Signal_Handler *sig_name_changed;
46 static void _set_notification_type(Evas_Object *win, Eina_Bool high)
52 static Eina_Bool _phone_locked(void)
56 if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock) == -1)
59 if (lock == VCONFKEY_IDLE_LOCK)
64 return EINA_TRUE; /* always have it to show */
68 static Call *_call_create(Eldbus_Message *msg)
71 const char *img, *name, *id, *type;
73 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
75 if (!eldbus_message_arguments_get(msg, "ssss", &img, &id, &name, &type)) {
76 ERR("Could not get call create arguments");
80 call = calloc(1, sizeof(Call));
81 EINA_SAFETY_ON_NULL_RETURN_VAL(call, NULL);
82 call->img = eina_stringshare_add(img);
83 call->line_id = eina_stringshare_add(id);
84 call->type = eina_stringshare_add(type);
85 call->name = eina_stringshare_add(name);
86 DBG("c=%p line_id=%s, name=%s, type=%s, img=%s",
87 call, call->line_id, call->name, call->type, call->img);
91 static void _call_destroy(Call *c)
93 DBG("c=%p line_id=%s, name=%s, type=%s, img=%s",
94 c, c->line_id, c->name, c->type, c->img);
95 eina_stringshare_del(c->img);
96 eina_stringshare_del(c->line_id);
97 eina_stringshare_del(c->type);
98 eina_stringshare_del(c->name);
102 static void _call_screen_show(Call_Screen *cs)
105 Evas_Object *icon = NULL;
107 INF("Show line_id=%s, name=%s, type=%s",
108 c->line_id, c->name, c->type);
110 _set_notification_type(cs->win, EINA_TRUE);
111 cs->screen_visible = EINA_TRUE;
112 elm_win_raise(cs->win);
113 elm_win_activate(cs->win);
115 if (strcmp("", c->name) == 0)
116 elm_object_part_text_set(cs->layout, "elm.text.name",
119 elm_object_part_text_set(cs->layout, "elm.text.name",
121 icon = elm_icon_add(cs->layout);
123 if (strcmp("", c->img) != 0) {
124 elm_image_file_set(icon, c->img, NULL);
126 elm_icon_standard_set(icon, "no-picture");
128 elm_object_part_text_set(cs->layout, "elm.text.state", _("Incoming..."));
129 elm_object_part_text_set(cs->layout, "elm.text.phone.type", c->type);
130 elm_object_part_content_set(cs->layout, "elm.swallow.photo", icon);
131 elm_object_signal_emit(cs->layout, "show,activecall", "gui");
132 evas_object_show(cs->win);
134 //screen can't be off
135 power_lock_state(POWER_STATE_NORMAL, 0);
139 static void _sig_call_added(void *data, Eldbus_Message *msg)
141 Call_Screen *cs = data;
142 Eina_Bool locked = _phone_locked();
144 DBG("previous=%p, visible=%d, locked=%d", cs->call, cs->screen_visible,
148 _call_destroy(cs->call);
149 cs->call = _call_create(msg);
154 _call_screen_show(cs);
157 static void _call_screen_hide(Call_Screen *cs)
160 cs->screen_visible = EINA_FALSE;
161 _set_notification_type(cs->win, EINA_FALSE);
162 elm_object_signal_emit(cs->layout, "hide,activecall", "gui");
163 evas_object_hide(cs->win);
165 //screen can go off again
166 power_unlock_state(POWER_STATE_NORMAL);
170 static void _sig_call_removed(void *data, Eldbus_Message *msg __UNUSED__)
172 Call_Screen *cs = data;
174 DBG("previous=%p, visible=%d", cs->call, cs->screen_visible);
177 _call_destroy(cs->call);
181 if (!cs->screen_visible)
184 _call_screen_hide(cs);
187 static void _signal_handlers_add(Call_Screen *cs)
189 cs->sig_call_add = eldbus_signal_handler_add(bus_conn, BUS_NAME,
194 cs->sig_call_removed = eldbus_signal_handler_add(bus_conn,
202 static void _signal_handlers_del(Call_Screen *cs)
204 if (cs->sig_call_add) {
205 eldbus_signal_handler_del(cs->sig_call_add);
206 cs->sig_call_add = NULL;
209 if (cs->sig_call_removed) {
210 eldbus_signal_handler_del(cs->sig_call_removed);
211 cs->sig_call_removed = NULL;
215 static void _daemon_method_call_reply(void *data __UNUSED__, Eldbus_Message *msg,
216 Eldbus_Pending *pending __UNUSED__)
218 const char *err_name, *err_message;
220 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
221 ERR("Error calling remote method: %s: %s", err_name, err_message);
226 static void _daemon_method_call_make_with_reply(const char *method,
227 Eldbus_Message_Cb cb,
232 msg = eldbus_message_method_call_new(BUS_NAME, PATH, RC_IFACE, method);
233 INF("msg=%p name=%s, path=%s, %s.%s()",
234 msg, BUS_NAME, PATH, RC_IFACE, method);
235 EINA_SAFETY_ON_NULL_RETURN(msg);
237 eldbus_connection_send(bus_conn, msg, cb, data, -1);
240 static void _daemon_method_call_make(const char *method)
242 _daemon_method_call_make_with_reply(method, _daemon_method_call_reply,
246 static void _daemon_available_call_reply(void *data, Eldbus_Message *msg,
247 Eldbus_Pending *pending __UNUSED__)
250 const char *err_name, *err_message;
252 EINA_SAFETY_ON_NULL_RETURN(data);
256 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
257 ERR("Available call reply error %s: %s", err_name, err_message);
262 _call_destroy(cs->call);
264 cs->call = _call_create(msg);
265 _call_screen_show(cs);
268 static void _service_start_reply(void *data, Eldbus_Message *msg,
269 Eldbus_Pending *pending __UNUSED__)
272 const char *err_name, *err_message;
274 EINA_SAFETY_ON_NULL_RETURN(data);
278 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
279 ERR("Ofono reply error %s: %s", err_name, err_message);
283 _signal_handlers_add(cs);
284 _daemon_method_call_make_with_reply("GetAvailableCall",
285 _daemon_available_call_reply,
289 static void _has_owner_cb(void *data, Eldbus_Message *msg,
290 Eldbus_Pending *pending __UNUSED__)
294 const char *err_name, *err_message;
296 EINA_SAFETY_ON_NULL_RETURN(data);
298 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
299 ERR("Error %s: %s", err_name, err_message);
305 if (!eldbus_message_arguments_get(msg, "b", &online)) {
306 ERR("Could not get arguments");
311 INF("no dialer, start it");
312 Eldbus_Message *send_msg = eldbus_message_method_call_new(
313 BUS_NAME, PATH, FREEDESKTOP_IFACE,
314 "StartServiceByName");
319 if (!eldbus_message_arguments_append(send_msg, "si", BUS_NAME, 0))
322 eldbus_connection_send(bus_conn, send_msg, _service_start_reply, (void *) cs, -1);
326 _signal_handlers_add(cs);
327 _daemon_method_call_make_with_reply("GetAvailableCall",
328 _daemon_available_call_reply,
332 static void _name_owner_changed(void *data, Eldbus_Message *msg)
334 Call_Screen *cs = data;
335 const char *name, *from, *to;
337 if (!eldbus_message_arguments_get(msg, "sss", &name, &from, &to)) {
338 ERR("Could not get NameOwnerChanged arguments");
342 if (strcmp(name, BUS_NAME) != 0)
345 if ((to == NULL) || (*to == '\0')) {
346 INF("missed dialer");
347 _signal_handlers_del(cs);
351 INF("got new dialer at %s", to);
352 _signal_handlers_add(cs);
353 _daemon_method_call_make_with_reply("GetAvailableCall",
354 _daemon_available_call_reply,
358 static Eina_Bool _dbus_init(Call_Screen *cs)
361 char *bus_name = BUS_NAME;
363 INF("Running on Session bus");
364 bus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
367 ERR("Could not fetch the DBus session");
371 cs->sig_name_changed = eldbus_signal_handler_add(
372 bus_conn, ELDBUS_FDO_BUS, ELDBUS_FDO_PATH, ELDBUS_FDO_INTERFACE,
373 "NameOwnerChanged", _name_owner_changed, cs);
375 msg = eldbus_message_method_call_new(ELDBUS_FDO_BUS, ELDBUS_FDO_PATH,
376 ELDBUS_FDO_INTERFACE,
379 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, EINA_FALSE);
381 if (!eldbus_message_arguments_append(msg,"s", bus_name))
384 eldbus_connection_send(bus_conn, msg, _has_owner_cb, cs, -1);
388 eldbus_message_unref(msg);
392 Evas_Object *gui_layout_add(Evas_Object *parent, const char *style)
394 Evas_Object *layout = elm_layout_add(parent);
395 if (!elm_layout_theme_set(layout, "layout", "dialer", style)) {
396 evas_object_del(layout);
403 static int _running_apps_iter(const aul_app_info *info, void *data __UNUSED__)
405 if (strcmp(info->pkg_name, "org.tizen.draglock") == 0)
406 aul_terminate_pid(info->pid);
411 static void _phone_unlock_screen(void)
413 INF("unlock screen");
415 aul_app_get_running_app_info(_running_apps_iter, NULL);
419 static void _slider_pos_changed_cb(void *data, Evas_Object *obj,
420 void *event_inf __UNUSED__)
422 Call_Screen *cs = data;
423 const char *label = elm_actionslider_selected_label_get(obj);
428 if (strcmp(label, "Answer") == 0) {
429 _daemon_method_call_make("AnswerCall");
430 elm_actionslider_indicator_pos_set(obj,
431 ELM_ACTIONSLIDER_CENTER);
432 _phone_unlock_screen();
433 _call_screen_hide(cs);
434 } else if (strcmp(label, "Hangup") == 0) {
435 _daemon_method_call_make("HangupCall");
436 elm_actionslider_indicator_pos_set(obj,
437 ELM_ACTIONSLIDER_CENTER);
441 static Eina_Bool _gui_init(Call_Screen *cs)
443 Evas_Object *win, *obj, *lay, *slider;
445 char def_theme[PATH_MAX];
446 /* should never, ever quit */
448 elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_NONE);
449 elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR);
450 elm_app_compile_data_dir_set(PACKAGE_DATA_DIR);
451 elm_app_info_set(_gui_init, "answer-ofono-efl", "themes/default.edj");
453 snprintf(def_theme, sizeof(def_theme), "%s/themes/default.edj",
454 elm_app_data_dir_get());
456 elm_theme_extension_add(NULL, def_theme);
457 elm_theme_overlay_add(NULL, def_theme);
459 win = elm_win_util_standard_add("answer screen", "oFono Answer");
460 EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
461 elm_win_autodel_set(win, EINA_FALSE);
462 elm_object_part_text_set(win, "elm.text.name", _("Unknown"));
463 elm_object_part_text_set(win, "elm.text.state", _("Incoming..."));
465 lay = gui_layout_add(win, "answer");
466 EINA_SAFETY_ON_NULL_RETURN_VAL(lay, EINA_FALSE);
467 evas_object_show(lay);
469 slider = elm_actionslider_add(win);
470 EINA_SAFETY_ON_NULL_GOTO(slider, err_obj);
471 elm_object_style_set(slider, "answer");
472 elm_actionslider_indicator_pos_set(slider, ELM_ACTIONSLIDER_CENTER);
473 elm_actionslider_magnet_pos_set(slider, ELM_ACTIONSLIDER_CENTER);
474 elm_object_part_text_set(slider, "left", _("Hangup"));
475 elm_object_part_text_set(slider, "right", _("Answer"));
476 evas_object_smart_callback_add(slider, "selected",
477 _slider_pos_changed_cb, cs);
478 evas_object_show(slider);
479 elm_object_part_content_set(lay, "elm.swallow.slider", slider);
481 obj = elm_layout_edje_get(lay);
482 edje_object_size_min_get(obj, &w, &h);
483 if ((w == 0) || (h == 0))
484 edje_object_size_min_restricted_calc(obj, &w, &h, w, h);
485 if ((w == 0) || (h == 0))
486 edje_object_parts_extends_calc(obj, NULL, NULL, &w, &h);
487 evas_object_resize(lay, w, h);
488 evas_object_resize(win, w, h);
495 evas_object_del(win);
499 EAPI int elm_main(int argc __UNUSED__, char **argv __UNUSED__)
503 if (!elm_need_eldbus()) {
504 ERR("Could not start E_dbus");
508 _log_domain = eina_log_domain_register("answer_daemon", NULL);
509 cs = calloc(1, sizeof(Call_Screen));
510 EINA_SAFETY_ON_NULL_RETURN_VAL(cs, -1);
512 EINA_SAFETY_ON_FALSE_GOTO(_dbus_init(cs), err_dbus);
513 EINA_SAFETY_ON_FALSE_GOTO(_gui_init(cs), err_dbus);
517 _signal_handlers_del(cs);
519 if (cs->sig_name_changed)
520 eldbus_signal_handler_del(cs->sig_name_changed);
522 evas_object_del(cs->win);
524 _call_destroy(cs->call);