Add debug message temporarily
[platform/core/uifw/autofill-daemon.git] / src / autofill-daemon.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <tizen.h>
18 #include <stdlib.h>
19 #include <service_app.h>
20 #include <dlog.h>
21 #include <glib.h>
22 #include <rpc-port.h>
23 #include <app_manager.h>
24
25 #include "autofill_daemon_dlog.h"
26 #include "autofill_stub.h"
27 #include "autofill_service_proxy.h"
28 #include "autofill_manager_stub.h"
29 #include "autofill_config.h"
30
31 static rpc_port_proxy_AutofillSvcPort_h svc_rpc_h = NULL;
32
33 static int connect_service();
34
35 typedef struct {
36     char *app_id;
37     int context_id;
38
39     rpc_port_AutofillAppPort_autofill_auth_info_received_cb_h auth_info_cb;
40     rpc_port_AutofillAppPort_autofill_fill_response_received_cb_h fill_response_received_cb;
41 } autofill_client_s;
42
43 static GList *__client_list = NULL;
44
45 static autofill_client_s *
46 get_autofill_client(const char *app_id, int context_id)
47 {
48     GList *iter;
49     autofill_client_s *client;
50
51     iter = __client_list;
52     while (iter) {
53         client = iter->data;
54
55         iter = g_list_next(iter);
56
57         if (!client) {
58             LOGW("Warning: value is NULL");
59             continue;
60         }
61
62         if ((client->context_id == context_id) &&
63             client->app_id && strcmp(client->app_id, app_id) == 0) {
64             return client;
65         }
66     }
67
68     return NULL;
69 }
70
71 static autofill_client_s *__create_client(const char *app_id, int context_id,
72         rpc_port_AutofillAppPort_autofill_auth_info_received_cb_h auth_info_cb,
73         rpc_port_AutofillAppPort_autofill_fill_response_received_cb_h fill_response_received_cb)
74 {
75     LOGD("");
76     autofill_client_s *handle;
77
78     handle = calloc(1, sizeof(autofill_client_s));
79     if (!handle) {
80         LOGE("Out of memory");
81         return NULL;
82     }
83
84     handle->app_id = strdup(app_id);
85     if (!handle->app_id) {
86         LOGE("Out of memory");
87         free(handle);
88         return NULL;
89     }
90
91     handle->context_id = context_id;
92
93     rpc_port_AutofillAppPort_autofill_auth_info_received_cb_clone(auth_info_cb, &handle->auth_info_cb);
94     if (!handle->auth_info_cb) {
95         LOGE("Out of memory");
96         free(handle->app_id);
97         free(handle);
98         return NULL;
99     }
100
101     rpc_port_AutofillAppPort_autofill_fill_response_received_cb_clone(fill_response_received_cb, &handle->fill_response_received_cb);
102
103     if (!handle->fill_response_received_cb) {
104         LOGE("Out of memory");
105         free(handle->app_id);
106         rpc_port_AutofillAppPort_autofill_auth_info_received_cb_destroy(handle->auth_info_cb);
107         free(handle);
108         return NULL;
109     }
110
111     return handle;
112 }
113
114 static void __destroy_client(gpointer data)
115 {
116     LOGD("");
117     autofill_client_s *handle = data;
118
119     if (!handle)
120         return;
121
122     if (handle->auth_info_cb) {
123         rpc_port_AutofillAppPort_autofill_auth_info_received_cb_destroy(handle->auth_info_cb);
124         handle->auth_info_cb = NULL;
125     }
126
127     if (handle->fill_response_received_cb) {
128         rpc_port_AutofillAppPort_autofill_fill_response_received_cb_destroy(handle->fill_response_received_cb);
129         handle->fill_response_received_cb = NULL;
130     }
131
132     if (handle->app_id) {
133         free(handle->app_id);
134         handle->app_id = NULL;
135     }
136
137     free(handle);
138 }
139
140 static void __remove_client(rpc_port_stub_AutofillAppPort_context_h context)
141 {
142     autofill_client_s *client = NULL;
143     rpc_port_stub_AutofillAppPort_context_get_tag(context, (void *)&client);
144     if (!client)
145         return;
146
147     rpc_port_stub_AutofillAppPort_context_set_tag(context, NULL);
148
149     LOGI("name(%s)", client->app_id);
150
151     __client_list = g_list_remove(__client_list, client);
152     __destroy_client(client);
153 }
154
155 static void __message_create(rpc_port_stub_AutofillAppPort_context_h context,
156         void *user_data)
157 {
158     LOGD("");
159     char *sender = NULL;
160
161     rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
162     if (!sender)
163         return;
164
165     LOGD("sender(%s)", sender);
166     free(sender);
167 }
168
169 static void __message_terminate(rpc_port_stub_AutofillAppPort_context_h context,
170         void *user_data)
171 {
172     LOGD("");
173     char *sender = NULL;
174
175     rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
176     if (!sender)
177         return;
178
179     LOGD("[__RPC_PORT__] sender(%s)", sender);
180     free(sender);
181
182     __remove_client(context);
183 }
184
185 static int __message_register(rpc_port_stub_AutofillAppPort_context_h context, int context_id, rpc_port_AutofillAppPort_autofill_auth_info_received_cb_h auth_info_cb, rpc_port_AutofillAppPort_autofill_fill_response_received_cb_h fill_response_received_cb, void *user_data)
186 {
187     LOGD("");
188     char *sender = NULL;
189     autofill_client_s *client = NULL;
190
191     rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
192     if (!sender)
193         return -1;
194
195     LOGD("sender(%s)", sender);
196
197     client = __create_client(sender, context_id, auth_info_cb, fill_response_received_cb);
198     free(sender);
199
200     if (!client)
201         return -1;
202
203     __client_list = g_list_append(__client_list, client);
204
205     rpc_port_stub_AutofillAppPort_context_set_tag(context, client);
206
207     return 0;
208 }
209
210 static void __message_unregister(rpc_port_stub_AutofillAppPort_context_h context, int context_id, void *user_data)
211 {
212     __remove_client(context);
213 }
214
215 static void __manager_create(rpc_port_stub_AutofillManagerPort_context_h context,
216         void *user_data)
217 {
218     LOGD("");
219 }
220
221 static void __manager_terminate(rpc_port_stub_AutofillManagerPort_context_h context,
222         void *user_data)
223 {
224     LOGD("");
225 }
226
227 bool __view_info_item_cb(rpc_port_autofill_item_h items, void *user_data)
228 {
229     char *id = NULL;
230     char *label = NULL;
231     char *value = NULL;
232     int autofill_hint;
233     bool sensitive_data;
234
235     rpc_port_autofill_svc_view_info_h svi = (rpc_port_autofill_svc_view_info_h)user_data;
236
237     rpc_port_autofill_svc_item_h svc_item = NULL;
238
239     if (rpc_port_autofill_svc_item_create(&svc_item) != 0) {
240         LOGW("Failed to create autofill item");
241         return true;
242     }
243
244     LOGD("item : %p", svc_item);
245
246     rpc_port_autofill_item_get_id(items, &id);
247     rpc_port_autofill_svc_item_set_id(svc_item, id);
248     LOGD("id : %s", id);
249     if (id) {
250         free(id);
251     }
252
253     rpc_port_autofill_item_get_label(items, &label);
254     rpc_port_autofill_svc_item_set_label(svc_item, label);
255     LOGD("label : %s", label);
256     if (label) {
257         free(label);
258     }
259
260     rpc_port_autofill_item_get_value(items, &value);
261     rpc_port_autofill_svc_item_set_value(svc_item, value);
262     LOGD("value : %s", value);
263     if (value) {
264         free(value);
265     }
266
267     rpc_port_autofill_item_get_autofill_hint(items, &autofill_hint);
268     rpc_port_autofill_svc_item_set_autofill_hint(svc_item, autofill_hint);
269
270     rpc_port_autofill_item_get_is_sensitive_data(items, &sensitive_data);
271     rpc_port_autofill_svc_item_set_is_sensitive_data(svc_item, sensitive_data);
272
273     if (rpc_port_autofill_svc_view_info_add_items(svi, svc_item) != 0) {
274         LOGW("Failed to add item");
275     }
276
277     rpc_port_autofill_svc_item_destroy(svc_item);
278
279     return true;
280 }
281
282 bool __save_item_cb(rpc_port_autofill_save_item_h items, void *user_data)
283 {
284     char *id = NULL;
285     char *label = NULL;
286     char *value = NULL;
287     int autofill_hint;
288     bool sensitive_data;
289
290     rpc_port_autofill_svc_save_view_info_h svi = (rpc_port_autofill_svc_save_view_info_h)user_data;
291
292     rpc_port_autofill_svc_save_item_h svc_save_item = NULL;
293
294     if (rpc_port_autofill_svc_save_item_create(&svc_save_item) != 0)
295         return true;
296
297     rpc_port_autofill_save_item_get_id(items, &id);
298     rpc_port_autofill_svc_save_item_set_id(svc_save_item, id);
299     if (id) {
300         free(id);
301     }
302
303     rpc_port_autofill_save_item_get_label(items, &label);
304     rpc_port_autofill_svc_save_item_set_label(svc_save_item, label);
305     if (label) {
306         free(label);
307     }
308
309     rpc_port_autofill_save_item_get_value(items, &value);
310     rpc_port_autofill_svc_save_item_set_value(svc_save_item, value);
311     if (value) {
312         free(value);
313     }
314
315     rpc_port_autofill_save_item_get_autofill_hint(items, &autofill_hint);
316     rpc_port_autofill_svc_save_item_set_autofill_hint(svc_save_item, autofill_hint);
317
318     rpc_port_autofill_save_item_get_is_sensitive_data(items, &sensitive_data);
319     rpc_port_autofill_svc_save_item_set_is_sensitive_data(svc_save_item, sensitive_data);
320
321     rpc_port_autofill_svc_save_view_info_add_items(svi, svc_save_item);
322
323     rpc_port_autofill_svc_save_item_destroy(svc_save_item);
324
325     return true;
326 }
327
328 static int __auth_info_request_cb(rpc_port_stub_AutofillAppPort_context_h context, int context_id, rpc_port_autofill_view_info_h vi, void *user_data)
329 {
330     char *sender = NULL;
331
332     if (!svc_rpc_h) {
333         LOGW("Not initialized");
334         return 0;
335     }
336
337     rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
338     char *view_id = NULL;
339
340     rpc_port_autofill_view_info_get_view_id(vi, &view_id);
341     LOGD("app id : %s, view id : %s", sender, view_id);
342
343     /* create view info */
344     rpc_port_autofill_svc_view_info_h svi = NULL;
345     if (rpc_port_autofill_svc_view_info_create(&svi) != 0) {
346         goto end;
347     }
348
349     rpc_port_autofill_svc_view_info_set_app_id(svi, sender);
350     rpc_port_autofill_svc_view_info_set_view_id(svi, view_id);
351
352     rpc_port_autofill_view_info_foreach_items(vi, __view_info_item_cb, svi);
353
354     rpc_port_proxy_AutofillSvcPort_invoke_request_auth_info(svc_rpc_h, context_id, svi);
355
356     rpc_port_autofill_svc_view_info_destroy(svi);
357
358 end:
359     if (sender) {
360         free(sender);
361     }
362
363     if (view_id) {
364         free(view_id);
365     }
366
367     return 0;
368 }
369
370 static int __autofill_fill_request_cb(rpc_port_stub_AutofillAppPort_context_h context, int context_id, rpc_port_autofill_view_info_h vi, void *user_data)
371 {
372     char *sender = NULL;
373     char *view_id = NULL;
374
375     if (!svc_rpc_h) {
376         LOGW("Not initialized");
377         return 0;
378     }
379
380     rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
381     rpc_port_autofill_view_info_get_view_id(vi, &view_id);
382
383     LOGD("app id : %s, view id : %s, context id : %d", sender, view_id, context_id);
384
385     rpc_port_autofill_svc_view_info_h svi = NULL;
386     if (rpc_port_autofill_svc_view_info_create(&svi) != 0) {
387         goto end;
388     }
389
390     rpc_port_autofill_svc_view_info_set_app_id(svi, sender);
391     rpc_port_autofill_svc_view_info_set_view_id(svi, view_id);
392
393     rpc_port_autofill_view_info_foreach_items(vi, __view_info_item_cb, svi);
394
395     rpc_port_proxy_AutofillSvcPort_invoke_send_fill_request(svc_rpc_h, context_id, svi);
396
397     rpc_port_autofill_svc_view_info_destroy(svi);
398
399 end:
400     if (sender)
401         free(sender);
402
403     if (view_id)
404         free(view_id);
405
406     return 0;
407 }
408
409 static int __commit_cb(rpc_port_stub_AutofillAppPort_context_h context, int context_id, rpc_port_autofill_save_view_info_h vi, void *user_data)
410 {
411     char *sender = NULL;
412     char *view_id = NULL;
413
414     if (!svc_rpc_h) {
415         LOGW("Not initialized");
416         return 0;
417     }
418
419     rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
420     if (sender) {
421         LOGD("sender(%s)", sender);
422         free(sender);
423     }
424
425     rpc_port_autofill_svc_save_view_info_h svi = NULL;
426     if (rpc_port_autofill_svc_save_view_info_create(&svi) != 0) {
427         return 0;
428     }
429
430     rpc_port_autofill_save_view_info_get_view_id(vi, &view_id);
431     if (view_id) {
432         LOGD("view id : %s", view_id);
433     }
434     rpc_port_autofill_svc_save_view_info_set_view_id(svi, view_id);
435
436     rpc_port_autofill_save_view_info_foreach_items(vi, __save_item_cb, svi);
437
438     rpc_port_proxy_AutofillSvcPort_invoke_commit(svc_rpc_h, context_id, svi);
439
440     if (view_id)
441         free(view_id);
442
443     rpc_port_autofill_svc_save_view_info_destroy(svi);
444
445     return 0;
446 }
447
448 bool fill_response_item_cb(rpc_port_autofill_svc_response_item_h response_items, void *user_data)
449 {
450     rpc_port_autofill_response_group_h res_group = (rpc_port_autofill_response_group_h)user_data;
451
452     char *id = NULL;
453     char *presentation_text = NULL;
454     char *value = NULL;
455
456     rpc_port_autofill_response_item_h res_item = NULL;
457
458     if (rpc_port_autofill_response_item_create(&res_item) != 0) {
459         return true;
460     }
461
462     rpc_port_autofill_svc_response_item_get_id(response_items, &id);
463     rpc_port_autofill_response_item_set_id(res_item, id);
464
465     rpc_port_autofill_svc_response_item_get_presentation_text(response_items, &presentation_text);
466     rpc_port_autofill_response_item_set_presentation_text(res_item, presentation_text);
467
468     rpc_port_autofill_svc_response_item_get_value(response_items, &value);
469     rpc_port_autofill_response_item_set_value(res_item, value);
470
471     rpc_port_autofill_response_group_add_response_items(res_group, res_item);
472
473     if (id)
474         free(id);
475
476     if (presentation_text)
477         free(presentation_text);
478
479     if (value)
480         free(value);
481
482     rpc_port_autofill_response_item_destroy(res_item);
483
484     return true;
485 }
486
487 bool fill_response_group_cb(rpc_port_autofill_svc_response_group_h response_groups, void *user_data)
488 {
489     rpc_port_autofill_fill_response_h fr_h = (rpc_port_autofill_fill_response_h)user_data;
490
491     rpc_port_autofill_response_group_h res_group = NULL;
492     if (rpc_port_autofill_response_group_create(&res_group) != 0)
493         return true;
494
495     rpc_port_autofill_svc_response_group_foreach_response_items(response_groups, fill_response_item_cb, res_group);
496
497     rpc_port_autofill_fill_response_add_response_groups(fr_h, res_group);
498
499     rpc_port_autofill_response_group_destroy(res_group);
500
501     return true;
502 }
503
504 static void __fill_response_recv_cb(void *user_data, int context_id, rpc_port_autofill_svc_fill_response_h response_h)
505 {
506     // recv fill response from service
507     char *view_id = NULL;
508     char *app_id = NULL;
509
510     /* create autofill response */
511     rpc_port_autofill_fill_response_h fill_response_h = NULL;
512     if (rpc_port_autofill_fill_response_create(&fill_response_h) != 0)
513         return;
514
515     rpc_port_autofill_svc_fill_response_get_app_id(response_h, &app_id);
516     rpc_port_autofill_svc_fill_response_get_view_id(response_h, &view_id);
517
518     rpc_port_autofill_fill_response_set_view_id(fill_response_h, view_id);
519
520     rpc_port_autofill_svc_fill_response_foreach_response_groups(response_h, fill_response_group_cb, fill_response_h);
521
522     autofill_client_s *sender_client = get_autofill_client(app_id, context_id);
523     if (sender_client)
524         rpc_port_AutofillAppPort_autofill_fill_response_received_cb_invoke(sender_client->fill_response_received_cb, fill_response_h);
525
526     rpc_port_autofill_fill_response_destroy(fill_response_h);
527
528     if (app_id)
529         free(app_id);
530
531     if (view_id)
532         free(view_id);
533 }
534
535 static void __auth_info_recv_cb(void *user_data, int context_id, rpc_port_autofill_svc_auth_info_h svc_auth_info_h)
536 {
537     bool exist_autofill_data = false;
538     bool need_authentication = false;
539     char *service_name = NULL;
540     char *service_logo_image_path = NULL;
541     char *service_message = NULL;
542     char *app_id = NULL;
543     char *view_id = NULL;
544
545     rpc_port_autofill_svc_auth_info_get_app_id(svc_auth_info_h, &app_id);
546     rpc_port_autofill_svc_auth_info_get_view_id(svc_auth_info_h, &view_id);
547     rpc_port_autofill_svc_auth_info_get_exist_autofill_data(svc_auth_info_h, &exist_autofill_data);
548     rpc_port_autofill_svc_auth_info_get_need_authentication(svc_auth_info_h, &need_authentication);
549     rpc_port_autofill_svc_auth_info_get_service_name(svc_auth_info_h, &service_name);
550     rpc_port_autofill_svc_auth_info_get_service_logo_image_path(svc_auth_info_h, &service_logo_image_path);
551     rpc_port_autofill_svc_auth_info_get_service_message(svc_auth_info_h, &service_message);
552
553     LOGD("app id : %s, service name : %s, message : %s, logo path : %s", app_id, service_name, service_message, service_logo_image_path);
554
555     /* transfer auth info */
556     rpc_port_autofill_auth_info_h auth_info_h = NULL;
557     rpc_port_autofill_auth_info_create(&auth_info_h);
558     rpc_port_autofill_auth_info_set_view_id(auth_info_h, view_id);
559     rpc_port_autofill_auth_info_set_exist_autofill_data(auth_info_h, exist_autofill_data);
560     rpc_port_autofill_auth_info_set_need_authentication(auth_info_h, need_authentication);
561     rpc_port_autofill_auth_info_set_service_name(auth_info_h, service_name);
562     rpc_port_autofill_auth_info_set_service_message(auth_info_h, service_message);
563     rpc_port_autofill_auth_info_set_service_logo_image_path(auth_info_h, service_logo_image_path);
564
565     autofill_client_s *sender_client = get_autofill_client(app_id, context_id);
566     if (sender_client)
567         rpc_port_AutofillAppPort_autofill_auth_info_received_cb_invoke(sender_client->auth_info_cb, auth_info_h);
568
569     rpc_port_autofill_auth_info_destroy(auth_info_h);
570
571     if (app_id)
572         free(app_id);
573
574     if (view_id)
575         free(view_id);
576
577     if (service_name)
578         free(service_name);
579
580     if (service_logo_image_path)
581         free(service_logo_image_path);
582
583     if (service_message)
584         free(service_message);
585 }
586
587 static void __on_connected(rpc_port_proxy_AutofillSvcPort_h h, void *user_data)
588 {
589     LOGI("[__RPC_PORT__] connected");
590
591     rpc_port_AutofillSvcPort_autofill_svc_fill_response_cb_h fill_response_received_cb_h = rpc_port_AutofillSvcPort_autofill_svc_fill_response_cb_create(__fill_response_recv_cb, false, NULL);
592     rpc_port_AutofillSvcPort_autofill_svc_auth_info_cb_h auth_info_cb_h = rpc_port_AutofillSvcPort_autofill_svc_auth_info_cb_create(__auth_info_recv_cb, false, NULL);
593
594     int r = rpc_port_proxy_AutofillSvcPort_invoke_Register(h, auth_info_cb_h, fill_response_received_cb_h);
595     if (r != 0)
596         LOGD("Failed to invoke Register");
597 }
598
599 //LCOV_EXCL_START
600 static void __on_disconnected(rpc_port_proxy_AutofillSvcPort_h h, void *user_data)
601 {
602     LOGD("disconnected");
603
604     svc_rpc_h = NULL;
605 }
606
607 static void __on_rejected(rpc_port_proxy_AutofillSvcPort_h h, void *user_data)
608 {
609     LOGD("rejected");
610 }
611 //LCOV_EXCL_STOP
612
613 static bool __manager_set_autofill_service_cb(rpc_port_stub_AutofillManagerPort_context_h context, const char *app_id, void *user_data)
614 {
615     LOGD("app id : %s", app_id);
616
617     if (app_id)
618         autofill_config_set_autofill_service_app_id(app_id);
619
620     if (svc_rpc_h) {
621         LOGD("send terminate");
622         // terminate service
623         rpc_port_proxy_AutofillSvcPort_invoke_request_terminate(svc_rpc_h);
624
625         int ret = rpc_port_proxy_AutofillSvcPort_destroy(svc_rpc_h);
626         LOGD("ret : %d", ret);
627     }
628
629     svc_rpc_h = NULL;
630
631     connect_service();
632
633     return true;
634 }
635
636 static char * __manager_get_autofill_service_cb(rpc_port_stub_AutofillManagerPort_context_h context, void *user_data)
637 {
638     if (!svc_rpc_h) {
639         LOGW("Not initialized");
640         return false;
641     }
642
643     char *app_id = NULL;
644     autofill_config_get_autofill_service_app_id(&app_id);
645
646     LOGD("app id : %s", app_id);
647
648     return app_id;
649 }
650
651 bool add_autofill_service_cb(app_info_h app_info, void *user_data)
652 {
653     char *app_id = NULL;
654     rpc_port_list_string_h service_info_list = (rpc_port_list_string_h)user_data;
655
656     int ret = app_info_get_app_id(app_info, &app_id);
657     if (ret != APP_MANAGER_ERROR_NONE) {
658         LOGW("app_info_get_app_id failed (%d)", ret);
659         return true;
660     }
661
662     LOGD("Find autofill service : %s", app_id);
663
664     rpc_port_list_string_add_list_strings(service_info_list, app_id);
665
666     if (app_id) {
667         free(app_id);
668     }
669
670     return true;
671 }
672
673 static bool __manager_get_autofill_service_list_cb(rpc_port_stub_AutofillManagerPort_context_h context, rpc_port_list_string_h *service_info_list, void *user_data)
674 {
675     int ret;
676     app_info_metadata_filter_h handle = NULL;
677
678     // Get the Autofill service list
679     ret = app_info_metadata_filter_create(&handle);
680     if (ret != APP_MANAGER_ERROR_NONE) {
681         LOGW("app_info_metadata_filter_create failed (%d)", ret);
682         app_info_metadata_filter_destroy(handle);
683         return false;
684     }
685
686     ret = app_info_metadata_filter_add(handle, "autofill-service", "true");
687     if (ret != APP_MANAGER_ERROR_NONE) {
688         LOGW("app_info_metadata_filter_add failed (%d)", ret);
689         app_info_metadata_filter_destroy(handle);
690         return false;
691     }
692
693     rpc_port_list_string_h app_id_list_h = NULL;
694     rpc_port_list_string_create(&app_id_list_h);
695
696     ret = app_info_metadata_filter_foreach(handle, add_autofill_service_cb, app_id_list_h);
697     if (ret != APP_MANAGER_ERROR_NONE) {
698         LOGW("app_info_metadata_filter_foreach failed (%d)", ret);
699     }
700
701     *service_info_list = app_id_list_h;
702
703     app_info_metadata_filter_destroy(handle);
704
705     return true;
706 }
707
708 static int connect_service()
709 {
710     int ret;
711     size_t service_id_len = 0;
712
713     rpc_port_proxy_AutofillSvcPort_callback_s rpc_callback = {
714         .connected = __on_connected,
715         .disconnected = __on_disconnected,
716         .rejected = __on_rejected
717     };
718
719     if (svc_rpc_h) {
720         LOGI("already connected\n");
721         return RPC_PORT_ERROR_NONE;
722     }
723
724     char *active_autofill_service_id = NULL;
725     autofill_config_get_autofill_service_app_id(&active_autofill_service_id);
726     LOGD("autofill service : '%s'", active_autofill_service_id);
727
728     if (!active_autofill_service_id) {
729         active_autofill_service_id = strdup(AUTOFILL_SERVICE_APP_ID);
730     }
731
732     if (active_autofill_service_id) {
733         autofill_config_set_autofill_service_app_id(active_autofill_service_id);
734         service_id_len = strlen(active_autofill_service_id);
735
736         if (service_id_len > 0) {
737             ret = rpc_port_proxy_AutofillSvcPort_create(active_autofill_service_id, &rpc_callback, NULL, &svc_rpc_h);
738         }
739         free(active_autofill_service_id);
740
741         if (service_id_len == 0) {
742             LOGD("No Autofill service to connect");
743             return false;
744         }
745
746         if (ret != RPC_PORT_ERROR_NONE) {
747             LOGW("Failed to create rpc port. err = %d", ret);
748             return false;
749         }
750     }
751
752     ret = rpc_port_proxy_AutofillSvcPort_connect(svc_rpc_h);
753     if (ret != RPC_PORT_ERROR_NONE) {
754         LOGW("Failed to connect. err = %d", ret);
755         return false;
756     }
757
758     return ret;
759 }
760
761 bool service_app_create(void *data)
762 {
763     // Todo: add your code here.
764     LOGD("");
765
766     int ret;
767     // register app port
768     rpc_port_stub_AutofillAppPort_callback_s callback = {
769         __message_create,
770         __message_terminate,
771         __message_register,
772         __message_unregister,
773         __auth_info_request_cb,
774         __autofill_fill_request_cb,
775         __commit_cb,
776     };
777
778     ret = rpc_port_stub_AutofillAppPort_register(&callback, NULL);
779     if (ret != 0)
780         LOGI("Failed to register app port");
781     else
782         LOGI("Succeeded to register app port");
783
784     // register manager port
785     rpc_port_stub_AutofillManagerPort_callback_s manager_callback = {
786         __manager_create,
787         __manager_terminate,
788         __manager_set_autofill_service_cb,
789         __manager_get_autofill_service_cb,
790         __manager_get_autofill_service_list_cb,
791     };
792
793     ret = rpc_port_stub_AutofillManagerPort_register(&manager_callback, NULL);
794     if (ret != 0)
795         LOGI("Failed to register manager port");
796     else
797         LOGI("Succeeded to register manager port");
798
799     connect_service();
800
801     return true;
802 }
803
804 void service_app_terminate(void *data)
805 {
806     // Todo: add your code here.
807     LOGD("");
808
809     if (__client_list) {
810         g_list_free_full(__client_list, __destroy_client);
811         __client_list = NULL;
812     }
813
814     rpc_port_stub_AutofillAppPort_unregister();
815
816     return;
817 }
818
819 void service_app_control(app_control_h app_control, void *data)
820 {
821     // Todo: add your code here.
822     return;
823 }
824
825 static void
826 service_app_lang_changed(app_event_info_h event_info, void *user_data)
827 {
828     /*APP_EVENT_LANGUAGE_CHANGED*/
829     return;
830 }
831
832 static void
833 service_app_region_changed(app_event_info_h event_info, void *user_data)
834 {
835     /*APP_EVENT_REGION_FORMAT_CHANGED*/
836 }
837
838 static void
839 service_app_low_battery(app_event_info_h event_info, void *user_data)
840 {
841     /*APP_EVENT_LOW_BATTERY*/
842 }
843
844 static void
845 service_app_low_memory(app_event_info_h event_info, void *user_data)
846 {
847     /*APP_EVENT_LOW_MEMORY*/
848 }
849
850 /**
851  * Entry point for this application.
852  */
853 int main(int argc, char *argv[])
854 {
855     LOGI("BEGIN");
856
857     char ad[50] = {0,};
858     service_app_lifecycle_callback_s event_callback;
859     app_event_handler_h handlers[5] = {NULL, };
860
861     event_callback.create = service_app_create;
862     event_callback.terminate = service_app_terminate;
863     event_callback.app_control = service_app_control;
864
865     service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad);
866     service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad);
867     service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad);
868     service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad);
869
870     return service_app_main(argc, argv, &event_callback, ad);
871 }