MESSAGE("VERSION : ${VERSION}")
MESSAGE("LICENSE PATH : ${PKG_LICENSE_PATH}")
-IF(DEFINED SUPPORT_CLOUD_SYSTEM)
- MESSAGE("SUPPORT CLOUD SYSTEM : ${SUPPORT_CLOUD_SYSTEM}")
- IF(SUPPORT_CLOUD_SYSTEM)
- ADD_DEFINITIONS(-DSUPPORT_CLOUD_SYSTEM)
- ADD_DEFINITIONS(-DCLOUD_PDM_SERVER=\"${CLOUD_PDM_SERVER}\")
- ENDIF(SUPPORT_CLOUD_SYSTEM)
-ENDIF(DEFINED SUPPORT_CLOUD_SYSTEM)
+IF(DEFINED SUPPORT_CLOUD_SYNC)
+ MESSAGE("SUPPORT CLOUD SYNC : ${SUPPORT_CLOUD_SYNC}")
+ IF(SUPPORT_CLOUD_SYNC)
+ ADD_DEFINITIONS(-DSUPPORT_CLOUD_SYNC)
+ ENDIF(SUPPORT_CLOUD_SYNC)
+ENDIF(DEFINED SUPPORT_CLOUD_SYNC)
IF(DEFINED SUPPORT_BOOTING_DONE)
MESSAGE("SUPPORT BOOTING DONE : ${SUPPORT_BOOTING_DONE}")
SET(PC_REQUIRED "dlog libpng")
+IF(SUPPORT_CLOUD_SYNC)
+ SET(PC_REQUIRED "dlog libpng iotcloud notification json-c glib-2.0")
+ENDIF(SUPPORT_CLOUD_SYNC)
+
INCLUDE(FindPkgConfig)
pkg_check_modules(bookmark_adaptor_pkgs REQUIRED ${PC_REQUIRED})
ADD_DEFINITIONS(-DBROWSER_PROVIDER_LOG_TAG=\"BOOKMARK_ADAPTOR\")
-ADD_LIBRARY(${PROJECT_NAME} SHARED
+SET(BP_BOOKMARK_ADAPTOR_SOURCES
${CMAKE_SOURCE_DIR}/common-adaptor/common-adaptor.c
${CMAKE_SOURCE_DIR}/common-adaptor/common-adaptor-png.c
${CMAKE_SOURCE_DIR}/provider/browser-provider-socket.c
${CMAKE_SOURCE_DIR}/provider/browser-provider-shm.c
${CMAKE_CURRENT_SOURCE_DIR}/bookmark-adaptor-image.c
${CMAKE_CURRENT_SOURCE_DIR}/bookmark-adaptor.c )
+
+IF(SUPPORT_CLOUD_SYNC)
+ LIST(APPEND BP_BOOKMARK_ADAPTOR_SOURCES
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-bookmark.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-cloud-bookmark.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-cloud.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-cloud-json.c)
+ENDIF(SUPPORT_CLOUD_SYNC)
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${BP_BOOKMARK_ADAPTOR_SOURCES})
+
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${bookmark_adaptor_pkgs_LDFLAGS} ${BOOKMARK_LINK_LIBRARIES})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${PKG_VERSION})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0)
#include <browser-provider.h>
#include <browser-provider-socket.h>
+#ifdef SUPPORT_CLOUD_SYNC
+#include <sync-adaptor.h>
+#include <sync-adaptor-bookmark.h>
+#endif
+
bp_adaptor_defs *g_adaptorinfo = NULL;
pthread_mutex_t g_adaptor_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t g_adaptor_event_thread_pid = 0;
if (bp_common_adaptor_is_sync_adaptor() == 0)
client_type = BP_CLIENT_BOOKMARK_SYNC;
#endif
-
+#ifdef SUPPORT_CLOUD_SYNC
+ if (bp_sync_is_login()){
+ client_type = BP_CLIENT_BOOKMARK_SYNC;
+ }
+#endif
if (bp_common_adaptor_connect_to_provider(&g_adaptorinfo,
client_type) < 0) {
TRACE_ERROR("[CHECK connection]");
*/
EXPORT_API int bp_bookmark_adaptor_reset(void);
+
+/**
+ * @brief Gets the array of ids and the number of rows of all deleted items from the storage
+ * @remarks Allocated memory (ids) has to be released by the caller
+ * @param[out] ids The array of ids
+ * @param[out] count The array size
+ * @return 0 on success, otherwise -1 is returned and error code is set to indicate the error.
+ */
+EXPORT_API int bp_bookmark_adaptor_get_deleted_ids_p(int **ids, int *count);
+
+/**
+ * @brief Ddeletes all tabs having set 'is_deleted' property from the storage
+ * @details If cloud is on, "is_dirty" property is off by calling delete function,\n
+ * if cloud is off, a scrap is deleted really from storage whenever delete function is called.
+ * @return 0 on success, otherwise -1 is returned and error code is set to indicate the error.
+ */
+EXPORT_API int bp_bookmark_adaptor_clear_deleted_ids(void);
+
/**
* @}
*/
+EXPORT_API int bp_sync_bookmark_login(char* guid, char* accesstoken, char* app_id, char* package_name);
+EXPORT_API int bp_sync_bookmark(void);
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BROWSER_PROVIDER_SYNC_ADAPTOR_BOOKMARK_H__
+#define __BROWSER_PROVIDER_SYNC_ADAPTOR_BOOKMARK_H__
+
+#define MANIFEST_ID_BOOKMARK "org.tizen.manifest.web_bookmark"
+#define IS_BOOKMARK_SYNC_COLD_START (_bookmark_cloud.synctime>0 ? 0 : 1)
+
+typedef struct {
+ int count;
+ int *id_list;
+ int *mark;
+ bp_bookmark_info_fmt *item_list;
+}sync_bookmark_local_list;
+
+typedef struct {
+ char *id;
+ char *url;
+ char *title;
+ char *favicon_data;
+ int favicon_width;
+ int favicon_height;
+ int64_t create_time;
+ int64_t update_time;
+} sync_bookmark_cloud_info_fmt;
+
+typedef struct {
+ int count;
+ int64_t synctime;
+ int *mark;
+ sync_bookmark_cloud_info_fmt *item_list;
+} sync_bookmark_cloud_list;
+
+typedef void(*bookmark_sync_cb)(sync_bookmark_cloud_list*, sync_bookmark_local_list*);
+typedef void(*cloud_delete_bookmark_cb_func)(int result);
+
+int bp_sync_bookmark(void);
+
+#endif /* __BROWSER_PROVIDER_SYNC_ADAPTOR_BOOKMARK_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __BROWSER_PROVIDER_SYNC_ADAPTOR_CLOUD_JSON_H__
+#define __BROWSER_PROVIDER_SYNC_ADAPTOR_CLOUD_JSON_H__
+
+#include <glib.h>
+#include <json.h>
+
+inline char* _get_json_string(GSList * list, json_object *record_item, char *key_name);
+inline int _get_json_int(GSList * list, json_object *record_item, char *key_name);
+inline int _get_json_array_length(GSList * list, json_object *record_item, char *key_name);
+inline json_object* _get_json_array_object_by_idx(GSList * list, json_object *record_item, char *key_name, int idx);
+inline json_object* _get_json_tokener_parse(GSList * list, char *msg);
+void free_json(GSList * list);
+
+#endif /* __BROWSER_PROVIDER_SYNC_ADAPTOR_CLOUD_JSON_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BROWSER_PROVIDER_SYNC_ADAPTOR_CLOUD_H__
+#define __BROWSER_PROVIDER_SYNC_ADAPTOR_CLOUD_H__
+
+typedef enum {
+ SYNC_NONE = 0, /* No changes */
+ SYNC_UPDATE, /* Need to update */
+ SYNC_DELETE, /* Need to delete */
+ SYNC_DELETED_NONE, /* No need to upsync to delete*/
+ SYNC_DELETED_UPSYNC /* Need to upsync to delete*/
+}sync_mark_type;
+
+int cloud_init(char* device_id, char* samsung_account_app_id, char* app_package_name);
+int cloud_login(char* guid, char* accesstoken);
+void cloud_write(char* manifest_id, int manifest_cn, char* id, char* url, char* title,
+ const char* favicon_data, int favicon_width, int favicon_height);
+
+
+#endif /* __BROWSER_PROVIDER_SYNC_ADAPTOR_CLOUD_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BROWSER_PROVIDER_SYNC_ADAPTOR_TAB_H__
+#define __BROWSER_PROVIDER_SYNC_ADAPTOR_TAB_H__
+
+#define IS_TAB_SYNC_COLD_START (_tab_cloud.synctime>0 ? 0 : 1)
+#define MANIFEST_ID_TAB "org.tizen.manifest.web_tab"
+
+typedef struct {
+ int count;
+ int *id_list;
+ int *mark;
+ bp_tab_info_fmt *item_list;
+}sync_tab_local_list;
+
+typedef struct {
+ char *id;
+ char *url;
+ char *title;
+ char *device_id;
+ char *favicon_data;
+ int favicon_width;
+ int favicon_height;
+ int64_t create_time;
+ int64_t update_time;
+} sync_tab_cloud_info_fmt;
+
+typedef struct {
+ int count;
+ int64_t synctime;
+ int *mark;
+ sync_tab_cloud_info_fmt *item_list;
+} sync_tab_cloud_list;
+
+typedef void(*tab_sync_cb)(sync_tab_cloud_list*, sync_tab_local_list*);
+typedef void(*cloud_delete_tab_cb_func)(int);
+
+int bp_sync_tab(void);
+
+#endif /* __BROWSER_PROVIDER_SYNC_ADAPTOR_TAB_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BROWSER_PROVIDER_SYNC_ADAPTOR_H__
+#define __BROWSER_PROVIDER_SYNC_ADAPTOR_H__
+
+typedef enum {
+ SYNC_LOGOUT = 0,
+ SYNC_LOGIN
+}sync_login_type;
+
+#define SYNC_CLOUD_ID_MAX_LENGTH 40
+
+#define _LOOP_INIT(idx, list_type, list_var, list) int idx=0;\
+ list_type* list_var = list;
+#define CLOUD_LOOP_INIT(list_type,list) _LOOP_INIT(cloud_idx, list_type, cloud_list, list)
+#define LOCAL_LOOP_INIT(list_type,list) _LOOP_INIT(local_idx, list_type, local_list, list)
+
+#define _FOR_LOOP(idx,list) for (idx = 0; idx < list->count; idx++)
+#define CLOUD_LOOP() _FOR_LOOP(cloud_idx,cloud_list)
+#define LOCAL_LOOP() _FOR_LOOP(local_idx,local_list)
+
+#define IS_SAME_CLOUD_URL_AS_LOCAL() \
+ (strcmp(cloud_list->item_list[cloud_idx].url,local_list->item_list[local_idx].url) == 0)
+
+#define IS_LOCAL_NORMAL() \
+ (local_list->mark[local_idx] == SYNC_NONE)
+
+#define IS_LOCAL_DELETED() \
+ (local_list->mark[local_idx] == SYNC_DELETED_UPSYNC)
+
+#define IS_CLOUD_TO_UPDATE() \
+ (cloud_list->mark[cloud_idx] == SYNC_UPDATE)
+
+#define IS_CLOUD_TO_DELETE() \
+ (cloud_list->mark[cloud_idx] == SYNC_DELETE)
+
+#define IS_SAME_CLOUD_RECORD_AS_LOCAL() \
+ (strcmp(local_list->item_list[local_idx].sync,cloud_list->item_list[cloud_idx].id) == 0)
+
+#define IS_CLOUD_OLDER_THAN_LOCAL() \
+ (cloud_list->item_list[cloud_idx].update_time <= (int64_t)((int64_t)local_list->item_list[local_idx].date_modified*(int64_t)1000) )
+
+#define IS_SYNCED_RECORD_WITHOUT_DIRTY() \
+ (strcmp(local_list->item_list[local_idx].sync,cloud_list->item_list[cloud_idx].id) == 0 \
+ && local_list->item_list[local_idx].date_modified == local_list->item_list[local_idx].date_created)
+
+#define IS_MADE_BY_LOCAL() \
+ (local_list->item_list[local_idx].sync == NULL)
+
+#define HOLD_LOCAL() do {\
+ cloud_list->mark[cloud_idx] = SYNC_NONE;\
+ local_list->mark[local_idx] = SYNC_NONE;\
+ TRACE_DEBUG("hold local[%d]",local_idx);\
+} while(0)
+
+#define UPSYNC() do {\
+ cloud_list->mark[cloud_idx] = SYNC_NONE;\
+ local_list->mark[local_idx] = SYNC_UPDATE;\
+ local_list->item_list[local_idx].sync = cloud_list->item_list[cloud_idx].id;\
+ TRACE_DEBUG("cloud is old. local(%d)->cloud(%d)",local_idx,cloud_idx);\
+} while(0)
+
+#define UPSYNC_REVIVE() do {\
+ cloud_list->mark[cloud_idx] = SYNC_NONE;\
+ local_list->mark[local_idx] = SYNC_UPDATE;\
+ TRACE_DEBUG("local(%d)->cloud, deleted cloud (%d) is old.",local_idx,cloud_idx);\
+} while(0)
+
+#define UPSYNC_NEW_LOCAL() do {\
+ local_list->mark[local_idx] = SYNC_UPDATE;\
+ TRACE_DEBUG("local(%d)->cloud as a new item.",local_idx);\
+} while(0)
+
+#define DOWNSYNC() do {\
+ cloud_list->mark[cloud_idx] = SYNC_UPDATE;\
+ local_list->mark[local_idx] = SYNC_DELETE;\
+ TRACE_DEBUG("local is old. local(%d)<-cloud(%d)",local_idx,cloud_idx);\
+} while(0)
+
+#define DOWNSYNC_DELETE() do {\
+ cloud_list->mark[cloud_idx] = SYNC_NONE;\
+ local_list->mark[local_idx] = SYNC_DELETE;\
+ TRACE_DEBUG("local(%d) should be deleted. cloud(%d) was deleted.",local_idx,cloud_idx);\
+} while(0)
+
+#define UPSYNC_DELETED() do {\
+ cloud_list->mark[cloud_idx] = SYNC_NONE;\
+ local->mark[local_idx] = SYNC_DELETED_UPSYNC;\
+ TRACE_DEBUG("cloud[%d] should be deleted. local[%d] was deleted",cloud_idx,local_idx);\
+} while(0)
+
+#define NO_UPSYNC_DELETED() local_list->mark[local_idx] = SYNC_DELETED_NONE;
+
+#define MAKE_CLOUD_ID(device_id) do {\
+ cloud_list->item_list[cloud_idx].id = malloc(SYNC_CLOUD_ID_MAX_LENGTH);/*TODO : free later */\
+ memset(cloud_list->item_list[cloud_idx].id,0x00,SYNC_CLOUD_ID_MAX_LENGTH);\
+ if (local_list->item_list[local_idx].sync == NULL){\
+ sprintf(cloud_list->item_list[cloud_idx].id,"%d%s",local_list->id_list[local_idx],device_id);\
+ }else{\
+ sprintf(cloud_list->item_list[cloud_idx].id,"%s",local_list->item_list[local_idx].sync);\
+ }\
+} while(0)
+
+#define MARK_UPDATE_SYNC(device_id) do {\
+ if (( IS_MADE_BY_LOCAL() || IS_SAME_CLOUD_RECORD_AS_LOCAL() ) && (IS_SAME_CLOUD_URL_AS_LOCAL())){\
+ if (IS_CLOUD_OLDER_THAN_LOCAL()){\
+ if(IS_SYNCED_RECORD_WITHOUT_DIRTY()){\
+ HOLD_LOCAL();\
+ }else{\
+ UPSYNC();\
+ }\
+ }else{\
+ DOWNSYNC();\
+ MAKE_CLOUD_ID(device_id);\
+ }\
+ }\
+} while(0)
+
+#define MARK_DELETED_SYNC() do {\
+ if (IS_CLOUD_OLDER_THAN_LOCAL())\
+ {\
+ UPSYNC_DELETED();\
+ }else {\
+ NO_UPSYNC_DELETED();\
+ }\
+} while(0)
+
+
+#define MARK_DELETE_SYNC() do {\
+ if (IS_CLOUD_OLDER_THAN_LOCAL()){\
+ UPSYNC_REVIVE();\
+ }else{\
+ DOWNSYNC_DELETE();\
+ }\
+} while(0)
+
+#define PRINT_LOCAL_LOG() TRACE_DEBUG("LOCAL[%d/%d] %d",local_idx+1,local_list->count,local_list->mark[local_idx]);
+#define PRINT_CLOUD_LOG() TRACE_DEBUG("CLOUD[%d/%d] %d",cloud_idx+1,cloud_list->count,cloud_list->mark[cloud_idx]);
+#define PRINT_DELETED_LOG() TRACE_DEBUG("DELETED[%d/%d] %d",deleted_idx+1,deleted_list->count,deleted_list->mark[deleted_idx]);
+
+char* get_device_id(void);
+int bp_sync_login(char* guid, char* accesstoken);
+
+#endif /* __BROWSER_PROVIDER_SYNC_ADAPTOR_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <web_bookmark.h>
+#include <browser-provider.h>
+#include <browser-provider-log.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <sync-adaptor.h>
+#include <sync-adaptor-bookmark.h>
+#include <sync-adaptor-cloud.h>
+
+static sync_bookmark_local_list _bookmark_local;
+static sync_bookmark_cloud_list _bookmark_cloud;
+
+static void find_bookmark_conflict(sync_bookmark_cloud_list *cloud, sync_bookmark_local_list *local)
+{
+ TRACE_DEBUG("");
+
+ CLOUD_LOOP_INIT(sync_bookmark_cloud_list,cloud);
+ LOCAL_LOOP_INIT(sync_bookmark_local_list,local);
+
+ CLOUD_LOOP(){
+ LOCAL_LOOP(){
+ if(IS_CLOUD_TO_UPDATE()){
+ if(IS_LOCAL_NORMAL()){
+ MARK_UPDATE_SYNC(get_device_id());
+ }else if (IS_LOCAL_DELETED()){
+ MARK_DELETED_SYNC();
+ }
+ }
+ else if(IS_CLOUD_TO_DELETE()){
+ if(IS_SAME_CLOUD_RECORD_AS_LOCAL()){
+ MARK_DELETE_SYNC();
+ }
+ }
+ }
+ }
+}
+
+static find_new_bookmark_local(sync_bookmark_local_list *local)
+{
+ TRACE_DEBUG("");
+
+ LOCAL_LOOP_INIT(sync_bookmark_local_list,local);
+
+ LOCAL_LOOP(){
+ if (IS_LOCAL_NORMAL() && IS_MADE_BY_LOCAL()){
+ UPSYNC_NEW_LOCAL();
+ }
+ }
+}
+
+static int bookmark_write_local(char* url, char* title, char* sync_value, char* favicon_data, int favicon_width, int favicon_height)
+{
+ TRACE_DEBUG("");
+ int root_id = 0, id = -1;
+
+ bp_bookmark_adaptor_get_root(&root_id);
+ bp_bookmark_info_fmt info;
+ memset(&info, 0x00, sizeof(bp_bookmark_info_fmt));
+ info.url = url;
+ info.title = title;
+ info.type = 0;
+ info.parent = root_id;
+ info.sequence = -1;
+ info.access_count = -1;
+ info.editable = 1;
+ info.sync = sync_value; //id for cloud
+
+ int ret = bp_bookmark_adaptor_easy_create(&id, &info);
+
+ if (ret == 0){
+ ret = bp_bookmark_adaptor_set_sequence(id, -1); // set max sequence
+ if (favicon_data != NULL){
+ gsize len = 0;
+ const unsigned char * decoded_data;
+ decoded_data = g_base64_decode(favicon_data,&len);
+ TRACE_DEBUG("favicon %d x %d len: %d", favicon_width, favicon_height, len);
+ int ret_icon = bp_bookmark_adaptor_set_icon(id, favicon_width, favicon_height, (const unsigned char *)decoded_data, len);
+ if (ret_icon < 0) {
+ TRACE_DEBUG("bp_bookmark_adaptor_set_favicon is failed");
+ }
+ }
+ bp_bookmark_adaptor_publish_notification();
+ TRACE_DEBUG("");
+ return id;
+ }
+ else{
+ TRACE_DEBUG("ERROR adding bookmark! %d", bp_bookmark_adaptor_get_errorcode());
+ return -1;
+ }
+}
+
+static int bookmark_get_favicon(int id, int *width, int *height, const char **encoded_data)
+{
+ unsigned char *favicon_data = NULL;
+ int len = 0;
+ int ret = bp_bookmark_adaptor_get_icon(id, width, height, (unsigned char **)&favicon_data, &len);
+ if (ret < 0) {
+ TRACE_DEBUG("bp_bookmark_adaptor_get_icon is failed");
+ return -1;
+ }else{
+ *encoded_data = (const char *)g_base64_encode((const guchar *)favicon_data, (gsize) len);
+ TRACE_DEBUG("bp_bookmark_adaptor_get_icon (len:%d, %d x %d)", len, *width, *height);
+ return 1;
+ }
+}
+
+static void downsync_bookmark_update(sync_bookmark_cloud_list* list)
+{
+ TRACE_DEBUG("");
+
+ int i;
+ for (i = 0; i < list->count; i++) {
+ if(list->mark[i] == SYNC_UPDATE){
+ char *id = list->item_list[i].id; //for sync_value
+ char *url = list->item_list[i].url;
+ char *title = list->item_list[i].title;
+ char *favicon_data = list->item_list[i].favicon_data;
+ int favicon_width = list->item_list[i].favicon_width;
+ int favicon_height = list->item_list[i].favicon_height;
+
+ TRACE_DEBUG("UPDATE local bookmark [%s] %s %s",id,url,title);
+ int local_id = bookmark_write_local(url, title, id, favicon_data, favicon_width, favicon_height);
+ }
+ }
+}
+
+static void downsync_bookmark_delete(sync_bookmark_local_list* list)
+{
+ TRACE_DEBUG("");
+
+ int i = 0, cnt = 0;
+ for (i = 0; i < list->count; i++) {
+ if(list->mark[i] == SYNC_DELETE){
+ int id = list->id_list[i];
+ TRACE_DEBUG("DELETE local bookmark [%d]",id);
+ bp_bookmark_adaptor_delete(id);
+ cnt++;
+ }
+ }
+ if (cnt > 0)
+ {
+ bp_bookmark_adaptor_publish_notification();
+ bp_bookmark_adaptor_clear_deleted_ids();
+ }
+}
+
+static void upsync_bookmark_update(sync_bookmark_local_list *list)
+{
+ TRACE_DEBUG("");
+
+ int i;
+ char *id;
+ id = malloc(SYNC_CLOUD_ID_MAX_LENGTH);
+ for (i = 0; i < list->count; i++) {
+ if(list->mark[i] == SYNC_UPDATE){
+ memset(id,0x00,SYNC_CLOUD_ID_MAX_LENGTH);
+ //use bookmark 'sync' value to keep tracking ID on cloud
+ if (list->item_list[i].sync == NULL){
+ sprintf(id,"%d%s",list->id_list[i],get_device_id()); //new ID
+ list->item_list[i].sync = id;
+ bp_bookmark_adaptor_set_sync(list->id_list[i],id);
+ }else{
+ sprintf(id,"%s",list->item_list[i].sync); // used ID
+ }
+ char *url = list->item_list[i].url;
+ char *title = list->item_list[i].title;
+ TRACE_DEBUG("UPDATE Cloud [%s] %s",id,url);
+
+ const char *encoded_data = NULL;
+ int w = 0;
+ int h = 0;
+ if (bookmark_get_favicon(list->id_list[i], &w, &h, &encoded_data) > 0)
+ {
+ cloud_write_bookmark(id, url, title, encoded_data, w, h);
+ }
+ }
+ }
+ free(id);
+}
+
+static void upsync_bookmark_delete_cb(int result)
+{
+ if (result < 0)
+ TRACE_DEBUG("DELETED failed");//TODO
+ else
+ TRACE_DEBUG("DELETED succeeded");
+}
+
+static void upsync_bookmark_delete(sync_bookmark_local_list* local)
+{
+ TRACE_DEBUG("");
+
+ int i = 0, cnt = 0;;
+ for (i = 0; i < local->count; i++) {
+ if(local->mark[i] == SYNC_DELETED_UPSYNC && local->item_list[i].sync != NULL){
+ TRACE_DEBUG("DELETE Cloud [%d/%d] mark:%d sync:%s",i,local->count,local->mark[i],local->item_list[i].sync);
+ cloud_delete_bookmark(local->item_list[i].sync,upsync_bookmark_delete_cb);
+ cnt++;
+ }
+ }
+ if (cnt > 0)
+ {
+ bp_bookmark_adaptor_clear_deleted_ids();
+ }
+}
+
+static void bookmark_init_cold_start(sync_bookmark_local_list* list)
+{
+ //mark synched record to SYNC_DELETE.
+ //After find_sync(), if it is still SYNC_DELETE , it should be deleted.
+ int i = 0;
+ int cnt = list->count;
+ for(i = 0; i < cnt; i++){
+ if (list->item_list[i].sync != NULL){
+ list->mark[i] = SYNC_DELETE;
+ }
+ }
+}
+
+static void bookmark_get_local(sync_bookmark_local_list* list)
+{
+ int *ids = NULL;
+ int ids_count = 0;
+ int i = 0;
+ int value;
+ char * * url;
+ char * * title;
+ bp_bookmark_adaptor_get_ids_p(&ids, &ids_count, -1, 0, WEB_BOOKMARK_ROOT_ID,
+ -1, -1, -1, BP_BOOKMARK_O_SEQUENCE, 0);
+
+ list->count = ids_count;
+ list->id_list = malloc(ids_count*sizeof(int));
+ list->item_list = malloc(ids_count*sizeof(bp_bookmark_info_fmt));
+ list->mark = malloc(ids_count*sizeof(int));
+ for (i = 0; i < ids_count; i++) {
+ list->mark[i] = SYNC_NONE;
+ list->id_list[i] = ids[i];
+ bp_bookmark_adaptor_get_type(ids[i],&value);
+ if (value==0/*only bookmark not parent*/){
+ unsigned int b_offset = (BP_BOOKMARK_O_TYPE | BP_BOOKMARK_O_DATE_CREATED | BP_BOOKMARK_O_DATE_MODIFIED | BP_BOOKMARK_O_URL
+ | BP_BOOKMARK_O_TITLE | BP_BOOKMARK_O_SYNC );
+ memset(&(list->item_list[i]), 0x00, sizeof(bp_bookmark_info_fmt));
+ int ret = bp_bookmark_adaptor_get_info(list->id_list[i], b_offset, &(list->item_list[i]));
+ TRACE_DEBUG("[Local bookmark] id:%d title: %s url: %s sync: %s, created: %d, modified: %d",ids[i],
+ list->item_list[i].title, list->item_list[i].url, list->item_list[i].sync,
+ list->item_list[i].date_created, list->item_list[i].date_modified);
+ }
+ }
+ free(ids);
+}
+
+static void bookmark_get_deleted(sync_bookmark_local_list* local)
+{
+ int deleted_count = 0;
+ int i = 0, start_idx = 0;
+ int value;
+ char * * url;
+ char * * title;
+ int *local_delete_ids = NULL;
+
+ start_idx = local->count;
+ bp_bookmark_adaptor_get_deleted_ids_p(&local_delete_ids,&deleted_count);
+ TRACE_DEBUG("[Local Deleted] cnt:%d local_list(start_idx):%d", deleted_count, start_idx);
+
+ if(deleted_count > 0 && start_idx > 0){
+ local->count += deleted_count;
+ local->id_list = realloc(local->id_list, local->count*sizeof(int));
+ local->item_list = realloc(local->item_list, local->count*sizeof(bp_bookmark_info_fmt));
+ local->mark = realloc(local->mark, local->count*sizeof(int));
+ }else if (deleted_count > 0 && start_idx == 0){
+ local->count = deleted_count;
+ local->id_list = malloc(deleted_count*sizeof(int));
+ local->item_list = malloc(deleted_count*sizeof(bp_bookmark_info_fmt));
+ local->mark = malloc(deleted_count*sizeof(int));
+ }
+
+ for (i=start_idx; i < (start_idx + deleted_count); i++)
+ {
+ local->mark[i] = SYNC_DELETED_UPSYNC;
+ local->id_list[i] = local_delete_ids[i-start_idx];
+ bp_bookmark_adaptor_get_type(local_delete_ids[i-start_idx],&value);
+ if (value==0/*only bookmark not parent*/){
+ unsigned int b_offset = (BP_BOOKMARK_O_TYPE | BP_BOOKMARK_O_DATE_CREATED | BP_BOOKMARK_O_DATE_MODIFIED | BP_BOOKMARK_O_URL
+ | BP_BOOKMARK_O_TITLE | BP_BOOKMARK_O_SYNC);
+ memset(&(local->item_list[i]), 0x00, sizeof(bp_bookmark_info_fmt));
+ int ret = bp_bookmark_adaptor_get_info(local->id_list[i], b_offset, &(local->item_list[i]));
+ TRACE_DEBUG("[Local Deleted] id:%d url: %s sync: %s",local_delete_ids[i-start_idx], local->item_list[i].url, local->item_list[i].sync);
+ }
+ }
+}
+
+static void clear_bookmark_list(sync_bookmark_cloud_list *cloud, sync_bookmark_local_list *local)
+{
+ int i;
+
+ /* TODO
+ for (i = 0; i < local->count; i++) {
+ bp_bookmark_adaptor_easy_free(&_bookmark_local.item_list[i]);
+ }*/
+
+ if (local->count > 0){
+ free(local->id_list);
+ free(local->item_list);
+ free(local->mark);
+ }
+ if (cloud->count > 0 ){
+ free(cloud->item_list);
+ free(cloud->mark);
+ }
+
+ cloud->count = 0;
+ local->count = 0;
+}
+
+static void bookmark_init()
+{
+ bp_bookmark_adaptor_deinitialize();
+ bp_bookmark_adaptor_initialize();
+}
+
+static void bookmark_load(sync_bookmark_local_list* local, bool cold_start)
+{
+ bookmark_get_local(local);
+ if (cold_start){
+ bookmark_init_cold_start(local);
+ }
+ else
+ {
+ bookmark_get_deleted(local);
+ }
+}
+
+static void print_bookmark_log(sync_bookmark_cloud_list *cloud, sync_bookmark_local_list *local)
+{
+ LOCAL_LOOP_INIT(sync_bookmark_local_list,local);
+ LOCAL_LOOP(){PRINT_LOCAL_LOG();}
+
+ CLOUD_LOOP_INIT(sync_bookmark_cloud_list,cloud);
+ CLOUD_LOOP(){PRINT_CLOUD_LOG();}
+}
+
+static void do_bookmark_cb(sync_bookmark_cloud_list *cloud, sync_bookmark_local_list *local)
+{
+ find_bookmark_conflict(cloud,local); //1. Cloud Update/Delete vs. Local Update/Deleted
+ find_new_bookmark_local(local); //2. Local New Update -> Cloud
+ print_bookmark_log(cloud,local);
+ downsync_bookmark_update(cloud);
+ downsync_bookmark_delete(local);
+ upsync_bookmark_update(local);
+ upsync_bookmark_delete(local);
+}
+
+static int sync_bookmark_init(char* app_id, char* package_name)
+{
+ TRACE_DEBUG("");
+
+ int ret=-1;
+
+ cloud_set_bookmark_list(&_bookmark_cloud,&_bookmark_local);
+
+ ret = sync_init(app_id, package_name);
+
+ if (ret != 0) {
+ return -1;
+ }else{
+ return 0;
+ }
+}
+
+int bp_sync_bookmark()
+{
+ clear_bookmark_list(&_bookmark_cloud,&_bookmark_local);
+ bookmark_load(&_bookmark_local, IS_BOOKMARK_SYNC_COLD_START);
+ cloud_sync_bookmark(do_bookmark_cb);
+}
+
+int bp_sync_bookmark_login(char* guid, char* accesstoken, char* app_id, char* package_name)
+{
+ int ret = bp_sync_login(guid,accesstoken);
+ bookmark_init();
+ sync_bookmark_init(app_id, package_name);
+ cloud_bookmark_init();
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <browser-provider.h>
+#include <browser-provider-log.h>
+#include <stdbool.h>
+#include <web_bookmark.h>
+#include <iotcloud.h>
+#include <json.h>
+#include <glib.h>
+#include <sync-adaptor.h>
+#include <sync-adaptor-bookmark.h>
+#include <sync-adaptor-cloud.h>
+#include <sync-adaptor-cloud-json.h>
+
+static int bookmark_manifest_cn = 0;
+
+static void* __cloud_cb_bookmark_func = NULL;
+static void* __cloud_delete_bookmark_cb_func = NULL;
+
+sync_bookmark_local_list* __cloud_bookmark_local = NULL;
+sync_bookmark_cloud_list* __cloud_bookmark_cloud = NULL;
+
+static GSList *_bookmark_json = NULL;
+
+#define GET_BOOKMARK_JSON_STRING(json, key) \
+ _get_json_string(_bookmark_json, json, key)
+
+#define GET_BOOKMARK_JSON_INT(json, key) \
+ _get_json_int(_bookmark_json, json, key)
+
+#define GET_BOOKMARK_JSON_ARRAY(json, key, idx ) \
+ _get_json_array_object_by_idx(_bookmark_json, json, key, idx)
+
+#define GET_BOOKMARK_JSON_INIT(string_msg) \
+ _get_json_tokener_parse(_bookmark_json, string_msg)
+
+#define GET_BOOKMARK_JSON_ARRAY_COUNT(json, key) \
+ _get_json_array_length(_bookmark_json, json, key)
+
+
+
+static void cloud_bookmark_read_json_record(json_object *record_item, sync_bookmark_cloud_info_fmt *data){
+ TRACE_DEBUG("");
+
+ data->id = GET_BOOKMARK_JSON_STRING(record_item, "datauuid");
+ data->url = GET_BOOKMARK_JSON_STRING(record_item, "url");
+ data->title = GET_BOOKMARK_JSON_STRING(record_item, "title");
+ data->favicon_data = GET_BOOKMARK_JSON_STRING(record_item, "favicon_data");
+
+ if (data->favicon_data){
+ data->favicon_width = GET_BOOKMARK_JSON_INT(record_item, "favicon_width");
+ data->favicon_height = GET_BOOKMARK_JSON_INT(record_item, "favicon_height");
+ }else
+ {
+ data->favicon_width = NULL;
+ data->favicon_height = NULL;
+ }
+
+ char *bookmark_ctime_str = GET_BOOKMARK_JSON_STRING(record_item, "create_time");
+ char *bookmark_utime_str = GET_BOOKMARK_JSON_STRING(record_item, "update_time");
+
+ if (bookmark_ctime_str)
+ data->create_time = strtoll(bookmark_ctime_str, NULL, 10);
+
+ if (bookmark_utime_str)
+ data->update_time = strtoll(bookmark_utime_str, NULL, 10);
+}
+
+static int cloud_bookmark_new_json(json_object *my_object, sync_bookmark_cloud_list *list)
+{
+ int i = 0, cnt = 0;
+
+ char *bookmark_synctime_str = GET_BOOKMARK_JSON_STRING(my_object, "synced_timestamp");
+
+ if(bookmark_synctime_str == NULL) {
+ return 0;
+ }
+
+ int64_t bookmark_synctime = strtoll(bookmark_synctime_str, NULL, 10);
+ cnt = GET_BOOKMARK_JSON_ARRAY_COUNT(my_object, "records");
+ TRACE_DEBUG("Cloud Bookmark Count: %d last_synctime:%lld", cnt, bookmark_synctime);
+
+ list->count = cnt;
+ list->synctime = bookmark_synctime;
+ list->item_list = malloc(cnt*sizeof(sync_bookmark_cloud_info_fmt));
+ list->mark = malloc(cnt*sizeof(int));
+
+ for(i =0 ; i<cnt ; i++){
+ list->mark[i] = SYNC_UPDATE;
+ json_object *record_item = GET_BOOKMARK_JSON_ARRAY(my_object,"records",i);
+ cloud_bookmark_read_json_record(record_item,&(list->item_list[i]));
+ }
+
+ return cnt;
+}
+
+static int cloud_bookmark_update_json(json_object *my_object, sync_bookmark_cloud_list *list)
+{
+ TRACE_DEBUG("");
+
+ int i = 0, j = 0, cnt = 0;
+ char *id;
+
+ cnt = GET_BOOKMARK_JSON_ARRAY_COUNT(my_object, "records");
+
+ for(i =0 ; i<cnt ; i++){
+ json_object *record_item = GET_BOOKMARK_JSON_ARRAY(my_object, "records",i);
+ id = GET_BOOKMARK_JSON_STRING(record_item, "datauuid");
+
+ for (j = 0; j < list->count; j++){
+ if (strcmp(id,list->item_list[j].id) == 0){
+ cloud_bookmark_read_json_record(record_item,&(list->item_list[j]));
+ break;
+ }
+ }
+ }
+}
+
+static void cloud_bookmark_read(sync_bookmark_cloud_list* cloud_list, iotcloud_read_cb callback)
+{
+ TRACE_DEBUG("");
+
+ void* iotcloud_handle;
+ int i;
+ iotcloud_handle = iot_cloud_create(IOTCLOUD_READ, MANIFEST_ID_BOOKMARK, bookmark_manifest_cn);
+ for (i = 0; i < cloud_list->count; i++) {
+ if (cloud_list->mark[i] == SYNC_UPDATE){
+ iot_cloud_add_datauuid(iotcloud_handle,cloud_list->item_list[i].id);
+ }
+ }
+ iot_cloud_read(iotcloud_handle, callback);
+}
+
+static int cloud_bookmark_get_all( char* resp_msg_json)
+{
+ int i=0, cnt=0;
+
+ if (resp_msg_json == NULL){
+ return 0;
+ }
+
+ json_object *my_object = GET_BOOKMARK_JSON_INIT(resp_msg_json);
+
+ cnt = cloud_bookmark_new_json(my_object,__cloud_bookmark_cloud);
+ return cnt;
+}
+
+static bool cloud_write_cb(iot_error_e error, char* err_msg)
+{
+ void* iotcloud_handle;
+
+ if(error != IOT_ERROR_NONE)
+ {
+ TRACE_DEBUG("Error : %s", err_msg);
+ return false;
+ }
+ else
+ {
+ TRACE_DEBUG("Success");
+ return true;
+ }
+}
+
+/*
+static bool cloud_get_manifest_cb(iot_error_e error, char* resp_msg_json)
+{
+ TRACE_DEBUG("Response : %s", resp_msg_json);
+
+ json_object *my_object = json_tokener_parse(resp_msg_json);
+ save_bookmark_obj(my_object);
+ json_object *manifest_cn_obj = json_object_object_get(my_object, "manifest_cn");
+ save_bookmark_obj(manifest_cn_obj);
+ g_manifest_cn = json_object_get_int(manifest_cn_obj);
+
+ TRACE_DEBUG("g_manifest_cn : %d", g_manifest_cn);
+}
+*/
+
+static void cloud_bookmark_read_data(char* resp_msg_json)
+{
+ TRACE_DEBUG("Changes: %s", resp_msg_json);
+ if (resp_msg_json == NULL) {
+ __cloud_bookmark_cloud->count = 0;
+ return 0;
+ }
+
+ json_object *my_object = GET_BOOKMARK_JSON_INIT(resp_msg_json);
+
+ cloud_bookmark_update_json(my_object,__cloud_bookmark_cloud);
+}
+
+static bool cloud_bookmark_read_cb(iot_error_e error, char* resp_msg_json)
+{
+ cloud_bookmark_read_data(resp_msg_json);
+ ((bookmark_sync_cb)__cloud_cb_bookmark_func)(__cloud_bookmark_cloud,__cloud_bookmark_local);
+}
+
+static int cloud_bookmark_changes(sync_bookmark_cloud_list *list, char* resp_msg_json)
+{
+ TRACE_DEBUG("");
+
+ int i=0, cnt=0, ret_cnt=0;
+
+ if (resp_msg_json == NULL) {
+ list->count = 0;
+ TRACE_DEBUG("");
+ return 0;
+ }
+
+ json_object *my_object = GET_BOOKMARK_JSON_INIT(resp_msg_json);
+
+ cnt = GET_BOOKMARK_JSON_ARRAY_COUNT(my_object, "changes");
+
+ if (cnt == 0) {
+ list->count = 0;
+ TRACE_DEBUG("");
+ return 0;
+ }
+
+ char *bookmark_synctime_str = GET_BOOKMARK_JSON_STRING(my_object, "synced_timestamp");
+ int64_t bookmark_synctime = strtoll(bookmark_synctime_str, NULL, 10);
+ TRACE_DEBUG("Cloud Bookmark Count: %d last_synctime:%lld", cnt, bookmark_synctime);
+
+ list->count = cnt;
+ list->synctime = bookmark_synctime;
+ list->item_list = malloc(cnt*sizeof(sync_bookmark_cloud_info_fmt));
+ list->mark = malloc(cnt*sizeof(int));
+
+ for(i =0 ; i<cnt ; i++){
+ json_object *record_item = GET_BOOKMARK_JSON_ARRAY(my_object, "changes",i);
+ list->item_list[i].id = GET_BOOKMARK_JSON_STRING(record_item, "datauuid");
+ int action = GET_BOOKMARK_JSON_INT(record_item, "action");
+ char *update_time_str = GET_BOOKMARK_JSON_STRING(record_item, "update_time");
+ list->item_list[i].update_time = strtoll(update_time_str, NULL, 10);
+
+ TRACE_DEBUG("%s => action: %d",list->item_list[i].id,action);
+ if (action == 1){
+ list->mark[i] = SYNC_UPDATE;
+ ret_cnt++;
+ }
+ else if (action == 0){
+ list->mark[i] = SYNC_DELETE;
+ }
+ else {
+ list->mark[i] = SYNC_NONE;
+ }
+ }
+ return ret_cnt;
+}
+
+static bool cloud_bookmark_get_all_to_sync_cb(iot_error_e error, char* resp_msg_json)
+{
+ TRACE_DEBUG("Response : %s", resp_msg_json);
+ int cnt=0;
+ cnt = cloud_bookmark_get_all(resp_msg_json);
+
+ if (cnt == 0) __cloud_bookmark_cloud->count = 0;
+
+ ((bookmark_sync_cb)__cloud_cb_bookmark_func)(__cloud_bookmark_cloud,__cloud_bookmark_local);
+}
+
+static bool cloud_bookmark_changes_to_sync_cb(iot_error_e error, char* resp_msg_json)
+{
+ int updated_cnt = 0;
+ TRACE_DEBUG("Response : %s", resp_msg_json);
+ updated_cnt = cloud_bookmark_changes(__cloud_bookmark_cloud, resp_msg_json);
+ if (updated_cnt > 0){
+ cloud_bookmark_read(__cloud_bookmark_cloud, cloud_bookmark_read_cb);
+ }else{
+ ((bookmark_sync_cb)__cloud_cb_bookmark_func)(__cloud_bookmark_cloud,__cloud_bookmark_local);
+ }
+}
+
+static bool cloud_delete_bookmark_cb(iot_error_e error, char* resp_msg_json)
+{
+ TRACE_DEBUG("Response : %s", resp_msg_json);
+ int i = 0, fail_cnt = 0, result = 0;
+ char *id;
+
+ json_object *my_object = GET_BOOKMARK_JSON_INIT(resp_msg_json);
+
+ fail_cnt = GET_BOOKMARK_JSON_ARRAY_COUNT(my_object, "fails");
+
+ for(i =0 ; i<fail_cnt ; i++){ //fails
+ json_object *record_item = GET_BOOKMARK_JSON_ARRAY(my_object, "fails",i);
+ id = GET_BOOKMARK_JSON_STRING(record_item, "datauuid");
+ TRACE_DEBUG("Delete failed: %s", id);
+ }
+
+ if (fail_cnt > 0)
+ result = -1;
+ else
+ result = 0;
+
+ ((cloud_delete_bookmark_cb_func)__cloud_delete_bookmark_cb_func)(result); //TODO : add response information
+}
+
+void cloud_delete_bookmark(char* data_id, void *cb)
+{
+ __cloud_delete_bookmark_cb_func = cb;
+ iot_cloud_delete(MANIFEST_ID_BOOKMARK,data_id, cloud_delete_bookmark_cb);
+}
+
+void cloud_write_bookmark(char* id, char* url, char* title,
+ const char* favicon_data, int favicon_width, int favicon_height){
+ cloud_write(MANIFEST_ID_BOOKMARK, bookmark_manifest_cn, id, url, title, favicon_data, favicon_width, favicon_height);
+}
+
+static void cloud_get_all_sync_bookmark(void* cb)
+{
+ void* iotcloud_handle;
+ __cloud_cb_bookmark_func = cb;
+ iotcloud_handle = iot_cloud_create(IOTCLOUD_GET_ALL, MANIFEST_ID_BOOKMARK, bookmark_manifest_cn);
+ iot_cloud_get_all(iotcloud_handle, MANIFEST_ID_BOOKMARK, cloud_bookmark_get_all_to_sync_cb);
+}
+
+static void cloud_changes_sync_bookmark(void* cb)
+{
+ __cloud_cb_bookmark_func = cb;
+ iot_cloud_get_changes(MANIFEST_ID_BOOKMARK,__cloud_bookmark_cloud->synctime, NULL /*offset*/, NULL /*limit*/, cloud_bookmark_changes_to_sync_cb);
+}
+
+void cloud_sync_bookmark(void* cb)
+{
+ TRACE_DEBUG("");
+
+ if(_bookmark_json){
+ free_json(_bookmark_json);
+ }
+
+ //iot_cloud_get_manifest(MANIFEST_ID_BOOKMARK,1,cloud_get_manifest_cb);
+ TRACE_DEBUG("Last Synced Time:%lld",__cloud_bookmark_cloud->synctime);
+
+ if (__cloud_bookmark_cloud->synctime > 0){
+ cloud_changes_sync_bookmark(cb);
+ }else{
+ cloud_get_all_sync_bookmark(cb);
+ }
+}
+
+void cloud_set_bookmark_list(sync_bookmark_cloud_list* cloud, sync_bookmark_local_list* local)
+{
+ __cloud_bookmark_cloud = cloud;
+ __cloud_bookmark_local = local;
+}
+
+void cloud_bookmark_init()
+{
+ __cloud_bookmark_cloud->synctime = 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <json.h>
+
+static inline void add_obj(GSList * list, void* obj)
+{
+ list = g_slist_prepend(list,obj);
+}
+
+inline char* _get_json_string(GSList * list, json_object *record_item, char *key_name)
+{
+ json_object *obj = NULL;
+ char* ret_value = NULL;
+
+ obj = json_object_object_get(record_item, key_name);
+ if(!obj) return NULL;
+
+ add_obj(list,obj);
+ ret_value = json_object_get_string(obj);
+ return(ret_value);
+}
+
+inline int _get_json_int(GSList * list, json_object *record_item, char *key_name)
+{
+ json_object *obj = NULL;
+ int ret_value = 0;
+
+ obj = json_object_object_get(record_item, key_name);
+ if(!obj) return 0;
+
+ add_obj(list,obj);
+ ret_value = json_object_get_int(obj);
+ return(ret_value);
+}
+
+inline int _get_json_array_length(GSList * list, json_object *record_item, char *key_name)
+{
+ json_object *obj = NULL;
+ int ret_value = 0;
+
+ obj = json_object_object_get(record_item, key_name);
+
+ if(!obj) return 0;
+
+ add_obj(list,obj);
+ ret_value = json_object_array_length(obj);
+ return(ret_value);
+}
+
+inline json_object* _get_json_array_object_by_idx(GSList * list, json_object *record_item, char *key_name, int idx)
+{
+ json_object *obj = NULL;
+ json_object *ret_value = NULL;
+
+ obj = json_object_object_get(record_item, key_name);
+
+ if(!obj) return 0;
+
+ add_obj(list,obj);
+ ret_value = json_object_array_get_idx(obj,idx);
+ add_obj(list,ret_value);
+ return(ret_value);
+}
+
+inline json_object* _get_json_tokener_parse(GSList * list, char *msg)
+{
+ json_object *my_object = json_tokener_parse(msg);
+ add_obj(list, my_object);
+ return(my_object);
+}
+
+void free_json(GSList *obj_list)
+{
+ GSList *i;
+
+ if (g_slist_length (obj_list) > 0){
+
+ for(i = obj_list; i != NULL; i = i->next)
+ {
+ if (i->data) {
+ json_object_put((json_object *)i->data);
+ }
+ }
+
+ if (obj_list){
+ g_slist_free (obj_list);
+ obj_list = NULL;
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <browser-provider.h>
+#include <browser-provider-log.h>
+#include <stdbool.h>
+#include <web_tab.h>
+#include <iotcloud.h>
+#include <json.h>
+#include <glib.h>
+#include <sync-adaptor.h>
+#include <sync-adaptor-tab.h>
+#include <sync-adaptor-cloud.h>
+#include <sync-adaptor-cloud-json.h>
+
+static void* __cloud_cb_tab_func = NULL;
+static void* __cloud_delete_tab_cb_func = NULL;
+
+static int tab_manifest_cn = 0;
+
+sync_tab_local_list* __cloud_tab_local = NULL;
+sync_tab_cloud_list* __cloud_tab_cloud = NULL;
+
+static GSList *_tab_json = NULL;
+
+#define GET_TAB_JSON_STRING(json, key) \
+ _get_json_string(_tab_json, json, key)
+
+#define GET_TAB_JSON_INT(json, key) \
+ _get_json_int(_tab_json, json, key)
+
+#define GET_TAB_JSON_ARRAY(json, key, idx ) \
+ _get_json_array_object_by_idx(_tab_json, json, key, idx)
+
+#define GET_TAB_JSON_INIT(string_msg) \
+ _get_json_tokener_parse(_tab_json, string_msg)
+
+#define GET_TAB_JSON_ARRAY_COUNT(json, key) \
+ _get_json_array_length(_tab_json, json, key)
+
+static void cloud_tab_read_json_record(json_object *record_item, sync_tab_cloud_info_fmt *data){
+ TRACE_DEBUG("");
+
+ data->id = GET_TAB_JSON_STRING(record_item, "datauuid");
+ data->url = GET_TAB_JSON_STRING(record_item, "url");
+ data->title = GET_TAB_JSON_STRING(record_item, "title");
+ data->device_id = GET_TAB_JSON_STRING(record_item, "deviceuuid");
+
+ data->favicon_data = GET_TAB_JSON_STRING( record_item, "favicon_data");
+
+ if (data->favicon_data){
+ data->favicon_width = GET_TAB_JSON_INT(record_item, "favicon_width");
+ data->favicon_height = GET_TAB_JSON_INT(record_item, "favicon_height");
+ }else
+ {
+ data->favicon_width = NULL;
+ data->favicon_height = NULL;
+ }
+
+ char *tab_ctime_str = GET_TAB_JSON_STRING(record_item, "create_time");
+ char *tab_utime_str = GET_TAB_JSON_STRING(record_item, "update_time");
+
+ if (tab_ctime_str)
+ data->create_time = strtoll(tab_ctime_str, NULL, 10);
+
+ if (tab_utime_str)
+ data->update_time = strtoll(tab_utime_str, NULL, 10);
+}
+
+static int cloud_tab_new_json(json_object *my_object, sync_tab_cloud_list *list)
+{
+ int i = 0, cnt = 0;
+
+ char *tab_synctime_str = GET_TAB_JSON_STRING(my_object, "synced_timestamp");
+
+ if(tab_synctime_str == NULL) {
+ return 0;
+ }
+
+ int64_t tab_synctime = strtoll(tab_synctime_str, NULL, 10);
+ cnt = GET_TAB_JSON_ARRAY_COUNT(my_object, "records");
+
+ TRACE_DEBUG("Cloud Tab Count: %d last_synctime:%lld", cnt, tab_synctime);
+
+ list->count = cnt;
+ list->synctime = tab_synctime;
+ list->item_list = malloc(cnt*sizeof(sync_tab_cloud_info_fmt));
+ list->mark = malloc(cnt*sizeof(int));
+
+ for(i =0 ; i<cnt ; i++){
+ list->mark[i] = SYNC_UPDATE;
+ json_object *record_item = GET_TAB_JSON_ARRAY(my_object,"records",i);
+ cloud_tab_read_json_record(record_item,&(list->item_list[i]));
+ }
+
+ return cnt;
+}
+
+static int cloud_tab_update_json(json_object *my_object, sync_tab_cloud_list *list)
+{
+ TRACE_DEBUG("");
+
+ int i = 0, j = 0, cnt = 0;
+ char *id;
+
+ cnt = GET_TAB_JSON_ARRAY_COUNT(my_object, "records");
+
+ for(i =0 ; i<cnt ; i++){
+ json_object *record_item = GET_TAB_JSON_ARRAY(my_object, "records",i);
+ id = GET_TAB_JSON_STRING(record_item, "datauuid");
+
+ for (j = 0; j < list->count; j++){
+ if (strcmp(id,list->item_list[j].id) == 0){
+ cloud_tab_read_json_record(record_item,&(list->item_list[j]));
+ break;
+ }
+ }
+ }
+}
+
+static void cloud_tab_read(sync_tab_cloud_list* cloud_list, iotcloud_read_cb callback)
+{
+ TRACE_DEBUG("");
+
+ void* iotcloud_handle;
+ int i;
+ iotcloud_handle = iot_cloud_create(IOTCLOUD_READ, MANIFEST_ID_TAB, tab_manifest_cn);
+ for (i = 0; i < cloud_list->count; i++) {
+ if (cloud_list->mark[i] == SYNC_UPDATE){
+ iot_cloud_add_datauuid(iotcloud_handle,cloud_list->item_list[i].id);
+ }
+ }
+ iot_cloud_read(iotcloud_handle, callback);
+}
+
+static int cloud_tab_get_all( char* resp_msg_json)
+{
+ int i=0, cnt=0;
+
+ if (resp_msg_json == NULL){
+ return 0;
+ }
+
+ json_object *my_object = GET_TAB_JSON_INIT(resp_msg_json);
+
+ cnt = cloud_tab_new_json(my_object,__cloud_tab_cloud);
+ return cnt;
+}
+
+static void cloud_tab_read_data(char* resp_msg_json)
+{
+ TRACE_DEBUG("Changes: %s", resp_msg_json);
+ if (resp_msg_json == NULL) {
+ __cloud_tab_cloud->count = 0;
+ return 0;
+ }
+
+ json_object *my_object = GET_TAB_JSON_INIT(resp_msg_json);
+
+ cloud_tab_update_json(my_object,__cloud_tab_cloud);
+}
+
+static bool cloud_tab_read_cb(iot_error_e error, char* resp_msg_json)
+{
+ cloud_tab_read_data(resp_msg_json);
+ ((tab_sync_cb)__cloud_cb_tab_func)(__cloud_tab_cloud,__cloud_tab_local);
+}
+
+static int cloud_tab_changes(sync_tab_cloud_list *list, char* resp_msg_json)
+{
+ TRACE_DEBUG("");
+
+ int i=0, cnt=0, ret_cnt=0;
+
+ if (resp_msg_json == NULL) {
+ list->count = 0;
+ TRACE_DEBUG("");
+ return 0;
+ }
+
+ json_object *my_object = GET_TAB_JSON_INIT(resp_msg_json);
+
+ cnt = GET_TAB_JSON_ARRAY_COUNT(my_object, "changes");
+
+ if (cnt == 0) {
+ list->count = 0;
+ TRACE_DEBUG("");
+ return 0;
+ }
+
+ char *tab_synctime_str = GET_TAB_JSON_STRING(my_object, "synced_timestamp");
+ int64_t tab_synctime = strtoll(tab_synctime_str, NULL, 10);
+ TRACE_DEBUG("Cloud Tab Count: %d last_synctime:%lld", cnt, tab_synctime);
+
+ list->count = cnt;
+ list->synctime = tab_synctime;
+ list->item_list = malloc(cnt*sizeof(sync_tab_cloud_info_fmt));
+ list->mark = malloc(cnt*sizeof(int));
+
+ for(i =0 ; i<cnt ; i++){
+ json_object *record_item = GET_TAB_JSON_ARRAY(my_object, "changes",i);
+ list->item_list[i].id = GET_TAB_JSON_STRING(record_item, "datauuid");
+ int action = GET_TAB_JSON_INT(record_item, "action");
+ char *update_time_str = GET_TAB_JSON_STRING(record_item, "update_time");
+ list->item_list[i].update_time = strtoll(update_time_str, NULL, 10);
+ TRACE_DEBUG("%s => action: %d",list->item_list[i].id,action);
+ if (action == 1){
+ list->mark[i] = SYNC_UPDATE;
+ ret_cnt++;
+ }
+ else if (action == 0){
+ list->mark[i] = SYNC_DELETE;
+ }
+ else {
+ list->mark[i] = SYNC_NONE;
+ }
+ }
+ return ret_cnt;
+}
+
+static bool cloud_delete_tab_cb(iot_error_e error, char* resp_msg_json)
+{
+ TRACE_DEBUG("Response : %s", resp_msg_json);
+ int i = 0, fail_cnt = 0, result = 0;
+ char *id;
+
+ json_object *my_object = GET_TAB_JSON_INIT(resp_msg_json);
+
+ fail_cnt = GET_TAB_JSON_ARRAY_COUNT(my_object, "fails");
+
+ for(i =0 ; i<fail_cnt ; i++){ //fails
+ json_object *record_item = GET_TAB_JSON_ARRAY(my_object, "fails",i);
+ id = GET_TAB_JSON_STRING(record_item, "datauuid");
+ TRACE_DEBUG("Delete failed: %s", id);
+ }
+
+ if (fail_cnt > 0)
+ result = -1;
+ else
+ result = 0;
+
+ ((cloud_delete_tab_cb_func)__cloud_delete_tab_cb_func)(result); //TODO : add response information
+}
+
+void cloud_delete_tab(char* data_id, void *cb)
+{
+ __cloud_delete_tab_cb_func = cb;
+ iot_cloud_delete(MANIFEST_ID_TAB, data_id, cloud_delete_tab_cb);
+}
+
+void cloud_write_tab(char* id, char* url, char* title,
+ const char* favicon_data, int favicon_width, int favicon_height){
+ cloud_write(MANIFEST_ID_TAB, tab_manifest_cn, id, url, title, favicon_data, favicon_width, favicon_height);
+}
+
+static bool cloud_tab_get_all_to_sync_cb(iot_error_e error, char* resp_msg_json)
+{
+ TRACE_DEBUG("Response : %s", resp_msg_json);
+ int cnt=0;
+ cnt = cloud_tab_get_all(resp_msg_json);
+
+ if (cnt == 0) __cloud_tab_cloud->count = 0;
+
+ ((tab_sync_cb)__cloud_cb_tab_func)(__cloud_tab_cloud,__cloud_tab_local);
+}
+
+static bool cloud_tab_changes_to_sync_cb(iot_error_e error, char* resp_msg_json)
+{
+ int updated_cnt = 0;
+ TRACE_DEBUG("Response : %s", resp_msg_json);
+ updated_cnt = cloud_tab_changes(__cloud_tab_cloud, resp_msg_json);
+ if (updated_cnt > 0){
+ cloud_tab_read(__cloud_tab_cloud, cloud_tab_read_cb);
+ }else{
+ ((tab_sync_cb)__cloud_cb_tab_func)(__cloud_tab_cloud,__cloud_tab_local);
+ }
+}
+
+static void cloud_get_all_sync_tab(void* cb)
+{
+ TRACE_DEBUG("");
+
+ void* iotcloud_handle;
+ __cloud_cb_tab_func = cb;
+ iotcloud_handle = iot_cloud_create(IOTCLOUD_GET_ALL, MANIFEST_ID_TAB, tab_manifest_cn);
+ iot_cloud_get_all(iotcloud_handle, MANIFEST_ID_TAB, cloud_tab_get_all_to_sync_cb);
+}
+
+static void cloud_changes_sync_tab(void* cb)
+{
+ __cloud_cb_tab_func = cb;
+ iot_cloud_get_changes(MANIFEST_ID_TAB,__cloud_tab_cloud->synctime, NULL /*offset*/, NULL /*limit*/, cloud_tab_changes_to_sync_cb);
+}
+
+void cloud_sync_tab(void* cb)
+{
+ TRACE_DEBUG("");
+
+ if(_tab_json){
+ TRACE_DEBUG("");
+ free_json(_tab_json);
+ }
+
+ cloud_get_all_sync_tab(cb);
+}
+
+void cloud_set_tab_list(sync_tab_cloud_list* cloud, sync_tab_local_list* local)
+{
+ __cloud_tab_cloud = cloud;
+ __cloud_tab_local = local;
+}
+
+void cloud_tab_init(void)
+{
+ __cloud_tab_cloud->synctime=0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <browser-provider.h>
+#include <browser-provider-log.h>
+#include <stdbool.h>
+#include <iotcloud.h>
+#include <glib.h>
+#include <sync-adaptor.h>
+#include <sync-adaptor-cloud.h>
+
+static int g_cloud_init = 0;
+
+char* __cloud_device_id = NULL;
+
+static bool cloud_write_cb(iot_error_e error, char* err_msg)
+{
+ void* iotcloud_handle;
+
+ if(error != IOT_ERROR_NONE)
+ {
+ TRACE_DEBUG("Error : %s", err_msg);
+ return false;
+ }
+ else
+ {
+ TRACE_DEBUG("Success");
+ return true;
+ }
+}
+
+void cloud_write(char* manifest_id, int manifest_cn, char* id, char* url, char* title,
+ const char* favicon_data, int favicon_width, int favicon_height)
+{
+ TRACE_DEBUG("");
+ void* iotcloud_handle;
+ iotcloud_handle = iot_cloud_create(IOTCLOUD_CREATE_UPDATE, manifest_id, manifest_cn);
+
+ if(url == NULL)
+ return;
+ else
+ iot_cloud_add_message(iotcloud_handle, id, __cloud_device_id, "url", (void*)url, KEYVAL_STRING);
+
+ if(title != NULL)
+ iot_cloud_add_message(iotcloud_handle, id, __cloud_device_id, "title", (void*)title, KEYVAL_STRING);
+
+ TRACE_DEBUG("");
+ if(favicon_data != NULL && favicon_width > 0 && favicon_height > 0){
+ iot_cloud_add_message(iotcloud_handle, id, __cloud_device_id, "favicon_data", (void*)favicon_data, KEYVAL_BLOB);
+ iot_cloud_add_message(iotcloud_handle, id, __cloud_device_id, "favicon_width", (void*)&favicon_width, KEYVAL_INT);
+ iot_cloud_add_message(iotcloud_handle, id, __cloud_device_id, "favicon_height", (void*)&favicon_height, KEYVAL_INT);
+ }
+ iot_cloud_write(iotcloud_handle, cloud_write_cb);
+}
+
+int cloud_login(char* guid, char* accesstoken)
+{
+ TRACE_DEBUG("");
+
+ return(iot_cloud_set_credential(guid, accesstoken));
+}
+
+int cloud_init(char* device_id, char* app_id, char* app_package_name)
+{
+ TRACE_DEBUG("");
+
+ int ret = 0;
+ if (g_cloud_init == 1){
+ TRACE_DEBUG("Already called iot_cloud_init, just return");
+ return 0;
+ }
+ __cloud_device_id = device_id;
+
+ ret = iot_cloud_init(app_id, app_package_name, __cloud_device_id);
+ if (ret != 0 /*IOT_ERROR_NONE*/) {
+ TRACE_ERROR("iot_cloud_init failed %d", ret);
+ return -1;
+ }
+
+ g_cloud_init = 1;
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <web_tab.h>
+#include <browser-provider.h>
+#include <browser-provider-log.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <sync-adaptor.h>
+#include <sync-adaptor-tab.h>
+#include <sync-adaptor-cloud.h>
+
+static sync_tab_local_list _tab_local;
+static sync_tab_cloud_list _tab_cloud;
+
+static find_new_tab_local(sync_tab_local_list *local)
+{
+ TRACE_DEBUG("");
+
+ LOCAL_LOOP_INIT(sync_tab_local_list,local);
+
+ LOCAL_LOOP(){
+ if (IS_LOCAL_NORMAL() && IS_MADE_BY_LOCAL()){
+ UPSYNC_NEW_LOCAL();
+ }
+ }
+}
+
+static int tab_get_favicon(int id, int *width, int *height, const char **encoded_data)
+{
+ unsigned char *favicon_data = NULL;
+ int len = 0;
+ int ret = bp_tab_adaptor_get_icon(id, width, height, (unsigned char **)&favicon_data, &len);
+ if (ret < 0) {
+ TRACE_DEBUG("bp_tab_adaptor_get_icon is failed");
+ return -1;
+ }else{
+ *encoded_data = (const char *)g_base64_encode((const guchar *)favicon_data, (gsize) len);
+ TRACE_DEBUG("bp_tab_adaptor_get_icon (len:%d, %d x %d)", len, *width, *height);
+ return 1;
+ }
+}
+
+static void downsync_others_tab(sync_tab_cloud_list* list)
+{
+ TRACE_DEBUG("");
+
+ int i;
+ for (i = 0; i < list->count; i++) {
+ if(list->mark[i] == SYNC_UPDATE
+ && strcmp(list->item_list[i].device_id, get_device_id()) != 0)
+ {
+ char *id = list->item_list[i].id; //for sync_value
+ char *url = list->item_list[i].url;
+ char *title = list->item_list[i].title;
+ char *device_id = list->item_list[i].device_id;
+ char *favicon_data = list->item_list[i].favicon_data;
+ int favicon_width = list->item_list[i].favicon_width;
+ int favicon_height = list->item_list[i].favicon_height;
+
+ TRACE_DEBUG("Others Tab [%s] %s %s %s",id,device_id,url,title);
+ //TODO : update tab list of other devices (url, title, id, favicon_data, favicon_width, favicon_height);
+ }
+ }
+}
+
+static void upsync_tab_update(sync_tab_local_list *list)
+{
+ TRACE_DEBUG("");
+
+ int i;
+ char *id;
+ id = malloc(SYNC_CLOUD_ID_MAX_LENGTH);
+ for (i = 0; i < list->count; i++) {
+ if(list->mark[i] == SYNC_UPDATE){
+ memset(id,0x00,SYNC_CLOUD_ID_MAX_LENGTH);
+ //use tab 'sync' value to keep tracking ID on cloud
+ if (list->item_list[i].sync == NULL){
+ sprintf(id,"%d%s",list->id_list[i],get_device_id()); //new ID
+ list->item_list[i].sync = id;
+ bp_tab_adaptor_set_sync(list->id_list[i],id);
+ }else{
+ sprintf(id,"%s",list->item_list[i].sync); // used ID
+ }
+ char *url = list->item_list[i].url;
+ char *title = list->item_list[i].title;
+ TRACE_DEBUG("UPDATE Cloud [%s] %s",id,url);
+
+ const char *encoded_data = NULL;
+ int w = 0;
+ int h = 0;
+ if (tab_get_favicon(list->id_list[i], &w, &h, &encoded_data) > 0)
+ {
+ cloud_write_tab(id, url, title, encoded_data, w, h);
+ }
+ }
+ }
+ free(id);
+}
+
+static void upsync_tab_delete_cb(int result)
+{
+ if (result < 0)
+ TRACE_DEBUG("DELETED failed");//TODO
+ else
+ TRACE_DEBUG("DELETED succeeded");
+}
+
+static void upsync_tab_delete(sync_tab_local_list* local)
+{
+ TRACE_DEBUG("");
+
+ int i = 0, cnt = 0;;
+ for (i = 0; i < local->count; i++) {
+ if(local->mark[i] == SYNC_DELETED_UPSYNC && local->item_list[i].sync != NULL){
+ TRACE_DEBUG("DELETE Cloud [%d/%d] mark:%d sync:%s",i,local->count,local->mark[i],local->item_list[i].sync);
+ cloud_delete_tab(local->item_list[i].sync,upsync_tab_delete_cb);
+ cnt++;
+ }
+ }
+ if (cnt > 0)
+ {
+ bp_tab_adaptor_clear_deleted_ids();
+ }
+}
+
+static void tab_get_local(sync_tab_local_list* list)
+{
+ int *ids = NULL;
+ int ids_count = 0;
+ int i = 0;
+ char * * url;
+ char * * title;
+ bp_tab_adaptor_get_full_ids_p(&ids, &ids_count);
+
+ list->count = ids_count;
+ list->id_list = malloc(ids_count*sizeof(int));
+ list->item_list = malloc(ids_count*sizeof(bp_tab_info_fmt));
+ list->mark = malloc(ids_count*sizeof(int));
+ for (i = 0; i < ids_count; i++) {
+ list->mark[i] = SYNC_NONE;
+ list->id_list[i] = ids[i];
+
+ unsigned int b_offset = (BP_TAB_O_DATE_CREATED | BP_TAB_O_DATE_MODIFIED | BP_TAB_O_URL | BP_TAB_O_TITLE | BP_TAB_O_SYNC );
+ memset(&(list->item_list[i]), 0x00, sizeof(bp_tab_info_fmt));
+ int ret = bp_tab_adaptor_get_info(list->id_list[i], b_offset, &(list->item_list[i]));
+ TRACE_DEBUG("[Local tab] id:%d title: %s url: %s sync: %s, created: %d, modified: %d",ids[i],
+ list->item_list[i].title, list->item_list[i].url, list->item_list[i].sync,
+ list->item_list[i].date_created, list->item_list[i].date_modified);
+ }
+ free(ids);
+}
+
+static void tab_get_deleted(sync_tab_local_list* local)
+{
+ int deleted_count = 0;
+ int i = 0, start_idx = 0;
+ int value;
+ char * * url;
+ char * * title;
+ int *local_delete_ids = NULL;
+
+ start_idx = local->count;
+ bp_tab_adaptor_get_deleted_ids_p(&local_delete_ids,&deleted_count);
+ TRACE_DEBUG("[Local tab Deleted] cnt:%d", deleted_count);
+
+ if(deleted_count > 0 && start_idx > 0){
+ local->count += deleted_count;
+ local->id_list = realloc(local->id_list, local->count*sizeof(int));
+ local->item_list = realloc(local->item_list, local->count*sizeof(bp_tab_info_fmt));
+ local->mark = realloc(local->mark, local->count*sizeof(int));
+ }else if (deleted_count > 0 && start_idx == 0){
+ local->count = deleted_count;
+ local->id_list = malloc(deleted_count*sizeof(int));
+ local->item_list = malloc(deleted_count*sizeof(bp_tab_info_fmt));
+ local->mark = malloc(deleted_count*sizeof(int));
+ }
+
+ for (i=start_idx; i < (start_idx + deleted_count); i++)
+ {
+ local->mark[i] = SYNC_DELETED_UPSYNC;
+ local->id_list[i] = local_delete_ids[i-start_idx];
+ unsigned int b_offset = (BP_TAB_O_DATE_CREATED | BP_TAB_O_DATE_MODIFIED | BP_TAB_O_URL | BP_TAB_O_TITLE | BP_TAB_O_SYNC );
+ memset(&(local->item_list[i]), 0x00, sizeof(bp_tab_info_fmt));
+ int ret = bp_tab_adaptor_get_info(local->id_list[i], b_offset, &(local->item_list[i]));
+ TRACE_DEBUG("[Local tab Deleted] id:%d url: %s sync: %s",local_delete_ids[i-start_idx], local->item_list[i].url, local->item_list[i].sync);
+ }
+}
+
+static void clear_tab_list(sync_tab_cloud_list *cloud, sync_tab_local_list *local)
+{
+ TRACE_DEBUG("");
+
+ int i;
+
+ if (local->count > 0){
+ TRACE_DEBUG("");
+ free(local->id_list);
+ free(local->item_list);
+ free(local->mark);
+ }
+ if (cloud->count > 0 ){
+ TRACE_DEBUG("");
+ free(cloud->item_list);
+ free(cloud->mark);
+ }
+
+ cloud->count = 0;
+ local->count = 0;
+}
+
+static void tab_init()
+{
+ bp_tab_adaptor_deinitialize();
+ bp_tab_adaptor_initialize();
+}
+
+static void tab_load(sync_tab_local_list* local)
+{
+ TRACE_DEBUG("");
+
+ tab_get_local(local);
+ tab_get_deleted(local);
+}
+
+static void print_tab_log(sync_tab_cloud_list *cloud, sync_tab_local_list *local)
+{
+ LOCAL_LOOP_INIT(sync_tab_local_list,local);
+ LOCAL_LOOP(){PRINT_LOCAL_LOG();}
+
+ CLOUD_LOOP_INIT(sync_tab_cloud_list,cloud);
+ CLOUD_LOOP(){PRINT_CLOUD_LOG();}
+}
+
+static void do_tab_cb(sync_tab_cloud_list *cloud, sync_tab_local_list *local)
+{
+ find_new_tab_local(local);
+ print_tab_log(cloud,local);
+ upsync_tab_update(local);
+ upsync_tab_delete(local);
+ downsync_others_tab(cloud);
+}
+
+static int sync_tab_init(char* app_id, char* package_name)
+{
+ int ret=-1;
+
+ cloud_set_tab_list(&_tab_cloud,&_tab_local);
+
+ ret = sync_init(app_id, package_name);
+
+ if (ret != 0) {
+ return -1;
+ }else{
+ return 0;
+ }
+}
+
+int bp_sync_tab()
+{
+ TRACE_DEBUG("");
+ clear_tab_list(&_tab_cloud,&_tab_local);
+ tab_load(&_tab_local);
+ cloud_sync_tab(do_tab_cb);
+}
+
+int bp_sync_tab_login(char* guid, char* accesstoken, char* app_id, char* package_name)
+{
+ int ret = bp_sync_login(guid,accesstoken);
+ tab_init();
+ sync_tab_init(app_id,package_name);
+ cloud_tab_init();
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <browser-provider.h>
+#include <browser-provider-log.h>
+#include <net/if.h>
+#include <netinet/ether.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <glib.h>
+#include <sync-adaptor.h>
+#include <sync-adaptor-cloud.h>
+
+static char *_device_id = NULL;
+
+static int is_login = SYNC_LOGOUT;
+
+static void int_to_char(int64_t num, char* string)
+{
+ int m=1;
+ int index=0;
+ char str[20]={0,};
+ if(num == 0)
+ {
+ *string = '0';
+ return;
+ }
+ while(num>0)
+ {
+ *(str+index)=num%10+'0';
+ index++;
+ num=num/10;
+ }
+ index--;
+ m = index;
+ while(m>=0)
+ {
+ *(string+m) = *(str+(index-m));
+ m--;
+ }
+}
+
+static void conv_mac( const char *data, char *cvrt_str, int sz )
+{
+ static char buf[128] = {0x00,};
+ char t_buf[8];
+ char *stp = strtok( (char *)data , ":" );
+ int temp=0;
+ do
+ {
+ memset( t_buf, 0x0, sizeof(t_buf) );
+ sscanf( stp, "%x", &temp );
+ snprintf( t_buf, sizeof(t_buf)-1, "%02X", temp );
+ strncat( buf, t_buf, sizeof(buf)-1 );
+ strncat( buf, ":", sizeof(buf)-1 );
+ } while( (stp = strtok( NULL , ":" )) != NULL );
+ buf[strlen(buf) -1] = '\0';
+ strncpy( cvrt_str, buf, sz );
+}
+
+static char *get_mac()
+{
+ int r, iter;
+ int sk;
+ struct ifreq ifr;
+ char *mac;
+ char *interface_string[2];
+ interface_string[0] = "eth0";
+ interface_string[1] = "wlan0";
+ sk = socket(AF_INET, SOCK_STREAM, 0);
+ if (sk == -1) {
+ TRACE_ERROR("socket() failed(%s)", strerror(errno));
+ return NULL;
+ }
+ for (iter = 0; iter<2; iter++)
+ {
+ strcpy(ifr.ifr_name, interface_string[iter]);
+ r = ioctl(sk, SIOCGIFHWADDR, &ifr);
+
+ if (r==0)
+ {
+ TRACE_INFO("interface %s found", interface_string[iter]);
+ break;
+ }
+ }
+ close(sk);
+ if (r < 0) {
+ TRACE_ERROR("ioctl failed(%d)", r);
+ return NULL;
+ }
+ mac = (char*)calloc(20, sizeof(char));
+ memset(mac, 0x00,20);
+ if (!mac) {
+ TRACE_ERROR("calloc() failed");
+ return NULL;
+ }
+ conv_mac(ether_ntoa((struct ether_addr *)(ifr.ifr_hwaddr.sa_data)), mac, 20);
+ TRACE_INFO("mac [%s]", mac);
+ return mac;
+}
+
+static char *_get_device_info(void)
+{
+ char* dev_info = NULL;
+ dev_info = get_mac();
+ return dev_info;
+}
+
+int bp_sync_is_login(void)
+{
+ if (is_login == SYNC_LOGIN)
+ return 1;
+ else
+ return 0;
+}
+
+int bp_sync_login(char* guid, char* accesstoken)
+{
+ int ret = 0;
+ TRACE_DEBUG("guid:%s ,accesstoken:%s",guid,accesstoken);
+
+ ret = cloud_login(guid, accesstoken);
+ if(ret != 0){
+ TRACE_DEBUG("Error!");
+ is_login = SYNC_LOGOUT;
+ return -1;
+ }
+ is_login = SYNC_LOGIN;
+
+ return 0;
+}
+
+int bp_sync_logout()
+{
+ is_login = 0;
+
+ return 0;
+}
+
+int sync_init(char* app_id, char* app_package_name)
+{
+ int ret=-1;
+ _device_id = _get_device_info();
+ TRACE_DEBUG("Device ID %s",_device_id);
+ ret = cloud_init(_device_id, app_id, app_package_name);
+
+ if (ret != 0) {
+ TRACE_ERROR("cloud init failed %d", ret);
+ return -1;
+ }else{
+ return 0;
+ }
+}
+
+char* get_device_id(){
+ return _device_id;
+}
+
BuildRequires: cmake
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(sqlite3)
-#BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(glib-2.0)
#BuildRequires: pkgconfig(gobject-2.0)
#BuildRequires: pkgconfig(ecore)
#BuildRequires: pkgconfig(edbus)
BuildRequires: pkgconfig(cynara-session)
BuildRequires: pkgconfig(openssl)
+%define _cloud_sync_enabled ON
+%if %{?_cloud_sync_enabled} == ON
+BuildRequires: pkgconfig(iotcloud)
+BuildRequires: pkgconfig(notification)
+BuildRequires: pkgconfig(json-c)
+%endif
+
%define _data_install_path /opt/usr/data/%{name}
%define _resource_install_path /opt/data/%{name}
%define _notifydir %{_data_install_path}/notify
%define _ipc_socket %{_resource_install_path}/%{name}.sock
%define _license_path /usr/share/license
-%define _cloud_pdm_server /usr/bin/cloud-pdm-server
%description
Description: sync in background
-DPKG_VERSION=%{version} \\\
-DPKG_RELEASE=%{release} \\\
-DPKG_LICENSE_PATH:PATH=%{_license_path} \\\
- -DCLOUD_PDM_SERVER:PATH=%{_cloud_pdm_server} \\\
-DPROVIDER_DIR:PATH=%{_data_install_path} \\\
-DDATABASE_DIR:PATH=%{_databasedir} \\\
-DNOTIFY_DIR:PATH=%{_notifydir} \\\
-DSUPPORT_LOG_MESSAGE:BOOL=ON \\\
-DSUPPORT_FILE_LOGGING:BOOL=OFF \\\
-DSUPPORT_SERVER_PRIVILEGE:BOOL=ON \\\
+ -DSUPPORT_CLOUD_SYNC:BOOL=%{_cloud_sync_enabled} \\\
%if "%{?_lib}" == "lib64" \
%{?_cmake_lib_suffix64} \\\
%endif \
break;
}
#endif
+#ifdef SUPPORT_CLOUD_SYNC
+ TRACE_DEBUG("client->type: %d",client->type);
+ if (client->type == BP_CLIENT_BOOKMARK_SYNC) {
+ TRACE_DEBUG("BP_CLIENT_BOOKMARK_SYNC");
+ errorcode = __bp_bookmark_set_is_deleted_no_care_child(sock, id);
+ break;
+ }
+#endif
errorcode = __bp_bookmark_delete_no_care_child(sock, id);
break;
break;
}
#endif
+#ifdef SUPPORT_CLOUD_SYNC
+ TRACE_DEBUG("client->type: %d",client->type);
+ if (client->type == BP_CLIENT_BOOKMARK_SYNC) {
+ TRACE_DEBUG("BP_CLIENT_BOOKMARK_SYNC");
+ errorcode = __bp_bookmark_set_is_deleted(sock, id);
+ break;
+ }
+#endif
+
errorcode = __bp_bookmark_delete(sock, id);
break;
break;
}
#endif
+#ifdef SUPPORT_CLOUD_SYNC
+ TRACE_DEBUG("client->type: %d",client->type);
+ if (client->type == BP_CLIENT_BOOKMARK_SYNC) {
+ TRACE_DEBUG("BP_CLIENT_BOOKMARK_SYNC");
+ errorcode = __bp_bookmark_delete_all_childs(WEB_BOOKMARK_ROOT_ID, 0);
+ bp_ipc_send_errorcode(sock, errorcode);
+ break;
+ }
+#endif
+
errorcode = __bp_bookmark_reset(sock);
}
break;
}
#endif
+#ifdef SUPPORT_CLOUD_SYNC
+ if (client->type == BP_CLIENT_TABS_SYNC) {
+ errorcode = bp_common_set_is_deleted
+ (g_db_handle, &g_db_mutex, BP_DB_TABLE_TABS, sock, id);
+ break;
+ }
+#endif
+
errorcode = bp_common_delete
(g_db_handle, &g_db_mutex, BP_DB_TABLE_TABS, sock, id);
break;
SET(PC_REQUIRED "dlog libpng")
+IF(SUPPORT_CLOUD_SYNC)
+ SET(PC_REQUIRED "dlog libpng iotcloud notification json-c glib-2.0")
+ENDIF(SUPPORT_CLOUD_SYNC)
+
INCLUDE(FindPkgConfig)
pkg_check_modules(tab_adaptor_pkgs REQUIRED ${PC_REQUIRED})
ADD_DEFINITIONS(-DBROWSER_PROVIDER_LOG_TAG=\"TAB_ADAPTOR\")
-ADD_LIBRARY(${PROJECT_NAME} SHARED
+SET(BP_TAB_ADAPTOR_SOURCES
${CMAKE_SOURCE_DIR}/common-adaptor/common-adaptor.c
${CMAKE_SOURCE_DIR}/common-adaptor/common-adaptor-png.c
${CMAKE_SOURCE_DIR}/provider/browser-provider-socket.c
${CMAKE_SOURCE_DIR}/provider/browser-provider-shm.c
${CMAKE_CURRENT_SOURCE_DIR}/tab-adaptor.c )
+
+IF(SUPPORT_CLOUD_SYNC)
+ LIST(APPEND BP_TAB_ADAPTOR_SOURCES
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-tab.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-cloud-tab.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-cloud.c
+ ${CMAKE_SOURCE_DIR}/common-adaptor/sync-adaptor-cloud-json.c)
+ENDIF(SUPPORT_CLOUD_SYNC)
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${BP_TAB_ADAPTOR_SOURCES})
+
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${tab_adaptor_pkgs_LDFLAGS} ${TAB_LINK_LIBRARIES})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${PKG_VERSION})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0)
/**
* @}
*/
+EXPORT_API int bp_sync_tab_login(char* guid, char* accesstoken, char* app_id, char* package_name);
+EXPORT_API int bp_sync_tab(void);
#ifdef __cplusplus
}
#include <browser-provider-db-defs.h>
#include <browser-provider-socket.h>
+#ifdef SUPPORT_CLOUD_SYNC
+#include <sync-adaptor.h>
+#include <sync-adaptor-tab.h>
+#endif
+
static bp_adaptor_defs *g_adaptorinfo = NULL;
static pthread_mutex_t g_adaptor_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t g_adaptor_event_thread_pid = 0;
if (bp_common_adaptor_is_sync_adaptor() == 0)
client_type = BP_CLIENT_TABS_SYNC;
#endif
+#ifdef SUPPORT_CLOUD_SYNC
+ if (bp_sync_is_login()){
+ client_type = BP_CLIENT_TABS_SYNC;
+ }
+#endif
if (bp_common_adaptor_connect_to_provider(&g_adaptorinfo,
client_type) < 0) {
bp_tab_adaptor_set_snapshot(*id, info->thumbnail_width,
info->thumbnail_height, info->thumbnail, info->thumbnail_length);
}
+
+#ifdef SUPPORT_CLOUD_SYNC
+ if (info->sync != NULL) {
+ bp_tab_adaptor_set_sync(*id, info->sync);
+ }
+#endif
+
return 0;
}