Adding documentation for Sync adapter and Sync adapter service app
authorJyothi Kumar Sambolu <s.jyothi@samsung.com>
Mon, 14 Sep 2015 14:09:17 +0000 (19:39 +0530)
committerJyothi Kumar Sambolu <s.jyothi@samsung.com>
Mon, 14 Sep 2015 14:13:15 +0000 (19:43 +0530)
Change-Id: I71907de3dac374350c19c1aa35cab991d4f1a19a
Signed-off-by: Jyothi Kumar Sambolu <s.jyothi@samsung.com>
12 files changed:
org.tizen.sampledescriptions/html/images/syncadapterapp_datachange.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/syncadapterapp_getsyncjobs.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/syncadapterapp_mainscreen.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand_sync.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/syncadapterapp_periodic.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/syncadapterapp_periodic_sync.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/index.htm
org.tizen.sampledescriptions/html/mobile_n/sd_mn.htm
org.tizen.sampledescriptions/html/mobile_n/syncadapterapp_sd_mn.htm [new file with mode: 0644]
org.tizen.sampledescriptions/html/mobile_n/syncadapterserviceapp_sd_mn.htm [new file with mode: 0644]
org.tizen.sampledescriptions/index.xml

diff --git a/org.tizen.sampledescriptions/html/images/syncadapterapp_datachange.png b/org.tizen.sampledescriptions/html/images/syncadapterapp_datachange.png
new file mode 100644 (file)
index 0000000..eb0cb54
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/syncadapterapp_datachange.png differ
diff --git a/org.tizen.sampledescriptions/html/images/syncadapterapp_getsyncjobs.png b/org.tizen.sampledescriptions/html/images/syncadapterapp_getsyncjobs.png
new file mode 100644 (file)
index 0000000..a1a46df
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/syncadapterapp_getsyncjobs.png differ
diff --git a/org.tizen.sampledescriptions/html/images/syncadapterapp_mainscreen.png b/org.tizen.sampledescriptions/html/images/syncadapterapp_mainscreen.png
new file mode 100644 (file)
index 0000000..025941b
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/syncadapterapp_mainscreen.png differ
diff --git a/org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand.png b/org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand.png
new file mode 100644 (file)
index 0000000..7f08ebc
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand.png differ
diff --git a/org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand_sync.png b/org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand_sync.png
new file mode 100644 (file)
index 0000000..3280c1b
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/syncadapterapp_ondemand_sync.png differ
diff --git a/org.tizen.sampledescriptions/html/images/syncadapterapp_periodic.png b/org.tizen.sampledescriptions/html/images/syncadapterapp_periodic.png
new file mode 100644 (file)
index 0000000..530567a
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/syncadapterapp_periodic.png differ
diff --git a/org.tizen.sampledescriptions/html/images/syncadapterapp_periodic_sync.png b/org.tizen.sampledescriptions/html/images/syncadapterapp_periodic_sync.png
new file mode 100644 (file)
index 0000000..4e0aaf2
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/syncadapterapp_periodic_sync.png differ
index 90a32ba..d650a54 100644 (file)
                        <li><a href="mobile_n/simple_home_sd_mn.htm">Simple Homescreen</a></li>
                        <li><a href="mobile_n/sketch_sd_mn.htm">Sketch</a></li>
                        <li><a href="mobile_n/stopwatch_sd_mn.htm">Stopwatch</a></li>
+                       <li><a href="mobile_n/syncadapterapp_sd_mn.htm">Syncadapter UI App</a></li>
+                       <li><a href="mobile_n/syncadapterserviceapp_sd_mn.htm">Syncadapter Service App</a></li>
                        <li><a href="mobile_n/systeminfo_sd_mn.htm">System Info</a></li>
                        <li><a href="mobile_n/taskmanager_sd_mn.htm">Taskmanager</a></li>
                        <li><a href="mobile_n/ui_components_sd_mn.htm">UI Components</a></li>
