SPEC=https://developer.tizen.org/dev-guide/2.2.1/org.tizen.web.device.apireference/tizen/datasync.html
BUG=XWALK-1061
----------------------------------------------------
Running TCT:
- install rpms on device:
- libwbxml2,
- sync-agent,
- oma-ds-agent (and start: systemctl start oma-ds-agent.service),
- copy 'tct-datasync-tizen-tests.wgt' to device,
- install and run application,
Current TCT datasync passrate: 63/63
--------------------------------------------------
--- /dev/null
+{
+ 'includes':[
+ '../common/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'tizen_datasync',
+ 'type': 'loadable_module',
+ 'variables': {
+ 'packages': [
+ 'sync-agent',
+ ],
+ },
+ 'dependencies': [
+ '../tizen/tizen.gyp:tizen',
+ ],
+ 'includes': [
+ '../common/pkg-config.gypi',
+ ],
+ 'sources': [
+ 'datasync_api.js',
+ 'datasync_error.h',
+ 'datasync_extension.cc',
+ 'datasync_extension.h',
+ 'datasync_instance.cc',
+ 'datasync_instance.h',
+ 'datasync_log.h',
+ 'datasync_manager.cc',
+ 'datasync_manager.h',
+ 'datasync_scoped_exit.h',
+ 'datasync_serialization.h',
+ 'sync_info.cc',
+ 'sync_info.h',
+ 'sync_profile_info.cc',
+ 'sync_profile_info.h',
+ 'sync_service_info.cc',
+ 'sync_service_info.h',
+ 'sync_statistics.cc',
+ 'sync_statistics.h',
+ ],
+ },
+ ],
+}
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// those variables are not exported anyway so no closure
+var callbackId = 0;
+var callbacks = {};
+var hideProtectedProporties = true;
+
+// for the time of serialization 'write-only' and 'read-only' properties
+// should be able to run with correct value
+function executeUnrestricted(func) {
+ try {
+ hideProtectedProporties = false;
+ func();
+ } finally {
+ hideProtectedProporties = true;
+ }
+}
+
+function nextCallbackId() {
+ return callbackId++;
+}
+
+extension.setMessageListener(function(msg) {
+ var m = JSON.parse(msg);
+
+ if (typeof callbacks[m['callback_key']] !== 'object') {
+ return;
+ }
+
+ var callback = callbacks[m['callback_key']];
+ var answer = m['answer'];
+ var callbackName = m['callback_name'];
+
+ if (typeof answer['profileId'] !== 'string') {
+ return;
+ }
+ var profileId = answer['profileId'];
+
+ if (callbackName === 'onprogress') {
+ if (SyncServiceType.indexOf(answer['serviceType']) === -1 ||
+ typeof answer['isFromServer'] !== 'boolean' ||
+ typeof answer['totalPerService'] !== 'number' ||
+ typeof answer['syncedPerService'] !== 'number') {
+ return;
+ }
+
+ var serviceType = answer['serviceType'];
+ var isFromServer = answer['isFromServer'];
+ var totalPerService = answer['totalPerService'];
+ var syncedPerService = answer['syncedPerService'];
+
+ callback['onprogress'](profileId, serviceType,
+ isFromServer, totalPerService, syncedPerService);
+ } else if (callbackName === 'oncompleted') {
+ // callback will not be needed anymore
+ delete callbacks[m['callback_key']];
+
+ callback['oncompleted'](profileId);
+ } else if (callbackName === 'onstopped') {
+ // callback will not be needed anymore
+ delete callbacks[m['callback_key']];
+
+ callback['onstopped'](profileId);
+ } else if (callbackName === 'onfailed') {
+ // callback will not be needed anymore
+ delete callbacks[m['callback_key']];
+
+ if (typeof answer['error'] !== 'object' ||
+ typeof answer['error']['code'] !== 'number' ||
+ typeof answer['error']['name'] !== 'string' ||
+ typeof answer['error']['message'] !== 'string') {
+ return;
+ }
+ var code = answer['error']['code'];
+ var name = answer['error']['name'];
+ var message = answer['error']['message'];
+
+ var error = new tizen.WebAPIError(code, name, message);
+ callback['onfailed'](profileId, error);
+ }
+});
+
+function sendSyncMessage(msg) {
+ var data = null;
+ executeUnrestricted(function() {
+ data = JSON.stringify(msg);
+ });
+
+ var result = JSON.parse(extension.internal.sendSyncMessage(data));
+
+ if (typeof result !== 'object') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+
+ if (result['exception'] !== undefined) {
+ if (typeof result['exception'] !== 'object' ||
+ typeof result['exception']['code'] !== 'number' ||
+ typeof result['exception']['name'] !== 'string' ||
+ typeof result['exception']['message'] !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+
+ var code = result['exception']['code'];
+ var name = result['exception']['name'];
+ var message = result['exception']['message'];
+
+ throw new tizen.WebAPIException(code, name, message);
+ } else if (result['answer'] !== undefined) {
+ return result['answer'];
+ } else {
+ return; //undefined
+ }
+}
+
+function postSyncMessageWithCallback(msg, callback) {
+ if (callback) {
+ var id = nextCallbackId();
+ msg['callback_key'] = id;
+ callbacks[id] = callback;
+ }
+ return sendSyncMessage(msg);
+}
+
+function defineReadWriteProperty(object, key, value) {
+ Object.defineProperty(object, key, {
+ enumerable: true,
+ writable: true,
+ value: value
+ });
+}
+
+function defineReadWriteNonNullProperty(object, key, value) {
+ var hvalue = value;
+ Object.defineProperty(object, key, {
+ enumerable: true,
+ set: function(val) {
+ if (val !== null && val !== undefined) {
+ hvalue = val;
+ }
+ },
+ get: function() {
+ return hvalue;
+ }
+ });
+}
+
+function defineReadWriteWithAcceptListProperty(object, key, value, acceptList, doThrow) {
+ var hvalue = value;
+ Object.defineProperty(object, key, {
+ enumerable: true,
+ set: function(val) {
+ if (acceptList.indexOf(val) !== -1) {
+ hvalue = val;
+ } else {
+ if (doThrow) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ }
+ },
+ get: function() {
+ return hvalue;
+ }
+ });
+}
+
+function defineReadOnlyProperty(object, key, value) {
+ var hvalue = value;
+ Object.defineProperty(object, key, {
+ enumerable: true,
+ set: function(val) {
+ if (!hideProtectedProporties) {
+ hvalue = val;
+ }
+ },
+ get: function() {
+ return hvalue;
+ }
+ });
+}
+
+function defineWriteOnlyProperty(object, key, value, accessedValue) {
+ var hvalue = value;
+ Object.defineProperty(object, key, {
+ enumerable: true,
+ set: function(val) {
+ hvalue = val;
+ },
+ get: function() {
+ if (hideProtectedProporties) {
+ return accessedValue;
+ } else {
+ return hvalue;
+ }
+ }
+ });
+}
+
+// enums
+var SyncModes = ['MANUAL', 'PERIODIC', 'PUSH'];
+var SyncType = ['TWO_WAY', 'SLOW', 'ONE_WAY_FROM_CLIENT', 'REFRESH_FROM_CLIENT',
+ 'ONE_WAY_FROM_SERVER', 'REFRESH_FROM_SERVER'];
+var SyncInterval = ['5_MINUTES', '15_MINUTES', '1_HOUR', '4_HOURS',
+ '12_HOURS', '1_DAY', '1_WEEK', '1_MONTH'];
+var SyncServiceType = ['CONTACT', 'EVENT'];
+var SyncStatus = ['SUCCESS', 'FAIL', 'STOP', 'NONE'];
+
+// SyncInfo interface
+tizen.SyncInfo = function(url, id, password, mode, typeorinterval) {
+ if (!(this instanceof tizen.SyncInfo)) {
+ throw new TypeError;
+ }
+
+ if (typeof url !== 'string' ||
+ typeof id !== 'string' ||
+ typeof password !== 'string' ||
+ typeof mode !== 'string' ||
+ SyncModes.indexOf(mode) === -1) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+
+ defineReadWriteNonNullProperty(this, 'url', url);
+ defineWriteOnlyProperty(this, 'id', id, null);
+ defineWriteOnlyProperty(this, 'password', password, null);
+ defineReadWriteWithAcceptListProperty(this, 'mode', mode, SyncModes, false);
+
+ if (mode === 'MANUAL' && SyncType.indexOf(typeorinterval) !== -1) {
+ defineReadWriteWithAcceptListProperty(
+ this, 'type', typeorinterval, SyncType.concat([null]), false
+ );
+ defineReadWriteWithAcceptListProperty(
+ this, 'interval', null, SyncInterval.concat([null]), false
+ );
+ } else if (mode === 'PERIODIC' && SyncInterval.indexOf(typeorinterval) !== -1) {
+ defineReadWriteWithAcceptListProperty(
+ this, 'type', null, SyncType.concat([null]), false
+ );
+ defineReadWriteWithAcceptListProperty(
+ this, 'interval', typeorinterval, SyncInterval.concat([null]), false
+ );
+ } else {
+ defineReadWriteWithAcceptListProperty(
+ this, 'type', null, SyncType.concat([null]), true
+ );
+ defineReadWriteWithAcceptListProperty(
+ this, 'interval', null, SyncInterval.concat([null]), false
+ );
+ }
+};
+
+// SyncServiceInfo interface
+tizen.SyncServiceInfo = function(enable, serviceType, serverDatabaseUri, id, password) {
+ if (!(this instanceof tizen.SyncServiceInfo)) {
+ throw new TypeError;
+ }
+
+ if (typeof enable !== 'boolean') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ if (SyncServiceType.indexOf(serviceType) === -1) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ if (typeof serverDatabaseUri !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+
+ defineReadWriteNonNullProperty(this, 'enable', enable);
+ defineReadWriteWithAcceptListProperty(this, 'serviceType', serviceType, SyncServiceType, false);
+ defineReadWriteNonNullProperty(this, 'serverDatabaseUri', serverDatabaseUri);
+
+ if (id !== undefined) {
+ if (typeof id !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ } else {
+ defineWriteOnlyProperty(this, 'id', id, null);
+ }
+ } else {
+ defineWriteOnlyProperty(this, 'id', null, null);
+ }
+
+ if (password !== undefined) {
+ if (typeof password !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ } else {
+ defineWriteOnlyProperty(this, 'password', password, null);
+ }
+ } else {
+ defineWriteOnlyProperty(this, 'password', null, null);
+ }
+};
+
+// SyncProfileInfo interface
+tizen.SyncProfileInfo = function(profileName, syncInfo, serviceInfo) {
+ if (!(this instanceof tizen.SyncProfileInfo)) {
+ throw new TypeError;
+ }
+
+ if (typeof profileName !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ if (!(syncInfo instanceof tizen.SyncInfo)) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+
+ defineReadOnlyProperty(this, 'profileId', null);
+ defineReadWriteNonNullProperty(this, 'profileName', profileName);
+ defineReadWriteNonNullProperty(this, 'syncInfo', syncInfo);
+
+ if (serviceInfo !== undefined) {
+ if (serviceInfo instanceof Array) {
+ for (var i = 0; i < serviceInfo.length; i++) {
+ if (!(serviceInfo[i] instanceof tizen.SyncServiceInfo)) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ }
+ defineReadWriteProperty(this, 'serviceInfo', serviceInfo);
+ } else if (serviceInfo === null) {
+ defineReadWriteProperty(this, 'serviceInfo', null);
+ } else {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ } else {
+ defineReadWriteProperty(this, 'serviceInfo', null);
+ }
+};
+
+// SyncStatistics interface.
+function SyncStatistics(json) {
+ for (var field in json) {
+ var val = json[field];
+ if (val !== undefined) {
+ if (field === 'lastSyncTime') {
+ val = new Date(val * 1000);
+ }
+ }
+ defineReadOnlyProperty(this, field, val);
+ }
+}
+
+function validateCallbacks(callbacks) {
+ var callbackNames = ['onprogress', 'oncompleted', 'onstopped', 'onfailed'];
+
+ for (var i = 0; i < callbackNames.length; i++) {
+ if (typeof callbacks[callbackNames[i]] !== 'function') {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+function convertToSyncStatistics(data) {
+ if (!(data instanceof Array)) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+ var result = [];
+ for (var i = 0; i < data.length; i++) {
+ result.push(new SyncStatistics(data[i]));
+ }
+ return result;
+}
+
+function convertToProfileInfo(data) {
+ if (typeof data !== 'object') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+
+ var profileId = data['profileId'];
+ var profileName = data['profileName'];
+ var syncInfo = data['syncInfo'];
+ var serviceInfo = data['serviceInfo'];
+
+ if (typeof profileId !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+ if (typeof profileName !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+ if (syncInfo === undefined) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+
+ var serviceInfoList = [];
+ if (serviceInfo instanceof Array) {
+ for (var i = 0; i < serviceInfo.length; i++) {
+ serviceInfoList.push(convertToServiceInfo(serviceInfo[i]));
+ }
+ } else if (serviceInfo === null) {
+ serviceInfoList = null;
+ } else {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+
+ var profile = new tizen.SyncProfileInfo(profileName,
+ convertToSyncInfo(syncInfo), serviceInfoList);
+
+ executeUnrestricted(function() {
+ profile.profileId = profileId;
+ });
+
+ return profile;
+}
+
+function convertToSyncInfo(data) {
+ try {
+ var mode = data['mode'];
+ var type = data['type'];
+ var interval = data['interval'];
+
+ var typeorinterval = null;
+ if (mode === 'MANUAL') {
+ typeorinterval = type;
+ } else if (mode === 'PERIODIC') {
+ typeorinterval = interval;
+ }
+
+ return new tizen.SyncInfo(data['url'], data['id'], data['password'],
+ mode, typeorinterval);
+ } catch (e) {
+ if (e instanceof tizen.WebAPIException) {
+ throw tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ } else {
+ throw e;
+ }
+ }
+}
+
+function convertToServiceInfo(data) {
+ try {
+ return new tizen.SyncServiceInfo(data['enable'], data['serviceType'],
+ data['serverDatabaseUri'], data['id'], data['password']);
+ } catch (e) {
+ if (e instanceof tizen.WebAPIException) {
+ throw tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ } else {
+ throw e;
+ }
+ }
+}
+
+// DataSynchronizationManager interface
+function DataSynchronizationManager() {
+ if (!(this instanceof DataSynchronizationManager)) {
+ throw new TypeError;
+ }
+}
+
+DataSynchronizationManager.prototype.add = function(profile) {
+ if (!(profile instanceof tizen.SyncProfileInfo)) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ var msg = {
+ cmd: 'add',
+ arg: profile
+ };
+
+ var id = sendSyncMessage(msg);
+ executeUnrestricted(function() {
+ profile.profileId = id;
+ });
+};
+
+DataSynchronizationManager.prototype.update = function(profile) {
+ if (!(profile instanceof tizen.SyncProfileInfo)) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ var msg = {
+ cmd: 'update',
+ arg: profile
+ };
+ return sendSyncMessage(msg);
+};
+
+DataSynchronizationManager.prototype.remove = function(profileId) {
+ if (typeof profileId !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ var msg = {
+ cmd: 'remove',
+ arg: profileId
+ };
+ return sendSyncMessage(msg);
+};
+
+DataSynchronizationManager.prototype.getMaxProfilesNum = function() {
+ var msg = {
+ cmd: 'getMaxProfilesNum'
+ };
+ return sendSyncMessage(msg);
+};
+
+DataSynchronizationManager.prototype.getProfilesNum = function() {
+ var msg = {
+ cmd: 'getProfilesNum'
+ };
+ return sendSyncMessage(msg);
+};
+
+DataSynchronizationManager.prototype.get = function(profileId) {
+ if (typeof profileId !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ var msg = {
+ cmd: 'get',
+ arg: profileId
+ };
+
+ return convertToProfileInfo(sendSyncMessage(msg));
+};
+
+DataSynchronizationManager.prototype.getAll = function() {
+ var msg = {
+ cmd: 'getAll'
+ };
+
+ var result = sendSyncMessage(msg);
+ if (!(result instanceof Array)) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_UNKNOWN_ERR);
+ }
+ var final = [];
+ for (var i = 0; i < result.length; i++) {
+ final.push(convertToProfileInfo(result[i]));
+ }
+ return final;
+};
+
+DataSynchronizationManager.prototype.startSync = function(profileId, progressCallback) {
+ if (typeof profileId !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ if (arguments.length > 1) {
+ // Array is an object, should not accept Array
+ if (progressCallback instanceof Array) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ if (typeof progressCallback !== 'object') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ if (!validateCallbacks(progressCallback)) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ }
+
+ var msg = {
+ cmd: 'startSync',
+ arg: profileId
+ };
+
+ return postSyncMessageWithCallback(msg, progressCallback);
+};
+
+DataSynchronizationManager.prototype.stopSync = function(profileId) {
+ if (typeof profileId !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ var msg = {
+ cmd: 'stopSync',
+ arg: profileId
+ };
+ return sendSyncMessage(msg);
+};
+
+DataSynchronizationManager.prototype.getLastSyncStatistics = function(profileId) {
+ if (typeof profileId !== 'string') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+ var msg = {
+ cmd: 'getLastSyncStatistics',
+ arg: profileId
+ };
+ var result = sendSyncMessage(msg);
+ return convertToSyncStatistics(result);
+};
+
+exports = new DataSynchronizationManager();
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_DATASYNC_ERROR_H_
+#define DATASYNC_DATASYNC_ERROR_H_
+
+#include <cassert>
+#include <functional>
+#include <string>
+
+namespace datasync {
+
+class Error {
+ public:
+ Error() { }
+ Error(const std::string& name, const std::string& message)
+ : name_(name),
+ message_(message) {}
+ const std::string& message() const { return message_; }
+ const std::string& name() const { return name_; }
+
+ private:
+ std::string name_;
+ std::string message_;
+};
+
+/**
+ * Abstraction for returning result or error from function as one piece
+ *
+ * This type allows you to pass two callback to this object which will
+ * be called respectively on Success or Failure.
+ *
+ * Code example:
+ *
+ * ResultOrError<std::string> func(bool ok) {
+ * return ok ? "string" : Error("string", "string");
+ * }
+ *
+ * func(x).Success([]() {
+ * // success of calculations...
+ * }).Failure([]() {
+ * // failure of calculations...
+ * });
+ *
+ */
+template<class Result> class ResultOrError {
+ public:
+ typedef std::function<void(Result)> SuccessFunction;
+ typedef std::function<void(const Error&)> HandlerFunction;
+
+ ResultOrError(const Error& ex) // NOLINT
+ : error_(ex),
+ is_error_(true) {
+ }
+
+ ResultOrError(Result r) // NOLINT
+ : result_(r),
+ is_error_(false) {
+ }
+
+ const ResultOrError& Failure(const HandlerFunction& f) const {
+ if (is_error()) {
+ f(error_);
+ }
+ return *this;
+ }
+
+ const ResultOrError& Success(const SuccessFunction& f) const {
+ if (!is_error()) {
+ f(result_);
+ }
+ return *this;
+ }
+
+ private:
+ bool is_error() const {
+ return is_error_;
+ }
+
+ Error error_;
+ Result result_;
+ bool is_error_;
+};
+
+template<> class ResultOrError<void> {
+ public:
+ typedef std::function<void()> SuccessFunction;
+ typedef std::function<void(const Error&)> HandlerFunction;
+
+ ResultOrError<void>(const Error& ex)
+ : error_(ex),
+ is_error_(true) {
+ }
+
+ ResultOrError<void>() : is_error_(false) { }
+
+ const ResultOrError<void>& Failure(const HandlerFunction& f) const {
+ if (is_error()) {
+ f(error_);
+ }
+ return *this;
+ }
+
+ const ResultOrError& Success(const SuccessFunction& f) const {
+ if (!is_error()) {
+ f();
+ }
+ return *this;
+ }
+
+ private:
+ bool is_error() const {
+ return is_error_;
+ }
+
+ Error error_;
+ bool is_error_;
+};
+
+} // namespace datasync
+
+#endif // DATASYNC_DATASYNC_ERROR_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datasync/datasync_extension.h"
+#include "datasync/datasync_instance.h"
+
+// This will be generated from datasync_api.js.
+extern const char kSource_datasync_api[];
+
+namespace datasync {
+
+DatasyncExtension::DatasyncExtension() {
+ SetExtensionName("tizen.datasync");
+ SetJavaScriptAPI(kSource_datasync_api);
+
+ const char* entry_points[] = {
+ "tizen.SyncInfo", "tizen.SyncProfileInfo", "tizen.SyncServiceInfo", NULL};
+ SetExtraJSEntryPoints(entry_points);
+}
+
+DatasyncExtension::~DatasyncExtension() {}
+
+common::Instance* DatasyncExtension::CreateInstance() {
+ return new DatasyncInstance;
+}
+
+} // namespace datasync
+
+// entry point
+common::Extension* CreateExtension() {
+ return new datasync::DatasyncExtension;
+}
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_DATASYNC_EXTENSION_H_
+#define DATASYNC_DATASYNC_EXTENSION_H_
+
+#include "common/extension.h"
+
+namespace datasync {
+
+class DatasyncExtension : public common::Extension {
+ public:
+ DatasyncExtension();
+ virtual ~DatasyncExtension();
+
+ private:
+ // common::Extension implementation.
+ virtual common::Instance* CreateInstance();
+};
+
+} // namespace datasync
+
+#endif // DATASYNC_DATASYNC_EXTENSION_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datasync/datasync_instance.h"
+
+#include "datasync/datasync_log.h"
+#include "datasync/datasync_serialization.h"
+
+#include "tizen/tizen.h"
+
+namespace datasync {
+
+DatasyncInstance::DatasyncInstance()
+ : manager_(new DataSyncManager(*this)) {
+}
+
+DatasyncInstance::~DatasyncInstance() {}
+
+void DatasyncInstance::HandleMessage(const char* msg) {
+ // this is stub, no async messages
+ LogError("No handling of async message: " << msg);
+}
+
+void DatasyncInstance::HandleSyncMessage(const char* msg) {
+ LogDebug("HandleSyncMessage: " << msg);
+ picojson::value v;
+ std::string err;
+
+ picojson::parse(v, msg, msg + strlen(msg), &err);
+ if (!err.empty()) {
+ LogError("Ignoring message");
+ return;
+ }
+
+ int callback_id = -1;
+ std::string cmd = v.get("cmd").to_str();
+ picojson::value arg = v.get("arg");
+
+ LogDebug("cmd:" << cmd << " arg: " << arg.to_str());
+
+ if (v.contains("callback_key")) {
+ callback_id = static_cast<int>(v.get("callback_key").get<double>());
+ }
+
+ if (cmd == "getMaxProfilesNum") {
+ HandleGetMaxProfilesNum(arg);
+ } else if (cmd == "getProfilesNum") {
+ HandleGetProfilesNum(arg);
+ } else if (cmd == "get") {
+ HandleGet(arg);
+ } else if (cmd == "getAll") {
+ HandleGetAll(arg);
+ } else if (cmd == "getLastSyncStatistics") {
+ HandleGetLastSyncStatistics(arg);
+ } else if (cmd == "add") {
+ HandleAdd(arg);
+ } else if (cmd == "update") {
+ HandleUpdate(arg);
+ } else if (cmd == "remove") {
+ HandleRemove(arg);
+ } else if (cmd == "startSync") {
+ HandleStartSync(arg, callback_id);
+ } else if (cmd == "stopSync") {
+ HandleStopSync(arg);
+ } else {
+ LogError("Unknown command");
+ }
+}
+
+void DatasyncInstance::ReplySyncAnswer(const picojson::value& value) {
+ picojson::object answer;
+ answer["answer"] = value;
+
+ LogDebug("ReplySyncAnswer: " << picojson::value(answer).serialize().c_str());
+
+ SendSyncReply(picojson::value(answer).serialize().c_str());
+}
+
+void DatasyncInstance::ReplySyncUndefinedAnswer() {
+ picojson::object answer;
+ std::string message = picojson::value(answer).serialize();
+ LogDebug("ReplySyncUndefinedAnswer: " << message.c_str());
+
+ SendSyncReply(message.c_str());
+}
+
+void DatasyncInstance::ReplySyncException(unsigned code,
+ const std::string& name,
+ const std::string& message) {
+ picojson::object exception;
+ picojson::object error;
+ error["code"] = picojson::value(static_cast<double>(code));
+ error["name"] = picojson::value(name);
+ error["message"] = picojson::value(message);
+ exception["exception"] = picojson::value(error);
+
+ std::string ret = picojson::value(exception).serialize();
+ LogDebug("ReplySyncException: " << ret.c_str());
+
+ SendSyncReply(ret.c_str());
+}
+
+void DatasyncInstance::MakeExceptionAndReply(const Error& e) {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, e.name(), e.message());
+}
+
+void DatasyncInstance::ReplyAsyncAnswer(int key, const std::string& name,
+ const picojson::value& ret) {
+ picojson::object toSend;
+ toSend["callback_key"] = picojson::value(static_cast<double>(key));
+ toSend["callback_name"] = picojson::value(name);
+ toSend["answer"] = ret;
+
+ LogDebug("ReplyAsync: " << picojson::value(toSend).serialize().c_str());
+
+ PostMessage(picojson::value(toSend).serialize().c_str());
+}
+
+void DatasyncInstance::ReplyAsyncOnCompleted(int key,
+ const std::string& profile_id) {
+ picojson::object ret;
+ ret["profileId"] = picojson::value(profile_id);
+ ReplyAsyncAnswer(key, "oncompleted", picojson::value(ret));
+}
+
+void DatasyncInstance::ReplyAsyncOnStopped(int key,
+ const std::string& profile_id) {
+ picojson::object ret;
+ ret["profileId"] = picojson::value(profile_id);
+ ReplyAsyncAnswer(key, "onstopped", picojson::value(ret));
+}
+
+void DatasyncInstance::ReplyAsyncOnFailed(int key,
+ const std::string& profile_id,
+ int error_code,
+ const std::string& name,
+ const std::string& message) {
+ picojson::object ret;
+ picojson::object error;
+
+ error["code"] = picojson::value(static_cast<double>(error_code));
+ error["name"] = picojson::value(name);
+ error["message"] = picojson::value(message);
+
+ ret["error"] = picojson::value(error);
+ ret["profileId"] = picojson::value(profile_id);
+
+ ReplyAsyncAnswer(key, "onfailed", picojson::value(ret));
+}
+
+void DatasyncInstance::ReplyAsyncOnProgress(int key,
+ const std::string& profile_id,
+ bool is_from_server,
+ int synced_per_db,
+ int total_per_db,
+ SyncServiceInfo::SyncServiceType type) {
+ picojson::object ret;
+ ret["profileId"] = picojson::value(profile_id);
+
+ ret["isFromServer"] = picojson::value(is_from_server);
+ ret["syncedPerService"] = picojson::value(static_cast<double>(synced_per_db));
+ ret["totalPerService"] = picojson::value(static_cast<double>(total_per_db));
+
+ ret["serviceType"] =
+ picojson::value(SyncServiceInfo::SyncServiceTypeToString(type));
+
+ ReplyAsyncAnswer(key, "onprogress", picojson::value(ret));
+}
+
+void DatasyncInstance::HandleGetMaxProfilesNum(const picojson::value&) {
+ manager_->GetMaxProfilesNum().Success([this](unsigned max){
+ ReplySyncAnswer(serialization::ToJson(max));
+ });
+}
+
+void DatasyncInstance::HandleGetProfilesNum(const picojson::value&) {
+ manager_->GetProfilesNum().Success([this](unsigned num) {
+ ReplySyncAnswer(serialization::ToJson(num));
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+}
+
+void DatasyncInstance::HandleGet(const picojson::value& arg) {
+ std::unique_ptr<std::string> profile_id =
+ serialization::FromJson<std::string>(arg);
+ if (profile_id) {
+ manager_->Get(*profile_id).Success([this](SyncProfileInfoPtr profileInfo) {
+ ReplySyncAnswer(serialization::ToJson(*profileInfo));
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+ } else {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, "PlatformException",
+ "Error during SyncProfile Construction");
+ }
+}
+
+void DatasyncInstance::HandleGetAll(const picojson::value&) {
+ manager_->GetAll().Success([this](SyncProfileInfoListPtr profileInfoList) {
+ picojson::array array;
+
+ for (const auto& element : *profileInfoList) {
+ array.push_back(serialization::ToJson(*element));
+ }
+
+ ReplySyncAnswer(serialization::ToJson(array));
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+}
+
+void DatasyncInstance::HandleGetLastSyncStatistics(const picojson::value& arg) {
+ std::unique_ptr<std::string> profile_id =
+ serialization::FromJson<std::string>(arg);
+ if (profile_id) {
+ manager_->GetLastSyncStatistics(*profile_id)
+ .Success([this](SyncStatisticsListPtr statisticsList) {
+ picojson::array array;
+
+ for (const auto& element : *statisticsList) {
+ array.push_back(serialization::ToJson(*element));
+ }
+
+ ReplySyncAnswer(serialization::ToJson(array));
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+ } else {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, "PlatformException",
+ "Error during object construction");
+ }
+}
+
+void DatasyncInstance::HandleAdd(const picojson::value& arg) {
+ std::unique_ptr<SyncProfileInfo> profile =
+ serialization::FromJson<SyncProfileInfo>(arg);
+ if (profile) {
+ manager_->Add(*profile).Success([this](std::string id) {
+ ReplySyncAnswer(serialization::ToJson(id));
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+ } else {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, "PlatformException",
+ "Error during object construction");
+ }
+}
+
+void DatasyncInstance::HandleUpdate(const picojson::value& arg) {
+ std::unique_ptr<SyncProfileInfo> profile =
+ serialization::FromJson<SyncProfileInfo>(arg);
+ if (profile) {
+ manager_->Update(*profile).Success([this]() {
+ ReplySyncUndefinedAnswer();
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+ } else {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, "PlatformException",
+ "Error during object construction");
+ }
+}
+
+void DatasyncInstance::HandleRemove(const picojson::value& arg) {
+ std::unique_ptr<std::string> profile_id =
+ serialization::FromJson<std::string>(arg);
+ if (profile_id) {
+ manager_->Remove(*profile_id).Success([this]() {
+ ReplySyncUndefinedAnswer();
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+ } else {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, "PlatformException",
+ "Error during object construction");
+ }
+}
+
+void DatasyncInstance::HandleStartSync(
+ const picojson::value& arg, int callback_id) {
+ std::unique_ptr<std::string> profile_id =
+ serialization::FromJson<std::string>(arg);
+ if (profile_id) {
+ manager_->StartSync(*profile_id, callback_id).Success([this]() {
+ ReplySyncUndefinedAnswer();
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+ } else {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, "PlatformException",
+ "Error during object construction");
+ }
+}
+
+void DatasyncInstance::HandleStopSync(const picojson::value& arg) {
+ std::unique_ptr<std::string> profile_id =
+ serialization::FromJson<std::string>(arg);
+ if (profile_id) {
+ manager_->StopSync(*profile_id).Success([this]() {
+ ReplySyncUndefinedAnswer();
+ }).Failure([this](const Error& e) {
+ MakeExceptionAndReply(e);
+ });
+ } else {
+ ReplySyncException(WebApiAPIErrors::UNKNOWN_ERR, "PlatformException",
+ "Error during object construction");
+ }
+}
+
+} // namespace datasync
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_DATASYNC_INSTANCE_H_
+#define DATASYNC_DATASYNC_INSTANCE_H_
+
+#include <memory>
+#include <string>
+
+#include "common/extension.h"
+#include "common/picojson.h"
+
+#include "datasync/datasync_manager.h"
+
+namespace datasync {
+
+class DatasyncInstance : public common::Instance {
+ public:
+ DatasyncInstance();
+ virtual ~DatasyncInstance();
+
+ void ReplyAsyncOnCompleted(int key, const std::string& profile_id);
+ void ReplyAsyncOnStopped(int key, const std::string& profile_id);
+ void ReplyAsyncOnFailed(int key,
+ const std::string& profile_id,
+ int error_code,
+ const std::string& name,
+ const std::string& message);
+ void ReplyAsyncOnProgress(int key,
+ const std::string& profile_id,
+ bool is_from_server,
+ int synced_per_db,
+ int total_per_db,
+ SyncServiceInfo::SyncServiceType type);
+
+ private:
+ void HandleMessage(const char* msg);
+ void HandleSyncMessage(const char* msg);
+
+ void ReplySyncAnswer(const picojson::value& value);
+ void ReplySyncUndefinedAnswer();
+ void ReplySyncException(unsigned code, const std::string& name,
+ const std::string& message);
+ void MakeExceptionAndReply(const Error& e);
+
+ void ReplyAsyncAnswer(int key, const std::string& name,
+ const picojson::value& returnValue);
+
+ // Synchronous message handlers
+
+ // with result
+ void HandleGetMaxProfilesNum(const picojson::value& arg);
+ void HandleGetProfilesNum(const picojson::value& arg);
+ void HandleGet(const picojson::value& arg);
+ void HandleGetAll(const picojson::value& arg);
+ void HandleGetLastSyncStatistics(const picojson::value& arg);
+
+ // undefined result
+ void HandleAdd(const picojson::value& arg);
+ void HandleUpdate(const picojson::value& arg);
+ void HandleRemove(const picojson::value& arg);
+ void HandleStartSync(const picojson::value& arg, int callback_id);
+ void HandleStopSync(const picojson::value& arg);
+
+ std::unique_ptr<DataSyncManager> manager_;
+};
+
+} // namespace datasync
+
+#endif // DATASYNC_DATASYNC_INSTANCE_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_DATASYNC_LOG_H_
+#define DATASYNC_DATASYNC_LOG_H_
+
+#include <iostream>
+
+// TODO(t.iwanek): this header is to be removed
+// when some common logging mechanism will be introduced
+
+#define LogInfo(MESSAGE) \
+ { std::cerr << MESSAGE << std::endl; }
+#define LogDebug(MESSAGE) \
+ { std::cerr << MESSAGE << std::endl; }
+#define LogWarning(MESSAGE) \
+ { std::cerr << MESSAGE << std::endl; }
+#define LogError(MESSAGE) \
+ { std::cerr << MESSAGE << std::endl; }
+
+#endif // DATASYNC_DATASYNC_LOG_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datasync/datasync_manager.h"
+
+#include "datasync/datasync_instance.h"
+#include "datasync/datasync_log.h"
+#include "datasync/datasync_scoped_exit.h"
+#include "datasync/sync_info.h"
+#include "datasync/sync_service_info.h"
+#include "datasync/sync_profile_info.h"
+
+#include "tizen/tizen.h"
+
+namespace {
+
+const int MAX_PROFILES_NUM = 5;
+
+sync_agent_ds_sync_mode_e ConvertToPlatformSyncMode(
+ datasync::SyncInfo::SyncMode sync_mode) {
+ switch (sync_mode) {
+ case datasync::SyncInfo::MANUAL_MODE: {
+ return SYNC_AGENT_SYNC_MODE_MANUAL;
+ }
+ case datasync::SyncInfo::PERIODIC_MODE: {
+ return SYNC_AGENT_SYNC_MODE_PERIODIC;
+ }
+ case datasync::SyncInfo::PUSH_MODE: {
+ return SYNC_AGENT_SYNC_MODE_PUSH;
+ }
+ default: {
+ LogWarning("Error while converting a sync mode.");
+ return SYNC_AGENT_SYNC_MODE_MANUAL;
+ }
+ }
+}
+
+datasync::SyncInfo::SyncMode ConvertToSyncMode(
+ sync_agent_ds_sync_mode_e sync_mode) {
+ switch (sync_mode) {
+ case SYNC_AGENT_SYNC_MODE_MANUAL: {
+ return datasync::SyncInfo::MANUAL_MODE;
+ }
+ case SYNC_AGENT_SYNC_MODE_PERIODIC: {
+ return datasync::SyncInfo::PERIODIC_MODE;
+ }
+ case SYNC_AGENT_SYNC_MODE_PUSH: {
+ return datasync::SyncInfo::PUSH_MODE;
+ }
+ default: {
+ LogWarning("Error while converting a sync mode.");
+ return datasync::SyncInfo::UNDEFINED_MODE;
+ }
+ }
+}
+
+sync_agent_ds_sync_type_e ConvertToPlatformSyncType(
+ datasync::SyncInfo::SyncType syncType) {
+ switch (syncType) {
+ case datasync::SyncInfo::TWO_WAY_TYPE: {
+ return SYNC_AGENT_SYNC_TYPE_UPDATE_BOTH;
+ }
+ case datasync::SyncInfo::SLOW_TYPE: {
+ return SYNC_AGENT_SYNC_TYPE_FULL_SYNC;
+ }
+ case datasync::SyncInfo::ONE_WAY_FROM_CLIENT_TYPE: {
+ return SYNC_AGENT_SYNC_TYPE_UPDATE_TO_SERVER;
+ }
+ case datasync::SyncInfo::REFRESH_FROM_CLIENT_TYPE: {
+ return SYNC_AGENT_SYNC_TYPE_REFRESH_FROM_PHONE;
+ }
+ case datasync::SyncInfo::ONE_WAY_FROM_SERVER_TYPE: {
+ return SYNC_AGENT_SYNC_TYPE_UPDATE_TO_PHONE;
+ }
+ case datasync::SyncInfo::REFRESH_FROM_SERVER_TYPE: {
+ return SYNC_AGENT_SYNC_TYPE_REFRESH_FROM_SERVER;
+ }
+ default: {
+ LogWarning("Error while converting a sync type.");
+ return SYNC_AGENT_SYNC_TYPE_UPDATE_BOTH;
+ }
+ }
+}
+
+sync_agent_ds_src_uri_e ConvertToPlatformSourceUri(
+ datasync::SyncServiceInfo::SyncServiceType serviceType) {
+ switch (serviceType) {
+ case datasync::SyncServiceInfo::CONTACT_SERVICE_TYPE: {
+ return SYNC_AGENT_SRC_URI_CONTACT;
+ }
+ case datasync::SyncServiceInfo::EVENT_SERVICE_TYPE: {
+ return SYNC_AGENT_SRC_URI_CALENDAR;
+ }
+ default: {
+ LogWarning("Error while converting a sync service.");
+ return SYNC_AGENT_SRC_URI_CONTACT;
+ }
+ }
+}
+
+datasync::SyncStatistics::SyncStatus ConvertToSyncStatus(char* status) {
+ if (0 == strncmp(status, "success", 7)) {
+ return datasync::SyncStatistics::SUCCESS_STATUS;
+ } else if (0 == strncmp(status, "stop", 4)) {
+ return datasync::SyncStatistics::STOP_STATUS;
+ } else if (0 == strncmp(status, "fail", 4)) {
+ return datasync::SyncStatistics::FAIL_STATUS;
+ } else if (0 == strncmp(status, "No", 2)) {
+ return datasync::SyncStatistics::NONE_STATUS;
+ } else {
+ LogWarning("Error while converting a sync status.");
+ }
+
+ return datasync::SyncStatistics::NONE_STATUS;
+}
+
+datasync::SyncInfo::SyncType ConvertToSyncType(
+ sync_agent_ds_sync_type_e sync_type) {
+ switch (sync_type) {
+ case SYNC_AGENT_SYNC_TYPE_UPDATE_BOTH: {
+ return datasync::SyncInfo::TWO_WAY_TYPE;
+ }
+ case SYNC_AGENT_SYNC_TYPE_FULL_SYNC: {
+ return datasync::SyncInfo::SLOW_TYPE;
+ }
+ case SYNC_AGENT_SYNC_TYPE_UPDATE_TO_SERVER: {
+ return datasync::SyncInfo::ONE_WAY_FROM_CLIENT_TYPE;
+ }
+ case SYNC_AGENT_SYNC_TYPE_REFRESH_FROM_PHONE: {
+ return datasync::SyncInfo::REFRESH_FROM_CLIENT_TYPE;
+ }
+ case SYNC_AGENT_SYNC_TYPE_UPDATE_TO_PHONE: {
+ return datasync::SyncInfo::ONE_WAY_FROM_SERVER_TYPE;
+ }
+ case SYNC_AGENT_SYNC_TYPE_REFRESH_FROM_SERVER: {
+ return datasync::SyncInfo::REFRESH_FROM_SERVER_TYPE;
+ }
+ default: {
+ LogWarning("Error while converting a sync type.");
+ return datasync::SyncInfo::UNDEFINED_TYPE;
+ }
+ }
+}
+
+sync_agent_ds_sync_interval_e ConvertToPlatformSyncInterval(
+ datasync::SyncInfo::SyncInterval sync_interval) {
+ switch (sync_interval) {
+ case datasync::SyncInfo::INTERVAL_5_MINUTES: {
+ return SYNC_AGENT_SYNC_INTERVAL_5_MINUTES;
+ }
+ case datasync::SyncInfo::INTERVAL_15_MINUTES: {
+ return SYNC_AGENT_SYNC_INTERVAL_15_MINUTES;
+ }
+ case datasync::SyncInfo::INTERVAL_1_HOUR: {
+ return SYNC_AGENT_SYNC_INTERVAL_1_HOUR;
+ }
+ case datasync::SyncInfo::INTERVAL_4_HOURS: {
+ return SYNC_AGENT_SYNC_INTERVAL_4_HOURS;
+ }
+ case datasync::SyncInfo::INTERVAL_12_HOURS: {
+ return SYNC_AGENT_SYNC_INTERVAL_12_HOURS;
+ }
+ case datasync::SyncInfo::INTERVAL_1_DAY: {
+ return SYNC_AGENT_SYNC_INTERVAL_1_DAY;
+ }
+ case datasync::SyncInfo::INTERVAL_1_WEEK: {
+ return SYNC_AGENT_SYNC_INTERVAL_1_WEEK;
+ }
+ case datasync::SyncInfo::INTERVAL_1_MONTH: {
+ return SYNC_AGENT_SYNC_INTERVAL_1_MONTH;
+ }
+ case datasync::SyncInfo::INTERVAL_UNDEFINED: {
+ return SYNC_AGENT_SYNC_INTERVAL_NONE;
+ }
+ default: {
+ LogWarning("Error while converting a JS sync interval.");
+ return SYNC_AGENT_SYNC_INTERVAL_1_WEEK;
+ }
+ }
+}
+
+datasync::SyncInfo::SyncInterval ConvertToSyncInterval(
+ sync_agent_ds_sync_interval_e sync_interval) {
+ switch (sync_interval) {
+ case SYNC_AGENT_SYNC_INTERVAL_5_MINUTES: {
+ return datasync::SyncInfo::INTERVAL_5_MINUTES;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_15_MINUTES: {
+ return datasync::SyncInfo::INTERVAL_15_MINUTES;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_1_HOUR: {
+ return datasync::SyncInfo::INTERVAL_1_HOUR;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_4_HOURS: {
+ return datasync::SyncInfo::INTERVAL_4_HOURS;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_12_HOURS: {
+ return datasync::SyncInfo::INTERVAL_12_HOURS;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_1_DAY: {
+ return datasync::SyncInfo::INTERVAL_1_DAY;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_1_WEEK: {
+ return datasync::SyncInfo::INTERVAL_1_WEEK;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_1_MONTH: {
+ return datasync::SyncInfo::INTERVAL_1_MONTH;
+ }
+ case SYNC_AGENT_SYNC_INTERVAL_NONE: {
+ return datasync::SyncInfo::INTERVAL_UNDEFINED;
+ }
+ default: {
+ LogWarning("Error while converting a platform sync interval.");
+ return datasync::SyncInfo::INTERVAL_UNDEFINED;
+ }
+ }
+}
+
+sync_agent_ds_service_type_e ConvertToPlatformSyncServiceType(
+ datasync::SyncServiceInfo::SyncServiceType service_type) {
+ switch (service_type) {
+ case datasync::SyncServiceInfo::CONTACT_SERVICE_TYPE: {
+ return SYNC_AGENT_CONTACT;
+ }
+ case datasync::SyncServiceInfo::EVENT_SERVICE_TYPE: {
+ return SYNC_AGENT_CALENDAR;
+ }
+ default: {
+ LogWarning("Error while converting a sync service type.");
+ return SYNC_AGENT_CONTACT;
+ }
+ }
+}
+
+datasync::SyncServiceInfo::SyncServiceType ConvertToSyncServiceType(
+ sync_agent_ds_service_type_e service_type) {
+ switch (service_type) {
+ case SYNC_AGENT_CONTACT: {
+ return datasync::SyncServiceInfo::CONTACT_SERVICE_TYPE;
+ }
+ case SYNC_AGENT_CALENDAR: {
+ return datasync::SyncServiceInfo::EVENT_SERVICE_TYPE;
+ }
+ default: {
+ LogWarning("Error while converting a sync service type.");
+ return datasync::SyncServiceInfo::UNDEFINED_SERVICE_TYPE;
+ }
+ }
+}
+
+} // namespace
+
+namespace datasync {
+
+bool DataSyncManager::sync_agent_initialized_ = false;
+
+DataSyncManager::DataSyncManager(DatasyncInstance& parent)
+ : instance_(parent) {
+ // initialize sync agent once per process
+ if (sync_agent_initialized_) {
+ return;
+ }
+
+ LogInfo("Initialize the datasync manager");
+ sync_agent_ds_error_e ds_err = sync_agent_ds_init();
+ if (SYNC_AGENT_DS_SUCCESS != ds_err) {
+ LogError("Failed to init oma ds.");
+ } else {
+ sync_agent_initialized_ = true;
+ }
+}
+
+DataSyncManager::~DataSyncManager() {
+// TODO(t.iwanek): sync-agent crashes internally..
+// sync-agent should fix it's deinitialization
+}
+
+ResultOrError<std::string> DataSyncManager::Add(SyncProfileInfo& profile_info) {
+ ds_profile_h profile_h = nullptr;
+ char* profile_name = nullptr;
+
+ // Check if the quota is full first.
+ GList* profile_list = nullptr;
+ GList* iter = nullptr;
+
+ ScopedExit exit([&profile_name, &profile_h](){
+ if (profile_name) {
+ free(profile_name);
+ }
+
+ if (profile_h) {
+ sync_agent_ds_free_profile_info(profile_h);
+ }
+ });
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ ret = sync_agent_ds_get_all_profile(&profile_list);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while getting all profiles");
+ }
+
+ int num_profiles = g_list_length(profile_list);
+ for (iter = profile_list; iter != nullptr; iter = g_list_next(iter)) {
+ sync_agent_ds_free_profile_info((ds_profile_h)iter->data);
+ }
+ if (profile_list) {
+ g_list_free(profile_list);
+ }
+ LogDebug("numProfiles: " << num_profiles);
+ if (MAX_PROFILES_NUM == num_profiles) {
+ return Error("OutOfRangeException",
+ "There are already maximum number of profiles!");
+ }
+
+ ret = sync_agent_ds_create_profile_info(&profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while creating a profile");
+ }
+
+ ret = sync_agent_ds_set_profile_name(
+ profile_h, const_cast<char*>(profile_info.profile_name().c_str()));
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a profile name");
+ }
+
+ ret = sync_agent_ds_set_server_info(
+ profile_h, const_cast<char*>(profile_info.sync_info()->url().c_str()),
+ const_cast<char*>(profile_info.sync_info()->id().c_str()),
+ const_cast<char*>(profile_info.sync_info()->password().c_str()));
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a server info");
+ }
+
+ sync_agent_ds_sync_mode_e sync_mode =
+ ConvertToPlatformSyncMode(profile_info.sync_info()->sync_mode());
+ sync_agent_ds_sync_type_e sync_type =
+ ConvertToPlatformSyncType(profile_info.sync_info()->sync_type());
+ sync_agent_ds_sync_interval_e sync_interval =
+ ConvertToPlatformSyncInterval(profile_info.sync_info()->sync_interval());
+ LogDebug("syncMode: " << sync_mode << ", syncType: " << sync_type
+ << ", syncInterval: " << sync_interval);
+
+ ret = sync_agent_ds_set_sync_info(profile_h, sync_mode, sync_type,
+ sync_interval);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a sync info");
+ }
+
+ // Set the sync categories.
+ SyncServiceInfoListPtr categories = profile_info.service_info();
+ for (unsigned int i = 0; categories->size() < i; ++i) {
+ sync_agent_ds_service_type_e service_type =
+ ConvertToPlatformSyncServiceType(
+ categories->at(i)->sync_service_type());
+ std::string tgt_uri = categories->at(i)->server_database_uri();
+ sync_agent_ds_src_uri_e src_uri =
+ ConvertToPlatformSourceUri(categories->at(i)->sync_service_type());
+ std::string id = categories->at(i)->id();
+ std::string password = categories->at(i)->password();
+ bool enable = categories->at(i)->enable();
+
+ LogInfo("serviceType: " << service_type << ", tgtURI: " << tgt_uri
+ << ", enable: " << enable << " for index: " << i);
+
+ ret = sync_agent_ds_set_sync_service_info(
+ profile_h, service_type, enable, src_uri,
+ const_cast<char*>(tgt_uri.c_str()),
+ 0 == id.size() ? nullptr : const_cast<char*>(id.c_str()),
+ 0 == password.size() ? nullptr : const_cast<char*>(password.c_str()));
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a sync service info");
+ }
+ }
+
+ int profile_id;
+ ret = sync_agent_ds_add_profile(profile_h, &profile_id);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while adding a profile");
+ }
+
+ LogDebug("profileId from platform: " << profile_id);
+
+ ret = sync_agent_ds_get_profile_name(profile_h, &profile_name);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while getting a profile name");
+ }
+
+ LogDebug("profileName: " << profile_name << ", profileId: " << profile_id);
+
+ profile_info.set_profile_id(std::to_string(profile_id));
+
+ return profile_info.profile_id();
+}
+
+ResultOrError<void> DataSyncManager::Update(SyncProfileInfo& profile_info) {
+ ds_profile_h profile_h = nullptr;
+
+ ScopedExit exit([&profile_h]() {
+ if (profile_h) {
+ sync_agent_ds_free_profile_info(profile_h);
+ }
+ });
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ int profile_id = std::stoi(profile_info.profile_id());
+ LogDebug("profileId: " << profile_id);
+
+ ret = sync_agent_ds_get_profile(profile_id, &profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("NotFoundException",
+ "Platform error while getting a profile");
+ }
+
+ ret = sync_agent_ds_set_profile_name(
+ profile_h, const_cast<char*>(profile_info.profile_name().c_str()));
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a profile name");
+ }
+
+ ret = sync_agent_ds_set_server_info(
+ profile_h, const_cast<char*>(profile_info.sync_info()->url().c_str()),
+ const_cast<char*>(profile_info.sync_info()->id().c_str()),
+ const_cast<char*>(profile_info.sync_info()->password().c_str()));
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a server info");
+ }
+
+ sync_agent_ds_sync_mode_e sync_mode =
+ ConvertToPlatformSyncMode(profile_info.sync_info()->sync_mode());
+ sync_agent_ds_sync_type_e sync_type =
+ ConvertToPlatformSyncType(profile_info.sync_info()->sync_type());
+ sync_agent_ds_sync_interval_e sync_interval =
+ ConvertToPlatformSyncInterval(profile_info.sync_info()->sync_interval());
+ LogDebug("syncMode: " << sync_mode << ", syncType: " << sync_type
+ << ", syncInterval: " << sync_interval);
+
+ ret = sync_agent_ds_set_sync_info(profile_h, sync_mode, sync_type,
+ sync_interval);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a sync info");
+ }
+
+ // Set the sync categories.
+ SyncServiceInfoListPtr categories = profile_info.service_info();
+ for (unsigned int i = 0; categories->size() < i; ++i) {
+ sync_agent_ds_service_type_e service_type =
+ ConvertToPlatformSyncServiceType(
+ categories->at(i)->sync_service_type());
+ std::string tgt_uri = categories->at(i)->server_database_uri();
+ sync_agent_ds_src_uri_e src_uri =
+ ConvertToPlatformSourceUri(categories->at(i)->sync_service_type());
+ std::string id = categories->at(i)->id();
+ std::string password = categories->at(i)->password();
+ bool enable = categories->at(i)->enable();
+
+ LogDebug("serviceType: " << service_type << ", tgtURI: " << tgt_uri
+ << " for index: " << i);
+
+ ret = sync_agent_ds_set_sync_service_info(
+ profile_h, service_type, enable, src_uri,
+ const_cast<char*>(tgt_uri.c_str()),
+ 0 == id.size() ? nullptr : const_cast<char*>(id.c_str()),
+ 0 == password.size() ? nullptr : const_cast<char*>(password.c_str()));
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while settting a sync service info");
+ }
+ }
+
+ ret = sync_agent_ds_update_profile(profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret && SYNC_AGENT_DS_SYNCHRONISING != ret) {
+ return Error("Exception",
+ "Platform error while updating a profile");
+ }
+ return {};
+}
+
+ResultOrError<void> DataSyncManager::Remove(const std::string& id) {
+ ds_profile_h profile_h = nullptr;
+
+ ScopedExit exit([&profile_h]() {
+ if (profile_h) {
+ sync_agent_ds_free_profile_info(profile_h);
+ }
+ });
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ int profile_id = std::stoi(id);
+ LogDebug("profileId: " << profile_id);
+
+ ret = sync_agent_ds_get_profile(profile_id, &profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while getting a profile");
+ }
+
+ ret = sync_agent_ds_delete_profile(profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret && SYNC_AGENT_DS_SYNCHRONISING != ret) {
+ return Error("Exception",
+ "Platform error while deleting a profile");
+ }
+
+ return {};
+}
+
+ResultOrError<unsigned> DataSyncManager::GetMaxProfilesNum() const {
+ return MAX_PROFILES_NUM;
+}
+
+ResultOrError<unsigned> DataSyncManager::GetProfilesNum() const {
+ GList* profile_list = nullptr;
+ GList* iter = nullptr;
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ ret = sync_agent_ds_get_all_profile(&profile_list);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while getting all profiles");
+ }
+
+ int num_profiles = 0;
+ for (iter = profile_list; iter != nullptr; iter = g_list_next(iter)) {
+ sync_agent_ds_free_profile_info((ds_profile_h)iter->data);
+ num_profiles++;
+ LogDebug("Free sync_agent_ds_profile_info for index: " << num_profiles);
+ }
+
+ LogDebug("numProfiles: " << num_profiles);
+
+ return num_profiles;
+}
+
+ResultOrError<SyncProfileInfoPtr> DataSyncManager::Get(
+ const std::string& profile_id) const {
+ ds_profile_h profile_h = nullptr;
+ GList* category_list = nullptr;
+
+ ScopedExit exit([&category_list, &profile_h]() {
+ if (category_list) {
+ g_list_free(category_list);
+ }
+
+ if (profile_h) {
+ sync_agent_ds_free_profile_info(profile_h);
+ }
+ });
+
+ SyncProfileInfoPtr profile(new SyncProfileInfo());
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ int profile_id_str = std::stoi(profile_id);
+ LogDebug("profileId: " << profile_id_str);
+
+ ret = sync_agent_ds_get_profile(profile_id_str, &profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("NotFoundException",
+ "Platform error while getting a profile");
+ }
+
+ profile->set_profile_id(profile_id);
+
+ char* profile_name = nullptr;
+ ret = sync_agent_ds_get_profile_name(profile_h, &profile_name);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting a profile name");
+ }
+ profile->set_profile_name(profile_name);
+
+ sync_agent_ds_server_info server_info = {nullptr};
+ ret = sync_agent_ds_get_server_info(profile_h, &server_info);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting a server info");
+ }
+ profile->sync_info()->set_url(server_info.addr);
+ profile->sync_info()->set_id(server_info.id);
+ profile->sync_info()->set_password(server_info.password);
+
+ sync_agent_ds_sync_info sync_info;
+ ret = sync_agent_ds_get_sync_info(profile_h, &sync_info);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting a sync info");
+ }
+ profile->sync_info()->set_sync_mode(ConvertToSyncMode(sync_info.sync_mode));
+ profile->sync_info()->set_sync_type(ConvertToSyncType(sync_info.sync_type));
+ profile->sync_info()->set_sync_interval(
+ ConvertToSyncInterval(sync_info.interval));
+
+ LogDebug("Sync mode: " << sync_info.sync_mode
+ << ", type: " << sync_info.sync_type
+ << ", interval: " << sync_info.interval);
+
+ sync_agent_ds_service_info* category_info = nullptr;
+ ret = sync_agent_ds_get_sync_service_info(profile_h, &category_list);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting sync categories");
+ }
+ int category_count = g_list_length(category_list);
+ LogDebug("category_count: " << category_count);
+ while (category_count--) {
+ category_info = static_cast<sync_agent_ds_service_info*>(
+ g_list_nth_data(category_list, category_count));
+ if (SYNC_AGENT_CALENDAR < category_info->service_type) {
+ LogDebug("Skip unsupported sync service type: "
+ << category_info->service_type);
+ continue;
+ }
+
+ SyncServiceInfoPtr service_info(new SyncServiceInfo());
+ service_info->set_enable(category_info->enabled);
+ if (category_info->id) {
+ service_info->set_id(category_info->id);
+ }
+ if (category_info->password) {
+ service_info->set_password(category_info->password);
+ }
+ service_info->set_sync_service_type(
+ ConvertToSyncServiceType(category_info->service_type));
+ if (category_info->tgt_uri) {
+ service_info->set_server_database_uri(category_info->tgt_uri);
+ }
+
+ LogDebug("Service type: " << service_info->sync_service_type());
+ profile->service_info()->push_back(service_info);
+ }
+
+ return profile;
+}
+
+ResultOrError<SyncProfileInfoListPtr> DataSyncManager::GetAll() const {
+ GList* profile_list = nullptr;
+ GList* iter = nullptr;
+
+ ds_profile_h profile_h = nullptr;
+
+ ScopedExit exit([&profile_list, &profile_h, &iter]() {
+ LogDebug("Free profiles list.");
+ for (iter = profile_list; iter != nullptr; iter = g_list_next(iter)) {
+ sync_agent_ds_free_profile_info((ds_profile_h)iter->data);
+ }
+
+ if (profile_list) {
+ g_list_free(profile_list);
+ }
+ });
+
+ SyncProfileInfoListPtr profiles = std::make_shared<SyncProfileInfoList>();
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ ret = sync_agent_ds_get_all_profile(&profile_list);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while getting all profiles");
+ }
+
+ int profile_id;
+ LogDebug("Number of profiles: " << g_list_length(profile_list));
+ for (iter = profile_list; iter != nullptr; iter = g_list_next(iter)) {
+ profile_h = (ds_profile_h)iter->data;
+ SyncProfileInfoPtr profile(new SyncProfileInfo());
+
+ ret = sync_agent_ds_get_profile_id(profile_h, &profile_id);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting a profile id");
+ }
+
+ profile->set_profile_id(std::to_string(profile_id));
+
+ LogDebug("Processing a profile with id: " << profile->profile_id());
+
+ char* profile_name = nullptr;
+ ret = sync_agent_ds_get_profile_name(profile_h, &profile_name);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting a profile name");
+ }
+ profile->set_profile_name(profile_name);
+
+ sync_agent_ds_server_info server_info = {nullptr};
+ ret = sync_agent_ds_get_server_info(profile_h, &server_info);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting a server info");
+ }
+ profile->sync_info()->set_url(server_info.addr);
+ profile->sync_info()->set_id(server_info.id);
+ profile->sync_info()->set_password(server_info.password);
+
+ sync_agent_ds_sync_info sync_info;
+ ret = sync_agent_ds_get_sync_info(profile_h, &sync_info);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting a sync info");
+ }
+ profile->sync_info()->set_sync_mode(
+ ConvertToSyncMode(sync_info.sync_mode));
+ profile->sync_info()->set_sync_type(
+ ConvertToSyncType(sync_info.sync_type));
+ profile->sync_info()->set_sync_interval(
+ ConvertToSyncInterval(sync_info.interval));
+
+ LogDebug("Sync mode: " << sync_info.sync_mode
+ << ", type: " << sync_info.sync_type
+ << ", interval: " << sync_info.interval);
+
+ GList* category_list = nullptr;
+ sync_agent_ds_service_info* category_info = nullptr;
+ ret = sync_agent_ds_get_sync_service_info(profile_h, &category_list);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error(
+ "Exception",
+ "Platform error while gettting sync categories");
+ }
+ int category_count = g_list_length(category_list);
+ LogDebug("category_count: " << category_count);
+ while (category_count--) {
+ category_info = static_cast<sync_agent_ds_service_info*>(
+ g_list_nth_data(category_list, category_count));
+ if (SYNC_AGENT_CALENDAR < category_info->service_type) {
+ LogDebug("Skip unsupported sync service type: "
+ << category_info->service_type);
+ continue;
+ }
+
+ SyncServiceInfoPtr service_info(new SyncServiceInfo());
+ service_info->set_enable(category_info->enabled);
+ if (category_info->id) {
+ service_info->set_id(category_info->id);
+ }
+ if (category_info->password) {
+ service_info->set_password(category_info->password);
+ }
+ service_info->set_sync_service_type(
+ ConvertToSyncServiceType(category_info->service_type));
+ if (category_info->tgt_uri) {
+ service_info->set_server_database_uri(category_info->tgt_uri);
+ }
+
+ LogDebug("Service type: " << service_info->sync_service_type());
+ profile->service_info()->push_back(service_info);
+ }
+ if (category_list) {
+ g_list_free(category_list);
+ }
+
+ LogDebug("Adding a profile to the list.");
+ profiles->push_back(profile);
+ }
+
+ return profiles;
+}
+
+ResultOrError<void> DataSyncManager::StartSync(
+ const std::string& profile_id_str, int callback_id) {
+ ds_profile_h profile_h = nullptr;
+
+ ScopedExit exit([&profile_h]() {
+ if (profile_h) {
+ sync_agent_ds_free_profile_info(profile_h);
+ }
+ });
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+ sync_agent_event_error_e err = SYNC_AGENT_EVENT_FAIL;
+
+ int profile_id = std::stoi(profile_id_str);
+ LogDebug("profileId: " << profile_id);
+
+ ret = sync_agent_ds_get_profile(profile_id, &profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while getting a profile");
+ }
+
+ err = sync_agent_set_noti_callback(
+ 1, [](sync_agent_event_data_s* d, void* ud) {
+ return static_cast<DataSyncManager*>(ud)->StateChangedCallback(d);
+ },
+ static_cast<void*>(this));
+ if (SYNC_AGENT_EVENT_SUCCESS != err) {
+ return Error("Exception",
+ "Platform error while setting state changed cb");
+ }
+
+ err = sync_agent_set_noti_callback(
+ 2, [](sync_agent_event_data_s* d, void* ud) {
+ return static_cast<DataSyncManager*>(ud)->ProgressCallback(d);
+ },
+ static_cast<void*>(this));
+ if (SYNC_AGENT_EVENT_SUCCESS != err) {
+ return Error("Exception",
+ "Platform error while setting progress cb");
+ }
+
+ ret = sync_agent_ds_start_sync(profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret && SYNC_AGENT_DS_SYNCHRONISING != ret) {
+ return Error("Exception",
+ "Platform error while starting a profile");
+ }
+
+ if (callback_id >= 0) {
+ callbacks_.insert({profile_id, callback_id});
+ }
+
+ return {};
+}
+
+ResultOrError<void> DataSyncManager::StopSync(
+ const std::string& profile_id_str) {
+ ds_profile_h profile_h = nullptr;
+
+ ScopedExit exit([&profile_h]() {
+ if (profile_h) {
+ sync_agent_ds_free_profile_info(profile_h);
+ }
+ });
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ int profile_id = std::stoi(profile_id_str.c_str());
+ LogDebug("profileId: " << profile_id);
+
+ ret = sync_agent_ds_get_profile(profile_id, &profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while getting a profile");
+ }
+
+ ret = sync_agent_ds_stop_sync(profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while stopping a profile");
+ }
+
+ return {};
+}
+
+ResultOrError<SyncStatisticsListPtr> DataSyncManager::GetLastSyncStatistics(
+ const std::string& profile_str_id) const {
+ ds_profile_h profile_h = nullptr;
+ GList* statistics_list = nullptr;
+
+ ScopedExit exit([&statistics_list, &profile_h]() {
+ if (statistics_list) {
+ g_list_free(statistics_list);
+ }
+
+ if (profile_h) {
+ sync_agent_ds_free_profile_info(profile_h);
+ }
+ });
+
+ SyncStatisticsListPtr statistics_list_ptr(new SyncStatisticsList());
+
+ sync_agent_ds_error_e ret = SYNC_AGENT_DS_FAIL;
+
+ int profile_id = std::stoi(profile_str_id);
+ LogDebug("profileId: " << profile_id);
+ ret = sync_agent_ds_get_profile(profile_id, &profile_h);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("NotFoundException",
+ "Platform error while getting a profile");
+ }
+
+ ret = sync_agent_ds_get_sync_statistics(profile_h, &statistics_list);
+ if (SYNC_AGENT_DS_SUCCESS != ret) {
+ return Error("Exception",
+ "Platform error while gettting sync statistics");
+ }
+
+ int statistics_count = g_list_length(statistics_list);
+ LogDebug("statistics_count: " << statistics_count);
+ sync_agent_ds_statistics_info* statistics = nullptr;
+ for (int i = 0; i < statistics_count; i++) {
+ statistics = static_cast<sync_agent_ds_statistics_info*>(
+ g_list_nth_data(statistics_list, i));
+
+ SyncStatisticsPtr statistics_ptr(new SyncStatistics());
+
+ if (0 == i) {
+ LogDebug("Statistics for contact.");
+ statistics_ptr->set_service_type(
+ ConvertToSyncServiceType(SYNC_AGENT_CONTACT));
+ } else if (1 == i) {
+ LogDebug("Statistics for event.");
+ statistics_ptr->set_service_type(
+ ConvertToSyncServiceType(SYNC_AGENT_CALENDAR));
+ } else {
+ LogWarning("Unsupported category for statistics: " << i);
+ continue;
+ }
+
+ LogDebug("dbsynced: " << statistics->dbsynced);
+ if (statistics->dbsynced) {
+ statistics_ptr->set_sync_status(
+ ConvertToSyncStatus(statistics->dbsynced));
+ statistics_ptr->set_client_to_server_total(
+ statistics->client2server_total);
+ statistics_ptr->set_client_to_server_added(
+ statistics->client2server_nrofadd);
+ statistics_ptr->set_client_to_server_updated(
+ statistics->client2server_nrofreplace);
+ statistics_ptr->set_client_to_server_removed(
+ statistics->client2server_nrofdelete);
+ statistics_ptr->set_server_to_client_total(
+ statistics->server2client_total);
+ statistics_ptr->set_server_to_client_added(
+ statistics->server2client_nrofadd);
+ statistics_ptr->set_server_to_client_updated(
+ statistics->server2client_nrofreplace);
+ statistics_ptr->set_server_to_client_removed(
+ statistics->server2client_nrofdelete);
+
+ statistics_ptr->set_last_sync_time(
+ static_cast<unsigned>(statistics->last_session_time));
+ }
+
+ LogDebug(
+ "ClientToServerTotal: " << statistics_ptr->client_to_server_total()
+ << ", ServerToClientTotal: "
+ << statistics_ptr->server_to_client_total());
+
+ statistics_list_ptr->push_back(statistics_ptr);
+ }
+
+ return statistics_list_ptr;
+}
+
+int DataSyncManager::StateChangedCallback(sync_agent_event_data_s* request) {
+ LogDebug("DataSync session state changed.");
+
+ char* profile_dir_name = nullptr;
+ int sync_type = 0;
+ char* progress = nullptr;
+ char* error = nullptr;
+
+ LogDebug("Get state info.");
+ sync_agent_get_event_data_param(request, &profile_dir_name);
+ sync_agent_get_event_data_param(request, &sync_type);
+ sync_agent_get_event_data_param(request, &progress);
+ sync_agent_get_event_data_param(request, &error);
+
+ LogInfo("profileDirName: " << profile_dir_name
+ << ", sync_type: " << sync_type
+ << ", progress: " << progress
+ << ", error: " << error);
+
+ if (profile_dir_name) {
+ std::string profileDirNameStr(profile_dir_name);
+
+ // truncate the rest
+ profileDirNameStr.resize(4);
+ int profileId = std::stoi(profileDirNameStr);
+
+ auto it = callbacks_.find(profileId);
+ if (it != callbacks_.end()) {
+ int callback_id = it->second;
+ callbacks_.erase(it);
+
+ if (nullptr == progress) {
+ LogWarning("nullptr status.");
+ instance_.ReplyAsyncOnFailed(callback_id, profileDirNameStr,
+ UNKNOWN_ERR, "Exception",
+ "nullptr status");
+ } else if (0 == strncmp(progress, "DONE", 4)) {
+ instance_.ReplyAsyncOnCompleted(callback_id, profileDirNameStr);
+ } else if (0 == strncmp(progress, "CANCEL", 6)) {
+ instance_.ReplyAsyncOnStopped(callback_id, profileDirNameStr);
+ } else if (0 == strncmp(progress, "ERROR", 5)) {
+ instance_.ReplyAsyncOnFailed(callback_id, profileDirNameStr,
+ UNKNOWN_ERR, "Exception",
+ "Datasync failed");
+ } else {
+ LogInfo("Undefined status");
+ instance_.ReplyAsyncOnFailed(callback_id, profileDirNameStr,
+ UNKNOWN_ERR, "Exception",
+ "Undefined status");
+ }
+ }
+ }
+
+ g_free(profile_dir_name);
+ g_free(progress);
+ g_free(error);
+
+ if (request->size != nullptr) {
+ g_free(request->size);
+ }
+ g_free(request);
+
+ return 0;
+}
+
+int DataSyncManager::ProgressCallback(sync_agent_event_data_s* request) {
+ LogDebug("DataSync progress called.");
+
+ char* profile_dir_name = nullptr;
+ int sync_type = 0;
+ int uri;
+ char* progress_status = nullptr;
+ char* operation_type = nullptr;
+
+ int is_from_server, total_per_operation, synced_per_operation, total_per_db,
+ synced_per_db;
+
+ LogDebug("Get progress info.");
+ sync_agent_get_event_data_param(request, &profile_dir_name);
+ sync_agent_get_event_data_param(request, &sync_type);
+ sync_agent_get_event_data_param(request, &uri);
+ sync_agent_get_event_data_param(request, &progress_status);
+ sync_agent_get_event_data_param(request, &operation_type);
+
+ LogInfo("profileDirName: " << profile_dir_name << ", syncType: " << sync_type
+ << ", uri: " << uri
+ << ", progressStatus: " << progress_status
+ << ", operationType " << operation_type);
+
+ sync_agent_get_event_data_param(request, &is_from_server);
+ sync_agent_get_event_data_param(request, &total_per_operation);
+ sync_agent_get_event_data_param(request, &synced_per_operation);
+ sync_agent_get_event_data_param(request, &total_per_db);
+ sync_agent_get_event_data_param(request, &synced_per_db);
+
+ LogInfo("isFromServer: " << is_from_server
+ << ", totalPerOperation: " << total_per_operation
+ << ", syncedPerOperation: " << synced_per_operation
+ << ", totalPerDb: " << total_per_db
+ << ", syncedPerDb " << synced_per_db);
+
+ if (profile_dir_name) {
+ std::string profile_dir_name_str(profile_dir_name);
+ profile_dir_name_str.resize(4);
+ int profile_id = std::stoi(profile_dir_name_str);
+
+ auto it = callbacks_.find(profile_id);
+ if (it != callbacks_.end()) {
+ int callback_id = it->second;
+
+ if (SYNC_AGENT_SRC_URI_CONTACT == uri) {
+ instance_.ReplyAsyncOnProgress(callback_id, profile_dir_name_str,
+ is_from_server, synced_per_db,
+ total_per_db,
+ SyncServiceInfo::CONTACT_SERVICE_TYPE);
+ } else if (SYNC_AGENT_SRC_URI_CALENDAR == uri) {
+ instance_.ReplyAsyncOnProgress(callback_id, profile_dir_name_str,
+ is_from_server, synced_per_db,
+ total_per_db,
+ SyncServiceInfo::EVENT_SERVICE_TYPE);
+ } else {
+ LogWarning("Wrong service type");
+ instance_.ReplyAsyncOnFailed(callback_id, profile_dir_name_str,
+ UNKNOWN_ERR, "Exception",
+ "Wrong service type");
+ }
+ }
+ }
+
+ g_free(profile_dir_name);
+ g_free(progress_status);
+ g_free(operation_type);
+
+ if (request != nullptr) {
+ if (request->size != nullptr) {
+ g_free(request->size);
+ }
+ g_free(request);
+ }
+
+ return 0;
+}
+
+} // namespace datasync
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_DATASYNC_MANAGER_H_
+#define DATASYNC_DATASYNC_MANAGER_H_
+
+#include <sync_agent.h>
+
+#include <map>
+#include <string>
+
+#include "common/utils.h"
+#include "datasync/datasync_error.h"
+#include "datasync/sync_profile_info.h"
+#include "datasync/sync_statistics.h"
+
+namespace datasync {
+
+class DatasyncInstance;
+
+class DataSyncManager {
+ public:
+ typedef std::map<int, int> ProfileIdToCallbackIdMap;
+
+ explicit DataSyncManager(DatasyncInstance& parent);
+ ~DataSyncManager();
+
+ ResultOrError<std::string> Add(SyncProfileInfo& profile_info);
+ ResultOrError<void> Update(SyncProfileInfo& profile_info);
+ ResultOrError<void> Remove(const std::string& id);
+
+ ResultOrError<unsigned> GetMaxProfilesNum() const;
+ ResultOrError<unsigned> GetProfilesNum() const;
+
+ ResultOrError<SyncProfileInfoPtr> Get(
+ const std::string& profile_id) const;
+ ResultOrError<SyncProfileInfoListPtr> GetAll() const;
+ ResultOrError<SyncStatisticsListPtr> GetLastSyncStatistics(
+ const std::string& profile_str_id) const;
+
+ ResultOrError<void> StartSync(
+ const std::string& profile_id_str, int callback_id);
+ ResultOrError<void> StopSync(const std::string& profile_id_str);
+
+ private:
+ int StateChangedCallback(sync_agent_event_data_s* request);
+ int ProgressCallback(sync_agent_event_data_s* request);
+
+ DatasyncInstance& instance_;
+ ProfileIdToCallbackIdMap callbacks_;
+
+ static bool sync_agent_initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataSyncManager);
+};
+
+} // namespace datasync
+
+#endif // DATASYNC_DATASYNC_MANAGER_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_DATASYNC_SCOPED_EXIT_H_
+#define DATASYNC_DATASYNC_SCOPED_EXIT_H_
+
+#include <functional>
+
+namespace datasync {
+
+class ScopedExit {
+ public:
+ explicit ScopedExit(std::function<void()> func) : func_(func) { }
+ ~ScopedExit() { func_(); }
+ private:
+ std::function<void()> func_;
+};
+
+} // namespace datasync
+
+#endif // DATASYNC_DATASYNC_SCOPED_EXIT_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_DATASYNC_SERIALIZATION_H_
+#define DATASYNC_DATASYNC_SERIALIZATION_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "common/picojson.h"
+
+#include "datasync/sync_info.h"
+#include "datasync/sync_profile_info.h"
+#include "datasync/sync_service_info.h"
+#include "datasync/sync_statistics.h"
+
+namespace datasync {
+namespace serialization {
+namespace detail {
+
+enum class ConvResult {
+ SUCCESS,
+ MISSING,
+ ERROR
+};
+
+// picojson does not accepts int in value construction
+template <class Type>
+struct ConvertToPicojsonType {
+ typedef Type AccessType;
+ typedef Type ConstructType;
+};
+
+template <>
+struct ConvertToPicojsonType<unsigned> {
+ typedef int AccessType;
+ typedef double ConstructType;
+};
+
+template <>
+struct ConvertToPicojsonType<int> {
+ typedef int AccessType;
+ typedef double ConstructType;
+};
+
+/**
+ * Gets member 'field' field for given 'obj' object.
+ *
+ * Template parameter T of type of field to be extracted.
+ */
+template <class T>
+ConvResult GetMember(const picojson::object& obj, const char* field, T* out) {
+ const auto& it = obj.find(field);
+ if (it != obj.end()) {
+ if (it->second.is<typename ConvertToPicojsonType<T>::AccessType>()) {
+ *out = it->second.get<typename ConvertToPicojsonType<T>::AccessType>();
+ return ConvResult::SUCCESS;
+ } else {
+ return ConvResult::ERROR;
+ }
+ } else {
+ return ConvResult::MISSING;
+ }
+}
+
+/**
+ * Gets member 'field' field for given 'obj' object and converts value to
+ * expected type T using adapter functor.
+ *
+ * Template parameter T states for type of target type of extracted field
+ * Template parameter A states for type of type of extracted field received
+ * from picojson.
+ * Template parameter Adapter states for functor type converting A to T type
+ */
+template <class T, class A, class Adapter>
+ConvResult GetMember(const picojson::object& obj, const char* field,
+ const Adapter& adapter, T* out) {
+ const auto& it = obj.find(field);
+ if (it != obj.end()) {
+ const auto& fld = it->second;
+ if (fld.is<typename ConvertToPicojsonType<A>::AccessType>()) {
+ *out = adapter(fld.get<typename ConvertToPicojsonType<A>::AccessType>());
+ return ConvResult::SUCCESS;
+ } else {
+ return ConvResult::ERROR;
+ }
+ } else {
+ return ConvResult::MISSING;
+ }
+}
+
+} // namespace detail
+
+template <class T>
+struct SerializationDefinition {
+ static picojson::value ToJson(const T& type) {
+ return picojson::value(
+ static_cast<typename detail::ConvertToPicojsonType<T>::ConstructType>(
+ type));
+ }
+
+ static std::unique_ptr<T> FromJson(const picojson::value& value) {
+ if (value.is<typename detail::ConvertToPicojsonType<T>::AccessType>()) {
+ return std::unique_ptr<T>(new T(
+ value.get<typename detail::ConvertToPicojsonType<T>::AccessType>()));
+ } else {
+ return nullptr;
+ }
+ }
+};
+
+template <>
+struct SerializationDefinition<SyncStatistics> {
+ static picojson::value ToJson(const SyncStatistics& type) {
+ picojson::object obj;
+ obj["syncStatus"] = picojson::value(
+ SyncStatistics::SyncStatusToString(type.sync_status()));
+ obj["serviceType"] = picojson::value(
+ SyncServiceInfo::SyncServiceTypeToString(type.service_type()));
+ obj["lastSyncTime"] =
+ picojson::value(static_cast<double>(type.last_sync_time()));
+
+ obj["serverToClientTotal"] =
+ picojson::value(static_cast<double>(type.server_to_client_total()));
+ obj["serverToClientAdded"] =
+ picojson::value(static_cast<double>(type.server_to_client_added()));
+ obj["serverToClientUpdated"] =
+ picojson::value(static_cast<double>(type.server_to_client_updated()));
+ obj["serverToClientRemoved"] =
+ picojson::value(static_cast<double>(type.server_to_client_removed()));
+
+ obj["clientToServerTotal"] =
+ picojson::value(static_cast<double>(type.client_to_server_total()));
+ obj["clientToServerAdded"] =
+ picojson::value(static_cast<double>(type.client_to_server_added()));
+ obj["clientToServerUpdated"] =
+ picojson::value(static_cast<double>(type.client_to_server_updated()));
+ obj["clientToServerRemoved"] =
+ picojson::value(static_cast<double>(type.client_to_server_removed()));
+
+ return picojson::value(obj);
+ }
+
+ static std::unique_ptr<SyncStatistics> FromJson(
+ const picojson::value& value) {
+ std::unique_ptr<SyncStatistics> result;
+
+ if (!value.is<picojson::object>()) {
+ return nullptr;
+ }
+ const picojson::object& obj = value.get<picojson::object>();
+
+ SyncStatistics::SyncStatus sync_status;
+ if (detail::GetMember<SyncStatistics::SyncStatus, std::string>(
+ obj, "syncStatus",
+ std::bind(SyncStatistics::ConvertToSyncStatus, std::placeholders::_1),
+ &sync_status)
+ != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ SyncServiceInfo::SyncServiceType sync_service_type;
+ if (detail::GetMember<SyncServiceInfo::SyncServiceType, std::string>(
+ obj, "syncServiceType",
+ std::bind(SyncServiceInfo::ConvertToSyncServiceType,
+ std::placeholders::_1),
+ &sync_service_type) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned last_sync_time;
+ if (detail::GetMember(obj, "lastSyncTime",
+ &last_sync_time) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned server_to_client_total;
+ if (detail::GetMember(obj, "serverToClientTotal",
+ &server_to_client_total) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned server_to_client_added;
+ if (detail::GetMember(obj, "serverToClientAdded",
+ &server_to_client_added) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned server_to_client_updated;
+ if (detail::GetMember(obj, "serverToClientUpdated",
+ &server_to_client_updated) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned server_to_client_removed;
+ if (detail::GetMember(obj, "serverToClientRemoved",
+ &server_to_client_removed) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned client_to_server_total;
+ if (detail::GetMember(obj, "clientToServerTotal",
+ &client_to_server_total) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned client_to_server_added;
+ if (detail::GetMember(obj, "clientToServerAdded",
+ &client_to_server_added) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned client_to_server_updated;
+ if (detail::GetMember(obj, "clientToServerUpdated",
+ &client_to_server_updated) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ unsigned client_to_server_removed;
+ if (detail::GetMember(obj, "clientToServerRemoved",
+ &client_to_server_removed) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ result.reset(new SyncStatistics(
+ sync_status, sync_service_type, last_sync_time,
+ server_to_client_total, server_to_client_added,
+ server_to_client_updated, server_to_client_removed,
+ client_to_server_total, client_to_server_added,
+ client_to_server_updated, client_to_server_removed));
+
+ return result;
+ }
+};
+
+template <>
+struct SerializationDefinition<SyncServiceInfo> {
+ static picojson::value ToJson(const SyncServiceInfo& type) {
+ picojson::object obj;
+ obj["enable"] = picojson::value(type.enable());
+ obj["serviceType"] = picojson::value(
+ SyncServiceInfo::SyncServiceTypeToString(type.sync_service_type()));
+ obj["serverDatabaseUri"] = picojson::value(type.server_database_uri());
+
+ std::string id = type.id();
+ if (!id.empty()) {
+ obj["id"] = picojson::value(id);
+ }
+
+ std::string password = type.password();
+ if (!password.empty()) {
+ obj["password"] = picojson::value(password);
+ }
+
+ return picojson::value(obj);
+ }
+
+ static std::unique_ptr<SyncServiceInfo> FromJson(
+ const picojson::value& value) {
+ if (!value.is<picojson::object>()) {
+ return nullptr;
+ }
+ const picojson::object& obj = value.get<picojson::object>();
+
+ bool enable;
+ if (detail::GetMember(obj, "enable",
+ &enable) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ SyncServiceInfo::SyncServiceType serviceType;
+ if (detail::GetMember<SyncServiceInfo::SyncServiceType, std::string>(
+ obj, "serviceType",
+ std::bind(&SyncServiceInfo::ConvertToSyncServiceType,
+ std::placeholders::_1),
+ &serviceType) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ std::string serverDatabaseUri;
+ if (detail::GetMember(obj, "serverDatabaseUri",
+ &serverDatabaseUri) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ std::string id;
+ std::string password;
+ detail::GetMember(obj, "id", &id);
+ detail::GetMember(obj, "password", &password);
+
+ std::unique_ptr<SyncServiceInfo> result(
+ new SyncServiceInfo(enable,
+ serviceType,
+ serverDatabaseUri,
+ id,
+ password));
+ return result;
+ }
+};
+
+template <>
+struct SerializationDefinition<SyncInfo> {
+ static picojson::value ToJson(const SyncInfo& type) {
+ picojson::object obj;
+ obj["url"] = picojson::value(type.url());
+ obj["id"] = picojson::value(type.id());
+ obj["password"] = picojson::value(type.password());
+
+ SyncInfo::SyncMode mode = type.sync_mode();
+
+ obj["mode"] = picojson::value(SyncInfo::SyncModeToString(mode));
+
+ if (mode == SyncInfo::MANUAL_MODE) {
+ obj["type"] =
+ picojson::value(SyncInfo::SyncTypeToString(type.sync_type()));
+ } else if (mode == SyncInfo::PERIODIC_MODE) {
+ obj["interval"] = picojson::value(
+ SyncInfo::SyncIntervalToString(type.sync_interval()));
+ }
+
+ return picojson::value(obj);
+ }
+
+ static std::unique_ptr<SyncInfo> FromJson(const picojson::value& value) {
+ if (!value.is<picojson::object>()) {
+ return nullptr;
+ }
+ const picojson::object& obj = value.get<picojson::object>();
+
+ std::string url;
+ if (detail::GetMember(obj, "url",
+ &url) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ std::string id;
+ if (detail::GetMember(obj, "id",
+ &id) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ std::string password;
+ if (detail::GetMember(obj, "password",
+ &password) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ SyncInfo::SyncMode mode;
+ if (detail::GetMember<SyncInfo::SyncMode, std::string>(
+ obj, "mode",
+ std::bind(SyncInfo::ConvertToSyncMode, std::placeholders::_1),
+ &mode) != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ std::unique_ptr<SyncInfo> result;
+ if (mode == SyncInfo::MANUAL_MODE) {
+ SyncInfo::SyncType type;
+ detail::ConvResult res =
+ detail::GetMember<SyncInfo::SyncType, std::string>(
+ obj, "type",
+ std::bind(SyncInfo::ConvertToSyncType, std::placeholders::_1),
+ &type);
+
+ if (res == detail::ConvResult::ERROR) {
+ return nullptr;
+ } else if (res == detail::ConvResult::SUCCESS) {
+ result.reset(new SyncInfo(url, id, password, mode, type,
+ SyncInfo::INTERVAL_UNDEFINED));
+ } else {
+ result.reset(new SyncInfo(url, id, password, mode,
+ SyncInfo::UNDEFINED_TYPE,
+ SyncInfo::INTERVAL_UNDEFINED));
+ }
+ } else if (mode == SyncInfo::PERIODIC_MODE) {
+ SyncInfo::SyncInterval interval;
+ detail::ConvResult res =
+ detail::GetMember<SyncInfo::SyncInterval, std::string>(
+ obj, "interval",
+ std::bind(SyncInfo::ConvertToSyncInterval,
+ std::placeholders::_1),
+ &interval);
+
+ if (res == detail::ConvResult::ERROR) {
+ return nullptr;
+ } else if (res == detail::ConvResult::SUCCESS) {
+ result.reset(new SyncInfo(url, id, password, mode,
+ SyncInfo::UNDEFINED_TYPE, interval));
+ } else {
+ result.reset(new SyncInfo(url, id, password, mode,
+ SyncInfo::UNDEFINED_TYPE,
+ SyncInfo::INTERVAL_UNDEFINED));
+ }
+ } else {
+ result.reset(new SyncInfo(url, id, password, mode,
+ SyncInfo::UNDEFINED_TYPE,
+ SyncInfo::INTERVAL_UNDEFINED));
+ }
+
+ return result;
+ }
+};
+
+template <>
+struct SerializationDefinition<SyncProfileInfo> {
+ static picojson::value ToJson(const SyncProfileInfo& type) {
+ picojson::object obj;
+ obj["profileId"] = picojson::value(type.profile_id());
+ obj["profileName"] = picojson::value(type.profile_name());
+ obj["syncInfo"] =
+ SerializationDefinition<SyncInfo>::ToJson(*type.sync_info());
+
+ picojson::array array;
+ for (const auto& element : *type.service_info()) {
+ array.push_back(
+ SerializationDefinition<SyncServiceInfo>::ToJson(*element));
+ }
+
+ if (array.empty()) {
+ obj["serviceInfo"] = picojson::value();
+ } else {
+ obj["serviceInfo"] = picojson::value(array);
+ }
+
+ return picojson::value(obj);
+ }
+
+ static std::unique_ptr<SyncProfileInfo> FromJson(
+ const picojson::value& value) {
+ std::unique_ptr<SyncProfileInfo> result;
+
+ if (!value.is<picojson::object>()) {
+ return nullptr;
+ }
+ const picojson::object& obj = value.get<picojson::object>();
+
+ std::string profileName;
+ if (detail::GetMember(obj, "profileName", &profileName)
+ != detail::ConvResult::SUCCESS)
+ return nullptr;
+
+ auto syncInfoIt = obj.find("syncInfo");
+ if (syncInfoIt == obj.end()) {
+ return nullptr;
+ }
+ std::unique_ptr<SyncInfo> syncInfo =
+ SerializationDefinition<SyncInfo>::FromJson(syncInfoIt->second);
+ if (!syncInfo) {
+ return nullptr;
+ }
+
+ SyncServiceInfoListPtr serviceList =
+ std::make_shared<SyncServiceInfoList>();
+
+ auto serviceInfoIt = obj.find("serviceInfo");
+ if (serviceInfoIt == obj.end()) {
+ return nullptr;
+ }
+ if (serviceInfoIt->second.is<picojson::array>()) {
+ const picojson::array& array =
+ serviceInfoIt->second.get<picojson::array>();
+ for (const auto& element : array) {
+ serviceList->push_back(SyncServiceInfoPtr(
+ SerializationDefinition<SyncServiceInfo>::FromJson(element)
+ .release()));
+ }
+ } else if (!serviceInfoIt->second.is<picojson::null>()) {
+ return nullptr;
+ }
+
+ std::string profileId;
+ detail::GetMember(obj, "profileId", &profileId);
+
+ result.reset(new SyncProfileInfo(profileId, profileName,
+ SyncInfoPtr(syncInfo.release()),
+ serviceList));
+ return result;
+ }
+};
+
+template <class T>
+picojson::value ToJson(const T& type) {
+ return SerializationDefinition<T>::ToJson(type);
+}
+
+template <class T>
+std::unique_ptr<T> FromJson(const picojson::value& value) {
+ return SerializationDefinition<T>::FromJson(value);
+}
+
+} // namespace serialization
+} // namespace datasync
+
+#endif // DATASYNC_DATASYNC_SERIALIZATION_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datasync/sync_info.h"
+
+namespace datasync {
+
+std::string SyncInfo::SyncModeToString(SyncMode mode) {
+ switch (mode) {
+ case MANUAL_MODE:
+ return "MANUAL";
+ case PERIODIC_MODE:
+ return "PERIODIC";
+ case PUSH_MODE:
+ return "PUSH";
+ default:
+ return "";
+ }
+}
+
+std::string SyncInfo::SyncTypeToString(SyncType type) {
+ switch (type) {
+ case TWO_WAY_TYPE:
+ return "TWO_WAY";
+ case SLOW_TYPE:
+ return "SLOW";
+ case ONE_WAY_FROM_CLIENT_TYPE:
+ return "ONE_WAY_FROM_CLIENT";
+ case REFRESH_FROM_CLIENT_TYPE:
+ return "REFRESH_FROM_CLIENT";
+ case ONE_WAY_FROM_SERVER_TYPE:
+ return "ONE_WAY_FROM_SERVER";
+ case REFRESH_FROM_SERVER_TYPE:
+ return "REFRESH_FROM_SERVER";
+ default:
+ return "";
+ }
+}
+
+std::string SyncInfo::SyncIntervalToString(SyncInterval interval) {
+ switch (interval) {
+ case INTERVAL_5_MINUTES:
+ return "5_MINUTES";
+ case INTERVAL_15_MINUTES:
+ return "15_MINUTES";
+ case INTERVAL_1_HOUR:
+ return "1_HOUR";
+ case INTERVAL_4_HOURS:
+ return "4_HOURS";
+ case INTERVAL_12_HOURS:
+ return "12_HOURS";
+ case INTERVAL_1_DAY:
+ return "1_DAY";
+ case INTERVAL_1_WEEK:
+ return "1_WEEK";
+ case INTERVAL_1_MONTH:
+ return "1_MONTH";
+ default:
+ return "";
+ }
+}
+
+SyncInfo::SyncMode SyncInfo::ConvertToSyncMode(const std::string& str) {
+ if (str == "MANUAL") {
+ return MANUAL_MODE;
+ } else if (str == "PERIODIC") {
+ return PERIODIC_MODE;
+ } else if (str == "PUSH") {
+ return PUSH_MODE;
+ } else {
+ return UNDEFINED_MODE;
+ }
+}
+
+SyncInfo::SyncType SyncInfo::ConvertToSyncType(const std::string& str) {
+ if (str == "TWO_WAY") {
+ return TWO_WAY_TYPE;
+ } else if (str == "SLOW") {
+ return SLOW_TYPE;
+ } else if (str == "ONE_WAY_FROM_CLIENT") {
+ return ONE_WAY_FROM_CLIENT_TYPE;
+ } else if (str == "REFRESH_FROM_CLIENT") {
+ return REFRESH_FROM_CLIENT_TYPE;
+ } else if (str == "ONE_WAY_FROM_SERVER") {
+ return ONE_WAY_FROM_SERVER_TYPE;
+ } else if (str == "REFRESH_FROM_SERVER") {
+ return REFRESH_FROM_SERVER_TYPE;
+ } else {
+ return UNDEFINED_TYPE;
+ }
+}
+
+SyncInfo::SyncInterval SyncInfo::ConvertToSyncInterval(const std::string& str) {
+ if (str == "5_MINUTES") {
+ return INTERVAL_5_MINUTES;
+ } else if (str == "15_MINUTES") {
+ return INTERVAL_15_MINUTES;
+ } else if (str == "1_HOUR") {
+ return INTERVAL_1_HOUR;
+ } else if (str == "4_HOURS") {
+ return INTERVAL_4_HOURS;
+ } else if (str == "12_HOURS") {
+ return INTERVAL_12_HOURS;
+ } else if (str == "1_DAY") {
+ return INTERVAL_1_DAY;
+ } else if (str == "1_WEEK") {
+ return INTERVAL_1_WEEK;
+ } else if (str == "1_MONTH") {
+ return INTERVAL_1_MONTH;
+ } else {
+ return INTERVAL_UNDEFINED;
+ }
+}
+
+SyncInfo::SyncInfo()
+ : sync_mode_(UNDEFINED_MODE),
+ sync_type_(UNDEFINED_TYPE),
+ sync_interval_(INTERVAL_UNDEFINED) {
+}
+
+SyncInfo::SyncInfo(std::string url, std::string id, std::string password,
+ SyncMode sync_mode, SyncType sync_type,
+ SyncInterval sync_interval)
+ : url_(url),
+ id_(id),
+ password_(password),
+ sync_mode_(sync_mode),
+ sync_type_(sync_type),
+ sync_interval_(sync_interval) {
+}
+
+SyncInfo::~SyncInfo() {}
+
+std::string SyncInfo::url() const { return url_; }
+
+void SyncInfo::set_url(const std::string& url) { url_ = url; }
+
+std::string SyncInfo::id() const { return id_; }
+
+void SyncInfo::set_id(const std::string& id) { id_ = id; }
+
+std::string SyncInfo::password() const { return password_; }
+
+void SyncInfo::set_password(const std::string& password) {
+ password_ = password;
+}
+
+SyncInfo::SyncMode SyncInfo::sync_mode() const { return sync_mode_; }
+
+void SyncInfo::set_sync_mode(SyncInfo::SyncMode syncMode) {
+ sync_mode_ = syncMode;
+}
+
+SyncInfo::SyncType SyncInfo::sync_type() const { return sync_type_; }
+
+void SyncInfo::set_sync_type(SyncInfo::SyncType syncType) {
+ sync_type_ = syncType;
+}
+
+SyncInfo::SyncInterval SyncInfo::sync_interval() const {
+ return sync_interval_;
+}
+
+void SyncInfo::set_sync_interval(SyncInfo::SyncInterval syncInterval) {
+ sync_interval_ = syncInterval;
+}
+
+} // namespace datasync
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_SYNC_INFO_H_
+#define DATASYNC_SYNC_INFO_H_
+
+#include <memory>
+#include <string>
+
+namespace datasync {
+
+/**
+ * Representation of SyncInfo JS type
+ */
+class SyncInfo {
+ public:
+ typedef enum {
+ MANUAL_MODE,
+ PERIODIC_MODE,
+ PUSH_MODE,
+ UNDEFINED_MODE
+ } SyncMode;
+
+ typedef enum {
+ TWO_WAY_TYPE,
+ SLOW_TYPE,
+ ONE_WAY_FROM_CLIENT_TYPE,
+ REFRESH_FROM_CLIENT_TYPE,
+ ONE_WAY_FROM_SERVER_TYPE,
+ REFRESH_FROM_SERVER_TYPE,
+ UNDEFINED_TYPE
+ } SyncType;
+
+ typedef enum {
+ INTERVAL_5_MINUTES,
+ INTERVAL_15_MINUTES,
+ INTERVAL_1_HOUR,
+ INTERVAL_4_HOURS,
+ INTERVAL_12_HOURS,
+ INTERVAL_1_DAY,
+ INTERVAL_1_WEEK,
+ INTERVAL_1_MONTH,
+ INTERVAL_UNDEFINED
+ } SyncInterval;
+
+ static std::string SyncModeToString(SyncMode mode);
+ static std::string SyncTypeToString(SyncType type);
+ static std::string SyncIntervalToString(SyncInterval interval);
+
+ static SyncMode ConvertToSyncMode(const std::string& str);
+ static SyncType ConvertToSyncType(const std::string& str);
+ static SyncInterval ConvertToSyncInterval(const std::string& str);
+
+ SyncInfo();
+ SyncInfo(std::string url, std::string id, std::string password,
+ SyncMode sync_mode, SyncType sync_type, SyncInterval sync_interval);
+ virtual ~SyncInfo();
+
+ std::string url() const;
+ void set_url(const std::string& value);
+
+ std::string id() const;
+ void set_id(const std::string& value);
+
+ std::string password() const;
+ void set_password(const std::string& value);
+
+ SyncMode sync_mode() const;
+ void set_sync_mode(SyncMode value);
+
+ SyncType sync_type() const;
+ void set_sync_type(SyncType value);
+
+ SyncInterval sync_interval() const;
+ void set_sync_interval(SyncInterval value);
+
+ protected:
+ std::string url_;
+ std::string id_;
+ std::string password_;
+ SyncMode sync_mode_;
+ SyncType sync_type_;
+ SyncInterval sync_interval_;
+};
+
+typedef std::shared_ptr<SyncInfo> SyncInfoPtr;
+
+} // namespace datasync
+
+#endif // DATASYNC_SYNC_INFO_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datasync/sync_profile_info.h"
+
+namespace datasync {
+
+SyncProfileInfo::SyncProfileInfo()
+ : sync_info_(new SyncInfo()),
+ service_info_(new SyncServiceInfoList()) {
+}
+
+SyncProfileInfo::SyncProfileInfo(const std::string& profileId,
+ const std::string& profile_name,
+ SyncInfoPtr sync_info,
+ SyncServiceInfoListPtr service_info)
+ : profile_id_(profileId),
+ profile_name_(profile_name),
+ sync_info_(sync_info),
+ service_info_(service_info) {
+}
+
+std::string SyncProfileInfo::profile_id() const { return profile_id_; }
+
+void SyncProfileInfo::set_profile_id(const std::string &profileId) {
+ profile_id_ = profileId;
+}
+
+std::string SyncProfileInfo::profile_name() const { return profile_name_; }
+
+void SyncProfileInfo::set_profile_name(const std::string &profileName) {
+ profile_name_ = profileName;
+}
+
+SyncInfoPtr SyncProfileInfo::sync_info() const { return sync_info_; }
+
+void SyncProfileInfo::set_sync_info(SyncInfoPtr syncInfo) {
+ sync_info_ = syncInfo;
+}
+
+SyncServiceInfoListPtr SyncProfileInfo::service_info() const {
+ return service_info_;
+}
+
+void SyncProfileInfo::set_service_info(SyncServiceInfoListPtr serviceInfo) {
+ service_info_ = serviceInfo;
+}
+
+} // namespace datasync
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_SYNC_PROFILE_INFO_H_
+#define DATASYNC_SYNC_PROFILE_INFO_H_
+
+#include <string>
+#include <vector>
+
+#include "datasync/sync_info.h"
+#include "datasync/sync_service_info.h"
+
+namespace datasync {
+
+/**
+ * Representation of SyncProfileInfo JS type
+ */
+class SyncProfileInfo {
+ public:
+ SyncProfileInfo();
+ SyncProfileInfo(const std::string& profileId, const std::string& profile_name,
+ SyncInfoPtr sync_info, SyncServiceInfoListPtr service_info);
+
+ std::string profile_id() const;
+ void set_profile_id(const std::string &value);
+
+ std::string profile_name() const;
+ void set_profile_name(const std::string &value);
+
+ SyncInfoPtr sync_info() const;
+ void set_sync_info(SyncInfoPtr value);
+
+ SyncServiceInfoListPtr service_info() const;
+ void set_service_info(SyncServiceInfoListPtr value);
+
+ protected:
+ std::string profile_id_;
+ std::string profile_name_;
+ SyncInfoPtr sync_info_;
+ SyncServiceInfoListPtr service_info_;
+};
+
+typedef std::shared_ptr<SyncProfileInfo> SyncProfileInfoPtr;
+typedef std::vector<SyncProfileInfoPtr> SyncProfileInfoList;
+typedef std::shared_ptr<SyncProfileInfoList> SyncProfileInfoListPtr;
+
+} // namespace datasync
+
+#endif // DATASYNC_SYNC_PROFILE_INFO_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datasync/sync_service_info.h"
+
+namespace datasync {
+
+SyncServiceInfo::SyncServiceType SyncServiceInfo::ConvertToSyncServiceType(
+ const std::string &type) {
+ if (type == "CONTACT") {
+ return CONTACT_SERVICE_TYPE;
+ } else if (type == "EVENT") {
+ return EVENT_SERVICE_TYPE;
+ } else {
+ return INVALID;
+ }
+}
+
+std::string SyncServiceInfo::SyncServiceTypeToString(SyncServiceType type) {
+ switch (type) {
+ case CONTACT_SERVICE_TYPE:
+ return "CONTACT";
+ case EVENT_SERVICE_TYPE:
+ return "EVENT";
+ default:
+ return "";
+ }
+}
+
+SyncServiceInfo::SyncServiceInfo()
+ : enable_(true),
+ sync_service_type_(UNDEFINED_SERVICE_TYPE) {
+}
+
+SyncServiceInfo::SyncServiceInfo(bool enable,
+ SyncServiceType sync_service_type,
+ std::string server_database_uri,
+ std::string id,
+ std::string password)
+ : enable_(enable),
+ sync_service_type_(sync_service_type),
+ server_database_uri_(server_database_uri),
+ id_(id),
+ password_(password) {
+}
+
+bool SyncServiceInfo::enable() const { return enable_; }
+
+void SyncServiceInfo::set_enable(bool enable) { enable_ = enable; }
+
+SyncServiceInfo::SyncServiceType SyncServiceInfo::sync_service_type() const {
+ return sync_service_type_;
+}
+
+void SyncServiceInfo::set_sync_service_type(
+ SyncServiceInfo::SyncServiceType syncServiceType) {
+ sync_service_type_ = syncServiceType;
+}
+
+std::string SyncServiceInfo::server_database_uri() const {
+ return server_database_uri_;
+}
+
+void SyncServiceInfo::set_server_database_uri(const std::string &uri) {
+ server_database_uri_ = uri;
+}
+
+std::string SyncServiceInfo::id() const { return id_; }
+
+void SyncServiceInfo::set_id(const std::string &id) { id_ = id; }
+
+std::string SyncServiceInfo::password() const { return password_; }
+
+void SyncServiceInfo::set_password(const std::string &password) {
+ password_ = password;
+}
+
+} // namespace datasync
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_SYNC_SERVICE_INFO_H_
+#define DATASYNC_SYNC_SERVICE_INFO_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace datasync {
+
+/**
+ * Representation of SyncServiceInfo JS type
+ */
+class SyncServiceInfo {
+ public:
+ typedef enum {
+ CONTACT_SERVICE_TYPE,
+ EVENT_SERVICE_TYPE,
+ UNDEFINED_SERVICE_TYPE,
+ INVALID
+ } SyncServiceType;
+
+ static SyncServiceType ConvertToSyncServiceType(const std::string &type);
+ static std::string SyncServiceTypeToString(SyncServiceType type);
+
+ SyncServiceInfo();
+ SyncServiceInfo(bool enable, SyncServiceType sync_service_type,
+ std::string server_database_uri, std::string id,
+ std::string password);
+
+ bool enable() const;
+ void set_enable(bool value);
+
+ SyncServiceType sync_service_type() const;
+ void set_sync_service_type(SyncServiceType value);
+
+ std::string server_database_uri() const;
+ void set_server_database_uri(const std::string &value);
+
+ std::string id() const;
+ void set_id(const std::string &value);
+
+ std::string password() const;
+ void set_password(const std::string &value);
+
+ protected:
+ bool enable_;
+ SyncServiceType sync_service_type_;
+ std::string server_database_uri_;
+ std::string id_;
+ std::string password_;
+};
+
+typedef std::shared_ptr<SyncServiceInfo> SyncServiceInfoPtr;
+typedef std::vector<SyncServiceInfoPtr> SyncServiceInfoList;
+typedef std::shared_ptr<SyncServiceInfoList> SyncServiceInfoListPtr;
+
+} // namespace datasync
+
+#endif // DATASYNC_SYNC_SERVICE_INFO_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datasync/sync_statistics.h"
+
+namespace {
+
+const int kUndefinedTime = -1;
+
+}
+
+namespace datasync {
+
+SyncStatistics::SyncStatus SyncStatistics::ConvertToSyncStatus(
+ const std::string& status) {
+ if (status == "SUCCESS") {
+ return SUCCESS_STATUS;
+ } else if (status == "FAIL") {
+ return FAIL_STATUS;
+ } else if (status == "STOP") {
+ return STOP_STATUS;
+ } else if (status == "NONE") {
+ return NONE_STATUS;
+ } else {
+ return INVALID;
+ }
+}
+
+std::string SyncStatistics::SyncStatusToString(SyncStatus status) {
+ switch (status) {
+ case SUCCESS_STATUS:
+ return "SUCCESS";
+ case FAIL_STATUS:
+ return "FAIL";
+ case STOP_STATUS:
+ return "STOP";
+ case NONE_STATUS:
+ return "NONE";
+ default:
+ return "";
+ }
+}
+
+SyncStatistics::SyncStatistics()
+ : sync_status_(NONE_STATUS),
+ service_type_(SyncServiceInfo::UNDEFINED_SERVICE_TYPE),
+ last_sync_time_(kUndefinedTime),
+ server_to_client_total_(0),
+ server_to_client_added_(0),
+ server_to_client_updated_(0),
+ server_to_client_removed_(0),
+ client_to_server_total_(0),
+ client_to_server_added_(0),
+ client_to_server_updated_(0),
+ client_to_server_removed_(0) {
+}
+
+SyncStatistics::SyncStatistics(
+ SyncStatus sync_status, SyncServiceInfo::SyncServiceType service_type,
+ unsigned last_sync_time, unsigned server_to_client_total,
+ unsigned server_to_client_added, unsigned server_to_client_updated,
+ unsigned server_to_client_removed, unsigned client_to_server_total,
+ unsigned client_to_server_added, unsigned client_to_server_updated,
+ unsigned client_to_server_removed)
+ : sync_status_(sync_status),
+ service_type_(service_type),
+ last_sync_time_(last_sync_time),
+ server_to_client_total_(server_to_client_total),
+ server_to_client_added_(server_to_client_added),
+ server_to_client_updated_(server_to_client_updated),
+ server_to_client_removed_(server_to_client_removed),
+ client_to_server_total_(client_to_server_total),
+ client_to_server_added_(client_to_server_added),
+ client_to_server_updated_(client_to_server_updated),
+ client_to_server_removed_(client_to_server_removed) {
+}
+
+SyncStatistics::SyncStatus SyncStatistics::sync_status() const {
+ return sync_status_;
+}
+
+void SyncStatistics::set_sync_status(SyncStatistics::SyncStatus sync_status) {
+ sync_status_ = sync_status;
+}
+
+SyncServiceInfo::SyncServiceType SyncStatistics::service_type() const {
+ return service_type_;
+}
+
+void SyncStatistics::set_service_type(
+ SyncServiceInfo::SyncServiceType service_type) {
+ service_type_ = service_type;
+}
+
+unsigned SyncStatistics::last_sync_time() const { return last_sync_time_; }
+
+void SyncStatistics::set_last_sync_time(unsigned value) {
+ last_sync_time_ = value;
+}
+
+unsigned SyncStatistics::server_to_client_total() const {
+ return server_to_client_total_;
+}
+
+void SyncStatistics::set_server_to_client_total(unsigned value) {
+ server_to_client_total_ = value;
+}
+
+unsigned SyncStatistics::server_to_client_added() const {
+ return server_to_client_added_;
+}
+
+void SyncStatistics::set_server_to_client_added(unsigned value) {
+ server_to_client_added_ = value;
+}
+
+unsigned SyncStatistics::server_to_client_updated() const {
+ return server_to_client_updated_;
+}
+
+void SyncStatistics::set_server_to_client_updated(unsigned value) {
+ server_to_client_updated_ = value;
+}
+
+unsigned SyncStatistics::server_to_client_removed() const {
+ return server_to_client_removed_;
+}
+
+void SyncStatistics::set_server_to_client_removed(unsigned value) {
+ server_to_client_removed_ = value;
+}
+
+unsigned SyncStatistics::client_to_server_total() const {
+ return client_to_server_total_;
+}
+
+void SyncStatistics::set_client_to_server_total(unsigned value) {
+ client_to_server_total_ = value;
+}
+
+unsigned SyncStatistics::client_to_server_added() const {
+ return client_to_server_added_;
+}
+
+void SyncStatistics::set_client_to_server_added(unsigned value) {
+ client_to_server_added_ = value;
+}
+
+unsigned SyncStatistics::client_to_server_updated() const {
+ return client_to_server_updated_;
+}
+
+void SyncStatistics::set_client_to_server_updated(unsigned value) {
+ client_to_server_updated_ = value;
+}
+
+unsigned SyncStatistics::client_to_server_removed() const {
+ return client_to_server_removed_;
+}
+
+void SyncStatistics::set_client_to_server_removed(unsigned value) {
+ client_to_server_removed_ = value;
+}
+
+} // namespace datasync
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATASYNC_SYNC_STATISTICS_H_
+#define DATASYNC_SYNC_STATISTICS_H_
+
+#include <string>
+#include <vector>
+
+#include "datasync/sync_service_info.h"
+
+namespace datasync {
+
+/**
+ *Representation of SyncStatistics JS type
+ */
+class SyncStatistics {
+ public:
+ typedef enum {
+ SUCCESS_STATUS,
+ FAIL_STATUS,
+ STOP_STATUS,
+ NONE_STATUS,
+ INVALID
+ } SyncStatus;
+
+ static SyncStatus ConvertToSyncStatus(const std::string& status);
+ static std::string SyncStatusToString(SyncStatus status);
+
+ SyncStatistics();
+ SyncStatistics(SyncStatus sync_status,
+ SyncServiceInfo::SyncServiceType service_type,
+ unsigned last_sync_time,
+ unsigned server_to_client_total,
+ unsigned server_to_client_added,
+ unsigned server_to_client_updated,
+ unsigned server_to_client_removed,
+ unsigned client_to_server_total,
+ unsigned client_to_server_added,
+ unsigned client_to_server_updated,
+ unsigned client_to_server_removed);
+
+ SyncStatus sync_status() const;
+ void set_sync_status(SyncStatus sync_status);
+
+ SyncServiceInfo::SyncServiceType service_type() const;
+ void set_service_type(SyncServiceInfo::SyncServiceType service_type);
+
+ unsigned last_sync_time() const;
+ void set_last_sync_time(unsigned value);
+
+ unsigned server_to_client_total() const;
+ void set_server_to_client_total(unsigned value);
+
+ unsigned server_to_client_added() const;
+ void set_server_to_client_added(unsigned value);
+
+ unsigned server_to_client_updated() const;
+ void set_server_to_client_updated(unsigned value);
+
+ unsigned server_to_client_removed() const;
+ void set_server_to_client_removed(unsigned value);
+
+ unsigned client_to_server_total() const;
+ void set_client_to_server_total(unsigned value);
+
+ unsigned client_to_server_added() const;
+ void set_client_to_server_added(unsigned value);
+
+ unsigned client_to_server_updated() const;
+ void set_client_to_server_updated(unsigned value);
+
+ unsigned client_to_server_removed() const;
+ void set_client_to_server_removed(unsigned value);
+
+ private:
+ SyncStatus sync_status_;
+ SyncServiceInfo::SyncServiceType service_type_;
+ unsigned last_sync_time_;
+ unsigned server_to_client_total_;
+ unsigned server_to_client_added_;
+ unsigned server_to_client_updated_;
+ unsigned server_to_client_removed_;
+ unsigned client_to_server_total_;
+ unsigned client_to_server_added_;
+ unsigned client_to_server_updated_;
+ unsigned client_to_server_removed_;
+};
+
+typedef std::shared_ptr<SyncStatistics> SyncStatisticsPtr;
+typedef std::vector<SyncStatisticsPtr> SyncStatisticsList;
+typedef std::shared_ptr<SyncStatisticsList> SyncStatisticsListPtr;
+
+} // namespace datasync
+
+#endif // DATASYNC_SYNC_STATISTICS_H_
BuildRequires: pkgconfig(pkgmgr-info)
BuildRequires: pkgconfig(pmapi)
BuildRequires: pkgconfig(tapi)
+BuildRequires: pkgconfig(sync-agent)
BuildRequires: pkgconfig(vconf)
%if %{with wayland}
BuildRequires: pkgconfig(wayland-client)
'application/application.gyp:*',
'bookmark/bookmark.gyp:*',
'content/content.gyp:*',
+ 'datasync/datasync.gyp:*',
'download/download.gyp:*',
'filesystem/filesystem.gyp:*',
'messageport/messageport.gyp:*',