10 #include "E_Connman.h"
11 #include "e_mod_main.h"
12 #define AGENT_IFACE "net.connman.Agent"
13 #define AGENT_KEY "agent"
15 typedef struct _E_Connman_Agent_Input E_Connman_Agent_Input;
22 const char *requirement;
24 Eina_Array *alternates;
27 struct _E_Connman_Agent_Input
34 struct _E_Connman_Agent
37 Eldbus_Service_Interface *iface;
39 Eldbus_Connection *conn;
44 _dict_append_basic(Eldbus_Message_Iter *array, const char *key, void *val)
46 Eldbus_Message_Iter *dict, *variant;
48 eldbus_message_iter_arguments_append(array, "{sv}", &dict);
49 eldbus_message_iter_basic_append(dict, 's', key);
50 variant = eldbus_message_iter_container_new(dict, 'v', "s");
51 eldbus_message_iter_basic_append(variant, 's', val ?: "");
52 eldbus_message_iter_container_close(dict, variant);
53 eldbus_message_iter_container_close(array, dict);
57 _dialog_ok_cb(void *data, E_Dialog *dialog)
59 E_Connman_Agent *agent = data;
60 E_Connman_Agent_Input *input;
61 Evas_Object *toolbook, *list;
62 Eldbus_Message_Iter *iter, *array;
63 Eina_List *input_list, *l;
64 Eldbus_Message *reply;
66 toolbook = agent->dialog->content_object;
68 /* fugly - no toolbook page get */
69 list = evas_object_data_get(toolbook, "mandatory");
70 if ((!list) || (!evas_object_visible_get(list)))
72 list = evas_object_data_get(toolbook, "alternate");
73 if ((!list) || (!evas_object_visible_get(list)))
75 ERR("Couldn't get user input.");
76 e_object_del(E_OBJECT(dialog));
81 agent->canceled = EINA_FALSE;
82 input_list = evas_object_data_get(list, "input_list");
84 reply = eldbus_message_method_return_new(agent->msg);
85 iter = eldbus_message_iter_get(reply);
86 eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
88 EINA_LIST_FOREACH(input_list, l, input)
89 _dict_append_basic(array, input->key, input->value);
90 eldbus_message_iter_container_close(iter, array);
92 eldbus_connection_send(agent->conn, reply, NULL, NULL, -1);
94 e_object_del(E_OBJECT(dialog));
98 _dialog_cancel_cb(void *data, E_Dialog *dialog)
100 E_Connman_Agent *agent = data;
101 agent->canceled = EINA_TRUE;
102 e_object_del(E_OBJECT(dialog));
106 _dialog_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__,
109 Evas_Event_Key_Down *ev = event;
110 E_Connman_Agent *agent = data;
112 if (!strcmp(ev->key, "Return"))
113 _dialog_ok_cb(agent, agent->dialog);
114 else if (strcmp(ev->key, "Escape") == 0)
115 _dialog_cancel_cb(agent, agent->dialog);
119 _dialog_cancel(E_Connman_Agent *agent)
121 Eldbus_Message *reply;
123 reply = eldbus_message_error_new(agent->msg,
124 "net.connman.Agent.Error.Canceled",
125 "User canceled dialog");
126 eldbus_connection_send(agent->conn, reply, NULL, NULL, -1);
130 _dialog_del_cb(void *data)
132 E_Dialog *dialog = data;
133 E_Connman_Agent *agent = e_object_data_get(E_OBJECT(dialog));
136 _dialog_cancel(agent);
138 // FIXME need to mark cs->pending_connect = NULL;
139 eldbus_message_unref(agent->msg);
140 agent->dialog = NULL;
144 _page_del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
146 E_Connman_Agent_Input *input;
147 Eina_List *input_list;
149 input_list = evas_object_data_get(obj, "input_list");
150 EINA_LIST_FREE(input_list, input)
158 _show_password_cb(void *data, Evas_Object *obj, void *event __UNUSED__)
160 Evas_Object *entry = data;
163 hidden = !e_widget_check_checked_get(obj);
164 e_widget_entry_password_set(entry, hidden);
168 _dialog_field_add(E_Connman_Agent *agent, struct Connman_Field *field)
170 Evas_Object *toolbook, *list, *framelist, *entry, *check;
171 E_Connman_Agent_Input *input;
172 Eina_List *input_list;
177 evas = evas_object_evas_get(agent->dialog->win);
178 toolbook = agent->dialog->content_object;
179 mandatory = !strcmp(field->requirement, "mandatory");
181 if ((!mandatory) && (strcmp(field->requirement, "alternate")))
183 WRN("Field not handled: %s %s", field->name, field->type);
187 input = E_NEW(E_Connman_Agent_Input, 1);
188 input->key = strdup(field->name);
189 entry = e_widget_entry_add(agent->dialog->win, &(input->value), NULL, NULL, NULL);
190 evas_object_show(entry);
192 list = evas_object_data_get(toolbook, field->requirement);
195 list = e_widget_list_add(evas, 0, 0);
196 e_widget_toolbook_page_append(toolbook, NULL, field->name,
197 list, 1, 1, 1, 1, 0.5, 0.0);
198 evas_object_data_set(toolbook, field->requirement, list);
200 e_widget_toolbook_page_show(toolbook, 0);
201 evas_object_event_callback_add(list, EVAS_CALLBACK_DEL,
205 e_widget_focus_set(entry, 1);
208 input_list = evas_object_data_get(list, "input_list");
209 input_list = eina_list_append(input_list, input);
210 evas_object_data_set(list, "input_list", input_list);
212 snprintf(header, sizeof(header), "%s required to access network:",
214 framelist = e_widget_framelist_add(evas, header, 0);
215 evas_object_show(framelist);
216 e_widget_list_object_append(list, framelist, 1, 1, 0.5);
218 e_widget_framelist_object_append(framelist, entry);
220 if ((!strcmp(field->name, "Passphrase")) ||
221 (!strcmp(field->name, "Password")))
223 e_widget_entry_password_set(entry, 1);
225 check = e_widget_check_add(evas, _("Show password"),
226 &(input->show_password));
227 evas_object_show(check);
228 e_widget_framelist_object_append(framelist, check);
230 evas_object_smart_callback_add(check, "changed", _show_password_cb,
236 _dialog_new(E_Connman_Agent *agent)
238 Evas_Object *toolbook;
243 dialog = e_dialog_new(NULL, "E", "connman_request_input");
247 e_dialog_title_set(dialog, _("Input requested"));
248 e_dialog_border_icon_set(dialog, "dialog-ask");
250 e_dialog_button_add(dialog, _("Ok"), NULL, _dialog_ok_cb, agent);
251 e_dialog_button_add(dialog, _("Cancel"), NULL, _dialog_cancel_cb, agent);
252 agent->canceled = EINA_TRUE; /* if win is closed it works like cancel */
254 evas = evas_object_evas_get(dialog->win);
256 toolbook = e_widget_toolbook_add(evas, 48 * e_scale, 48 * e_scale);
257 evas_object_show(toolbook);
259 e_widget_size_min_get(toolbook, &mw, &mh);
265 e_dialog_content_set(dialog, toolbook, mw, mh);
266 e_dialog_show(dialog);
268 evas_object_event_callback_add(dialog->bg_object, EVAS_CALLBACK_KEY_DOWN,
269 _dialog_key_down_cb, agent);
271 e_object_del_attach_func_set(E_OBJECT(dialog), _dialog_del_cb);
272 e_object_data_set(E_OBJECT(dialog), agent);
274 e_dialog_button_focus_num(dialog, 0);
275 elm_win_center(dialog->win, 1, 1);
280 static Eldbus_Message *
281 _agent_release(const Eldbus_Service_Interface *iface,
282 const Eldbus_Message *msg)
284 E_Connman_Agent *agent;
285 Eldbus_Message *reply;
287 DBG("Agent released");
289 reply = eldbus_message_method_return_new(msg);
291 agent = eldbus_service_object_data_get(iface, AGENT_KEY);
292 EINA_SAFETY_ON_FALSE_RETURN_VAL(agent, reply);
295 e_object_del(E_OBJECT(agent->dialog));
300 static Eldbus_Message *
301 _agent_report_error(const Eldbus_Service_Interface *iface EINA_UNUSED,
302 const Eldbus_Message *msg EINA_UNUSED)
307 static Eldbus_Message *
308 _agent_request_browser(const Eldbus_Service_Interface *iface EINA_UNUSED,
309 const Eldbus_Message *msg EINA_UNUSED)
315 _parse_field_value(struct Connman_Field *field, const char *key,
316 Eldbus_Message_Iter *value, const char *signature)
318 if (!strcmp(key, "Type"))
320 EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 's', EINA_FALSE);
321 eldbus_message_iter_basic_get(value, &field->type);
325 if (!strcmp(key, "Requirement"))
327 EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 's', EINA_FALSE);
328 eldbus_message_iter_basic_get(value, &field->requirement);
332 if (!strcmp(key, "Alternates"))
334 EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 'a', EINA_FALSE);
335 /* ignore alternates */
339 if (!strcmp(key, "Value"))
341 EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 's', EINA_FALSE);
342 eldbus_message_iter_basic_get(value, &field->value);
346 DBG("Ignored unknown argument: %s", key);
351 _parse_field(struct Connman_Field *field, Eldbus_Message_Iter *value,
352 const char *signature EINA_UNUSED)
354 Eldbus_Message_Iter *array, *dict;
356 eldbus_message_iter_arguments_get(value, "a{sv}", &array);
357 EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE);
359 while (eldbus_message_iter_get_and_next(array, 'e', &dict))
361 Eldbus_Message_Iter *var;
365 if (!eldbus_message_iter_arguments_get(dict, "sv", &key, &var))
367 sig2 = eldbus_message_iter_signature_get(var);
371 if (!_parse_field_value(field, key, var, sig2))
382 static Eldbus_Message *
383 _agent_request_input(const Eldbus_Service_Interface *iface,
384 const Eldbus_Message *msg)
386 E_Connman_Module_Context *ctxt = connman_mod->data;
388 E_Connman_Instance *inst;
389 Eldbus_Message_Iter *array, *dict;
390 E_Connman_Agent *agent;
393 agent = eldbus_service_object_data_get(iface, AGENT_KEY);
395 /* Discard previous requests */
396 // if msg is the current agent msg? eek.
397 if (agent->msg == msg) return NULL;
400 eldbus_message_unref(agent->msg);
401 agent->msg = eldbus_message_ref((Eldbus_Message *)msg);
403 EINA_LIST_FOREACH(ctxt->instances, l, inst)
404 econnman_popup_del(inst);
407 e_object_del(E_OBJECT(agent->dialog));
408 agent->dialog = _dialog_new(agent);
409 EINA_SAFETY_ON_NULL_GOTO(agent->dialog, err);
411 if (!eldbus_message_arguments_get(msg, "oa{sv}", &path, &array))
414 while (eldbus_message_iter_get_and_next(array, 'e', &dict))
416 Eldbus_Message_Iter *var;
418 struct Connman_Field field = { NULL, NULL, NULL, NULL, NULL };
420 if (!eldbus_message_iter_arguments_get(dict, "sv", &field.name, &var))
422 signature = eldbus_message_iter_signature_get(var);
423 if (!signature) goto err;
425 if (!_parse_field(&field, var, signature))
432 DBG("AGENT Got field:\n"
435 "\tRequirement: %s\n"
436 "\tAlternates: (omit array)\n"
438 field.name, field.type, field.requirement, field.value);
440 _dialog_field_add(agent, &field);
446 eldbus_message_unref((Eldbus_Message *)msg);
448 WRN("Failed to parse msg");
449 return eldbus_message_method_return_new(msg);
452 static Eldbus_Message *
453 _agent_cancel(const Eldbus_Service_Interface *iface,
454 const Eldbus_Message *msg)
456 E_Connman_Agent *agent;
457 Eldbus_Message *reply = eldbus_message_method_return_new(msg);
459 DBG("Agent canceled");
461 agent = eldbus_service_object_data_get(iface, AGENT_KEY);
462 EINA_SAFETY_ON_FALSE_RETURN_VAL(agent, reply);
465 e_object_del(E_OBJECT(agent->dialog));
470 static const Eldbus_Method methods[] = {
471 { "Release", NULL, NULL, _agent_release, 0 },
473 "ReportError", ELDBUS_ARGS({"o", "service"}, {"s", "error"}), NULL,
474 _agent_report_error, 0
477 "RequestBrowser", ELDBUS_ARGS({"o", "service"}, {"s", "url"}), NULL,
478 _agent_request_browser, 0
481 "RequestInput", ELDBUS_ARGS({"o", "service"}, {"a{sv}", "fields"}),
482 ELDBUS_ARGS({"a{sv}", ""}), _agent_request_input, 0
484 { "Cancel", NULL, NULL, _agent_cancel, 0 },
485 { NULL, NULL, NULL, NULL, 0 }
488 static const Eldbus_Service_Interface_Desc desc = {
489 AGENT_IFACE, methods, NULL, NULL, NULL, NULL
493 econnman_agent_new(Eldbus_Connection *eldbus_conn)
495 Eldbus_Service_Interface *iface;
496 E_Connman_Agent *agent;
498 agent = E_NEW(E_Connman_Agent, 1);
499 EINA_SAFETY_ON_NULL_RETURN_VAL(agent, NULL);
501 iface = eldbus_service_interface_register(eldbus_conn, AGENT_PATH, &desc);
504 ERR("Failed to create eldbus interface");
508 eldbus_service_object_data_set(iface, AGENT_KEY, agent);
510 agent->iface = iface;
511 agent->conn = eldbus_conn;
517 econnman_agent_del(E_Connman_Agent *agent)
519 EINA_SAFETY_ON_NULL_RETURN(agent);
520 eldbus_service_object_unregister(agent->iface);