index a94323f..212d27b 100644 (file)
      <td>Demonstrates how you can implement a complex view using recursive composition of the standard EFL UI components and containers in a component hierarchy.</td>
     </tr>
        <tr>
+     <td><a href="syncadapterapp_sd_mn.htm">Sync adapter UI App</a></td>
+     <td>Demonstrates how you can add different sync requests to sync manager for scheduling of data synchronization tasks</td>
+       </tr>
+       <tr>
+     <td><a href="syncadapterserviceapp_sd_mn.htm">Sync adapter Service App</a></td>
+     <td>Demonstrates how sync callbacks are to be implemented to handle sync requests from Sync adapter UI app</td>
+       </tr>
+       <tr>
      <td><a href="systeminfo_sd_mn.htm">System Info</a></td>
      <td>Demonstrates how you can get system information.</td>
     </tr>
diff --git a/org.tizen.sampledescriptions/html/mobile_n/syncadapterapp_sd_mn.htm b/org.tizen.sampledescriptions/html/mobile_n/syncadapterapp_sd_mn.htm
new file mode 100644 (file)
index 0000000..8bdfbdb
--- /dev/null
@@ -0,0 +1,538 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="../css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="../css/snippet.css" />
+       <script type="text/javascript" src="../scripts/snippet.js"></script>
+       <script type="text/javascript" src="../scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/search.js" charset="utf-8"></script>
+
+       <title>Sync Adapter Sample Overview</title>
+</head>
+
+<body class="no-toc" onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+</div>
+
+<div id="container"><div id="contents"><div class="content">
+<div id="profile">
+               <p><img alt="Mobile native" src="../images/mobile_s_n.png"/></p>
+</div>
+
+<h1>Sync Adapter Sample Overview</h1>
+<p>The application opens with the <strong>Sync Adapter App</strong> screen, which displays a list of sync manager features.</p>
+<p>The following figure illustrates the home screen of the application.</p>
+       <p class="figure">Figure: Sync adapter home screen view</p>
+       <p align="center"><img alt="Sync adapter home screen view" src="../images/syncadapterapp_mainscreen.png" />
+</p>
+<ul>
+       <li>To request one time/on demand sync click <strong>On Demand Sync</strong></li>
+       <li>To schedule sync periodically click <strong>Periodic Sync</strong></li>
+       <li>To perform sync upon device data change click <strong>Data change Sync</strong></li>
+       <li>To get all the sync jobs requested by application click <strong> Get all sync jobs</strong></li>
+       <li>To remove all sync jobs requested by application <strong>Remove all sync jobs</strong>.</li>
+</ul>
+
+
+<p>The application uses the <span style="font-family: Courier New,Courier,monospace">libaccounts-svc</span> module to work with the accounts database and the <span style="font-family: Courier New,Courier,monospace">elementary</span> module to support the UI requirements.</p>
+
+<h2>Prerequisites</h2>
+<ol>
+<li>To ensure proper application execution, the following privileges must be set:
+<ul>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/alarm.set</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/contact.read</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/datasharing</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/network.get</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/appmanager.launch</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/account.read</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/network.profile</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/account.write</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/internet</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/network.set</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/download</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/alarm.set</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/contact.read</span></li>
+</ul>
+</li>
+<li>Launch the service app which acts as a sync adapter to this UI app. The service app must be built and included along with Sync adapter UI app into the package.
+Please refer <a href="./syncadapterserviceapp_sd_mn.htm">Sync Adapter Service App</a> for reference.
+<pre class="prettyprint">
+#define SYNC_ADAPTER_APP_ID "org.tizen.syncadapterserviceapp"
+
+static void
+create_sync_main_menu(appdata_s *ad)
+{
+       app_control_h app_control;
+       int ret = app_control_create(&app_control);
+       ret = app_control_set_app_id(app_control, SYNC_ADAPTER_APP_ID);
+
+       app_control_send_launch_request(app_control, NULL, NULL);
+       ...
+       ...
+       ...
+}</pre>
+</li>
+<li>Create a dummy account for passing it to sync manager API. Enable sync support on the account.
+<pre class="prettyprint">
+static void
+create_account()
+{
+       LOGI("creating dummy account");
+
+       sa_account_id = 10;
+       account_h account;
+
+       int ret = account_create(&account);
+       LOGI("account_create = %d", ret);
+
+       ret = account_set_user_name(account, "dummy_user");
+       LOGI("account_set_user_name = %d", ret);
+
+       ret = account_set_email_address(account, "dummy_user@syncadapterapp.com");
+       LOGI("account_set_email_address = %d", ret);
+
+       ret = account_set_capability(account, ACCOUNT_SUPPORTS_CAPABILITY_CONTACT, ACCOUNT_CAPABILITY_ENABLED);
+       LOGI("account_set_capability = %d", ret);
+
+       ret = account_set_sync_support(account, ACCOUNT_SYNC_STATUS_IDLE);
+       LOGI("account_set_sync_support = %d", ret);
+
+       ret = account_insert_to_db(account, &sa_account_id);
+       LOGI("Account id is = %d", sa_account_id);
+       account_destroy(account);
+
+       LOGI("Dummy account is created = %d", sa_account_id);
+}</pre>
+</li>
+</ol>
+
+<h2>On Demand Sync</h2>
+<p class="figure">Figure: On Demand Sync</p>
+<p align="center"> <img alt="On Demand Sync" src="../images/syncadapterapp_ondemand.png"/> <img alt="On Demand sync" src="../images/syncadapterapp_ondemand_sync.png"/></p>
+
+<h3>Request On Demand Sync</h3>
+<ol>
+<li>To perform On Demand sync select <strong>On Demand sync</strong> from home screen view. Click on <strong>Sync</strong> button which will trigger corresponding sync manager API as shown below.
+<pre class="prettyprint">
+static void
+cb_add_on_demand_sync(void* pData, Evas_Object* pObj, void* pEvent_info)
+{
+       LOGI("Request manual sync");
+       viewdata_s* viewData = pData;
+
+       account_query_account_by_user_name(query_account_cb, "dummy_user", NULL);
+
+       account_h account;
+       account_create(&account);
+       account_query_account_by_account_id(sa_account_id, &account);
+
+       bundle *extra = bundle_create();
+       bundle_add_str(extra, "URL", "http://android-developers.blogspot.com/atom.xml");
+       viewData->account_id = sa_account_id;
+
+       int ret = sync_manager_on_demand_sync_job(account, "OnDemand", SYNC_OPTION_NO_RETRY, extra, &on_demand_sync_job_id);
+       if (ret != SYNC_ERROR_NONE)
+               LOGE("Sync manager failed with error code %d", ret);
+       else
+               LOGI("sync manager added on demand sync id %d", on_demand_sync_job_id);
+
+       bundle_free(extra);
+       account_destroy(account);
+       LOGI("Exit");
+}</pre>
+</li>
+
+<li>When the sync manager schedules sync job for this request, sync callbacks in sync adapter service app will be invoked. The sync adapter service app will download the titles from the URL parameter sent along with the API and writes it into a database.
+Upon completion of sync job, service app will communicate the same to Sync adapter UI app using app_control.
+<pre class="prettyprint">
+static void
+app_control(app_control_h app_control, void *data)
+{
+       char *operation;
+       int ret = app_control_get_operation(app_control, &operation);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               LOGE("failed to get operation");
+               return;
+       }
+
+       if (operation && !strcmp(operation, "http://tizen.org/appcontrol/operation/sync_complete")) {
+               LOGE("Sync completed by service app. Loading ..");
+
+               char* collist[5];
+               collist[0] = "TITLE";
+
+               int req_id;
+               int result = data_control_sql_select_with_page(sql_provider, collist, 1, NULL, "TITLE DESC", 1, 5, &req_id);
+               if (result != DATA_CONTROL_ERROR_NONE)
+                       LOGE("data_control_sql_select() is failed: ");
+               return;
+       }
+       ....
+       ....
+}</pre>
+</li>
+
+
+<li>Display the contents from database using data_control.
+<p>Use a data control to read the contents of the database and dislay it as a list view</p>
+<pre class="prettyprint">
+static void
+create_list_view(Evas_Object *object)
+{
+       Evas_Object *btn;
+       Elm_Object_Item *nf_it;
+
+       /* List */
+       if (list == NULL || clear_flag == 1) {
+               list = elm_list_add(object);
+               elm_list_mode_set(list, ELM_LIST_EXPAND);
+               /* evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL); */
+               elm_object_part_content_set(object, "list", list);
+       }
+       /* Main Menu Items Here */
+       if (clear_flag != 1)
+               elm_list_item_append(list, pageContents, NULL, NULL, page_cb, object);
+
+       elm_list_go(list);
+
+       /* This button is set for devices which doesn't have H/W back key. */
+       btn = elm_button_add(object);
+       elm_object_style_set(btn, "naviframe/end_btn/default");
+       nf_it = elm_naviframe_item_push(object, "Client App", btn, NULL, list, NULL);
+       elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, object);
+
+       clear_flag = 0;
+}
+
+
+static void select_response_cb(int request_id, data_control_h provider, result_set_cursor enumerator, bool provider_result, const char *error, void *user_data)
+{
+       LOGI("Enter");
+       if (provider_result) {
+               if (enumerator) {
+                       char col_name[1024] = {0};
+                       char word[1024] = {0};
+                       char word_desc[1024] = {0};
+                       int count = 0;
+                       while (data_control_sql_step_next(enumerator) == DATA_CONTROL_ERROR_NONE && ++count < 10) {
+                               memset(word, 0, 1024);
+                               memset(word_desc, 0, 1024);
+                               data_control_sql_get_column_name(enumerator, 0, col_name);
+                               if (!strcmp(col_name, "TITLE")) {
+                                       data_control_sql_get_text_data(enumerator, 0, word);
+                                       pageContents = word;
+                                       LOGI("TITLE %s", word);
+                                       create_list_view(manualObject);
+                               }
+                       }
+               }
+       } else {
+               LOGE("select_response_cb() is failed: %s", error);
+       }
+
+       LOGI("Exit");
+}
+</pre>
+</li>
+</ol>
+
+<h2>Periodic sync</h2>
+<p class="figure">Figure: Periodic Sync</p>
+<p align="center"> <img alt="Periodic Sync" src="../images/syncadapterapp_periodic.png"/> <img alt="Periodic sync" src="../images/syncadapterapp_periodic_sync.png"/></p>
+
+<h3>Request Periodic Sync</h3>
+<ol>
+<li>To perform Periodic sync select <strong>Periodic sync</strong> from home screen view. Click on <strong>Sync</strong> button which will trigger corresponding sync manager API as shown below.
+<pre class="prettyprint">
+static void
+cb_add_periodic_sync(void* pData, Evas_Object* pObj, void* pEvent_info)
+{
+       LOGI("Request periodic sync");
+       viewdata_s* viewData = pData;
+       elm_object_text_set(viewData->syncBtn, "Wait for 30 Min");
+       evas_object_smart_callback_del(viewData->syncBtn, "clicked", cb_add_periodic_sync);
+
+       account_query_account_by_user_name(query_account_cb, "dummy_user", NULL);
+
+       account_h account;
+       account_create(&account);
+       account_query_account_by_account_id(sa_account_id, &account);
+
+       bundle *extra = bundle_create();
+       bundle_add_str(extra, "URL", "http://android-developers.blogspot.com/atom.xml");
+
+       viewData->account_id = sa_account_id;
+       int job_id;
+       int ret = sync_manager_add_periodic_sync_job(account, "Periodic", SYNC_PERIOD_INTERVAL_30MIN, SYNC_OPTION_EXPEDITED, extra, &periodic_sync_job_id);
+       if (ret == SYNC_ERROR_NONE)
+               LOGI("sync manager added periodic sync job id %d", ret, periodic_sync_job_id);
+       else
+               LOGE("sync manager error %d", ret);
+
+       bundle_free(extra);
+       account_destroy(account);
+       LOGI("Exit");
+}</pre>
+</li>
+
+<li>When the sync manager schedules sync job for this request, sync callbacks in sync adapter service app will be invoked periodically. The sync adapter service app will download the titles from the URL parameter sent along with the API and writes it into a database.
+Upon completion of sync job, service app will communicate the same to Sync adapter UI app using app_control.
+<pre class="prettyprint">
+static void
+app_control(app_control_h app_control, void *data)
+{
+       char *operation;
+       int ret = app_control_get_operation(app_control, &operation);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               LOGE("failed to get operation");
+               return;
+       }
+
+       if (operation && !strcmp(operation, "http://tizen.org/appcontrol/operation/sync_complete")) {
+               LOGE("Sync completed by service app. Loading ..");
+
+               char* collist[5];
+               collist[0] = "TITLE";
+
+               int req_id;
+               int result = data_control_sql_select_with_page(sql_provider, collist, 1, NULL, "TITLE DESC", 1, 5, &req_id);
+               if (result != DATA_CONTROL_ERROR_NONE)
+                       LOGE("data_control_sql_select() is failed: ");
+               return;
+       }
+       ....
+       ....
+}</pre>
+</li>
+
+
+<li>Display the contents from database using data_control.
+<p>Use a data control to read the contents of the database and dislay it as a list view</p>
+<pre class="prettyprint">
+static void
+create_list_view(Evas_Object *object)
+{
+       Evas_Object *btn;
+       Elm_Object_Item *nf_it;
+
+       /* List */
+       if (list == NULL || clear_flag == 1) {
+               list = elm_list_add(object);
+               elm_list_mode_set(list, ELM_LIST_EXPAND);
+               /* evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL); */
+               elm_object_part_content_set(object, "list", list);
+       }
+       /* Main Menu Items Here */
+       if (clear_flag != 1)
+               elm_list_item_append(list, pageContents, NULL, NULL, page_cb, object);
+
+       elm_list_go(list);
+
+       /* This button is set for devices which doesn't have H/W back key. */
+       btn = elm_button_add(object);
+       elm_object_style_set(btn, "naviframe/end_btn/default");
+       nf_it = elm_naviframe_item_push(object, "Client App", btn, NULL, list, NULL);
+       elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, object);
+
+       clear_flag = 0;
+}
+
+
+static void select_response_cb(int request_id, data_control_h provider, result_set_cursor enumerator, bool provider_result, const char *error, void *user_data)
+{
+       LOGI("Enter");
+       if (provider_result) {
+               if (enumerator) {
+                       char col_name[1024] = {0};
+                       char word[1024] = {0};
+                       char word_desc[1024] = {0};
+                       int count = 0;
+                       while (data_control_sql_step_next(enumerator) == DATA_CONTROL_ERROR_NONE && ++count < 10) {
+                               memset(word, 0, 1024);
+                               memset(word_desc, 0, 1024);
+                               data_control_sql_get_column_name(enumerator, 0, col_name);
+                               if (!strcmp(col_name, "TITLE")) {
+                                       data_control_sql_get_text_data(enumerator, 0, word);
+                                       pageContents = word;
+                                       LOGI("TITLE %s", word);
+                                       create_list_view(manualObject);
+                               }
+                       }
+               }
+       } else {
+               LOGE("select_response_cb() is failed: %s", error);
+       }
+
+       LOGI("Exit");
+}
+</pre>
+</li>
+</ol>
+
+<h2>Data Change sync</h2>
+<p class="figure">Figure: Data Change Sync</p>
+<p align="center"> <img alt="Data Change Sync" src="../images/syncadapterapp_datachange.png"/></p>
+
+<h3>Request Data change Sync</h3>
+<ol>
+<li>To perform data change sync select <strong>Data Change sync </strong> from home screen view. Click on <strong>ContactSync</strong> button which will trigger corresponding sync manager API as shown below.
+<pre class="prettyprint">
+static void
+cb_add_data_change_sync(void* pData, Evas_Object* pObj, void* pEvent_info)
+{
+       LOGI("Request data change sync");
+       viewdata_s* viewData = pData;
+
+       account_query_account_by_user_name(query_account_cb, "dummy_user", NULL);
+
+       account_h account;
+       account_create(&account);
+       account_query_account_by_account_id(sa_account_id, &account);
+
+       bundle *extra = bundle_create();
+       bundle_add_str(extra, "URL", "http://posttestserver.com/post.php?dir=MyContacts");
+       viewData->account_id = sa_account_id;
+       int ret = sync_manager_add_data_change_sync_job(account, SYNC_SUPPORTS_CAPABILITY_CONTACT, SYNC_OPTION_NONE, extra, &data_change_sync_job_id);
+       if (ret == SYNC_ERROR_NONE)
+               LOGI("sync manager added data change sync job id %d", ret, data_change_sync_job_id);
+       else
+               LOGE("sync manager error %d", ret);
+
+       bundle_free(extra);
+       account_destroy(account);
+       LOGI("Exit");
+}</pre>
+</li>
+
+<li>The sync manager stores the data change sync request. Whenever there is a change in contacts db of the device sync manager schedules sync job for contacts data. Sync callbacks in sync adapter service app will be invoked accordingly.
+The sync adapter service app will upload the contact details to the server given along with the request. Upon completion of upload sync job, service app will communicate the same to Sync adapter UI app using app_control.
+The Sync adapter UI app will show a popup to notify the user about the status.
+<pre class="prettyprint">
+
+static void
+app_control(app_control_h app_control, void *data)
+{
+       ...
+       ...
+       if (operation && !strcmp(operation, "http://tizen.org/appcontrol/operation/upload_sync_complete")) {
+               LOGE("upload sync");
+               Evas_Object *popup;
+               Evas_Object *win = NF;
+
+               popup = elm_popup_add(win);
+               elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
+               eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
+               evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               elm_object_text_set(popup, "Upload Sync completed at\n http://posttestserver.com/data/YYYY/MM/DD/MyContacts/");
+
+               elm_popup_timeout_set(popup, 3.0);
+               evas_object_show(popup);
+               return;
+       }
+}</pre>
+</li>
+</ol>
+
+
+<h2>Get all sync jobs</h2>
+<p class="figure">Figure: Get all sync jobs</p>
+<p align="center"> <img alt="Get all sync jobs" src="../images/syncadapterapp_getsyncjobs.png"/></p>
+
+<h3>Request get sync jobs</h3>
+<li>To query the sync jobs requested by the application select <strong>Get all sync jobs </strong> from home screen view. The corresponding sync manager API will be called as shown below.
+<pre class="prettyprint">
+bool
+sync_adapter_sample_foreach_sync_job_cb(account_h account, const char *sync_job_name, const char *sync_capability, int sync_job_id, bundle* sync_job_user_data, void *user_data)
+{
+       Evas_Object* list = (Evas_Object*) (user_data);
+       char sync_job_info[1024];
+       memset(sync_job_info, 0, 1024);
+
+       if (sync_job_name) {
+               if (!strcmp(sync_job_name, "OnDemand"))
+                       on_demand_sync_job_id = sync_job_id;
+               else if (!strcmp(sync_job_name, "Periodic"))
+                       periodic_sync_job_id = sync_job_id;
+
+               sprintf(sync_job_info, "job_id[%d] job_name[%s]", sync_job_id, strdup(sync_job_name));
+       }
+       if (sync_capability) {
+               data_change_sync_job_id = sync_job_id;
+               sprintf(sync_job_info, "job_id[%d] capability[%s]", sync_job_id, strdup(sync_capability));
+       }
+
+       elm_list_item_append(list, sync_job_info, NULL, NULL, NULL, NULL);
+       return true;
+}
+
+void
+on_get_all_sync_jobs_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       ...
+       ...
+       int ret = sync_manager_foreach_sync_job(sync_adapter_sample_foreach_sync_job_cb, lst);
+       if (ret == SYNC_ERROR_NONE) {
+               elm_list_go(lst);
+               evas_object_show(lst);
+       } else
+               LOGI("Error %d", ret);
+       ...
+}</pre>
+</li>
+
+<h2>Remove all sync jobs</h2>
+
+<h3>Request to remove all sync jobs</h3>
+<li>To remove all the sync jobs requested by the application select <strong>Remove all sync jobs</strong> from home screen view. The corresponding sync manager API will be called as shown below.
+<pre class="prettyprint">
+void
+on_remove_all_sync_jobs_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       LOGI("Enter");
+       int ret = SYNC_ERROR_NONE;
+
+       /* Its not necessary to free On demand sync job. The sync job will be freed when sync is complete */
+       /* Removing other sync requests */
+
+       if (data_change_sync_job_id != -1) {
+               ret = sync_manager_remove_sync_job(data_change_sync_job_id);
+               LOGI("Remove data sync request. ret = %d", ret);
+               data_change_sync_job_id = -1;
+       }
+
+       if (periodic_sync_job_id != -1) {
+               ret = sync_manager_remove_sync_job(periodic_sync_job_id);
+               LOGI("Remove periodic sync request. ret = %d", ret);
+               periodic_sync_job_id = -1;
+       }
+}</pre>
+</li>
+<script type="text/javascript" src="../scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="../scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="../images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
diff --git a/org.tizen.sampledescriptions/html/mobile_n/syncadapterserviceapp_sd_mn.htm b/org.tizen.sampledescriptions/html/mobile_n/syncadapterserviceapp_sd_mn.htm
new file mode 100644 (file)
index 0000000..bbad7a9
--- /dev/null
@@ -0,0 +1,186 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="../css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="../css/snippet.css" />
+       <script type="text/javascript" src="../scripts/snippet.js"></script>
+       <script type="text/javascript" src="../scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/search.js" charset="utf-8"></script>
+
+       <title>Sync Adapter Service Sample Overview</title>
+</head>
+
+<body class="no-toc" onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+</div>
+
+<div id="container"><div id="contents"><div class="content">
+<div id="profile">
+               <p><img alt="Mobile native" src="../images/mobile_s_n.png"/></p>
+</div>
+
+<h1>Sync Adapter Service Sample Overview</h1>
+<p>The service application acts as a sync adapter to <a href="./syncadapterapp_sd_mn.htm">Sync Adapter UI App</a>. The service app handles all sync requets from Sync Adapter UI App.</p>
+
+<h2>Prerequisites</h2>
+<ol>
+<li>To ensure proper application execution, the following privileges must be set:
+<ul>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/contact.read</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/datasharing</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/network.get</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/appmanager.launch</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/account.read</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/network.profile</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/internet</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/network.set</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/download</span></li>
+       <li><span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/contact.read</span></li>
+</ul>
+</li>
+<li>Register the service application as a sync adapter by passiong the sync callbacks to the following Sync adapter API.
+<pre class="prettyprint">
+bool service_app_create(void *data)
+{
+       LOGI("service_app_create called");
+
+       sync_adapter_set_callbacks(handleStartSync, handleStopSync);
+       ...
+       ...
+       return true;
+}</pre>
+</li>
+<li>Create a database and intialize data_control handle for writing data into database.
+<pre class="prettyprint">
+#define DB_PATH "/opt/usr/apps/org.tizen.syncadapterapp/data/sync.db"
+...
+...
+
+int create_database()
+{
+       LOGI("create database, %s", DB_PATH);
+       remove(DB_PATH);
+
+       char* sql_command = "CREATE TABLE IF NOT EXISTS sync_data ( TITLE TEXT)";
+       int open_flags = (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
+
+       int ret = sqlite3_open_v2(DB_PATH, &db, open_flags, NULL);
+       if (ret != SQLITE_OK)
+       {
+               LOGE("database creation failed with error: %d",ret);
+               return ret;
+       }
+
+       ret = sqlite3_exec(db, sql_command, NULL, NULL, NULL);
+       if (ret != SQLITE_OK)
+       {
+               LOGE("database table creation failed with error: %d",ret);
+       }
+
+       return ret;
+}
+</pre>
+</li>
+</ol>
+
+<h2>Start Sync</h2>
+<h3>Handle start sync</h3>
+<li>Whenever sync manager schedules a sync job for Sync Adapter UI app, the following callback method will be tirgger to perform sync job.
+The sample service application will download the content from server and communicates to Sync Adapter UI app using app_control.
+<pre class="prettyprint">
+static bool handleStartSync(account_h account, const char *sync_job_name, const char *sync_capability, bundle *sync_job_user_data)
+{
+       bool is_data_sync_cb = sync_capability ? true : false;
+       LOGI("HandleStartSync called in service app");
+       LOGI("Sync parameters:");
+       if (sync_job_name)
+       {
+               LOGI("Syncjob Name [%s]", sync_job_name);
+       }
+       else
+               LOGE("Error Syncjob Name is must");
+
+       if (account)
+       {
+               int id;
+               account_get_account_id(account, &id);
+               LOGI("account [%d] ", id);
+       }
+       else
+               LOGI("account is NULL");
+
+       if (is_data_sync_cb)
+       {
+               LOGI("Data change sync capability [%s]", sync_capability);
+       }
+
+       app_control_h app_control;
+       int ret = app_control_create(&app_control);
+       ret = app_control_set_app_id(app_control, "org.tizen.syncadapterapp");
+
+       char* pURL = NULL;
+       ret = bundle_get_str(sync_job_user_data, "URL", &pURL);
+       if (pURL != NULL)
+       {
+               if (is_data_sync_cb)
+               {
+                       start_upload_to_server(pURL);
+                       ret = app_control_set_operation(app_control, "http://tizen.org/appcontrol/operation/upload_sync_complete");
+                       LOGI("upload sync completed");
+               }
+               else
+               {
+                       start_download_from_server(pURL);
+                       ret = app_control_set_operation(app_control, "http://tizen.org/appcontrol/operation/sync_complete");
+                       LOGI("Download sync completed");
+               }
+       }
+
+       app_control_send_launch_request(app_control, NULL, NULL);
+
+       return 0;
+}</pre>
+</li>
+
+
+<h2>Cancel sync</h2>
+<h3>Handle Cancel sync</h3>
+<li>This callback method is a notification to inform sync adapter service app to safely cancel ongoing sync job (if any).
+<pre class="prettyprint">
+static void handleStopSync(account_h account, const char* capability)
+{
+       int id;
+       account_get_account_id(account, &id);
+       LOGI("details %d, %s ", id, capability);
+       LOGI("HandleStopSync called in client");
+}</pre>
+</li>
+
+<script type="text/javascript" src="../scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="../scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="../images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
index fb32366..46a836a 100644 (file)
@@ -93,6 +93,8 @@
                        <topic href="html/mobile_n/simple_home_sd_mn.htm" label="Simple Homescreen"></topic>
                        <topic href="html/mobile_n/sketch_sd_mn.htm" label="Sketch"></topic>
                        <topic href="html/mobile_n/stopwatch_sd_mn.htm" label="Stopwatch"></topic>
+                       <topic href="html/mobile_n/syncadapterapp_sd_mn.htm" label="Syncadapter UI App"></topic>
+                       <topic href="html/mobile_n/syncadapterserviceapp_sd_mn.htm" label="Syncadapter Service App"></topic>
                        <topic href="html/mobile_n/systeminfo_sd_mn.htm" label="System Info"></topic>
                        <topic href="html/mobile_n/taskmanager_sd_mn.htm" label="Taskmanager"></topic>
                        <topic href="html/mobile_n/ui_components_sd_mn.htm" label="UI Components"></topic>