34c0be662f0db0c3f078bc54d87ff4862e1f8974
[platform/core/uifw/autofill.git] / client / autofill.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 <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <dlog.h>
21 #include <unistd.h>
22 #include <autofill.h>
23 #include <rpc-port.h>
24 #include "autofill_private.h"
25 #include "autofill_proxy.h"
26
27 #define AUTOFILL_DAEMON_APP_ID "org.tizen.autofill-daemon"
28
29 #ifdef LOG_TAG
30 #undef LOG_TAG
31 #endif
32 #define LOG_TAG "AUTOFILL"
33
34 rpc_port_proxy_AutofillAppPort_h rpc_h = NULL;
35
36 static autofill_connection_status_changed_cb connection_callback = NULL;
37 static void *connection_userdata = NULL;
38
39 extern Autofill_Fill_Response_Cb g_autofill_fill_response_cb;
40 extern void *g_autofill_fill_response_data;
41
42 extern Autofill_Auth_Info_Cb g_autofill_auth_info_cb;
43 extern void *g_autofill_auth_info_data;
44
45 static bool fill_response_item_cb(rpc_port_autofill_response_item_h response_items, void *user_data)
46 {
47     char *id = NULL;
48     char *presentation_text = NULL;
49     char *value = NULL;
50     autofill_fill_response_group_h res_group = (autofill_fill_response_group_h)user_data;
51
52     if (!res_group)
53         return true;
54
55     rpc_port_autofill_response_item_get_id(response_items, &id);
56     rpc_port_autofill_response_item_get_presentation_text(response_items, &presentation_text);
57     rpc_port_autofill_response_item_get_value(response_items, &value);
58
59     LOGD("id : %s, presentation text : %s, value : %s", id, presentation_text, value);
60
61     autofill_fill_response_item_h ritem;
62
63     autofill_fill_response_item_create(&ritem);
64     autofill_fill_response_item_set_id(ritem, id);
65     autofill_fill_response_item_set_presentation_text(ritem, presentation_text);
66     autofill_fill_response_item_set_value(ritem, value);
67
68     autofill_fill_response_group_add_item(res_group, ritem);
69
70     if (id)
71         free(id);
72
73     if (presentation_text)
74         free(presentation_text);
75
76     if (value)
77         free(value);
78
79     autofill_fill_response_item_destroy(ritem);
80
81     return true;
82 }
83
84 static bool fill_response_group_cb(rpc_port_autofill_response_group_h response_groups, void *user_data)
85 {
86     autofill_fill_response_h rh = (autofill_fill_response_h)user_data;
87     autofill_fill_response_group_h res_group;
88
89     LOGD("");
90
91     autofill_fill_response_group_create(&res_group);
92
93     rpc_port_autofill_response_group_foreach_response_items(response_groups, fill_response_item_cb, res_group);
94
95     autofill_fill_response_add_group(rh, res_group);
96
97     autofill_fill_response_group_destroy(res_group);
98
99     return true;
100 }
101
102 static void __fill_response_recv_cb(void *user_data, rpc_port_autofill_fill_response_h response_h)
103 {
104     char *view_id = NULL;
105     autofill_fill_response_h rh;
106
107     autofill_fill_response_create(&rh);
108
109     rpc_port_autofill_fill_response_get_view_id(response_h, &view_id);
110
111     autofill_fill_response_set_view_id(rh, view_id);
112
113     LOGD("view id : %s", view_id);
114     free(view_id);
115
116     rpc_port_autofill_fill_response_foreach_response_groups(response_h, fill_response_group_cb, rh);
117
118     if (g_autofill_fill_response_cb)
119         g_autofill_fill_response_cb(rh, g_autofill_fill_response_data);
120
121     autofill_fill_response_destroy(rh);
122 }
123
124 static void __auth_info_recv_cb(void *user_data, rpc_port_autofill_auth_info_h auth_info_h)
125 {
126     autofill_auth_info_h ah;
127     autofill_auth_info_create(&ah);
128
129     bool exist_autofill_data;
130     bool need_authentication;
131     char *view_id = NULL;
132     char *service_name = NULL;
133     char *service_logo_image_path = NULL;
134     char *service_message = NULL;
135
136     rpc_port_autofill_auth_info_get_view_id(auth_info_h, &view_id);
137     rpc_port_autofill_auth_info_get_exist_autofill_data(auth_info_h, &exist_autofill_data);
138     rpc_port_autofill_auth_info_get_need_authentication(auth_info_h, &need_authentication);
139     rpc_port_autofill_auth_info_get_service_name(auth_info_h, &service_name);
140     rpc_port_autofill_auth_info_get_service_logo_image_path(auth_info_h, &service_logo_image_path);
141     rpc_port_autofill_auth_info_get_service_message(auth_info_h, &service_message);
142
143     LOGD("service name : %s", service_name);
144
145     autofill_auth_info_set_view_id(ah, view_id);
146     autofill_auth_info_set_exist_autofill_data(ah, exist_autofill_data);
147     autofill_auth_info_set_need_authentication(ah, need_authentication);
148     autofill_auth_info_set_service_name(ah, service_name);
149     autofill_auth_info_set_service_logo_image_path(ah, service_logo_image_path);
150     autofill_auth_info_set_service_message(ah, service_message);
151
152     if (view_id)
153         free(view_id);
154
155     if (service_name)
156         free(service_name);
157
158     if (service_logo_image_path)
159         free(service_logo_image_path);
160
161     if (service_message)
162         free(service_message);
163
164     if (g_autofill_auth_info_cb)
165         g_autofill_auth_info_cb(ah, g_autofill_fill_response_data);
166
167     autofill_auth_info_destroy(ah);
168 }
169
170 static void __on_connected(rpc_port_proxy_AutofillAppPort_h h, void *user_data)
171 {
172     LOGI("[__RPC_PORT__] connected");
173     rpc_port_AutofillAppPort_autofill_fill_response_cb_h fill_response_cb = rpc_port_AutofillAppPort_autofill_fill_response_cb_create(__fill_response_recv_cb, false, NULL);
174     rpc_port_AutofillAppPort_autofill_auth_info_cb_h auth_info_cb = rpc_port_AutofillAppPort_autofill_auth_info_cb_create(__auth_info_recv_cb, false, NULL);
175
176     int r = rpc_port_proxy_AutofillAppPort_invoke_Register(h, auth_info_cb, fill_response_cb);
177     if (r != 0)
178         LOGD("Failed to invoke Register");
179
180     if (connection_callback)
181         connection_callback(AUTOFILL_CONNECTION_STATUS_CONNECTED, connection_userdata);
182 }
183
184 //LCOV_EXCL_START
185 static void __on_disconnected(rpc_port_proxy_AutofillAppPort_h h, void *user_data)
186 {
187     LOGD("disconnected");
188
189     if (connection_callback)
190         connection_callback(AUTOFILL_CONNECTION_STATUS_DISCONNECTED, connection_userdata);
191
192     rpc_h = NULL;
193 }
194
195 static void __on_rejected(rpc_port_proxy_AutofillAppPort_h h, void *user_data)
196 {
197     LOGD("rejected");
198
199     if (connection_callback)
200         connection_callback(AUTOFILL_CONNECTION_STATUS_REJECTED, connection_userdata);
201 }
202 //LCOV_EXCL_STOP
203
204 EXPORT_API int autofill_initialize()
205 {
206     LOGD("autofill initialize");
207
208     int ret;
209
210     if (rpc_h) {
211         LOGI("already initialized\n");
212         return AUTOFILL_ERROR_NONE;
213     }
214
215     rpc_port_proxy_AutofillAppPort_callback_s rpc_callback = {
216         .connected = __on_connected,
217         .disconnected = __on_disconnected,
218         .rejected = __on_rejected
219     };
220
221     ret = rpc_port_proxy_AutofillAppPort_create(AUTOFILL_DAEMON_APP_ID, &rpc_callback, NULL, &rpc_h);
222     if (ret != RPC_PORT_ERROR_NONE) {
223         LOGW("Failed to create rpc port. err = %d", ret);
224         return AUTOFILL_ERROR_OUT_OF_MEMORY;
225     }
226
227     return ret;
228 }
229
230 EXPORT_API int autofill_deinitialize()
231 {
232     LOGD("autofill deinitialize");
233
234     connection_callback = NULL;
235     g_autofill_fill_response_cb = NULL;
236     g_autofill_auth_info_cb = NULL;
237
238     return autofill_disconnect();
239 }
240
241 EXPORT_API int autofill_connect(autofill_connection_status_changed_cb callback, void *user_data)
242 {
243     LOGD("autofill connect");
244
245     int ret;
246
247     if (!callback) {
248         LOGW("parameter is NULL\n");
249         return AUTOFILL_ERROR_INVALID_PARAMETER;
250     }
251
252     if (!rpc_h) {
253         return AUTOFILL_ERROR_NOT_INITIALIZED;
254     }
255
256     connection_callback = callback;
257     connection_userdata = user_data;
258
259     ret = rpc_port_proxy_AutofillAppPort_connect(rpc_h);
260     switch (ret) {
261         case RPC_PORT_ERROR_NONE:
262             ret = AUTOFILL_ERROR_NONE;
263             break;
264         case RPC_PORT_ERROR_IO_ERROR:
265             break;
266         case RPC_PORT_ERROR_PERMISSION_DENIED:
267             ret = AUTOFILL_ERROR_PERMISSION_DENIED;
268             break;
269         default:
270             ret = AUTOFILL_ERROR_IO_ERROR;
271             break;
272     }
273
274     if (ret != AUTOFILL_ERROR_NONE) {
275         LOGW("Failed to connect rpc port. err = %d", ret);
276         return ret;
277     }
278
279     return ret;
280 }
281
282 EXPORT_API int autofill_disconnect()
283 {
284     LOGD("autofill disconnect");
285
286     if (rpc_h) {
287         rpc_port_proxy_AutofillAppPort_destroy(rpc_h);
288         rpc_h = NULL;
289     }
290     else
291         return AUTOFILL_ERROR_NOT_INITIALIZED;
292
293     return AUTOFILL_ERROR_NONE;
294 }
295
296 EXPORT_API int autofill_commit(autofill_save_view_info_h vi)
297 {
298     rpc_port_autofill_save_view_info_h vih;
299     char *id;
300     char *label;
301     char *value;
302     autofill_hint_e autofill_hint;
303     bool sensitive_data;
304
305     if (!vi) {
306         LOGW("parameter is NULL");
307         return AUTOFILL_ERROR_INVALID_PARAMETER;
308     }
309
310     if (!rpc_h) {
311         LOGW("not connected");
312         return AUTOFILL_ERROR_NOT_INITIALIZED;
313     }
314
315     rpc_port_autofill_save_view_info_create(&vih);
316     rpc_port_autofill_save_view_info_set_view_id(vih, vi->view_id);
317
318     Eina_List *l;
319     autofill_save_item_h it;
320     EINA_LIST_FOREACH(vi->autofill_save_item_list, l, it)
321     {
322         autofill_save_item_get_id(it, &id);
323         autofill_save_item_get_label(it, &label);
324         autofill_save_item_get_value(it, &value);
325         autofill_save_item_get_autofill_hint(it, &autofill_hint);
326         autofill_save_item_get_sensitive_data(it, &sensitive_data);
327
328         LOGD("it : %p, id : %s, label : %s, hint : %d, sensitive : %d", it, id, label, autofill_hint, sensitive_data);
329
330         rpc_port_autofill_save_item_h aih;
331         rpc_port_autofill_save_item_create(&aih);
332         rpc_port_autofill_save_item_set_id(aih, id);
333         rpc_port_autofill_save_item_set_label(aih, label);
334         rpc_port_autofill_save_item_set_value(aih, value);
335         rpc_port_autofill_save_item_set_autofill_hint(aih, (int)autofill_hint);
336         rpc_port_autofill_save_item_set_is_sensitive_data(aih, sensitive_data);
337         rpc_port_autofill_save_view_info_add_items(vih, aih);
338
339         if (id) {
340             free(id);
341             id = NULL;
342         }
343
344         if (label) {
345             free(label);
346             label = NULL;
347         }
348
349         if (value) {
350             free(value);
351             value = NULL;
352         }
353
354         rpc_port_autofill_save_item_destroy(aih);
355     }
356
357     LOGD("app id : %s, view id : %s", vi->app_id, vi->view_id);
358
359     int ret = rpc_port_proxy_AutofillAppPort_invoke_commit(rpc_h, vih);
360
361     rpc_port_autofill_save_view_info_destroy(vih);
362
363     return ret;
364 }