4 #include <Elementary.h>
10 typedef struct _AMB_Manager AMB_Manager;
11 typedef struct _AMB_Bus_Object AMB_Bus_Object;
13 static const char bus_name[] = "org.automotive.message.broker";
15 static Eldbus_Connection *bus_conn = NULL;
16 static char *bus_id = NULL;
17 static AMB_Manager *amb_manager = NULL;
18 static Eldbus_Signal_Handler *sig_amb_properties_changed = NULL;
20 struct _AMB_Callback_List_Node
23 void (*cb)(void *data);
27 static Eina_Inlist *cbs_amb_connected = NULL;
28 static Eina_Inlist *cbs_amb_disconnected = NULL;
29 static Eina_Inlist *cbs_amb_properties_changed = NULL;
31 #define AMB_MANAGER_IFACE "org.automotive.Manager"
32 #define AMB_PROPERTIES_IFACE "org.freedesktop.DBus.Properties"
33 #define AMB_NIGHT_MODE_IFACE "org.automotive.NightMode"
34 #define PROP_NIGHT_MODE_STRING "NightMode"
36 struct _AMB_Bus_Object
39 Eina_List *dbus_signals; /* of Eldbus_Signal_Handler */
42 static void _bus_object_free(AMB_Bus_Object *o)
44 Eldbus_Signal_Handler *sh;
46 eina_stringshare_del(o->path);
48 EINA_LIST_FREE(o->dbus_signals, sh)
49 eldbus_signal_handler_del(sh);
56 unsigned int interfaces;
60 static AMB_Manager *_amb_get(void)
65 static void _notify_amb_callbacks_list(Eina_Inlist *list)
67 AMB_Callback_List_Node *node;
69 EINA_INLIST_FOREACH(list, node)
70 node->cb((void *) node->cb_data);
73 static void _amb_get_property_reply(void *data, const Eldbus_Message *msg,
74 Eldbus_Pending *pending __UNUSED__)
76 Eldbus_Message_Iter *variant;
77 const char *err_name, *err_message;
79 EINA_SAFETY_ON_NULL_RETURN(data);
86 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
87 ERR("Failed to get property: %s: %s", err_name, err_message);
91 if (!eldbus_message_arguments_get(msg, "v", &variant)) {
92 ERR("Could not get arguments");
96 char *property_name = (char*) data;
97 AMB_Manager *m = _amb_get();
99 if (strcmp(property_name, PROP_NIGHT_MODE_STRING) == 0) {
100 eldbus_message_iter_arguments_get(variant, "b", &m->night_mode);
101 DBG("NightMode is set to: %d", m->night_mode);
106 _notify_amb_callbacks_list(cbs_amb_properties_changed);
109 static void _amb_manager_property_get(const char *property, const char *path, Eldbus_Message_Cb cb, void *data)
112 char *interface_name;
114 EINA_SAFETY_ON_NULL_RETURN(property);
115 EINA_SAFETY_ON_NULL_RETURN(path);
117 if (strcmp(property, PROP_NIGHT_MODE_STRING) == 0) {
118 interface_name = AMB_NIGHT_MODE_IFACE;
123 msg = eldbus_message_method_call_new(
124 bus_id, path, AMB_PROPERTIES_IFACE, "Get");
126 eldbus_message_arguments_append(msg,"ss", interface_name, property);
127 eldbus_connection_send(bus_conn, msg, cb, data, -1);
130 static void _amb_get_property_path_reply(void *data, Eldbus_Message *msg,
131 Eldbus_Pending *pending __UNUSED__)
133 Eldbus_Message_Iter *ao;
134 const char *path, *err_name, *err_message;
136 EINA_SAFETY_ON_NULL_RETURN(data);
143 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
144 ERR("Failed to get property path: %s: %s", err_name, err_message);
148 if (!eldbus_message_arguments_get(msg, "ao", &ao)) {
149 ERR("Could not get arguments");
153 eldbus_message_iter_get_and_next(ao, 'o', &path);
156 ERR("Could not get object path");
160 _amb_manager_property_get((const char*) data, path, _amb_get_property_reply, data);
163 static void _amb_get_property_path(const char *property, Eldbus_Message_Cb cb)
165 Eldbus_Message *msg = eldbus_message_method_call_new(
166 bus_id, "/", AMB_MANAGER_IFACE, "FindObject");
168 eldbus_message_arguments_append(msg, "s", property);
169 eldbus_connection_send(bus_conn, msg, cb, (void*) property, -1);
172 static void _amb_get_property(const char *property)
174 _amb_get_property_path(property, _amb_get_property_path_reply);
177 static AMB_Manager *_amb_new(const char *path)
179 AMB_Manager *m = calloc(1, sizeof(AMB_Manager));
180 EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
182 m->base.path = eina_stringshare_add(path);
183 EINA_SAFETY_ON_NULL_GOTO(m->base.path, error_path);
192 static void _amb_free(AMB_Manager *m)
194 eina_stringshare_del(m->name);
196 _bus_object_free(&m->base);
200 static void _amb_properties_changed(void *data __UNUSED__, Eldbus_Message *msg)
202 Eina_Bool changed = EINA_FALSE;
203 Eldbus_Message_Iter *array1, *array2, *dict;
204 const char *interface, *err_name, *err_message;
206 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
207 ERR("Failed to get signal: %s: %s", err_name, err_message);
211 if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &array1, &array2)) {
212 ERR("Could not get PropertiesChanged arguments");
216 AMB_Manager *m = _amb_get();
218 while (eldbus_message_iter_get_and_next(array1, 'e', &dict)) {
219 Eldbus_Message_Iter *variant;
220 const char *property;
222 if (!eldbus_message_iter_arguments_get(dict, "sv", &property, &variant))
225 DBG("AMB property changed at %s: %s", interface, property);
226 if (strcmp(interface, AMB_NIGHT_MODE_IFACE) == 0 &&
227 strcmp(property, PROP_NIGHT_MODE_STRING) == 0) {
228 eldbus_message_iter_arguments_get(variant, "b", &m->night_mode);
230 DBG("NightMode updated: %d", m->night_mode);
235 _notify_amb_callbacks_list(cbs_amb_properties_changed);
238 static void _amb_load(void)
240 amb_manager = _amb_new("/");
241 EINA_SAFETY_ON_NULL_RETURN(amb_manager);
243 _amb_get_property(PROP_NIGHT_MODE_STRING);
246 static void _amb_connected(const char *id)
251 sig_amb_properties_changed = eldbus_signal_handler_add(
252 bus_conn, bus_id, NULL,
253 AMB_PROPERTIES_IFACE,
255 _amb_properties_changed, NULL);
259 _notify_amb_callbacks_list(cbs_amb_connected);
262 static void _amb_disconnected(void)
264 if (sig_amb_properties_changed) {
265 eldbus_signal_handler_del(sig_amb_properties_changed);
266 sig_amb_properties_changed = NULL;
270 _notify_amb_callbacks_list(cbs_amb_disconnected);
276 static void _name_owner_changed(void *data __UNUSED__, Eldbus_Message *msg)
278 const char *name, *from, *to;
280 if (!eldbus_message_arguments_get(msg, "sss", &name, &from, &to)) {
281 ERR("Could not get NameOwnerChanged arguments");
285 if (strcmp(name, bus_name) != 0)
288 DBG("NameOwnerChanged %s from=%s to=%s", name, from, to);
290 if (from[0] == '\0' && to[0] != '\0') {
291 INF("amb appeared as %s", to);
293 } else if (from[0] != '\0' && to[0] == '\0') {
294 INF("amb disappeared from %s", from);
299 static void _amb_get_name_owner(void *data __UNUSED__, Eldbus_Message *msg,
300 Eldbus_Pending *pending __UNUSED__)
302 const char *id, *err_name, *err_message;
309 if (eldbus_message_error_get(msg, &err_name, &err_message)) {
310 ERR("Failed to get name owner: %s: %s", err_name, err_message);
314 if (!eldbus_message_arguments_get(msg, "s", &id)) {
315 ERR("Could not get arguments");
319 if (!id || id[0] == '\0') {
320 ERR("No name owner fo %s!", bus_name);
324 INF("amb bus id: %s", id);
328 Eina_Bool amb_night_mode_get(void)
330 AMB_Manager *m = _amb_get();
331 EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE);
332 return m->night_mode;
335 Eina_Bool amb_init(void)
337 if (!elm_need_eldbus()) {
338 CRITICAL("Elementary does not support DBus.");
342 bus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
344 CRITICAL("Could not get DBus System Bus");
348 eldbus_signal_handler_add(bus_conn, ELDBUS_FDO_BUS, ELDBUS_FDO_PATH,
349 ELDBUS_FDO_INTERFACE,
351 _name_owner_changed, NULL);
353 eldbus_name_owner_get(bus_conn, bus_name, _amb_get_name_owner, NULL);
358 void amb_shutdown(void)
361 _amb_free(amb_manager);
367 static AMB_Callback_List_Node * _amb_callback_list_node_create(
368 void (*cb)(void *data),const void *data)
370 AMB_Callback_List_Node *node_new;
372 node_new = calloc(1, sizeof(AMB_Callback_List_Node));
373 EINA_SAFETY_ON_NULL_RETURN_VAL(node_new, NULL);
375 node_new->cb_data = data;
381 static void _amb_callback_list_delete(Eina_Inlist **list,
382 AMB_Callback_List_Node *node)
384 EINA_SAFETY_ON_NULL_RETURN(*list);
385 *list = eina_inlist_remove(*list, EINA_INLIST_GET(node));
389 AMB_Callback_List_Node *
390 amb_properties_changed_cb_add(void (*cb)(void *data), const void *data)
392 AMB_Callback_List_Node *node;
394 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
395 node = _amb_callback_list_node_create(cb, data);
396 EINA_SAFETY_ON_NULL_RETURN_VAL(node, NULL);
398 cbs_amb_properties_changed = eina_inlist_append(cbs_amb_properties_changed,
399 EINA_INLIST_GET(node));
404 void amb_properties_changed_cb_del(AMB_Callback_List_Node *node)
406 EINA_SAFETY_ON_NULL_RETURN(node);
407 _amb_callback_list_delete(&cbs_amb_properties_changed, node);