#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
+#include <json-glib/json-glib.h>
+#include <vconf.h>
+#include <queue>
+#include <thumbnail_util.h>
+#include <Ecore.h>
+#include <app_preference.h>
+#include "ft.h"
#include "log.h"
#include "sticker_info.h"
+#include "../inc/sticker_data.h"
+#include "sticker_request.h"
+#include "message.h"
+#include "config.h"
+#include "receiver_preference.h"
-#define ACCESSORY_SERVICE_PROFILE_ID "/sample/filetransfersender"
+#define STICKER_SYNC_FEATURE_REQ "sticker-sync-feature-req"
+#define STICKER_SYNC_FEATURE_RSP "sticker-sync-feature-rsp"
+#define STICKER_REQUEST_SYNC_REQ "sticker-request-sync-req"
+#define STICKER_REQUEST_NOTI_REQ "sticker-request-noti-req"
+#define STICKER_SYNC_START_REQ "sticker-sync-start-req"
+#define STICKER_SYNC_START_RSP "sticker-sync-start-rsp"
+#define STICKER_SEND_START_REQ "sticker-send-start-req"
+#define STICKER_SEND_START_RSP "sticker-send-start-rsp"
+#define STICKER_SEND_FACE_DATA "sticker-send-face-data"
+#define STICKER_SEND_STOP_REQ "sticker-send-stop-req"
+#define STICKER_SEND_STOP_RSP "sticker-send-stop-rsp"
+#define STICKER_SEND_DISCONNECT_REQ "sticker-send-disconnect-req"
+
+#ifndef VCONFKEY_STICKER_SYNC_COMPLETE_DONE
+#define VCONFKEY_STICKER_SYNC_COMPLETE_DONE 0x1
+#endif
using namespace std;
-struct priv {
+enum {
+ SYNC_START_RSP_SUCCESS = 1000,
+ SYNC_START_RSP_NO_STICKER = 1001,
+ SYNC_START_RSP_BITMOJI_ALL_DELETE = 1002,
+ SYNC_START_RSP_AREMOJI_ALL_DELETE = 1003,
+ SYNC_START_RSP_SYNC_AFTER_DELETING_AREMOJI = 1004
+};
+
+struct sap_info_s {
sap_agent_h agent;
- sap_file_transaction_h socket;
+ sap_socket_h socket;
+ sap_peer_agent_h peer_agent;
+ sap_file_transaction_h file_socket;
};
-static struct priv priv_data = { 0 };
+static struct sap_info_s priv_data = { 0 };
+static struct sticker_info sticker_data;
+static queue<StickerRequest> ReqQueue;
+static StickerRequest current_request;
-gboolean file_on_progress = 0;
+static gboolean file_on_progress = FALSE;
static string incoming_file_name;
-static string recv_filepath;
+static int t_id = 0;
+static int rec_file_cnt_in_group = 0;
+static int total_file_count_in_group = 0;
+static int sync_success_cnt = 0;
+static gboolean job_progress = FALSE;
+static int sync_complete_flags = 0;
-static void _on_send_completed(sap_file_transaction_h file_transaction,
- sap_ft_transfer_e result,
- const char *file_path,
- void *user_data)
+static void save_last_sync_time()
+{
+ // save last sync time in preference
+ double current_time = ecore_time_unix_get();
+ if (preference_set_double(LAST_SYNC_TIME, current_time) == PREFERENCE_ERROR_NONE) {
+ LOGI("Succeed to set last sync time : %f", current_time);
+ }
+ else {
+ LOGW("Failed to set last sync time");
+ }
+}
+
+static void set_sync_first_complete()
+{
+ int complete_flags = 0;
+ if (vconf_get_int(VCONFKEY_STICKER_SYNC_COMPLETE, &complete_flags) == 0 && complete_flags == 0) {
+ // first sync
+ if (vconf_set_int(VCONFKEY_STICKER_SYNC_COMPLETE, VCONFKEY_STICKER_SYNC_COMPLETE_DONE) == 0)
+ LOGD("Succeed to set sync complete");
+ else
+ LOGW("Fail to set sync complete");
+ }
+}
+
+static void set_sync_complete()
+{
+ set_sync_first_complete();
+ save_last_sync_time();
+}
+
+static void set_sync_progressing(gboolean flag)
{
- char error_message[100];
+ job_progress = flag;
+#ifdef VCONFKEY_STICKER_SYNC_STATE
+ LOGD("sync progressing : %d", flag);
+ if (vconf_set_int(VCONFKEY_STICKER_SYNC_STATE, flag ? VCONFKEY_STICKER_SYNC_STATE_IN_PROGRESS : VCONFKEY_STICKER_SYNC_STATE_WAITING) == 0)
+ LOGD("Succeed to set sync state");
+ else
+ LOGW("Fail to set sync state");
+#else
+ LOGW("No vconf sync state definition");
+#endif
+}
+
+static gboolean _send_json_data(JsonObject *obj)
+{
+ JsonGenerator *j_generator = NULL;
+ JsonNode *j_node = NULL;
+ gsize size = 0;
+ gchar *data = NULL;
+ int result = 1;
+
+ j_generator = json_generator_new();
+ if (j_generator == NULL) {
+ LOGE("Unable to json_generator_new");
+ goto cleanup;
+ }
+
+ j_node = json_node_new(JSON_NODE_OBJECT);
+ if (j_node == NULL) {
+ LOGE("Unable to json_node_new");
+ goto cleanup;
+ }
+
+ json_node_set_object(j_node, obj);
+ json_generator_set_root(j_generator, j_node);
- LOGI("# transfer completed");
+ data = json_generator_to_data(j_generator, &size);
+ if (data == NULL) {
+ LOGE("Unable to json_generator_to_data");
+ goto cleanup;
+ }
if (priv_data.socket) {
+ LOGD("Send JSON data : %s", data);
+ result = sap_socket_send_data(priv_data.socket, ACCESSORY_SERVICE_CHANNEL_ID, strlen(data), (void *)data);
+ }
+
+cleanup:
+ if (data)
+ g_free(data);
+
+ if (j_node)
+ json_node_free(j_node);
+
+ if (j_generator)
+ g_object_unref(j_generator);
+
+ return result ? FALSE : TRUE;
+}
+
+static void notify_sync_progress(unsigned int file_progress)
+{
+ if (total_file_count_in_group == 0)
+ return;
+
+ LOGI("(%2d / %2d), file progress : %3u%%", rec_file_cnt_in_group+1, total_file_count_in_group, file_progress);
+ send_message("sync_progress", NULL);
+}
+
+static void _on_transfer_completed(sap_file_transaction_h file_transaction,
+ sap_ft_transfer_e result,
+ const char *file_path,
+ void *user_data)
+{
+ if (priv_data.file_socket) {
sap_file_transfer_destroy(file_transaction);
- priv_data.socket = NULL;
+ priv_data.file_socket = NULL;
}
if (result == SAP_FT_TRANSFER_SUCCESS) {
- sprintf(error_message, "Transfer Completed");
LOGI("Transfer Completed");
- if (chmod(recv_filepath.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
- LOGE("Failed to change permission : %s. error : %s", recv_filepath.c_str(), strerror(errno));
+ if (chmod(sticker_data.file_path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
+ LOGE("Failed to change permission : %s. error : %s", sticker_data.file_path.c_str(), strerror(errno));
}
else {
- LOGI("Succeed to change permission : %s", recv_filepath.c_str());
- if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
- insert_sticker_data(recv_filepath.c_str(), "keyword", "group", "test icon");
- destroy_sticker_provider_handle();
+ LOGI("Succeed to change permission : %s", sticker_data.file_path.c_str());
+ char thumb_path[PATH_MAX];
+ char *data_path = NULL;
+ data_path = app_get_shared_data_path();
+ snprintf(thumb_path, sizeof(thumb_path), "%s/thumbnail/%s", data_path, incoming_file_name.c_str());
+ sticker_data.thumbnail_path = string(thumb_path);
+
+ if (data_path)
+ free(data_path);
+
+ int ret = thumbnail_util_extract_to_file(sticker_data.file_path.c_str(), THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, sticker_data.thumbnail_path.c_str());
+ if (ret != THUMBNAIL_UTIL_ERROR_NONE) {
+ LOGE("Failed to create thumbnail. msg : %s", get_error_message(ret));
+ sticker_data.thumbnail_path.clear();
+ }
+
+ insert_sticker_data(sticker_data.file_path.c_str(), sticker_data.keyword.c_str(), sticker_data.group.c_str(), sticker_data.description.c_str(),
+ sticker_data.thumbnail_path.c_str(), sticker_data.disp_type.c_str());
- if (unlink(recv_filepath.c_str()) == -1)
- LOGE("Failed to remove sticker file");
+ if (unlink(sticker_data.file_path.c_str()) == -1)
+ LOGE("Failed to remove sticker file");
+
+ if (!sticker_data.thumbnail_path.empty()) {
+ if (unlink(sticker_data.thumbnail_path.c_str()) == -1)
+ LOGE("Failed to remove sticker thumbnail");
}
}
+
+ rec_file_cnt_in_group++;
} else {
switch (result) {
case (SAP_FT_TRANSFER_FAIL_CHANNEL_IO): {
- sprintf(error_message, "Channel IO Error.");
LOGW("Channel IO Error.");
break;
}
case (SAP_FT_TRANSFER_FAIL_FILE_IO): {
- sprintf(error_message, "File IO Error.");
LOGW("File IO Error.");
break;
}
case (SAP_FT_TRANSFER_FAIL_CMD_DROPPED):
{
- sprintf(error_message, "Transfer dropped.");
LOGW("Transfer dropped.");
break;
}
case (SAP_FT_TRANSFER_FAIL_PEER_UNRESPONSIVE):
{
- sprintf(error_message, "Peer Un Responsive.");
LOGW("Peer Un Responsive.");
break;
}
case (SAP_FT_TRANSFER_FAIL_PEER_CONN_LOST):
{
- sprintf(error_message, "Connection Lost.");
LOGW("Connection Lost.");
break;
}
case (SAP_FT_TRANSFER_FAIL_PEER_CANCELLED):
{
- sprintf(error_message, "Peer Cancelled.");
LOGW("Peer Cancelled.");
break;
}
case (SAP_FT_TRANSFER_FAIL_SPACE_NOT_AVAILABLE):
{
- sprintf(error_message, "No Space.");
LOGW("No Space.");
break;
}
default:
- sprintf(error_message, "Unknown Error");
LOGW("Unknown Error");
break;
}
}
- file_on_progress = 0;
+ file_on_progress = FALSE;
+ sticker_data.reset();
}
-static void _on_sending_file_in_progress(sap_file_transaction_h file_transaction,
- unsigned short int percentage_progress,
- void *user_data)
+static void _on_transfer_file_in_progress(sap_file_transaction_h file_transaction,
+ unsigned short int percentage_progress,
+ void *user_data)
{
- LOGI("# progress %d", percentage_progress);
+ notify_sync_progress(percentage_progress);
}
static void __set_file_transfer_cb(sap_file_transaction_h file_socket)
{
LOGI("# set callbacks");
- sap_file_transfer_set_progress_cb(file_socket, _on_sending_file_in_progress, NULL);
+ sap_file_transfer_set_progress_cb(file_socket, _on_transfer_file_in_progress, NULL);
- sap_file_transfer_set_done_cb(file_socket, _on_send_completed, NULL);
+ sap_file_transfer_set_done_cb(file_socket, _on_transfer_completed, NULL);
+}
+
+bool get_job_progress()
+{
+ return job_progress;
}
void accept_file()
data_path = app_get_shared_data_path();
LOGI("Path : %s", data_path);
- sprintf(file_path, "%s/%s", data_path, incoming_file_name.c_str());
+ snprintf(file_path, sizeof(file_path), "%s/%s", data_path, incoming_file_name.c_str());
LOGI("Receive filepath : %s", file_path);
- recv_filepath = string(file_path);
- free(data_path);
+ sticker_data.file_path = string(file_path);
+
+ if (data_path)
+ free(data_path);
- ret = sap_file_transfer_receive(priv_data.socket, file_path);
+ ret = sap_file_transfer_receive(priv_data.file_socket, file_path);
switch(ret) {
case SAP_RESULT_PERMISSION_DENIED:
LOGW("permission denied");
break;
}
- file_on_progress = 1;
+ file_on_progress = TRUE;
+}
+
+static int _create_thumbnail_directory()
+{
+ char thumb_path[PATH_MAX];
+ char *data_path = NULL;
+ data_path = app_get_shared_data_path();
+ snprintf(thumb_path, sizeof(thumb_path), "%s/thumbnail", data_path);
+
+ if (data_path)
+ free(data_path);
+
+ if (access(thumb_path, F_OK) == 0)
+ return 0;
+
+ if (mkdir(thumb_path, 0755) == -1) {
+ LOGE("directory create error");
+ return -1;
+ }
+
+ return 0;
+}
+
+bool request_sticker_data(const char *mode, const char *category, const char *type)
+{
+ bool result = false;
+ JsonObject *j_object = NULL;
+
+ if (!priv_data.socket) {
+ job_progress = TRUE;
+ StickerRequest pending_request;
+ pending_request.req_type = REQUEST_TYPE_SYNC;
+ pending_request.mode = string(mode ? mode : "manual");
+ pending_request.category = string(category ? category : "arsticker");
+ pending_request.type = string(type ? type : "input");
+
+ ReqQueue.push(pending_request);
+ LOGI("Push sync request");
+
+ return false;
+ }
+
+ j_object = json_object_new();
+ if (j_object == NULL) {
+ LOGE("json object create error");
+ return false;
+ }
+
+ if (_create_thumbnail_directory() != 0)
+ LOGE("Failed to create thumbnail directory");
+
+ json_object_set_string_member(j_object, "msgId", STICKER_SYNC_START_REQ);
+ json_object_set_int_member(j_object, "tID", ++t_id);
+ json_object_set_string_member(j_object, "mode", mode);
+ json_object_set_string_member(j_object, "category", category);
+ json_object_set_string_member(j_object, "type", type);
+
+ if (_send_json_data(j_object) == FALSE) {
+ LOGE("Failed to send STICKER_SYNC_START_REQ");
+ result = false;
+ }
+ else {
+ current_request.req_type = REQUEST_TYPE_SYNC;
+ current_request.mode = string(mode ? mode : "manual");
+ current_request.category = string(category ? category : "arsticker");
+ current_request.type = string(type ? type : "input");
+ set_sync_progressing(TRUE);
+ result = true;
+ }
+
+ json_object_unref(j_object);
+
+ return result;
+}
+
+static bool process_request_queue()
+{
+ if (ReqQueue.empty())
+ return false;
+
+ StickerRequest request = ReqQueue.front();
+
+ if (request.req_type == REQUEST_TYPE_FEATURE_REQ) {
+ LOGD("[Request feature exchange]");
+ request_sticker_feature();
+ ReqQueue.pop();
+ }
+ else if (request.req_type == REQUEST_TYPE_SYNC) {
+ LOGD("[Request to sync sticker] mode: %s, category: %s, type : %s", request.mode.c_str(),
+ request.category.c_str(),
+ request.type.c_str());
+
+ if (request_sticker_data(request.mode.c_str(), request.category.c_str(), request.type.c_str()))
+ ReqQueue.pop();
+ }
+ else if (request.req_type == REQUEST_TYPE_SHOW_NOTIFICATION) {
+ LOGD("[Request to show notification]");
+ request_show_sync_notification();
+ ReqQueue.pop();
+ }
+
+ return true;
}
-void sap_file_transfer_get_receive_filepath(char **filepath)
+void request_all_sticker_data(const char *mode, const char *type)
{
- *filepath = strdup(recv_filepath.c_str());
+ StickerRequest pending_request;
+ pending_request.req_type = REQUEST_TYPE_SYNC;
+ pending_request.mode = string(mode);
+ pending_request.type = string(type);
+
+#ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
+ int feature_flag = 0;
+ if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0)
+ {
+ if (feature_flag & VCONFKEY_STICKER_FEATURE_AREMOJI) {
+ pending_request.category = string("arsticker");
+ ReqQueue.push(pending_request);
+ }
+
+ if (feature_flag & VCONFKEY_STICKER_FEATURE_BITMOJI) {
+ pending_request.category = string("bitmoji");
+ ReqQueue.push(pending_request);
+ }
+ }
+ else
+ LOGW("Failed to get value of VCONFKEY_STICKER_SUPPORTED_FEATURE");
+#else
+ pending_request.category = string("arsticker");
+ ReqQueue.push(pending_request);
+ pending_request.category = string("bitmoji");
+ ReqQueue.push(pending_request);
+#endif
+
+ if (priv_data.socket)
+ process_request_queue();
+}
+
+void request_sticker_feature()
+{
+ JsonObject *j_object = NULL;
+
+ if (!priv_data.socket) {
+ job_progress = TRUE;
+ StickerRequest pending_request;
+ pending_request.req_type = REQUEST_TYPE_FEATURE_REQ;
+ ReqQueue.push(pending_request);
+ LOGI("Push sync feature request");
+ return;
+ }
+
+ j_object = json_object_new();
+ if (j_object == NULL) {
+ LOGE("json object create error");
+ return;
+ }
+
+ json_object_set_string_member(j_object, "msgId", STICKER_SYNC_FEATURE_REQ);
+ json_object_set_int_member(j_object, "tID", ++t_id);
+
+ if (_send_json_data(j_object) == FALSE) {
+ LOGE("Failed to send STICKER_SYNC_FEATURE_REQ");
+ }
+ else {
+ job_progress = TRUE;
+ }
+
+ json_object_unref(j_object);
+
+ if (_create_thumbnail_directory() != 0)
+ LOGE("Failed to create thumbnail directory");
+}
+
+void send_disconnect_message()
+{
+ JsonObject *j_object = NULL;
+ j_object = json_object_new();
+ if (j_object == NULL) {
+ LOGE("json object create error");
+ return;
+ }
+
+ json_object_set_string_member(j_object, "msgId", STICKER_SEND_DISCONNECT_REQ);
+ json_object_set_int_member(j_object, "tID", t_id);
+
+ if (_send_json_data(j_object) == FALSE) {
+ LOGE("Failed to send STICKER_SEND_DISCONNECT_REQ");
+ }
+
+ json_object_unref(j_object);
+}
+
+void request_show_sync_notification()
+{
+ JsonObject *j_object = NULL;
+
+ if (!priv_data.socket) {
+ job_progress = TRUE;
+ StickerRequest pending_request;
+ pending_request.req_type = REQUEST_TYPE_SHOW_NOTIFICATION;
+ ReqQueue.push(pending_request);
+ LOGI("Push show notification request");
+ return;
+ }
+
+ j_object = json_object_new();
+ if (j_object == NULL) {
+ LOGE("json object create error");
+ return;
+ }
+
+ json_object_set_string_member(j_object, "msgId", STICKER_REQUEST_NOTI_REQ);
+ json_object_set_int_member(j_object, "tID", ++t_id);
+
+ if (_send_json_data(j_object) == FALSE) {
+ LOGE("Failed to send STICKER_REQUEST_NOTI_REQ");
+ } else {
+ job_progress = TRUE;
+ }
+
+ json_object_unref(j_object);
}
void reject_file()
{
- int ret = sap_file_transfer_reject(priv_data.socket);
+ int ret = sap_file_transfer_reject(priv_data.file_socket);
LOGI("ret : %d", ret);
- file_on_progress = 0;
+ file_on_progress = FALSE;
}
-static void _on_receive_file_cb(sap_peer_agent_h peer_agent_h,
- sap_file_transaction_h socket,
- const char *file_path,
- void *user_data)
+static void _on_transfer_file_cb(sap_peer_agent_h peer_agent_h,
+ sap_file_transaction_h socket,
+ const char *file_path,
+ void *user_data)
{
- file_on_progress = 1;
- priv_data.socket = socket;
+ file_on_progress = TRUE;
+ priv_data.file_socket = socket;
LOGI("# incoming file request.");
- __set_file_transfer_cb(priv_data.socket);
+ __set_file_transfer_cb(priv_data.file_socket);
incoming_file_name = file_path;
std::size_t found = incoming_file_name.find_last_of("/");
sap_service_connection_terminated_reason_e result,
void *user_data)
{
- LOGI("connection terminated");
+ sap_info_s *priv = NULL;
+ priv = (sap_info_s *)user_data;
+
+ switch (result)
+ {
+ case SAP_CONNECTION_TERMINATED_REASON_PEER_DISCONNECTED:
+ LOGW("Peer Disconnected");
+ break;
+ case SAP_CONNECTION_TERMINATED_REASON_DEVICE_DETACHED:
+ LOGW("Disconnected Device Detached");
+ break;
+ case SAP_CONNECTION_TERMINATED_REASON_UNKNOWN:
+ LOGW("Disconnected Unknown Reason");
+ break;
+ default:
+ LOGW("connection terminated. reason : %d", result);
+ break;
+ }
+
+ sap_socket_destroy(priv->socket);
+ priv->socket = NULL;
+
+ set_sync_progressing(FALSE);
+ send_message("sync_stop_result", "cancel");
+ service_app_exit();
+}
+
+static void quit()
+{
+ job_progress = FALSE;
+ send_disconnect_message();
service_app_exit();
}
+static void send_sync_start_response(int result_code)
+{
+ int feature_flag = 0;
+ string response_to_app;
+ switch (result_code) {
+ case SYNC_START_RSP_SUCCESS:
+ {
+ response_to_app = "success";
+ if (current_request.category == string("arsticker"))
+ sync_complete_flags |= VCONFKEY_STICKER_FEATURE_AREMOJI;
+ else if (current_request.category == string("bitmoji"))
+ sync_complete_flags |= VCONFKEY_STICKER_FEATURE_BITMOJI;
+ }
+ break;
+ case SYNC_START_RSP_NO_STICKER:
+ response_to_app = "no_sticker";
+ break;
+ case SYNC_START_RSP_BITMOJI_ALL_DELETE:
+ {
+ int is_synced = 0;
+ if (vconf_get_int(VCONFKEY_STICKER_SYNC_COMPLETE, &is_synced) != 0)
+ LOGW("Failed to read sync completion");
+
+ if (is_synced == VCONFKEY_STICKER_SYNC_COMPLETE_NONE)
+ response_to_app = "no_sticker";
+ else
+ response_to_app = "success";
+ break;
+ }
+ case SYNC_START_RSP_AREMOJI_ALL_DELETE:
+ response_to_app = "success";
+ break;
+ case SYNC_START_RSP_SYNC_AFTER_DELETING_AREMOJI:
+ response_to_app = "success";
+ break;
+ default:
+ response_to_app = "unknown_error";
+ break;
+ }
+
+ LOGD("result code : %d, sync complete flag : %d", result_code, sync_complete_flags);
+
+#ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
+ if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) != 0)
+ {
+ LOGW("Failed to read support feature");
+ return;
+ }
+
+ LOGD("feature : %d, current request category : %s", feature_flag, current_request.category.c_str());
+ if (feature_flag == VCONFKEY_STICKER_FEATURE_AREMOJI ||
+ feature_flag == VCONFKEY_STICKER_FEATURE_BITMOJI)
+ {
+ LOGD("only standalone sync mode");
+ send_message("sync_start_response", response_to_app.c_str());
+ }
+ else {
+ if (current_request.category == string("arsticker"))
+ {
+ if (result_code == SYNC_START_RSP_SUCCESS)
+ send_message("sync_start_response", response_to_app.c_str());
+ }
+ else if (current_request.category == string("bitmoji"))
+ {
+ if (sync_complete_flags == 0 ||
+ sync_complete_flags == VCONFKEY_STICKER_FEATURE_BITMOJI)
+ send_message("sync_start_response", response_to_app.c_str());
+ }
+ }
+#endif
+}
+
void
on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned int payload_length, void *buffer,
void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
{
- LOGI("received data: %s, len:%d", (char *)buffer, payload_length);
+ unsigned int buf_len = strlen((char *)buffer);
+ LOGI("received data: %s, len: %d, buffer len : %d", (char *)buffer, payload_length, buf_len);
+
+ JsonParser *parser = json_parser_new();
+ GError *err_msg = NULL;
+ JsonNode *root = NULL;
+ JsonObject *root_obj = NULL;
+ string msg_id;
+ const char *json_msgid = NULL;
+
+ json_parser_load_from_data(parser, (char *)buffer, payload_length, &err_msg);
+ if (err_msg) {
+ LOGE("failed to load json file. error message: %s", err_msg->message);
+ goto cleanup;
+ }
+
+ root = json_parser_get_root(parser);
+ if (root == NULL) {
+ LOGE("failed to get root");
+ goto cleanup;
+ }
+
+ root_obj = json_node_get_object(root);
+ if (root_obj == NULL) {
+ LOGE("failed to get object");
+ goto cleanup;
+ }
+
+ json_msgid = json_object_get_string_member(root_obj, "msgId");
+ msg_id = string(json_msgid ? json_msgid : "");
+ if (msg_id == STICKER_REQUEST_SYNC_REQ) {
+ request_all_sticker_data("manual", "input");
+ } else if (msg_id == STICKER_SYNC_FEATURE_RSP) {
+ LOGD("msg : %s", msg_id.c_str());
+#ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
+ const char *json_aremoji = json_object_get_string_member(root_obj, "arEmoji");
+ const char *json_bitmoji = json_object_get_string_member(root_obj, "bitmoji");
+ string support_aremoji = string(json_aremoji ? json_aremoji : "");
+ string support_bitmoji = string(json_bitmoji ? json_bitmoji : "");
+ int supported_feature = VCONFKEY_STICKER_FEATURE_NONE;
+
+ if (support_aremoji == "support")
+ supported_feature |= VCONFKEY_STICKER_FEATURE_AREMOJI;
+
+ if (support_bitmoji == "support")
+ supported_feature |= VCONFKEY_STICKER_FEATURE_BITMOJI;
+
+ if (vconf_set_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, supported_feature) == 0)
+ LOGD("Succeed to set supported feature");
+ else
+ LOGW("Fail to set supported feature");
+#else
+ LOGW("No vconf supported feature");
+#endif
+
+ if (!process_request_queue()) {
+ quit();
+ }
+ } else if (msg_id == STICKER_SYNC_START_RSP) {
+ LOGD("msg : %s", msg_id.c_str());
+ const char *json_result = json_object_get_string_member(root_obj, "result");
+ string result = string(json_result ? json_result : "");
+ int result_code = json_object_get_int_member(root_obj, "resultCode");
+ LOGD("result : %s, resultCode : %d", result.c_str(), result_code);
+
+ if(result_code == SYNC_START_RSP_SUCCESS) {
+ send_sync_start_response(result_code);
+ if (current_request.category == string("bitmoji")) {
+ LOGD("Delete all bitmoji stickers");
+ delete_all_stickers("bitmoji");
+ }
+ } else if (result_code == SYNC_START_RSP_SYNC_AFTER_DELETING_AREMOJI) {
+ send_sync_start_response(result_code);
+ LOGD("Delete all AR Emoji stickers");
+ delete_all_stickers("arsticker");
+ } else {
+ if (result_code == SYNC_START_RSP_BITMOJI_ALL_DELETE) {
+ LOGD("Delete all bitmoji stickers");
+ delete_all_stickers("bitmoji");
+ } else if (result_code == SYNC_START_RSP_AREMOJI_ALL_DELETE) {
+ LOGD("Delete all AR Emoji stickers");
+ delete_all_stickers("arsticker");
+ }
+
+ if (!process_request_queue()) {
+#ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
+ int feature_flag = 0;
+
+ if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0)
+ {
+ LOGD("feature : %d, current request category : %s", feature_flag, current_request.category.c_str());
+ if (feature_flag & VCONFKEY_STICKER_FEATURE_BITMOJI)
+ {
+ if (current_request.category == string("bitmoji"))
+ {
+ /* other sticker group(s) has been synchronized completely */
+ if (sync_success_cnt > 0) {
+ set_sync_complete();
+ }
+ }
+ }
+ }
+ else {
+ LOGW("Failed to read support feature");
+ }
+#else
+ LOGW("No vconf supported feature");
+#endif /* VCONFKEY_STICKER_SUPPORTED_FEATURE */
+
+ send_sync_start_response(result_code);
+ set_sync_progressing(FALSE);
+ save_last_sync_time();
+
+ quit();
+ }
+ }
+ } else if (msg_id == STICKER_SEND_START_REQ) {
+ LOGD("msg : %s", msg_id.c_str());
+ total_file_count_in_group = 0;
+ rec_file_cnt_in_group = 0;
+ t_id = json_object_get_int_member(root_obj, "tID");
+ JsonArray *file_list = json_object_get_array_member(root_obj, "list");
+ if (file_list) {
+ int arr_len = json_array_get_length(file_list);
+ for (int i = 0; i < arr_len; i++) {
+ JsonObject *file_obj = json_array_get_object_element(file_list, i);
+ int file_len = json_object_get_int_member(file_obj, "size");
+ const char *json_filename = json_object_get_string_member(file_obj, "fileName");
+ string file_name = string(json_filename ? json_filename : "");
+
+ if (file_len > 0) {
+ LOGD("Add file : %s, len : %d", file_name.c_str(), file_len);
+ total_file_count_in_group++;
+ } else {
+ char *app_id = NULL;
+ char file_path[PATH_MAX];
+ char del_path[PATH_MAX];
+ std::size_t found = file_name.find_last_of("/");
+ string del_file_name = file_name.substr(found+1);
+ char *data_path = app_get_shared_data_path();
+ app_get_id(&app_id);
+ snprintf(file_path, sizeof(file_path), "%s/%s", data_path, del_file_name.c_str());
+ snprintf(del_path, sizeof(del_path), "%s/%s%s",STICKER_DIRECTORY, app_id, file_path);
+
+ LOGD("Delete file : %s, len : %d", del_path, file_len);
+ delete_sticker_data(del_path);
+
+ if (app_id)
+ free(app_id);
+ }
+ }
+ }
+
+ JsonObject *j_object = json_object_new();
+ if (j_object == NULL) {
+ LOGE("Unable to json_object_new");
+ goto cleanup;
+ }
+
+ json_object_set_string_member(j_object, "msgId", STICKER_SEND_START_RSP);
+ json_object_set_int_member(j_object, "tID", t_id);
+ json_object_set_string_member(j_object, "result", "success");
+
+ if (_send_json_data(j_object) == FALSE)
+ LOGE("Failed to send message");
+
+ json_object_unref(j_object);
+ } else if (msg_id == STICKER_SEND_FACE_DATA) {
+ LOGD("msg : %s", msg_id.c_str());
+ const char *type_data = json_object_get_string_member(root_obj, "type");
+ if (type_data)
+ sticker_data.disp_type = string(type_data);
+
+ const char *category = json_object_get_string_member(root_obj, "category");
+ if (category) {
+ sticker_data.group = string(category);
+ sticker_data.keyword = string(category);
+ }
+ } else if (msg_id == STICKER_SEND_STOP_REQ) {
+ LOGD("msg : %s", msg_id.c_str());
+ const char *json_reason = json_object_get_string_member(root_obj, "reason");
+ string reason = string(json_reason ? json_reason : "");
+ int file_len = json_object_get_int_member(root_obj, "count");
+
+ JsonObject *j_object = json_object_new();
+ if (j_object == NULL) {
+ LOGE("Unable to json_object_new");
+ goto cleanup;
+ }
+
+ json_object_set_string_member(j_object, "msgId", STICKER_SEND_STOP_RSP);
+ json_object_set_int_member(j_object, "tID", t_id);
+
+ if (reason == "complete") {
+ if (rec_file_cnt_in_group == file_len) {
+#ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
+ int feature_flag = 0;
+
+ if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0)
+ {
+ LOGD("feature : %d, current request category : %s", feature_flag, current_request.category.c_str());
+ if (feature_flag == VCONFKEY_STICKER_FEATURE_AREMOJI)
+ {
+ if (current_request.category == string("arsticker"))
+ {
+ set_sync_complete();
+ set_sync_progressing(FALSE);
+ }
+ }
+ else if (feature_flag & VCONFKEY_STICKER_FEATURE_BITMOJI)
+ {
+ if (current_request.category == string("bitmoji"))
+ {
+ set_sync_complete();
+ set_sync_progressing(FALSE);
+ }
+ }
+ }
+ else {
+ LOGW("Failed to read support feature");
+ }
+#else
+ LOGW("No vconf supported feature");
+#endif /* VCONFKEY_STICKER_SUPPORTED_FEATURE */
+
+ json_object_set_string_member(j_object, "result", "success");
+ sync_success_cnt++;
+ }
+ else {
+ json_object_set_string_member(j_object, "result", "failure");
+ }
+ }
+ else {
+ json_object_set_string_member(j_object, "result", "failure");
+ }
+
+ if (_send_json_data(j_object) == FALSE)
+ LOGE("Failed to send message");
+
+ json_object_unref(j_object);
+
+ send_message("sync_stop_result", reason.c_str());
+
+ current_request.mode.clear();
+ current_request.category.clear();
+ current_request.type.clear();
+
+ if (!process_request_queue()) {
+ sync_success_cnt = 0;
+
+ quit();
+ }
+ } else
+ LOGW("unknown msg id : %s", msg_id.c_str());
+
+cleanup:
+ if (err_msg)
+ g_error_free(err_msg);
+
+ if (parser)
+ g_object_unref(parser);
}
static void on_conn_req(sap_peer_agent_h peer_agent,
sap_service_connection_result_e result,
void *user_data)
{
- sap_peer_agent_accept_service_connection(peer_agent);
- sap_peer_agent_set_service_connection_terminated_cb(peer_agent, conn_terminated, NULL);
+ switch (result)
+ {
+ case SAP_CONNECTION_SUCCESS:
+ LOGI("Connection success");
+ priv_data.socket = socket;
+ sap_peer_agent_accept_service_connection(peer_agent);
+ sap_peer_agent_set_service_connection_terminated_cb(peer_agent, conn_terminated, &priv_data);
+ sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
+ break;
+ case SAP_CONNECTION_ALREADY_EXIST:
+ priv_data.socket = socket;
+ LOGI("Connection Already Exist");
+ break;
+ case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
+ LOGW("Connection failure device unreachable");
+ break;
+ case SAP_CONNECTION_FAILURE_INVALID_PEERAGENT:
+ LOGW("Connection failure invalid peer agent");
+ break;
+ case SAP_CONNECTION_FAILURE_NETWORK:
+ LOGW("Connection failure network");
+ break;
+ case SAP_CONNECTION_FAILURE_PEERAGENT_NO_RESPONSE:
+ LOGW("Connection failure peer agent no response");
+ break;
+ case SAP_CONNECTION_FAILURE_PEERAGENT_REJECTED:
+ LOGW("Connection failure peer agent rejected");
+ break;
+ case SAP_CONNECTION_FAILURE_UNKNOWN:
+ LOGW("Connection failure unknown");
+ break;
+ default:
+ LOGW("Connection failure. error code : %d", result);
+ break;
+ }
+}
+
+static void
+_on_service_connection_created(sap_peer_agent_h peer_agent,
+ sap_socket_h socket,
+ sap_service_connection_result_e result,
+ void *user_data)
+{
+ sap_info_s *priv = (sap_info_s *)user_data;
+
+ switch (result)
+ {
+ case SAP_CONNECTION_SUCCESS:
+ sap_peer_agent_set_service_connection_terminated_cb(priv->peer_agent,
+ conn_terminated,
+ priv);
+
+ sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
+ priv->socket = socket;
+ LOGI("Connection Established");
+
+ process_request_queue();
+
+ break;
+
+ case SAP_CONNECTION_ALREADY_EXIST:
+ priv->socket = socket;
+ LOGI("Connection Already Exist");
+ break;
+
+ case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
+ LOGW("Connection Failure device unreachable");
+ break;
+
+ case SAP_CONNECTION_FAILURE_INVALID_PEERAGENT:
+ LOGW("Connection Failure invalid peer agent");
+ break;
+
+ case SAP_CONNECTION_FAILURE_NETWORK:
+ LOGW("Connection Failure network");
+ break;
+
+ case SAP_CONNECTION_FAILURE_PEERAGENT_NO_RESPONSE:
+ LOGW("Connection Failure peer agent no response");
+ break;
+
+ case SAP_CONNECTION_FAILURE_PEERAGENT_REJECTED:
+ LOGW("Connection Failure peer agent rejected");
+ break;
+
+ case SAP_CONNECTION_FAILURE_UNKNOWN:
+ LOGW("Connection Failure peer agent unknown");
+ break;
+
+ case SAP_CONNECTION_IN_PROGRESS:
+ LOGW("Connection in progress");
+ break;
+
+ case SAP_CONNECTION_PEER_AGENT_NOT_SUPPORTED:
+ LOGW("Connection peer agent not supported");
+ break;
+ }
+}
+
+static gboolean
+_create_service_connection(gpointer user_data)
+{
+ sap_info_s *priv = (sap_info_s *)user_data;
+ int result = sap_agent_request_service_connection(priv->agent,
+ priv->peer_agent,
+ _on_service_connection_created,
+ priv);
+
+ LOGD("request connection result : %d", result);
- sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
+ return FALSE;
+}
+
+static void
+_on_peer_agent_updated(sap_peer_agent_h peer_agent,
+ sap_peer_agent_status_e peer_status,
+ sap_peer_agent_found_result_e result,
+ void *user_data)
+{
+ sap_info_s *priv = (sap_info_s *)user_data;
+
+ switch (result)
+ {
+ case SAP_PEER_AGENT_FOUND_RESULT_DEVICE_NOT_CONNECTED:
+ LOGW("SAP_PEER_AGENT_FOUND_RESULT_DEVICE_NOT_CONNECTED");
+ break;
+
+ case SAP_PEER_AGENT_FOUND_RESULT_FOUND:
+ if (peer_status == SAP_PEER_AGENT_STATUS_AVAILABLE)
+ {
+ LOGD("SAP_PEER_AGENT_FOUND_RESULT_FOUND");
+ priv->peer_agent = peer_agent;
+ g_idle_add(_create_service_connection, priv);
+ }
+ else
+ {
+ sap_peer_agent_destroy(peer_agent);
+ }
+ break;
+
+ case SAP_PEER_AGENT_FOUND_RESULT_SERVICE_NOT_FOUND:
+ LOGW("SAP_PEER_AGENT_FOUND_RESULT_SERVICE_NOT_FOUND");
+ break;
+
+ case SAP_PEER_AGENT_FOUND_RESULT_TIMEDOUT:
+ LOGW("SAP_PEER_AGENT_FOUND_RESULT_TIMEDOUT");
+ break;
+
+ case SAP_PEER_AGENT_FOUND_RESULT_INTERNAL_ERROR:
+ LOGW("SAP_PEER_AGENT_FOUND_RESULT_INTERNAL_ERROR");
+ break;
+
+ default:
+ break;
+ }
+}
+
+static gboolean
+_find_peer_agent(gpointer user_data)
+{
+ sap_info_s *priv = (sap_info_s *)user_data;
+ sap_agent_find_peer_agent(priv->agent, _on_peer_agent_updated, priv);
+
+ return FALSE;
}
static void on_agent_initialized(sap_agent_h agent,
priv_data.agent = agent;
- sap_file_transfer_set_incoming_file_cb(agent, _on_receive_file_cb, NULL);
+ sap_file_transfer_set_incoming_file_cb(agent, _on_transfer_file_cb, NULL);
sap_agent_set_service_connection_requested_cb(agent, on_conn_req, NULL);
break;
switch (status) {
case SAP_DEVICE_STATUS_DETACHED:
LOGD("device is not connected.");
+ send_message("sync_stop_result", "cancel");
break;
case SAP_DEVICE_STATUS_ATTACHED:
LOGD("Attached calling find peer now");
+ g_idle_add(_find_peer_agent, &priv_data);
break;
default:
LOGE("unknown status (%d)", status);
{
sap_agent_h agent = NULL;
+ if (priv_data.agent) {
+ LOGW("duplicate initialize");
+ return FALSE;
+ }
+
sap_agent_create(&agent);
priv_data.agent = agent;
void deinitialize_sap(void)
{
+ LOGD("deinitialize");
if (priv_data.agent) {
int ret = sap_agent_deinitialize(priv_data.agent, on_agent_deinitialized, NULL);
switch (ret) {
priv_data.agent = NULL;
}
}
+
+gboolean is_init_sap()
+{
+ return priv_data.agent ? TRUE : FALSE;
+}
\ No newline at end of file