Add code to delete all AR emoji stickers
[platform/core/uifw/capi-ui-sticker.git] / receiver / src / ft.cpp
1 /*
2  * Copyright (c) 2020 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 <glib.h>
19 #include <dlog.h>
20 #include <service_app.h>
21 #include <app_common.h>
22 #include <sap.h>
23 #include <sap_file_transfer.h>
24 #include <sticker_provider.h>
25 #include <string.h>
26 #include <string>
27 #include <unistd.h>
28 #include <linux/limits.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <pwd.h>
32 #include <json-glib/json-glib.h>
33 #include <vconf.h>
34 #include <queue>
35 #include <thumbnail_util.h>
36 #include <Ecore.h>
37 #include <app_preference.h>
38
39 #include "ft.h"
40 #include "log.h"
41 #include "sticker_info.h"
42 #include "../inc/sticker_data.h"
43 #include "sticker_request.h"
44 #include "message.h"
45 #include "config.h"
46 #include "receiver_preference.h"
47
48 #define STICKER_SYNC_FEATURE_REQ "sticker-sync-feature-req"
49 #define STICKER_SYNC_FEATURE_RSP "sticker-sync-feature-rsp"
50 #define STICKER_REQUEST_SYNC_REQ "sticker-request-sync-req"
51 #define STICKER_REQUEST_NOTI_REQ "sticker-request-noti-req"
52 #define STICKER_SYNC_START_REQ "sticker-sync-start-req"
53 #define STICKER_SYNC_START_RSP "sticker-sync-start-rsp"
54 #define STICKER_SEND_START_REQ "sticker-send-start-req"
55 #define STICKER_SEND_START_RSP "sticker-send-start-rsp"
56 #define STICKER_SEND_FACE_DATA "sticker-send-face-data"
57 #define STICKER_SEND_STOP_REQ  "sticker-send-stop-req"
58 #define STICKER_SEND_STOP_RSP  "sticker-send-stop-rsp"
59 #define STICKER_SEND_DISCONNECT_REQ "sticker-send-disconnect-req"
60
61 #ifndef VCONFKEY_STICKER_SYNC_COMPLETE_DONE
62 #define VCONFKEY_STICKER_SYNC_COMPLETE_DONE 0x1
63 #endif
64
65 using namespace std;
66
67 enum {
68     SYNC_START_RSP_SUCCESS = 1000,
69     SYNC_START_RSP_NO_STICKER = 1001,
70     SYNC_START_RSP_BITMOJI_ALL_DELETE = 1002,
71     SYNC_START_RSP_AREMOJI_ALL_DELETE = 1003
72 };
73
74 struct sap_info_s {
75     sap_agent_h agent;
76     sap_socket_h socket;
77     sap_peer_agent_h peer_agent;
78     sap_file_transaction_h file_socket;
79 };
80
81 static struct sap_info_s priv_data = { 0 };
82 static struct sticker_info sticker_data;
83 static queue<StickerRequest> ReqQueue;
84 static StickerRequest current_request;
85
86 static gboolean file_on_progress = FALSE;
87 static string incoming_file_name;
88 static int t_id = 0;
89 static int rec_file_cnt_in_group = 0;
90 static int total_file_count_in_group = 0;
91 static int sync_success_cnt = 0;
92 static gboolean job_progress = FALSE;
93 static int sync_complete_flags = 0;
94
95 static void save_last_sync_time()
96 {
97     // save last sync time in preference
98     double current_time = ecore_time_unix_get();
99     if (preference_set_double(LAST_SYNC_TIME, current_time) == PREFERENCE_ERROR_NONE) {
100         LOGI("Succeed to set last sync time : %f", current_time);
101     }
102     else {
103         LOGW("Failed to set last sync time");
104     }
105 }
106
107 static void set_sync_first_complete()
108 {
109     int complete_flags = 0;
110     if (vconf_get_int(VCONFKEY_STICKER_SYNC_COMPLETE, &complete_flags) == 0 && complete_flags == 0) {
111         // first sync
112         if (vconf_set_int(VCONFKEY_STICKER_SYNC_COMPLETE, VCONFKEY_STICKER_SYNC_COMPLETE_DONE) == 0)
113             LOGD("Succeed to set sync complete");
114         else
115             LOGW("Fail to set sync complete");
116     }
117 }
118
119 static void set_sync_complete()
120 {
121     set_sync_first_complete();
122     save_last_sync_time();
123 }
124
125 static void set_sync_progressing(gboolean flag)
126 {
127     job_progress = flag;
128 #ifdef VCONFKEY_STICKER_SYNC_STATE
129     LOGD("sync progressing : %d", flag);
130     if (vconf_set_int(VCONFKEY_STICKER_SYNC_STATE, flag ? VCONFKEY_STICKER_SYNC_STATE_IN_PROGRESS :  VCONFKEY_STICKER_SYNC_STATE_WAITING) == 0)
131         LOGD("Succeed to set sync state");
132     else
133         LOGW("Fail to set sync state");
134 #else
135     LOGW("No vconf sync state definition");
136 #endif
137 }
138
139 static gboolean _send_json_data(JsonObject *obj)
140 {
141     JsonGenerator *j_generator = NULL;
142     JsonNode *j_node = NULL;
143     gsize size = 0;
144     gchar *data = NULL;
145     int result = 1;
146
147     j_generator = json_generator_new();
148     if (j_generator == NULL) {
149         LOGE("Unable to json_generator_new");
150         goto cleanup;
151     }
152
153     j_node = json_node_new(JSON_NODE_OBJECT);
154     if (j_node == NULL) {
155         LOGE("Unable to json_node_new");
156         goto cleanup;
157     }
158
159     json_node_set_object(j_node, obj);
160     json_generator_set_root(j_generator, j_node);
161
162     data = json_generator_to_data(j_generator, &size);
163     if (data == NULL) {
164         LOGE("Unable to json_generator_to_data");
165         goto cleanup;
166     }
167
168     if (priv_data.socket) {
169         LOGD("Send JSON data : %s", data);
170         result = sap_socket_send_data(priv_data.socket, ACCESSORY_SERVICE_CHANNEL_ID, strlen(data), (void *)data);
171     }
172
173 cleanup:
174     if (data)
175         g_free(data);
176
177     if (j_node)
178         json_node_free(j_node);
179
180     if (j_generator)
181         g_object_unref(j_generator);
182
183     return result ? FALSE : TRUE;
184 }
185
186 static void notify_sync_progress(unsigned int file_progress)
187 {
188     if (total_file_count_in_group == 0)
189         return;
190
191     LOGI("(%2d / %2d), file progress : %3u%%", rec_file_cnt_in_group+1, total_file_count_in_group, file_progress);
192     send_message("sync_progress", NULL);
193 }
194
195 static void _on_transfer_completed(sap_file_transaction_h file_transaction,
196                                    sap_ft_transfer_e result,
197                                    const char *file_path,
198                                    void *user_data)
199 {
200     if (priv_data.file_socket) {
201         sap_file_transfer_destroy(file_transaction);
202         priv_data.file_socket = NULL;
203     }
204
205     if (result == SAP_FT_TRANSFER_SUCCESS) {
206         LOGI("Transfer Completed");
207
208         if (chmod(sticker_data.file_path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
209             LOGE("Failed to change permission : %s. error : %s", sticker_data.file_path.c_str(), strerror(errno));
210         }
211         else {
212             LOGI("Succeed to change permission : %s", sticker_data.file_path.c_str());
213             if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
214                 char thumb_path[PATH_MAX];
215                 char *data_path = NULL;
216                 data_path = app_get_shared_data_path();
217                 snprintf(thumb_path, sizeof(thumb_path), "%s/thumbnail/%s", data_path, incoming_file_name.c_str());
218                 sticker_data.thumbnail_path = string(thumb_path);
219
220                 if (data_path)
221                     free(data_path);
222
223                 int ret = thumbnail_util_extract_to_file(sticker_data.file_path.c_str(), THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, sticker_data.thumbnail_path.c_str());
224                 if (ret != THUMBNAIL_UTIL_ERROR_NONE) {
225                     LOGE("Failed to create thumbnail. msg : %s", get_error_message(ret));
226                     sticker_data.thumbnail_path.clear();
227                 }
228
229                 insert_sticker_data(sticker_data.file_path.c_str(), sticker_data.keyword.c_str(), sticker_data.group.c_str(), sticker_data.description.c_str(),
230                                     sticker_data.thumbnail_path.c_str(), sticker_data.disp_type.c_str());
231                 destroy_sticker_provider_handle();
232
233                 if (unlink(sticker_data.file_path.c_str()) == -1)
234                     LOGE("Failed to remove sticker file");
235
236                 if (!sticker_data.thumbnail_path.empty()) {
237                     if (unlink(sticker_data.thumbnail_path.c_str()) == -1)
238                         LOGE("Failed to remove sticker thumbnail");
239                 }
240             }
241         }
242
243         rec_file_cnt_in_group++;
244     } else {
245         switch (result) {
246             case (SAP_FT_TRANSFER_FAIL_CHANNEL_IO): {
247                 LOGW("Channel IO Error.");
248                 break;
249             }
250
251             case (SAP_FT_TRANSFER_FAIL_FILE_IO): {
252                 LOGW("File IO Error.");
253                 break;
254             }
255
256             case (SAP_FT_TRANSFER_FAIL_CMD_DROPPED):
257             {
258                 LOGW("Transfer dropped.");
259                 break;
260             }
261
262             case (SAP_FT_TRANSFER_FAIL_PEER_UNRESPONSIVE):
263             {
264                 LOGW("Peer Un Responsive.");
265                 break;
266             }
267
268             case (SAP_FT_TRANSFER_FAIL_PEER_CONN_LOST):
269             {
270                 LOGW("Connection Lost.");
271                 break;
272             }
273
274             case (SAP_FT_TRANSFER_FAIL_PEER_CANCELLED):
275             {
276                 LOGW("Peer Cancelled.");
277                 break;
278             }
279
280             case (SAP_FT_TRANSFER_FAIL_SPACE_NOT_AVAILABLE):
281             {
282                 LOGW("No Space.");
283                 break;
284             }
285
286             default:
287                 LOGW("Unknown Error");
288                 break;
289         }
290     }
291
292     file_on_progress = FALSE;
293     sticker_data.reset();
294 }
295
296 static void _on_transfer_file_in_progress(sap_file_transaction_h file_transaction,
297                                           unsigned short int percentage_progress,
298                                           void *user_data)
299 {
300     notify_sync_progress(percentage_progress);
301 }
302
303 static void __set_file_transfer_cb(sap_file_transaction_h file_socket)
304 {
305     LOGI("# set callbacks");
306     sap_file_transfer_set_progress_cb(file_socket, _on_transfer_file_in_progress, NULL);
307
308     sap_file_transfer_set_done_cb(file_socket, _on_transfer_completed, NULL);
309 }
310
311 bool get_job_progress()
312 {
313     return job_progress;
314 }
315
316 void accept_file()
317 {
318     int ret;
319     char file_path[PATH_MAX];
320     char *data_path = NULL;
321
322     data_path = app_get_shared_data_path();
323     LOGI("Path : %s", data_path);
324     snprintf(file_path, sizeof(file_path), "%s/%s", data_path, incoming_file_name.c_str());
325     LOGI("Receive filepath : %s", file_path);
326     sticker_data.file_path = string(file_path);
327
328     if (data_path)
329         free(data_path);
330
331     ret = sap_file_transfer_receive(priv_data.file_socket, file_path);
332     switch(ret) {
333         case SAP_RESULT_PERMISSION_DENIED:
334             LOGW("permission denied");
335             break;
336         case SAP_RESULT_FAILURE:
337             LOGW("Fail");
338             break;
339         case SAP_RESULT_SUCCESS:
340             LOGI("Success");
341             break;
342     }
343
344     file_on_progress = TRUE;
345 }
346
347 static int _create_thumbnail_directory()
348 {
349     char thumb_path[PATH_MAX];
350     char *data_path = NULL;
351     data_path = app_get_shared_data_path();
352     snprintf(thumb_path, sizeof(thumb_path), "%s/thumbnail", data_path);
353
354     if (data_path)
355         free(data_path);
356
357     if (access(thumb_path, F_OK) == 0)
358         return 0;
359
360     if (mkdir(thumb_path, 0755) == -1) {
361         LOGE("directory create error");
362         return -1;
363     }
364
365     return 0;
366 }
367
368 bool request_sticker_data(const char *mode, const char *category, const char *type)
369 {
370     bool result = false;
371     JsonObject *j_object = NULL;
372
373     if (!priv_data.socket) {
374         job_progress = TRUE;
375         StickerRequest pending_request;
376         pending_request.req_type = REQUEST_TYPE_SYNC;
377         pending_request.mode = string(mode ? mode : "manual");
378         pending_request.category = string(category ? category : "arsticker");
379         pending_request.type = string(type ? type : "input");
380
381         ReqQueue.push(pending_request);
382         LOGI("Push sync request");
383
384         return false;
385     }
386
387     j_object = json_object_new();
388     if (j_object == NULL) {
389         LOGE("json object create error");
390         return false;
391     }
392
393     if (_create_thumbnail_directory() != 0)
394         LOGE("Failed to create thumbnail directory");
395
396     json_object_set_string_member(j_object, "msgId", STICKER_SYNC_START_REQ);
397     json_object_set_int_member(j_object, "tID", ++t_id);
398     json_object_set_string_member(j_object, "mode", mode);
399     json_object_set_string_member(j_object, "category", category);
400     json_object_set_string_member(j_object, "type", type);
401
402     if (_send_json_data(j_object) == FALSE) {
403         LOGE("Failed to send STICKER_SYNC_START_REQ");
404         result = false;
405     }
406     else {
407         current_request.req_type = REQUEST_TYPE_SYNC;
408         current_request.mode = string(mode ? mode : "manual");
409         current_request.category = string(category ? category : "arsticker");
410         current_request.type = string(type ? type : "input");
411         set_sync_progressing(TRUE);
412         result = true;
413     }
414
415     json_object_unref(j_object);
416
417     return result;
418 }
419
420 static bool process_request_queue()
421 {
422     if (ReqQueue.empty())
423         return false;
424
425     StickerRequest request = ReqQueue.front();
426
427     if (request.req_type == REQUEST_TYPE_FEATURE_REQ) {
428         LOGD("[Request feature exchange]");
429         request_sticker_feature();
430         ReqQueue.pop();
431     }
432     else if (request.req_type == REQUEST_TYPE_SYNC) {
433         LOGD("[Request to sync sticker] mode: %s, category: %s, type : %s", request.mode.c_str(),
434                 request.category.c_str(),
435                 request.type.c_str());
436
437         if (request_sticker_data(request.mode.c_str(), request.category.c_str(), request.type.c_str()))
438             ReqQueue.pop();
439     }
440     else if (request.req_type == REQUEST_TYPE_SHOW_NOTIFICATION) {
441         LOGD("[Request to show notification]");
442         request_show_sync_notification();
443         ReqQueue.pop();
444     }
445
446     return true;
447 }
448
449 void request_all_sticker_data(const char *mode, const char *type)
450 {
451     StickerRequest pending_request;
452     pending_request.req_type = REQUEST_TYPE_SYNC;
453     pending_request.mode = string(mode);
454     pending_request.type = string(type);
455
456 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
457     int feature_flag = 0;
458     if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0)
459     {
460         if (feature_flag & VCONFKEY_STICKER_FEATURE_AREMOJI) {
461             pending_request.category = string("arsticker");
462             ReqQueue.push(pending_request);
463         }
464
465         if (feature_flag & VCONFKEY_STICKER_FEATURE_BITMOJI) {
466             pending_request.category = string("bitmoji");
467             ReqQueue.push(pending_request);
468         }
469     }
470     else
471         LOGW("Failed to get value of VCONFKEY_STICKER_SUPPORTED_FEATURE");
472 #else
473     pending_request.category = string("arsticker");
474     ReqQueue.push(pending_request);
475     pending_request.category = string("bitmoji");
476     ReqQueue.push(pending_request);
477 #endif
478
479     if (priv_data.socket)
480         process_request_queue();
481 }
482
483 void request_sticker_feature()
484 {
485     JsonObject *j_object = NULL;
486
487     if (!priv_data.socket) {
488         job_progress = TRUE;
489         StickerRequest pending_request;
490         pending_request.req_type = REQUEST_TYPE_FEATURE_REQ;
491         ReqQueue.push(pending_request);
492         LOGI("Push sync feature request");
493         return;
494     }
495
496     j_object = json_object_new();
497     if (j_object == NULL) {
498         LOGE("json object create error");
499         return;
500     }
501
502     json_object_set_string_member(j_object, "msgId", STICKER_SYNC_FEATURE_REQ);
503     json_object_set_int_member(j_object, "tID", ++t_id);
504
505     if (_send_json_data(j_object) == FALSE) {
506         LOGE("Failed to send STICKER_SYNC_FEATURE_REQ");
507     }
508     else {
509         job_progress = TRUE;
510     }
511
512     json_object_unref(j_object);
513
514     if (_create_thumbnail_directory() != 0)
515         LOGE("Failed to create thumbnail directory");
516 }
517
518 void send_disconnect_message()
519 {
520     JsonObject *j_object = NULL;
521     j_object = json_object_new();
522     if (j_object == NULL) {
523         LOGE("json object create error");
524         return;
525     }
526
527     json_object_set_string_member(j_object, "msgId", STICKER_SEND_DISCONNECT_REQ);
528     json_object_set_int_member(j_object, "tID", t_id);
529
530     if (_send_json_data(j_object) == FALSE) {
531         LOGE("Failed to send STICKER_SEND_DISCONNECT_REQ");
532     }
533
534     json_object_unref(j_object);
535 }
536
537 void request_show_sync_notification()
538 {
539     JsonObject *j_object = NULL;
540
541     if (!priv_data.socket) {
542         job_progress = TRUE;
543         StickerRequest pending_request;
544         pending_request.req_type = REQUEST_TYPE_SHOW_NOTIFICATION;
545         ReqQueue.push(pending_request);
546         LOGI("Push show notification request");
547         return;
548     }
549
550     j_object = json_object_new();
551     if (j_object == NULL) {
552         LOGE("json object create error");
553         return;
554     }
555
556     json_object_set_string_member(j_object, "msgId", STICKER_REQUEST_NOTI_REQ);
557     json_object_set_int_member(j_object, "tID", ++t_id);
558
559     if (_send_json_data(j_object) == FALSE) {
560         LOGE("Failed to send STICKER_REQUEST_NOTI_REQ");
561     } else {
562         job_progress = TRUE;
563     }
564
565     json_object_unref(j_object);
566 }
567
568 void reject_file()
569 {
570     int ret = sap_file_transfer_reject(priv_data.file_socket);
571     LOGI("ret : %d", ret);
572
573     file_on_progress = FALSE;
574 }
575
576 static void _on_transfer_file_cb(sap_peer_agent_h peer_agent_h,
577                                  sap_file_transaction_h socket,
578                                  const char *file_path,
579                                  void *user_data)
580 {
581     file_on_progress = TRUE;
582     priv_data.file_socket = socket;
583     LOGI("# incoming file request.");
584     __set_file_transfer_cb(priv_data.file_socket);
585
586     incoming_file_name = file_path;
587     std::size_t found = incoming_file_name.find_last_of("/");
588     incoming_file_name = incoming_file_name.substr(found+1);
589
590     LOGI("# file path : %s, incoming file name : %s", file_path, incoming_file_name.c_str());
591
592     accept_file();
593 }
594
595 void conn_terminated(sap_peer_agent_h peer_agent,
596                      sap_socket_h socket,
597                      sap_service_connection_terminated_reason_e result,
598                      void *user_data)
599 {
600     sap_info_s *priv = NULL;
601     priv = (sap_info_s *)user_data;
602
603     switch (result)
604     {
605     case SAP_CONNECTION_TERMINATED_REASON_PEER_DISCONNECTED:
606         LOGW("Peer Disconnected");
607         break;
608     case SAP_CONNECTION_TERMINATED_REASON_DEVICE_DETACHED:
609         LOGW("Disconnected Device Detached");
610         break;
611     case SAP_CONNECTION_TERMINATED_REASON_UNKNOWN:
612         LOGW("Disconnected Unknown Reason");
613         break;
614     default:
615         LOGW("connection terminated. reason : %d", result);
616         break;
617     }
618
619     sap_socket_destroy(priv->socket);
620     priv->socket = NULL;
621
622     set_sync_progressing(FALSE);
623     send_message("sync_stop_result", "cancel");
624     service_app_exit();
625 }
626
627 static void quit()
628 {
629     job_progress = FALSE;
630     send_disconnect_message();
631     service_app_exit();
632 }
633
634 static void send_sync_start_response(int result_code)
635 {
636     int feature_flag = 0;
637     string response_to_app;
638     switch (result_code) {
639         case SYNC_START_RSP_SUCCESS:
640         {
641             response_to_app = "success";
642             if (current_request.category == string("arsticker"))
643                 sync_complete_flags |= VCONFKEY_STICKER_FEATURE_AREMOJI;
644             else if (current_request.category == string("bitmoji"))
645                 sync_complete_flags |= VCONFKEY_STICKER_FEATURE_BITMOJI;
646         }
647         break;
648         case SYNC_START_RSP_NO_STICKER:
649             response_to_app = "no_sticker";
650             break;
651         case SYNC_START_RSP_BITMOJI_ALL_DELETE:
652         {
653             int is_synced = 0;
654             if (vconf_get_int(VCONFKEY_STICKER_SYNC_COMPLETE, &is_synced) != 0)
655                 LOGW("Failed to read sync completion");
656
657             if (is_synced == VCONFKEY_STICKER_SYNC_COMPLETE_NONE)
658                 response_to_app = "no_sticker";
659             else
660                 response_to_app = "success";
661             break;
662         }
663         case SYNC_START_RSP_AREMOJI_ALL_DELETE:
664             response_to_app = "success";
665             break;
666         default:
667             response_to_app = "unknown_error";
668             break;
669     }
670
671     LOGD("result code : %d, sync complete flag : %d", result_code, sync_complete_flags);
672
673 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
674     if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) != 0)
675     {
676         LOGW("Failed to read support feature");
677         return;
678     }
679
680     LOGD("feature : %d, current request category : %s", feature_flag, current_request.category.c_str());
681     if (feature_flag == VCONFKEY_STICKER_FEATURE_AREMOJI ||
682         feature_flag == VCONFKEY_STICKER_FEATURE_BITMOJI)
683     {
684         LOGD("only standalone sync mode");
685         send_message("sync_start_response", response_to_app.c_str());
686     }
687     else {
688         if (current_request.category == string("arsticker"))
689         {
690             if (result_code == SYNC_START_RSP_SUCCESS)
691                 send_message("sync_start_response", response_to_app.c_str());
692         }
693         else if (current_request.category == string("bitmoji"))
694         {
695             if (sync_complete_flags == 0 ||
696                 sync_complete_flags == VCONFKEY_STICKER_FEATURE_BITMOJI)
697                 send_message("sync_start_response", response_to_app.c_str());
698         }
699     }
700 #endif
701 }
702
703 void
704 on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned int payload_length, void *buffer,
705                  void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
706 {
707     unsigned int buf_len = strlen((char *)buffer);
708     LOGI("received data: %s, len: %d, buffer len : %d", (char *)buffer, payload_length, buf_len);
709
710     JsonParser *parser = json_parser_new();
711     GError *err_msg = NULL;
712     JsonNode *root = NULL;
713     JsonObject *root_obj = NULL;
714     string msg_id;
715     const char *json_msgid = NULL;
716
717     json_parser_load_from_data(parser, (char *)buffer, payload_length, &err_msg);
718     if (err_msg) {
719         LOGE("failed to load json file. error message: %s", err_msg->message);
720         goto cleanup;
721     }
722
723     root = json_parser_get_root(parser);
724     if (root == NULL) {
725         LOGE("failed to get root");
726         goto cleanup;
727     }
728
729     root_obj = json_node_get_object(root);
730     if (root_obj == NULL) {
731         LOGE("failed to get object");
732         goto cleanup;
733     }
734
735     json_msgid = json_object_get_string_member(root_obj, "msgId");
736     msg_id = string(json_msgid ? json_msgid : "");
737     if (msg_id == STICKER_REQUEST_SYNC_REQ) {
738         request_all_sticker_data("manual", "input");
739     } else if (msg_id == STICKER_SYNC_FEATURE_RSP) {
740         LOGD("msg : %s", msg_id.c_str());
741 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
742         const char *json_aremoji = json_object_get_string_member(root_obj, "arEmoji");
743         const char *json_bitmoji = json_object_get_string_member(root_obj, "bitmoji");
744         string support_aremoji = string(json_aremoji ? json_aremoji : "");
745         string support_bitmoji = string(json_bitmoji ? json_bitmoji : "");
746         int supported_feature = VCONFKEY_STICKER_FEATURE_NONE;
747
748         if (support_aremoji == "support")
749             supported_feature |= VCONFKEY_STICKER_FEATURE_AREMOJI;
750
751         if (support_bitmoji == "support")
752             supported_feature |= VCONFKEY_STICKER_FEATURE_BITMOJI;
753
754         if (vconf_set_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, supported_feature) == 0)
755             LOGD("Succeed to set supported feature");
756         else
757             LOGW("Fail to set supported feature");
758 #else
759         LOGW("No vconf supported feature");
760 #endif
761
762         if (!process_request_queue()) {
763             quit();
764         }
765     } else if (msg_id == STICKER_SYNC_START_RSP) {
766         LOGD("msg : %s", msg_id.c_str());
767         const char *json_result = json_object_get_string_member(root_obj, "result");
768         string result = string(json_result ? json_result : "");
769         int result_code = json_object_get_int_member(root_obj, "resultCode");
770         LOGD("result : %s, resultCode : %d", result.c_str(), result_code);
771
772         if(result_code == SYNC_START_RSP_SUCCESS) {
773             send_sync_start_response(result_code);
774             if (current_request.category == string("bitmoji")) {
775                 LOGD("Delete all bitmoji stickers");
776                 if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
777                     delete_all_stickers("bitmoji");
778                     destroy_sticker_provider_handle();
779                 }
780             }
781         } else {
782             if (result_code == SYNC_START_RSP_BITMOJI_ALL_DELETE) {
783                 LOGD("Delete all bitmoji stickers");
784                 if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
785                     delete_all_stickers("bitmoji");
786                     destroy_sticker_provider_handle();
787                 }
788             } else if (result_code == SYNC_START_RSP_AREMOJI_ALL_DELETE) {
789                 LOGD("Delete all AR Emoji stickers");
790                 if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
791                     delete_all_stickers("arsticker");
792                     destroy_sticker_provider_handle();
793                 }
794             }
795
796             if (!process_request_queue()) {
797 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
798                 int feature_flag = 0;
799
800                 if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0)
801                 {
802                     LOGD("feature : %d, current request category : %s", feature_flag, current_request.category.c_str());
803                     if (feature_flag & VCONFKEY_STICKER_FEATURE_BITMOJI)
804                     {
805                         if (current_request.category == string("bitmoji"))
806                         {
807                             /* other sticker group(s) has been synchronized completely */
808                             if (sync_success_cnt > 0) {
809                                 set_sync_complete();
810                             }
811                         }
812                     }
813                 }
814                 else {
815                     LOGW("Failed to read support feature");
816                 }
817 #else
818                 LOGW("No vconf supported feature");
819 #endif /* VCONFKEY_STICKER_SUPPORTED_FEATURE */
820
821                 send_sync_start_response(result_code);
822                 set_sync_progressing(FALSE);
823                 save_last_sync_time();
824
825                 quit();
826             }
827         }
828     } else if (msg_id == STICKER_SEND_START_REQ) {
829         LOGD("msg : %s", msg_id.c_str());
830         total_file_count_in_group = 0;
831         rec_file_cnt_in_group = 0;
832         t_id = json_object_get_int_member(root_obj, "tID");
833         JsonArray *file_list = json_object_get_array_member(root_obj, "list");
834         if (file_list) {
835             int arr_len = json_array_get_length(file_list);
836             for (int i = 0; i < arr_len; i++) {
837                 JsonObject *file_obj = json_array_get_object_element(file_list, i);
838                 int file_len = json_object_get_int_member(file_obj, "size");
839                 const char *json_filename = json_object_get_string_member(file_obj, "fileName");
840                 string file_name = string(json_filename ? json_filename : "");
841
842                 if (file_len > 0) {
843                     LOGD("Add file : %s, len : %d", file_name.c_str(), file_len);
844                     total_file_count_in_group++;
845                 } else {
846                     char *app_id = NULL;
847                     char file_path[PATH_MAX];
848                     char del_path[PATH_MAX];
849                     std::size_t found = file_name.find_last_of("/");
850                     string del_file_name = file_name.substr(found+1);
851                     char *data_path = app_get_shared_data_path();
852                     app_get_id(&app_id);
853                     snprintf(file_path, sizeof(file_path), "%s/%s", data_path, del_file_name.c_str());
854                     snprintf(del_path, sizeof(del_path), "%s/%s%s",STICKER_DIRECTORY, app_id, file_path);
855
856                     LOGD("Delete file : %s, len : %d", del_path, file_len);
857                     if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
858                         delete_sticker_data(del_path);
859                         destroy_sticker_provider_handle();
860                     }
861
862                     if (app_id)
863                         free(app_id);
864                 }
865             }
866         }
867
868         JsonObject *j_object = json_object_new();
869         if (j_object == NULL) {
870             LOGE("Unable to json_object_new");
871             goto cleanup;
872         }
873
874         json_object_set_string_member(j_object, "msgId", STICKER_SEND_START_RSP);
875         json_object_set_int_member(j_object, "tID", t_id);
876         json_object_set_string_member(j_object, "result", "success");
877
878         if (_send_json_data(j_object) == FALSE)
879             LOGE("Failed to send message");
880
881         json_object_unref(j_object);
882     } else if (msg_id == STICKER_SEND_FACE_DATA) {
883         LOGD("msg : %s", msg_id.c_str());
884         const char *type_data = json_object_get_string_member(root_obj, "type");
885         if (type_data)
886             sticker_data.disp_type = string(type_data);
887
888         const char *category = json_object_get_string_member(root_obj, "category");
889         if (category) {
890             sticker_data.group = string(category);
891             sticker_data.keyword = string(category);
892         }
893     } else if (msg_id == STICKER_SEND_STOP_REQ) {
894         LOGD("msg : %s", msg_id.c_str());
895         const char *json_reason = json_object_get_string_member(root_obj, "reason");
896         string reason = string(json_reason ? json_reason : "");
897         int file_len = json_object_get_int_member(root_obj, "count");
898
899         JsonObject *j_object = json_object_new();
900         if (j_object == NULL) {
901             LOGE("Unable to json_object_new");
902             goto cleanup;
903         }
904
905         json_object_set_string_member(j_object, "msgId", STICKER_SEND_STOP_RSP);
906         json_object_set_int_member(j_object, "tID", t_id);
907
908         if (reason == "complete") {
909             if (rec_file_cnt_in_group == file_len) {
910 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
911                 int feature_flag = 0;
912
913                 if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0)
914                 {
915                     LOGD("feature : %d, current request category : %s", feature_flag, current_request.category.c_str());
916                     if (feature_flag == VCONFKEY_STICKER_FEATURE_AREMOJI)
917                     {
918                         if (current_request.category == string("arsticker"))
919                         {
920                             set_sync_complete();
921                             set_sync_progressing(FALSE);
922                         }
923                     }
924                     else if (feature_flag & VCONFKEY_STICKER_FEATURE_BITMOJI)
925                     {
926                         if (current_request.category == string("bitmoji"))
927                         {
928                             set_sync_complete();
929                             set_sync_progressing(FALSE);
930                         }
931                     }
932                 }
933                 else {
934                     LOGW("Failed to read support feature");
935                 }
936 #else
937                 LOGW("No vconf supported feature");
938 #endif /* VCONFKEY_STICKER_SUPPORTED_FEATURE */
939
940                 json_object_set_string_member(j_object, "result", "success");
941                 sync_success_cnt++;
942             }
943             else {
944                 json_object_set_string_member(j_object, "result", "failure");
945             }
946         }
947         else {
948             json_object_set_string_member(j_object, "result", "failure");
949         }
950
951         if (_send_json_data(j_object) == FALSE)
952             LOGE("Failed to send message");
953
954         json_object_unref(j_object);
955
956         send_message("sync_stop_result", reason.c_str());
957
958         current_request.mode.clear();
959         current_request.category.clear();
960         current_request.type.clear();
961
962         if (!process_request_queue()) {
963             sync_success_cnt = 0;
964
965             quit();
966         }
967     } else
968         LOGW("unknown msg id : %s", msg_id.c_str());
969
970 cleanup:
971     if (err_msg)
972         g_error_free(err_msg);
973
974     if (parser)
975         g_object_unref(parser);
976 }
977
978 static void on_conn_req(sap_peer_agent_h peer_agent,
979                         sap_socket_h socket,
980                         sap_service_connection_result_e result,
981                         void *user_data)
982 {
983     switch (result)
984     {
985     case SAP_CONNECTION_SUCCESS:
986         LOGI("Connection success");
987         priv_data.socket = socket;
988         sap_peer_agent_accept_service_connection(peer_agent);
989         sap_peer_agent_set_service_connection_terminated_cb(peer_agent, conn_terminated, &priv_data);
990         sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
991         break;
992     case SAP_CONNECTION_ALREADY_EXIST:
993         priv_data.socket = socket;
994         LOGI("Connection Already Exist");
995         break;
996     case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
997         LOGW("Connection failure device unreachable");
998         break;
999     case SAP_CONNECTION_FAILURE_INVALID_PEERAGENT:
1000         LOGW("Connection failure invalid peer agent");
1001         break;
1002     case SAP_CONNECTION_FAILURE_NETWORK:
1003         LOGW("Connection failure network");
1004         break;
1005     case SAP_CONNECTION_FAILURE_PEERAGENT_NO_RESPONSE:
1006         LOGW("Connection failure peer agent no response");
1007         break;
1008     case SAP_CONNECTION_FAILURE_PEERAGENT_REJECTED:
1009         LOGW("Connection failure peer agent rejected");
1010         break;
1011     case SAP_CONNECTION_FAILURE_UNKNOWN:
1012         LOGW("Connection failure unknown");
1013         break;
1014     default:
1015         LOGW("Connection failure. error code : %d", result);
1016         break;
1017     }
1018 }
1019
1020 static void
1021 _on_service_connection_created(sap_peer_agent_h peer_agent,
1022                                sap_socket_h socket,
1023                                sap_service_connection_result_e result,
1024                                void *user_data)
1025 {
1026     sap_info_s *priv = (sap_info_s *)user_data;
1027
1028     switch (result)
1029     {
1030     case SAP_CONNECTION_SUCCESS:
1031         sap_peer_agent_set_service_connection_terminated_cb(priv->peer_agent,
1032                                                             conn_terminated,
1033                                                             priv);
1034
1035         sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
1036         priv->socket = socket;
1037         LOGI("Connection Established");
1038
1039         process_request_queue();
1040
1041         break;
1042
1043     case SAP_CONNECTION_ALREADY_EXIST:
1044         priv->socket = socket;
1045         LOGI("Connection Already Exist");
1046         break;
1047
1048     case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
1049         LOGW("Connection Failure device unreachable");
1050         break;
1051
1052     case SAP_CONNECTION_FAILURE_INVALID_PEERAGENT:
1053         LOGW("Connection Failure invalid peer agent");
1054         break;
1055
1056     case SAP_CONNECTION_FAILURE_NETWORK:
1057         LOGW("Connection Failure network");
1058         break;
1059
1060     case SAP_CONNECTION_FAILURE_PEERAGENT_NO_RESPONSE:
1061         LOGW("Connection Failure peer agent no response");
1062         break;
1063
1064     case SAP_CONNECTION_FAILURE_PEERAGENT_REJECTED:
1065         LOGW("Connection Failure peer agent rejected");
1066         break;
1067
1068     case SAP_CONNECTION_FAILURE_UNKNOWN:
1069         LOGW("Connection Failure peer agent unknown");
1070         break;
1071
1072     case SAP_CONNECTION_IN_PROGRESS:
1073         LOGW("Connection in progress");
1074         break;
1075
1076     case SAP_CONNECTION_PEER_AGENT_NOT_SUPPORTED:
1077         LOGW("Connection peer agent not supported");
1078         break;
1079     }
1080 }
1081
1082 static gboolean
1083 _create_service_connection(gpointer user_data)
1084 {
1085     sap_info_s *priv = (sap_info_s *)user_data;
1086     int result = sap_agent_request_service_connection(priv->agent,
1087                                                       priv->peer_agent,
1088                                                       _on_service_connection_created,
1089                                                       priv);
1090
1091     LOGD("request connection result : %d", result);
1092
1093     return FALSE;
1094 }
1095
1096 static void
1097 _on_peer_agent_updated(sap_peer_agent_h peer_agent,
1098                        sap_peer_agent_status_e peer_status,
1099                        sap_peer_agent_found_result_e result,
1100                        void *user_data)
1101 {
1102     sap_info_s *priv = (sap_info_s *)user_data;
1103
1104     switch (result)
1105     {
1106     case SAP_PEER_AGENT_FOUND_RESULT_DEVICE_NOT_CONNECTED:
1107         LOGW("SAP_PEER_AGENT_FOUND_RESULT_DEVICE_NOT_CONNECTED");
1108         break;
1109
1110     case SAP_PEER_AGENT_FOUND_RESULT_FOUND:
1111         if (peer_status == SAP_PEER_AGENT_STATUS_AVAILABLE)
1112         {
1113             LOGD("SAP_PEER_AGENT_FOUND_RESULT_FOUND");
1114             priv->peer_agent = peer_agent;
1115             g_idle_add(_create_service_connection, priv);
1116         }
1117         else
1118         {
1119             sap_peer_agent_destroy(peer_agent);
1120         }
1121         break;
1122
1123     case SAP_PEER_AGENT_FOUND_RESULT_SERVICE_NOT_FOUND:
1124         LOGW("SAP_PEER_AGENT_FOUND_RESULT_SERVICE_NOT_FOUND");
1125         break;
1126
1127     case SAP_PEER_AGENT_FOUND_RESULT_TIMEDOUT:
1128         LOGW("SAP_PEER_AGENT_FOUND_RESULT_TIMEDOUT");
1129         break;
1130
1131     case SAP_PEER_AGENT_FOUND_RESULT_INTERNAL_ERROR:
1132         LOGW("SAP_PEER_AGENT_FOUND_RESULT_INTERNAL_ERROR");
1133         break;
1134
1135     default:
1136         break;
1137     }
1138 }
1139
1140 static gboolean
1141 _find_peer_agent(gpointer user_data)
1142 {
1143     sap_info_s *priv = (sap_info_s *)user_data;
1144     sap_agent_find_peer_agent(priv->agent, _on_peer_agent_updated, priv);
1145
1146     return FALSE;
1147 }
1148
1149 static void on_agent_initialized(sap_agent_h agent,
1150                                  sap_agent_initialized_result_e result,
1151                                  void *user_data)
1152 {
1153     switch (result) {
1154         case SAP_AGENT_INITIALIZED_RESULT_SUCCESS:
1155             LOGD("agent is initialized");
1156
1157             priv_data.agent = agent;
1158
1159             sap_file_transfer_set_incoming_file_cb(agent, _on_transfer_file_cb, NULL);
1160             sap_agent_set_service_connection_requested_cb(agent, on_conn_req, NULL);
1161
1162             break;
1163         case SAP_AGENT_INITIALIZED_RESULT_DUPLICATED:
1164             LOGE("duplicate registration");
1165             break;
1166         case SAP_AGENT_INITIALIZED_RESULT_INVALID_ARGUMENTS:
1167             LOGE("invalid arguments");
1168             break;
1169         case SAP_AGENT_INITIALIZED_RESULT_INTERNAL_ERROR:
1170             LOGE("internal sap error");
1171             break;
1172         default:
1173             LOGE("unknown status (%d)", result);
1174             break;
1175     }
1176 }
1177
1178 static void on_agent_deinitialized(sap_agent_h agent,
1179                                    sap_agent_deinitialized_result_e result,
1180                                    void *user_data)
1181 {
1182     LOGD("result of deinitialize : %d", result);
1183 }
1184
1185 static void _on_device_status_changed(sap_device_status_e status,
1186                                       sap_transport_type_e transport_type,
1187                                       void *user_data)
1188 {
1189     LOGD("%s, status :%d", __func__, status);
1190
1191     switch (transport_type) {
1192         case SAP_TRANSPORT_TYPE_BT:
1193             LOGD("transport_type (%d): bt", transport_type);
1194             break;
1195         case SAP_TRANSPORT_TYPE_BLE:
1196             LOGD("transport_type (%d): ble", transport_type);
1197             break;
1198         case SAP_TRANSPORT_TYPE_TCP:
1199             LOGD("transport_type (%d): tcp/ip", transport_type);
1200             break;
1201         case SAP_TRANSPORT_TYPE_USB:
1202             LOGD("transport_type (%d): usb", transport_type);
1203             break;
1204         case SAP_TRANSPORT_TYPE_MOBILE:
1205             LOGD("transport_type (%d): mobile", transport_type);
1206             break;
1207         default:
1208             LOGE("unknown transport_type (%d)", transport_type);
1209             break;
1210     }
1211
1212     switch (status) {
1213         case SAP_DEVICE_STATUS_DETACHED:
1214             LOGD("device is not connected.");
1215             send_message("sync_stop_result", "cancel");
1216             break;
1217         case SAP_DEVICE_STATUS_ATTACHED:
1218             LOGD("Attached calling find peer now");
1219             g_idle_add(_find_peer_agent, &priv_data);
1220             break;
1221         default:
1222             LOGE("unknown status (%d)", status);
1223             break;
1224     }
1225 }
1226
1227 gboolean agent_initialize()
1228 {
1229     int result = 0;
1230
1231     do {
1232         result = sap_agent_initialize(priv_data.agent, ACCESSORY_SERVICE_PROFILE_ID, SAP_AGENT_ROLE_CONSUMER,
1233                 on_agent_initialized, NULL);
1234
1235         LOGD("SAP >>> getRegisteredServiceAgent() >>> %d", result);
1236     } while (result != SAP_RESULT_SUCCESS);
1237
1238     return TRUE;
1239 }
1240
1241 gboolean initialize_sap(void)
1242 {
1243     sap_agent_h agent = NULL;
1244
1245     if (priv_data.agent) {
1246         LOGW("duplicate initialize");
1247         return FALSE;
1248     }
1249
1250     sap_agent_create(&agent);
1251
1252     priv_data.agent = agent;
1253
1254     agent_initialize();
1255
1256     sap_set_device_status_changed_cb(_on_device_status_changed, NULL);
1257
1258     return TRUE;
1259 }
1260
1261 void deinitialize_sap(void)
1262 {
1263     LOGD("deinitialize");
1264     if (priv_data.agent) {
1265         int ret = sap_agent_deinitialize(priv_data.agent, on_agent_deinitialized, NULL);
1266         switch (ret) {
1267             case SAP_RESULT_FAILURE:
1268                 LOGW("Failed to deinitialize");
1269                 break;
1270             case SAP_RESULT_SUCCESS:
1271                 LOGD("Succeed to deinitialize");
1272                 break;
1273             case SAP_RESULT_PERMISSION_DENIED:
1274                 LOGW("permission denied: deinitialize ");
1275                 break;
1276             default:
1277                 LOGD("deinitialize : %d", ret);
1278                 break;
1279         }
1280
1281         sap_agent_destroy(priv_data.agent);
1282         priv_data.agent = NULL;
1283     }
1284 }
1285
1286 gboolean is_init_sap()
1287 {
1288     return priv_data.agent ? TRUE : FALSE;
1289 }