From: Jimmy Huang Date: Wed, 21 Aug 2013 23:35:58 +0000 (-0700) Subject: Adding support for nightmode theme change X-Git-Tag: submit/tizen/20130826.172726~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9153d94c2d34a37eed5ffb375206f34b53257aa5;p=profile%2Fivi%2Flemolo.git Adding support for nightmode theme change - Added support for AMB for querying NightMode properties - Dialer will change theme by using theme overlay to darker theme if NightMode is set Signed-off-by: Jimmy Huang Change-Id: I13f4466d9c538a4fb9d571a2059c5a1b782719c7 --- diff --git a/Makefile.am b/Makefile.am index 7665eb2..a627f54 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,6 +26,8 @@ EXTRA_DIST = noinst_LTLIBRARIES = utils/libofono-efl-utils.la utils_libofono_efl_utils_la_SOURCES = \ + utils/amb.c \ + utils/amb.h \ utils/contacts-ofono-efl.h \ utils/log.h \ utils/ofono.c \ diff --git a/dialer/callscreen.c b/dialer/callscreen.c index b447c95..65aa6d2 100644 --- a/dialer/callscreen.c +++ b/dialer/callscreen.c @@ -632,6 +632,10 @@ static void _call_auto_place(Callscreen *ctx, OFono_Call *c) if (!ctx->calls.first) { DBG("first call %p", c); + _call_clear(ctx, 1); + _call_clear(ctx, 2); + elm_object_signal_emit(ctx->self, "calls,1", "call"); + _call_first_set(ctx, c); _call_current_set(ctx, c); return; diff --git a/dialer/gui.c b/dialer/gui.c index e533770..4b03cd9 100644 --- a/dialer/gui.c +++ b/dialer/gui.c @@ -27,14 +27,18 @@ static Evas_Object *contacts = NULL; static Evas_Object *history = NULL; static Evas_Object *cs = NULL; static Evas_Object *flip = NULL; +static Evas_Object *current_view = NULL; static OFono_Callback_List_Modem_Node *callback_node_modem_changed = NULL; static OFono_Callback_List_USSD_Notify_Node *callback_node_ussd_notify = NULL; +static AMB_Callback_List_Node *callback_node_night_mode_changed = NULL; /* XXX elm_flip should just do the right thing, but it does not */ static Eina_Bool in_call = EINA_FALSE; static Eina_Bool in_flip_anim = EINA_FALSE; +static Eina_Bool night_mode = EINA_FALSE; + Contact_Info *gui_contact_search(const char *number, const char **type) { return contact_search(contacts, number, type); @@ -71,6 +75,7 @@ static void _gui_show(Evas_Object *o) else if (o == history) elm_object_signal_emit(main_layout, "show,history", "gui"); elm_object_focus_set(o, EINA_TRUE); + current_view = o; } Evas_Object *gui_simple_popup(const char *title, const char *message) @@ -231,6 +236,21 @@ static void _ofono_changed(void *data __UNUSED__) elm_object_part_text_set(main_layout, "elm.text.voicemail", buf); } +static void _night_mode_changed(void *data __UNUSED__) +{ + DBG("Night mode changed"); + Eina_Bool changed = amb_night_mode_get(); + if (night_mode != changed) + { + DBG("Nightmode changed to %d", changed); + night_mode = changed; + util_set_night_mode(night_mode); + + if (current_view) + _gui_show(current_view); + } +} + static void _ofono_ussd_notify(void *data __UNUSED__, Eina_Bool needs_reply, const char *message) { @@ -314,6 +334,8 @@ Eina_Bool gui_init(void) ofono_modem_changed_cb_add(_ofono_changed, NULL); callback_node_ussd_notify = ofono_ussd_notify_cb_add(_ofono_ussd_notify, NULL); + callback_node_night_mode_changed = + amb_properties_changed_cb_add(_night_mode_changed, NULL); /* TODO: make it match better with Tizen: icon and other properties */ obj = elm_layout_edje_get(lay); diff --git a/dialer/gui.h b/dialer/gui.h index 22f5afe..9a6396a 100644 --- a/dialer/gui.h +++ b/dialer/gui.h @@ -3,6 +3,7 @@ #include "contacts-ofono-efl.h" #include "ofono.h" +#include "amb.h" Evas_Object *gui_simple_popup(const char *title, const char *message); diff --git a/dialer/main.c b/dialer/main.c index b0b4948..3d4a55f 100644 --- a/dialer/main.c +++ b/dialer/main.c @@ -11,6 +11,7 @@ #ifndef ELM_LIB_QUICKLAUNCH +#include "amb.h" #include "gui.h" #include "log.h" #include "ofono.h" @@ -207,6 +208,14 @@ EAPI int elm_main(int argc, char **argv) goto end_ofono; } +#ifdef HAVE_TIZEN + if (!amb_init()) { + CRITICAL("Could not setup automotive-message-broker"); + _app_exit_code = EXIT_FAILURE; + goto end_amb; + } +#endif + if (!gui_init()) { CRITICAL("Could not setup graphical user interface"); _app_exit_code = EXIT_FAILURE; @@ -235,6 +244,10 @@ EAPI int elm_main(int argc, char **argv) end_util: util_shutdown(); +#ifdef HAVE_TIZEN +end_amb: + amb_shutdown(); +#endif end_ofono: ofono_shutdown(); end_rc: diff --git a/packaging/lemolo.spec b/packaging/lemolo.spec index 4f9b3d1..a55dafe 100644 --- a/packaging/lemolo.spec +++ b/packaging/lemolo.spec @@ -20,6 +20,7 @@ BuildRequires: pkgconfig(appsvc) BuildRequires: pkgconfig(notification) BuildRequires: edje-tools Requires: ofono +Requires: automotive-message-broker %description Provides a dialer application for an In-Vehicle Infotainment (IVI) system, where diff --git a/utils/amb.c b/utils/amb.c new file mode 100644 index 0000000..6e15048 --- /dev/null +++ b/utils/amb.c @@ -0,0 +1,420 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include + +#include "amb.h" +#include "log.h" + +typedef struct _AMB_Manager AMB_Manager; +typedef struct _AMB_Bus_Object AMB_Bus_Object; + +static const char bus_name[] = "org.automotive.message.broker"; + +static E_DBus_Connection *bus_conn = NULL; +static char *bus_id = NULL; +static AMB_Manager *amb_manager = NULL; +static E_DBus_Signal_Handler *sig_amb_properties_changed = NULL; +static DBusPendingCall *amb_get_night_mode_path = NULL; + +struct _AMB_Callback_List_Node +{ + EINA_INLIST; + void (*cb)(void *data); + const void *cb_data; +}; + +static Eina_Inlist *cbs_amb_connected = NULL; +static Eina_Inlist *cbs_amb_disconnected = NULL; +static Eina_Inlist *cbs_amb_properties_changed = NULL; + +#define AMB_MANAGER_IFACE "org.automotive.Manager" +#define AMB_PROPERTIES_IFACE "org.freedesktop.DBus.Properties" +#define AMB_NIGHT_MODE_IFACE "org.automotive.NightMode" +#define PROP_NIGHT_MODE_STRING "NightMode" + +static Eina_Bool _dbus_bool_get(DBusMessageIter *itr) +{ + dbus_bool_t val; + dbus_message_iter_get_basic(itr, &val); + return val; +} + +struct _AMB_Bus_Object +{ + const char *path; + Eina_List *dbus_signals; /* of E_DBus_Signal_Handler */ +}; + +static void _bus_object_free(AMB_Bus_Object *o) +{ + E_DBus_Signal_Handler *sh; + + eina_stringshare_del(o->path); + + EINA_LIST_FREE(o->dbus_signals, sh) + e_dbus_signal_handler_del(bus_conn, sh); +} + +struct _AMB_Manager +{ + AMB_Bus_Object base; + const char *name; + unsigned int interfaces; + unsigned char vehiclespeed; + Eina_Bool nightmode : 1; +}; + +static void _amb_property_update(AMB_Manager *m, const char *interface, + DBusMessageIter *property) +{ + if (strcmp(interface, AMB_NIGHT_MODE_IFACE) == 0) { + /* TODO: change later to use night mode */ + DBusMessageIter entry, variant; + const char *key; + + dbus_message_iter_recurse(property, &entry); + dbus_message_iter_get_basic(&entry, &key); + + if (strcmp(key, PROP_NIGHT_MODE_STRING) == 0) { + + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &variant); + m->nightmode = _dbus_bool_get(&variant); + DBG("NightMode updated: %d", m->nightmode); + } else { + DBG("invalid key: %s", key); + } + } else { + DBG("%s (unused property)", interface); + } +} + +static AMB_Manager *_amb_get(void) +{ + return amb_manager; +} + +static void _notify_amb_callbacks_list(Eina_Inlist *list) +{ + AMB_Callback_List_Node *node; + + EINA_INLIST_FOREACH(list, node) + node->cb((void *) node->cb_data); +} + +static void _amb_get_night_mode_reply(void *data __UNUSED__, DBusMessage *msg, + DBusError *err) +{ + if (!msg) { + if (err) + ERR("%s: %s", err->name, err->message); + else + ERR("No message"); + return; + } + + DBusError e; + dbus_error_init(&e); + dbus_bool_t value; + + AMB_Manager *m = _amb_get(); + + dbus_message_get_args(msg, &e, DBUS_TYPE_BOOLEAN, &value, DBUS_TYPE_INVALID); + + m->nightmode = value; + DBG("NightMode is set to: %d", m->nightmode); + _notify_amb_callbacks_list(cbs_amb_properties_changed); +} + +static void _amb_manager_property_get(char *property, char *path, E_DBus_Method_Return_Cb cb, void *data) +{ + DBusMessage *msg; + + EINA_SAFETY_ON_NULL_RETURN(property); + EINA_SAFETY_ON_NULL_RETURN(path); + + if (strcmp(property, PROP_NIGHT_MODE_STRING) == 0) { + char* interface_name = AMB_NIGHT_MODE_IFACE; + + msg = dbus_message_new_method_call( + bus_id, path, AMB_PROPERTIES_IFACE, "Get"); + + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &interface_name, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + + e_dbus_message_send(bus_conn, msg, cb, -1, data); + } + + dbus_message_unref(msg); +} + +static void _amb_get_night_mode_path_reply(void *data __UNUSED__, DBusMessage *msg, + DBusError *err) +{ + amb_get_night_mode_path = NULL; + + if (!msg) { + if (err) + ERR("%s: %s", err->name, err->message); + else + ERR("No message"); + return; + } + + DBusError e; + char *path; + dbus_error_init(&e); + dbus_message_get_args(msg, &e, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); + + if(!path) { + ERR("Could not get NightMode object path"); + return; + } + + _amb_manager_property_get(PROP_NIGHT_MODE_STRING, path, _amb_get_night_mode_reply, NULL); +} + +static AMB_Manager *_amb_new(const char *path) +{ + AMB_Manager *m = calloc(1, sizeof(AMB_Manager)); + EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); + + m->base.path = eina_stringshare_add(path); + EINA_SAFETY_ON_NULL_GOTO(m->base.path, error_path); + + return m; + +error_path: + free(m); + return NULL; +} + +static void _amb_free(AMB_Manager *m) +{ + eina_stringshare_del(m->name); + + _bus_object_free(&m->base); + free(m); +} + +static void _amb_properties_changed(void *data __UNUSED__, DBusMessage *msg) +{ + const char *path; + AMB_Manager *m = _amb_get(); + DBusMessageIter iter, value; + const char *interface; + + if (!msg || !dbus_message_iter_init(msg, &iter)) { + ERR("Could not handle message %p", msg); + return; + } + + path = dbus_message_get_path(msg); + + dbus_message_iter_get_basic(&iter, &interface); + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &value); + + if (strcmp(interface, AMB_NIGHT_MODE_IFACE) == 0) { + _amb_property_update(m, interface, &value); + _notify_amb_callbacks_list(cbs_amb_properties_changed); + } +} + +static void _amb_load(void) +{ + amb_manager = _amb_new("/"); + EINA_SAFETY_ON_NULL_RETURN(amb_manager); + + char *property_name = PROP_NIGHT_MODE_STRING; + + DBusMessage *msg = dbus_message_new_method_call( + bus_id, "/", AMB_MANAGER_IFACE, "findProperty"); + + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &property_name, + DBUS_TYPE_INVALID); + + amb_get_night_mode_path = e_dbus_message_send( + bus_conn, msg, _amb_get_night_mode_path_reply, -1, NULL); + + dbus_message_unref(msg); +} + +static void _amb_connected(const char *id) +{ + free(bus_id); + bus_id = strdup(id); + + sig_amb_properties_changed = e_dbus_signal_handler_add( + bus_conn, bus_id, NULL, + AMB_PROPERTIES_IFACE, + "PropertiesChanged", + _amb_properties_changed, NULL); + + _amb_load(); + + _notify_amb_callbacks_list(cbs_amb_connected); +} + +static void _amb_disconnected(void) +{ + if (sig_amb_properties_changed) { + e_dbus_signal_handler_del(bus_conn, sig_amb_properties_changed); + sig_amb_properties_changed = NULL; + } + + if (bus_id) { + _notify_amb_callbacks_list(cbs_amb_disconnected); + free(bus_id); + bus_id = NULL; + } +} + +static void _name_owner_changed(void *data __UNUSED__, DBusMessage *msg) +{ + DBusError err; + const char *name, *from, *to; + + dbus_error_init(&err); + if (!dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &from, + DBUS_TYPE_STRING, &to, + DBUS_TYPE_INVALID)) { + ERR("Could not get NameOwnerChanged arguments: %s: %s", + err.name, err.message); + dbus_error_free(&err); + return; + } + + if (strcmp(name, bus_name) != 0) + return; + + DBG("NameOwnerChanged %s from=%s to=%s", name, from, to); + + if (from[0] == '\0' && to[0] != '\0') { + INF("amb appeared as %s", to); + _amb_connected(to); + } else if (from[0] != '\0' && to[0] == '\0') { + INF("amb disappeared from %s", from); + _amb_disconnected(); + } +} + +static void _amb_get_name_owner(void *data __UNUSED__, DBusMessage *msg, DBusError *err) +{ + DBusMessageIter itr; + const char *id; + + if (!msg) { + if (err) + ERR("%s: %s", err->name, err->message); + else + ERR("No message"); + return; + } + + dbus_message_iter_init(msg, &itr); + dbus_message_iter_get_basic(&itr, &id); + if (!id || id[0] == '\0') { + ERR("No name owner fo %s!", bus_name); + return; + } + + INF("amb bus id: %s", id); + _amb_connected(id); +} + +Eina_Bool amb_nightmode_get(void) +{ + AMB_Manager *m = _amb_get(); + EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); + return m->nightmode; +} + +Eina_Bool amb_init(void) +{ + if (!elm_need_e_dbus()) { + CRITICAL("Elementary does not support DBus."); + return EINA_FALSE; + } + + bus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM); + if (!bus_conn) { + CRITICAL("Could not get DBus System Bus"); + return EINA_FALSE; + } + + e_dbus_signal_handler_add(bus_conn, E_DBUS_FDO_BUS, E_DBUS_FDO_PATH, + E_DBUS_FDO_INTERFACE, + "NameOwnerChanged", + _name_owner_changed, NULL); + + e_dbus_get_name_owner(bus_conn, bus_name, _amb_get_name_owner, NULL); + + return EINA_TRUE; +} + +void amb_shutdown(void) +{ + if (amb_manager) { + _amb_free(amb_manager); + amb_manager = NULL; + } + _amb_disconnected(); +} + +Eina_Bool amb_night_mode_get(void) +{ + AMB_Manager *m = _amb_get(); + EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); + return m->nightmode; +} + +static AMB_Callback_List_Node * _amb_callback_list_node_create( + void (*cb)(void *data),const void *data) +{ + AMB_Callback_List_Node *node_new; + + node_new = calloc(1, sizeof(AMB_Callback_List_Node)); + EINA_SAFETY_ON_NULL_RETURN_VAL(node_new, NULL); + + node_new->cb_data = data; + node_new->cb = cb; + + return node_new; +} + +static void _amb_callback_list_delete(Eina_Inlist **list, + AMB_Callback_List_Node *node) +{ + EINA_SAFETY_ON_NULL_RETURN(*list); + *list = eina_inlist_remove(*list, EINA_INLIST_GET(node)); + free(node); +} + +AMB_Callback_List_Node * +amb_properties_changed_cb_add(void (*cb)(void *data), const void *data) +{ + AMB_Callback_List_Node *node; + + EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL); + node = _amb_callback_list_node_create(cb, data); + EINA_SAFETY_ON_NULL_RETURN_VAL(node, NULL); + + cbs_amb_properties_changed = eina_inlist_append(cbs_amb_properties_changed, + EINA_INLIST_GET(node)); + + return node; +} + +void amb_properties_changed_cb_del(AMB_Callback_List_Node *node) +{ + EINA_SAFETY_ON_NULL_RETURN(node); + _amb_callback_list_delete(&cbs_amb_properties_changed, node); +} diff --git a/utils/amb.h b/utils/amb.h new file mode 100644 index 0000000..86f95f3 --- /dev/null +++ b/utils/amb.h @@ -0,0 +1,22 @@ +#ifndef _AMB_H__ +#define _AMB_H__ + +typedef enum +{ + AMB_ERROR_NONE = 0, + AMB_ERROR_FAILED +} AMB_Error; + +typedef struct _AMB_Callback_List_Node AMB_Callback_List_Node; + +AMB_Callback_List_Node *amb_properties_changed_cb_add(void (*cb)(void *data), const void *data); + +void amb_properties_changed_cb_del(AMB_Callback_List_Node *callback_node); + +Eina_Bool amb_night_mode_get(void); + +Eina_Bool amb_init(void); + +void amb_shutdown(void); + +#endif diff --git a/utils/util.c b/utils/util.c index 0949b33..81bb9b2 100644 --- a/utils/util.c +++ b/utils/util.c @@ -159,6 +159,29 @@ Evas_Object *layout_add(Evas_Object *parent, const char *style) return layout; } +Eina_Bool util_set_night_mode(Eina_Bool night_mode) +{ + snprintf(def_theme, sizeof(def_theme), "%s/themes/night.edj", + elm_app_data_dir_get()); + + elm_theme_extension_add(NULL, def_theme); + + if (night_mode) + { + night_mode = EINA_TRUE; + elm_theme_overlay_add(NULL, def_theme); + DBG("Load theme at %s", def_theme); + } + else + { + night_mode = EINA_FALSE; + elm_theme_overlay_del(NULL, def_theme); + DBG("Unload theme at %s", def_theme); + } + + return EINA_TRUE; +} + Eina_Bool util_init(const char *theme) { elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR); diff --git a/utils/util.h b/utils/util.h index 246dbe6..cb0a279 100644 --- a/utils/util.h +++ b/utils/util.h @@ -17,6 +17,8 @@ Evas_Object *picture_icon_get(Evas_Object *parent, const char *picture); Evas_Object *layout_add(Evas_Object *parent, const char *style); +Eina_Bool util_set_night_mode(Eina_Bool night_mode); + Eina_Bool util_init(const char *theme); void util_shutdown(void);