diff options
author | jk7744.park <jk7744.park@samsung.com> | 2015-10-26 15:42:38 +0900 |
---|---|---|
committer | jk7744.park <jk7744.park@samsung.com> | 2015-10-26 15:42:38 +0900 |
commit | d230b507036b9ed162a99fdb4a4d73be96a9f6f2 (patch) | |
tree | 17f1627fc49cd47fe655075810e186730e9423d9 /src | |
parent | 1dea8054d0390b29fd9f052f666f12b02c61bffb (diff) | |
download | sync-manager-d230b507036b9ed162a99fdb4a4d73be96a9f6f2.tar.gz sync-manager-d230b507036b9ed162a99fdb4a4d73be96a9f6f2.tar.bz2 sync-manager-d230b507036b9ed162a99fdb4a4d73be96a9f6f2.zip |
tizen 2.4 releasetizen_2.4_mobile_releasesubmit/tizen_2.4/20151028.063459accepted/tizen/2.4/mobile/20151029.035010
Diffstat (limited to 'src')
55 files changed, 9055 insertions, 0 deletions
diff --git a/src/sync-client/CMakeLists.txt b/src/sync-client/CMakeLists.txt new file mode 100644 index 0000000..dfc0371 --- /dev/null +++ b/src/sync-client/CMakeLists.txt @@ -0,0 +1,119 @@ +# Copyright (c) 2013 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. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT("core-sync-client") + +SET(this_target "core-sync-client") + +IF(NOT DEFINED PACKAGE_NAME) + SET(PACKAGE_NAME "core-sync-client") +ENDIF(NOT DEFINED PACKAGE_NAME) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(LIBDIR "${PREFIX}/lib") +SET(INCLUDEDIR "${PREFIX}/include") +SET(VERSION_MAJOR 1) +SET(FULLVER "${VERSION_MAJOR}.0") + +IF(NOT DEFINED SYSTEMD_DIR) + SET(SYSTEMD_DIR "/usr/lib/systemd/system") +ENDIF(NOT DEFINED SYSTEMD_DIR) + +INCLUDE_DIRECTORIES( + ./ + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/common + ) + +SET(SRCS sync_manager.c sync_adapter.c ${CMAKE_SOURCE_DIR}/common/sync-ipc-marshal.c +) + +SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/cmake_build_tmp/output) + +ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE_NAME}\"") + +INCLUDE(FindPkgConfig) +pkg_check_modules(PKGS REQUIRED + capi-system-device + capi-system-info + capi-appfw-application + capi-appfw-app-manager + pkgmgr + pkgmgr-info + dlog + appsvc + appcore-efl + gio-unix-2.0 + bundle) + +FOREACH(flag ${PKGS_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}") + +ADD_CUSTOM_COMMAND( + WORKING_DIRECTORY + OUTPUT sync-adapter-stub.c + COMMAND gdbus-codegen --interface-prefix org. + --generate-c-code sync-adapter-stub ../../sync_adapter.xml + COMMENT "Generating Sync adapter GDBus .c/.h") + +ADD_CUSTOM_COMMAND( + WORKING_DIRECTORY + OUTPUT sync-manager-stub.c + COMMAND gdbus-codegen --interface-prefix org. + --generate-c-code sync-manager-stub ../../sync_manager.xml + COMMENT "Generating Sync Client GDBus .c/.h") + +## Create Library +ADD_LIBRARY(${this_target} SHARED ${SRCS} sync-manager-stub.c sync-adapter-stub.c) +TARGET_LINK_LIBRARIES(${this_target} ${PKGS_LDFLAGS} "-ldl -laul") + + +## SET LINKER FLAGS +#SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +SET_TARGET_PROPERTIES(${this_target} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${VERSION_MAJOR} + ) + + +CONFIGURE_FILE(${this_target}.pc.in ${CMAKE_SOURCE_DIR}/${this_target}.pc @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/${this_target}.pc DESTINATION lib/pkgconfig) + +INSTALL(TARGETS ${this_target} DESTINATION lib) +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ + DESTINATION include/ + FILES_MATCHING + PATTERN "*_private.h" EXCLUDE + PATTERN "*sync_manager.h" + PATTERN "*sync_adapter.h" + PATTERN "*sync-error.h" + PATTERN "*sync_manager_internal.h" + ) + +INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION lib + FILES_MATCHING PATTERN "*core-sync-client*.so*" + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) +#TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PKGS_LDFLAGS} "-ldl") +#INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) + diff --git a/src/sync-client/core-sync-client.pc.in b/src/sync-client/core-sync-client.pc.in new file mode 100644 index 0000000..edce025 --- /dev/null +++ b/src/sync-client/core-sync-client.pc.in @@ -0,0 +1,14 @@ +#Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: Sync manager library +Description: Sync manager client API +Version: @VERSION@ +Requires: capi-base-common accounts-svc bundle +Libs: -L${libdir} -lcore-sync-client +Cflags: -I${includedir} + diff --git a/src/sync-client/sync_adapter.c b/src/sync-client/sync_adapter.c new file mode 100644 index 0000000..8d9b024 --- /dev/null +++ b/src/sync-client/sync_adapter.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2013 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 <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <dlfcn.h> +#include <stdio.h> +#include <app.h> +#include <app_manager.h> +#include <pkgmgr-info.h> +#include <account.h> +#include <bundle.h> +#include <pthread.h> +#include "sync_adapter.h" +#include "sync-ipc-marshal.h" +#include "sync-manager-stub.h" +#include "sync-adapter-stub.h" +#include "sync-log.h" +#include "sync-error.h" + +typedef enum { + SYNC_STATUS_SUCCESS = 0, + SYNC_STATUS_CANCELLED = -1, + SYNC_STATUS_SYNC_ALREADY_IN_PROGRESS = -2, + SYNC_STATUS_FAILURE = -3 +} SyncSatus; + + +#define SYNC_THREAD 0 /*As sync adapter itself runs in service app*/ + +#define SYNC_MANAGER_DBUS_SERVICE "org.tizen.sync" +#define SYNC_MANAGER_DBUS_PATH "/org/tizen/sync/manager" +#define SYNC_ADAPTER_COMMON_DBUS_PATH "/org/tizen/sync/adapter" + + +typedef struct sync_adapter_s { + TizenSyncAdapter *sync_adapter_obj; + bool __syncRunning; + sync_adapter_start_sync_cb start_sync_cb; + sync_adapter_cancel_sync_cb cancel_sync_cb; +} sync_adapter_s; + +static sync_adapter_s *g_sync_adapter = NULL; + +extern int read_proc(const char *path, char *buf, int size); +extern char *proc_get_cmdline_self(); + +gboolean +__sync_adapter_on_start_sync(TizenSyncAdapter *pObject, + gint accountId, + const gchar *pSyncJobName, + gboolean is_data_sync, + GVariant *pSyncJobUserData) +{ + SYNC_LOGE_RET_RES(pObject != NULL && pSyncJobName != NULL, true, "sync adapter object is null"); + LOG_LOGD("Received start sync request in sync adapter: params account[%d] jobname [%s] Data sync [%s]", accountId, pSyncJobName, is_data_sync ? "YES" : "NO"); + + if (g_sync_adapter->__syncRunning) { + LOG_LOGD("Sync already running"); + + tizen_sync_adapter_call_send_result_sync(pObject, (int)SYNC_STATUS_SYNC_ALREADY_IN_PROGRESS, pSyncJobName, NULL, NULL); + + return true; + } + + g_sync_adapter->__syncRunning = true; + + int ret = SYNC_STATUS_SUCCESS; + account_h account = NULL; + if (accountId != -1) { + account_create(&account); + account_query_account_by_account_id(accountId, &account); + } + bundle *sync_job_user_data = umarshal_bundle(pSyncJobUserData); + + bool is_sync_success; + if (is_data_sync) + is_sync_success = g_sync_adapter->start_sync_cb(account, NULL, pSyncJobName, sync_job_user_data); + else + is_sync_success = g_sync_adapter->start_sync_cb(account, pSyncJobName, NULL, sync_job_user_data); + + if (!is_sync_success) + ret = SYNC_STATUS_FAILURE; + + tizen_sync_adapter_call_send_result_sync(pObject, ret, pSyncJobName, NULL, NULL); + g_sync_adapter->__syncRunning = false; + bundle_free(sync_job_user_data); + LOG_LOGD("Sync completed"); + + return true; +} + + +gboolean +__sync_adapter_on_stop_sync( + TizenSyncAdapter *pObject, + gint accountId, + const gchar *pSyncJobName, + gboolean is_data_sync, + GVariant *pSyncJobUserData) +{ + LOG_LOGD("handle stop in adapter"); + + SYNC_LOGE_RET_RES(pObject != NULL, true, "sync adapter object is null"); + LOG_LOGD("Received stop sync request in sync adapter: params account[%d] jobname [%s] Data sync [%s]", accountId, pSyncJobName, is_data_sync ? "YES" : "NO"); + + account_h account = NULL; + if (accountId != -1) { + account_create(&account); + account_query_account_by_account_id(accountId, &account); + } + bundle *sync_job_user_data = umarshal_bundle(pSyncJobUserData); + + if (is_data_sync) + g_sync_adapter->cancel_sync_cb(account, NULL, pSyncJobName, sync_job_user_data); + else + g_sync_adapter->cancel_sync_cb(account, pSyncJobName, NULL, sync_job_user_data); + + return true; +} + +/* flag == true => register */ +/* flag == false => de-register */ +int __register_sync_adapter(bool flag) +{ + GError *error = NULL; + GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + SYNC_LOGE_RET_RES(connection != NULL, SYNC_ERROR_IO_ERROR, "tizen_sync_manager_proxy_new_sync failed %s", error->message); + + TizenSyncManager *ipcObj = tizen_sync_manager_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + SYNC_MANAGER_DBUS_SERVICE, + SYNC_MANAGER_DBUS_PATH, + NULL, + &error); + SYNC_LOGE_RET_RES(error == NULL && ipcObj != NULL, SYNC_ERROR_IO_ERROR, "tizen_sync_manager_proxy_new_sync failed %s", error->message); + + char *command_line = proc_get_cmdline_self(); + if (flag) + tizen_sync_manager_call_add_sync_adapter_sync(ipcObj, command_line, NULL, &error); + else + tizen_sync_manager_call_remove_sync_adapter_sync(ipcObj, command_line, NULL, &error); + + free(command_line); + SYNC_LOGE_RET_RES(error == NULL, SYNC_ERROR_IO_ERROR, "Register sync adapter failed %s", error->message); + + return SYNC_ERROR_NONE; +} + + +int sync_adapter_set_callbacks(sync_adapter_start_sync_cb on_start_cb, sync_adapter_cancel_sync_cb on_cancel_cb) +{ + SYNC_LOGE_RET_RES(on_start_cb != NULL && on_cancel_cb != NULL, SYNC_ERROR_INVALID_PARAMETER, "Callback parameters must be passed"); + + if (!g_sync_adapter) { + g_sync_adapter = (sync_adapter_s *) malloc(sizeof(struct sync_adapter_s)); + SYNC_LOGE_RET_RES(g_sync_adapter != NULL, SYNC_ERROR_OUT_OF_MEMORY, "Out of memory"); + + g_sync_adapter->sync_adapter_obj = NULL; + g_sync_adapter->__syncRunning = false; + + if (__register_sync_adapter(true) == SYNC_ERROR_NONE) { + pid_t pid = getpid(); + GError *error = NULL; + GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + SYNC_LOGE_RET_RES(connection != NULL, SYNC_ERROR_SYSTEM, "System error occured %s", error->message); + + char obj_path[50]; + snprintf(obj_path, 50, "%s/%d", SYNC_ADAPTER_COMMON_DBUS_PATH, pid); + + TizenSyncAdapter *pSyncAdapter = tizen_sync_adapter_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + SYNC_MANAGER_DBUS_SERVICE, + obj_path, + NULL, + &error); + SYNC_LOGE_RET_RES(error == NULL && pSyncAdapter != NULL, SYNC_ERROR_IO_ERROR, "tizen_sync_manager_proxy_new_sync failed %s", error->message); + + g_signal_connect(pSyncAdapter, "start-sync", G_CALLBACK(__sync_adapter_on_start_sync), NULL); + g_signal_connect(pSyncAdapter, "cancel-sync", G_CALLBACK(__sync_adapter_on_stop_sync), NULL); + g_sync_adapter->sync_adapter_obj = pSyncAdapter; + } + } + + g_sync_adapter->start_sync_cb = on_start_cb; + g_sync_adapter->cancel_sync_cb = on_cancel_cb; + + return SYNC_ERROR_NONE; +} + + +int sync_adapter_unset_callbacks() +{ + SYNC_LOGE_RET_RES(g_sync_adapter != NULL, SYNC_ERROR_SYSTEM, "sync_adapter_set_callbacks should be called first"); + + __register_sync_adapter(false); + g_sync_adapter->start_sync_cb = NULL; + g_sync_adapter->cancel_sync_cb = NULL; + + LOG_LOGD("sync_adapter_destroy"); + if (g_sync_adapter) { + free(g_sync_adapter); + g_sync_adapter = NULL; + } + + return SYNC_ERROR_NONE; +} diff --git a/src/sync-client/sync_manager.c b/src/sync-client/sync_manager.c new file mode 100644 index 0000000..e08f8d5 --- /dev/null +++ b/src/sync-client/sync_manager.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2013 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 <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <app_manager.h> +#include <bundle_internal.h> +#include "sync-ipc-marshal.h" +#include "sync-manager-stub.h" +#include "sync-adapter-stub.h" +#include "sync_manager.h" +#include "sync-log.h" +#include "sync-error.h" + +#define SYNC_MANAGER_DBUS_PATH "/org/tizen/sync/manager" +#define SYNC_ADAPTER_DBUS_PATH "/org/tizen/sync/adapter" +#define SYNC_ERROR_PREFIX "org.tizen.sync.Error" + + +typedef struct sync_manager_s { + TizenSyncManager *ipcObj; + sync_manager_sync_job_cb sync_job_cb; + char *appid; +} sync_manager_s; + +static sync_manager_s *g_sync_manager; + +int read_proc(const char *path, char *buf, int size) +{ + int fd; + int ret; + + if (buf == NULL || path == NULL) + return -1; + + fd = open(path, O_RDONLY); + if (fd < 0) { + LOG_LOGD("fd = %d", fd); + + return -1; + } + + ret = read(fd, buf, size - 1); + if (ret <= 0) { + close(fd); + + return -1; + } else + buf[ret] = 0; + + close(fd); + + return ret; +} + +char *proc_get_cmdline_self() +{ + char cmdline[1024]; + int ret; + + ret = read_proc("/proc/self/cmdline", cmdline, sizeof(cmdline)); + if (ret <= 0) + return NULL; + + return strdup(cmdline); +} + + +GDBusErrorEntry _sync_errors[] = { + {SYNC_ERROR_NONE, SYNC_ERROR_PREFIX".NoError"}, + {SYNC_ERROR_OUT_OF_MEMORY, SYNC_ERROR_PREFIX".OutOfMemory"}, + {SYNC_ERROR_IO_ERROR, SYNC_ERROR_PREFIX".IOError"}, + {SYNC_ERROR_PERMISSION_DENIED, SYNC_ERROR_PREFIX".PermissionDenied"}, + {SYNC_ERROR_ALREADY_IN_PROGRESS, SYNC_ERROR_PREFIX".AlreadyInProgress"}, + {SYNC_ERROR_INVALID_OPERATION, SYNC_ERROR_PREFIX".InvalidOperation"}, + {SYNC_ERROR_INVALID_PARAMETER, SYNC_ERROR_PREFIX".InvalidParameter"}, + {SYNC_ERROR_QUOTA_EXCEEDED, SYNC_ERROR_PREFIX".QuotaExceeded"}, + {SYNC_ERROR_UNKNOWN, SYNC_ERROR_PREFIX".Unknown"}, + {SYNC_ERROR_SYSTEM, SYNC_ERROR_PREFIX".System"}, + {SYNC_ERROR_SYNC_ADAPTER_NOT_FOUND, SYNC_ERROR_PREFIX".SyncAdapterIsNotFound"}, +}; + + +static int _sync_get_error_code(bool is_success, GError *error) +{ + if (!is_success) { + LOG_LOGD("Received error Domain[%d] Message[%s] Code[%d]", error->domain, error->message, error->code); + + if (g_dbus_error_is_remote_error(error)) { + gchar *remote_error = g_dbus_error_get_remote_error(error); + if (remote_error) { + LOG_LOGD("Remote error[%s]", remote_error); + + int error_enum_count = G_N_ELEMENTS(_sync_errors); + int i = 0; + for (i = 0; i < error_enum_count; i++) { + if (g_strcmp0(_sync_errors[i].dbus_error_name, remote_error) == 0) { + LOG_LOGD("Remote error code matched[%d]", _sync_errors[i].error_code); + return _sync_errors[i].error_code; + } + } + } + } + /*All undocumented errors mapped to SYNC_ERROR_UNKNOWN*/ + return SYNC_ERROR_UNKNOWN; + } + return SYNC_ERROR_NONE; +} + + +static int initialize_connection() +{ + SYNC_LOGE_RET_RES(g_sync_manager == NULL, SYNC_ERROR_NONE, "sync manager already connected"); + + pid_t pid = getpid(); + char *appId = NULL; + + GDBusConnection *connection = NULL; + GError *error = NULL; + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + TizenSyncManager *ipcObj = tizen_sync_manager_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + "org.tizen.sync", + "/org/tizen/sync/manager", + NULL, + &error); + if (error != NULL) { + LOG_LOGC("sync client: gdbus error [%s]", error->message); + g_sync_manager = NULL; + + return SYNC_ERROR_IO_ERROR; + } + + if (ipcObj == NULL) { + g_sync_manager = NULL; + + return SYNC_ERROR_SYSTEM; + } + + g_sync_manager = (sync_manager_s *) malloc(sizeof(struct sync_manager_s)); + if (g_sync_manager == NULL) + return SYNC_ERROR_OUT_OF_MEMORY; + + int ret = app_manager_get_app_id(pid, &appId); + if (ret != APP_MANAGER_ERROR_NONE) + appId = proc_get_cmdline_self(); + g_sync_manager->ipcObj = ipcObj; + g_sync_manager->appid = appId; + + return SYNC_ERROR_NONE; +} + + +int get_interval(sync_period_e period) +{ + int frequency = 0; + switch (period) { + case SYNC_PERIOD_INTERVAL_30MIN: + { + LOG_LOGD("SYNC_PERIOD_INTERVAL_30MIN"); + frequency = 30; + break; + } + case SYNC_PERIOD_INTERVAL_1H: + { + LOG_LOGD("SYNC_PERIOD_INTERVAL_1H"); + frequency = 60; + break; + } + case SYNC_PERIOD_INTERVAL_2H: + { + LOG_LOGD("SYNC_PERIOD_INTERVAL_2H"); + frequency = 2 * 60; + break; + } + case SYNC_PERIOD_INTERVAL_3H: + { + LOG_LOGD("SYNC_PERIOD_INTERVAL_3H"); + frequency = 3 * 60; + break; + } + case SYNC_PERIOD_INTERVAL_6H: + { + LOG_LOGD("SYNC_PERIOD_INTERVAL_6H"); + frequency = 6 * 60; + break; + } + case SYNC_PERIOD_INTERVAL_12H: + { + LOG_LOGD("SYNC_PERIOD_INTERVAL_12H"); + frequency = 12 * 60; + break; + } + case SYNC_PERIOD_INTERVAL_1DAY: + { + LOG_LOGD("SYNC_PERIOD_INTERVAL_1DAY"); + frequency = 24 * 60; + break; + } + case SYNC_PERIOD_INTERVAL_MAX: + default: + { + LOG_LOGD("Error"); + break; + } + } + + return frequency * 60; /*return in seconds*/ +} + + +int sync_manager_on_demand_sync_job(account_h account, const char *sync_job_name, sync_option_e sync_option, bundle *sync_job_user_data, int *sync_job_id) +{ + SYNC_LOGE_RET_RES(sync_job_name != NULL, SYNC_ERROR_INVALID_PARAMETER, "sync_job_name is NULL"); + SYNC_LOGE_RET_RES(sync_option >= SYNC_OPTION_NONE && sync_option <= (SYNC_OPTION_EXPEDITED | SYNC_OPTION_NO_RETRY), SYNC_ERROR_INVALID_PARAMETER, "sync_option is invalid %d", sync_option); + SYNC_LOGE_RET_RES(sync_job_id != NULL, SYNC_ERROR_INVALID_PARAMETER, "sync_job_id is NULL"); + + int ret = initialize_connection(); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Connection to sync service failed"); + + LOG_LOGC("sync client: %s requesting one time sync", g_sync_manager->appid); + + int id = -1; + if (account) { + ret = account_get_account_id(account, &id); + if (ret != 0) { + LOG_LOGC("sync client: account_get_account_id failure"); + return SYNC_ERROR_SYSTEM; + } + LOG_LOGC("appid [%s] accid [%d] sync_job_name [%s] ", g_sync_manager->appid, id, sync_job_name); + } else + LOG_LOGC("appid [%s] sync_job_name [%s] ", g_sync_manager->appid, sync_job_name); + + GError *error = NULL; + GVariant *user_data = marshal_bundle(sync_job_user_data); + + bool is_success = tizen_sync_manager_call_add_on_demand_sync_job_sync(g_sync_manager->ipcObj, id, sync_job_name, sync_option, user_data, sync_job_id, NULL, &error); + if (!is_success || error) { + int error_code = _sync_get_error_code(is_success, error); + LOG_LOGC("sync client: gdbus error [%s]", error->message); + g_clear_error(&error); + + return error_code; + } + if (*sync_job_id == -1) + return SYNC_ERROR_QUOTA_EXCEEDED; + + + return SYNC_ERROR_NONE; +} + + +int sync_manager_add_periodic_sync_job(account_h account, const char *sync_job_name, sync_period_e sync_period, sync_option_e sync_option, bundle *sync_job_user_data, int *sync_job_id) +{ + SYNC_LOGE_RET_RES(sync_job_name != NULL, SYNC_ERROR_INVALID_PARAMETER, "sync_job_name is NULL"); + SYNC_LOGE_RET_RES((sync_period >= SYNC_PERIOD_INTERVAL_30MIN && sync_period < SYNC_PERIOD_INTERVAL_MAX), SYNC_ERROR_INVALID_PARAMETER, "Time interval not supported %d", sync_period); + SYNC_LOGE_RET_RES(sync_option >= SYNC_OPTION_NONE && sync_option <= (SYNC_OPTION_EXPEDITED | SYNC_OPTION_NO_RETRY), SYNC_ERROR_INVALID_PARAMETER, "sync_option is invalid %d", sync_option); + SYNC_LOGE_RET_RES(sync_job_id != NULL, SYNC_ERROR_INVALID_PARAMETER, "sync_job_id is NULL"); + + int ret = initialize_connection(); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Connection to sync service failed"); + + LOG_LOGC("sync client: %s requesting periodic sync", g_sync_manager->appid); + + int id = -1; + if (account) { + ret = account_get_account_id(account, &id); + if (ret != 0) { + LOG_LOGC("sync client: account_get_account_id failure"); + return SYNC_ERROR_SYSTEM; + } + LOG_LOGC("appid [%s] accid [%d] sync_job_name [%s] ", g_sync_manager->appid, id, sync_job_name); + } else + LOG_LOGC("appid [%s] sync_job_name [%s] ", g_sync_manager->appid, sync_job_name); + + int sync_interval = get_interval(sync_period); + + GError *error = NULL; + GVariant *user_data = marshal_bundle(sync_job_user_data); + + bool is_success = tizen_sync_manager_call_add_periodic_sync_job_sync(g_sync_manager->ipcObj, id, sync_job_name, sync_interval, sync_option, user_data, sync_job_id, NULL, &error); + if (!is_success || error) { + int error_code = _sync_get_error_code(is_success, error); + LOG_LOGC("sync client: gdbus error [%s]", error->message); + g_clear_error(&error); + + return error_code; + } + + return SYNC_ERROR_NONE; +} + + +int sync_manager_add_data_change_sync_job(account_h account, const char *sync_capability, sync_option_e sync_option, bundle *sync_job_user_data, int *sync_job_id) +{ + if (sync_capability != NULL) { + if (!(strcmp(sync_capability, "http://tizen.org/sync/capability/calendar")) || + !(strcmp(sync_capability, "http://tizen.org/sync/capability/contact")) || + !(strcmp(sync_capability, "http://tizen.org/sync/capability/image")) || + !(strcmp(sync_capability, "http://tizen.org/sync/capability/video")) || + !(strcmp(sync_capability, "http://tizen.org/sync/capability/sound")) || + !(strcmp(sync_capability, "http://tizen.org/sync/capability/music"))) { + LOG_LOGC("sync client: capability [%s] ", sync_capability); + } else { + LOG_LOGD("sync client: invalid capability"); + return SYNC_ERROR_INVALID_PARAMETER; + } + } else { + LOG_LOGD("sync client: sync_capability is NULL"); + return SYNC_ERROR_INVALID_PARAMETER; + } + + SYNC_LOGE_RET_RES(sync_option >= SYNC_OPTION_NONE && sync_option <= (SYNC_OPTION_EXPEDITED | SYNC_OPTION_NO_RETRY), SYNC_ERROR_INVALID_PARAMETER, "sync_option is invalid %d", sync_option); + SYNC_LOGE_RET_RES(sync_job_id != NULL, SYNC_ERROR_INVALID_PARAMETER, "sync_job_id is NULL"); + + int ret = initialize_connection(); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Connection to sync service failed"); + + LOG_LOGC("sync client: %s requesting data change callback", g_sync_manager->appid); + + int id = -1; + if (account) { + ret = account_get_account_id(account, &id); + if (ret != 0) { + LOG_LOGC("sync client: account_get_account_id failure"); + return SYNC_ERROR_SYSTEM; + } + LOG_LOGC("appid [%s] accid [%d] capability [%s] ", g_sync_manager->appid, id, sync_capability); + } else + LOG_LOGC("appid [%s] capability [%s] ", g_sync_manager->appid, sync_capability); + + GError *error = NULL; + GVariant *user_data = marshal_bundle(sync_job_user_data); + + bool is_success = tizen_sync_manager_call_add_data_change_sync_job_sync(g_sync_manager->ipcObj, id, sync_capability, sync_option, user_data, sync_job_id, NULL, &error); + if (!is_success || error) { + int error_code = _sync_get_error_code(is_success, error); + LOG_LOGC("sync client: gdbus error [%s]", error->message); + g_clear_error(&error); + + return error_code; + } + + return SYNC_ERROR_NONE; +} + + +int sync_manager_remove_sync_job(int sync_job_id) +{ + SYNC_LOGE_RET_RES(sync_job_id >= 1 && sync_job_id <= 100, SYNC_ERROR_INVALID_PARAMETER, "sync_job_id is inappropriate value"); + + int ret = initialize_connection(); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Connection to sync service failed"); + + LOG_LOGC("sync client: %s removing sync job with sync_job_id [%d] ", g_sync_manager->appid, sync_job_id); + + GError *error = NULL; + bool is_success = tizen_sync_manager_call_remove_sync_job_sync(g_sync_manager->ipcObj, sync_job_id, NULL, &error); + + if (!is_success || error) { + int error_code = _sync_get_error_code(is_success, error); + LOG_LOGC("sync client: gdbus error [%s]", error->message); + g_clear_error(&error); + + return error_code; + } + return SYNC_ERROR_NONE; +} + + +int sync_manager_foreach_sync_job(sync_manager_sync_job_cb sync_job_cb, void *user_data) +{ + if (!sync_job_cb) { + LOG_LOGD("sync client: sync_job_cb is NULL"); + return SYNC_ERROR_INVALID_PARAMETER; + } + + int ret = initialize_connection(); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Connection to sync service failed"); + + g_sync_manager->sync_job_cb = sync_job_cb; + + GError *error = NULL; + GVariant *sync_job_list_variant = NULL; + gboolean is_success = tizen_sync_manager_call_get_all_sync_jobs_sync(g_sync_manager->ipcObj, &sync_job_list_variant, NULL, &error); + + if (!is_success || error) { + int error_code = _sync_get_error_code(is_success, error); + LOG_LOGC("sync client: gdbus error [%s]", error->message); + g_clear_error(&error); + + return error_code; + } else { + unmarshal_sync_job_list(sync_job_list_variant, sync_job_cb, user_data); + } + + return SYNC_ERROR_NONE; +} + + +int _sync_manager_enable_sync() +{ + int ret = initialize_connection(); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Connection to sync service failed"); + + GError *error = NULL; + tizen_sync_manager_call_set_sync_status_sync(g_sync_manager->ipcObj, true, NULL, &error); + if (error != NULL) { + LOG_LOGC("sync client: gdbus error [%s]", error->message); + + return SYNC_ERROR_IO_ERROR; + } + + return SYNC_ERROR_NONE; +} + + +int _sync_manager_disable_sync() +{ + int ret = initialize_connection(); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Connection to sync service failed"); + + GError *error = NULL; + tizen_sync_manager_call_set_sync_status_sync(g_sync_manager->ipcObj, false, NULL, &error); + if (error != NULL) { + LOG_LOGC("sync client: gdbus error [%s]", error->message); + + return SYNC_ERROR_IO_ERROR; + } + + return SYNC_ERROR_NONE; +} diff --git a/src/sync-service/CMakeLists.txt b/src/sync-service/CMakeLists.txt new file mode 100644 index 0000000..f8c1105 --- /dev/null +++ b/src/sync-service/CMakeLists.txt @@ -0,0 +1,126 @@ +# Copyright (c) 2013 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. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT("sync-service") + +IF(NOT DEFINED PACKAGE_NAME) + SET(PACKAGE_NAME "sync-service") +ENDIF(NOT DEFINED PACKAGE_NAME) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +IF(NOT DEFINED BINDIR) + SET(BINDIR"${PREFIX}/bin") +ENDIF(NOT DEFINED BINDIR) + +IF(NOT DEFINED SYSTEMD_DIR) + SET(SYSTEMD_DIR "/usr/lib/systemd/system") +ENDIF(NOT DEFINED SYSTEMD_DIR) +SET(INCLUDEDIR "${PREFIX}/include") + +INCLUDE_DIRECTORIES( + ./ + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/common + ) + +SET(SRCS + main.cpp + SyncManager_ServiceInterface.cpp + SyncManager_CapabilityInfo.cpp + SyncManager_PeriodicSyncJob.cpp + SyncManager_SyncManager.cpp + SyncManager_SyncService.cpp + SyncManager_NetworkChangeListener.cpp + SyncManager_StorageChangeListener.cpp + SyncManager_CurrentSyncJobQueue.cpp + SyncManager_RepositoryEngine.cpp + SyncManager_BatteryStatusListener.cpp + SyncManager_SyncJob.cpp + SyncManager_SyncJobQueue.cpp + SyncManager_SyncStatusInfo.cpp + SyncManager_SyncDefines.cpp + SyncManager_SyncJobDispatcher.cpp + ${CMAKE_SOURCE_DIR}/common/sync-ipc-marshal.c + SyncManager_SyncWorker.cpp + SyncManager_CurrentSyncContext.cpp + SyncManager_DataChangeSyncScheduler.cpp + SyncManager_PeriodicSyncScheduler.cpp + SyncManager_SyncAdapterAggregator.cpp + SyncManager_SyncJobsAggregator.cpp + SyncManager_SyncJobsInfo.cpp + SyncManager_DataSyncJob.cpp) + + +IF(_SEC_FEATURE_CONTAINER_ENABLE) + ADD_DEFINITIONS("-D_SEC_FEATURE_CONTAINER_ENABLE=1") +ENDIF(_SEC_FEATURE_CONTAINER_ENABLE) + +ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE_NAME}\"") + +INCLUDE(FindPkgConfig) +SET(PACKAGES + capi-network-connection + capi-system-runtime-info + capi-system-device + capi-appfw-application + capi-appfw-app-manager + pkgmgr + dlog + appsvc + glib-2.0 + vconf-internal-keys + accounts-svc + libxml-2.0 + gio-unix-2.0 + alarm-service + bundle + calendar-service2 + contacts-service2 + capi-content-media-content) + +IF(_SEC_FEATURE_CONTAINER_ENABLE) + SET(PACKAGES ${PACKAGES} vasum) +ENDIF(_SEC_FEATURE_CONTAINER_ENABLE) + +pkg_check_modules(PKGS REQUIRED ${PACKAGES}) + +FOREACH(flag ${PKGS_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fvisibility=hidden -fPIE") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}") +SET(PKGS_LDFLAGS "${PKGS_LDFLAGS} -pie") + +ADD_CUSTOM_COMMAND( + WORKING_DIRECTORY + OUTPUT sync-adapter-stub.c + COMMAND gdbus-codegen --interface-prefix org. + --generate-c-code sync-adapter-stub ../../sync_adapter.xml + COMMENT "Generating Sync adapter GDBus .c/.h") + +ADD_CUSTOM_COMMAND( + WORKING_DIRECTORY + OUTPUT sync-manager-stub.c + COMMAND gdbus-codegen --interface-prefix org. + --generate-c-code sync-manager-stub ../../sync_manager.xml + COMMENT "Generating Sync Service GDBus .c/.h") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS} sync-manager-stub.c sync-adapter-stub.c) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PKGS_LDFLAGS} "-ldl") +#TARGET_LINK_LIBRARIES(${PROJECT_NAME} core-sync-client) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/sync-manager.service DESTINATION ${SYSTEMD_DIR}) diff --git a/src/sync-service/SyncManager_BatteryStatusListener.cpp b/src/sync-service/SyncManager_BatteryStatusListener.cpp new file mode 100644 index 0000000..f390462 --- /dev/null +++ b/src/sync-service/SyncManager_BatteryStatusListener.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_BatteryStatusListener.cpp + * @brief This is the implementation file for the BatteryStatusListener class. + */ + +#include <vconf.h> +#include <vconf-keys.h> +#include <vconf-internal-dnet-keys.h> +#include "SyncManager_SyncManager.h" +#include "SyncManager_BatteryStatusListener.h" +#include "SyncManager_SyncDefines.h" +#include "sync-log.h" + + +/*namespace _SyncManager +{*/ + + +void OnBatteryStatusChanged(keynode_t* pKey, void* pData) +{ + LOG_LOGD("OnBatteryStatusChanged Starts"); + + BatteryStatus value = static_cast<BatteryStatus> (vconf_keynode_get_int(pKey)); + + SyncManager::GetInstance()->OnBatteryStatusChanged(value); + + LOG_LOGD("OnBatteryStatusChanged Ends"); +} + + +BatteryStatusListener::BatteryStatusListener(void) +{ +} + + +BatteryStatusListener::~BatteryStatusListener(void) +{ +} + + +int +BatteryStatusListener::RegisterBatteryStatusListener(void) +{ + return(vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, OnBatteryStatusChanged, NULL)); +} + + +int +BatteryStatusListener::DeRegisterBatteryStatusListener(void) +{ + LOG_LOGD("DeRegisterBatteryStatusListener"); + + return(vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, OnBatteryStatusChanged)); +} +//}//_SyncManager diff --git a/src/sync-service/SyncManager_BatteryStatusListener.h b/src/sync-service/SyncManager_BatteryStatusListener.h new file mode 100644 index 0000000..7cda138 --- /dev/null +++ b/src/sync-service/SyncManager_BatteryStatusListener.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_BatteryStatusListener.h + * @brief This is the header file for the BatteryStatusObserver class. + */ + + +#ifndef SYNC_SERVICE_BATTERY_STATUS_LISTENER_H +#define SYNC_SERVICE_BATTERY_STATUS_LISTENER_H + + +/*namespace _SyncManager +{ +*/ + +class BatteryStatusListener +{ +public: + + BatteryStatusListener(void); + + ~BatteryStatusListener(void); + + int RegisterBatteryStatusListener(void); + + int DeRegisterBatteryStatusListener(void); +}; +//}//_SyncManager +#endif // SYNC_SERVICE_BATTERY_STATUS_LISTENER_H diff --git a/src/sync-service/SyncManager_CapabilityInfo.cpp b/src/sync-service/SyncManager_CapabilityInfo.cpp new file mode 100644 index 0000000..ef38eba --- /dev/null +++ b/src/sync-service/SyncManager_CapabilityInfo.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CapabilityInfo.cpp + * @brief This is the implementation file for the CapabilityInfo class. + */ + +#include <bundle.h> +#include "sync-log.h" +#include "SyncManager_RepositoryEngine.h" +#include "SyncManager_CapabilityInfo.h" +#include "SyncManager_SyncManager.h" + + +/*namespace _SyncManager +{*/ + + +CapabilityInfo::CapabilityInfo(void) +{ + //Empty +} + + +CapabilityInfo::~CapabilityInfo(void) +{ +} + + +CapabilityInfo::CapabilityInfo(string capability) + : __capability(capability) +{ + +} + + +void +CapabilityInfo::AddPeriodicSyncJob(int account_id, PeriodicSyncJob* pJob) +{ + __periodicSyncList.insert(pair<int, PeriodicSyncJob*> (account_id, pJob)); +} + +void +CapabilityInfo::RemovePeriodicSyncJob(PeriodicSyncJob* pJob) +{ + int acc_id; + //int ret = account_get_account_id(pJob->accountHandle, &acc_id); + //LOG_LOGE_VOID(ret == ACCOUNT_ERROR_NONE, "app account_get_account_id failed %d", ret); + + //__periodicSyncList.erase(__periodicSyncList.find(acc_id)); +} + + + +bool +CapabilityInfo::RequestAlreadyExists(int account_id, PeriodicSyncJob* pJob) +{ + map<int, PeriodicSyncJob*>::iterator it = __periodicSyncList.find(account_id); + if (it == __periodicSyncList.end()) + { + return false; + } + PeriodicSyncJob* pSyncJob = it->second; + if ( *pSyncJob == *pJob) + { + return true; + } + else + return false; +} + + +CapabilityInfo::CapabilityInfo(const CapabilityInfo& capabilityInfo) +{ + this->__capability = capabilityInfo.__capability; + + map<int, PeriodicSyncJob*>::const_iterator endItr = capabilityInfo.__periodicSyncList.end(); + + for(map<int, PeriodicSyncJob*>::const_iterator itr = capabilityInfo.__periodicSyncList.begin(); itr != endItr; ++itr) + { + PeriodicSyncJob* pJob = new PeriodicSyncJob(*(itr->second)); + if (pJob) + { + __periodicSyncList.insert(pair<int, PeriodicSyncJob*> (itr->first, pJob)); + } + } +} + + +CapabilityInfo& CapabilityInfo::operator =(const CapabilityInfo& capabilityInfo) +{ + this->__capability = capabilityInfo.__capability; + + map<int, PeriodicSyncJob*>::const_iterator endItr = capabilityInfo.__periodicSyncList.end(); + for(map<int, PeriodicSyncJob*>::const_iterator itr = capabilityInfo.__periodicSyncList.begin(); itr != endItr; ++itr) + { + PeriodicSyncJob* pJob = new PeriodicSyncJob(*(itr->second)); + if (pJob) + { + __periodicSyncList.insert(pair<int, PeriodicSyncJob*> (itr->first, pJob)); + } + } + + return *this; +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_CapabilityInfo.h b/src/sync-service/SyncManager_CapabilityInfo.h new file mode 100644 index 0000000..7445d1b --- /dev/null +++ b/src/sync-service/SyncManager_CapabilityInfo.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CapabilityInfo.h + * @brief This is the header file for the CapabilityInfo class. + */ + +#ifndef SYNC_SERVICE_CAPABILITY_INFO_H +#define SYNC_SERVICE_CAPABILITY_INFO_H + +#include <string> +#include <vector> +#include <account.h> +#include "SyncManager_PeriodicSyncJob.h" + +/*namespace _SyncManager +{ +*/ +using namespace std; + +class CapabilityInfo +{ +public: + + CapabilityInfo(void); + + ~CapabilityInfo(void); + + CapabilityInfo(string capability); + + void AddPeriodicSyncJob(int account_id, PeriodicSyncJob* pJob); + + void RemovePeriodicSyncJob(PeriodicSyncJob* pJob); + + bool RequestAlreadyExists(int account_id, PeriodicSyncJob* pJob); + + CapabilityInfo(const CapabilityInfo& accountInfo); + + CapabilityInfo& operator =(const CapabilityInfo& capabilityInfo); + +public: + string __capability; + map<int, PeriodicSyncJob*> __periodicSyncList; +}; +//}//_SyncManager +#endif // SYNC_SERVICE_CAPABILITY_INFO_H diff --git a/src/sync-service/SyncManager_CurrentSyncContext.cpp b/src/sync-service/SyncManager_CurrentSyncContext.cpp new file mode 100644 index 0000000..307568e --- /dev/null +++ b/src/sync-service/SyncManager_CurrentSyncContext.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CurrentSyncContext.cpp + * @brief This is the implementation file for the CurrentSyncContext class. + */ + +#include <stdlib.h> +#include "SyncManager_CurrentSyncContext.h" +#include "SyncManager_SyncService.h" +#include "SyncManager_SyncDefines.h" +#include "SyncManager_SyncManager.h" +#include "sync-log.h" + +/*namespace _SyncManager +{*/ + +CurrentSyncContext::CurrentSyncContext(SyncJob* pSyncJob) +{ + __pCurrentSyncJob = pSyncJob; +} + + +CurrentSyncContext::CurrentSyncContext(const CurrentSyncContext& currContext) +{ + __startTime = currContext.GetStartTime(); + __timerId = currContext.GetTimerId(); + __pCurrentSyncJob = currContext.GetSyncJob(); + LOG_LOGE_VOID(__pCurrentSyncJob, "Failed to construct SyncJob in CurrentSyncContext"); +} + + +CurrentSyncContext::~CurrentSyncContext(void) +{ +} + + +SyncJob* +CurrentSyncContext::GetSyncJob() const +{ + return __pCurrentSyncJob; +} + +long +CurrentSyncContext::GetStartTime() const +{ + return __startTime; +} + +long +CurrentSyncContext::GetTimerId() const +{ + return __timerId; +} + +void +CurrentSyncContext::SetTimerId(long id) +{ + __timerId = id; +} diff --git a/src/sync-service/SyncManager_CurrentSyncContext.h b/src/sync-service/SyncManager_CurrentSyncContext.h new file mode 100644 index 0000000..6f1b4f1 --- /dev/null +++ b/src/sync-service/SyncManager_CurrentSyncContext.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CurrentSyncContext.h + * @brief This is the header file for the CurrentSyncContext class. + */ + +#ifndef SYNC_SERVICE_CURRENT_SYNC_CONTEXT_H +#define SYNC_SERVICE_CURRENT_SYNC_CONTEXT_H + +#include <pthread.h> +#include "SyncManager_SyncJob.h" +#include "SyncManager_SyncJobDispatcher.h" +#include "SyncManager_CurrentSyncJobQueue.h" + +/*namespace _SyncManager +{ +*/ + +class CurrentSyncContext +{ +public: + CurrentSyncContext(SyncJob* pSyncJob); + CurrentSyncContext(const CurrentSyncContext& job); + ~CurrentSyncContext(void); + SyncJob *GetSyncJob() const; + long GetStartTime() const; + long GetTimerId() const; + void SetTimerId(long id); + + +private: + SyncJob* __pCurrentSyncJob; + long __startTime; + long __timerId; + + friend class SyncJobDispatcher; + friend class CurrentSyncJobQueue; +}; + +//}//_SyncManager +#endif // SYNC_SERVICE_CURRENT_SYNC_CONTEXT_H diff --git a/src/sync-service/SyncManager_CurrentSyncJobQueue.cpp b/src/sync-service/SyncManager_CurrentSyncJobQueue.cpp new file mode 100644 index 0000000..9c08065 --- /dev/null +++ b/src/sync-service/SyncManager_CurrentSyncJobQueue.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CurrentSyncJobQueue.cpp + * @brief This is the implementation file for the CurrentSyncJobQueue class. + */ + +#include <iostream> +#include <sstream> +#include <alarm.h> +#include <glib.h> +#include "sync-log.h" +#include "sync-error.h" +#include "SyncManager_SyncManager.h" +#include "SyncManager_CurrentSyncJobQueue.h" + +using namespace std; +/*namespace _SyncManager +{*/ + + +CurrentSyncJobQueue::CurrentSyncJobQueue(void) +{ + //Empty +} + + +CurrentSyncJobQueue::~CurrentSyncJobQueue(void) +{ + //Empty +} + + +int +CurrentSyncJobQueue::AddSyncJobToCurrentSyncQueue(SyncJob* syncJob) +{ + LOG_LOGD("Active Sync Jobs Queue size : Before = %d", __currentSyncJobQueue.size()); + + map<const string, CurrentSyncContext*>::iterator it; + it = __currentSyncJobQueue.find(syncJob->__key); + + if (it != __currentSyncJobQueue.end()) + { + LOG_LOGD("Sync already in progress"); + return SYNC_ERROR_ALREADY_IN_PROGRESS; + } + else + { + LOG_LOGD("Create a Sync context"); + + CurrentSyncContext* pCurrentSyncContext = new (std::nothrow) CurrentSyncContext(syncJob); + if (!pCurrentSyncContext) + { + LOG_LOGD("Failed to construct CurrentSyncContext instance"); + return SYNC_ERROR_OUT_OF_MEMORY; + } + //adding timeout of 30 seconds + pCurrentSyncContext->SetTimerId(g_timeout_add (300000, CurrentSyncJobQueue::OnTimerExpired, pCurrentSyncContext)); + pair<map<const string, CurrentSyncContext*>::iterator,bool> ret; + ret = __currentSyncJobQueue.insert(pair<const string, CurrentSyncContext*>(syncJob->__key, pCurrentSyncContext)); + if (ret.second == false) + { + return SYNC_ERROR_ALREADY_IN_PROGRESS; + } + } + LOG_LOGD("Active Sync Jobs Queue size : After = %d", __currentSyncJobQueue.size()); + + return SYNC_ERROR_NONE; +} + + +int +CurrentSyncJobQueue::OnTimerExpired(void* data) +{ + LOG_LOGD("CurrentSyncJobQueue::onTimerExpired Starts"); + + CurrentSyncContext* pSyncContext = static_cast<CurrentSyncContext*>(data); + if (pSyncContext) + { + LOG_LOGD("CurrentSyncJobQueue::onTimerExpired sending sync-cancelled message"); + SyncJob* pJob = pSyncContext->GetSyncJob(); + if (pJob) + { + SyncManager::GetInstance()->CloseCurrentSyncContext(pSyncContext); + SyncManager::GetInstance()->SendSyncCompletedOrCancelledMessage(pJob, SYNC_STATUS_CANCELLED); + LOG_LOGD("CurrentSyncJobQueue::onTimerExpired sending sync-cancelled message end"); + } + else + { + LOG_LOGD("Failed to get SyncJob"); + } + } + else + { + LOG_LOGD(" context null"); + } + + LOG_LOGD("CurrentSyncJobQueue::onTimerExpired Ends"); + + return false; +} + + +list<CurrentSyncContext*> +CurrentSyncJobQueue::GetOperations(void) +{ + list<CurrentSyncContext*> opsList; + map<const string, CurrentSyncContext*>::iterator it; + for (it = __currentSyncJobQueue.begin(); it != __currentSyncJobQueue.end(); it++) + { + CurrentSyncContext *pContext = new CurrentSyncContext(*(it->second)); + opsList.push_back(pContext); + } + return opsList; +} + + +bool +CurrentSyncJobQueue::IsJobActive(CurrentSyncContext *pCurrSync) +{ + LOG_LOGD("CurrentSyncJobQueue::IsJobActive() Starts"); + + LOG_LOGD("job q size %d", __currentSyncJobQueue.size()); + + if (pCurrSync == NULL) + { + return false; + } + + string jobKey; + jobKey.append(pCurrSync->GetSyncJob()->__key); + + map<const string, CurrentSyncContext*>::iterator it; + it = __currentSyncJobQueue.find(jobKey); + + if (it != __currentSyncJobQueue.end()) + { + LOG_LOGD("job active"); + return true; + } + LOG_LOGD("job in-active"); + return false; + LOG_LOGD("CurrentSyncJobQueue::IsJobActive() Ends"); +} + +int +CurrentSyncJobQueue::RemoveSyncContextFromCurrentSyncQueue(CurrentSyncContext* pSyncContext) +{ + LOG_LOGD("Remove sync job from Active Sync Jobs queue"); + if (pSyncContext == NULL) + { + LOG_LOGD("sync cotext is null"); + return SYNC_ERROR_INVALID_PARAMETER; + } + + SyncJob* pSyncJob = pSyncContext->GetSyncJob(); + + map<const string, CurrentSyncContext*>::iterator it = __currentSyncJobQueue.find(pSyncJob->__key); + CurrentSyncContext* pCurrContext = it->second; + __currentSyncJobQueue.erase(it); + LOG_LOGD("Active Sync Jobs queue size, After = %d", __currentSyncJobQueue.size()); + delete pCurrContext; + pCurrContext = NULL; + return SYNC_ERROR_NONE; +} + +string +CurrentSyncJobQueue::ToKey(account_h account, string capability) +{ + int ret; + string key; + char* pName; + int id; + stringstream ss; + + ret = account_get_user_name(account, &pName); + ret = account_get_account_id(account, &id); + + ss<<id; + key.append("id:").append(ss.str()).append("name:").append(pName).append("capability:").append(capability.c_str()); + + return key; +} + +CurrentSyncContext* +CurrentSyncJobQueue::DoesAccAuthExist(account_h account, string auth) +{ + if (account == NULL) + { + LOG_LOGD("CurrentSyncJobQueue::DoesAccAuthExist account is null"); + return NULL; + } + LOG_LOGD("CurrentSyncJobQueue::DoesAccAuthExist() Starts"); + + string key = ToKey(account, auth); + + map<const string, CurrentSyncContext*>::iterator it; + it = __currentSyncJobQueue.find(key); + if (it == __currentSyncJobQueue.end()) + { + return NULL; + } + + LOG_LOGD("CurrentSyncJobQueue::DoesAccAuthExist() Ends"); + return (CurrentSyncContext*)it->second; +} + +CurrentSyncContext* +CurrentSyncJobQueue::GetCurrJobfromKey(string key) +{ + map<const string, CurrentSyncContext*>::iterator it; + it = __currentSyncJobQueue.find(key); + if (it == __currentSyncJobQueue.end()) + { + return NULL; + } + return (CurrentSyncContext*)it->second; +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_CurrentSyncJobQueue.h b/src/sync-service/SyncManager_CurrentSyncJobQueue.h new file mode 100644 index 0000000..5034673 --- /dev/null +++ b/src/sync-service/SyncManager_CurrentSyncJobQueue.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CurrentSyncJobQueue.h + * @brief This is the header file for the CurrentSyncJobQueue class. + */ + +#ifndef SYNC_SERVICE_CURRENT_SYNC_JOB_QUEUE_H +#define SYNC_SERVICE_CURRENT_SYNC_JOB_QUEUE_H + +#include <string> +#include <account.h> +#include <bundle.h> +#include <map> +#include <queue> +#include "SyncManager_CurrentSyncContext.h" + +/*namespace _SyncManager +{ +*/ + +using namespace std; + +class CurrentSyncJobQueue +{ +public: + CurrentSyncJobQueue(void); + + ~CurrentSyncJobQueue(void); + + int AddSyncJobToCurrentSyncQueue(SyncJob* syncJob); + + bool IsJobActive(CurrentSyncContext *pCurrSync); + + int RemoveSyncContextFromCurrentSyncQueue(CurrentSyncContext* pSyncContext); + + CurrentSyncContext* DoesAccAuthExist(account_h account, string auth); + + list<CurrentSyncContext*> GetOperations(void); + + static string ToKey(account_h account, string auth); + + CurrentSyncContext* GetCurrJobfromKey(string key); + + static int OnTimerExpired(void* data); + +private: + map<const string, CurrentSyncContext*> __currentSyncJobQueue; + priority_queue<string> __name; +}; + +//}//_SyncManager +#endif // SYNC_SERVICE_CURRENT_SYNC_JOB_QUEUE_H diff --git a/src/sync-service/SyncManager_DataChangeSyncScheduler.cpp b/src/sync-service/SyncManager_DataChangeSyncScheduler.cpp new file mode 100644 index 0000000..559af43 --- /dev/null +++ b/src/sync-service/SyncManager_DataChangeSyncScheduler.cpp @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_DataChangeListener.cpp + * @brief This is the implementation file for the DataChangeListener class. + */ + + +#include <calendar.h> +#include <contacts.h> +#include <media_content.h> +#include "sync-error.h" +#include "sync_manager.h" +#include "SyncManager_DataChangeSyncScheduler.h" +#include "SyncManager_SyncDefines.h" +#include "SyncManager_SyncManager.h" + + +void OnCalendarBookChanged(const char* view_uri, void* user_data) +{ + LOG_LOGD("On Calendar Book Changed"); + + DataChangeSyncScheduler* pDCScheduler = (DataChangeSyncScheduler*) (user_data); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_CALENDAR); +} + + +void OnCalendarEventChanged(const char* view_uri, void* user_data) +{ + LOG_LOGD("On Calendar Event Changed"); + + DataChangeSyncScheduler* pDCScheduler = (DataChangeSyncScheduler*) (user_data); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_CALENDAR); +} + + +void OnCalendarTodoChanged(const char* view_uri, void* user_data) +{ + LOG_LOGD("On Calendar TODO Changed"); + + DataChangeSyncScheduler* pDCScheduler = (DataChangeSyncScheduler*) (user_data); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_CALENDAR); +} + + +void OnContactsDataChanged(const char* view_uri, void* user_data) +{ + LOG_LOGD("On Contacts Data Changed"); + + DataChangeSyncScheduler* pDCScheduler = (DataChangeSyncScheduler*) (user_data); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_CONTACT); +} + + +void OnMediaContentDataChanged(media_content_error_e error, int pid, media_content_db_update_item_type_e update_item, media_content_db_update_type_e update_type, media_content_type_e media_type, char *uuid, char *path, char *mime_type, void *user_data) +{ + LOG_LOGD("On Media Content Data Changed"); + + media_content_type_e value = media_type; + DataChangeSyncScheduler* pDCScheduler = (DataChangeSyncScheduler*) (user_data); + + switch (media_type) { + case MEDIA_CONTENT_TYPE_IMAGE: + { + LOG_LOGD("Media Content Image Type Data Changed"); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_IMAGE); + break; + } + case MEDIA_CONTENT_TYPE_VIDEO: + { + LOG_LOGD("Media Content Video Type Data Changed"); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_VIDEO); + break; + } + case MEDIA_CONTENT_TYPE_MUSIC: + { + LOG_LOGD("Media Content Music Type Data Changed"); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_MUSIC); + break; + } + case MEDIA_CONTENT_TYPE_SOUND: + { + LOG_LOGD("Media Content Sound Type Data Changed"); + pDCScheduler->HandleDataChangeEvent(SYNC_SUPPORTS_CAPABILITY_SOUND); + break; + } + case MEDIA_CONTENT_TYPE_OTHERS: + { + break; + } + default: + { + LOG_LOGD("Invalid capability is inserted"); + } + } + +} + + +DataChangeSyncScheduler::DataChangeSyncScheduler(void) +{ + calendar_subscription_started = false; + contacts_subscription_started = false; + media_content_subscription_started = false; +} + + +DataChangeSyncScheduler::~DataChangeSyncScheduler(void) +{ + +} + + +int +DataChangeSyncScheduler::SubscribeCalendarCallback(void) +{ + SYNC_LOGE_RET_RES(!calendar_subscription_started, SYNC_ERROR_NONE, "Calendar Callback Already Subscribed"); + int err = VALUE_UNDEFINED; + + err = calendar_connect_with_flags(CALENDAR_CONNECT_FLAG_RETRY); + + if (err != CALENDAR_ERROR_NONE) + LOG_LOGD("Calendar connection failed : %d, %s", err, get_error_message(err)); + + SYNC_LOGE_RET_RES(err == CALENDAR_ERROR_NONE, SYNC_ERROR_INVALID_OPERATION, "Calendar Connection Failed"); + + err = calendar_db_add_changed_cb(_calendar_book._uri, OnCalendarBookChanged, this); + if (err != CALENDAR_ERROR_NONE) { + calendar_disconnect(); + + LOG_LOGD("Subscribing Calendar Callback for BOOK Failed"); + + return SYNC_ERROR_INVALID_OPERATION; + } + + err = calendar_db_add_changed_cb(_calendar_event._uri, OnCalendarEventChanged, this); + if (err != CALENDAR_ERROR_NONE) { + calendar_db_remove_changed_cb(_calendar_book._uri, OnCalendarBookChanged, NULL); + calendar_disconnect(); + + LOG_LOGD("Subscribing Calendar Callback for EVENT Failed"); + + return SYNC_ERROR_INVALID_OPERATION; + } + + err = calendar_db_add_changed_cb(_calendar_todo._uri, OnCalendarTodoChanged, this); + if (err != CALENDAR_ERROR_NONE) { + calendar_db_remove_changed_cb(_calendar_book._uri, OnCalendarBookChanged, NULL); + calendar_db_remove_changed_cb(_calendar_event._uri, OnCalendarEventChanged, NULL); + calendar_disconnect(); + + LOG_LOGD("Subscribing Calendar Callback for TODO Failed"); + + return SYNC_ERROR_INVALID_OPERATION; + } + + calendar_subscription_started = true; + + return SYNC_ERROR_NONE; +} + + +int +DataChangeSyncScheduler::SubscribeContactsCallback(void) +{ + SYNC_LOGE_RET_RES(!contacts_subscription_started, SYNC_ERROR_NONE, "Contacts Callback Already Subscribed"); + int err = VALUE_UNDEFINED; + + err = contacts_connect_with_flags(CONTACTS_CONNECT_FLAG_RETRY); + SYNC_LOGE_RET_RES(err == CONTACTS_ERROR_NONE, SYNC_ERROR_INVALID_OPERATION, "Contacts Connection Failed"); + + err = contacts_db_add_changed_cb(_contacts_contact._uri, OnContactsDataChanged, this); + if (err != CONTACTS_ERROR_NONE) { + contacts_disconnect(); + + LOG_LOGD("Subscribing Contacts Callback for DataChanged Failed"); + + return SYNC_ERROR_INVALID_OPERATION; + } + + contacts_subscription_started = true; + + return SYNC_ERROR_NONE; +} + + +int +DataChangeSyncScheduler::SubscribeMediaContentCallback(void) +{ + SYNC_LOGE_RET_RES(!media_content_subscription_started, SYNC_ERROR_NONE, "Media Content Callback Already Subscribed"); + int err = VALUE_UNDEFINED; + + err = media_content_connect(); + if (err == MEDIA_CONTENT_ERROR_DB_FAILED) + LOG_LOGD("media content connection error [%s]", get_error_message(err)); + SYNC_LOGE_RET_RES(err == MEDIA_CONTENT_ERROR_NONE, SYNC_ERROR_INVALID_OPERATION, "Media Content Connection Failed"); + + err = media_content_set_db_updated_cb(OnMediaContentDataChanged, this); + if (err != MEDIA_CONTENT_ERROR_NONE) { + media_content_disconnect(); + + LOG_LOGD("Subscribing Media Content Callback for DataChanged Failed"); + + return SYNC_ERROR_INVALID_OPERATION; + } + + media_content_subscription_started = true; + + return SYNC_ERROR_NONE; +} + + +int +DataChangeSyncScheduler::UnSubscribeCalendarCallback(void) +{ + SYNC_LOGE_RET_RES(calendar_subscription_started, SYNC_ERROR_NONE, "Calendar Callback Already UnSubscribed"); + + calendar_db_remove_changed_cb(_calendar_book._uri, OnCalendarBookChanged, NULL); + calendar_db_remove_changed_cb(_calendar_event._uri, OnCalendarEventChanged, NULL); + calendar_db_remove_changed_cb(_calendar_todo._uri, OnCalendarTodoChanged, NULL); + calendar_disconnect(); + + calendar_subscription_started = false; + + return SYNC_ERROR_NONE; +} + + +int +DataChangeSyncScheduler::UnSubscribeContactsCallback(void) +{ + SYNC_LOGE_RET_RES(contacts_subscription_started, SYNC_ERROR_NONE, "Contacts Callback Already UnSubscribed"); + + contacts_db_remove_changed_cb(_contacts_contact._uri, OnContactsDataChanged, NULL); + contacts_disconnect(); + + contacts_subscription_started = false; + + return SYNC_ERROR_NONE; +} + + +int +DataChangeSyncScheduler::UnSubscribeMediaContentCallback(void) +{ + SYNC_LOGE_RET_RES(media_content_subscription_started, SYNC_ERROR_NONE, "Media Content Callback Already UnSubscribed"); + + media_content_unset_db_updated_cb(); + media_content_disconnect(); + + media_content_subscription_started = false; + + return SYNC_ERROR_NONE; +} + + +int +DataChangeSyncScheduler::RegisterDataChangeListeners(void) +{ + int err = SYNC_ERROR_NONE; + + err = SubscribeCalendarCallback(); + if (err != SYNC_ERROR_NONE) { + LOG_LOGD("Registration of Calendar DataChangeListener Failed"); + return SYNC_ERROR_INVALID_OPERATION; + } + + err = SubscribeContactsCallback(); + if (err != SYNC_ERROR_NONE) { + LOG_LOGD("Registration of Contacts DataChangeListener Failed"); + return SYNC_ERROR_INVALID_OPERATION; + } + + err = SubscribeMediaContentCallback(); + if (err != SYNC_ERROR_NONE) { + LOG_LOGD("Registration of Media Content DataChangeListener Failed"); + return SYNC_ERROR_INVALID_OPERATION; + } + + LOG_LOGD("Registration of DataChangeListener Successfully Ends"); + + return SYNC_ERROR_NONE; +} + + +int +DataChangeSyncScheduler::DeRegisterDataChangeListeners(void) +{ + int err = VALUE_UNDEFINED; + + err = UnSubscribeCalendarCallback(); + if (err != SYNC_ERROR_NONE) { + LOG_LOGD("DeRegistration of Calendar DataChangeListener Failed"); + return SYNC_ERROR_INVALID_OPERATION; + } + + err = UnSubscribeContactsCallback(); + if (err != SYNC_ERROR_NONE) { + LOG_LOGD("DeRegistration of Contacts DataChangeListener Failed"); + return SYNC_ERROR_INVALID_OPERATION; + } + + err = UnSubscribeMediaContentCallback(); + if (err != SYNC_ERROR_NONE) { + LOG_LOGD("DeRegistration of Media Content DataChangeListener Failed"); + return SYNC_ERROR_INVALID_OPERATION; + } + + LOG_LOGD("DeRegistration of DataChangeListener Successfully Ends"); + + return SYNC_ERROR_NONE; +} + + +void +DataChangeSyncScheduler::HandleDataChangeEvent(const char* pSyncCapability) +{ + LOG_LOGD("DataChangeSyncScheduler::HandleDataChangeEvent() Starts"); + + pair<std::multimap<string, DataSyncJob*>::iterator, std::multimap<string, DataSyncJob*>::iterator> ret; + ret = __dataChangeSyncJobs.equal_range(pSyncCapability); + + for (std::multimap<string, DataSyncJob*>::iterator it = ret.first; it != ret.second; ++it) + { + DataSyncJob* pDataSyncJob = it->second; + SyncManager::GetInstance()->ScheduleSyncJob(pDataSyncJob, false); + } + + SyncManager::GetInstance()->AlertForChange(); + + LOG_LOGD("DataChangeSyncScheduler::HandleDataChangeEvent() Ends"); +} + + +int +DataChangeSyncScheduler::AddDataSyncJob(string capability, DataSyncJob* dataSyncJob) +{ + __dataChangeSyncJobs.insert(make_pair(capability, dataSyncJob)); + + return SYNC_ERROR_NONE; +} + + +void +DataChangeSyncScheduler::RemoveDataSyncJob(DataSyncJob* dataSyncJob) +{ + typedef multimap<string, DataSyncJob*>::iterator iterator; + std::pair<iterator, iterator> iterpair = __dataChangeSyncJobs.equal_range(dataSyncJob->__capability); + + iterator it = iterpair.first; + for (; it != iterpair.second; ++it) + { + if (it->second == dataSyncJob) + { + __dataChangeSyncJobs.erase(it); + break; + } + } +} diff --git a/src/sync-service/SyncManager_DataChangeSyncScheduler.h b/src/sync-service/SyncManager_DataChangeSyncScheduler.h new file mode 100644 index 0000000..d7d2797 --- /dev/null +++ b/src/sync-service/SyncManager_DataChangeSyncScheduler.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_DataChangeSyncScheduler.h + * @brief This is the header file for the DataChangeSyncScheduler class. + */ + +#ifndef _SYNC_SERVICE_DATA_CHANGE_SYNC_SCHEDULER_H_ +#define _SYNC_SERVICE_DATA_CHANGE_SYNC_SCHEDULER_H_ + +#include "SyncManager_DataSyncJob.h" +#include <map> + +class DataChangeSyncScheduler +{ +public: + bool calendar_subscription_started; + bool contacts_subscription_started; + bool media_content_subscription_started; + +public: + DataChangeSyncScheduler(void); + + ~DataChangeSyncScheduler(void); + + int RegisterDataChangeListeners(void); + + int DeRegisterDataChangeListeners(void); + + int AddDataSyncJob(string capability, DataSyncJob* dataSyncJob); + + void RemoveDataSyncJob(DataSyncJob* dataSyncJob); + + void HandleDataChangeEvent(const char* syncCapability); + + //void OnCalendarDataChanged(int value); + + //void OnContactsDataChanged(int value); + + //void OnMediaContentDataChanged(media_content_type_e media_content_type); + +private: + int SubscribeCalendarCallback(void); + + int SubscribeContactsCallback(void); + + int SubscribeMediaContentCallback(void); + + int UnSubscribeCalendarCallback(void); + + int UnSubscribeContactsCallback(void); + + int UnSubscribeMediaContentCallback(void); + +private: + std::multimap<string, DataSyncJob*> __dataChangeSyncJobs; +}; + + +#endif // _SYNC_SERVICE_DATA_CHANGE_SYNC_SCHEDULER_H_ diff --git a/src/sync-service/SyncManager_DataSyncJob.cpp b/src/sync-service/SyncManager_DataSyncJob.cpp new file mode 100644 index 0000000..81948f9 --- /dev/null +++ b/src/sync-service/SyncManager_DataSyncJob.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_DataSyncJob.cpp + * @brief This is the implementation file for the DataSyncJob class. + */ + +#include "SyncManager_SyncManager.h" +#include "SyncManager_DataSyncJob.h" + +/*namespace _SyncManager +{*/ + + +DataSyncJob::~DataSyncJob(void) +{ + +} + + +DataSyncJob::DataSyncJob(const string appId, const string syncJobName, int accountId, bundle* pUserData, int syncOption, int syncJobId, SyncType type, string capability) + : SyncJob(appId, syncJobName, accountId, pUserData, syncOption, syncJobId, type) + , __capability(capability) +{ + +} + + +DataSyncJob::DataSyncJob(const DataSyncJob& other) + : SyncJob(other) +{ +/* this->__accountHandle = other.__accountHandle; + this->__capability = other.__capability; + this->__pExtras = bundle_dup(other.__pExtras); + this->__period = other.__period; + this->__syncAdapter = other.__syncAdapter;*/ +} + + +DataSyncJob& +DataSyncJob::operator= (const DataSyncJob& other) +{ + /*this->__accountHandle = other.__accountHandle; + this->__capability = other.__capability; + this->__pExtras = bundle_dup(other.__pExtras); + this->__period = other.__period; + this->__syncAdapter = other.__syncAdapter;*/ + + return *this; +} + +void +DataSyncJob::Reset(int accountId, bundle* pUserData, int syncOption, string capability) +{ + SyncJob::Reset(accountId, pUserData, syncOption); + __capability = capability; +} + + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_DataSyncJob.h b/src/sync-service/SyncManager_DataSyncJob.h new file mode 100644 index 0000000..91a8088 --- /dev/null +++ b/src/sync-service/SyncManager_DataSyncJob.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_DataSyncJob.h + * @brief This is the header file for the DataSyncJob class. + */ + +#ifndef SYNC_SERVICE_DATA_SYNC_JOB_H +#define SYNC_SERVICE_DATA_SYNC_JOB_H + +#include <string> +#include <vector> +#include <bundle.h> +#include <bundle_internal.h> +#include <account.h> +#include "SyncManager_SyncJob.h" + +/*namespace _SyncManager +{ +*/ +using namespace std; + +class DataSyncJob : public SyncJob +{ +public: + ~DataSyncJob(void); + + DataSyncJob(const string appId, const string syncJobName, int accountId, bundle* pUserData, int syncOption, int syncJobId, SyncType type, string capability); + + DataSyncJob(const DataSyncJob&); + + DataSyncJob& operator=(const DataSyncJob&); + + void Reset(int accountId, bundle* pUserData, int syncOption, string capability); + + virtual SyncType GetSyncType() + { + return __syncType; + } + +public: + string __capability; +}; +//}//_SyncManager +#endif// SYNC_SERVICE_PERIODIC_SYNC_H diff --git a/src/sync-service/SyncManager_ISyncJob.h b/src/sync-service/SyncManager_ISyncJob.h new file mode 100644 index 0000000..380b2f4 --- /dev/null +++ b/src/sync-service/SyncManager_ISyncJob.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_ISyncJob.h + * @brief This is the header file for the SyncJob class. + */ + + +#ifndef SYNC_SERVICE_ISYNC_JOB_H +#define SYNC_SERVICE_ISYNC_JOB_H + + +/*namespace _SyncManager +{ +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + +using namespace std; + +enum SyncType +{ + SYNC_TYPE_ON_DEMAND = 0, + SYNC_TYPE_PERIODIC, + SYNC_TYPE_DATA_CHANGE, + SYNC_TYPE_UNKNOWN +}; + +class ISyncJob +{ +public: + ISyncJob() + : __syncJobId(-1) + { + + } + + ISyncJob(int syncJobId, SyncType type) + : __syncJobId(syncJobId) + , __syncType(type) + { + + } + + virtual ~ISyncJob() + { + + } + + virtual SyncType GetSyncType() = 0; + + virtual int GetSyncJobId() + { + return __syncJobId; + } + +protected: + int __syncJobId; + SyncType __syncType; +}; + +#ifdef __cplusplus +} +#endif +//}//_SyncManager +#endif//SYNC_SERVICE_ISYNC_JOB_H diff --git a/src/sync-service/SyncManager_NetworkChangeListener.cpp b/src/sync-service/SyncManager_NetworkChangeListener.cpp new file mode 100644 index 0000000..33ec836 --- /dev/null +++ b/src/sync-service/SyncManager_NetworkChangeListener.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_NetworkChangeListener.cpp + * @brief This is the implementation file for the NetworkChangeListener class. + */ + + +#include "SyncManager_SyncManager.h" +#include "SyncManager_NetworkChangeListener.h" +#include "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{*/ + + +void OnConnectionChanged(connection_type_e type, void *user_data) +{ + LOG_LOGD("Network connection changed %d", type); + + switch (type) + { + case CONNECTION_TYPE_WIFI: + { + SyncManager::GetInstance()->OnWifiStatusChanged(true); + break; + } + case CONNECTION_TYPE_CELLULAR: + { + SyncManager::GetInstance()->OnDNetStatusChanged(true); + break; + } + case CONNECTION_TYPE_BT: + { + SyncManager::GetInstance()->OnBluetoothStatusChanged(true); + break; + } + case CONNECTION_TYPE_DISCONNECTED: + { + SyncManager::GetInstance()->OnWifiStatusChanged(false); + SyncManager::GetInstance()->OnDNetStatusChanged(false); + SyncManager::GetInstance()->OnBluetoothStatusChanged(false); + break; + } + default: + break; + } +} + + +NetworkChangeListener::NetworkChangeListener(void) + : connection(NULL) +{ + int ret = connection_create(&connection); + if (ret != CONNECTION_ERROR_NONE) + { + LOG_LOGD("Create connection failed %d, %s", ret, get_error_message(ret)); + } +} + + +NetworkChangeListener::~NetworkChangeListener(void) +{ + if (connection) + { + connection_destroy(connection); + } +} + + +bool +NetworkChangeListener::IsWifiConnected() +{ + int ret; + connection_wifi_state_e state = CONNECTION_WIFI_STATE_DEACTIVATED; + ret = connection_get_wifi_state(connection, &state); + if (ret != CONNECTION_ERROR_NONE) + { + LOG_LOGD("Connection wifi failure %d, %s", ret, get_error_message(ret)); + } + return (state == CONNECTION_WIFI_STATE_CONNECTED); +} + + +bool +NetworkChangeListener::IsDataConnectionPresent() +{ + int ret; + connection_cellular_state_e state = CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE; + ret = connection_get_cellular_state(connection, &state); + if (ret == CONNECTION_ERROR_NOT_SUPPORTED) { + LOG_LOGD("Telephony does not be supported on this target"); + } else if (ret != CONNECTION_ERROR_NONE) { + LOG_LOGD("Connection cellular failure %d, %s", ret, get_error_message(ret)); + } + + return (state == CONNECTION_CELLULAR_STATE_CONNECTED); +} + + +int +NetworkChangeListener::RegisterNetworkChangeListener(void) +{ + int ret = CONNECTION_ERROR_NONE; + ret = connection_set_type_changed_cb(connection, OnConnectionChanged, NULL); + if (ret != CONNECTION_ERROR_NONE) + { + LOG_LOGD("Registration of network change listener failed %d, %s", ret, get_error_message(ret)); + } + return ret; +} + + +int +NetworkChangeListener::DeRegisterNetworkChangeListener(void) +{ + LOG_LOGD("Removing network change listener"); + + int ret; + ret = connection_unset_type_changed_cb(connection); + if (ret != CONNECTION_ERROR_NONE) + { + LOG_LOGD("Removal of network change listener failed"); + } + + return ret; +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_NetworkChangeListener.h b/src/sync-service/SyncManager_NetworkChangeListener.h new file mode 100644 index 0000000..b5054f0 --- /dev/null +++ b/src/sync-service/SyncManager_NetworkChangeListener.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_NetworkChangeListener.h + * @brief This is the header file for the NetworkChangeListener class. + */ + + +#ifndef SYNC_SERVICE_NETWORK_CHANGE_LISTENER_H +#define SYNC_SERVICE_NETWORK_CHANGE_LISTENER_H + +#include <net_connection.h> + +/*namespace _SyncManager +{ +*/ + +class NetworkChangeListener +{ + +public: + NetworkChangeListener(void); + + ~NetworkChangeListener(void); + + int RegisterNetworkChangeListener(void); + + bool IsWifiConnected(); + + bool IsDataConnectionPresent(); + + int DeRegisterNetworkChangeListener(void); +private: + connection_h connection; +}; +//}//_SyncManager +#endif // SYNC_SERVICE_NETWORK_CHANGE_LISTENER_H diff --git a/src/sync-service/SyncManager_PeriodicSyncJob.cpp b/src/sync-service/SyncManager_PeriodicSyncJob.cpp new file mode 100644 index 0000000..7ad91eb --- /dev/null +++ b/src/sync-service/SyncManager_PeriodicSyncJob.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_PeriodicSyncJob.cpp + * @brief This is the implementation file for the PeriodicSyncJob class. + */ + +#include "SyncManager_SyncManager.h" +#include "SyncManager_PeriodicSyncJob.h" + +/*namespace _SyncManager +{*/ + + +PeriodicSyncJob::~PeriodicSyncJob(void) +{ + +} + + +PeriodicSyncJob::PeriodicSyncJob(const string appId, const string syncJobName, int accountId, bundle* pUserData, int syncOption, int syncJobId, SyncType type, long frequency) + : SyncJob(appId, syncJobName, accountId, pUserData, syncOption, syncJobId, type) + , __period(frequency) +{ + +} + + +PeriodicSyncJob::PeriodicSyncJob(const PeriodicSyncJob& other) + : SyncJob(other) +{ +/* this->__accountHandle = other.__accountHandle; + this->__capability = other.__capability; + this->__pExtras = bundle_dup(other.__pExtras); + this->__period = other.__period; + this->__syncAdapter = other.__syncAdapter;*/ +} + + +PeriodicSyncJob& +PeriodicSyncJob::operator = (const PeriodicSyncJob& other) +{ + /*this->__accountHandle = other.__accountHandle; + this->__capability = other.__capability; + this->__pExtras = bundle_dup(other.__pExtras); + this->__period = other.__period; + this->__syncAdapter = other.__syncAdapter;*/ + + return *this; +} + + +bool +PeriodicSyncJob::operator==(const PeriodicSyncJob& other) +{/* + if ((SyncManager::GetInstance())->AreAccountsEqual(this->__accountHandle, other.__accountHandle) + && (this->__capability).compare(other.__capability) == 0 + && this->__period == other.__period + && this->__syncAdapter == other.__syncAdapter + && IsExtraEqual((PeriodicSyncJob*)&other)) + { + return true; + }*/ + return false; +} + + +bool +PeriodicSyncJob::IsExtraEqual(PeriodicSyncJob* pJob) +{ + /*bundle* pExtra1 = this->__pExtras; + bundle* pExtra2 = pJob->__pExtras; + + if (pExtra2 == NULL || pExtra1 == NULL) + { + return NULL; + } + + char **argv1; + int argc1 = bundle_export_to_argv(pExtra1, &argv1); + + char **argv2; + int argc2 = bundle_export_to_argv(pExtra2, &argv2); + + if (argc1 != argc2) + { + return false; + } + + int index1 = 0; + int index2 = 0; + for (index1 = 2; index1 < argc1 ; index1 = index1 + 2) + { + const char* pValue1 = bundle_get_val(pExtra1, argv1[index1]); + string key1(argv1[index1]); + bool found = false; + + for (index2 = 2; index2 < argc2 ; index2 = index2 + 2) + { + const char* pValue2 = bundle_get_val(pExtra2, argv2[index2]); + string key2(argv2[index2]); + + if (strcmp(pValue1, pValue2) == 0 && key1.compare(key2) == 0) + { + found = true; + break; + } + } + if (!found) + { + bundle_free_exported_argv(argc1, &argv1); + bundle_free_exported_argv(argc2, &argv2); + + return false; + } + } + + bundle_free_exported_argv(argc1, &argv1); + bundle_free_exported_argv(argc2, &argv2);*/ + + return true; +} + +void +PeriodicSyncJob::Reset(int accountId, bundle* pUserData, int syncOption, long frequency) +{ + SyncJob::Reset(accountId, pUserData, syncOption); + __period = frequency; +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_PeriodicSyncJob.h b/src/sync-service/SyncManager_PeriodicSyncJob.h new file mode 100644 index 0000000..32c6a1a --- /dev/null +++ b/src/sync-service/SyncManager_PeriodicSyncJob.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_PeriodicSyncJob.h + * @brief This is the header file for the PeriodicSyncJob class. + */ + +#ifndef SYNC_SERVICE_PERIODIC_SYNC_H +#define SYNC_SERVICE_PERIODIC_SYNC_H + +#include <string> +#include <vector> +#include <bundle.h> +#include <bundle_internal.h> +#include <account.h> +#include "SyncManager_SyncJob.h" + +/*namespace _SyncManager +{ +*/ +using namespace std; + +class PeriodicSyncJob : public SyncJob +{ +public: + ~PeriodicSyncJob(void); + + PeriodicSyncJob(const string appId, const string syncJobName, int accountId, bundle* pUserData, int syncOption, int syncJobId, SyncType type, long frequency); + + PeriodicSyncJob(const PeriodicSyncJob&); + + PeriodicSyncJob& operator=(const PeriodicSyncJob&); + + void Reset(int accountId, bundle* pUserData, int syncOption, long frequency); + + bool operator==(const PeriodicSyncJob&); + + bool IsExtraEqual(PeriodicSyncJob* pJob); + + virtual SyncType GetSyncType() + { + return __syncType; + } +private: + +public: + long __period; +}; +//}//_SyncManager +#endif// SYNC_SERVICE_PERIODIC_SYNC_H diff --git a/src/sync-service/SyncManager_PeriodicSyncScheduler.cpp b/src/sync-service/SyncManager_PeriodicSyncScheduler.cpp new file mode 100644 index 0000000..b5cf94f --- /dev/null +++ b/src/sync-service/SyncManager_PeriodicSyncScheduler.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_PeriodicSyncScheduler.cpp + * @brief This is the implementation file for the PeriodicSyncScheduler class. + */ + + +#include <calendar.h> +#include <contacts.h> +#include <media_content.h> +#include "sync-error.h" +#include "SyncManager_PeriodicSyncScheduler.h" +#include "SyncManager_SyncDefines.h" +#include "SyncManager_SyncManager.h" + + +PeriodicSyncScheduler::~PeriodicSyncScheduler(void) +{ + +} + + +PeriodicSyncScheduler::PeriodicSyncScheduler(void) +{ + +} + + +int +PeriodicSyncScheduler::OnAlarmExpired(alarm_id_t alarm_id, void *user_param) +{ + LOG_LOGD("Alarm id %d", alarm_id); + + PeriodicSyncScheduler* pPeriodicSyncScheduler = (PeriodicSyncScheduler*) user_param; + map<int, PeriodicSyncJob*>::iterator itr = pPeriodicSyncScheduler->__activePeriodicSyncJobs.find(alarm_id); + if(itr != pPeriodicSyncScheduler->__activePeriodicSyncJobs.end()) + { + PeriodicSyncJob* pSyncJob = pPeriodicSyncScheduler->__activePeriodicSyncJobs[alarm_id]; + + LOG_LOGD("Alarm expired for [%s]", pSyncJob->__key.c_str()); + + SyncManager::GetInstance()->ScheduleSyncJob(pSyncJob, true); + } + + return true; +} + + +int +PeriodicSyncScheduler::RemoveAlarmForPeriodicSyncJob(PeriodicSyncJob* pSyncJob) +{ + string jobKey = pSyncJob->__key; + map<string, int>::iterator iter = __activeAlarmList.find(jobKey); + if (iter != __activeAlarmList.end()) + { + alarm_id_t alarm = iter->second; + int ret = alarmmgr_remove_alarm(alarm); + SYNC_LOGE_RET_RES(ret == ALARMMGR_RESULT_SUCCESS, SYNC_ERROR_SYSTEM, "alarm remove failed for [%s], [%d]", jobKey.c_str(), ret); + + __activeAlarmList.erase(iter); + __activePeriodicSyncJobs.erase(alarm); + LOG_LOGD("Removed alarm for [%s], [%d]", jobKey.c_str(), alarm); + } + else + { + LOG_LOGD("No active alarm found for [%s]", jobKey.c_str()); + } + return SYNC_ERROR_NONE; +} + + +int +PeriodicSyncScheduler::SchedulePeriodicSyncJob(PeriodicSyncJob* periodicSyncJob) +{ + string jobKey = periodicSyncJob->__key; + + /// Remove previous alarms, if set already + int ret = RemoveAlarmForPeriodicSyncJob(periodicSyncJob); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, SYNC_ERROR_SYSTEM, "Failed to remove previous alarm for [%s], [%d]", jobKey.c_str(), ret); + + alarm_id_t alarm_id; + ret = alarmmgr_add_periodic_alarm_withcb(periodicSyncJob->__period, QUANTUMIZE, PeriodicSyncScheduler::OnAlarmExpired, this, &alarm_id); + if (ret == ALARMMGR_RESULT_SUCCESS) + { + LOG_LOGD("Alarm added for %ld min, id %ld", periodicSyncJob->__period, alarm_id); + + __activePeriodicSyncJobs.insert(make_pair<int, PeriodicSyncJob*> (alarm_id, periodicSyncJob)); + __activeAlarmList.insert(make_pair(jobKey, alarm_id)); + } + else + { + LOG_LOGD("Failed to add Alarm for %ld min, ret %d", periodicSyncJob->__period, ret); + ret = SYNC_ERROR_SYSTEM; + } + + LOG_LOGD("Active periodic alarm count, %d", __activePeriodicSyncJobs.size()); + return ret; +} + diff --git a/src/sync-service/SyncManager_PeriodicSyncScheduler.h b/src/sync-service/SyncManager_PeriodicSyncScheduler.h new file mode 100644 index 0000000..660b422 --- /dev/null +++ b/src/sync-service/SyncManager_PeriodicSyncScheduler.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_PeriodicSyncScheduler.h + * @brief This is the header file for the PeriodicSyncScheduler class. + */ + +#ifndef _SYNC_SERVICE_PERIODIC_SYNC_SCHEDULER_H_ +#define _SYNC_SERVICE_PERIODIC_SYNC_SCHEDULER_H_ + +#include <alarm.h> +#include <map> +#include "SyncManager_PeriodicSyncJob.h" + +class PeriodicSyncScheduler +{ + +public: + PeriodicSyncScheduler(void); + + ~PeriodicSyncScheduler(void); + + static int OnAlarmExpired(alarm_id_t alarm_id, void *user_param); + + int RemoveAlarmForPeriodicSyncJob(PeriodicSyncJob* pSyncJob); + + int SchedulePeriodicSyncJob(PeriodicSyncJob* dataSyncJob); + +private: + +private: + std::map<int, PeriodicSyncJob*> __activePeriodicSyncJobs; + std::map<string, int> __activeAlarmList; +}; + + +#endif // _SYNC_SERVICE_DATA_CHANGE_SYNC_SCHEDULER_H_ diff --git a/src/sync-service/SyncManager_RepositoryEngine.cpp b/src/sync-service/SyncManager_RepositoryEngine.cpp new file mode 100644 index 0000000..938325a --- /dev/null +++ b/src/sync-service/SyncManager_RepositoryEngine.cpp @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_RepositoryEngine.cpp + * @brief This is the implementation file for the RepositoryEngine class. + */ + +#include <sys/time.h> +#include <iostream> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include <errno.h> +#include <fstream> +#include <sstream> +#include "SyncManager_RepositoryEngine.h" +#include "SyncManager_SyncDefines.h" +#include "SyncManager_SyncJobQueue.h" +#include "SyncManager_SyncManager.h" +#include "SyncManager_SyncAdapterAggregator.h" +#include "SyncManager_SyncJobsAggregator.h" +#include "SyncManager_SyncJobsInfo.h" +#include "sync-log.h" +#include "sync-error.h" + + +/*namespace _SyncManager +{ +*/ + +#define SYNC_DIRECTORY "sync-manager"; + +#ifndef MAX +#define MAX(a, b) a>b?a:b +#endif + + +//xml Tags Definitions +//For Accounts.xml +static char PATH_ACCOUNT[] = "/opt/usr/data/sync-manager/accounts.xml"; +static char PATH_SYNCJOBS[] = "/opt/usr/data/sync-manager/syncjobs.xml"; +static char PATH_SYNCADAPTERS[] = "/opt/usr/data/sync-manager/syncadapters.xml"; +static char PATH_STATUS[] = "/opt/usr/data/sync-manager/statusinfo.bin"; +static const xmlChar _VERSION[] = "1.0"; + + +static const xmlChar XML_NODE_ACCOUNTS[] = "accounts"; +static const xmlChar XML_ATTR_NEXT_CAPABILITY_ID[] = "nextCapabilityId"; +static const xmlChar XML_ATTR_SYNC_RANDOM_OFFSET[] = "randomOffsetInSec"; + +static const xmlChar XML_NODE_CAPABILITY[] = "capability"; +static const xmlChar XML_ATTR_CAPABILITY_ID[] = "id"; +static const xmlChar XML_ATTR_APP_ID[] = "appId"; +static const xmlChar XML_ATTR_ENABLED[] = "enabled"; +static const xmlChar XML_ATTR_ACCOUNT_ID[] = "accountId"; +static const xmlChar XML_ATTR_ACCOUNT_TYPE[] = "accountType"; +static const xmlChar XML_ATTR_CAPABILITY[] = "capability"; +static const xmlChar XML_ATTR_SYNCABLE[] = "syncable"; + +static const xmlChar XML_NODE_PERIODIC_SYNC[] = "periodicSync"; +static const xmlChar XML_ATTR_PERIODIC_SYNC_PEIOD[] = "period"; +static const xmlChar XML_ATTR_PERIODIC_SYNC_FLEX[] = "flex"; + +static const xmlChar XML_NODE_SYNC_EXTRA[] = "extra"; +static const xmlChar XML_ATTR_SYNC_EXTRA_KEY[] = "key"; +static const xmlChar XML_ATTR_SYNC_EXTRA_VALUE[] = "value"; + +static const xmlChar XML_NODE_JOBS[] = "jobs"; +static const xmlChar XML_ATTR_JOBS_COUNT[] = "count"; + +static const xmlChar XML_NODE_PACKAGE[] = "package"; +static const xmlChar XML_NODE_SYNC_JOB[] = "job"; +static const xmlChar XML_ATTR_JOB_APP_ID[] = "appId"; +static const xmlChar XML_ATTR_JOB_ACCOUNT_ID[] = "accountId"; +static const xmlChar XML_ATTR_JOB_ID[] = "jobId"; +static const xmlChar XML_ATTR_JOB_NAME[] = "jobName"; +static const xmlChar XML_ATTR_JOB_CAPABILITY[] = "capability"; +static const xmlChar XML_ATTR_JOB_OPTION_NORETRY[] = "noRetry"; +static const xmlChar XML_ATTR_JOB_OPTION_EXPEDIT[] = "expedit"; +static const xmlChar XML_ATTR_JOB_TYPE[] = "syncType"; + + +static const xmlChar XML_NODE_SYNCADAPTERS[] = "sync-adapters"; +static const xmlChar XML_ATTR_COUNT[] = "count"; + +static const xmlChar XML_NODE_SYNCADAPTER[] = "sync-adapter"; +static const xmlChar XML_ATTR_SYNCADAPTER_SERVICE_APP_ID[] = "service-app-id"; +static const xmlChar XML_ATTR_PACKAGE_ID[] = "package-id"; + +static const string SYNCABLE_STATE_UNKNOWN = "unknown"; + +const long RepositoryEngine::NOT_IN_BACKOFF_MODE = -1; +const long RepositoryEngine::DEFAULT_PERIOD_SEC = 24*60*60; // 1 day +const double RepositoryEngine::DEFAULT_FLEX_PERCENT = 0.04; // 4 percent +const long RepositoryEngine::DEFAULT_MIN_FLEX_ALLOWED_SEC = 5; // 5 seconds + +#define ID_FOR_ACCOUNT_LESS_SYNC -2 + +RepositoryEngine* RepositoryEngine::__pInstance = NULL; + + +RepositoryEngine* +RepositoryEngine::GetInstance(void) +{ + if (!__pInstance) + { + __pInstance = new (std::nothrow) RepositoryEngine(); + if (__pInstance == NULL) + { + LOG_LOGD("Failed to construct RepositoryEngine"); + return NULL; + } + } + + return __pInstance; +} + + +RepositoryEngine::~RepositoryEngine(void) +{ + pthread_mutex_destroy(&__capabilityInfoMutex); +} + + +RepositoryEngine::RepositoryEngine(void) +{ + if (pthread_mutex_init(&__capabilityInfoMutex, NULL) != 0) + { + LOG_LOGD("\n __syncJobQueueMutex init failed\n"); + return; + } +} + + +void +RepositoryEngine::OnBooting() +{ + ReadSyncAdapters(); + ReadSyncJobsData(); +} + +//Test method +/* +static void +bndl_iterator_test(const char* pKey, const char* pVal, void* pData) +{ + LOG_LOGD("SyncJobQueue sync extra key %s val %s", pKey, pVal); +} +*/ + +void +RepositoryEngine::ReadSyncJobsData(void) +{ + LOG_LOGD("Read Sync jobs"); + + //Parse the Xml file + char* pDocName; + xmlDocPtr doc = NULL; + xmlNodePtr cur = NULL; + + pDocName = PATH_SYNCJOBS; + doc = xmlParseFile(pDocName); + + if (doc == NULL) + { + LOG_LOGD("Failed to parse syncjobs.xml."); + return; + } + + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + LOG_LOGD("Found empty document while parsing syncjobs.xml."); + xmlFreeDoc(doc); + return; + } + + //Parse sync jobs + if (xmlStrcmp(cur->name, XML_NODE_JOBS)) + { + LOG_LOGD("Found empty document while parsing syncjobs.xml."); + xmlFreeDoc(doc); + return; + } + else + { + xmlChar* pTotalJobsCount = xmlGetProp(cur, XML_ATTR_JOBS_COUNT); + int totalcount = (pTotalJobsCount == NULL) ? 0 : atoi((char*)pTotalJobsCount); + LOG_LOGD("Total Sync jobs [%d]", totalcount); + + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if (!xmlStrcmp(cur->name, XML_NODE_PACKAGE)) + { + xmlChar* pPackageId; + xmlChar* pJobsCount; + + pPackageId = xmlGetProp(cur, XML_ATTR_PACKAGE_ID); + pJobsCount = xmlGetProp(cur, XML_ATTR_JOBS_COUNT); + + int count = (pJobsCount == NULL) ? 0 : atoi((char*)pJobsCount); + LOG_LOGD("Sync jobs for package [%s] [%d]", pPackageId, count); + + xmlNodePtr curJob = cur->xmlChildrenNode; + while (curJob != NULL) + { + if (!xmlStrcmp(curJob->name, XML_NODE_SYNC_JOB)) + { + ParseSyncJobsN(curJob, pPackageId); + } + curJob = curJob->next; + } + } + + cur = cur->next; + } + } + + xmlFreeDoc(doc); + + // Test code + /* + int size = SyncManager::GetInstance()->GetSyncJobQueue()->GetSyncJobQueue().size(); + map<const string, SyncJob*> queue = SyncManager::GetInstance()->GetSyncJobQueue()->GetSyncJobQueue(); + map<const string, SyncJob*>::iterator it; + LOG_LOGD("SyncJobQueue size %d", size); + for (it = queue.begin(); it != queue.end(); it++) + { + SyncJob* pJob = it->second; + LOG_LOGD("SyncJobQueue appId %s", pJob->appId.c_str()); + LOG_LOGD("SyncJobQueue capability %s", pJob->capability.c_str()); + LOG_LOGD("SyncJobQueue backoff %ld, delay %ld", pJob->backoff, pJob->delayUntil); + LOG_LOGD("SyncJobQueue key %s, reason %d, source %d", pJob->key.c_str(), pJob->reason, pJob->syncSource); + //string str; + //str.append("["); + //bundle_iterate(pJob->pExtras, bndl_iterator_test, &str); + //str.append("]"); + } + */ + //Till here +} + +void +RepositoryEngine::ReadSyncAdapters(void) +{ + LOG_LOGD("Reading sync adapters"); + + //Parse the Xml file + char* pDocName; + xmlDocPtr doc = NULL; + xmlNodePtr cur = NULL; + + pDocName = PATH_SYNCADAPTERS; + doc = xmlParseFile(pDocName); + + if (doc == NULL) + { + LOG_LOGD("Failed to parse syncadapters.xml."); + return; + } + + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + LOG_LOGD("Found empty document while parsing syncadapters.xml."); + xmlFreeDoc(doc); + return; + } + + //Parse sync jobs + if (xmlStrcmp(cur->name, XML_NODE_SYNCADAPTERS)) + { + LOG_LOGD("Found empty document while parsing syncadapters.xml."); + xmlFreeDoc(doc); + return; + } + else + { + xmlChar* pSACount; + + pSACount = xmlGetProp(cur, XML_ATTR_COUNT); + int count = (pSACount == NULL) ? 0 : atoi((char*)pSACount); + + LOG_LOGD("sync adapter count %d", count); + + SyncAdapterAggregator* pAggregator = SyncManager::GetInstance()->GetSyncAdapterAggregator(); + + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if (!xmlStrcmp(cur->name, XML_NODE_SYNCADAPTER)) + { + xmlChar* pServiceAppId = xmlGetProp(cur, XML_ATTR_SYNCADAPTER_SERVICE_APP_ID); + xmlChar* pPackageId = xmlGetProp(cur, XML_ATTR_PACKAGE_ID); + + pAggregator->AddSyncAdapter((char*)pPackageId, (char*)pServiceAppId); + } + cur = cur->next; + } + pAggregator->dumpSyncAdapters(); + } + + xmlFreeDoc(doc); + + LOG_LOGD("sync adapters are initialized"); +} + + +static void +bndl_iterator(const char* pKey, const char* pVal, void* pData) +{ + xmlNodePtr parentNode = *((xmlNodePtr*)pData); + + xmlNodePtr extraNode = xmlNewChild(parentNode, NULL, XML_NODE_SYNC_EXTRA, NULL); + xmlNewProp(extraNode, XML_ATTR_SYNC_EXTRA_KEY, (const xmlChar*)pKey); + xmlNewProp(extraNode, XML_ATTR_SYNC_EXTRA_VALUE, (const xmlChar*)pVal); +} + + + +void +RepositoryEngine::WriteSyncJobsData(void) +{ + LOG_LOGD("Starts"); + + xmlDocPtr doc; + xmlNodePtr rootNode, jobNode; + stringstream ss; + + doc = xmlNewDoc(_VERSION); + + rootNode = xmlNewNode(NULL, XML_NODE_JOBS); + xmlDocSetRootElement(doc, rootNode); + + SyncJobsAggregator* pSyncJobsAggregator = SyncManager::GetInstance()->GetSyncJobsAggregator(); + + map<string, SyncJobsInfo*>& syncJobs = pSyncJobsAggregator->GetAllSyncJobs(); + + ss << syncJobs.size(); + xmlNewProp(rootNode, XML_ATTR_COUNT, (const xmlChar*)ss.str().c_str()); + LOG_LOGD("size %d", syncJobs.size()); + + map<string, SyncJobsInfo*>::iterator itr = syncJobs.begin(); + while (itr != syncJobs.end()) + { + string package = itr->first; + SyncJobsInfo* pJobsInfo = itr->second; + + map<int, ISyncJob*>& packageJobs = pJobsInfo->GetAllSyncJobs(); + + xmlNodePtr packageNode = xmlNewChild(rootNode, NULL, XML_NODE_PACKAGE, NULL); + xmlNewProp(packageNode, XML_ATTR_PACKAGE_ID, (const xmlChar*)(package.c_str())); + ss.str(string()); + + ss<<packageJobs.size(); + xmlNewProp(packageNode, XML_ATTR_JOBS_COUNT, (const xmlChar*)ss.str().c_str()); + ss.str(string()); + + map<int, ISyncJob*>::iterator it; + for (it = packageJobs.begin(); it != packageJobs.end(); it++) + { + SyncJob* pJob = dynamic_cast< SyncJob* > (it->second); + if (pJob == NULL) + { + LOG_LOGD("Invalid sync job entry"); + continue; + } + + jobNode = xmlNewChild(packageNode, NULL, XML_NODE_SYNC_JOB, NULL); + xmlNewProp(jobNode, XML_ATTR_JOB_APP_ID, (const xmlChar*)(pJob->__appId.c_str())); + + ss<<pJob->__accountId; + xmlNewProp(jobNode, XML_ATTR_JOB_ACCOUNT_ID, (const xmlChar*)ss.str().c_str()); + ss.str(string()); + + ss<<(int)pJob->GetSyncJobId(); + xmlNewProp(jobNode, XML_ATTR_JOB_ID, (const xmlChar*)ss.str().c_str()); + ss.str(string()); + + ss<<(int)pJob->GetSyncType(); + xmlNewProp(jobNode, XML_ATTR_JOB_TYPE, (const xmlChar*)ss.str().c_str()); + ss.str(string()); + + ss<<(int)pJob->__isExpedited; + xmlNewProp(jobNode, XML_ATTR_JOB_OPTION_EXPEDIT, (const xmlChar*)ss.str().c_str()); + ss.str(string()); + + ss<<(int)pJob->__noRetry; + xmlNewProp(jobNode, XML_ATTR_JOB_OPTION_NORETRY, (const xmlChar*)ss.str().c_str()); + ss.str(string()); + + xmlNewProp(jobNode, XML_ATTR_JOB_NAME, (const xmlChar*)pJob->__syncJobName.c_str()); + ss.str(string()); + + if (pJob->__pExtras) + { + bundle_iterate(pJob->__pExtras, bndl_iterator, &jobNode); + } + if (pJob->GetSyncType() == SYNC_TYPE_PERIODIC) + { + PeriodicSyncJob* pPeriodJob = dynamic_cast<PeriodicSyncJob*> (pJob); + if (pPeriodJob == NULL) + { + LOG_LOGD("Invalid periodic sync job entry"); + continue; + } + ss<<(int)pPeriodJob->__period; + xmlNewProp(jobNode, XML_ATTR_PERIODIC_SYNC_PEIOD, (const xmlChar*)ss.str().c_str()); + ss.str(string()); + } + } + + itr++; + } + + int ret = xmlSaveFormatFileEnc(PATH_SYNCJOBS, doc, "UTF-8" , 1 ); + if (ret < 0) + { + LOG_LOGD("Failed to write account data, error %d, errno %d", ret, errno); + } + xmlFreeDoc(doc); + xmlCleanupParser(); + + LOG_LOGD("Ends"); +} + + +void +RepositoryEngine::WriteSyncAdapters(void) +{ + LOG_LOGD(" Starts"); + + xmlDocPtr doc; + xmlNodePtr rootNode, saNode; + stringstream ss; + + doc = xmlNewDoc(_VERSION); + + rootNode = xmlNewNode(NULL, XML_NODE_SYNCADAPTERS); + xmlDocSetRootElement(doc, rootNode); + + SyncAdapterAggregator* pAggregator = SyncManager::GetInstance()->GetSyncAdapterAggregator(); + if (!pAggregator) + { + LOG_LOGD("Failed to get sync adapter aggregator, skip writing to file"); + xmlFreeDoc(doc); + return; + } + + ss << pAggregator->__syncAdapterList.size(); + xmlNewProp(rootNode, XML_ATTR_COUNT, (const xmlChar*)ss.str().c_str()); + if (pAggregator->__syncAdapterList.size() != 0) + { + ss.str(string()); + for (map<string, string>::iterator it = pAggregator->__syncAdapterList.begin(); it != pAggregator->__syncAdapterList.end(); ++it) + { + string syncAdapter = it->second; + string packageId = it->first; + saNode = xmlNewChild(rootNode, NULL, XML_NODE_SYNCADAPTER, NULL); + xmlNewProp(saNode, XML_ATTR_SYNCADAPTER_SERVICE_APP_ID, (const xmlChar*)(syncAdapter.c_str())); + xmlNewProp(saNode, XML_ATTR_PACKAGE_ID, (const xmlChar*)(packageId.c_str())); + } + } + + int ret = xmlSaveFormatFileEnc(PATH_SYNCADAPTERS, doc, "UTF-8" , 1 ); + if (ret < 0) + { + LOG_LOGD("Failed to write sync adapter data, error %d", ret); + } + xmlFreeDoc(doc); + xmlCleanupParser(); + + LOG_LOGD(" Ends"); +} + + + + +void +RepositoryEngine::ParseExtras(xmlNodePtr cur, bundle* pExtra) +{ + xmlChar* pKey = xmlGetProp(cur, XML_ATTR_SYNC_EXTRA_KEY); + xmlChar* pVal = xmlGetProp(cur, XML_ATTR_SYNC_EXTRA_VALUE); + + if (!pKey || !pVal) + { + return; + } + + bundle_add(pExtra, (char*)pKey, (char*)pVal); +} + + +void +RepositoryEngine::ParseSyncJobsN(xmlNodePtr cur, xmlChar* pPackage) +{ + + xmlChar* pAppId = xmlGetProp(cur, XML_ATTR_JOB_APP_ID); + xmlChar* pAccId = xmlGetProp(cur, XML_ATTR_JOB_ACCOUNT_ID); + xmlChar* pJobId = xmlGetProp(cur, XML_ATTR_JOB_ID); + xmlChar* pJobName = xmlGetProp(cur, XML_ATTR_JOB_NAME); + xmlChar* pJobNoRetry = xmlGetProp(cur, XML_ATTR_JOB_OPTION_NORETRY); + xmlChar* pJobExpedit = xmlGetProp(cur, XML_ATTR_JOB_OPTION_EXPEDIT); + xmlChar* pJobType = xmlGetProp(cur, XML_ATTR_JOB_TYPE); + + SyncType type = (pJobType == NULL) ? SYNC_TYPE_UNKNOWN : (SyncType)atoi((char*)pJobType); + bool noretry = (pJobNoRetry == NULL) ? false : atoi((char*)pJobNoRetry); + bool expedit = (pJobExpedit == NULL) ? false : atoi((char*)pJobExpedit); + int acountId = (pAccId == NULL) ? -1 : atoi((char*)pAccId); + int jobId = (pJobId == NULL) ? -1 : atoi((char*)pJobId); + int syncOption = (noretry) ? 0x00 : 0x02; + syncOption |= (expedit) ? 0x00 : 0x01; + + bundle* pExtra = NULL; + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + pExtra = bundle_create(); + ParseExtras(cur, pExtra); + cur = cur->next; + } + + switch (type) + { + case SYNC_TYPE_DATA_CHANGE: + { + SyncManager::GetInstance()->AddDataSyncJob((char*)pPackage, (char*)pJobName, acountId, pExtra, syncOption, jobId, (char*)pJobName); + break; + } + case SYNC_TYPE_ON_DEMAND: + { + SyncManager::GetInstance()->AddOnDemandSync((char*)pPackage, (char*)pJobName, acountId, pExtra, syncOption,jobId); + break; + } + case SYNC_TYPE_PERIODIC: + { + xmlChar* pPeriod = xmlGetProp(cur, XML_ATTR_PERIODIC_SYNC_PEIOD); + int period = (pPeriod == NULL)? 1800 : atoi((char*) pPeriod); + + SyncManager::GetInstance()->AddPeriodicSyncJob((char*)pPackage, (char*)pJobName, acountId, pExtra, syncOption, jobId, period); + break; + } + case SYNC_TYPE_UNKNOWN: + default: + { + LOG_LOGD("failed add sync job: sync type is SYNC_TYPE_UNKNOWN"); + break; + } + } +} + + +void +RepositoryEngine::SaveCurrentState(void) +{ + LOG_LOGD("saving states during shutdown"); + pthread_mutex_lock(&__capabilityInfoMutex); + WriteSyncJobsData(); + pthread_mutex_unlock(&__capabilityInfoMutex); + WriteSyncAdapters(); +} + + +//}//_SyncManager + diff --git a/src/sync-service/SyncManager_RepositoryEngine.h b/src/sync-service/SyncManager_RepositoryEngine.h new file mode 100644 index 0000000..7994ca0 --- /dev/null +++ b/src/sync-service/SyncManager_RepositoryEngine.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_RepositoryEngine.h + * @brief This is the header file for the RepositoryEngine class. + */ + +#ifndef SYNC_SERVICE_REPOSITORY_ENGINE_H +#define SYNC_SERVICE_REPOSITORY_ENGINE_H + +#include <libxml/parser.h> +#include <libxml/tree.h> +#include <bundle.h> +#include <bundle_internal.h> +#include <account.h> +#include <pthread.h> +#include <vector> +#include <list> +#include <map> +#include "SyncManager_CapabilityInfo.h" +#include "SyncManager_SyncStatusInfo.h" +#include "SyncManager_SyncJob.h" +#include "SyncManager_PeriodicSyncJob.h" + + + +/*namespace _SyncManager +{ +*/ + +using namespace std; + + +class SyncJobQueue; +class SyncJob; + +class RepositoryEngine +{ + friend class CapabilityInfo; + +public: + static RepositoryEngine* GetInstance(void); + + ~RepositoryEngine(void); + + void OnBooting(); + + void SaveCurrentState(void); + +public: + static const long NOT_IN_BACKOFF_MODE; + +private: + + RepositoryEngine(void); + + RepositoryEngine(const RepositoryEngine&); + + const RepositoryEngine& operator=(const RepositoryEngine&); + + void ReadSyncJobsData(void); + + void WriteSyncJobsData(void); + + void ReadSyncAdapters(void); + + void WriteSyncAdapters(void); + + void ParseCapabilities(xmlNodePtr cur); + + void ParsePeriodicSyncs(xmlNodePtr cur, xmlChar* pCapability); + + void ParseExtras(xmlNodePtr cur, bundle* pExtra); + + void ParseSyncJobsN(xmlNodePtr cur, xmlChar* pPackage); + +private: + pthread_mutex_t __capabilityInfoMutex; + + vector<PeriodicSyncJob*> __pendingJobList; // Pending periodic job list to be scheduled + //map<string, DataSyncJob*> __pendingDataSyncJobList; // Data sync job list to be scheduled + + map<string, CapabilityInfo*> __capabilities; + map<string, map<string, SyncJob*> > __Aggr; // Data sync job list to be scheduled + map<int, SyncStatusInfo*> __syncStatus; + + int PENDING_FINISH_TO_WRITE; + + static RepositoryEngine* __pInstance; + + static const long DEFAULT_PERIOD_SEC; + static const double DEFAULT_FLEX_PERCENT; + static const long DEFAULT_MIN_FLEX_ALLOWED_SEC; +}; +//}//_SyncManager +#endif // SYNC_SERVICE_REPOSITORY_ENGINE_H diff --git a/src/sync-service/SyncManager_ServiceInterface.cpp b/src/sync-service/SyncManager_ServiceInterface.cpp new file mode 100644 index 0000000..1c9b90a --- /dev/null +++ b/src/sync-service/SyncManager_ServiceInterface.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 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 "SyncManager_ServiceInterface.h" +#include "SyncManager_SyncService.h" +#include "SyncManager_SyncManager.h" + +/*namespace _SyncManager +{*/ + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + + +API int sync_service_initialise(void) +{ + return SyncService::GetInstance()->StartService(); +} + + +API int sync_service_finalise(void) +{ + SyncService::GetInstance()->HandleShutdown(); + SyncManager::Destroy(); + SyncService::Destroy(); + + LOG_LOGD("Sync Service Terminated"); + + return 0; +} +//}//_SyncManager diff --git a/src/sync-service/SyncManager_ServiceInterface.h b/src/sync-service/SyncManager_ServiceInterface.h new file mode 100644 index 0000000..674f697 --- /dev/null +++ b/src/sync-service/SyncManager_ServiceInterface.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 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 SYNC_SERVICE_SERVICE_INTERFACE_H +#define SYNC_SERVICE_SERVICE_INTERFACE_H + + +/*namespace _SyncManager +{ +*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +int sync_service_initialise(void); + +int sync_service_finalise(void); + +#ifdef __cplusplus +} +#endif +//}//_SyncManager +#endif // SYNC_SERVICE_SERVICE_INTERFACE_H diff --git a/src/sync-service/SyncManager_Singleton.h b/src/sync-service/SyncManager_Singleton.h new file mode 100644 index 0000000..4183690 --- /dev/null +++ b/src/sync-service/SyncManager_Singleton.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013 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 SYNC_SERVICE_SINGLETON_H +#define SYNC_SERVICE_SINGLETON_H + +#include <stdlib.h> +#include "sync-log.h" + +/*namespace _SyncManager +{ +*/ + +template<typename TYPE> +class Singleton +{ +public: + static TYPE* GetInstance(void) + { + if (__pInstance == NULL) + { + LOG_LOGD("singleton creation called"); + __pInstance = new (std::nothrow) TYPE; + if (__pInstance == NULL) + { + LOG_LOGD("heap error"); + } + } + return __pInstance; + } + static void Destroy(void) + { + } + +protected: + Singleton(void) {} + + virtual ~Singleton(void){} + +private: + Singleton(const Singleton& obj); + + Singleton& operator=( const Singleton& obj); + +private: + static TYPE* __pInstance; +}; + +template<typename TYPE> +TYPE* Singleton<TYPE>::__pInstance = NULL; + +//}//_SyncManager +#endif // SYNC_SERVICE_SINGLETON_H diff --git a/src/sync-service/SyncManager_StorageChangeListener.cpp b/src/sync-service/SyncManager_StorageChangeListener.cpp new file mode 100644 index 0000000..8654294 --- /dev/null +++ b/src/sync-service/SyncManager_StorageChangeListener.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_StorageChangeListener.cpp + * @brief This is the implementation file for the StorageChangeListener class. + */ + +#include <vconf.h> +#include <vconf-keys.h> +#include <vconf-internal-dnet-keys.h> +#include "SyncManager_SyncManager.h" +#include "SyncManager_StorageChangeListener.h" +#include "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{*/ + +void OnMemoryStatusChanged(keynode_t* pKey, void* pData) +{ + MemoryStatus value = static_cast<MemoryStatus> (vconf_keynode_get_int(pKey)); + + SyncManager::GetInstance()->OnStorageStatusChanged(value); +} + +StorageChangeListener::StorageChangeListener(void) +{ +} + +StorageChangeListener::~StorageChangeListener(void) +{ +} + +int +StorageChangeListener::RegisterStorageChangeListener(void) +{ + return( vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, OnMemoryStatusChanged, NULL) ); +} + +int +StorageChangeListener::DeRegisterStorageChangeListener(void) +{ + LOG_LOGD("Remove storage listener"); + + return(vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, OnMemoryStatusChanged)); +} +//}//_SyncManager diff --git a/src/sync-service/SyncManager_StorageChangeListener.h b/src/sync-service/SyncManager_StorageChangeListener.h new file mode 100644 index 0000000..2ccbf69 --- /dev/null +++ b/src/sync-service/SyncManager_StorageChangeListener.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_StorageChangeListener.h + * @brief This is the header file for the StorageChangeListener class. + */ + +#ifndef SYNC_SERVICE_STORAGE_CHANGE_LISTENER_H +#define SYNC_SERVICE_STORAGE_CHANGE_LISTENER_H + + +/*namespace _SyncManager +{ +*/ + +class StorageChangeListener +{ +public: + StorageChangeListener(void); + + ~StorageChangeListener(void); + + int RegisterStorageChangeListener(void); + + int DeRegisterStorageChangeListener(void); +}; +//}//_SyncManager +#endif // SYNC_SERVICE_STORAGE_CHANGE_LISTENER_H diff --git a/src/sync-service/SyncManager_SyncAdapterAggregator.cpp b/src/sync-service/SyncManager_SyncAdapterAggregator.cpp new file mode 100644 index 0000000..48c0b3f --- /dev/null +++ b/src/sync-service/SyncManager_SyncAdapterAggregator.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncAdapterAggregator.cpp + * @brief This is the implementation file for the SyncManager class. + */ + +#include <sys/time.h> +#include <map> +#include <set> +#include <climits> +#include <stdlib.h> +#include <vconf.h> +#include <alarm.h> +#include <glib.h> +#include <aul.h> +#include <pkgmgr-info.h> +#include <app_manager.h> +#include "SyncManager_SyncManager.h" +#include "SyncManager_SyncAdapterAggregator.h" + + +/*namespace _SyncManager +{*/ +using namespace std; + + +SyncAdapterAggregator::SyncAdapterAggregator(void) +{ + +} + + +SyncAdapterAggregator::~SyncAdapterAggregator(void) +{ + +} + + +void +SyncAdapterAggregator::AddSyncAdapter(const char* pPackageId, const char* pServiceAppId) +{ + if (HasSyncAdapter(pPackageId)) + { + LOG_LOGD("Sync adapter already registered for package [%s]", pPackageId); + } + else + { + LOG_LOGD("Registering sync-adapter [%s] for package [%s]", pServiceAppId, pPackageId); + __syncAdapterList.insert(std::pair<string, string> (pPackageId, pServiceAppId)); + } +} + + +void +SyncAdapterAggregator::dumpSyncAdapters() +{ + //for (multimap<string, SyncAdapter*>::iterator it = __syncAdapterList.begin(); it != __syncAdapterList.end(); ++it) + { + //SyncAdapter* pSyncAdapter = it->second; + //LOG_LOGD("account provider ID %s => service app Id %s & syncJobName %s", (*it).first.c_str(), pSyncAdapter->__pAppId, pSyncAdapter->__pCapability); + } +} + + +const char* +SyncAdapterAggregator::GetSyncAdapter(const char* pAppId) +{ + string PkgId(pAppId); + if (PkgId.empty()) + { + PkgId = SyncManager::GetInstance()->GetPkgIdByCommandline(pAppId); + if (PkgId.empty()) + return NULL; + } + + map<string, string>::iterator it = __syncAdapterList.find(PkgId.c_str()); + if (it != __syncAdapterList.end()) + { + return it->second.c_str(); + } + + LOG_LOGD("Sync adapter not found for account provider id %s", pAppId); + return NULL; +} + + +bool +SyncAdapterAggregator::HasServiceAppId(const char* pAccountProviderId) +{ + bool result = false; + /*pair<multimap<string, SyncAdapter*>::iterator, multimap<string, SyncAdapter*>::iterator> ret; + ret = __syncAdapterList.equal_range(pAccountProviderId); + + for(multimap<string, SyncAdapter*>::iterator it = ret.first; it != ret.second; ++it) + { + LOG_LOGD("Sync Adapter is found by using caller package name successfully"); + result = true; + }*/ + return result; +} + + +bool +SyncAdapterAggregator::HasSyncAdapter(const char* pPackageId) +{ + map<string, string>::iterator it = __syncAdapterList.find(pPackageId); + return it != __syncAdapterList.end(); +} + + +void +SyncAdapterAggregator::HandlePackageUninstalled(const char* pPackageId) +{ + LOG_LOGD("Removing sync adapter for package [%s]", pPackageId); + __syncAdapterList.erase(pPackageId); +} + + +void +SyncAdapterAggregator::RemoveSyncAdapter(const char* pPackageId) +{ + __syncAdapterList.erase(pPackageId); +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncAdapterAggregator.h b/src/sync-service/SyncManager_SyncAdapterAggregator.h new file mode 100644 index 0000000..29b083d --- /dev/null +++ b/src/sync-service/SyncManager_SyncAdapterAggregator.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncAdapterAggregator.h + * @brief This is the header file for the SyncManager class. + */ + +#ifndef SYNC_SERVICE_SYNC_ADAPTER_AGGREGATOR_H +#define SYNC_SERVICE_SYNC_ADAPTER_AGGREGATOR_H + +#include <iostream> +#include <list> +#include <bundle.h> +#include <stdio.h> +#include <account.h> +#include <package-manager.h> +#include "SyncManager_SyncJobQueue.h" +#include "SyncManager_RepositoryEngine.h" +#include "SyncManager_NetworkChangeListener.h" +#include "SyncManager_StorageChangeListener.h" +#include "SyncManager_BatteryStatusListener.h" +#include "SyncManager_SyncJobDispatcher.h" +#include "SyncManager_SyncService.h" +#include "SyncManager_SyncWorker.h" +#include "SyncManager_Singleton.h" +#include "SyncManager_CurrentSyncJobQueue.h" +#include "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{ +*/ +class RepositoryEngine; +class SyncAdapter; + +using namespace std; + +class SyncAdapterAggregator +{ +public: + void AddSyncAdapter(const char* pPackageId, const char* pServiceAppId); + + bool HasServiceAppId(const char* pServiceAppId); + + bool HasSyncAdapter(const char* pPackageId); + + void RemoveSyncAdapter(const char* pPackageId); + + const char* GetSyncAdapter(const char* pPackageId); + + void HandlePackageUninstalled(const char* pPackageId); + + void dumpSyncAdapters(); + +protected: + SyncAdapterAggregator(void); + + ~SyncAdapterAggregator(void); + + friend class Singleton<SyncManager>; + +private: + + SyncAdapterAggregator(const SyncAdapterAggregator&); + + const SyncAdapterAggregator& operator=(const SyncAdapterAggregator&); + +private: + map<string, string> __syncAdapterList; + + friend class SyncManager; + friend class RepositoryEngine; +}; +//}//_SyncManager +#endif //SYNC_SERVICE_SYNC_ADAPTER_AGGREGATOR_H diff --git a/src/sync-service/SyncManager_SyncDefines.cpp b/src/sync-service/SyncManager_SyncDefines.cpp new file mode 100644 index 0000000..8710eef --- /dev/null +++ b/src/sync-service/SyncManager_SyncDefines.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 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 "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{*/ + +long BackOffMode::NOT_IN_BACKOFF_MODE = -1; + +/* +bool SyncStatus::syncCancel = false; +bool SyncStatus::syncSuccess = false; +bool SyncStatus::syncFailure = false; +bool SyncStatus::syncError = false; +bool SyncStatus::syncAlreadyInProgress = false; +bool SyncStatus::syncTooManyDelets = false; +bool SyncStatus::fullSyncRequested = false; +long SyncStatus::delayUntill = 0; +bool SyncStatus::syncAlarm = false; +bool SyncStatus::syncTooManyTries = false; +bool SyncStatus::syncSomeProgress = false; +*/ +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncDefines.h b/src/sync-service/SyncManager_SyncDefines.h new file mode 100644 index 0000000..7a7bbeb --- /dev/null +++ b/src/sync-service/SyncManager_SyncDefines.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2013 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 SYNC_SERVICE_SYNC_DEFINES_H +#define SYNC_SERVICE_SYNC_DEFINES_H + +#include <account.h> +#include <string> +#if defined(_SEC_FEATURE_CONTAINER_ENABLE) +#include <vasum.h> +#endif + +#define VALUE_UNDEFINED -1 + +/*namespace _SyncManager +{ +*/ + +#if defined(_SEC_FEATURE_CONTAINER_ENABLE) +#define KNOX_CONTAINER_ZONE_ENTER(pid) struct vsm_context *ctx; \ + struct vsm_zone* effective_zone; \ + ctx = vsm_create_context();\ + effective_zone = (pid == -1)? vsm_get_foreground(ctx) : vsm_lookup_zone_by_pid(ctx, pid);\ + vsm_zone* prev_zone = vsm_join_zone(effective_zone); + +#define KNOX_CONTAINER_ZONE_EXIT() vsm_zone* zone = vsm_join_zone(prev_zone); +#else +#define KNOX_CONTAINER_ZONE_ENTER(pid) +#define KNOX_CONTAINER_ZONE_EXIT() + +#endif + +typedef int account_id; + +enum BluetoothStatus +{ + /** Bluetooth OFF */ + BT_OFF, + /** Bluetooth ON */ + BT_ON, + /** Discoverable mode */ + BT_VISIBLE, + /** In transfering */ + BT_TRANSFER +}; + + +enum WifiStatus +{ + /** power off */ + WIFI_OFF, + /** power on */ + WIFI_NOT_CONNECTED, + /** connected */ + WIFI_CONNECTED +}; + +enum DNetStatus +{ + /** not connected */ + DNET_OFF = 0x00, + /** connected */ + DNET_NORMAL_CONNECTED, + /** secure connected */ + DNET_SECURE_CONNECTED, + /** patcket transmitted */ + DNET_TRANSFER, + DNET_STATE_MAX +}; + + +enum WifiDirect +{ + /** Power off */ + WIFI_DIRECT_DEACTIVATED = 0, + /** Power on */ + WIFI_DIRECT_ACTIVATED, + /** Discoverable mode */ + WIFI_DIRECT_DISCOVERING, + /** Connected with peer as GC */ + WIFI_DIRECT_CONNECTED, + /** Connected with peer as GO */ + WIFI_DIRECT_GROUP_OWNER +}; + + +enum MemoryStatus +{ + /** Normal */ + LOW_MEMORY_NORMAL = 0x01, + /** 60M and under */ + LOW_MEMORY_SOFT_WARNING = 0x02, + /** 40M and under */ + LOW_MEMORY_HARD_WARNING = 0x04 +}; + + +enum BatteryStatus +{ + /** 1% and under */ + BAT_POWER_OFF = 1, + /** 5% and under */ + BAT_CRITICAL_LOW, + /** 15% and under */ + BAT_WARNING_LOW, + /** over 15% */ + BAT_NORMAL, + /** full */ + BAT_FULL, + /** power off */ + BAT_REAL_POWER_OFF +}; + + +enum DataChangeStatus +{ + /** Calendar Book */ + CALENDAR_BOOK_CHANGED = 0, + /** Calendar Event */ + CALENDAR_EVENT_CHANGED, + /** Calendar Todo */ + CALENDAR_TODO_CHANGED, + /** Contacts Modify */ + CONTACTS_DATA_CHANGED, +}; + + +enum SyncDispatchMessage +{ + /** Sync Finished*/ + SYNC_FINISHED = 0, + /** Sync Alaram*/ + SYNC_ALARM, + /** Check Alaram */ + SYNC_CHECK_ALARM, + /** Sync Cancel */ + SYNC_CANCEL +}; + + +enum SyncReason +{ + /** User initiated */ + REASON_USER_INITIATED = -1, + /** Settings Changed */ + REASON_DATA_SETTINGS_CHANGED = -2, + /** Periodic */ + REASON_PERIODIC = -3, + /** Service Changed */ + REASON_SERVICE_CHANGED = -4, + /** Account Updated */ + REASON_ACCOUNT_UPDATED = -5, + /** Auto Sync */ + REASON_AUTO_SYNC = -6, + /** Change in calendar/contacts data */ + REASON_DEVICE_DATA_CHANGED = -7 +}; + + +enum SyncSource +{ + /** User initated*/ + SOURCE_USER = 0, + /** Server initiated */ + SOURCE_SERVER, + /** Periodic sync */ + SOURCE_PERIODIC, + /** Poll based, like on connection to network */ + SOURCE_POLL, + /** local-initiated source */ + SOURCE_LOCAL +}; + +class BackOffMode +{ +public: + static long NOT_IN_BACKOFF_MODE; +}; + +/* +typedef struct SyncStatus +{ + static bool syncCancel; + static bool syncSuccess; + static bool syncFailure; + static bool syncError; + static bool syncAlreadyInProgress; + static bool syncTooManyDelets; + static bool fullSyncRequested; + static long delayUntill; + static bool syncAlarm; + static bool syncTooManyTries; + static bool syncSomeProgress; +}SyncStatus; +*/ + +enum SyncStatus +{ + SYNC_STATUS_SUCCESS = 0, + SYNC_STATUS_CANCELLED = -1, + SYNC_STATUS_SYNC_ALREADY_IN_PROGRESS = -2, + SYNC_STATUS_FAILURE = -3, + SYNC_STATUS_UNKNOWN = -4 +}; + +#define SYNC_JOB_LIMIT 100 +class SyncJob; + +struct Message +{ + Message() + { + acc = NULL; + pSyncJob = NULL; + res = SYNC_STATUS_UNKNOWN; + } + + SyncDispatchMessage type; + account_h acc; + std::string capability; + SyncStatus res; + SyncJob* pSyncJob; +}; +//}//_SyncManager +#endif // SYNC_SERVICE_SYNC_DEFINES_H diff --git a/src/sync-service/SyncManager_SyncJob.cpp b/src/sync-service/SyncManager_SyncJob.cpp new file mode 100644 index 0000000..ce81762 --- /dev/null +++ b/src/sync-service/SyncManager_SyncJob.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncJob.cpp + * @brief This is the implementation file for the SyncJob class. + */ + +#include <string> +#include <sys/time.h> +#include <sstream> +#include <account.h> +#include "sync-log.h" +#include "sync_manager.h" +#include "SyncManager_SyncManager.h" +#include "SyncManager_SyncJob.h" + +/*namespace _SyncManager +{*/ + +#ifndef MAX +#define MAX(a, b) a>b?a:b +#endif + +extern "C" +{ + + +SyncJob::~SyncJob(void) +{ + if (__pExtras) + { + bundle_free(__pExtras); + } + //TODO uncomment below line while implementing pending sync job list + /*delete pPendingJob;*/ +} + + +SyncJob::SyncJob(const SyncJob& job) +{ + __appId = job.__appId; + __accountId = job.__accountId; + __syncJobName = job.__syncJobName; + __pExtras = bundle_dup(job.__pExtras); + __isExpedited = job.__isExpedited; + __key = job.__key; + __waitCounter = job.__waitCounter; + __noRetry = job.__noRetry; +} + + +SyncJob& +SyncJob::operator = (const SyncJob& job) +{ + __appId = job.__appId; + __accountId = job.__accountId; + __syncJobName = job.__syncJobName; + __pExtras = bundle_dup(job.__pExtras); + __isExpedited = job.__isExpedited; + __key = job.__key; + __waitCounter = job.__waitCounter; + __noRetry = job.__noRetry; + + return *this; +} + + +void +SyncJob::CleanBundle(bundle* pData) +{ +} + + +SyncJob::SyncJob(const string appId, const string syncJobName, int account, bundle* pExtras, int syncOption, int syncJobId, SyncType syncType) + : ISyncJob(syncJobId, syncType) + , __appId(appId) + , __accountId(account) + , __syncJobName(syncJobName) + , __pExtras(NULL) + , __isExpedited(syncOption & SYNC_OPTION_EXPEDITED) + , __noRetry(syncOption & SYNC_OPTION_NO_RETRY) +{ + if (pExtras) + { + __pExtras = bundle_dup(pExtras); + } + __key = ToKey(); +} + + +bool +SyncJob::IsNoRetry(void) +{ + return __noRetry; +} + + +bool +SyncJob::IsExpedited(void) +{ + return __isExpedited; +} + + +void +SyncJob::IncrementWaitCounter() +{ + __waitCounter++; +} + + +string +SyncJob::ToKey(void) +{ + LOG_LOGD("Generating key"); + + string key; + + key.append("id:").append(__appId).append(__syncJobName); + LOG_LOGD("%s", key.c_str()); + + return key; +} + + +static void +bndl_iterator(const char* pKey, const char* pVal, void* pData) +{ + string str = *((string*)pData); + str.append(pKey).append("=").append(pVal).append(" "); +} + + +string +SyncJob::GetExtrasInfo(bundle* pData) +{ + string str; + if (pData == NULL) + { + LOG_LOGD("Invalid Parameter"); + return str; + } + str.append("["); + bundle_iterate(pData, bndl_iterator, &str); + str.append("]"); + return str; +} + + +void +SyncJob::Reset(int accountId, bundle* pUserData, int syncOption) +{ + __accountId = accountId; + __noRetry = syncOption & SYNC_OPTION_NO_RETRY; + __isExpedited = syncOption & SYNC_OPTION_EXPEDITED; + if (__pExtras) + { + bundle_free(__pExtras); + __pExtras = bundle_dup(pUserData); + } +} + +} +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncJob.h b/src/sync-service/SyncManager_SyncJob.h new file mode 100644 index 0000000..a22134c --- /dev/null +++ b/src/sync-service/SyncManager_SyncJob.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncJob.h + * @brief This is the header file for the SyncJob class. + */ + + +#ifndef SYNC_SERVICE_SYNC_JOB_H +#define SYNC_SERVICE_SYNC_JOB_H + +#include <string.h> +#include <bundle.h> +#include <bundle_internal.h> +#include <account.h> +#include <stdio.h> +#include <iostream> +#include "SyncManager_ISyncJob.h" +#include "SyncManager_SyncDefines.h" + +/*namespace _SyncManager +{ +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + +using namespace std; + +class SyncJob : public ISyncJob +{ +public: + ~SyncJob(void); + + SyncJob(const SyncJob& job); + + SyncJob& operator=(const SyncJob& job); + + SyncJob(const string appId, const string syncJobName, int accountId, bundle* pUserData, int syncOption, int syncJobId, SyncType type); + + void Reset(int accountId, bundle* pUserData, int syncOption); + + bool IsExpedited(void); + + bool IsNoRetry(void); + + bool IsNoTooManyRetry(void); + + string GetExtrasInfo(bundle* pData); + + void SetJobExtraValue(const char* data, bool val); + + void IncrementWaitCounter(); + + virtual SyncType GetSyncType() + { + return __syncType; + } + +public: + string __appId; + int __accountId; + SyncReason __reason; + SyncSource __syncSource; + bundle* __pExtras; + string __syncJobName; + string __key; + bool __noRetry; + bool __isExpedited; + int __waitCounter; + //SyncType __syncType; + //PendingJob* pPendingJob; + +private: + + void CleanBundle(bundle* Bundle); + + string ToKey(void); + + bool GetBundleVal(const char* pKey); + + void RemoveFalseExtra(bundle* pBundle, const char* pExtraName); + +}; +#ifdef __cplusplus +} +#endif +//}//_SyncManager +#endif//SYNC_SERVICE_SYNC_JOB_H diff --git a/src/sync-service/SyncManager_SyncJobDispatcher.cpp b/src/sync-service/SyncManager_SyncJobDispatcher.cpp new file mode 100644 index 0000000..1e19a1a --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobDispatcher.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_SyncJobDispatcher.cpp + * @brief This is the implementation file for the SyncJobDispatcher class. + */ + +#include <sys/time.h> +#include <climits> +#include <alarm.h> +#include <glib.h> +#include <unistd.h> +#include <device/power.h> +#include "sync-error.h" +#include "sync-log.h" +#include <aul.h> +#include "SyncManager_SyncJobDispatcher.h" +#include "SyncManager_SyncManager.h" +#include "SyncManager_SyncJob.h" + +#ifndef MAX +#define MAX(a, b) a>b?a:b +#endif +#ifndef MIN +#define MIN(a, b) a < b ? a : b +#endif + +#define NON_PRIORITY_SYNC_WAIT_LIMIT 5 + +long MAX_TIME_PER_SYNC = 5*60*1000; //5 minutes +long MAX_SIMULTANEOUS_INITIALIZATION_SYNCS = 2; +long MAX_SIMULTANEOUS_REGULAR_SYNCS = 10; +long MAX_TIMEOUT_VAL = 2*60*60*1000; // 2 hours +long MIN_TIMEOUT_VAL = 30*1000; // 30 seconds + +long long scheduledTimeoutTime = -1; +alarm_id_t alarm_id = 0; + +using namespace std; +/*namespace _SyncManager +{*/ + +SyncJobDispatcher::SyncJobDispatcher(void) +{ +} + + +SyncJobDispatcher::~SyncJobDispatcher(void) +{ +} + + +int +SyncJobDispatcher::DispatchSyncJob(SyncJob* syncJob) +{ + int ret = SYNC_ERROR_NONE; + LOG_LOGD("Dispatching sync job %s, %s", syncJob->__appId.c_str(), syncJob->__syncJobName.c_str()); + + bool isDataSync = (syncJob->GetSyncType() == SYNC_TYPE_DATA_CHANGE); + ret = SyncService::GetInstance()->TriggerStartSync(syncJob->__appId.c_str(), syncJob->__accountId, syncJob->__syncJobName.c_str(), isDataSync, syncJob->__pExtras); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, ret, "Failed to start sync job") + + if (SyncManager::GetInstance()->__pCurrentSyncJobQueue) + { + pthread_mutex_lock(&(SyncManager::GetInstance()->__currJobQueueMutex)); + LOG_LOGD("Add to Active Sync queue"); + + SyncManager::GetInstance()->__pCurrentSyncJobQueue->AddSyncJobToCurrentSyncQueue(syncJob); + pthread_mutex_unlock(&(SyncManager::GetInstance()->__currJobQueueMutex)); + } + + return SYNC_ERROR_NONE; +} + + +void +SyncJobDispatcher::HandleJobCompletedOrCancelledLocked(SyncStatus res, SyncJob *pJob) +{ + LOG_LOGD("Starts"); + + switch (res) + { + case SYNC_STATUS_SUCCESS: + LOG_LOGD("Handle Sync event : SYNC_STATUS_SUCCESS"); + break; + + case SYNC_STATUS_SYNC_ALREADY_IN_PROGRESS: + LOG_LOGD("Handle Sync event : SYNC_STATUS_SYNC_ALREADY_IN_PROGRESS"); + SyncManager::GetInstance()->TryToRescheduleJob(res, pJob); + break; + + case SYNC_STATUS_FAILURE: + LOG_LOGD("Handle Sync event : SYNC_STATUS_FAILURE"); + SyncManager::GetInstance()->TryToRescheduleJob(res, pJob); + break; + + case SYNC_STATUS_CANCELLED: + LOG_LOGD("Handle Sync event : SYNC_STATUS_CANCELLED"); + SyncService::GetInstance()->TriggerStopSync(pJob->__appId.c_str(), pJob->__accountId, pJob->__syncJobName.c_str(), (pJob->GetSyncType() == SYNC_TYPE_DATA_CHANGE), pJob->__pExtras); + delete pJob; + break; + + default: + break; + } + +} + +void +SyncJobDispatcher::OnEventReceived(Message msg) +{ + LOG_LOGD("0. Sync Job dispatcher starts"); + + if (!SyncManager::GetInstance()->__isSyncPermitted) + { + LOG_LOGD("Sync not permitted now"); + return; + } + + switch (msg.type) + { + case SYNC_CANCEL: + { + LOG_LOGD("1. Handle Event : SYNC_CANCEL"); + HandleJobCompletedOrCancelledLocked(SYNC_STATUS_CANCELLED, msg.pSyncJob); + LOG_LOGD("2. Start next Syncjob from main queue"); + TryStartingNextJobLocked(); + } + break; + + case SYNC_FINISHED: + { + LOG_LOGD("1. Handle Event : SYNC_FINISHED"); + HandleJobCompletedOrCancelledLocked(msg.res, msg.pSyncJob); + LOG_LOGD("2. Start next Sync job from main queue"); + TryStartingNextJobLocked(); + } + break; + + case SYNC_CHECK_ALARM: + { + LOG_LOGD("1. Handle Event : SYNC_CHECK_ALARM"); + LOG_LOGD("2. Start next Sync job from main queue"); + TryStartingNextJobLocked(); + } + break; + + case SYNC_ALARM: + { + LOG_LOGD("1. Handle Event : SYNC_ALARM"); + LOG_LOGD("2. Start next Sync job from main queue"); + TryStartingNextJobLocked(); + } + break; + default: + break; + }; + + LOG_LOGD("3. Sync Job dispatcher Ends"); +} + + +bool +sortFunc(const SyncJob* pJob1, const SyncJob* pJob2) +{ + return false; +} + + +void +SyncJobDispatcher::TryStartingNextJobLocked() +{ + if (SyncManager::GetInstance()->__isWifiConnectionPresent == false && SyncManager::GetInstance()->__isSimDataConnectionPresent == false) + { + LOG_LOGD("No network available: Skipping sync"); + return; + } + + if (!SyncManager::GetInstance()->__isSyncPermitted) + { + LOG_LOGD("Sync not permitted now: Skipping sync"); + return; + } + + if (SyncManager::GetInstance()->__isUPSModeEnabled) + { + LOG_LOGD("UPS mode enabled: Skipping sync"); + return; + } + + if (SyncManager::GetInstance()->__isStorageLow) + { + LOG_LOGD("Storage Low: Skipping sync"); + return; + } + + pthread_mutex_lock(&(SyncManager::GetInstance()->__syncJobQueueMutex)); + + SyncJobQueue* pSyncJobQueue = SyncManager::GetInstance()->GetSyncJobQueue(); + + list< SyncJob* >& jobQueue = pSyncJobQueue->GetSyncJobQueue(); + list< SyncJob* >& priorityJobQueue = pSyncJobQueue->GetPrioritySyncJobQueue(); + + if (jobQueue.empty() && priorityJobQueue.empty()) + { + LOG_LOGD("SyncJob Queues are empty"); + pthread_mutex_unlock(&(SyncManager::GetInstance()->__syncJobQueueMutex)); + return; + } + + SyncJob* syncJobToRun = NULL; + + if (!jobQueue.empty()) + { + SyncJob* nonPrioritySyncJob = jobQueue.front(); + if (nonPrioritySyncJob->__waitCounter > NON_PRIORITY_SYNC_WAIT_LIMIT) + { + LOG_LOGD("Long waiting Non priority job found. Handle this job first"); + syncJobToRun = nonPrioritySyncJob; + jobQueue.pop_front(); + } + } + + if (syncJobToRun == NULL && !priorityJobQueue.empty()) + { + LOG_LOGD("Priority job found."); + syncJobToRun = priorityJobQueue.front(); + priorityJobQueue.pop_front(); + } + + if (syncJobToRun == NULL && !jobQueue.empty()) + { + LOG_LOGD("Non priority job found."); + syncJobToRun = jobQueue.front(); + jobQueue.pop_front(); + LOG_LOGD("Non priority size.%d", jobQueue.size()); + } + + if (syncJobToRun != NULL) + { + int ret = DispatchSyncJob(syncJobToRun); + if (ret != SYNC_ERROR_NONE) + { + SyncManager::GetInstance()->ScheduleSyncJob(syncJobToRun, false); + LOG_LOGD("Failed to dispatch sync job. Adding it back to job queue"); + } + } + pthread_mutex_unlock(&(SyncManager::GetInstance()->__syncJobQueueMutex)); +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncJobDispatcher.h b/src/sync-service/SyncManager_SyncJobDispatcher.h new file mode 100644 index 0000000..181cb2e --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobDispatcher.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncJobDispatcher.h + * @brief This is the header file for the SyncJobDispatcher class. + */ + + +#ifndef SYNC_SERVICE_SYNC_JOB_DISPATCHER_H +#define SYNC_SERVICE_SYNC_JOB_DISPATCHER_H + +#include "account.h" +#include "SyncManager_SyncDefines.h" +#include "SyncManager_SyncJobQueue.h" +#include "SyncManager_SyncWorkerResultListener.h" +#include "SyncManager_Singleton.h" + +/*namespace _SyncManager +{ +*/ + +class CurrentSyncContext; + +class SyncJobDispatcher + :public ISyncWorkerResultListener +{ +public: + + SyncJobDispatcher(void); + + ~SyncJobDispatcher(void); + + int DispatchSyncJob(SyncJob* syncJob); + + //ISyncWorkerResultListener + void OnEventReceived(Message msg); + +private: + SyncJobDispatcher(const SyncJobDispatcher&); + + const SyncJobDispatcher& operator=(const SyncJobDispatcher&); + + void HandleJobCompletedOrCancelledLocked(SyncStatus res, SyncJob *pJob); + + void TryStartingNextJobLocked(); + + }; +//}//_SyncManager +#endif //SYNC_SERVICE_SYNC_JOB_DISPATCHER_H diff --git a/src/sync-service/SyncManager_SyncJobQueue.cpp b/src/sync-service/SyncManager_SyncJobQueue.cpp new file mode 100644 index 0000000..b464c2e --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobQueue.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncJobQueue.cpp + * @brief This is the implementation file for the SyncJobQueue class. + */ + +#include <string> +#include <map> +#include <stdio.h> +#include <stdlib.h> +#include <sstream> +#include <dlog.h> +#include <sync-error.h> +#include "sync-log.h" +#include "SyncManager_SyncManager.h" +#include "SyncManager_SyncJobQueue.h" + +/*namespace _SyncManager +{*/ + +#ifndef MIN +#define MIN(a, b) a < b ? a : b +#endif + +extern "C" +{ + + +SyncJobQueue::SyncJobQueue(void) +{ + //Empty +} + + +SyncJobQueue::SyncJobQueue(RepositoryEngine* pSyncRepositoryEngine) +{ + __pSyncRepositoryEngine = pSyncRepositoryEngine; +} + + +SyncJobQueue::~SyncJobQueue(void) +{ + //Empty +} + + +list< SyncJob* >& +SyncJobQueue::GetSyncJobQueue(void) +{ + return __syncJobsQueue; +} + + +list< SyncJob* >& +SyncJobQueue::GetPrioritySyncJobQueue(void) +{ + return __prioritySyncJobsQueue; +} + + +int +SyncJobQueue::AddSyncJob(SyncJob* pSyncJob) +{ + SyncJob* pSyncJobEntry = dynamic_cast< SyncJob* > (pSyncJob); + SYNC_LOGE_RET_RES(pSyncJobEntry != NULL, SYNC_ERROR_SYSTEM, "Failed to get sync job"); + + if (pSyncJobEntry ->IsExpedited()) + { + LOG_LOGD("Priority SyncJob Queue size, before = %d", __prioritySyncJobsQueue.size()); + __prioritySyncJobsQueue.push_back(pSyncJob); + LOG_LOGD("Priority SyncJob Queue size, after = %d", __prioritySyncJobsQueue.size()); + } + else + { + LOG_LOGD("SyncJob Queue size, before = %d", __syncJobsQueue.size()); + __syncJobsQueue.push_back(pSyncJob); + LOG_LOGD("SyncJob Queue size, after = %d", __syncJobsQueue.size()); + } + + return SYNC_ERROR_NONE; +} + + +int +SyncJobQueue::RemoveSyncJob(SyncJob* pSyncJob) +{ + if (pSyncJob ->IsExpedited()) + { + LOG_LOGD("Priority SyncJob Queue size, before = %d", __prioritySyncJobsQueue.size()); + __prioritySyncJobsQueue.remove(pSyncJob); + LOG_LOGD("Priority SyncJob Queue size, after = %d", __prioritySyncJobsQueue.size()); + } + else + { + LOG_LOGD("SyncJob Queue size, before = %d", __syncJobsQueue.size()); + __syncJobsQueue.remove(pSyncJob); + LOG_LOGD("SyncJob Queue size, after = %d", __syncJobsQueue.size()); + } + + return SYNC_ERROR_NONE; +} + + +void +SyncJobQueue::UpdateAgeCount() +{ + list< SyncJob* >::iterator itr = __syncJobsQueue.begin(); + while (itr != __syncJobsQueue.end()) + { + (*itr)->IncrementWaitCounter(); + } +} + +} +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncJobQueue.h b/src/sync-service/SyncManager_SyncJobQueue.h new file mode 100644 index 0000000..d47246a --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobQueue.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_SyncJobQueue.h + * @brief This is the header file for the SyncJobQueue class. + */ + +#ifndef SYNC_SERVICE_SYNC_JOB_QUEUE_H +#define SYNC_SERVICE_SYNC_JOB_QUEUE_H + +#include <queue> +#include <bundle.h> +#include <account.h> +#include <stdio.h> +#include <iostream> +#include <string> +#include "SyncManager_RepositoryEngine.h" +#include "SyncManager_SyncJob.h" + + +/*namespace _SyncManager +{ +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + +using namespace std; + +class SyncJob; + +class SyncJobQueue +{ +public: + + SyncJobQueue(void); + + ~SyncJobQueue(void); + + SyncJobQueue(RepositoryEngine* pSyncRepositoryEngine); + + list< SyncJob* >& GetSyncJobQueue(void); + + list< SyncJob* >& GetPrioritySyncJobQueue(void); + + int AddSyncJob(SyncJob* pJob); + + int RemoveSyncJob(SyncJob* pJob); + + void UpdateAgeCount(); + +private: + RepositoryEngine* __pSyncRepositoryEngine; + list< SyncJob* > __syncJobsQueue; + list< SyncJob* > __prioritySyncJobsQueue; +}; + +#ifdef __cplusplus +} +#endif +//}//_SyncManager +#endif//SYNC_SERVICE_SYNC_JOB_QUEUE_H diff --git a/src/sync-service/SyncManager_SyncJobsAggregator.cpp b/src/sync-service/SyncManager_SyncJobsAggregator.cpp new file mode 100644 index 0000000..3593ebf --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobsAggregator.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncAdapterAggregator.cpp + * @brief This is the header file for the SyncManager class. + */ + + +#include <iostream> +#include <list> +#include <bundle.h> +#include <stdio.h> +#include "SyncManager_SyncJobsAggregator.h" +#include "SyncManager_SyncJobsInfo.h" +#include "SyncManager_SyncWorker.h" +#include "SyncManager_Singleton.h" +#include "SyncManager_CurrentSyncJobQueue.h" +#include "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{ +*/ + + +SyncJobsAggregator::SyncJobsAggregator(void) +{ + +} + +SyncJobsAggregator::~SyncJobsAggregator(void) +{ + +} + + +/*SyncJob* +SyncJobsAggregator::GetOrCreateSyncJob(const char* pPackageId, const char* pSyncJobName, SyncJob* pSyncJob) +{ + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + pPackageSyncJobsInfo->Add(pSyncJobName, pSyncJob); + } +}*/ + + +bool +SyncJobsAggregator::HasSyncJob(const char* pPackageId, const char* pSyncJobName) +{ + ISyncJob* pSyncJob = GetSyncJob(pPackageId, pSyncJobName); + return pSyncJob != NULL; +} + + +int +SyncJobsAggregator::GenerateSyncJobId(const char* pPackageId) +{ + int id = -1; + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + id = pPackageSyncJobsInfo->GetNextSyncJobId(); + } + else + { + LOG_LOGD("First request for the package [%s]", pPackageId); + + SyncJobsInfo* pPackageSyncJobsInfo = new (std::nothrow) SyncJobsInfo(pPackageId); + id = pPackageSyncJobsInfo->GetNextSyncJobId(); + __syncJobsContainer.insert(make_pair(pPackageId, pPackageSyncJobsInfo)); + } + + return id; +} + + +void +SyncJobsAggregator::AddSyncJob(const char* pPackageId, const char* pSyncJobName, ISyncJob* pSyncJob) +{ + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + LOG_LOGD("Sync Jobs info found for package %s", pPackageId); + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + pPackageSyncJobsInfo->AddSyncJob(pSyncJobName, pSyncJob); + } + else + { + LOG_LOGD("Creating new Sync Jobs info handle for package %s", pPackageId); + SyncJobsInfo* pPackageSyncJobsInfo = new (std::nothrow) SyncJobsInfo(pPackageId); + pPackageSyncJobsInfo->AddSyncJob(pSyncJobName, pSyncJob); + __syncJobsContainer.insert(make_pair(pPackageId, pPackageSyncJobsInfo)); + } +} + + +int +SyncJobsAggregator::RemoveSyncJob(const char* pPackageId, int syncJobId) +{ + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + int ret = pPackageSyncJobsInfo->RemoveSyncJob(syncJobId); + if (pPackageSyncJobsInfo->GetSyncJobsCount() == 0) + { + delete pPackageSyncJobsInfo; + __syncJobsContainer.erase(itr); + } + return ret; + } + + return -1; +} + + +int +SyncJobsAggregator::RemoveSyncJob(const char* pPackageId, const char* pSyncJobName) +{ + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + int ret = pPackageSyncJobsInfo->RemoveSyncJob(pSyncJobName); + if (pPackageSyncJobsInfo->GetSyncJobsCount() == 0) + { + delete pPackageSyncJobsInfo; + __syncJobsContainer.erase(itr); + } + return ret; + } + else + { + LOG_LOGD("Sync jobs for package %s are not found", pPackageId); + } + + return -1; +} + + + +int +SyncJobsAggregator::GetSyncJobId(const char* pPackageId, const char* pSyncJobName) +{ + ISyncJob* pSyncJob = GetSyncJob(pPackageId, pSyncJobName); + int id = (pSyncJob == NULL) ? -1 : pSyncJob->GetSyncJobId(); + + return id; +} + + + +ISyncJob* +SyncJobsAggregator::GetSyncJob(const char* pPackageId, const char* pSyncJobName) +{ + ISyncJob* pSyncJob = NULL; + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + pSyncJob = pPackageSyncJobsInfo->GetSyncJob(pSyncJobName); + } + + return pSyncJob; +} + + +void +SyncJobsAggregator::HandlePackageUninstalled(const char* pPackageId) +{ + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + pPackageSyncJobsInfo->RemoveAllSyncJobs(); + __syncJobsContainer.erase(pPackageId); + } + else + { + LOG_LOGD("Sync jobs for package %s are not found", pPackageId); + } +} + + +ISyncJob* +SyncJobsAggregator::GetSyncJob(const char* pPackageId, int syncJobId) +{ + ISyncJob* pSyncJob = NULL; + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + pSyncJob = pPackageSyncJobsInfo->GetSyncJob(syncJobId); + } + else + { + LOG_LOGD("Sync jobs for package %s are not found", pPackageId); + } + return pSyncJob; +} + + +vector< int > +SyncJobsAggregator::GetSyncJobIDList(const char* pPackageId) +{ + vector<int> list; + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + SyncJobsInfo* pPackageSyncJobsInfo = itr->second; + list = pPackageSyncJobsInfo->GetSyncJobIdList(); + } + return list; +} + + +SyncJobsInfo* +SyncJobsAggregator::GetSyncJobsInfo(const char* pPackageId) +{ + map<string, SyncJobsInfo*>::iterator itr = __syncJobsContainer.find(pPackageId); + if (itr != __syncJobsContainer.end()) + { + return itr->second; + } + + return NULL; +} + +map<string, SyncJobsInfo*>& +SyncJobsAggregator::GetAllSyncJobs() +{ + return __syncJobsContainer; +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncJobsAggregator.h b/src/sync-service/SyncManager_SyncJobsAggregator.h new file mode 100644 index 0000000..1c42529 --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobsAggregator.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncAdapterAggregator.h + * @brief This is the header file for the SyncManager class. + */ + +#ifndef SYNC_SERVICE_SYNC_JOBS_AGGREGATOR_H +#define SYNC_SERVICE_SYNC_JOBS_AGGREGATOR_H + +#include <iostream> +#include <list> +#include <bundle.h> +#include <stdio.h> +#include "SyncManager_SyncService.h" +#include "SyncManager_SyncWorker.h" +#include "SyncManager_Singleton.h" +#include "SyncManager_CurrentSyncJobQueue.h" +#include "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{ +*/ +class RepositoryEngine; +class SyncJobsInfo; + +using namespace std; + +class SyncJobsAggregator +{ +public: + void AddSyncJob(const char* pPackageId, const char* pSyncJobName, ISyncJob* pSyncJob); + + int RemoveSyncJob(const char* pPackageId, int jobId); + + int RemoveSyncJob(const char* pPackageId, const char* pSyncJobName); + + bool HasSyncJob(const char* pPackageId, const char* pSyncJobName); + + int GetSyncJobId(const char* pPackageId, const char* pSyncJobName); + + int GenerateSyncJobId(const char* pPackageId); + + ISyncJob* GetSyncJob(const char* pPackageId, const char* pSyncJobName); + + ISyncJob* GetSyncJob(const char* pPackageId, int syncJobId); + + vector< int > GetSyncJobIDList(const char* pPackageId); + + SyncJobsInfo* GetSyncJobsInfo(const char* pPackageId); + + void HandlePackageUninstalled(const char* pPackageId); + + map<string, SyncJobsInfo*>& GetAllSyncJobs(); + +protected: + SyncJobsAggregator(void); + + ~SyncJobsAggregator(void); + + friend class Singleton<SyncManager>; + +/*class SyncJobsInfo +{ +public: + SyncJobsInfo(string __packageId); +private: + + SyncJobsInfo(const SyncJobsInfo&); + + const SyncJobsInfo& operator=(const SyncJobsInfo&); + +public: + map<string, SyncJob*> __syncJobs; + int __nextJobId; +};*/ + +private: + + SyncJobsAggregator(const SyncJobsAggregator&); + + const SyncJobsAggregator& operator=(const SyncJobsAggregator&); + +private: + map<string, SyncJobsInfo*> __syncJobsContainer; + + friend class SyncManager; + friend class RepositoryEngine; +}; +//}//_SyncManager +#endif //SYNC_SERVICE_SYNC_JOBS_AGGREGATOR_H diff --git a/src/sync-service/SyncManager_SyncJobsInfo.cpp b/src/sync-service/SyncManager_SyncJobsInfo.cpp new file mode 100644 index 0000000..718d886 --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobsInfo.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CapabilityInfo.cpp + * @brief This is the implementation file for the CapabilityInfo class. + */ + +#include <bundle.h> +#include "sync-log.h" +#include "SyncManager_RepositoryEngine.h" +#include "SyncManager_SyncJobsInfo.h" +#include "SyncManager_SyncManager.h" +#include "sync-error.h" + + +/*namespace _SyncManager +{*/ + + +SyncJobsInfo::~SyncJobsInfo(void) +{ +} + + +SyncJobsInfo::SyncJobsInfo(string packageId) + : __packageId(packageId) +{ + for (int i = 0; i < SYNC_JOB_LIMIT; i++) + { + __syncJobId[i] = false; + } + +} + + +int +SyncJobsInfo::AddSyncJob(string syncJobName, ISyncJob* pSyncJob) +{ + __syncJobsList.insert(make_pair(syncJobName, pSyncJob)); + __syncIdList.insert(make_pair(pSyncJob->GetSyncJobId(), pSyncJob)); + __syncJobId[pSyncJob->GetSyncJobId()] = true; + return SYNC_ERROR_NONE; +} + + +ISyncJob* +SyncJobsInfo::GetSyncJob(string syncJobName) +{ + map<string, ISyncJob*>::iterator itr = __syncJobsList.find(syncJobName); + if (itr != __syncJobsList.end()) + { + return itr->second; + } + return NULL; +} + + +ISyncJob* +SyncJobsInfo::GetSyncJob(int syncJobId) +{ + map<int, ISyncJob*>::iterator itr = __syncIdList.find(syncJobId); + if (itr != __syncIdList.end()) + { + LOG_LOGD("Found sync job for id [%d]", syncJobId); + return itr->second; + } + + return NULL; +} + + +int +SyncJobsInfo::RemoveSyncJob(int syncJobId) +{ + map<int, ISyncJob*>::iterator itr = __syncIdList.find(syncJobId); + if (itr != __syncIdList.end()) + { + SyncJob* syncJob = dynamic_cast< SyncJob* > (itr->second); + if (syncJob != NULL) + { + RemoveSyncJob(syncJob->__syncJobName); + } + } + + return 0; +} + + +int +SyncJobsInfo::RemoveSyncJob(string syncJobname) +{ + map<string, ISyncJob*>::iterator itr = __syncJobsList.find(syncJobname); + if (itr != __syncJobsList.end()) + { + ISyncJob* pSyncJob = itr->second; + int syncJobId = pSyncJob->GetSyncJobId(); + __syncJobId[syncJobId] = false; + LOG_LOGD("Removing job name [%s] id [%d] from package [%s]", syncJobname.c_str(), syncJobId, __packageId.c_str()); + + delete pSyncJob; + __syncJobsList.erase(itr); + __syncIdList.erase(syncJobId); + } + else + { + LOG_LOGD("Sync job name doesnt exists in package [%s] for job name [%s]", __packageId.c_str(), syncJobname.c_str()); + } + return 0; +} + + +void +SyncJobsInfo::RemoveAllSyncJobs() +{ + LOG_LOGD("Removing Sync jobs for package [%s]. Count [%d] ", __packageId.c_str(), __syncIdList.size()); + + map<int, ISyncJob*>::iterator itr = __syncIdList.begin(); + while (itr != __syncIdList.end()) + { + SyncManager::GetInstance()->RemoveSyncJob(__packageId.c_str(), itr->first); + itr++; + } +} + + +int +SyncJobsInfo::GetNextSyncJobId() +{ + int value = -1; + int idx; + + for (idx = 1; idx <= SYNC_JOB_LIMIT; idx++) + { + if (!__syncJobId[idx]) + { + value = idx; + break; + } + } + + if (idx == SYNC_JOB_LIMIT) + { + value = SYNC_JOB_LIMIT + 1; + } + + return value; +} + + +vector <int> +SyncJobsInfo::GetSyncJobIdList() +{ + vector<int> idList; + int idx; + + for (idx = 0; idx < SYNC_JOB_LIMIT; idx++) + { + if (__syncJobId[idx]) + { + idList.push_back(idx); + } + } + return idList; +} + + +map<int, ISyncJob*>& +SyncJobsInfo::GetAllSyncJobs() +{ + return __syncIdList; +} + + +int +SyncJobsInfo::GetSyncJobsCount() +{ + return __syncJobsList.size(); +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncJobsInfo.h b/src/sync-service/SyncManager_SyncJobsInfo.h new file mode 100644 index 0000000..010ec8c --- /dev/null +++ b/src/sync-service/SyncManager_SyncJobsInfo.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_CapabilityInfo.h + * @brief This is the header file for the CapabilityInfo class. + */ + +#ifndef SYNC_SERVICE_SYNC_JOBS_INFO_H +#define SYNC_SERVICE_SYNC_JOBS_INFO_H + +#include <string> +#include <vector> +#include <account.h> +#include "SyncManager_ISyncJob.h" +#include "SyncManager_SyncDefines.h" + +/*namespace _SyncManager +{ +*/ +using namespace std; + +class SyncJobsInfo +{ +public: + + ~SyncJobsInfo(void); + + SyncJobsInfo(string packageId); + + ISyncJob* GetSyncJob(string syncJobName); + + ISyncJob* GetSyncJob(int syncJobId); + + int RemoveSyncJob(int syncJobId); + + int RemoveSyncJob(string syncJobName); + + int AddSyncJob(string syncJobName, ISyncJob* pSyncJob); + + int GetNextSyncJobId(); + + int GetSyncJobsCount(); + + vector< int > GetSyncJobIdList(); + + map<int, ISyncJob*>& GetAllSyncJobs(); + + void RemoveAllSyncJobs(); + +private: + + SyncJobsInfo(const SyncJobsInfo&); + + const SyncJobsInfo& operator=(const SyncJobsInfo&); + +public: + map<string, ISyncJob*> __syncJobsList; + map<int, ISyncJob*> __syncIdList; + string __packageId; + bool __syncJobId[SYNC_JOB_LIMIT + 1]; +}; +//}//_SyncManager +#endif // SYNC_SERVICE_SYNC_JOBS_INFO_H diff --git a/src/sync-service/SyncManager_SyncManager.cpp b/src/sync-service/SyncManager_SyncManager.cpp new file mode 100644 index 0000000..b94c71f --- /dev/null +++ b/src/sync-service/SyncManager_SyncManager.cpp @@ -0,0 +1,1112 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncManager.cpp + * @brief This is the implementation file for the SyncManager class. + */ + +#include <sys/time.h> +#include <map> +#include <set> +#include <climits> +#include <stdlib.h> +#include <vconf.h> +#include <alarm.h> +#include <glib.h> +#include <aul.h> +#include <pkgmgr-info.h> +#include <app_manager.h> +#include "sync-error.h" +#include "SyncManager_SyncManager.h" +#include "SyncManager_SyncAdapterAggregator.h" +#include "SyncManager_SyncJobsAggregator.h" +#include "SyncManager_SyncDefines.h" +#include "SyncManager_PeriodicSyncJob.h" +#include "SyncManager_DataSyncJob.h" +#include "sync_manager.h" + + +/*namespace _SyncManager +{*/ + +#define VCONF_HOME_SCREEN "db/setting/homescreen/package_name" +#define VCONF_LOCK_SCREEN "file/private/lockscreen/pkgname" + +int DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS = 10; +#define ID_FOR_ACCOUNT_LESS_SYNC -2 + +template<> +SyncManager* +Singleton< SyncManager >::GetInstance() +{ + if (__pInstance == NULL) + { + __pInstance = new (std::nothrow) SyncManager(); + if (__pInstance == NULL) + { + LOG_LOGD("Sync Manager creation failed"); + } + else + { + if (!__pInstance->Construct()) + { + LOG_LOGD("Sync Manager initialization failed"); + + delete __pInstance; + } + + } + } + return __pInstance; + +} + + +void +SyncManager::SetSyncSetting(bool enable) +{ + bool wasSuspended = (__isSyncPermitted == false); + __isSyncPermitted = enable; + if (wasSuspended && __isSyncPermitted) + { + SendSyncCheckAlarmMessage(); + } +} + + +bool +SyncManager::GetSyncSetting() +{ + return __isSyncPermitted; +} + + +int +SyncManager::AddOnDemandSync(string pPackageId, const char* syncJobName, int accountId, bundle* pExtras, int syncOption, int syncJobId) +{ + const char* pSyncAdapterApp = __pSyncAdapterAggregator->GetSyncAdapter(pPackageId.c_str()); + SYNC_LOGE_RET_RES(pSyncAdapterApp != NULL, SYNC_ERROR_SYNC_ADAPTER_NOT_FOUND, "Sync adapter cannot be found for package %s", pPackageId.c_str()); + + if (accountId != -1 && !GetSyncSupport(accountId)) + { + LOG_LOGD("Sync is not enabled for account ID %s", accountId); + + return SYNC_ERROR_SYSTEM; + } + + SyncJob* pJob = new (std::nothrow) SyncJob(pSyncAdapterApp, syncJobName, accountId, pExtras, syncOption, syncJobId, SYNC_TYPE_ON_DEMAND); + SYNC_LOGE_RET_RES(pJob != NULL, SYNC_ERROR_OUT_OF_MEMORY, "Failed to construct SyncJob"); + + __pSyncJobsAggregator->AddSyncJob(pPackageId.c_str(), syncJobName, pJob); + + ScheduleSyncJob(pJob); + + return SYNC_ERROR_NONE; +} + + +int +SyncManager::CancelSync(SyncJob* pSyncJob) +{ + LOG_LOGD("SyncManager::CancelSync Starts"); + + ClearScheduledSyncJobs(pSyncJob); + CancelActiveSyncJob(pSyncJob); + + LOG_LOGD("SyncManager::CancelSync Ends"); + + return SYNC_ERROR_NONE; +} + + +int +SyncManager::AddPeriodicSyncJob(string pPackageId, const char* syncJobName, int accountId, bundle* pExtras, int syncOption, int syncJobId, long period) +{ + if (period < 1800) + { + LOG_LOGD("Requested period %d is less than minimum, rounding up to 30 mins", period); + + period = 1800; + } + + const char* pSyncAdapterApp = __pSyncAdapterAggregator->GetSyncAdapter(pPackageId.c_str()); + SYNC_LOGE_RET_RES(pSyncAdapterApp != NULL, SYNC_ERROR_SYNC_ADAPTER_NOT_FOUND, "Sync adapter cannot be found for package %s", pPackageId.c_str()); + LOG_LOGD("Found sync adapter [%s]", pSyncAdapterApp); + + if (accountId != -1 && !GetSyncSupport(accountId)) + { + LOG_LOGD("Sync is not enabled for account ID %s", accountId); + return SYNC_ERROR_SYSTEM; + } + + PeriodicSyncJob* pRequestedJob = new (std::nothrow) PeriodicSyncJob(pSyncAdapterApp, syncJobName, accountId, pExtras, syncOption, syncJobId, SYNC_TYPE_PERIODIC, period / 60); + SYNC_LOGE_RET_RES(pRequestedJob != NULL, SYNC_ERROR_OUT_OF_MEMORY, "Failed to construct periodic SyncJob"); + + __pSyncJobsAggregator->AddSyncJob(pPackageId.c_str(), syncJobName, pRequestedJob); + __pPeriodicSyncScheduler->SchedulePeriodicSyncJob(pRequestedJob); + if (pRequestedJob->IsExpedited()) + { + ScheduleSyncJob(pRequestedJob); + } + + return SYNC_ERROR_NONE; +} + + +int +SyncManager::AddDataSyncJob(string pPackageId, const char* syncJobName, int accountId, bundle* pExtras, int syncOption, int syncJobId, const char* pCapability) +{ + const char* pSyncAdapterApp = __pSyncAdapterAggregator->GetSyncAdapter(pPackageId.c_str()); + SYNC_LOGE_RET_RES(pSyncAdapterApp != NULL, SYNC_ERROR_SYNC_ADAPTER_NOT_FOUND, "Sync adapter cannot be found for package %s", pPackageId.c_str()); + LOG_LOGD("Found sync adapter [%s]", pSyncAdapterApp); + + if (accountId != -1 && !GetSyncSupport(accountId)) + { + LOG_LOGD("Sync is not enabled for account ID %s", accountId); + return SYNC_ERROR_SYSTEM; + } + + DataSyncJob* pRequestedJob = new (std::nothrow) DataSyncJob(pSyncAdapterApp, syncJobName, accountId, pExtras, syncOption, syncJobId, SYNC_TYPE_DATA_CHANGE, pCapability); + SYNC_LOGE_RET_RES(pRequestedJob != NULL, SYNC_ERROR_OUT_OF_MEMORY, "Failed to construct periodic SyncJob"); + + __pSyncJobsAggregator->AddSyncJob(pPackageId.c_str(), syncJobName, pRequestedJob); + __pDataChangeSyncScheduler->AddDataSyncJob(syncJobName, pRequestedJob); + if (pRequestedJob->IsExpedited()) + { + ScheduleSyncJob(pRequestedJob); + } + + return SYNC_ERROR_NONE; +} + + +int +SyncManager::RemoveSyncJob(string packageId, int syncJobId) +{ + LOG_LOGD("Starts"); + int ret = SYNC_ERROR_NONE; + + ISyncJob* pSyncJob = __pSyncJobsAggregator->GetSyncJob(packageId.c_str(), syncJobId); + SYNC_LOGE_RET_RES(pSyncJob != NULL, SYNC_ERROR_UNKNOWN, "Sync job for id [%d] doesnt exist or already removed", syncJobId); + + SyncType syncType = pSyncJob->GetSyncType(); + if (syncType == SYNC_TYPE_DATA_CHANGE) + { + DataSyncJob* dataSyncJob = dynamic_cast< DataSyncJob* > (pSyncJob); + SYNC_LOGE_RET_RES(dataSyncJob != NULL, SYNC_ERROR_SYSTEM, "Failed to cast %d", syncJobId); + + __pDataChangeSyncScheduler->RemoveDataSyncJob(dataSyncJob); + } + else if(syncType == SYNC_TYPE_PERIODIC) + { + PeriodicSyncJob* periodicSyncJob = dynamic_cast< PeriodicSyncJob* > (pSyncJob); + SYNC_LOGE_RET_RES(periodicSyncJob != NULL, SYNC_ERROR_SYSTEM, "Failed to cast %d", syncJobId); + + ret = __pPeriodicSyncScheduler->RemoveAlarmForPeriodicSyncJob(periodicSyncJob); + SYNC_LOGE_RET_RES(ret == SYNC_ERROR_NONE, SYNC_ERROR_SYSTEM, "Failed to remove %d", syncJobId); + } + + SyncJob* pJob = dynamic_cast< SyncJob* > (pSyncJob); + if (pJob == NULL) + { + LOG_LOGD("Invalid sync job entry"); + ret = SYNC_ERROR_SYSTEM; + } + else + { + CancelSync(pJob); + } + + __pSyncJobsAggregator->RemoveSyncJob(packageId.c_str(), syncJobId); + + return ret; +} + + +SyncJobQueue* +SyncManager::GetSyncJobQueue(void) const +{ + return __pSyncJobQueue; +} + + +int +SyncManager::AddToSyncQueue(SyncJob* pJob) +{ + //No need to add mutex here, will be called during startup only + return __pSyncJobQueue->AddSyncJob(pJob); +} + + +void +SyncManager::AddRunningAccount(int account_id, int pid) +{ + __runningAccounts.insert(make_pair(account_id, pid)); +} + + +int +SyncManager::GetAccountPid(int account_id) +{ + map<int, int>::iterator it = __runningAccounts.find(account_id); + if (it != __runningAccounts.end()) + { + return it->second; + } + LOG_LOGD("Account id cant be found"); + return -1; +} + + +bool accountCb(account_h account, void* pUserData) +{ + int account_id = -1; + int ret = account_get_account_id(account, &account_id); + if (ret == ACCOUNT_ERROR_NONE) + { + SyncManager* pSyncManager = (SyncManager*)pUserData; + pSyncManager->AddRunningAccount(account_id, 0); + } + return true; +} + + +void +SyncManager::UpdateRunningAccounts(void) +{ +#if !defined(_SEC_FEATURE_CONTAINER_ENABLE) + __runningAccounts.clear(); + if (account_foreach_account_from_db(accountCb, this) < 0) + { + LOG_LOGD("UpdateRunningAccounts: Can not fetch account from db"); + } +#endif +} + +#if !defined(_SEC_FEATURE_CONTAINER_ENABLE) +bool OnAccountUpdated(const char* pEventType, int acountId, void* pUserData) +{ + //TODO: will go in enhancements + SyncManager* pSyncManager = (SyncManager*)pUserData; + pSyncManager->UpdateRunningAccounts(); + + //pSyncManager->ScheduleSync(NULL, NULL, REASON_ACCOUNT_UPDATED, NULL, 0, 0, false); + + return true; +} +#endif + +void +SyncManager::OnDNetStatusChanged(bool connected) +{ + LOG_LOGD("Data network change detected %d", connected); + + bool wasConnected = __isSimDataConnectionPresent; + __isSimDataConnectionPresent = connected; + if (__isSimDataConnectionPresent) + { + SendSyncCheckAlarmMessage(); + } +} + + +void +SyncManager::OnWifiStatusChanged(bool connected) +{ + LOG_LOGD("Wifi network change detected %d", connected); + + bool wasConnected = __isWifiConnectionPresent; + __isWifiConnectionPresent = connected; + if (__isWifiConnectionPresent) + { + SendSyncCheckAlarmMessage(); + } +} + + +void +SyncManager::OnBluetoothStatusChanged(bool connected) +{ + LOG_LOGD("Bluetooth status %d", connected); +} + + +void +SyncManager::OnStorageStatusChanged(int value) +{ + LOG_LOGD("Storage status changed %d", value); + switch (value) + { + case LOW_MEMORY_NORMAL: + __isStorageLow = false; + break; + case LOW_MEMORY_SOFT_WARNING: + __isStorageLow = true; + break; + case LOW_MEMORY_HARD_WARNING: + __isStorageLow = true; + break; + } +} + +void +SyncManager::OnUPSModeChanged(bool enable) +{ + __isUPSModeEnabled = enable; +} + + +void +SyncManager::OnBatteryStatusChanged(int value) +{ + LOG_LOGD("SyncManager::OnBatteryStatusChanged Starts"); + + switch (value) + { + case BAT_POWER_OFF: + break; + case BAT_CRITICAL_LOW: + break; + case BAT_WARNING_LOW: + break; + case BAT_NORMAL: + break; + case BAT_REAL_POWER_OFF: + break; + case BAT_FULL: + break; + } + + LOG_LOGD("SyncManager::OnBatteryStatusChanged Ends"); +} + + + + +static int OnPackageUninstalled(int reqId, const char* pPkgType, const char* pPkgId, const char* pKey, + const char* pVal, const void* pMsg, void* pData) +{ + LOG_LOGD("OnPackageUninstalled [type %s] type [pkdId:%s]", pPkgType, pPkgId); + if (!strcmp("end", pKey) && !strcmp("ok", pVal)) + { + SyncManager::GetInstance()->GetSyncAdapterAggregator()->HandlePackageUninstalled(pPkgId); + SyncManager::GetInstance()->GetSyncJobsAggregator()->HandlePackageUninstalled(pPkgId); + } + + return 0; +} + + +string +SyncManager::GetPkgIdByAppId(const char* pAppId) +{ + pkgmgrinfo_appinfo_h handle; + string pkgId; + + int result = pkgmgrinfo_appinfo_get_appinfo(pAppId, &handle); + if (result == PMINFO_R_OK) + { + char* pPkgId = NULL; + + result = pkgmgrinfo_appinfo_get_pkgid(handle, &pPkgId); + if (result == PMINFO_R_OK) + { + pkgId.append(pPkgId); + } + else + { + LOG_LOGD("Failed to get Pkg ID from App Id [%s]", pAppId); + } + pkgmgrinfo_appinfo_destroy_appinfo(handle); + } + else + { + LOG_LOGD("Failed to get pkgmgr AppInfoHandle from App Id [%s]", pAppId); + } + return pkgId; +} + + +string +SyncManager::GetPkgIdByCommandline(const char* pCommandLine) +{ + string pkgId; + if (pCommandLine != NULL) + { + char cmd[100]; + memset(cmd, 0x00, sizeof(cmd)); + snprintf(cmd, sizeof(cmd), "rpm -qf %s --queryformat '%{name}\\t'", pCommandLine); + + FILE* pipe = popen(cmd, "r"); + if (!pipe) + { + LOG_LOGD("Failed to open pipe."); + return pkgId; + } + + char *buffer = NULL; + size_t len = 0; + while (!feof(pipe)) + { + if (getdelim(&buffer, &len, '\t', pipe) != -1) + { + pkgId = buffer; + } + } + pclose(pipe); + free(buffer); + } + + return pkgId; +} + + + +void +SyncManager::RegisterForNetworkChange(void) +{ + if (__pNetworkChangeListener) + { + if(!__pNetworkChangeListener->RegisterNetworkChangeListener()) + { + LOG_LOGD("Network listener : Success"); + } + else + { + LOG_LOGD("Network listener : Failed"); + } + } +} + + +int +SyncManager::DeRegisterForNetworkChange(void) +{ + if (__pNetworkChangeListener) + { + return(__pNetworkChangeListener->DeRegisterNetworkChangeListener()); + } + return -1; +} + +void OnUPSModeChangedCb(keynode_t* pKey, void* pData) +{ + int value = vconf_keynode_get_int(pKey); + bool enabled = (value == SETTING_PSMODE_EMERGENCY); + LOG_LOGD("UPS mode status %d , value %d",enabled, value); + + SyncManager::GetInstance()->OnUPSModeChanged(enabled); +} + + +void +SyncManager::RegisterForUPSModeChange(void) +{ + if(vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, OnUPSModeChangedCb, NULL) == 0) + { + LOG_LOGD("UPS mode listener : Success"); + } + else + { + LOG_LOGD("UPS mode listener : Failed"); + } +} + + +int +SyncManager::DeRegisterForUPSModeChange(void) +{ + LOG_LOGD("De Registering UPS mode listener"); + + return vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE, OnUPSModeChangedCb); +} + + +void +SyncManager::RegisterForStorageChange(void) +{ + if (__pStorageListener) + { + if (__pStorageListener->RegisterStorageChangeListener() == 0) + { + LOG_LOGD("Storage listener : Success"); + } + else + { + LOG_LOGD("Storage listener : Failed"); + } + } +} + + +int +SyncManager::DeRegisterForStorageChange(void) +{ + if (__pStorageListener) + { + return(__pStorageListener->DeRegisterStorageChangeListener()); + } + return -1; +} + + +void +SyncManager::RegisterForBatteryStatus(void) +{ + if (__pBatteryStatusListener) + { + if(__pBatteryStatusListener->RegisterBatteryStatusListener() == 0) + { + LOG_LOGD("Battery listener : Success"); + } + else + { + LOG_LOGD("Battery listener : Failed"); + } + } +} + + +int +SyncManager::DeRegisterForBatteryStatus(void) +{ + if (__pBatteryStatusListener) + { + return(__pBatteryStatusListener->DeRegisterBatteryStatusListener()); + } + return -1; +} + + +void SyncManager::RegisterForDataChange(void) +{ + if (__pDataChangeSyncScheduler) + { + if(!__pDataChangeSyncScheduler->RegisterDataChangeListeners()) + { + LOG_LOGD("Data listener : Success"); + } + else + { + LOG_LOGD("Data listener : Failed"); + } + } +} + + +int SyncManager::DeRegisterForDataChange(void) +{ + if (__pDataChangeSyncScheduler) + { + return (__pDataChangeSyncScheduler->DeRegisterDataChangeListeners()); + } + + return -1; +} + + +int +SyncManager::SetPkgMgrClientStatusChangedListener(void) +{ + int eventType = PKGMGR_CLIENT_STATUS_UNINSTALL; + + if (pkgmgr_client_set_status_type(__pPkgmgrClient, eventType) != PKGMGR_R_OK) + { + LOG_LOGD("pkgmgr_client_set_status_type failed."); + pkgmgr_client_free(__pPkgmgrClient); + __pPkgmgrClient = NULL; + return -1; + } + + if (pkgmgr_client_listen_status(__pPkgmgrClient, OnPackageUninstalled, &__syncJobQueueMutex) < 0) + { + LOG_LOGD("pkgmgr_client_listen_status failed."); + pkgmgr_client_free(__pPkgmgrClient); + __pPkgmgrClient = NULL; + return -1; + } + + return 0; +} + + +RepositoryEngine* +SyncManager::GetSyncRepositoryEngine(void) +{ + return __pSyncRepositoryEngine; +} + + +void +SyncManager::ClearScheduledSyncJobs(SyncJob* pSyncJob) +{ + pthread_mutex_lock(&__syncJobQueueMutex); + __pSyncJobQueue->RemoveSyncJob(pSyncJob); + pthread_mutex_unlock(&__syncJobQueueMutex); +} + + +void +SyncManager::CancelActiveSyncJob(SyncJob* pSyncJob) +{ + pthread_mutex_lock(&__currJobQueueMutex); + CurrentSyncContext *pCurrSyncContext = __pCurrentSyncJobQueue->GetCurrJobfromKey(pSyncJob->__key); + pthread_mutex_unlock(&__currJobQueueMutex); + if (pCurrSyncContext != NULL) + { + g_source_remove(pCurrSyncContext->GetTimerId()); + CloseCurrentSyncContext(pCurrSyncContext); + SendCancelSyncsMessage(pSyncJob); + } +} + + +SyncManager::SyncManager(void) + : __isStorageLow (false) + , __isWifiConnectionPresent(false) + , __isSimDataConnectionPresent(false) + , __isUPSModeEnabled(false) + , __isSyncPermitted(true) + , __pNetworkChangeListener(NULL) + , __pStorageListener(NULL) + , __pBatteryStatusListener(NULL) + , __pDataChangeSyncScheduler(NULL) + , __pPeriodicSyncScheduler(NULL) + , __pSyncRepositoryEngine(NULL) + , __pSyncJobQueue(NULL) + , __pSyncJobDispatcher(NULL) + , __pSyncAdapterAggregator(NULL) + , __pCurrentSyncJobQueue(NULL) + , __accountSubscriptionHandle(NULL) +{ + +} + + +bool +SyncManager::Construct(void) +{ + //interface=org.freedesktop.systemd1.Manager Signal=StartupFinished - bootcomplete dbus signal + LOG_LOGD("Sync manager initialization begins"); + + int storageState; + int ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &storageState); + LOG_LOGE_BOOL(ret == VCONF_OK, "vconf_get_int failed %d", ret); + __isStorageLow = (storageState == LOW_MEMORY_NORMAL) ? false : true; + + int upsMode; + ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &upsMode); + LOG_LOGE_BOOL(ret == VCONF_OK, "vconf_get_int failed %d", ret); + __isUPSModeEnabled = (upsMode == SETTING_PSMODE_EMERGENCY) ? true : false; + + __pNetworkChangeListener = new (std::nothrow) NetworkChangeListener(); + LOG_LOGE_BOOL(__pNetworkChangeListener, "Failed to construct NetworkChangeListener"); + + __pStorageListener = new (std::nothrow) StorageChangeListener(); + LOG_LOGE_BOOL(__pStorageListener, "Failed to construct StorageChangeListener"); + + __pBatteryStatusListener = new (std::nothrow) BatteryStatusListener(); + LOG_LOGE_BOOL(__pBatteryStatusListener, "Failed to construct BatteryStatusListener"); + + __pDataChangeSyncScheduler = new (std::nothrow) DataChangeSyncScheduler(); + LOG_LOGE_BOOL(__pDataChangeSyncScheduler, "Failed to Construct DataChangeSyncScheduler"); + + __pPeriodicSyncScheduler = new (std::nothrow) PeriodicSyncScheduler(); + LOG_LOGE_BOOL(__pPeriodicSyncScheduler, "Failed to Construct PeriodicSyncScheduler"); + + __pSyncAdapterAggregator = new (std::nothrow) SyncAdapterAggregator(); + LOG_LOGE_BOOL(__pSyncAdapterAggregator, "Failed to construct SyncAdapterAggregator"); + + __pSyncJobsAggregator = new (std::nothrow) SyncJobsAggregator(); + LOG_LOGE_BOOL(__pSyncJobsAggregator, "Failed to construct SyncJobsAggregator"); + + __pSyncRepositoryEngine = RepositoryEngine::GetInstance(); + LOG_LOGE_BOOL(__pSyncRepositoryEngine, "Failed to construct RepositoryEngine"); + + __pSyncJobQueue = new (std::nothrow) SyncJobQueue(__pSyncRepositoryEngine); + LOG_LOGE_BOOL(__pSyncJobQueue, "Failed to construct SyncJobQueue"); + + __pCurrentSyncJobQueue = new (std::nothrow) CurrentSyncJobQueue(); + LOG_LOGE_BOOL(__pCurrentSyncJobQueue, "Failed to construct CurrentSyncJobQueue"); + + __pSyncJobDispatcher = new (std::nothrow) SyncJobDispatcher(); + LOG_LOGE_BOOL(__pSyncJobDispatcher, "Failed to construct SyncJobDispatcher"); + + __isWifiConnectionPresent = __pNetworkChangeListener->IsWifiConnected(); + __isSimDataConnectionPresent = __pNetworkChangeListener->IsDataConnectionPresent(); + + LOG_LOGD("wifi %d, sim %d storage %d", __isWifiConnectionPresent, __isSimDataConnectionPresent, __isStorageLow); + + __pDataChangeSyncScheduler->RegisterDataChangeListeners(); + + LOG_LOGD("Register event listeners"); + RegisterForNetworkChange(); + RegisterForStorageChange(); + RegisterForBatteryStatus(); + RegisterForUPSModeChange(); + + LOG_LOGE_BOOL(pthread_mutex_init(&__syncJobQueueMutex, NULL) == 0, "__syncJobQueueMutex init failed"); + LOG_LOGE_BOOL(pthread_mutex_init(&__currJobQueueMutex, NULL) == 0, "__currJobQueueMutex init failed"); + + __pPkgmgrClient = pkgmgr_client_new(PC_LISTENING); + LOG_LOGE_BOOL(__pPkgmgrClient != NULL, "__pPkgmgrClient is null"); + + LOG_LOGE_BOOL(SetPkgMgrClientStatusChangedListener() == 0, "Failed to register for uninstall callback."); + + +#if !defined(_SEC_FEATURE_CONTAINER_ENABLE) + UpdateRunningAccounts(); + + if (account_subscribe_create(&__accountSubscriptionHandle) < 0) + { + LOG_LOGD("Failed to create account subscription handle"); + } + else if (account_subscribe_notification(__accountSubscriptionHandle, OnAccountUpdated, this) < 0) + { + LOG_LOGD("Failed to register callback for account updation"); + } +#endif + + + Initialize(); + + __pSyncRepositoryEngine->OnBooting(); + return true; +} + + +SyncManager::~SyncManager(void) +{ + LOG_LOGD("SyncManager::~SyncManager() Starts"); + + pthread_mutex_destroy(&__syncJobQueueMutex); + pthread_mutex_destroy(&__currJobQueueMutex); + + DeRegisterForNetworkChange(); + DeRegisterForStorageChange(); + DeRegisterForBatteryStatus(); + DeRegisterForDataChange(); + DeRegisterForUPSModeChange(); + + delete __pNetworkChangeListener; + delete __pStorageListener; + delete __pBatteryStatusListener; + delete __pDataChangeSyncScheduler; + delete __pPeriodicSyncScheduler; + delete __pSyncRepositoryEngine; + delete __pSyncJobQueue; + delete __pSyncJobDispatcher; + delete __pCurrentSyncJobQueue; + delete __pSyncAdapterAggregator; + + if (__pPkgmgrClient) + { + pkgmgr_client_free(__pPkgmgrClient); + } + __pPkgmgrClient = NULL; + + //TODO: uncomment below lines for running accounts logic + /*if (account_unsubscribe_notification(__accountSubscriptionHandle) < 0) + { + LOG_LOGD("SyncManager::SyncManager failed to deregister callback for account updation"); + }*/ + LOG_LOGD("SyncManager::~SyncManager() Ends"); +} + + +bool +SyncManager::AreAccountsEqual(account_h account1, account_h account2) +{ + bool isEqual = false; + int id1, id2; + if (account_get_account_id(account1, &id1) < 0) + { + isEqual = false; + } + if (account_get_account_id(account2, &id2) < 0) + { + isEqual = false; + } + + char* pName1; + char* pName2; + if (account_get_user_name(account1, &pName1) < 0) + { + isEqual = false; + } + if (account_get_user_name(account2, &pName2) < 0) + { + isEqual = false; + } + + if (id1 == id2 && strcmp(pName1, pName2) == 0) + { + isEqual = true; + } + + return isEqual; +} + + +bool +SyncManager::IsActiveAccount(vector<account_h> accounts, account_h account) +{ + return true; + //TODO: uncomment while implementing __running accounts logic + /* + for (unsigned int i = 0; i < accounts.size(); i++) + { + if (AreAccountsEqual(accounts[i], account)) + { + return true; + } + } + + return false;*/ +} + + +SyncAdapterAggregator* +SyncManager::GetSyncAdapterAggregator() +{ + return __pSyncAdapterAggregator; +} + + +SyncJobsAggregator* +SyncManager::GetSyncJobsAggregator() +{ + return __pSyncJobsAggregator; +} + +void +SyncManager::HandleShutdown(void) +{ + pthread_mutex_lock(&__syncJobQueueMutex); + __pSyncRepositoryEngine->SaveCurrentState(); + pthread_mutex_unlock(&__syncJobQueueMutex); +} + + +bool +SyncManager::GetSyncSupport(int accountId) +{ + account_h accountHandle = NULL; + int ret = account_create(&accountHandle); + LOG_LOGE_BOOL(ret == ACCOUNT_ERROR_NONE, "account access failed [%d]", ret); + + KNOX_CONTAINER_ZONE_ENTER(GetAccountPid(accountId)); + ret = account_query_account_by_account_id(accountId, &accountHandle); + KNOX_CONTAINER_ZONE_EXIT(); + LOG_LOGE_BOOL(ret == ACCOUNT_ERROR_NONE, "account query failed [%d]", ret); + + account_sync_state_e syncSupport; + ret = account_get_sync_support(accountHandle, &syncSupport); + LOG_LOGE_BOOL(ret == ACCOUNT_ERROR_NONE, "account access failed [%d]", ret); + + if (syncSupport == ACCOUNT_SYNC_INVALID || syncSupport == ACCOUNT_SYNC_NOT_SUPPORT) + { + LOG_LOGD("The account does not support sync"); + return false; + } + + return true; +} + + +void +SyncManager::SendCancelSyncsMessage(SyncJob* pJob) +{ + LOG_LOGD("SyncManager::SendCancelSyncsMessage :sending MESSAGE_CANCEL"); + Message msg; + msg.type = SYNC_CANCEL; + msg.pSyncJob = new SyncJob(*pJob); + FireEvent(__pSyncJobDispatcher, msg); +} + + +void +SyncManager::OnResultReceived(SyncStatus res, string appId, string packageId, const char* syncJobName) +{ + string key; + key.append("id:").append(appId).append(syncJobName); + + LOG_LOGD("Close Sync context for key %s", key.c_str()); + + pthread_mutex_lock(&__currJobQueueMutex); + CurrentSyncContext *pCurrSyncContext = __pCurrentSyncJobQueue->GetCurrJobfromKey(key); + pthread_mutex_unlock(&__currJobQueueMutex); + if (pCurrSyncContext == NULL) + { + LOG_LOGD("Sync context cant be found for %s", key.c_str()); + } + else + { + g_source_remove(pCurrSyncContext->GetTimerId()); + SyncJob* pJob = pCurrSyncContext->GetSyncJob(); + SendSyncCompletedOrCancelledMessage(pJob, res); + CloseCurrentSyncContext(pCurrSyncContext); + + if (res == SYNC_STATUS_SUCCESS && pJob->GetSyncType() == SYNC_TYPE_ON_DEMAND) + { + LOG_LOGD("On demand sync completed. Deleting the job %s", key.c_str()); + __pSyncJobsAggregator->RemoveSyncJob(packageId.c_str(), syncJobName); + } + } +} + + +void +SyncManager::CloseCurrentSyncContext(CurrentSyncContext *activeSyncContext) +{ + if (activeSyncContext == NULL) + { + LOG_LOGD("Invalid Parameter"); + return; + } + pthread_mutex_lock(&(__currJobQueueMutex)); + __pCurrentSyncJobQueue->RemoveSyncContextFromCurrentSyncQueue(activeSyncContext); + pthread_mutex_unlock(&(__currJobQueueMutex)); +} + + +void +SyncManager::SendSyncCompletedOrCancelledMessage(SyncJob *pJob, int result) +{ + LOG_LOGD("SyncManager::SendSyncCompletedOrCancelledMessage"); + Message msg; + msg.res = (SyncStatus)result; + msg.pSyncJob = pJob; + msg.type = SYNC_FINISHED; + FireEvent(__pSyncJobDispatcher, msg); +} + + +void +SyncManager::AlertForChange() +{ + SendSyncCheckAlarmMessage(); +} + + +void +SyncManager::SendSyncAlarmMessage() +{ + LOG_LOGD("Fire SYNC_ALARM"); + Message msg; + msg.type = SYNC_ALARM; + FireEvent(__pSyncJobDispatcher, msg); +} + +void +SyncManager::SendSyncCheckAlarmMessage() +{ + LOG_LOGD("Fire SYNC_CHECK_ALARM "); + Message msg; + msg.type = SYNC_CHECK_ALARM; + //TO DO: Implement code to remove all the pending messages from queue before firing a new one + FireEvent(__pSyncJobDispatcher, msg); +} + +/* + * + */ +bool +SyncManager::GetBundleVal(const char* pVal) +{ + if (pVal == NULL) + { + return false; + } + else return strcmp(pVal, "true")? true: false; +} + + +bool get_capability_all_cb(const char* capability_type, account_capability_state_e capability_state, void *user_data) +{ + set<string>* pSsncableCapabilities = (set<string>*)user_data; + + if (capability_state == ACCOUNT_CAPABILITY_ENABLED) + { + pSsncableCapabilities->insert(capability_type); + } + return true; +} + + +void +SyncManager::ScheduleSyncJob(SyncJob* pJob, bool fireCheckAlarm) +{ + int err; + pthread_mutex_lock(&__syncJobQueueMutex); + err = __pSyncJobQueue->AddSyncJob(pJob); + pthread_mutex_unlock(&__syncJobQueueMutex); + + if (err == SYNC_ERROR_NONE) + { + if(fireCheckAlarm) + { + LOG_LOGD("Added sync job [%s] to Main queue, Intiating dispatch sequence", pJob->__key.c_str()); + SendSyncCheckAlarmMessage(); + } + } + else if (err == SYNC_ERROR_ALREADY_IN_PROGRESS) + { + LOG_LOGD("Duplicate sync job [%s], No need to enqueue", pJob->__key.c_str()); + } + else + { + LOG_LOGD("Failed to add into sync job list"); + } +} + + +void +SyncManager::TryToRescheduleJob(SyncStatus syncResult, SyncJob* pJob) +{ + if (pJob == NULL) + { + LOG_LOGD("Invalid parameter"); + return; + } + LOG_LOGD("Reschedule for %s", pJob->__appId.c_str()); + + if (syncResult == SYNC_STATUS_FAILURE || syncResult == SYNC_STATUS_CANCELLED) + { + if (!pJob->IsNoRetry()) + { + ScheduleSyncJob(pJob, false); + } + } +} + + +bool +SyncManager::IsJobActive(CurrentSyncContext *pCurrSync) +{ + if (pCurrSync == NULL) + { + LOG_LOGD("Invalid parameter"); + return false; + } + pthread_mutex_lock(&__currJobQueueMutex); + bool ret = __pCurrentSyncJobQueue->IsJobActive(pCurrSync); + pthread_mutex_unlock(&__currJobQueueMutex); + return ret; +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncManager.h b/src/sync-service/SyncManager_SyncManager.h new file mode 100644 index 0000000..b1f5b44 --- /dev/null +++ b/src/sync-service/SyncManager_SyncManager.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncManager.h + * @brief This is the header file for the SyncManager class. + */ + +#ifndef SYNC_SERVICE_SYNC_MANAGER_H +#define SYNC_SERVICE_SYNC_MANAGER_H + +#include <iostream> +#include <list> +#include <bundle.h> +#include <bundle_internal.h> +#include <stdio.h> +#include <account.h> +#include <package-manager.h> +#include <media_content_type.h> +#include "SyncManager_SyncJobQueue.h" +#include "SyncManager_RepositoryEngine.h" +#include "SyncManager_NetworkChangeListener.h" +#include "SyncManager_StorageChangeListener.h" +#include "SyncManager_BatteryStatusListener.h" +#include "SyncManager_DataChangeSyncScheduler.h" +#include "SyncManager_PeriodicSyncScheduler.h" +#include "SyncManager_SyncJobDispatcher.h" +#include "SyncManager_SyncService.h" +#include "SyncManager_SyncWorker.h" +#include "SyncManager_Singleton.h" +#include "SyncManager_CurrentSyncJobQueue.h" +#include "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{ +*/ + +struct backOff; +class SyncStatusInfo; +class RepositoryEngine; +class SyncJob; +class SyncAdapterAggregator; +class SyncJobsAggregator; + +using namespace std; + +class SyncManager + : public SyncWorker, public Singleton<SyncManager> +{ + +public: + void SetSyncSetting(bool enable); + + bool GetSyncSetting(); + + int AddOnDemandSync(string pPackageId, const char* syncJobName, int accountId, bundle* pExtras, int syncOption, int syncJobId); + + int CancelSync(SyncJob* pJob); + + int AddPeriodicSyncJob(string pPackageId, const char* syncJobName, int accountId, bundle* pExtras, int syncOption, int syncJobId, long period); + + int AddDataSyncJob(string pPackageId, const char* syncJobName, int accountId, bundle* pExtras, int syncOption, int syncJobId, const char* pCapability); + + int RemoveSyncJob(string packageId, int syncJobId); + + SyncJobQueue* GetSyncJobQueue(void) const; + + int AddToSyncQueue(SyncJob* pJob); + + //Callback on wifi, cellular, bt and wifidirect status change + void OnDNetStatusChanged(bool connected); + + void OnWifiStatusChanged(bool connected); + + void OnBluetoothStatusChanged(bool connected); + + void OnStorageStatusChanged(int value); + + void OnBatteryStatusChanged(int value); + + void OnUPSModeChanged(bool enable); + + RepositoryEngine* GetSyncRepositoryEngine(void); + + bool AreAccountsEqual(account_h account1, account_h account2); + + bool GetSyncSupport(int accountId); + + SyncAdapterAggregator* GetSyncAdapterAggregator(); + + SyncJobsAggregator* GetSyncJobsAggregator(); + + void AddSyncAdapter(string packageId, string svcAppId); + + void AddRunningAccount(int account_id, int pid); + + int GetAccountPid(int account_id); + + void UpdateRunningAccounts(void); + + void ScheduleSyncJob(SyncJob* pJob, bool fireCheckAlarm = true); + + void SendSyncCompletedOrCancelledMessage(SyncJob *pJob, int result); + + void AlertForChange(); + + void OnResultReceived(SyncStatus res, string svcAppId, string packageId, const char* syncJobName); + + string GetPkgIdByAppId(const char* pAppId); + + string GetPkgIdByCommandline(const char* pCommandLine); + + void HandleShutdown(void); + + void CloseCurrentSyncContext(CurrentSyncContext *activeSyncContext); + +protected: + SyncManager(void); + + ~SyncManager(void); + + friend class Singleton< SyncManager >; + +private: + bool Construct(); + + void RegisterForUPSModeChange(); + + int DeRegisterForUPSModeChange(); + + void RegisterForNetworkChange(void); + + int DeRegisterForNetworkChange(void); + + void RegisterForStorageChange(void); + + int DeRegisterForStorageChange(void); + + void RegisterForBatteryStatus(void); + + int DeRegisterForBatteryStatus(void); + + void RegisterForDataChange(void); + + int DeRegisterForDataChange(void); + + int SetPkgMgrClientStatusChangedListener(void); + + void ClearScheduledSyncJobs(SyncJob* pSyncJob); + + void CancelActiveSyncJob(SyncJob* pSyncJob); + + bool IsActiveAccount(vector<account_h> accounts, account_h account); + + void TryToRescheduleJob(SyncStatus syncResult, SyncJob* pJob); + + bool IsJobActive(CurrentSyncContext *pCurrSync); + + void SendCancelSyncsMessage(SyncJob* pSyncJob); + + void SendSyncAlarmMessage(); + + void SendSyncCheckAlarmMessage(); + + bool GetBundleVal(const char* pKey); + +private: + + SyncManager(const SyncManager&); + + const SyncManager& operator=(const SyncManager&); + +private: + bool __isStorageLow; + bool __isWifiConnectionPresent; + bool __isSimDataConnectionPresent; + bool __isUPSModeEnabled; + bool __isSyncPermitted; + + NetworkChangeListener* __pNetworkChangeListener; + StorageChangeListener* __pStorageListener; + BatteryStatusListener* __pBatteryStatusListener; + DataChangeSyncScheduler* __pDataChangeSyncScheduler; + PeriodicSyncScheduler* __pPeriodicSyncScheduler; + + RepositoryEngine* __pSyncRepositoryEngine; + SyncJobQueue* __pSyncJobQueue; + SyncJobDispatcher* __pSyncJobDispatcher; + map<string, string> __syncAdapterList; + + SyncAdapterAggregator* __pSyncAdapterAggregator; + SyncJobsAggregator* __pSyncJobsAggregator; + CurrentSyncJobQueue* __pCurrentSyncJobQueue; + account_subscribe_h __accountSubscriptionHandle; + map<int, int> __runningAccounts; + //vector<account_h> __runningAccounts; + + pthread_mutex_t __syncJobQueueMutex; + pthread_mutex_t __currJobQueueMutex; + + pkgmgr_client* __pPkgmgrClient; + + friend class SyncJobDispatcher; + friend class RepositoryEngine; + friend class SyncService; +}; +//}//_SyncManager +#endif //SYNC_SERVICE_SYNC_MANAGER_H diff --git a/src/sync-service/SyncManager_SyncService.cpp b/src/sync-service/SyncManager_SyncService.cpp new file mode 100644 index 0000000..59ce564 --- /dev/null +++ b/src/sync-service/SyncManager_SyncService.cpp @@ -0,0 +1,1120 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncManager.cpp + * @brief This is the implementation file for the SyncService class. + */ + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <assert.h> +#include <glib.h> +#include <app.h> +#include <aul.h> +#include <app_manager.h> +#include <pkgmgr-info.h> +#include <security-server.h> +#include "sync-error.h" +#include "SyncManager_SyncManager.h" +#include "sync-manager-stub.h" +#include "sync-ipc-marshal.h" +#include "sync-adapter-stub.h" +#include "SyncManager_SyncService.h" +#include "SyncManager_SyncDefines.h" +#include "SyncManager_SyncJobsInfo.h" +#include "SyncManager_SyncAdapterAggregator.h" +#include "SyncManager_SyncJobsAggregator.h" + +static GDBusConnection* gdbusConnection = NULL; + +/*namespace _SyncManager +{*/ + +#define SYNC_MANAGER_DBUS_PATH "/org/tizen/sync/manager" +#define SYNC_ADAPTER_DBUS_PATH "/org/tizen/sync/adapter/" +#define SYNC_ERROR_DOMAIN "sync-manager" +#define SYNC_ERROR_PREFIX "org.tizen.sync.Error" +#define ALARM_SET_LABEL "alarm-server::alarm" +#define CALENDAR_READ_LABEL "calendar-service::svc" +#define CONTACT_READ_LABEL "contacts-service::svc" +#define READ_PERM "r" +#define WRITE_PERM "w" + +GDBusObjectManagerServer* pServerManager = NULL; + + +static TizenSyncManager* sync_ipc_obj = NULL; +GHashTable* g_hash_table = NULL; +string sa_app_id; + +using namespace std; + +void convert_to_path(char app_id[]) +{ + int i = 0; + while (app_id[i] != '\0') + { + if (app_id[i] == '.' || app_id[i] == '-') + { + app_id[i] = '_'; + } + i++; + } +} + +int +SyncService::StartService() +{ + __pSyncMangerIntacnce = SyncManager::GetInstance(); + if (__pSyncMangerIntacnce == NULL) + { + LOG_LOGD("Failed to initialize sync manager"); + return -1; + } + + return 0; +} + +TizenSyncAdapter* adapter; + +GDBusErrorEntry _sync_errors[] = +{ + {SYNC_ERROR_NONE, SYNC_ERROR_PREFIX".NoError"}, + {SYNC_ERROR_OUT_OF_MEMORY, SYNC_ERROR_PREFIX".OutOfMemory"}, + {SYNC_ERROR_IO_ERROR, SYNC_ERROR_PREFIX".IOError"}, + {SYNC_ERROR_PERMISSION_DENIED, SYNC_ERROR_PREFIX".PermissionDenied"}, + {SYNC_ERROR_ALREADY_IN_PROGRESS, SYNC_ERROR_PREFIX".AlreadyInProgress"}, + {SYNC_ERROR_INVALID_OPERATION, SYNC_ERROR_PREFIX".InvalidOperation"}, + {SYNC_ERROR_INVALID_PARAMETER, SYNC_ERROR_PREFIX".InvalidParameter"}, + {SYNC_ERROR_QUOTA_EXCEEDED, SYNC_ERROR_PREFIX".QuotaExceeded"}, + {SYNC_ERROR_UNKNOWN, SYNC_ERROR_PREFIX".Unknown"}, + {SYNC_ERROR_SYSTEM, SYNC_ERROR_PREFIX".System"}, + {SYNC_ERROR_SYNC_ADAPTER_NOT_FOUND, SYNC_ERROR_PREFIX".SyncAdapterIsNotFound"}, +}; + +static GQuark +_sync_error_quark (void) +{ + static volatile gsize quark_volatile = 0; + + g_dbus_error_register_error_domain (SYNC_ERROR_DOMAIN, + &quark_volatile, + _sync_errors, + G_N_ELEMENTS (_sync_errors)); + + return (GQuark) quark_volatile; +} + + +static int +_check_privilege_by_pid(const char *label, const char *access_perm, bool check_root, int pid) { + guchar *cookie = NULL; + gsize size = 0; + int retval = 0; + char buf[128] = {0,}; + FILE *fp = NULL; + char title[128] = {0,}; + int uid = -1; + + if (check_root) { + // Gets the userID from /proc/pid/status to check if the process is the root or not. + snprintf(buf, sizeof(buf), "/proc/%d/status", pid); + fp = fopen(buf, "r"); + if(fp) { + while (fgets(buf, sizeof(buf), fp) != NULL) { + if(strncmp(buf, "Uid:", 4) == 0) { + sscanf(buf, "%s %d", title, &uid); + break; + } + } + fclose(fp); + } + } + + if (uid != 0) { // Checks the privilege only when the process is not the root + retval = security_server_check_privilege_by_pid(pid, label, access_perm); + + if (retval < 0) { + if (retval == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) { + LOG_ERRORD("permission denied, app don't has \"%s %s\" smack rule.", label, access_perm); + } else { + LOG_ERRORD("Error has occurred in security_server_check_privilege_by_cookie() %d", retval); + } + return SYNC_ERROR_PERMISSION_DENIED; + } + } + + LOG_LOGD("The process(%d) was authenticated successfully.", pid); + return SYNC_ERROR_NONE; +} + + +int +SyncService::TriggerStartSync(const char* appId, int accountId, const char* syncJobName, bool isDataSync, bundle* pExtras) +{ + LOG_LOGD("appId [%s] jobname [%s]", appId, syncJobName); + + app_control_h app_control; + int ret = SYNC_ERROR_NONE; + + int isRunning = aul_app_is_running(appId); + if (isRunning == 0) + { + LOG_LOGD("app is not running, launch the app and wait for signal"); + ret = app_control_create(&app_control); + SYNC_LOGE_RET_RES(ret == APP_CONTROL_ERROR_NONE, SYNC_ERROR_SYSTEM,"app control create failed %d", ret); + + ret = app_control_set_app_id(app_control, appId); + if (ret != APP_CONTROL_ERROR_NONE) + { + LOG_LOGD("app control error %d", ret); + app_control_destroy(app_control); + return SYNC_ERROR_SYSTEM; + } + + sa_app_id.clear(); + ret = app_control_send_launch_request(app_control, NULL, NULL); + SYNC_LOGE_RET_RES(ret == APP_CONTROL_ERROR_NONE, SYNC_ERROR_SYSTEM, "app control launch request failed %d", ret); + } + else + { + LOG_LOGD("app is already running"); + } + + TizenSyncAdapter* pSyncAdapter = (TizenSyncAdapter*) g_hash_table_lookup(g_hash_table, appId); + if (pSyncAdapter) + { + GVariant* pBundle = marshal_bundle(pExtras); + tizen_sync_adapter_emit_start_sync(pSyncAdapter, accountId, syncJobName, isDataSync, pBundle); + } + else + { + LOG_LOGD("Sync adapter entry not found"); + return SYNC_ERROR_SYSTEM; + } + + return SYNC_ERROR_NONE; + +} + + +void +SyncService::TriggerStopSync(const char* appId, int accountId, const char* syncJobName, bool isDataSync, bundle* pExtras) +{ + LOG_LOGD("Trigger stop sync %s", appId); + + int id = -1; + + TizenSyncAdapter* pSyncAdapter = (TizenSyncAdapter*) g_hash_table_lookup(g_hash_table, appId); + if (pSyncAdapter == NULL) + { + LOG_LOGD("Failed to lookup syncadapter"); + return; + } + GVariant* pBundle = marshal_bundle(pExtras); + tizen_sync_adapter_emit_cancel_sync(pSyncAdapter, accountId, syncJobName, isDataSync, pBundle); +} + + +int +SyncService::RequestOnDemandSync(const char* pPackageId, const char* pSyncJobName, int accountId, bundle* pExtras, int syncOption, int* pSyncJobId) +{ + int ret = SYNC_ERROR_NONE; + int syncJobId = -1; + SyncJobsAggregator* pSyncJobsAggregator = __pSyncMangerIntacnce->GetSyncJobsAggregator(); + + ISyncJob* pSyncJob = pSyncJobsAggregator->GetSyncJob(pPackageId, pSyncJobName); + if (pSyncJob) + { + SyncJob* pSyncJobEntry = dynamic_cast< SyncJob* > (pSyncJob); + SYNC_LOGE_RET_RES(pSyncJobEntry != NULL, SYNC_ERROR_SYSTEM, "Failed to get sync job"); + + syncJobId = pSyncJobEntry->GetSyncJobId(); + LOG_LOGD("Sync request with job name [%s] already found. Sync job id [%d]", pSyncJobName, syncJobId); + + pSyncJobEntry->Reset(accountId, pExtras, syncOption); + LOG_LOGD("sync parameters are updated with new parameters", pSyncJobName); + } + else + { + syncJobId = pSyncJobsAggregator->GenerateSyncJobId(pPackageId); + SYNC_LOGE_RET_RES(syncJobId <= SYNC_JOB_LIMIT, SYNC_ERROR_QUOTA_EXCEEDED, "Sync job quota exceeded"); + + LOG_LOGD("New sync request. Adding sync job with Sync job name [%s] Sync job id [%d]", pSyncJobName, syncJobId); + ret = __pSyncMangerIntacnce->AddOnDemandSync(pPackageId, pSyncJobName, accountId, pExtras, syncOption, syncJobId); + } + + if (ret == SYNC_ERROR_NONE) + { + *pSyncJobId = syncJobId; + } + + return ret; +} + + +int +SyncService::RequestPeriodicSync(const char* pPackageId, const char* pSyncJobName, int accountId, bundle* pExtras, int syncOption, unsigned long pollFrequency, int* pSyncJobId) +{ + int ret = SYNC_ERROR_NONE; + SyncJobsAggregator* pSyncJobsAggregator = __pSyncMangerIntacnce->GetSyncJobsAggregator(); + int syncJobId = -1; + + ISyncJob* pSyncJob = pSyncJobsAggregator->GetSyncJob(pPackageId, pSyncJobName); + if (pSyncJob) + { + PeriodicSyncJob* pSyncJobEntry = dynamic_cast< PeriodicSyncJob* > (pSyncJob); + SYNC_LOGE_RET_RES(pSyncJobEntry != NULL, SYNC_ERROR_SYSTEM, "Failed to get syn job"); + + syncJobId = pSyncJobEntry->GetSyncJobId(); + LOG_LOGD("Sync request with job name [%s] already found. Sync job id [%d]", pSyncJobName, syncJobId); + + pSyncJobEntry->Reset(accountId, pExtras, syncOption, pollFrequency); + LOG_LOGD("sync parameters are updated with new parameters", pSyncJobName); + } + else + { + syncJobId = pSyncJobsAggregator->GenerateSyncJobId(pPackageId); + SYNC_LOGE_RET_RES(syncJobId <= SYNC_JOB_LIMIT, SYNC_ERROR_QUOTA_EXCEEDED, "Sync job quota exceeded"); + + LOG_LOGD("New sync request. Adding sync job with Sync job name [%s] Sync job id [%d]", pSyncJobName, syncJobId); + ret = __pSyncMangerIntacnce->AddPeriodicSyncJob(pPackageId, pSyncJobName, accountId, pExtras, syncOption, syncJobId, pollFrequency); + } + + if (ret == SYNC_ERROR_NONE) + { + *pSyncJobId = syncJobId; + } + return ret; +} + + +int +SyncService::RequestDataSync(const char* pPackageId, const char* pSyncJobName, int accountId, bundle* pExtras, int syncOption, const char* pCapability, int* pSyncJobId) +{ + int ret = SYNC_ERROR_NONE; + SyncJobsAggregator* pSyncJobsAggregator = __pSyncMangerIntacnce->GetSyncJobsAggregator(); + int syncJobId = -1; + + ISyncJob* pSyncJob = pSyncJobsAggregator->GetSyncJob(pPackageId, pSyncJobName); + if (pSyncJob) + { + DataSyncJob* pSyncJobEntry = dynamic_cast< DataSyncJob* > (pSyncJob); + SYNC_LOGE_RET_RES(pSyncJobEntry != NULL, SYNC_ERROR_SYSTEM, "Failed to get syn job"); + + syncJobId = pSyncJobEntry->GetSyncJobId(); + LOG_LOGD("Sync request with job name [%s] already found. Sync job id [%d]", pSyncJobName, syncJobId); + + pSyncJobEntry->Reset(accountId, pExtras, syncOption, pCapability); + LOG_LOGD("sync parameters are updated with new parameters", pSyncJobName); + } + else + { + syncJobId = pSyncJobsAggregator->GenerateSyncJobId(pPackageId); + SYNC_LOGE_RET_RES(syncJobId <= SYNC_JOB_LIMIT, SYNC_ERROR_QUOTA_EXCEEDED, "Sync job quota exceeded"); + + LOG_LOGD("New sync request. Adding sync job with Sync job name [%s] Sync job id [%d]", pSyncJobName, syncJobId); + ret = __pSyncMangerIntacnce->AddDataSyncJob(pPackageId, pSyncJobName, accountId, pExtras, syncOption, syncJobId, pCapability); + } + + if (ret == SYNC_ERROR_NONE) + { + *pSyncJobId = syncJobId; + } + return ret; +} + + +void +SyncService::HandleShutdown(void) +{ + LOG_LOGD("Shutdown Starts"); + + SyncManager::GetInstance()->HandleShutdown(); + + LOG_LOGD("Shutdown Ends"); +} + + +static guint +get_caller_pid(GDBusMethodInvocation* pMethodInvocation) +{ + guint pid = -1; + const char *name = NULL; + name = g_dbus_method_invocation_get_sender(pMethodInvocation); + if (name == NULL) + { + LOG_LOGD("GDbus error: Failed to get sender name"); + return -1; + } + + GError *error = NULL; + GDBusConnection* conn = g_dbus_method_invocation_get_connection(pMethodInvocation); + GVariant *ret = g_dbus_connection_call_sync(conn, "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixProcessID", + g_variant_new("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + + if (ret != NULL) + { + g_variant_get(ret, "(u)", &pid); + g_variant_unref(ret); + } + + return pid; +} + + +/* +* org.tizen.sync.adapter interface methods +*/ +gboolean +sync_adapter_handle_send_result( TizenSyncAdapter* pObject, GDBusMethodInvocation* pInvocation, + gint sync_result, + const gchar* sync_job_name) +{ + LOG_LOGD("Received sync job result"); + guint pid = get_caller_pid(pInvocation); + + string pkgIdStr; + char* pAppId = NULL; + int ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + LOG_LOGD("Request seems to be from app-id less/command line based request"); + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + + if (!pkgIdStr.empty()) + { + LOG_LOGD("Sync result received from [%s]: sync_job_name [%s] result [%d]", pAppId, sync_job_name, sync_result); + + SyncManager::GetInstance()->OnResultReceived((SyncStatus)sync_result, pAppId, pkgIdStr, sync_job_name); + free(pAppId); + } + else + LOG_LOGD("Get package Id fail %d", ret); + + tizen_sync_adapter_complete_send_result(pObject, pInvocation); + + /// Syncadapter may kill self after sync. + /// aul_terminate_pid(pid); + + return true; +} + + +gboolean +sync_adapter_handle_init_complete(TizenSyncAdapter* pObject, GDBusMethodInvocation* pInvocation) +{ + guint pid = get_caller_pid(pInvocation); + char* pAppId = NULL; + + int ret = app_manager_get_app_id(pid, &pAppId); + if(ret != APP_MANAGER_ERROR_NONE) + LOG_LOGD("app_manager_get_app_id fail"); + + sa_app_id.append(pAppId); + + LOG_LOGD("sync adapter client initialisation completed %s", pAppId); + + free(pAppId); + //tizen_sync_adapter_complete_init_complete(pObject, pInvocation); + + return true; +} + + +/* +* org.tizen.sync.manager interface methods +*/ +gboolean +sync_manager_add_on_demand_sync_job(TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation, + gint accountId, + const gchar* pSyncJobName, + gint sync_option, + GVariant* pSyncJobUserData) +{ + LOG_LOGD("Received On-Demand Sync request"); + + guint pid = get_caller_pid(pInvocation); + string pkgIdStr; + char* pAppId = NULL; + int ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + free(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + if (ret == AUL_R_OK) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + } + int sync_job_id = 0; + if(!pkgIdStr.empty()) + { + LOG_LOGD("Params acc[%d] name[%s] option[%d] package[%s]", accountId, pSyncJobName, sync_option, pkgIdStr.c_str()); + bundle* pBundle = umarshal_bundle(pSyncJobUserData); + SyncManager::GetInstance()->AddRunningAccount(accountId, pid); + ret = SyncService::GetInstance()->RequestOnDemandSync(pkgIdStr.c_str(), pSyncJobName, accountId, pBundle, sync_option, &sync_job_id); + bundle_free(pBundle); + } + else + { + LOG_LOGD("Failed to get package id"); + ret = SYNC_ERROR_SYSTEM; + } + + if (ret != SYNC_ERROR_NONE) + { + GError* error = g_error_new (_sync_error_quark(), ret, "system error"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + } + else + tizen_sync_manager_complete_add_on_demand_sync_job(pObject, pInvocation, sync_job_id); + + LOG_LOGD("End of On-Demand Sync request"); + + return true; +} + + +gboolean +sync_manager_remove_sync_job(TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation, gint sync_job_id) +{ + LOG_LOGD("Request to remove sync job %d", sync_job_id); + int ret = SYNC_ERROR_SYSTEM; + guint pid = get_caller_pid(pInvocation); + string pkgIdStr; + char* pAppId; + ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + free(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + LOG_LOGD("Request seems to be from app-id less/command line based request"); + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + if(!pkgIdStr.empty()) + { + LOG_LOGD("package id [%s]", pkgIdStr.c_str()); + ret = SyncManager::GetInstance()->RemoveSyncJob(pkgIdStr, sync_job_id); + } + + if (ret != SYNC_ERROR_NONE) + { + GError* error = g_error_new (_sync_error_quark(), ret, "system error"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + } + else + tizen_sync_manager_complete_remove_sync_job(pObject, pInvocation); + + LOG_LOGD("sync service: remove sync job ends"); + return true; +} + + +gboolean +sync_manager_add_periodic_sync_job(TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation, + gint accountId, + const gchar* pSyncJobName, + gint sync_interval, + gint sync_option, + GVariant* pSyncJobUserData) +{ + LOG_LOGD("Received Period Sync request"); + + int ret = SYNC_ERROR_NONE; + guint pid = get_caller_pid(pInvocation); + + ret = _check_privilege_by_pid(ALARM_SET_LABEL, WRITE_PERM, true, pid); + if (ret != SYNC_ERROR_NONE) { + GError* error = g_error_new (_sync_error_quark(), ret, "permission denied error"); + g_dbus_method_invocation_return_gerror (pInvocation, error); + g_clear_error(&error); + return true; + } + string pkgIdStr; + + int sync_job_id = 0; + char* pAppId; + ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + free(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + LOG_LOGD("Request seems to be from app-id less/command line based request"); + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + if(!pkgIdStr.empty()) + { + LOG_LOGD("Params acc[%d] name[%s] option[%d] period[%d] package[%s]", accountId, pSyncJobName, sync_option, sync_interval, pkgIdStr.c_str()); + bundle* pBundle = umarshal_bundle(pSyncJobUserData); + SyncManager::GetInstance()->AddRunningAccount(accountId, pid); + ret = SyncService::GetInstance()->RequestPeriodicSync(pkgIdStr.c_str(), pSyncJobName, accountId, pBundle, sync_option, sync_interval, &sync_job_id); + bundle_free(pBundle); + } + + if (ret != SYNC_ERROR_NONE) + { + GError* error = g_error_new (_sync_error_quark(), ret, "system error"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + } + else + tizen_sync_manager_complete_add_periodic_sync_job(pObject, pInvocation, sync_job_id); + + LOG_LOGD("sync service: add periodic sync job ends"); + return true; +} + + +gboolean +sync_manager_add_data_change_sync_job(TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation, + gint accountId, + const gchar* pCapabilityArg, + gint sync_option, + GVariant* pSyncJobUserData) +{ + LOG_LOGD("Received data change Sync request"); + int ret = SYNC_ERROR_NONE; + guint pid = get_caller_pid(pInvocation); + + const char *capability = (char *)pCapabilityArg; + if (!strcmp(capability, "http://tizen.org/sync/capability/calendar") || + !strcmp(capability, "http://tizen.org/sync/capability/contact")) { + if (!strcmp(capability, "http://tizen.org/sync/capability/calendar")) + ret = _check_privilege_by_pid(CALENDAR_READ_LABEL, READ_PERM, true, pid); + else + ret = _check_privilege_by_pid(CONTACT_READ_LABEL, READ_PERM, true, pid); + + if (ret != SYNC_ERROR_NONE) { + GError* error = g_error_new (_sync_error_quark(), ret, "permission denied error"); + g_dbus_method_invocation_return_gerror (pInvocation, error); + g_clear_error(&error); + return true; + } + } + string pkgIdStr; + int sync_job_id = 0; + char* pAppId; + ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + free(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + LOG_LOGD("Request seems to be from app-id less/command line based request"); + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + if(!pkgIdStr.empty()) + { + LOG_LOGD("Params account [%d] job_name [%s] sync_option[%d] sync_job_id[%d] package [%s] ", accountId, pCapabilityArg, sync_option, sync_job_id, pkgIdStr.c_str()); + + bundle* pBundle = umarshal_bundle(pSyncJobUserData); + SyncManager::GetInstance()->AddRunningAccount(accountId, pid); + ret = SyncService::GetInstance()->RequestDataSync(pkgIdStr.c_str(), pCapabilityArg, accountId, pBundle, sync_option, pCapabilityArg, &sync_job_id); + + bundle_free(pBundle); + } + + if (ret != SYNC_ERROR_NONE) + { + GError* error = g_error_new (_sync_error_quark(), ret, "system error"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + } + else + tizen_sync_manager_complete_add_data_change_sync_job(pObject, pInvocation, sync_job_id); + + LOG_LOGD("sync service: add data sync job ends"); + return true; +} + + +static bool +is_service_app(pid_t pid) +{ + char *current_app_id = NULL; + int ret = app_manager_get_app_id(pid, ¤t_app_id); + if (ret != APP_MANAGER_ERROR_NONE) + { + LOG_LOGD("Getting current app id is failed : %d, %s", ret, get_error_message(ret)); + return false; + } + + pkgmgrinfo_appinfo_h current_app_info = NULL; + + ret = pkgmgrinfo_appinfo_get_appinfo(current_app_id, ¤t_app_info); + if (ret != PMINFO_R_OK) + { + LOG_LOGD("Current app info handle creation error : %d, %s", ret, get_error_message(ret)); + free(current_app_id); + return false; + } + char *current_app_type = NULL; + ret = pkgmgrinfo_appinfo_get_component_type(current_app_info, ¤t_app_type); + if (ret != PMINFO_R_OK) + { + LOG_LOGD("Current app info getting app type error : %d, %s", ret, get_error_message(ret)); + + pkgmgrinfo_appinfo_destroy_appinfo(current_app_info); + free(current_app_id); + return false; + } + else + { + if (!strcmp(current_app_type, "svcapp")) + { + LOG_LOGD("Current application type : %s", current_app_type); + pkgmgrinfo_appinfo_destroy_appinfo(current_app_info); + } + else + { + LOG_LOGD("Current app is not a service application : %s", current_app_type); + pkgmgrinfo_appinfo_destroy_appinfo(current_app_info); + free(current_app_id); + return false; + } + } + + free(current_app_id); + return true; +} + + +static inline int __read_proc(const char *path, char *buf, int size) +{ + int fd; + int ret; + + if (buf == NULL || path == NULL) + return -1; + + fd = open(path, O_RDONLY); + if (fd < 0) + { + LOG_LOGD("fd = %d", fd); + return -1; + } + + ret = read(fd, buf, size - 1); + if (ret <= 0) { + close(fd); + return -1; + } else + buf[ret] = 0; + + close(fd); + + return ret; +} + + +gboolean +sync_manager_add_sync_adapter(TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation, const gchar* pCommandLine) +{ + LOG_LOGD("Received sync adapter registration request"); + + int ret = SYNC_ERROR_SYSTEM; + string pkgIdStr; + guint pid = get_caller_pid(pInvocation); + if (!is_service_app(pid)) + { + GError* error = g_error_new (_sync_error_quark(), SYNC_ERROR_INVALID_OPERATION, "App not supported"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + return true; + } + + char* pAppId; + ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + LOG_LOGD("Request seems to be from app-id less/command line based request"); + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + + if(!pkgIdStr.empty()) + { + char object_path[50]; + snprintf(object_path, 50, "%s%d", SYNC_ADAPTER_DBUS_PATH, pid); + + GError *error = NULL; + GDBusInterfaceSkeleton* interface = NULL; + TizenSyncAdapter* syncAdapterObj= tizen_sync_adapter_skeleton_new(); + if (syncAdapterObj != NULL) + { + interface = G_DBUS_INTERFACE_SKELETON(syncAdapterObj); + if (g_dbus_interface_skeleton_export(interface, gdbusConnection, object_path, &error)) + { + g_signal_connect(syncAdapterObj, "handle-send-result", G_CALLBACK(sync_adapter_handle_send_result), NULL); + g_signal_connect(syncAdapterObj, "handle-init-complete", G_CALLBACK(sync_adapter_handle_init_complete), NULL); + + SyncAdapterAggregator* pAggregator = SyncManager::GetInstance()->GetSyncAdapterAggregator(); + pAggregator->AddSyncAdapter(pkgIdStr.c_str(), pAppId); + + LOG_LOGD("inserting sync adapter ipc %s", pAppId); + g_hash_table_insert(g_hash_table, strdup(pAppId), syncAdapterObj); + ret = SYNC_ERROR_NONE; + } + else + { + LOG_LOGD("export failed %s", error->message); + } + } + else + { + LOG_LOGD("sync adapter object creation failed"); + } + } + else + { + LOG_LOGD("Failed to get package ID"); + } + + if (ret != SYNC_ERROR_NONE) + { + GError* error = g_error_new (_sync_error_quark(), ret, "system error"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + } + else + tizen_sync_manager_complete_add_sync_adapter(pObject, pInvocation); + + LOG_LOGD("End"); + + return true; +} + + +gboolean +sync_manager_remove_sync_adapter(TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation, const gchar* pCommandLine) +{ + LOG_LOGD("Request to remove sync adapter"); + guint pid = get_caller_pid(pInvocation); + if (!is_service_app(pid)) + { + GError* error = g_error_new (_sync_error_quark(), SYNC_ERROR_INVALID_OPERATION, "App not supported"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + return true; + } + + string pkgIdStr; + char* pAppId; + int ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + LOG_LOGD("Request seems to be from app-id less/command line based request"); + pkgIdStr = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + + if(!pkgIdStr.empty()) + { + SyncAdapterAggregator* pAggregator = SyncManager::GetInstance()->GetSyncAdapterAggregator(); + pAggregator->RemoveSyncAdapter(pkgIdStr.c_str()); + LOG_LOGD("Sync adapter removed for package [%s]", pkgIdStr.c_str()); + } + + TizenSyncAdapter* pSyncAdapter = (TizenSyncAdapter*) g_hash_table_lookup(g_hash_table, pAppId); + if (pSyncAdapter == NULL) + { + LOG_LOGD("Failed to lookup syncadapter gdbus object for [%s]", pAppId); + free(pAppId); + } + else + { + GDBusInterfaceSkeleton* interface = NULL; + interface = G_DBUS_INTERFACE_SKELETON(pSyncAdapter); + g_dbus_interface_skeleton_unexport(interface); + } + + tizen_sync_manager_complete_remove_sync_adapter(pObject, pInvocation); + + LOG_LOGD("End"); + + return true; +} + + +GVariant * +marshal_sync_job(ISyncJob* syncJob) +{ + SyncJob* pSyncJob = dynamic_cast< SyncJob* > (syncJob); + GVariantBuilder builder; + + if(pSyncJob) + { + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&builder, "{sv}", KEY_SYNC_JOB_ID, g_variant_new_int32 (pSyncJob->GetSyncJobId())); + g_variant_builder_add(&builder, "{sv}", KEY_SYNC_JOB_ACC_ID, g_variant_new_int32 (pSyncJob->__accountId)); + + if (pSyncJob->GetSyncType() == SYNC_TYPE_DATA_CHANGE) + g_variant_builder_add(&builder, "{sv}", KEY_SYNC_JOB_CAPABILITY, g_variant_new_string (pSyncJob->__syncJobName.c_str())); + else + g_variant_builder_add(&builder, "{sv}", KEY_SYNC_JOB_NAME, g_variant_new_string (pSyncJob->__syncJobName.c_str())); + + ///LOG_LOGD("job name and id [%s] [%d]", pSyncJob->__syncJobName.c_str(), pSyncJob->GetSyncJobId()); + + g_variant_builder_add(&builder, "{sv}", KEY_SYNC_JOB_USER_DATA, marshal_bundle(pSyncJob->__pExtras)); + } + + return g_variant_builder_end (&builder); +} + + + +gboolean +sync_manager_get_all_sync_jobs(TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation) +{ + LOG_LOGD("Received request to get Sync job ids"); + + int ret = SYNC_ERROR_SYSTEM; + + guint pid = get_caller_pid(pInvocation); + string pkgId; + char* pAppId; + ret = app_manager_get_app_id(pid, &pAppId); + if (ret == APP_MANAGER_ERROR_NONE) + { + pkgId = SyncManager::GetInstance()->GetPkgIdByAppId(pAppId); + free(pAppId); + } + else + { + char commandLine[1024] = {0,}; + ret = aul_app_get_cmdline_bypid(pid, commandLine, sizeof(commandLine) - 1); + LOG_LOGD("Request seems to be from app-id less/command line based request"); + pkgId = SyncManager::GetInstance()->GetPkgIdByCommandline(commandLine); + } + + GVariant* outSyncJobList = NULL; + GVariantBuilder builder; + + if(!pkgId.empty()) + { + SyncJobsAggregator* pSyncJobsAggregator = SyncManager::GetInstance()->GetSyncJobsAggregator(); + SyncJobsInfo* pPackageSyncJobs = pSyncJobsAggregator->GetSyncJobsInfo(pkgId.c_str()); + + if (pPackageSyncJobs != NULL) + { + LOG_LOGD("Package ID [%s]", pkgId.c_str()); + + map<int, ISyncJob*>& allSyncJobs = pPackageSyncJobs->GetAllSyncJobs(); + if(!allSyncJobs.empty()) + { + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + LOG_LOGD("Package has [%d] sync jobs", allSyncJobs.size()); + map< int, ISyncJob* >::iterator itr = allSyncJobs.begin(); + while (itr != allSyncJobs.end()) + { + ISyncJob* syncJob = itr->second; + g_variant_builder_add_value(&builder, marshal_sync_job(syncJob)); + itr++; + } + outSyncJobList = g_variant_builder_end(&builder); + } + } + else + { + LOG_LOGD("No registered sync jobs found"); + } + } + else + { + LOG_LOGD("Sync jobs information not found for package [%s], pkgId.str()"); + } + + if (outSyncJobList == NULL) + { + GError* error = g_error_new (_sync_error_quark(), ret, "system error"); + g_dbus_method_invocation_return_gerror(pInvocation, error); + g_clear_error(&error); + } + else + { + tizen_sync_manager_complete_get_all_sync_jobs(pObject, pInvocation, outSyncJobList); + } + + LOG_LOGD("End"); + + return true; +} + + +gboolean +sync_manager_set_sync_status( TizenSyncManager* pObject, GDBusMethodInvocation* pInvocation, gboolean sync_enable) +{ + SyncManager::GetInstance()->SetSyncSetting(sync_enable); + + tizen_sync_manager_complete_set_sync_status(pObject, pInvocation); + return true; +} + + +/* + * DBus related initialization and setup + */ +static void +OnBusAcquired (GDBusConnection* pConnection, const gchar* pName, gpointer userData) +{ + GDBusInterfaceSkeleton* interface = NULL; + sync_ipc_obj = tizen_sync_manager_skeleton_new(); + if (sync_ipc_obj == NULL) + { + LOG_LOGD("sync_ipc_obj NULL!!"); + return; + } + interface = G_DBUS_INTERFACE_SKELETON(sync_ipc_obj); + if (!g_dbus_interface_skeleton_export(interface, pConnection, SYNC_MANAGER_DBUS_PATH, NULL)) + { + LOG_LOGD("export failed!!"); + return; + } + g_signal_connect(sync_ipc_obj, "handle-add-sync-adapter", G_CALLBACK(sync_manager_add_sync_adapter), NULL); + g_signal_connect(sync_ipc_obj, "handle-remove-sync-adapter", G_CALLBACK(sync_manager_remove_sync_adapter), NULL); + g_signal_connect(sync_ipc_obj, "handle-add-on-demand-sync-job", G_CALLBACK(sync_manager_add_on_demand_sync_job), NULL); + g_signal_connect(sync_ipc_obj, "handle-add-periodic-sync-job", G_CALLBACK(sync_manager_add_periodic_sync_job), NULL); + g_signal_connect(sync_ipc_obj, "handle-add-data-change-sync-job", G_CALLBACK(sync_manager_add_data_change_sync_job), NULL); + g_signal_connect(sync_ipc_obj, "handle-get-all-sync-jobs", G_CALLBACK(sync_manager_get_all_sync_jobs), NULL); + g_signal_connect(sync_ipc_obj, "handle-remove-sync-job", G_CALLBACK(sync_manager_remove_sync_job), NULL); + g_signal_connect(sync_ipc_obj, "handle-set-sync-status", G_CALLBACK(sync_manager_set_sync_status), NULL); + + gdbusConnection = pConnection; + LOG_LOGD("Sync Service started [%s]", pName); + + //g_dbus_object_manager_server_set_connection(pServerManager, connection); +} + + +static void +OnNameAcquired (GDBusConnection* pConnection, const gchar* pName, gpointer userData) +{ +} + + +static void +OnNameLost (GDBusConnection* pConnection, const gchar* pName, gpointer userData) +{ + LOG_LOGD("OnNameLost"); + //exit (1); +} + + +static bool +__initialize_dbus() +{ + static guint ownerId = g_bus_own_name (G_BUS_TYPE_SYSTEM, + "org.tizen.sync", + G_BUS_NAME_OWNER_FLAGS_NONE, + OnBusAcquired, + OnNameAcquired, + OnNameLost, + NULL, + NULL); + + if (ownerId == 0) + { + LOG_LOGD("gdbus own failed!!"); + return false; + } + + return true; +} + + +void +SyncService::InitializeDbus(void) +{ + LOG_LOGD("Dbus initialization starts"); + + if (__initialize_dbus() == false) + { + LOG_LOGD("__initialize_dbus failed"); + exit(1); + } + + g_hash_table = g_hash_table_new(g_str_hash, g_str_equal); +} + + +/* + * DBus related initialization done + */ +SyncService::SyncService(void) +{ + LOG_LOGD("Sync service initialization starts"); + + InitializeDbus(); +} + + +SyncService::~SyncService(void) +{ +} + +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncService.h b/src/sync-service/SyncManager_SyncService.h new file mode 100644 index 0000000..8a4cf6d --- /dev/null +++ b/src/sync-service/SyncManager_SyncService.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_SyncManager.h + * @brief This is the header file for the SyncService class. + */ + + +#ifndef SYNC_SERVICE_SYNC_SERVICE_H +#define SYNC_SERVICE_SYNC_SERVICE_H + +#include <iostream> +#include <bundle.h> +#include "SyncManager_Singleton.h" +#include "sync-adapter-stub.h" +#include "account.h" + + +/*namespace _SyncManager +{ +*/ + +class SyncManager; + +class SyncService + : public Singleton<SyncService> +{ + +public: + + int StartService(void); + + int TriggerStartSync(const char* appId, int accountId, const char* syncJobName, bool isDataSync, bundle* pExtras); + + void TriggerStopSync(const char* appId, int accountId, const char* syncJobName, bool isDataSync, bundle* pExtras); + + int RequestOnDemandSync(const char* pPackageId, const char* pSyncJobName, int accountId, bundle* pExtras, int syncOption, int* pSyncJobId); + + int RequestPeriodicSync(const char* pPackageId, const char* pSyncJobName, int accountId, bundle* pExtras, int syncOption, unsigned long pollFrequency, int* pSyncJobId); + + int RequestDataSync(const char* pPackageId, const char* pSyncJobName, int accountId, bundle* pExtras, int syncOption, const char* pCapability, int* pSyncJobId); + + void HandleShutdown(void); + +protected: + SyncService(void); + + ~SyncService(void); + + friend class Singleton<SyncService>; + +private: + SyncService(const SyncService&); + + const SyncService& operator=(const SyncService&); + + void InitializeDbus(); + +private: + SyncManager* __pSyncMangerIntacnce; +}; +//}//_SyncManager +#endif //SYNC_SERVICE_SYNC_SERVICE_H diff --git a/src/sync-service/SyncManager_SyncStatusInfo.cpp b/src/sync-service/SyncManager_SyncStatusInfo.cpp new file mode 100644 index 0000000..1cc48a5 --- /dev/null +++ b/src/sync-service/SyncManager_SyncStatusInfo.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncStatusInfo.cpp + * @brief This is the implementation file for the SyncStatusInfo class. + */ + + +#include <sstream> +#include "sync-log.h" +#include "SyncManager_SyncStatusInfo.h" + + +/*namespace _SyncManager +{*/ + + +SyncStatusInfo::SyncStatusInfo(int capabilityId) +{ + this->capabilityId = capabilityId; +} + + +SyncStatusInfo::SyncStatusInfo(SyncStatusInfo &other) +{ + this->capabilityId = other.capabilityId; + + vector<long long> ::iterator it; + for (it = other.__periodicSyncTimes.begin(); it != other.__periodicSyncTimes.end(); it++) + { + long long val = (*it); + this->__periodicSyncTimes.push_back(val); + } +} + +SyncStatusInfo& +SyncStatusInfo::operator =(SyncStatusInfo& other) +{ + this->capabilityId = other.capabilityId; + + vector<long long> ::iterator it; + for (it = other.__periodicSyncTimes.begin(); it != other.__periodicSyncTimes.end(); it++) + { + long long val = (*it); + this->__periodicSyncTimes.push_back(val); + } + return *this; +} + +SyncStatusInfo::SyncStatusInfo(string statusInfo) +{ + if (statusInfo.empty()) + { + LOG_LOGD("statusInfo string empty"); + return; + } + stringstream ss(statusInfo); + + int capabilityId = 0; + int periodicSyncSize = 0; + + ss>>capabilityId; + if (ss) + { + ss>>periodicSyncSize; + if (periodicSyncSize <= 0) + { + LOG_LOGD("statusInfo corrupted"); + return; + } + } + + this->capabilityId = capabilityId; + + for (int i = 0; i < periodicSyncSize; i++) + { + int periodicSyncTime; + ss>>periodicSyncTime; + this->__periodicSyncTimes.push_back(periodicSyncTime); + } +} + + +void +SyncStatusInfo::SetPeriodicSyncTime(unsigned int index, long long when) +{ + // The list is initialized lazily when scheduling occurs so we need to make sure + // we initialize elements < index to zero (zero is ignore for scheduling purposes) + EnsurePeriodicSyncTimeSize(index); + __periodicSyncTimes[index] = when; +} + + +long long +SyncStatusInfo::GetPeriodicSyncTime(unsigned int index) +{ + if (index < __periodicSyncTimes.size()) + { + return __periodicSyncTimes[index]; + } + else + { + return 0; + } +} + + +void +SyncStatusInfo::RemovePeriodicSyncTime(unsigned int index) +{ + if (index < __periodicSyncTimes.size()) + { + __periodicSyncTimes.erase(__periodicSyncTimes.begin()+index); + } +} + + +void +SyncStatusInfo::EnsurePeriodicSyncTimeSize(unsigned int index) +{ + unsigned int requiredSize = index + 1; + if (__periodicSyncTimes.size() < requiredSize) + { + for (unsigned int i = __periodicSyncTimes.size(); i < requiredSize; i++) + { + __periodicSyncTimes.push_back((long) 0); + } + } +} + + +string +SyncStatusInfo::GetStatusInfoString(void) +{ + stringstream ss; + string buff; + + if (__periodicSyncTimes.size() > 0) + { + ss<<capabilityId; + buff.append(ss.str().c_str()); + ss.str(string()); + + LOG_LOGD("writing sync time now, size = %d", __periodicSyncTimes.size()); + buff.append(" "); + ss<<__periodicSyncTimes.size(); + buff.append(ss.str().c_str()); + ss.str(string()); + + for (unsigned int i = 0; i < __periodicSyncTimes.size(); i++) + { + LOG_LOGD("writing sync time %lld", __periodicSyncTimes[i]); + buff.append(" "); + ss<<__periodicSyncTimes[i]; + buff.append(ss.str().c_str()); + ss.str(string()); + } + } + + return buff; +} +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncStatusInfo.h b/src/sync-service/SyncManager_SyncStatusInfo.h new file mode 100644 index 0000000..2695184 --- /dev/null +++ b/src/sync-service/SyncManager_SyncStatusInfo.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 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. + */ + + +/** + * @file SyncManager_SyncStatusInfo.h + * @brief This is the header file for the SyncStatusInfo class. + */ + +#ifndef SYNC_SERVICE_STATUS_INFO_H +#define SYNC_SERVICE_STATUS_INFO_H + +#include <stdio.h> +#include <vector> +#include <string> + + +/*namespace _SyncManager +{ +*/ +using namespace std; + +class SyncStatusInfo +{ +public: + SyncStatusInfo(int capabilityId); + + SyncStatusInfo(SyncStatusInfo &other); + + SyncStatusInfo& operator =(SyncStatusInfo& other); + + SyncStatusInfo(string statusInfo); + + void SetPeriodicSyncTime(unsigned int index, long long when); + + long long GetPeriodicSyncTime(unsigned int index); + + void RemovePeriodicSyncTime(unsigned int index); + + string GetStatusInfoString(void); + +public: + int capabilityId; + +private: + void EnsurePeriodicSyncTimeSize(unsigned int index); + + // Warning: It is up to the external caller to ensure there are + // no race conditions when accessing this list +private: + vector<long long> __periodicSyncTimes; + +}; +//}//_SyncManager +#endif diff --git a/src/sync-service/SyncManager_SyncWorker.cpp b/src/sync-service/SyncManager_SyncWorker.cpp new file mode 100644 index 0000000..49b7a4e --- /dev/null +++ b/src/sync-service/SyncManager_SyncWorker.cpp @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncWorker.cpp + * @brief This is the implementation file for the SyncWorker class. + */ + +#include <sys/eventfd.h> +#include "sync-log.h" +#include "sync-error.h" +#include "SyncManager_SyncWorker.h" + + +/*namespace _SyncManager +{*/ + +SyncWorker::SyncWorker(void) +{ +} + + +SyncWorker::~SyncWorker(void) +{ + Finalize(); +} + + +int +SyncWorker::FireEvent(ISyncWorkerResultListener* pSyncWorkerResultListener, Message msg) +{ + return AddRequestN(pSyncWorkerResultListener, msg); +} + + +void +SyncWorker::Initialize(void) +{ + LOG_LOGD("Initializing sync worker thread"); + + GError* pGError = NULL; + int ret; + + ret = pthread_mutex_init(&__pendingRequestsMutex, NULL); + if (ret != 0) + { + LOG_ERRORD("__pendingRequestsMutex Initialise Failed %d", ret); + return; + } + else + { + __pContext = g_main_context_new(); + ASSERT(__pContext); + + __pLoop = g_main_loop_new(__pContext, FALSE); + ASSERT(__pLoop); + + int eventFd = eventfd(0, 0); + __pChannel = g_io_channel_unix_new(eventFd); + ASSERT(__pChannel); + + g_io_channel_set_encoding(__pChannel, NULL, &pGError); + g_io_channel_set_flags(__pChannel, G_IO_FLAG_NONBLOCK, &pGError); + g_io_channel_set_close_on_unref(__pChannel, TRUE); + + __pSource = g_io_create_watch(__pChannel, G_IO_IN); + ASSERT(__pSource); + + g_source_set_callback(__pSource, (GSourceFunc) SyncWorker::OnEventReceived, this, NULL); + g_source_attach(__pSource, __pContext); + + __pThread = g_thread_new("sync-thread", SyncWorker::ThreadLoop, static_cast<gpointer>(__pLoop)); + ASSERT(__pThread); + } + + LOG_LOGD("SyncManager::initialize() Ends"); +} + +void +SyncWorker::Finalize(void) +{ + LOG_LOGD("Finalizing sync worker"); + + for (std::list<RequestData*>::iterator it = __pendingRequests.begin(); it != __pendingRequests.end();) + { + RequestData* pRequestData = *it; + delete pRequestData; + pRequestData = NULL; + it = __pendingRequests.erase(it); + } + pthread_mutex_destroy(&__pendingRequestsMutex); + + if (__pSource) + { + g_source_unref(__pSource); + g_source_destroy(__pSource); + } + if (__pChannel) + { + g_io_channel_unref(__pChannel); + g_io_channel_shutdown(__pChannel, TRUE, NULL); + } + if (__pLoop) + { + g_main_loop_unref(__pLoop); + g_main_loop_quit(__pLoop); + } + if (__pContext) + { + g_main_context_unref(__pContext); + } + if (__pThread) + { + g_thread_exit(NULL); + } +} + + +int +SyncWorker::AddRequestN(ISyncWorkerResultListener* pSyncWorkerResultListener, Message msg) +{ + SYNC_LOGE_RET_RES(__pChannel != NULL, SYNC_ERROR_SYSTEM, "IO channel is not setup"); + + LOG_LOGD("Adding a request to sync worker"); + + RequestData* pRequestData = new (std::nothrow) RequestData(); + if (pRequestData != NULL) + { + pRequestData->message = msg; + pRequestData->pResultListener = pSyncWorkerResultListener; + + uint64_t count = 1; + gsize writtenSize = 0; + // GError* error = NULL; + // GIOStatus status; + + pthread_mutex_lock(&__pendingRequestsMutex); + __pendingRequests.push_back(pRequestData); + LOG_LOGD("Added into __pendingRequests, current size = %d", __pendingRequests.size()); + pthread_mutex_unlock(&__pendingRequestsMutex); + + GError* pError = NULL; + int status = g_io_channel_write_chars(__pChannel, (const gchar*) &count, sizeof(count), &writtenSize, &pError); + if (status != G_IO_STATUS_NORMAL) + { + LOG_LOGD("SyncWorker::Add Request Failed with IO Write Error %d %d", status, count); + return SYNC_ERROR_SYSTEM; + } + g_io_channel_flush (__pChannel, &pError); + + LOG_LOGD("Request Successfully added"); + return SYNC_ERROR_NONE; + } + + return SYNC_ERROR_SYSTEM; +} + + +gboolean +SyncWorker::OnEventReceived(GIOChannel* pChannel, GIOCondition condition, gpointer data) +{ + LOG_LOGD("GIO event received"); + + SyncWorker* pSyncWorker = static_cast<SyncWorker*>(data); + + if ((condition & G_IO_IN) && pSyncWorker != NULL) + { + uint64_t tmp = 0; + gsize readSize = 0; + GError* pError = NULL; + GIOStatus status; + + status = g_io_channel_read_chars (pChannel, (gchar*)&tmp, sizeof(tmp), &readSize, &pError); + + if (readSize == 0 || status != G_IO_STATUS_NORMAL) + { + LOG_LOGD("Failed with IO Read Error"); + return TRUE; + } + + pthread_mutex_lock(&pSyncWorker->__pendingRequestsMutex); + std::list<RequestData*>::iterator it; + it = pSyncWorker->__pendingRequests.begin(); + if (*it != NULL) + { + RequestData* pData = *it; + pSyncWorker->__pendingRequests.pop_front(); + LOG_LOGD("Popping from __pendingRequests, size = %d", pSyncWorker->__pendingRequests.size()); + pthread_mutex_unlock(&pSyncWorker->__pendingRequestsMutex); + + pData->pResultListener->OnEventReceived(pData->message); + + delete pData; + pData = NULL; + } + else + { + pthread_mutex_unlock(&pSyncWorker->__pendingRequestsMutex); + } + + LOG_LOGD("Event handled successfully"); + return TRUE; + } + + LOG_LOGD("UnSuccessfully Ends"); + return FALSE; +} + + +gpointer +SyncWorker::ThreadLoop(gpointer data) +{ + LOG_LOGD("Sync worker thread entered"); + + GMainLoop* pLoop = static_cast<GMainLoop*>(data); + if (pLoop != NULL) + { + LOG_LOGD("Thread loop Running"); + g_main_loop_run(pLoop); + } + + LOG_LOGD("Sync worker thread ends"); + + return NULL; +} +//}//_SyncManager diff --git a/src/sync-service/SyncManager_SyncWorker.h b/src/sync-service/SyncManager_SyncWorker.h new file mode 100644 index 0000000..fa55556 --- /dev/null +++ b/src/sync-service/SyncManager_SyncWorker.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 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. + */ + +/** + * @file SyncManager_SyncWorker.h + * @brief This is the header file for the SyncWorker class. + */ + +#ifndef SYNC_SERVICE_SYNC_WORKER_H +#define SYNC_SERVICE_SYNC_WORKER_H + +#include <glib.h> +#include <pthread.h> +#include <list> +#include <stdlib.h> +#include "SyncManager_SyncWorkerResultListener.h" +#include "SyncManager_SyncDefines.h" + + +/*namespace _SyncManager +{ +*/ + +using namespace std; + +class SyncWorker +{ +public: + SyncWorker(void); + + virtual ~SyncWorker(void); + + int FireEvent(ISyncWorkerResultListener* pSyncWorkerResultListener, Message msg); + +private: + SyncWorker(const SyncWorker& obj); + + SyncWorker& operator=(const SyncWorker& obj); + + void Initialize(void); + + void Finalize(void); + + int AddRequestN(ISyncWorkerResultListener* pSyncWorkerResultListener, Message msg); + + static gboolean OnEventReceived(GIOChannel* pChannel, GIOCondition condition, gpointer data); + + static gpointer ThreadLoop(gpointer data); + +private: + struct RequestData + { + ISyncWorkerResultListener* pResultListener; + Message message; + }; + + pthread_mutex_t __pendingRequestsMutex; + std::list<RequestData*> __pendingRequests; + SyncDispatchMessage __message; + GMainContext* __pContext; + GMainLoop* __pLoop; + GIOChannel* __pChannel; + GSource* __pSource; + GThread* __pThread; + + friend class SyncManager; +}; + +//}//_SyncManager +#endif // SYNC_SERVICE_SYNC_WORKER_H diff --git a/src/sync-service/SyncManager_SyncWorkerResultListener.h b/src/sync-service/SyncManager_SyncWorkerResultListener.h new file mode 100644 index 0000000..84b0436 --- /dev/null +++ b/src/sync-service/SyncManager_SyncWorkerResultListener.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013 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 SYNC_SERVICE_SYNC_WORKER_RESULT_LISTENER_H +#define SYNC_SERVICE_SYNC_WORKER_RESULT_LISTENER_H + +#include "SyncManager_SyncDefines.h" + +/*namespace _SyncManager +{ +*/ + +class ISyncWorkerResultListener +{ +public: + virtual ~ISyncWorkerResultListener() {}; + + virtual void OnEventReceived(Message msg) = 0; +}; + +//}//_SyncManager +#endif // SYNC_SERVICE_SYNC_WORKER_RESULT_LISTENER_H diff --git a/src/sync-service/main.cpp b/src/sync-service/main.cpp new file mode 100644 index 0000000..077112b --- /dev/null +++ b/src/sync-service/main.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013 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 <dbus/dbus.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <bundle.h> +#include <vector> +#include <app.h> +#include <aul.h> +#include "pthread.h" + +#include "SyncManager_ServiceInterface.h" +#include "sync-log.h" + +#define SYS_DBUS_INTERFACE "org.tizen.system.deviced.PowerOff" +#define SYS_DBUS_MATCH_RULE "type='signal',interface='org.tizen.system.deviced.PowerOff'" +#define POWEROFF_MSG "ChangeState" + +static bool ShutdownInitiated = false; +static GMainLoop *mainloop = NULL; + +DBusHandlerResult +DbusSignalHandler(DBusConnection* pConnection, DBusMessage* pMsg, void* pUserData) +{ + if (dbus_message_is_signal(pMsg, SYS_DBUS_INTERFACE, POWEROFF_MSG)) + { + LOG_LOGD("Shutdown dbus received"); + if (ShutdownInitiated == false) + { + ShutdownInitiated = true; + sync_service_finalise(); + g_main_loop_quit(mainloop); + } + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + +static void +signal_handler(int signo) +{ + LOG_LOGD("MainLoop OnTerminate"); + + if (ShutdownInitiated == false) + { + ShutdownInitiated = true; + sync_service_finalise(); + } + g_main_loop_quit(mainloop); +} + + +int +main(int argc, char **argv) +{ + LOG_LOGD("Sync Service"); + + //Dbus handler to catch shutdown signal in kiran + DBusError error; + mainloop = g_main_loop_new(NULL, FALSE); + + dbus_error_init(&error); + DBusConnection* pConn = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + + if (dbus_error_is_set(&error)) + { + LOG_LOGD("Failed to get System BUS connection: %s", error.message); + dbus_error_free(&error); + } + else + { + dbus_connection_setup_with_g_main(pConn, NULL); + //dbus_bus_get_with_g_main () + if (dbus_error_is_set(&error)) + { + LOG_LOGD("Failed to add D-BUS poweroff match rule, cause: %s", error.message); + dbus_error_free(&error); + } + else + { + dbus_bus_add_match(pConn, SYS_DBUS_MATCH_RULE, &error); + if (dbus_error_is_set(&error)) + { + LOG_LOGD("Failed to add Poweroff match rule, cause: %s", error.message); + dbus_error_free(&error); + } + else + { + if (!dbus_connection_add_filter(pConn, DbusSignalHandler, NULL, NULL)) + { + LOG_LOGD("Not enough memory to add poweroff filter"); + dbus_bus_remove_match(pConn, SYS_DBUS_MATCH_RULE, NULL); + } + } + } + } + + static struct sigaction signal_action; + signal_action.sa_handler = signal_handler; + sigemptyset(&signal_action.sa_mask); + + sigaction(SIGTERM, &signal_action, NULL); + sigaction(SIGQUIT, &signal_action, NULL); + + int ret = sync_service_initialise(); + if (ret != 0) + { + LOG_LOGD("Could not initialise sync service"); + return 0; + } + + g_main_loop_run(mainloop); + + g_main_loop_unref(mainloop); + + return 0; +} |