2 * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <service_app.h>
23 #include <app_manager.h>
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"
31 static rpc_port_proxy_AutofillSvcPort_h svc_rpc_h = NULL;
33 static int connect_service();
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;
43 static GList *__client_list = NULL;
45 static autofill_client_s *
46 get_autofill_client(const char *app_id, int context_id)
49 autofill_client_s *client;
55 iter = g_list_next(iter);
58 LOGW("Warning: value is NULL");
62 if ((client->context_id == context_id) &&
63 client->app_id && strcmp(client->app_id, app_id) == 0) {
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)
76 autofill_client_s *handle;
78 handle = calloc(1, sizeof(autofill_client_s));
80 LOGE("Out of memory");
84 handle->app_id = strdup(app_id);
85 if (!handle->app_id) {
86 LOGE("Out of memory");
91 handle->context_id = context_id;
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");
101 rpc_port_AutofillAppPort_autofill_fill_response_received_cb_clone(fill_response_received_cb, &handle->fill_response_received_cb);
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);
114 static void __destroy_client(gpointer data)
117 autofill_client_s *handle = data;
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;
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;
132 if (handle->app_id) {
133 free(handle->app_id);
134 handle->app_id = NULL;
140 static void __remove_client(rpc_port_stub_AutofillAppPort_context_h context)
142 autofill_client_s *client = NULL;
143 rpc_port_stub_AutofillAppPort_context_get_tag(context, (void *)&client);
147 rpc_port_stub_AutofillAppPort_context_set_tag(context, NULL);
149 LOGI("name(%s)", client->app_id);
151 __client_list = g_list_remove(__client_list, client);
152 __destroy_client(client);
155 static void __message_create(rpc_port_stub_AutofillAppPort_context_h context,
161 rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
165 LOGD("sender(%s)", sender);
169 static void __message_terminate(rpc_port_stub_AutofillAppPort_context_h context,
175 rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
179 LOGD("[__RPC_PORT__] sender(%s)", sender);
182 __remove_client(context);
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)
189 autofill_client_s *client = NULL;
191 rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
195 LOGD("sender(%s)", sender);
197 client = __create_client(sender, context_id, auth_info_cb, fill_response_received_cb);
203 __client_list = g_list_append(__client_list, client);
205 rpc_port_stub_AutofillAppPort_context_set_tag(context, client);
210 static void __message_unregister(rpc_port_stub_AutofillAppPort_context_h context, int context_id, void *user_data)
212 __remove_client(context);
215 static void __manager_create(rpc_port_stub_AutofillManagerPort_context_h context,
221 static void __manager_terminate(rpc_port_stub_AutofillManagerPort_context_h context,
227 bool __view_info_item_cb(rpc_port_autofill_item_h items, void *user_data)
235 rpc_port_autofill_svc_view_info_h svi = (rpc_port_autofill_svc_view_info_h)user_data;
237 rpc_port_autofill_svc_item_h svc_item = NULL;
239 if (rpc_port_autofill_svc_item_create(&svc_item) != 0) {
240 LOGW("Failed to create autofill item");
244 LOGD("item : %p", svc_item);
246 rpc_port_autofill_item_get_id(items, &id);
247 rpc_port_autofill_svc_item_set_id(svc_item, id);
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);
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);
267 rpc_port_autofill_item_get_autofill_hint(items, &autofill_hint);
268 rpc_port_autofill_svc_item_set_autofill_hint(svc_item, autofill_hint);
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);
273 if (rpc_port_autofill_svc_view_info_add_items(svi, svc_item) != 0) {
274 LOGW("Failed to add item");
277 rpc_port_autofill_svc_item_destroy(svc_item);
282 bool __save_item_cb(rpc_port_autofill_save_item_h items, void *user_data)
290 rpc_port_autofill_svc_save_view_info_h svi = (rpc_port_autofill_svc_save_view_info_h)user_data;
292 rpc_port_autofill_svc_save_item_h svc_save_item = NULL;
294 if (rpc_port_autofill_svc_save_item_create(&svc_save_item) != 0)
297 rpc_port_autofill_save_item_get_id(items, &id);
298 rpc_port_autofill_svc_save_item_set_id(svc_save_item, id);
303 rpc_port_autofill_save_item_get_label(items, &label);
304 rpc_port_autofill_svc_save_item_set_label(svc_save_item, label);
309 rpc_port_autofill_save_item_get_value(items, &value);
310 rpc_port_autofill_svc_save_item_set_value(svc_save_item, value);
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);
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);
321 rpc_port_autofill_svc_save_view_info_add_items(svi, svc_save_item);
323 rpc_port_autofill_svc_save_item_destroy(svc_save_item);
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)
333 LOGW("Not initialized");
337 rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
338 char *view_id = NULL;
340 rpc_port_autofill_view_info_get_view_id(vi, &view_id);
341 LOGD("app id : %s, view id : %s", sender, view_id);
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) {
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);
352 rpc_port_autofill_view_info_foreach_items(vi, __view_info_item_cb, svi);
354 rpc_port_proxy_AutofillSvcPort_invoke_request_auth_info(svc_rpc_h, context_id, svi);
356 rpc_port_autofill_svc_view_info_destroy(svi);
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)
373 char *view_id = NULL;
376 LOGW("Not initialized");
380 rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
381 rpc_port_autofill_view_info_get_view_id(vi, &view_id);
383 LOGD("app id : %s, view id : %s, context id : %d", sender, view_id, context_id);
385 rpc_port_autofill_svc_view_info_h svi = NULL;
386 if (rpc_port_autofill_svc_view_info_create(&svi) != 0) {
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);
393 rpc_port_autofill_view_info_foreach_items(vi, __view_info_item_cb, svi);
395 rpc_port_proxy_AutofillSvcPort_invoke_send_fill_request(svc_rpc_h, context_id, svi);
397 rpc_port_autofill_svc_view_info_destroy(svi);
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)
412 char *view_id = NULL;
415 LOGW("Not initialized");
419 rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
421 LOGD("sender(%s)", sender);
425 rpc_port_autofill_svc_save_view_info_h svi = NULL;
426 if (rpc_port_autofill_svc_save_view_info_create(&svi) != 0) {
430 rpc_port_autofill_save_view_info_get_view_id(vi, &view_id);
432 LOGD("view id : %s", view_id);
434 rpc_port_autofill_svc_save_view_info_set_view_id(svi, view_id);
436 rpc_port_autofill_save_view_info_foreach_items(vi, __save_item_cb, svi);
438 rpc_port_proxy_AutofillSvcPort_invoke_commit(svc_rpc_h, context_id, svi);
443 rpc_port_autofill_svc_save_view_info_destroy(svi);
448 bool fill_response_item_cb(rpc_port_autofill_svc_response_item_h response_items, void *user_data)
450 rpc_port_autofill_response_group_h res_group = (rpc_port_autofill_response_group_h)user_data;
453 char *presentation_text = NULL;
456 rpc_port_autofill_response_item_h res_item = NULL;
458 if (rpc_port_autofill_response_item_create(&res_item) != 0) {
462 rpc_port_autofill_svc_response_item_get_id(response_items, &id);
463 rpc_port_autofill_response_item_set_id(res_item, id);
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);
468 rpc_port_autofill_svc_response_item_get_value(response_items, &value);
469 rpc_port_autofill_response_item_set_value(res_item, value);
471 rpc_port_autofill_response_group_add_response_items(res_group, res_item);
476 if (presentation_text)
477 free(presentation_text);
482 rpc_port_autofill_response_item_destroy(res_item);
487 bool fill_response_group_cb(rpc_port_autofill_svc_response_group_h response_groups, void *user_data)
489 rpc_port_autofill_fill_response_h fr_h = (rpc_port_autofill_fill_response_h)user_data;
491 rpc_port_autofill_response_group_h res_group = NULL;
492 if (rpc_port_autofill_response_group_create(&res_group) != 0)
495 rpc_port_autofill_svc_response_group_foreach_response_items(response_groups, fill_response_item_cb, res_group);
497 rpc_port_autofill_fill_response_add_response_groups(fr_h, res_group);
499 rpc_port_autofill_response_group_destroy(res_group);
504 static void __fill_response_recv_cb(void *user_data, int context_id, rpc_port_autofill_svc_fill_response_h response_h)
506 // recv fill response from service
507 char *view_id = NULL;
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)
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);
518 rpc_port_autofill_fill_response_set_view_id(fill_response_h, view_id);
520 rpc_port_autofill_svc_fill_response_foreach_response_groups(response_h, fill_response_group_cb, fill_response_h);
522 autofill_client_s *sender_client = get_autofill_client(app_id, context_id);
524 rpc_port_AutofillAppPort_autofill_fill_response_received_cb_invoke(sender_client->fill_response_received_cb, fill_response_h);
526 rpc_port_autofill_fill_response_destroy(fill_response_h);
535 static void __auth_info_recv_cb(void *user_data, int context_id, rpc_port_autofill_svc_auth_info_h svc_auth_info_h)
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;
543 char *view_id = NULL;
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);
553 LOGD("app id : %s, service name : %s, message : %s, logo path : %s", app_id, service_name, service_message, service_logo_image_path);
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);
565 autofill_client_s *sender_client = get_autofill_client(app_id, context_id);
567 rpc_port_AutofillAppPort_autofill_auth_info_received_cb_invoke(sender_client->auth_info_cb, auth_info_h);
569 rpc_port_autofill_auth_info_destroy(auth_info_h);
580 if (service_logo_image_path)
581 free(service_logo_image_path);
584 free(service_message);
587 static void __on_connected(rpc_port_proxy_AutofillSvcPort_h h, void *user_data)
589 LOGI("[__RPC_PORT__] connected");
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);
594 int r = rpc_port_proxy_AutofillSvcPort_invoke_Register(h, auth_info_cb_h, fill_response_received_cb_h);
596 LOGD("Failed to invoke Register");
600 static void __on_disconnected(rpc_port_proxy_AutofillSvcPort_h h, void *user_data)
602 LOGD("disconnected");
607 static void __on_rejected(rpc_port_proxy_AutofillSvcPort_h h, void *user_data)
613 static bool __manager_set_autofill_service_cb(rpc_port_stub_AutofillManagerPort_context_h context, const char *app_id, void *user_data)
615 LOGD("app id : %s", app_id);
618 autofill_config_set_autofill_service_app_id(app_id);
621 LOGD("send terminate");
623 rpc_port_proxy_AutofillSvcPort_invoke_request_terminate(svc_rpc_h);
625 int ret = rpc_port_proxy_AutofillSvcPort_destroy(svc_rpc_h);
626 LOGD("ret : %d", ret);
636 static char * __manager_get_autofill_service_cb(rpc_port_stub_AutofillManagerPort_context_h context, void *user_data)
639 LOGW("Not initialized");
644 autofill_config_get_autofill_service_app_id(&app_id);
646 LOGD("app id : %s", app_id);
651 bool add_autofill_service_cb(app_info_h app_info, void *user_data)
654 rpc_port_list_string_h service_info_list = (rpc_port_list_string_h)user_data;
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);
662 LOGD("Find autofill service : %s", app_id);
664 rpc_port_list_string_add_list_strings(service_info_list, app_id);
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)
676 app_info_metadata_filter_h handle = NULL;
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);
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);
693 rpc_port_list_string_h app_id_list_h = NULL;
694 rpc_port_list_string_create(&app_id_list_h);
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);
701 *service_info_list = app_id_list_h;
703 app_info_metadata_filter_destroy(handle);
708 static int connect_service()
711 size_t service_id_len = 0;
713 rpc_port_proxy_AutofillSvcPort_callback_s rpc_callback = {
714 .connected = __on_connected,
715 .disconnected = __on_disconnected,
716 .rejected = __on_rejected
720 LOGI("already connected\n");
721 return RPC_PORT_ERROR_NONE;
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);
728 if (!active_autofill_service_id) {
729 active_autofill_service_id = strdup(AUTOFILL_SERVICE_APP_ID);
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);
736 if (service_id_len > 0) {
737 ret = rpc_port_proxy_AutofillSvcPort_create(active_autofill_service_id, &rpc_callback, NULL, &svc_rpc_h);
739 free(active_autofill_service_id);
741 if (service_id_len == 0) {
742 LOGD("No Autofill service to connect");
746 if (ret != RPC_PORT_ERROR_NONE) {
747 LOGW("Failed to create rpc port. err = %d", ret);
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);
761 bool service_app_create(void *data)
763 // Todo: add your code here.
768 rpc_port_stub_AutofillAppPort_callback_s callback = {
772 __message_unregister,
773 __auth_info_request_cb,
774 __autofill_fill_request_cb,
778 ret = rpc_port_stub_AutofillAppPort_register(&callback, NULL);
780 LOGI("Failed to register app port");
782 LOGI("Succeeded to register app port");
784 // register manager port
785 rpc_port_stub_AutofillManagerPort_callback_s manager_callback = {
788 __manager_set_autofill_service_cb,
789 __manager_get_autofill_service_cb,
790 __manager_get_autofill_service_list_cb,
793 ret = rpc_port_stub_AutofillManagerPort_register(&manager_callback, NULL);
795 LOGI("Failed to register manager port");
797 LOGI("Succeeded to register manager port");
804 void service_app_terminate(void *data)
806 // Todo: add your code here.
810 g_list_free_full(__client_list, __destroy_client);
811 __client_list = NULL;
814 rpc_port_stub_AutofillAppPort_unregister();
819 void service_app_control(app_control_h app_control, void *data)
821 // Todo: add your code here.
826 service_app_lang_changed(app_event_info_h event_info, void *user_data)
828 /*APP_EVENT_LANGUAGE_CHANGED*/
833 service_app_region_changed(app_event_info_h event_info, void *user_data)
835 /*APP_EVENT_REGION_FORMAT_CHANGED*/
839 service_app_low_battery(app_event_info_h event_info, void *user_data)
841 /*APP_EVENT_LOW_BATTERY*/
845 service_app_low_memory(app_event_info_h event_info, void *user_data)
847 /*APP_EVENT_LOW_MEMORY*/
851 * Entry point for this application.
853 int main(int argc, char *argv[])
858 service_app_lifecycle_callback_s event_callback;
859 app_event_handler_h handlers[5] = {NULL, };
861 event_callback.create = service_app_create;
862 event_callback.terminate = service_app_terminate;
863 event_callback.app_control = service_app_control;
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);
870 return service_app_main(argc, argv, &event_callback, ad);