SyncAdapter(M) / src /

sync-adapter-app.c

  1. #include <sync_manager.h>
  2. #include <sync-error.h>
  3. #include "sync-adapter-app.h"
  4.  
  5.  
  6. typedef struct app_data {
  7. Evas_Object *win;
  8. Evas_Object *layout;
  9. Evas_Object *conform;
  10. Evas_Object *nf;
  11. Evas_Object *syncBtn;
  12. Evas_Object *selectAllBtn;
  13. Evas_Object *removeBtn;
  14. } app_data_s;
  15.  
  16. /* Declare global app_data object */
  17. app_data_s *g_ad = NULL;
  18.  
  19. typedef struct list_item_data {
  20. int index;
  21. int type;
  22. Elm_Object_Item *item;
  23. Eina_Bool expanded;
  24. } list_item_data_s;
  25.  
  26. /*
  27. * Declare global list_itme_data object
  28. * depending on each list view
  29. */
  30. list_item_data_s *main_id;
  31. list_item_data_s *setting_id;
  32. list_item_data_s *data_id;
  33. list_item_data_s *foreach_id;
  34.  
  35. typedef struct list_menu_data {
  36. Evas_Object *nf;
  37. Evas_Object *popup;
  38. Evas_Object *genlist;
  39. } list_menu_data_s;
  40.  
  41. /*
  42. * Declare global list_menu_data object
  43. * depending on each list menu which can be selected
  44. * - Sync types
  45. * - Period interval types
  46. * - Capability types
  47. * - Option types
  48. */
  49. list_menu_data_s *sync_job_md;
  50. list_menu_data_s *interval_md;
  51. list_menu_data_s *capability_md;
  52. list_menu_data_s *option_md;
  53.  
  54. /* Account handle and ID for operating sync job related with Account */
  55. account_h account;
  56. int account_id = -1;
  57.  
  58. /* Flag for verifying accountless case */
  59. bool is_accountless = false;
  60.  
  61. /* The number of sync jobs which being operated */
  62. int cnt_sync_jobs = 0;
  63.  
  64. /*
  65. * Get selected text for displaying it on each button
  66. * Each button can display below text which is used to set up sync parameters
  67. */
  68. static char *sync_job_items[] = {"On Demand Sync", "Periodic Sync", "Data Change Sync"};
  69. static char *sync_interval_items[] = {"every 30 minutes", "every an hour", "every 2 hours", "every 3 hours", "every 6 hours", "every 12 hours", "every a day"};
  70. static char *sync_capability_items[] = {"Calendar", "Contact", "Image", "Music", "Sound", "Video"};
  71. static char *sync_option_items[] = {"Option None", "Sync with Priority", "Sync Once", "Sync Once with Priority"};
  72.  
  73. /* To display selected parameters */
  74. char displayed_job[MAX_SIZE] = "On Demand Sync";
  75. char displayed_interval[MAX_SIZE] = "every 30 minutes";
  76. char displayed_capability[MAX_SIZE] = "Calendar";
  77. char displayed_option[MAX_SIZE] = "Option None";
  78.  
  79. /* Variables as parameter for calling Sync Manager API */
  80. sync_period_e sync_interval = SYNC_PERIOD_INTERVAL_30MIN;
  81. char *sync_capability = SYNC_SUPPORTS_CAPABILITY_CALENDAR;
  82. sync_option_e sync_option = SYNC_OPTION_NONE;
  83.  
  84. /* Below sync job IDs are required for managing each sync job */
  85. int on_demand_sync_job_id = -1;
  86. int periodic_sync_job_id = -1;
  87. int data_change_sync_job_id = -1;
  88. int data_change_id[NUM_OF_CAPABILITY] = {-1, };
  89.  
  90. /* Store sync job ID to be managed */
  91. int remove_sync_job[MAX_NUM] = {-1, };
  92. /* Store whether sync jobs to be removed is checked */
  93. bool list_of_remove_sync_job[MAX_NUM] = {false, };
  94. /* Store text for showing that on "Manage sync jobs" */
  95. char list_of_sync_jobs[MAX_NUM][MAX_SIZE];
  96. /* Flag for verifying whether all sync jobs are checked */
  97. bool is_all_checked = false;
  98.  
  99. /* Flag for verifying whether user already uses a menu */
  100. int is_enter = 0;
  101.  
  102.  
  103. /*
  104. * Window delete request callback
  105. */
  106. static Eina_Bool
  107. win_delete_request_cb(void *data, Elm_Object_Item *it)
  108. {
  109. dlog_print(DLOG_INFO, LOG_TAG, "Delete main view");
  110. /* Terminate the Sync Adapter sample */
  111. ui_app_exit();
  112. return EINA_TRUE;
  113. }
  114.  
  115.  
  116. /*
  117. * Naviframe pop callback for "Start sync with settings"
  118. */
  119. static Eina_Bool
  120. sync_job_naviframe_pop_cb(void *data, Elm_Object_Item *it)
  121. {
  122. dlog_print(DLOG_INFO, LOG_TAG, "Return to previous view");
  123. /* Initialize flag to check whether user already uses the menu, "Start sync with settings" */
  124. is_enter--;
  125. return EINA_TRUE;
  126. }
  127.  
  128.  
  129. /*
  130. * Naviframe pop callback for "Manage sync jobs"
  131. */
  132. static Eina_Bool
  133. foreach_naviframe_pop_cb(void *data, Elm_Object_Item *it)
  134. {
  135. dlog_print(DLOG_INFO, LOG_TAG, "Return to previous view");
  136. /* Initialize list to show it on the menu "Manage sync jobs" */
  137. memset(list_of_sync_jobs, '\0', sizeof(list_of_sync_jobs));
  138. /* Initialize flag to check whether user already uses the menu, "Manage sync jobs" */
  139. is_enter--;
  140. /* Initialize variable which is used to count the number of registered sync jobs */
  141. cnt_sync_jobs = 0;
  142. return EINA_TRUE;
  143. }
  144.  
  145.  
  146. /*
  147. * Create scroller for genlist
  148. */
  149. static Evas_Object*
  150. create_scroller(Evas_Object *parent)
  151. {
  152. Evas_Object *scroller = elm_scroller_add(parent);
  153. elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
  154. elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
  155. evas_object_show(scroller);
  156. return scroller;
  157. }
  158.  
  159.  
  160. /*
  161. * Get edje file which is used to set size and location of UI object
  162. */
  163. static void
  164. app_get_resource(const char *edj_file_in, char *edj_path_out, int edj_path_max)
  165. {
  166. char *res_path = app_get_resource_path();
  167. if (res_path) {
  168. snprintf(edj_path_out, edj_path_max, "%s%s", res_path, edj_file_in);
  169. free(res_path);
  170. }
  171. }
  172.  
  173.  
  174. /*
  175. * Genlist selected callback for removing sync job
  176. */
  177. static void
  178. genlist_selected_cb(void *data, Evas_Object *obj, void *event_info)
  179. {
  180. Evas_Object *button = (Evas_Object *)data;
  181. Elm_Object_Item *it = event_info;
  182. Eina_Bool expanded = EINA_FALSE;
  183.  
  184. /*
  185. * If all of the items on lists are check,
  186. * select button text will be changed from "Select all" to "Deselect all"
  187. */
  188. if (is_all_checked)
  189. elm_object_text_set(button, "Deselect all");
  190. else
  191. elm_object_text_set(button, "Select all");
  192.  
  193. elm_genlist_item_selected_set(it, EINA_FALSE);
  194.  
  195. expanded = elm_genlist_item_expanded_get(it);
  196. elm_genlist_item_expanded_set(it, !expanded);
  197. }
  198.  
  199.  
  200. /*
  201. * Get text which can represent main menu
  202. */
  203. static char*
  204. get_main_menu_text(void *data, Evas_Object *obj, const char *part)
  205. {
  206. /* Item data for main UI */
  207. main_id = (list_item_data_s *)data;
  208.  
  209. /*
  210. * Below code will make text for main list
  211. * - "Create an account"
  212. * - "Set as accountless"
  213. * - "Start sync with settings"
  214. * - "Manage sync jobs"
  215. */
  216. switch (main_id->index) {
  217. case 0:
  218. if (!strcmp("elm.text", part)) return strdup("Create an account");
  219. else return NULL;
  220. case 1:
  221. if (!strcmp("elm.text", part)) return strdup("Set as accountless");
  222. else return NULL;
  223. case 2:
  224. if (!strcmp("elm.text", part)) return strdup("Start sync with settings");
  225. else return NULL;
  226. case 3:
  227. if (!strcmp("elm.text", part)) return strdup("Manage sync jobs");
  228. else return NULL;
  229. }
  230.  
  231. return NULL;
  232. }
  233.  
  234.  
  235. /*
  236. * Get text which can represent notice how to verify data change sync
  237. */
  238. static char*
  239. get_data_change_text(void *data, Evas_Object *obj, const char *part)
  240. {
  241. /* Item data for data change UI */
  242. data_id = (list_item_data_s *)data;
  243.  
  244. /*
  245. * Below code will make text for explaining how to test data change sync
  246. * - "1. Press home button"
  247. * - "2. Change data in your device"
  248. * - "3. Pop up will come after change"
  249. * - "4. Check the pop up message"
  250. */
  251. switch (data_id->index) {
  252. case 0:
  253. if (!strcmp("elm.text", part)) return strdup("1. Press home button");
  254. else return NULL;
  255. case 1:
  256. if (!strcmp("elm.text", part)) return strdup("2. Change data in your device");
  257. else return NULL;
  258. case 2:
  259. if (!strcmp("elm.text", part)) return strdup("3. Pop up will come after change");
  260. else return NULL;
  261. case 3:
  262. if (!strcmp("elm.text", part)) return strdup("4. Check the pop up message");
  263. else return NULL;
  264. }
  265.  
  266. return NULL;
  267. }
  268.  
  269.  
  270. /*
  271. * Get text which can represent menu to select specific sync condition
  272. * Below menu provides 4 items to set parameters for sync jobs
  273. * "Sync types" will show On Demand, Periodic, and Data Change sync jobs
  274. * "Period interval types" will show intervals from 30 minutes to a day
  275. * "Capability types" will show Calendar, Contact, Image, Music, Sound, and Video
  276. * "Option types" will show Option None, Sync with Priority, Sync Once, and Sync Once with Priority
  277. * Depending on the sync types, list which can be used to select each menu will be enabling
  278. */
  279. static char*
  280. get_setting_menu_text(void *data, Evas_Object *obj, const char *part)
  281. {
  282. /* Item data for setting UI */
  283. setting_id = (list_item_data_s *)data;
  284. char buf[MAX_SIZE*2];
  285.  
  286. /*
  287. * Change the state of genlist depending on selected "Sync types"
  288. * Each list represents title, setting value, and description for the menu
  289. * In the case of enabled list, setting value is blue
  290. * In the opposite case, the value is shown as light grey for indicating disabled
  291. * The description text is changed depending on the state of selection
  292. */
  293. switch (setting_id->index) {
  294. case 0:
  295. if (!strcmp("elm.text", part))
  296. return strdup("Sync types");
  297. else if (!strcmp("elm.text.multiline", part)) {
  298. char *sync_job_desc = "It is for selecting kind of sync job";
  299. snprintf(buf, sizeof(buf), "<font color=#3DB9CCFF>%s</font><br>%s", displayed_job, sync_job_desc);
  300. return strdup(buf);
  301. }
  302. break;
  303. case 1:
  304. if (!strcmp("elm.text", part))
  305. return strdup("Period interval types");
  306. else if (!strcmp("elm.text.multiline", part)) {
  307. if (!strcmp(displayed_job, "Periodic Sync")) {
  308. char *sync_period_desc = "It is for selecting kind of sync interval";
  309. snprintf(buf, sizeof(buf), "<font color=#3DB9CCFF>%s</font><br>%s", displayed_interval, sync_period_desc);
  310. } else {
  311. char *sync_period_desc = "It is only for Periodic Sync";
  312. snprintf(buf, sizeof(buf), "<font color=#CCCCCCFF>%s</font><br>%s", displayed_interval, sync_period_desc);
  313. }
  314. return strdup(buf);
  315. }
  316. break;
  317. case 2:
  318. if (!strcmp("elm.text", part))
  319. return strdup("Capability types");
  320. else if (!strcmp("elm.text.multiline", part)) {
  321. if (!strcmp(displayed_job, "Data Change Sync")) {
  322. char *sync_capability_desc = "It is for selecting kind of sync capability";
  323. snprintf(buf, sizeof(buf), "<font color=#3DB9CCFF>%s</font><br>%s", displayed_capability, sync_capability_desc);
  324. } else {
  325. char *sync_capability_desc = "It is only for Data Change Sync";
  326. snprintf(buf, sizeof(buf), "<font color=#CCCCCCFF>%s</font><br>%s", displayed_capability, sync_capability_desc);
  327. }
  328. return strdup(buf);
  329. }
  330. break;
  331. case 3:
  332. if (!strcmp("elm.text", part))
  333. return strdup("Option types");
  334. else if (!strcmp("elm.text.multiline", part)) {
  335. char *sync_option_desc = "It is for selecting kind of sync option";
  336. snprintf(buf, sizeof(buf), "<font color=#3DB9CCFF>%s</font><br>%s", displayed_option, sync_option_desc);
  337. return strdup(buf);
  338. }
  339. break;
  340. }
  341.  
  342. return NULL;
  343. }
  344.  
  345.  
  346. /*
  347. * Callback for counting checked list of sync jobs
  348. * Checked sync jobs can be removed by using "Remove" button
  349. */
  350. static void
  351. check_changed_cb(void *data, Evas_Object *obj, void *event_info)
  352. {
  353. int idx = (int)data;
  354.  
  355. /*
  356. * Store checked items in the listof_remove_sync_job
  357. * for checking removable sync jobs
  358. */
  359. Eina_Bool state = elm_check_state_get(obj);
  360. dlog_print(DLOG_INFO, LOG_TAG, "sync_job_id: [%d], State: [%s]", remove_sync_job[idx], (state == 1) ? "checked" : "unchecked");
  361. if (state) {
  362. list_of_remove_sync_job[idx] = true;
  363. } else {
  364. list_of_remove_sync_job[idx] = false;
  365. is_all_checked = false;
  366. return;
  367. }
  368.  
  369. /*
  370. * Check whether all of the sync jobs are checked
  371. * If not, is_all_checked won't be "true"
  372. */
  373. for (idx = 0; idx < cnt_sync_jobs; idx++) {
  374. if (!list_of_remove_sync_job[idx])
  375. return;
  376. }
  377.  
  378. dlog_print(DLOG_INFO, LOG_TAG, "All the sync jobs are checked");
  379. is_all_checked = true;
  380. }
  381.  
  382.  
  383. /*
  384. * Create check-box for representing selected sync jobs
  385. */
  386. static Evas_Object*
  387. create_check(Evas_Object *parent, list_item_data_s *foreach_id)
  388. {
  389. Evas_Object *check = elm_check_add(parent);
  390.  
  391. if (is_all_checked)
  392. elm_check_state_set(check, EINA_TRUE);
  393.  
  394. /* Set a callback for verifying the change of check-box state */
  395. evas_object_smart_callback_add(check, "changed", check_changed_cb, (void *)foreach_id->index);
  396.  
  397. return check;
  398. }
  399.  
  400.  
  401. /*
  402. * Get contents of registered sync jobs
  403. * It is mainly used to contain the check-box on right side of each line
  404. */
  405. static Evas_Object*
  406. get_content_registered_sync_jobs(void *data, Evas_Object *obj, const char *part)
  407. {
  408. foreach_id = (list_item_data_s *)data;
  409.  
  410. if ((foreach_id->type / 3) % 4 == 1 && !strcmp("elm.swallow.icon", part))
  411. return NULL;
  412. else if ((foreach_id->type / 3) % 4 == 2 && !strcmp("elm.swallow.end", part))
  413. return create_check(obj, foreach_id);
  414. else if ((foreach_id->type / 3) % 4 == 3) {
  415. if (!strcmp("elm.swallow.icon", part))
  416. return NULL;
  417. else if (!strcmp("elm.swallow.end", part))
  418. return create_check(obj, foreach_id);
  419. }
  420.  
  421. switch (foreach_id->type % 3) {
  422. case 0:
  423. return NULL;
  424. case 1:
  425. if (!strcmp("elm.swallow.icon.1", part)) return NULL;
  426. else return NULL;
  427. case 2:
  428. return NULL;
  429. }
  430.  
  431. return NULL;
  432. }
  433.  
  434.  
  435. /*
  436. * Get text of registered sync jobs
  437. * It is mainly used to contain text on each line
  438. */
  439. static char*
  440. get_text_registered_sync_jobs(void *data, Evas_Object *obj, const char *part)
  441. {
  442. foreach_id = (list_item_data_s *)data;
  443.  
  444. /* Stored sync job text is copied to buf */
  445. char buf[MAX_SIZE];
  446. snprintf(buf, sizeof(buf), "%s", list_of_sync_jobs[foreach_id->index]);
  447.  
  448. /* The contents of text in buf is included on each line */
  449. switch (foreach_id->type % 3) {
  450. case 0:
  451. if (!strcmp("elm.text", part)) return strdup(buf);
  452. else return NULL;
  453. case 1:
  454. if (!strcmp("elm.text", part)) return strdup(buf);
  455. else return NULL;
  456. case 2:
  457. if (!strcmp("elm.text", part)) return strdup(buf);
  458. else if (!strcmp("elm.text.end", part)) return strdup("Sub text");
  459. else return NULL;
  460. }
  461.  
  462. return NULL;
  463. }
  464.  
  465.  
  466. /*
  467. * Release list item data structure
  468. */
  469. static void
  470. gl_del_cb(void *data, Evas_Object *obj)
  471. {
  472. list_item_data_s *lid = data;
  473. free(lid);
  474. }
  475.  
  476.  
  477. /*
  478. * Notify whether account mode is selected
  479. * Neither "Create an account" nor "Set as accountless" is not pressed before starting a sync job,
  480. * "Select account mode first" is shown on the pop-up
  481. */
  482. void
  483. notify_by_using_popup(void *data, Evas_Object *obj, void *event_info)
  484. {
  485. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : select account mode first - create an account or use accountless mode");
  486.  
  487. Evas_Object *win = data, *popup;
  488.  
  489. popup = elm_popup_add(win);
  490. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  491. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  492. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  493.  
  494. /* Pop-up is maintained for 2 seconds */
  495. elm_object_text_set(popup, "Select account mode first");
  496. elm_popup_timeout_set(popup, TIME_FOR_POPUP);
  497. evas_object_show(popup);
  498. }
  499.  
  500.  
  501. /*
  502. * Query account callback for getting account ID
  503. */
  504. bool query_account_cb(account_h account, void *user_data)
  505. {
  506. account_get_account_id(account, &account_id);
  507. return false;
  508. }
  509.  
  510.  
  511. /*
  512. * Callback for operating on demand sync job
  513. * This function is a process of calling sync_manager_on_demand_sync_job()
  514. * Press "Start Sync" button with "Sync types" as "On Demand Sync"
  515. */
  516. static void
  517. cb_add_on_demand_sync(void *pData, Evas_Object *pObj, void *pEvent_info)
  518. {
  519. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : Request manual sync");
  520.  
  521. /*
  522. * Create bundle and use set sync option as sync_job_user_data
  523. * displayed_interval will be used to show requested on demand sync job
  524. * when it does not be operated properly due to network disconnected
  525. */
  526. bundle *sync_job_user_data = NULL;
  527. sync_job_user_data = bundle_create();
  528. bundle_add_str(sync_job_user_data, "option", displayed_option);
  529.  
  530. /*
  531. * Depending whether account is set, method of calling the API is decided
  532. * Below process includes getting account which is set and using it
  533. */
  534. int ret = SYNC_ERROR_NONE;
  535. if (is_accountless) {
  536. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : request accountless On Demand Sync");
  537. ret = sync_manager_on_demand_sync_job(NULL, "OnDemand", sync_option, sync_job_user_data, &on_demand_sync_job_id);
  538. } else {
  539. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : request On Demand Sync with an account");
  540. dlog_print(DLOG_INFO, LOG_TAG, "Account Id : [%d]", account_id);
  541. /* Query account by using account ID */
  542. ret = account_query_account_by_account_id(account_id, &account);
  543. if (ret != ACCOUNT_ERROR_NONE)
  544. dlog_print(DLOG_INFO, LOG_TAG, "account_query_account_by_account_id() is failed [%d : %s]", ret, get_error_message(ret));
  545. ret = sync_manager_on_demand_sync_job(account, "OnDemand", sync_option, sync_job_user_data, &on_demand_sync_job_id);
  546. }
  547.  
  548. if (ret != SYNC_ERROR_NONE)
  549. dlog_print(DLOG_INFO, LOG_TAG, "sync_manager_on_demand_sync_job() is failed [%d : %s]", ret, get_error_message(ret));
  550. else
  551. dlog_print(DLOG_INFO, LOG_TAG, "Sync manager added on demand sync id [%d]", on_demand_sync_job_id);
  552.  
  553. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : Exit the cb_add_on_demand_sync()");
  554. }
  555.  
  556.  
  557. /*
  558. * Callback for operating periodic sync job
  559. * This function is a process of calling sync_manager_add_periodic_sync_job()
  560. * Press "Start Sync" button with "Sync types" as "Periodic Sync"
  561. */
  562. static void
  563. cb_add_periodic_sync(void *pData, Evas_Object *pObj, void *pEvent_info)
  564. {
  565. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : Request periodic sync");
  566.  
  567. /*
  568. * Create bundle and use set sync interval as sync_job_user_data
  569. * displayed_interval will be used to show registered periodic sync job
  570. */
  571. bundle *sync_job_user_data = NULL;
  572. sync_job_user_data = bundle_create();
  573. bundle_add_str(sync_job_user_data, "interval", displayed_interval);
  574.  
  575. /*
  576. * Depending whether account is set, method of calling the API is decided
  577. * Below process includes getting account which is set and using it
  578. */
  579. int ret = SYNC_ERROR_NONE;
  580. if (is_accountless) {
  581. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : request accountless Periodic Sync");
  582. ret = sync_manager_add_periodic_sync_job(NULL, "Periodic", sync_interval, sync_option, sync_job_user_data, &periodic_sync_job_id);
  583. } else {
  584. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : request Periodic Sync with an account");
  585. dlog_print(DLOG_INFO, LOG_TAG, "Account Id : [%d]", account_id);
  586. /* Query account by using account ID */
  587. ret = account_query_account_by_account_id(account_id, &account);
  588. if (ret != ACCOUNT_ERROR_NONE)
  589. dlog_print(DLOG_INFO, LOG_TAG, "account_query_account_by_account_id() is failed [%d : %s]", ret, get_error_message(ret));
  590. ret = sync_manager_add_periodic_sync_job(account, "Periodic", sync_interval, sync_option, sync_job_user_data, &periodic_sync_job_id);
  591. }
  592.  
  593. if (ret != SYNC_ERROR_NONE) {
  594. dlog_print(DLOG_INFO, LOG_TAG, "sync_manager_add_periodic_sync_job() is failed [%d : %s]", ret, get_error_message(ret));
  595. } else {
  596. dlog_print(DLOG_INFO, LOG_TAG, "Sync manager added periodic sync id [%d]", periodic_sync_job_id);
  597.  
  598. /*
  599. * Adding periodic sync job will not send response immediately without expedited option
  600. * So, below pop-up messages show the result of adding periodic sync job
  601. */
  602. if ((sync_option == SYNC_OPTION_NONE) | (sync_option == SYNC_OPTION_NO_RETRY)) {
  603. Evas_Object *win = g_ad->nf, *popup;
  604. popup = elm_popup_add(win);
  605. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  606. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  607. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  608.  
  609. if (sync_interval == SYNC_PERIOD_INTERVAL_30MIN)
  610. elm_object_text_set(popup, "It is expected in 30mins");
  611. else if (sync_interval == SYNC_PERIOD_INTERVAL_1H)
  612. elm_object_text_set(popup, "It is expected in an hour");
  613. else if (sync_interval == SYNC_PERIOD_INTERVAL_2H)
  614. elm_object_text_set(popup, "It is expected in 2 hours");
  615. else if (sync_interval == SYNC_PERIOD_INTERVAL_3H)
  616. elm_object_text_set(popup, "It is expected in 3 hours");
  617. else if (sync_interval == SYNC_PERIOD_INTERVAL_6H)
  618. elm_object_text_set(popup, "It is expected in 6 hours");
  619. else if (sync_interval == SYNC_PERIOD_INTERVAL_12H)
  620. elm_object_text_set(popup, "It is expected in 12 hours");
  621. else
  622. elm_object_text_set(popup, "It is expected in a day");
  623.  
  624. /* Pop-up is maintained for 2 seconds */
  625. elm_popup_timeout_set(popup, TIME_FOR_POPUP);
  626. evas_object_show(popup);
  627. }
  628. }
  629.  
  630. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : Exit the cb_add_periodic_sync()");
  631. }
  632.  
  633.  
  634. /*
  635. * Callback for operating data change sync job
  636. * This function is a process of calling sync_manager_add_data_change_sync_job()
  637. * Press "Start Sync" button with "Sync types" as "Data Change Sync"
  638. */
  639. static void
  640. cb_add_data_change_sync(void *pData, Evas_Object *pObj, void *pEvent_info)
  641. {
  642. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : Request data change sync");
  643.  
  644. /*
  645. * Depending whether account is set, method of calling the API is decided
  646. * Below process includes getting account which is set and using it
  647. */
  648. int ret = SYNC_ERROR_NONE, idx = 0;
  649. if (is_accountless) {
  650. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : request accountless Data Change Sync");
  651.  
  652. /*
  653. * This logic is used to store data change sync job id
  654. * Because sync capabilities are six kinds, they should be stored
  655. * for managing the multiple of registered data change sync jobs
  656. */
  657. for (idx = 0; idx < NUM_OF_CAPABILITY; idx++) {
  658. if (data_change_id[idx] == -1) {
  659. ret = sync_manager_add_data_change_sync_job(NULL, sync_capability, sync_option, NULL, &data_change_sync_job_id);
  660. data_change_id[idx] = data_change_sync_job_id;
  661. dlog_print(DLOG_INFO, LOG_TAG, "[accountless case] restored data_change_id[%d] = %d", idx, data_change_id[idx]);
  662. break;
  663. } else {
  664. if (idx == NUM_OF_CAPABILITY - 1) {
  665. dlog_print(DLOG_INFO, LOG_TAG, "data_change_id[idx] is full");
  666. break;
  667. }
  668. continue;
  669. }
  670. }
  671. } else {
  672. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : request Data Change Sync with an account");
  673. dlog_print(DLOG_INFO, LOG_TAG, "Account Id : [%d]", account_id);
  674. /* Query account by using account ID */
  675. ret = account_query_account_by_account_id(account_id, &account);
  676. if (ret != ACCOUNT_ERROR_NONE)
  677. dlog_print(DLOG_INFO, LOG_TAG, "account_query_account_by_account_id() is failed [%d : %s]", ret, get_error_message(ret));
  678.  
  679. /*
  680. * This logic is used to store data change sync job id
  681. * Because sync capabilities are six kinds and they should be stored
  682. * for managing the multiple of registered data change sync jobs
  683. */
  684. for (idx = 0; idx < NUM_OF_CAPABILITY; idx++) {
  685. if (data_change_id[idx] == -1) {
  686. ret = sync_manager_add_data_change_sync_job(account, sync_capability, sync_option, NULL, &data_change_sync_job_id);
  687. data_change_id[idx] = data_change_sync_job_id;
  688. dlog_print(DLOG_INFO, LOG_TAG, "[account case] restored data_change_id[%d] = %d", idx, data_change_id[idx]);
  689. break;
  690. } else {
  691. if (idx == NUM_OF_CAPABILITY - 1) {
  692. dlog_print(DLOG_INFO, LOG_TAG, "data_change_id[idx] is full");
  693. break;
  694. }
  695. continue;
  696. }
  697. }
  698. }
  699.  
  700. if (ret != SYNC_ERROR_NONE) {
  701. dlog_print(DLOG_INFO, LOG_TAG, "sync_manager_add_data_change_sync_job() is failed [%d : %s]", ret, get_error_message(ret));
  702. } else {
  703. if (data_change_sync_job_id != -1)
  704. dlog_print(DLOG_INFO, LOG_TAG, "Sync manager added data change sync id [%d]", data_change_sync_job_id);
  705. }
  706.  
  707. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : Exit the cb_add_data_change_sync()");
  708. }
  709.  
  710.  
  711. /*
  712. * Callback for operating sync jobs when "Start Sync" button is pressed
  713. */
  714. static void
  715. cb_start_sync(void *data, Evas_Object *obj, void *event_info)
  716. {
  717. /* app_data */
  718. app_data_s *ad = NULL;
  719. ad = (app_data_s *) g_ad;
  720. if (ad == NULL) return;
  721.  
  722. /*
  723. * Depending on displayed_job, one of below callback functions will be invoked
  724. * or some UI will be shown for Data Changed Sync
  725. * - cb_add_on_demand_sync() for operating On Demand Sync
  726. * - cb_add_periodic_sync() for operating Periodic Sync
  727. */
  728. if (!strcmp(displayed_job, "On Demand Sync")) {
  729. cb_add_on_demand_sync(ad, NULL, NULL);
  730. } else if (!strcmp(displayed_job, "Periodic Sync")) {
  731. cb_add_periodic_sync(ad, NULL, NULL);
  732. } else {
  733. /* Flag for verifying whether user already uses a menu */
  734. if (is_enter == 2) return;
  735. is_enter++;
  736.  
  737. Elm_Object_Item *nf_it;
  738. Evas_Object *nf = data, *layout;
  739. layout = elm_layout_add(nf);
  740. ad->nf = nf;
  741.  
  742. /* Add path for edje file */
  743. char edj_path[PATH_MAX] = {0, };
  744. app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
  745. elm_layout_file_set(layout, edj_path, GRP_MAIN);
  746. ad->layout = layout;
  747.  
  748. Evas_Object *genlist;
  749. Elm_Object_Item *it;
  750. Elm_Genlist_Item_Class *itc;
  751. int idx;
  752.  
  753. itc = elm_genlist_item_class_new();
  754. /* This genlist type has only one line text */
  755. itc->item_style = "type1";
  756. /* Set text which can represent notice how to verify added data change sync job */
  757. itc->func.text_get = get_data_change_text;
  758. itc->func.del = gl_del_cb;
  759.  
  760. genlist = elm_genlist_add(nf);
  761. elm_genlist_block_count_set(genlist, MAX_NUM_LINE);
  762. elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
  763. elm_genlist_homogeneous_set(genlist, EINA_TRUE);
  764.  
  765. /* This logic is for appending genlist items */
  766. for (idx = 0; idx < NUM_OF_ITEMS; idx++) {
  767. data_id = calloc(sizeof(list_item_data_s), 1);
  768. data_id->index = idx;
  769. it = elm_genlist_item_append(genlist, itc, data_id, NULL, ELM_GENLIST_ITEM_NONE, NULL, nf);
  770. data_id->item = it;
  771. }
  772.  
  773. evas_object_smart_callback_add(genlist, "selected", genlist_selected_cb, NULL);
  774. elm_genlist_item_class_free(itc);
  775.  
  776. nf_it = elm_naviframe_item_push(nf, "Data Change Sync", NULL, NULL, genlist, NULL);
  777. cb_add_data_change_sync(ad, NULL, NULL);
  778.  
  779. elm_naviframe_item_pop_cb_set(nf_it, sync_job_naviframe_pop_cb, ad->nf);
  780. }
  781. }
  782.  
  783.  
  784. /*
  785. * Create an account handle for registering and managing sync job with account
  786. */
  787. static void
  788. create_account()
  789. {
  790. /* Create an account handle */
  791. int ret = account_create(&account);
  792. if (ret != ACCOUNT_ERROR_NONE) {
  793. dlog_print(DLOG_INFO, LOG_TAG, "account_create() is failed [%d : %s]", ret, get_error_message(ret));
  794. return;
  795. }
  796.  
  797. /* Set user name in the account handle */
  798. ret = account_set_user_name(account, USER_NAME);
  799. if (ret != ACCOUNT_ERROR_NONE) {
  800. dlog_print(DLOG_INFO, LOG_TAG, "account_set_user_name() is failed [%d : %s]", ret, get_error_message(ret));
  801. return;
  802. }
  803.  
  804. /* Set package name in the account handle */
  805. ret = account_set_package_name(account, PKG_NAME);
  806. if (ret != ACCOUNT_ERROR_NONE) {
  807. dlog_print(DLOG_INFO, LOG_TAG, "account_set_package_name() is failed [%d : %s]", ret, get_error_message(ret));
  808. return;
  809. }
  810.  
  811. /* Set Account Capabilities in the account handle for Calendar and Contact */
  812. ret = account_set_capability(account, ACCOUNT_SUPPORTS_CAPABILITY_CALENDAR, ACCOUNT_CAPABILITY_ENABLED);
  813. if (ret != ACCOUNT_ERROR_NONE)
  814. dlog_print(DLOG_INFO, LOG_TAG, "account_set_capability() for calendar is failed [%d : %s]", ret, get_error_message(ret));
  815. ret = account_set_capability(account, ACCOUNT_SUPPORTS_CAPABILITY_CONTACT, ACCOUNT_CAPABILITY_ENABLED);
  816. if (ret != ACCOUNT_ERROR_NONE)
  817. dlog_print(DLOG_INFO, LOG_TAG, "account_set_capability() for contact is failed [%d : %s]", ret, get_error_message(ret));
  818.  
  819. /* Set sync support on the account handle */
  820. ret = account_set_sync_support(account, ACCOUNT_SYNC_STATUS_IDLE);
  821. if (ret != ACCOUNT_ERROR_NONE) {
  822. dlog_print(DLOG_INFO, LOG_TAG, "account_set_sync_support() is failed [%d : %s]", ret, get_error_message(ret));
  823. return;
  824. }
  825.  
  826. /*
  827. * Insert the account handle into Account DB
  828. * If there is an account handle for the Sync Adapter already,
  829. * query it by using application ID
  830. */
  831. ret = account_insert_to_db(account, &account_id);
  832. if (ret == ACCOUNT_ERROR_DUPLICATED) {
  833. dlog_print(DLOG_INFO, LOG_TAG, "account is already exist and set properly");
  834. /* Query account id with application ID of SyncAdapter */
  835. ret = account_query_account_by_package_name(query_account_cb, SYNC_ADAPTER_APP_ID, NULL);
  836. if (ret == ACCOUNT_ERROR_NONE)
  837. dlog_print(DLOG_INFO, LOG_TAG, "account_query is success [%d]", ret);
  838. else
  839. dlog_print(DLOG_INFO, LOG_TAG, "account_query is failed [%d : %s]", ret, get_error_message(ret));
  840. } else if (ret != ACCOUNT_ERROR_NONE) {
  841. dlog_print(DLOG_INFO, LOG_TAG, "account_insert_to_db() is failed [%d : %s]", ret, get_error_message(ret));
  842. return;
  843. }
  844.  
  845. /* After creating account, is_accountless flag is set as false */
  846. is_accountless = false;
  847. }
  848.  
  849.  
  850. /*
  851. * Callback for creating or setting account handle
  852. * It is invoked when "Create an account" button is pressed on main menu
  853. */
  854. void
  855. on_create_account_sync_cb(void *data, Evas_Object *obj, void *event_info)
  856. {
  857. dlog_print(DLOG_INFO, LOG_TAG, "Enter the create_account()");
  858.  
  859. Evas_Object *nf = data;
  860. Evas_Object *win = nf, *popup;
  861.  
  862. popup = elm_popup_add(win);
  863. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  864. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  865. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  866.  
  867. /*
  868. * If there is no account ID is set, create_account() is called
  869. * Also, "Account creation completed" is popped up after creating an account
  870. * In the opposite case, "Account is already created" rises on bottom of the view
  871. */
  872. if (account_id == -1) {
  873. create_account();
  874. elm_object_text_set(popup, "Account creation completed");
  875. } else {
  876. create_account();
  877. elm_object_text_set(popup, "Account is already created");
  878. }
  879.  
  880. /* Pop-up is maintained for 2 seconds */
  881. elm_popup_timeout_set(popup, TIME_FOR_POPUP);
  882. evas_object_show(popup);
  883.  
  884. dlog_print(DLOG_INFO, LOG_TAG, "Setting account complete, Account ID = [%d]", account_id);
  885. }
  886.  
  887.  
  888. /*
  889. * Set accountless case for calling sync-manager APIs without Account
  890. */
  891. static void
  892. set_accountless()
  893. {
  894. dlog_print(DLOG_INFO, LOG_TAG, "Account ID is initialized");
  895. account_id = -1;
  896. is_accountless = true;
  897. }
  898.  
  899.  
  900. /*
  901. * Callback for unsetting account handle
  902. * It is invoked when "Set as accountless" button is pressed on main menu
  903. */
  904. void
  905. on_select_accountless_sync_cb(void *data, Evas_Object *obj, void *event_info)
  906. {
  907. dlog_print(DLOG_INFO, LOG_TAG, "Enter the select_accountless()");
  908.  
  909. Evas_Object *nf = data, *popup;
  910. Evas_Object *win = nf;
  911.  
  912. popup = elm_popup_add(win);
  913. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  914. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  915. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  916.  
  917. if (!is_accountless) {
  918. set_accountless();
  919. elm_object_text_set(popup, "Setting accountless completed");
  920. } else
  921. elm_object_text_set(popup, "Accountless is already set");
  922.  
  923. /* Pop-up is maintained for 2 seconds */
  924. elm_popup_timeout_set(popup, TIME_FOR_POPUP);
  925. evas_object_show(popup);
  926. }
  927.  
  928.  
  929. /*
  930. * Callback for storing and setting selected "Sync types"
  931. */
  932. static void
  933. sync_job_select_cb(void *data, Evas_Object *obj, void *event_info)
  934. {
  935. Evas_Object *genlist = ((list_menu_data_s *)data)->genlist;
  936. Evas_Object *popup = ((list_menu_data_s *)data)->popup;
  937. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  938.  
  939. int idx = (int)elm_object_item_data_get(item);
  940. dlog_print(DLOG_INFO, LOG_TAG, "Selected text sync_job_items[%d] : [%s]\n", idx, sync_job_items[idx]);
  941. /* Selected text is copied to displayable variable */
  942. snprintf(displayed_job, MAX_SIZE, "%s", sync_job_items[idx]);
  943.  
  944. item = elm_genlist_first_item_get(genlist);
  945. elm_genlist_item_update(item);
  946.  
  947. /*
  948. * Initialize index which is used to draw a new genlist view
  949. * as many as the number of genlist items
  950. */
  951. idx = 0;
  952. while (idx != (int)elm_genlist_items_count(genlist)) {
  953. item = elm_genlist_item_next_get(item);
  954. elm_genlist_item_update(item);
  955. idx++;
  956. }
  957.  
  958. evas_object_del(popup);
  959. }
  960.  
  961.  
  962. /*
  963. * Callback for storing and setting selected "Period interval types"
  964. */
  965. static void
  966. sync_interval_select_cb(void *data, Evas_Object *obj, void *event_info)
  967. {
  968. Evas_Object *genlist = ((list_menu_data_s *)data)->genlist;
  969. Evas_Object *popup = ((list_menu_data_s *)data)->popup;
  970. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  971.  
  972. int idx = (int)elm_object_item_data_get(item);
  973. dlog_print(DLOG_INFO, LOG_TAG, "Selected text sync_interval_items[%d] : [%s]\n", idx, sync_interval_items[idx]);
  974. /* Selected text is copied to displayable variable */
  975. snprintf(displayed_interval, MAX_SIZE, "%s", sync_interval_items[idx]);
  976.  
  977. /*
  978. * The sync_interval will be set depending on the text
  979. * It will be used to call sync_manager_add_periodic_sync_job() as parameter
  980. */
  981. if (!strcmp("every 30 minutes", displayed_interval))
  982. sync_interval = SYNC_PERIOD_INTERVAL_30MIN;
  983. else if (!strcmp("every an hour", displayed_interval))
  984. sync_interval = SYNC_PERIOD_INTERVAL_1H;
  985. else if (!strcmp("every 2 hours", displayed_interval))
  986. sync_interval = SYNC_PERIOD_INTERVAL_2H;
  987. else if (!strcmp("every 3 hours", displayed_interval))
  988. sync_interval = SYNC_PERIOD_INTERVAL_3H;
  989. else if (!strcmp("every 6 hours", displayed_interval))
  990. sync_interval = SYNC_PERIOD_INTERVAL_6H;
  991. else if (!strcmp("every 12 hours", displayed_interval))
  992. sync_interval = SYNC_PERIOD_INTERVAL_12H;
  993. else
  994. sync_interval = SYNC_PERIOD_INTERVAL_1DAY;
  995.  
  996. item = elm_genlist_first_item_get(genlist);
  997. elm_genlist_item_update(item);
  998.  
  999. /*
  1000. * Initialize index which is used to draw a new genlist view
  1001. * as many as the number of genlist items
  1002. */
  1003. idx = 0;
  1004. while (idx != (int)elm_genlist_items_count(genlist)) {
  1005. item = elm_genlist_item_next_get(item);
  1006. elm_genlist_item_update(item);
  1007. idx++;
  1008. }
  1009.  
  1010. evas_object_del(popup);
  1011. }
  1012.  
  1013.  
  1014. /*
  1015. * Callback for storing and setting selected "Capability types"
  1016. */
  1017. static void
  1018. sync_capability_select_cb(void *data, Evas_Object *obj, void *event_info)
  1019. {
  1020. Evas_Object *genlist = ((list_menu_data_s *)data)->genlist;
  1021. Evas_Object *popup = ((list_menu_data_s *)data)->popup;
  1022. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  1023.  
  1024. int idx = (int)elm_object_item_data_get(item);
  1025. dlog_print(DLOG_INFO, LOG_TAG, "Selected text sync_capability_items[%d] : [%s]\n", idx, sync_capability_items[idx]);
  1026. /* Selected text is copied to displayable variable */
  1027. snprintf(displayed_capability, MAX_SIZE, "%s", sync_capability_items[idx]);
  1028.  
  1029. /*
  1030. * The sync_capability will be set depending on the text
  1031. * It will be used to call sync_manager_add_data_change_sync_job() as parameter
  1032. */
  1033. if (!strcmp("Calendar", displayed_capability))
  1034. sync_capability = SYNC_SUPPORTS_CAPABILITY_CALENDAR;
  1035. else if (!strcmp("Contact", displayed_capability))
  1036. sync_capability = SYNC_SUPPORTS_CAPABILITY_CONTACT;
  1037. else if (!strcmp("Image", displayed_capability))
  1038. sync_capability = SYNC_SUPPORTS_CAPABILITY_IMAGE;
  1039. else if (!strcmp("Music", displayed_capability))
  1040. sync_capability = SYNC_SUPPORTS_CAPABILITY_MUSIC;
  1041. else if (!strcmp("Sound", displayed_capability))
  1042. sync_capability = SYNC_SUPPORTS_CAPABILITY_SOUND;
  1043. else
  1044. sync_capability = SYNC_SUPPORTS_CAPABILITY_VIDEO;
  1045.  
  1046. item = elm_genlist_first_item_get(genlist);
  1047. elm_genlist_item_update(item);
  1048.  
  1049. /*
  1050. * Initialize index which is used to draw a new genlist view
  1051. * as many as the number of genlist items
  1052. */
  1053. idx = 0;
  1054. while (idx != (int)elm_genlist_items_count(genlist)) {
  1055. item = elm_genlist_item_next_get(item);
  1056. elm_genlist_item_update(item);
  1057. idx++;
  1058. }
  1059.  
  1060. evas_object_del(popup);
  1061. }
  1062.  
  1063.  
  1064. /*
  1065. * Callback for storing and setting selected "Option types"
  1066. */
  1067. static void
  1068. sync_option_select_cb(void *data, Evas_Object *obj, void *event_info)
  1069. {
  1070. Evas_Object *genlist = ((list_menu_data_s *)data)->genlist;
  1071. Evas_Object *popup = ((list_menu_data_s *)data)->popup;
  1072. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  1073.  
  1074. int idx = 0;
  1075. idx = (int)elm_object_item_data_get(item);
  1076. dlog_print(DLOG_INFO, LOG_TAG, "Selected text sync_option_items[%d] : [%s]\n", idx, sync_option_items[idx]);
  1077. /* Selected text is copied to displayable variable */
  1078. snprintf(displayed_option, MAX_SIZE, "%s", sync_option_items[idx]);
  1079.  
  1080. if (!strcmp("Option None", displayed_option))
  1081. sync_option = SYNC_OPTION_NONE;
  1082. else if (!strcmp("Sync with Priority", displayed_option))
  1083. sync_option = SYNC_OPTION_EXPEDITED;
  1084. else if (!strcmp("Sync Once", displayed_option))
  1085. sync_option = SYNC_OPTION_NO_RETRY;
  1086. else
  1087. sync_option = SYNC_OPTION_EXPEDITED | SYNC_OPTION_NO_RETRY;
  1088.  
  1089. item = elm_genlist_first_item_get(genlist);
  1090. elm_genlist_item_update(item);
  1091.  
  1092. /*
  1093. * Initialize index which is used to draw a new genlist view
  1094. * as many as the number of genlist items
  1095. */
  1096. idx = 0;
  1097. while (idx != (int)elm_genlist_items_count(genlist)) {
  1098. item = elm_genlist_item_next_get(item);
  1099. elm_genlist_item_update(item);
  1100. idx++;
  1101. }
  1102.  
  1103. evas_object_del(popup);
  1104. }
  1105.  
  1106.  
  1107. /*
  1108. * Callback for getting text about the list of "Sync types"
  1109. */
  1110. static char*
  1111. sync_job_text_get_cb(void *data, Evas_Object *obj, const char *part)
  1112. {
  1113. int idx = (int)data;
  1114. return strdup(sync_job_items[idx]);
  1115. }
  1116.  
  1117.  
  1118. /*
  1119. * Callback for getting text about the list of "Period interval types"
  1120. */
  1121. static char*
  1122. sync_interval_text_get_cb(void *data, Evas_Object *obj, const char *part)
  1123. {
  1124. int idx = (int)data;
  1125. return strdup(sync_interval_items[idx]);
  1126. }
  1127.  
  1128.  
  1129. /*
  1130. * Callback for getting text about the list of "Capability types"
  1131. */
  1132. static char*
  1133. sync_capability_text_get_cb(void *data, Evas_Object *obj, const char *part)
  1134. {
  1135. int idx = (int)data;
  1136. return strdup(sync_capability_items[idx]);
  1137. }
  1138.  
  1139.  
  1140. /*
  1141. * Callback for getting text about the list of "Option types"
  1142. */
  1143. static char*
  1144. sync_option_text_get_cb(void *data, Evas_Object *obj, const char *part)
  1145. {
  1146. int idx = (int)data;
  1147. return strdup(sync_option_items[idx]);
  1148. }
  1149.  
  1150.  
  1151. /*
  1152. * Callback for showing pop-up list of "Sync types"
  1153. */
  1154. static void
  1155. on_sync_job_list_popup_cb(void *data, Evas_Object *obj, void *event_info)
  1156. {
  1157. dlog_print(DLOG_INFO, LOG_TAG, "Select Sync Job types");
  1158.  
  1159. static Elm_Genlist_Item_Class itc;
  1160. Evas_Object *box, *genlist, *popup;
  1161. Evas_Object *nf = ((list_menu_data_s *)data)->nf;
  1162. ((list_menu_data_s *)data)->genlist = (Evas_Object *)obj;
  1163.  
  1164. /* Pop-up object and its title is set as "Sync types" */
  1165. popup = elm_popup_add(nf);
  1166. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  1167. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  1168. elm_object_part_text_set(popup, "title,text", "Sync types");
  1169. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1170.  
  1171. /* Box object for including genlist */
  1172. box = elm_box_add(popup);
  1173. evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1174.  
  1175. genlist = elm_genlist_add(box);
  1176. evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1177. evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
  1178.  
  1179. /*
  1180. * Get text which are included on the list like below
  1181. * - "On Demand Sync"
  1182. * - "Periodic Sync"
  1183. * - "Data Change Sync"
  1184. */
  1185. itc.item_style = "default";
  1186. itc.func.text_get = sync_job_text_get_cb;
  1187. itc.func.content_get = NULL;
  1188. itc.func.state_get = NULL;
  1189. itc.func.del = NULL;
  1190.  
  1191. ((list_menu_data_s *)data)->popup = popup;
  1192.  
  1193. /*
  1194. * Once each item on the list is pressed,
  1195. * sync_job_select_cb() is invoked and the value is set depending on its text
  1196. */
  1197. int idx;
  1198. for (idx = 0; idx < NUM_OF_SYNC_JOB; idx++)
  1199. elm_genlist_item_append(genlist, &itc, (void *)idx, NULL, ELM_GENLIST_ITEM_GROUP, sync_job_select_cb, sync_job_md);
  1200.  
  1201. evas_object_show(genlist);
  1202. elm_box_pack_end(box, genlist);
  1203. evas_object_size_hint_min_set(box, -1, SIZE_OF_POPUP);
  1204. elm_object_content_set(popup, box);
  1205.  
  1206. evas_object_show(popup);
  1207. }
  1208.  
  1209.  
  1210. /*
  1211. * Callback for showing pop-up list of "Period interval types"
  1212. */
  1213. static void
  1214. on_sync_interval_list_popup_cb(void *data, Evas_Object *obj, void *event_info)
  1215. {
  1216. dlog_print(DLOG_INFO, LOG_TAG, "Select interval types");
  1217.  
  1218. /*
  1219. * Below if block is for enabling "Period interval types"
  1220. * It is only enabled when the "Sync types" is set as "Periodic Sync"
  1221. * On the other hand, "Sync types" is set as the other types,
  1222. * then, this pop-up list is disabled to press
  1223. */
  1224. if (!strcmp(displayed_job, "Periodic Sync")) {
  1225. static Elm_Genlist_Item_Class itc;
  1226. Evas_Object *box, *genlist, *popup;
  1227. Evas_Object *nf = ((list_menu_data_s *)data)->nf;
  1228. ((list_menu_data_s *)data)->genlist = (Evas_Object *)obj;
  1229.  
  1230. /* Pop-up object and its title is set as "Period interval types" */
  1231. popup = elm_popup_add(nf);
  1232. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  1233. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  1234. elm_object_part_text_set(popup, "title,text", "Period interval types");
  1235. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1236.  
  1237. /* Box object for including genlist */
  1238. box = elm_box_add(popup);
  1239. evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1240.  
  1241. genlist = elm_genlist_add(box);
  1242. evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1243. evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
  1244.  
  1245. /*
  1246. * Get text which are included on the list like below
  1247. * - "every 30 minutes"
  1248. * - "every an hour"
  1249. * - "every 2 hours"
  1250. * - "every 3 hours"
  1251. * - "every 6 hours"
  1252. * - "every 12 hours"
  1253. * - "every a day"
  1254. */
  1255. itc.item_style = "default";
  1256. itc.func.text_get = sync_interval_text_get_cb;
  1257. itc.func.content_get = NULL;
  1258. itc.func.state_get = NULL;
  1259. itc.func.del = NULL;
  1260.  
  1261. ((list_menu_data_s *)data)->popup = popup;
  1262.  
  1263. /*
  1264. * Once each item on the list is pressed,
  1265. * sync_interval_select_cb() is invoked and the value is set depending on its text
  1266. */
  1267. int idx;
  1268. for (idx = 0; idx < NUM_OF_INTERVAL; idx++)
  1269. elm_genlist_item_append(genlist, &itc, (void *)idx, NULL, ELM_GENLIST_ITEM_GROUP, sync_interval_select_cb, interval_md);
  1270.  
  1271. evas_object_show(genlist);
  1272. elm_box_pack_end(box, genlist);
  1273. evas_object_size_hint_min_set(box, -1, SIZE_OF_POPUP);
  1274. elm_object_content_set(popup, box);
  1275.  
  1276. evas_object_show(popup);
  1277. }
  1278. }
  1279.  
  1280.  
  1281. /*
  1282. * Callback for showing pop-up list of "Capability types"
  1283. */
  1284. static void
  1285. on_sync_capability_list_popup_cb(void *data, Evas_Object *obj, void *event_info)
  1286. {
  1287. dlog_print(DLOG_INFO, LOG_TAG, "Select capability types");
  1288.  
  1289. /*
  1290. * Below if block is for enabling "Capability types"
  1291. * It is only enabled when the "Sync types" is set as "Data Change Sync"
  1292. * On the other hand, "Sync types" is set as the other types,
  1293. * then, this pop-up list is disabled to press
  1294. */
  1295. if (!strcmp(displayed_job, "Data Change Sync")) {
  1296. static Elm_Genlist_Item_Class itc;
  1297. Evas_Object *box, *genlist, *popup;
  1298. Evas_Object *nf = ((list_menu_data_s *)data)->nf;
  1299. ((list_menu_data_s *)data)->genlist = (Evas_Object *)obj;
  1300.  
  1301. /* Pop-up object and its title is set as "Capability types" */
  1302. popup = elm_popup_add(nf);
  1303. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  1304. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  1305. elm_object_part_text_set(popup, "title,text", "Capability types");
  1306. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1307.  
  1308. /* Box object for including genlist */
  1309. box = elm_box_add(popup);
  1310. evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1311.  
  1312. genlist = elm_genlist_add(box);
  1313. evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1314. evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
  1315.  
  1316. /*
  1317. * Get text which are included on the list like below
  1318. * - "Calendar"
  1319. * - "Contact"
  1320. * - "Image"
  1321. * - "Music"
  1322. * - "Sound"
  1323. * - "Video"
  1324. */
  1325. itc.item_style = "default";
  1326. itc.func.text_get = sync_capability_text_get_cb;
  1327. itc.func.content_get = NULL;
  1328. itc.func.state_get = NULL;
  1329. itc.func.del = NULL;
  1330.  
  1331. ((list_menu_data_s *)data)->popup = popup;
  1332.  
  1333. /*
  1334. * Once each item on the list is pressed,
  1335. * sync_capability_select_cb() is invoked and the value is set depending on its text
  1336. */
  1337. int idx;
  1338. for (idx = 0; idx < NUM_OF_CAPABILITY; idx++)
  1339. elm_genlist_item_append(genlist, &itc, (void *)idx, NULL, ELM_GENLIST_ITEM_GROUP, sync_capability_select_cb, capability_md);
  1340.  
  1341. evas_object_show(genlist);
  1342. elm_box_pack_end(box, genlist);
  1343. evas_object_size_hint_min_set(box, -1, SIZE_OF_POPUP);
  1344. elm_object_content_set(popup, box);
  1345.  
  1346. evas_object_show(popup);
  1347. }
  1348. }
  1349.  
  1350.  
  1351. /*
  1352. * Callback for showing pop-up list of "Option types"
  1353. */
  1354. static void
  1355. on_sync_option_list_popup_cb(void *data, Evas_Object *obj, void *event_info)
  1356. {
  1357. dlog_print(DLOG_INFO, LOG_TAG, "Select option types");
  1358.  
  1359. static Elm_Genlist_Item_Class itc;
  1360. Evas_Object *box, *genlist, *popup;
  1361. Evas_Object *nf = ((list_menu_data_s *)data)->nf;
  1362. ((list_menu_data_s *)data)->genlist = (Evas_Object *)obj;
  1363.  
  1364. /* Pop-up object and its title is set as "Option types" */
  1365. popup = elm_popup_add(nf);
  1366. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  1367. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  1368. elm_object_part_text_set(popup, "title,text", "Option types");
  1369. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1370.  
  1371. /* Box object for including genlist */
  1372. box = elm_box_add(popup);
  1373. evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1374.  
  1375. genlist = elm_genlist_add(box);
  1376. evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1377. evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
  1378.  
  1379. /*
  1380. * Get text which are included on the list like below
  1381. * - "Option None"
  1382. * - "Sync with Priority"
  1383. * - "Sync Once"
  1384. * - "Sync Once with Priority"
  1385. */
  1386. itc.item_style = "default";
  1387. itc.func.text_get = sync_option_text_get_cb;
  1388. itc.func.content_get = NULL;
  1389. itc.func.state_get = NULL;
  1390. itc.func.del = NULL;
  1391.  
  1392. ((list_menu_data_s *)data)->popup = popup;
  1393.  
  1394. /*
  1395. * Once each item on the list is pressed,
  1396. * sync_option_select_cb() is invoked and the value is set depending on its text
  1397. */
  1398. int idx;
  1399. for (idx = 0; idx < NUM_OF_OPTION; idx++)
  1400. elm_genlist_item_append(genlist, &itc, (void *)idx, NULL, ELM_GENLIST_ITEM_GROUP, sync_option_select_cb, option_md);
  1401.  
  1402. evas_object_show(genlist);
  1403. elm_box_pack_end(box, genlist);
  1404. evas_object_size_hint_min_set(box, -1, SIZE_OF_POPUP);
  1405. elm_object_content_set(popup, box);
  1406.  
  1407. evas_object_show(popup);
  1408. }
  1409.  
  1410.  
  1411. /*
  1412. * Callback for drawing setting menu
  1413. * It is invoked when "Start sync with settings" is pressed on main UI
  1414. * It also includes a button for starting sync jobs,
  1415. * "Start Sync" is written on the button
  1416. * Once the button is pressed, the Sync Adapter conducts using sync-manager APIs
  1417. * depending on the "Sync types" which is set
  1418. */
  1419. void
  1420. on_select_settings_sync_cb(void *data, Evas_Object *obj, void *event_info)
  1421. {
  1422. /* Flag for verifying whether user already uses a menu */
  1423. if (is_enter) return;
  1424. is_enter++;
  1425.  
  1426. dlog_print(DLOG_INFO, LOG_TAG, "Enter the Start sync with settings");
  1427.  
  1428. /* app_data */
  1429. app_data_s *ad = NULL;
  1430. ad = (app_data_s *) g_ad;
  1431. if (ad == NULL) return;
  1432.  
  1433. Elm_Object_Item *nf_it, *it;
  1434. Evas_Object *nf = data, *layout, *scroller, *syncBtn, *genlist;
  1435. Elm_Genlist_Item_Class *itc;
  1436. ad->nf = nf;
  1437.  
  1438. scroller = create_scroller(nf);
  1439. layout = elm_layout_add(scroller);
  1440. evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1441.  
  1442. char edj_path[PATH_MAX] = {0, };
  1443. app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
  1444. elm_layout_file_set(layout, edj_path, GRP_MAIN);
  1445.  
  1446. ad->layout = layout;
  1447.  
  1448. genlist = elm_genlist_add(layout);
  1449. elm_genlist_block_count_set(genlist, MAX_NUM_LINE);
  1450. elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
  1451. elm_genlist_homogeneous_set(genlist, EINA_TRUE);
  1452. elm_object_part_content_set(layout, "genlist_tiny", genlist);
  1453. elm_object_content_set(scroller, layout);
  1454.  
  1455. itc = elm_genlist_item_class_new();
  1456. itc->item_style = "multiline";
  1457. itc->func.text_get = get_setting_menu_text;
  1458. itc->func.del = gl_del_cb;
  1459.  
  1460. /*
  1461. * This logic is for appending genlist items.
  1462. * Each line of the list is linked to callback functions for showing respective pop-up list
  1463. * Each pop-up list is based on respective menu data
  1464. */
  1465. int idx;
  1466. for (idx = 0; idx < NUM_OF_ITEMS; idx++) {
  1467. setting_id = calloc(sizeof(list_item_data_s), 1);
  1468. setting_id->type = 3;
  1469. setting_id->index = idx;
  1470. setting_id->item = it;
  1471.  
  1472. switch (idx) {
  1473. case 0:
  1474. sync_job_md = calloc(sizeof(list_menu_data_s), 1);
  1475. sync_job_md->nf = nf;
  1476. it = elm_genlist_item_append(genlist, itc, setting_id, NULL, ELM_GENLIST_ITEM_NONE, on_sync_job_list_popup_cb, sync_job_md);
  1477. break;
  1478. case 1:
  1479. interval_md = calloc(sizeof(list_menu_data_s), 1);
  1480. interval_md->nf = nf;
  1481. it = elm_genlist_item_append(genlist, itc, setting_id, NULL, ELM_GENLIST_ITEM_NONE, on_sync_interval_list_popup_cb, interval_md);
  1482. break;
  1483. case 2:
  1484. capability_md = calloc(sizeof(list_menu_data_s), 1);
  1485. capability_md->nf = nf;
  1486. it = elm_genlist_item_append(genlist, itc, setting_id, NULL, ELM_GENLIST_ITEM_NONE, on_sync_capability_list_popup_cb, capability_md);
  1487. break;
  1488. case 3:
  1489. option_md = calloc(sizeof(list_menu_data_s), 1);
  1490. option_md->nf = nf;
  1491. it = elm_genlist_item_append(genlist, itc, setting_id, NULL, ELM_GENLIST_ITEM_NONE, on_sync_option_list_popup_cb, option_md);
  1492. break;
  1493. default:
  1494. break;
  1495. }
  1496.  
  1497. setting_id->item = it;
  1498. }
  1499.  
  1500. evas_object_smart_callback_add(genlist, "selected", genlist_selected_cb, NULL);
  1501. elm_genlist_item_class_free(itc);
  1502.  
  1503. /* Button for stating sync jobs */
  1504. syncBtn = elm_button_add(layout);
  1505. elm_object_text_set(syncBtn, "Start Sync");
  1506. elm_object_part_content_set(layout, "sync_btn", syncBtn);
  1507.  
  1508. /*
  1509. * When you start sync job without setting for Account,
  1510. * any sync job won't be operated and
  1511. * pop-up message will be shown as "Select account mode first"
  1512. */
  1513. if (is_accountless || (account_id != -1))
  1514. evas_object_smart_callback_add(syncBtn, "clicked", cb_start_sync, nf);
  1515. else
  1516. evas_object_smart_callback_add(syncBtn, "clicked", notify_by_using_popup, nf);
  1517.  
  1518. evas_object_show(syncBtn);
  1519. ad->syncBtn = syncBtn;
  1520.  
  1521. nf_it = elm_naviframe_item_push(nf, "Start sync with settings", NULL, NULL, scroller, NULL);
  1522. elm_naviframe_item_pop_cb_set(nf_it, sync_job_naviframe_pop_cb, nf);
  1523. }
  1524.  
  1525.  
  1526. /*
  1527. * Callback for receiving the result of sync_manager_foreach_sync_job()
  1528. * This function can receive the result to search sync jobs respectively
  1529. * If there is sync_job_name in the result, On Demand or
  1530. * Periodic sync job ID is stored for managing them
  1531. * In the other case, Data Change sync job ID which is based on
  1532. * the value of sync_capability is stored
  1533. * Stored sync_job_id will be used to manage each sync job
  1534. */
  1535. bool
  1536. 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)
  1537. {
  1538. char sync_job_info[MAX_SIZE], *value = NULL;
  1539. memset(sync_job_info, 0, sizeof(sync_job_info));
  1540.  
  1541. /*
  1542. * Below text are stored in sync_job_info is used to represent their list
  1543. * When you press "Manage sync jobs" on main UI with registering sync job, the list is shown
  1544. * This function is called repeatedly until all of the sync jobs are printed
  1545. */
  1546. if (sync_job_name) {
  1547. if (!strcmp(sync_job_name, "OnDemand")) {
  1548. bundle_get_str(sync_job_user_data, "option", &value);
  1549. on_demand_sync_job_id = sync_job_id;
  1550. } else if (!strcmp(sync_job_name, "Periodic")) {
  1551. bundle_get_str(sync_job_user_data, "interval", &value);
  1552. periodic_sync_job_id = sync_job_id;
  1553. }
  1554. sprintf(sync_job_info, "[%d] %s %s", sync_job_id, strdup(sync_job_name), strdup(value));
  1555. } else if (sync_capability) {
  1556. if (!strcmp(sync_capability, SYNC_SUPPORTS_CAPABILITY_CALENDAR))
  1557. sprintf(sync_job_info, "[%d] Data Change for %s", sync_job_id, strdup("Calendar"));
  1558. else if (!strcmp(sync_capability, SYNC_SUPPORTS_CAPABILITY_CONTACT))
  1559. sprintf(sync_job_info, "[%d] Data Change for %s", sync_job_id, strdup("Contact"));
  1560. else if (!strcmp(sync_capability, SYNC_SUPPORTS_CAPABILITY_IMAGE))
  1561. sprintf(sync_job_info, "[%d] Data Change for %s", sync_job_id, strdup("Image"));
  1562. else if (!strcmp(sync_capability, SYNC_SUPPORTS_CAPABILITY_MUSIC))
  1563. sprintf(sync_job_info, "[%d] Data Change for %s", sync_job_id, strdup("Music"));
  1564. else if (!strcmp(sync_capability, SYNC_SUPPORTS_CAPABILITY_SOUND))
  1565. sprintf(sync_job_info, "[%d] Data Change for %s", sync_job_id, strdup("Sound"));
  1566. else if (!strcmp(sync_capability, SYNC_SUPPORTS_CAPABILITY_VIDEO))
  1567. sprintf(sync_job_info, "[%d] Data Change for %s", sync_job_id, strdup("Video"));
  1568. } else if (cnt_sync_jobs == 0) {
  1569. return true;
  1570. }
  1571.  
  1572. int idx, temp_idx = 0;
  1573. for (idx = 0; idx < MAX_NUM; idx++) {
  1574. if (list_of_sync_jobs[idx][0] == '\0') {
  1575. remove_sync_job[idx] = sync_job_id;
  1576. temp_idx = idx;
  1577. break;
  1578. }
  1579. }
  1580. strcpy(list_of_sync_jobs[temp_idx], sync_job_info);
  1581.  
  1582. /* Count the entire number of registered sync jobs */
  1583. cnt_sync_jobs++;
  1584.  
  1585. return true;
  1586. }
  1587.  
  1588.  
  1589. /*
  1590. * Declare on_manage_sync_jobs_cb() for calling it
  1591. * in on_select_manage_sync_job_cb()
  1592. */
  1593. void on_manage_sync_jobs_cb(void *data, Evas_Object *obj, void *event_info);
  1594.  
  1595.  
  1596. /*
  1597. * Callback is invoked when "Manage sync jobs" is pressed on main UI
  1598. */
  1599. static void
  1600. on_select_manage_sync_jobs_cb(void *data, Evas_Object *obj, void *event_info)
  1601. {
  1602. /* Flag for verifying whether user already uses a menu */
  1603. if (is_enter) return;
  1604. is_enter++;
  1605.  
  1606. /*
  1607. * Initialize is_all_checked flag
  1608. * Also, list_of_remove_sync_job should be initialized for storing renewed sync job list
  1609. */
  1610. is_all_checked = false;
  1611. memset(list_of_remove_sync_job, false, sizeof(list_of_remove_sync_job));
  1612.  
  1613. /*
  1614. * Call below function for using sync_manager_foreach_sync_job()
  1615. * to search all of the registered sync jobs.
  1616. */
  1617. on_manage_sync_jobs_cb(data, obj, event_info);
  1618. }
  1619.  
  1620.  
  1621. /*
  1622. * Callback is invoked when "Select all" button
  1623. * on upper right side of "Manage sync jobs" naviframe is pressed.
  1624. */
  1625. void
  1626. on_select_all_sync_jobs_cb(void *data, Evas_Object *obj, void *event_info)
  1627. {
  1628. Evas_Object *genlist = (Evas_Object *)data, *button = obj;
  1629. Elm_Object_Item *it = (Elm_Object_Item *)event_info;
  1630.  
  1631. /*
  1632. * Depending on the state of is_all_checked,
  1633. * "Select all" button is toggled to "Deselect all".
  1634. * Likewise, in the opposite case, the text is toggled.
  1635. */
  1636. if (!is_all_checked) {
  1637. if ((int)elm_genlist_items_count(genlist) != 0) {
  1638. is_all_checked = true;
  1639. elm_object_text_set(button, "Deselect all");
  1640. memset(list_of_remove_sync_job, true, sizeof(list_of_remove_sync_job));
  1641. dlog_print(DLOG_INFO, LOG_TAG, "[%d] items are checked", (int)elm_genlist_items_count(genlist));
  1642. dlog_print(DLOG_INFO, LOG_TAG, "All of the sync jobs are checked");
  1643. }
  1644. } else {
  1645. is_all_checked = false;
  1646. elm_object_text_set(button, "Select all");
  1647. memset(list_of_remove_sync_job, false, sizeof(list_of_remove_sync_job));
  1648. dlog_print(DLOG_INFO, LOG_TAG, "[%d] items are unchecked", (int)elm_genlist_items_count(genlist));
  1649. }
  1650.  
  1651. it = elm_genlist_first_item_get(genlist);
  1652. elm_genlist_item_selected_get(it);
  1653. elm_genlist_item_update(it);
  1654.  
  1655. /* Update the state of genlist */
  1656. int idx = 0;
  1657. while (idx != (int)elm_genlist_items_count(genlist)) {
  1658. it = elm_genlist_item_next_get(it);
  1659. elm_genlist_item_selected_get(it);
  1660. elm_genlist_item_update(it);
  1661. idx++;
  1662. }
  1663. }
  1664.  
  1665.  
  1666. /*
  1667. * Callback for removing selected sync job
  1668. */
  1669. void
  1670. on_remove_selected_sync_jobs_cb(void *data, Evas_Object *obj, void *event_info)
  1671. {
  1672. dlog_print(DLOG_INFO, LOG_TAG, "Enter remove selected sync jobs");
  1673.  
  1674. Evas_Object *nf = (Evas_Object *)data;
  1675. int idx, idx2;
  1676.  
  1677. /*
  1678. * If "Remove" button is pressed without selected any sync job,
  1679. * pop-up text, "Select any sync jobs first" rises on bottom of the view
  1680. */
  1681. for (idx = 0; idx < cnt_sync_jobs; idx++) {
  1682. if (list_of_remove_sync_job[idx])
  1683. break;
  1684. else if (idx == cnt_sync_jobs-1) {
  1685. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : select any sync jobs first");
  1686.  
  1687. Evas_Object *popup, *win = nf;
  1688.  
  1689. popup = elm_popup_add(win);
  1690. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  1691. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  1692. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1693.  
  1694. elm_object_text_set(popup, "Select any sync jobs first");
  1695.  
  1696. /* Pop-up is maintained for 2 seconds */
  1697. elm_popup_timeout_set(popup, TIME_FOR_POPUP);
  1698. evas_object_show(popup);
  1699. return;
  1700. }
  1701. }
  1702.  
  1703. /*
  1704. * Registered sync jobs can be removed by using sync_manager_remove_sync_job()
  1705. * with stored Sync Job ID in advance
  1706. * After removing a sync job, variable which is used to store Sync Job ID should be initialized
  1707. */
  1708. for (idx = 0; idx < cnt_sync_jobs; idx++) {
  1709. if (list_of_remove_sync_job[idx]) {
  1710. sync_manager_remove_sync_job(remove_sync_job[idx]);
  1711. list_of_remove_sync_job[idx] = false;
  1712. dlog_print(DLOG_INFO, LOG_TAG, "Removed sync job: [%d]", remove_sync_job[idx]);
  1713. }
  1714. for (idx2 = 0; idx2 < NUM_OF_CAPABILITY; idx2++) {
  1715. if (data_change_id[idx2] == remove_sync_job[idx]) {
  1716. data_change_id[idx2] = -1;
  1717. break;
  1718. }
  1719. }
  1720. remove_sync_job[idx] = -1;
  1721. }
  1722.  
  1723. if (is_all_checked) {
  1724. /*
  1725. * If "Remove" button is pressed with all item checked,
  1726. * all of the Data Change Sync Job IDs should be initialized
  1727. */
  1728. memset(data_change_id, -1, sizeof(data_change_id));
  1729. /*
  1730. * It would be good to remove account information also
  1731. * when all of the sync jobs which are registered through the Sync Adapter are removed
  1732. * Because this application can change account mode freely
  1733. */
  1734. int ret = account_delete_from_db_by_package_name(SYNC_ADAPTER_APP_ID);
  1735. if (ret == ACCOUNT_ERROR_NONE) {
  1736. dlog_print(DLOG_INFO, LOG_TAG, "Account DB is deleted successfully");
  1737. if (account) {
  1738. ret = account_destroy(account);
  1739. if (ret == ACCOUNT_ERROR_NONE)
  1740. dlog_print(DLOG_INFO, LOG_TAG, "Account handle is removed successfully");
  1741. }
  1742. }
  1743. /* Initialize account ID which is no longer used */
  1744. account_id = -1;
  1745. }
  1746.  
  1747. /* Initialize Sync Job ID */
  1748. on_demand_sync_job_id = -1;
  1749. periodic_sync_job_id = -1;
  1750.  
  1751. elm_naviframe_item_pop(nf);
  1752.  
  1753. /* Call below function again to draw renewed UI after removing sync jobs */
  1754. on_select_manage_sync_jobs_cb(data, obj, event_info);
  1755. }
  1756.  
  1757.  
  1758. /*
  1759. * Callback for calling sync_manager_foreach_sync_job()
  1760. * and drawing UI to contain the result on genlist.
  1761. */
  1762. void
  1763. on_manage_sync_jobs_cb(void *data, Evas_Object *obj, void *event_info)
  1764. {
  1765. dlog_print(DLOG_INFO, LOG_TAG, "Enter the Manage sync jobs");
  1766.  
  1767. /* app_data */
  1768. app_data_s *ad = NULL;
  1769. ad = (app_data_s *) g_ad;
  1770. if (ad == NULL) return;
  1771.  
  1772. Evas_Object *nf = data, *layout, *scroller, *removeBtn, *selectAllBtn, *genlist;
  1773. Elm_Object_Item *nf_it, *it;
  1774. Elm_Genlist_Item_Class *itc;
  1775. ad->nf = nf;
  1776.  
  1777. scroller = create_scroller(nf);
  1778. layout = elm_layout_add(scroller);
  1779. evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1780.  
  1781. char edj_path[PATH_MAX] = {0, };
  1782. app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
  1783. elm_layout_file_set(layout, edj_path, GRP_MAIN);
  1784. ad->layout = layout;
  1785.  
  1786. int idx, n_items;
  1787.  
  1788. genlist = elm_genlist_add(layout);
  1789. elm_genlist_block_count_set(genlist, MAX_NUM_LINE);
  1790. elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
  1791. elm_genlist_homogeneous_set(genlist, EINA_TRUE);
  1792. elm_object_part_content_set(layout, "genlist_tiny", genlist);
  1793. elm_object_content_set(scroller, layout);
  1794.  
  1795. memset(remove_sync_job, -1, sizeof(remove_sync_job));
  1796.  
  1797. int ret = sync_manager_foreach_sync_job(sync_adapter_sample_foreach_sync_job_cb, NULL);
  1798.  
  1799. for (idx = 0; idx < MAX_NUM; idx++) {
  1800. if (list_of_sync_jobs[idx][0] != '\0')
  1801. dlog_print(DLOG_INFO, LOG_TAG, "list_of_sync_jobs[%d] : %s", idx, list_of_sync_jobs[idx]);
  1802. }
  1803.  
  1804. itc = elm_genlist_item_class_new();
  1805. itc->item_style = "type1";
  1806. itc->func.content_get = get_content_registered_sync_jobs;
  1807. itc->func.text_get = get_text_registered_sync_jobs;
  1808. itc->func.del = gl_del_cb;
  1809.  
  1810. n_items = cnt_sync_jobs;
  1811.  
  1812. for (idx = 0; idx < n_items; idx++) {
  1813. foreach_id = calloc(sizeof(list_item_data_s), 1);
  1814. foreach_id->type = 6;
  1815. foreach_id->index = idx;
  1816. it = elm_genlist_item_append(genlist, itc, foreach_id, NULL, ELM_GENLIST_ITEM_TREE, NULL, nf);
  1817. foreach_id->item = it;
  1818. }
  1819.  
  1820. /* Add a button and initialize text as "Select all" on the button */
  1821. selectAllBtn = elm_button_add(nf);
  1822. elm_object_style_set(selectAllBtn, "naviframe/title_right");
  1823. elm_object_text_set(selectAllBtn, "Select all");
  1824. evas_object_show(selectAllBtn);
  1825. ad->selectAllBtn = selectAllBtn;
  1826.  
  1827. if (ret == SYNC_ERROR_NONE)
  1828. evas_object_show(genlist);
  1829. else
  1830. dlog_print(DLOG_INFO, LOG_TAG, "sync_manager_foreach_sync_job() is failed [%d : %s]", ret, get_error_message(ret));
  1831.  
  1832. elm_genlist_item_class_free(itc);
  1833.  
  1834. /*
  1835. * Set "Select all" button for checking all of the items
  1836. * If you press the button at the first time,
  1837. * text on the button is changed to "Deselect all" and all of the items are checked
  1838. * If the button is pressed again, the text is toggled as "Select all"
  1839. * and all of the items are unchecked
  1840. */
  1841. evas_object_smart_callback_add(genlist, "selected", genlist_selected_cb, selectAllBtn);
  1842. evas_object_smart_callback_add(selectAllBtn, "clicked", on_select_all_sync_jobs_cb, genlist);
  1843.  
  1844. /*
  1845. * Set "Remove" button for removing checked items
  1846. * The button is enabled only when there is sync job
  1847. * In the opposite case, it is shown as disabled
  1848. */
  1849. removeBtn = elm_button_add(layout);
  1850. elm_object_text_set(removeBtn, "Remove");
  1851. elm_object_part_content_set(layout, "remove_btn", removeBtn);
  1852. evas_object_smart_callback_add(removeBtn, "clicked", on_remove_selected_sync_jobs_cb, nf);
  1853. if (cnt_sync_jobs > 0)
  1854. elm_object_disabled_set(removeBtn, EINA_FALSE);
  1855. else
  1856. elm_object_disabled_set(removeBtn, EINA_TRUE);
  1857.  
  1858. evas_object_show(removeBtn);
  1859. ad->removeBtn = removeBtn;
  1860.  
  1861. /*
  1862. * If you want to check all the things on lists,
  1863. * just click the "Select all" button on upper right of the view
  1864. */
  1865. nf_it = elm_naviframe_item_push(nf, "Manage sync jobs", NULL, selectAllBtn, scroller, NULL);
  1866. elm_object_item_part_content_set(nf_it, "title_right_btn", selectAllBtn);
  1867. elm_naviframe_item_pop_cb_set(nf_it, foreach_naviframe_pop_cb, nf);
  1868. }
  1869.  
  1870.  
  1871. /*
  1872. * Draw the Sync Adapter's main menu
  1873. */
  1874. static void
  1875. create_sync_main_menu(app_data_s *ad)
  1876. {
  1877. /*
  1878. * The Sync Adapter should send request to launch the Sync Adapter Service
  1879. * Then, the Sync Adapter Service will set callback functions by using sync-adapter API
  1880. * Without below steps, the Sync Adapter can't receive the result of sync operation
  1881. * through the Sync Adapter Service
  1882. */
  1883. app_control_h app_control;
  1884. int ret = app_control_create(&app_control);
  1885. if (ret != APP_CONTROL_ERROR_NONE) {
  1886. dlog_print(DLOG_INFO, LOG_TAG, "Creating app_control handle is failed [%d : %s]", ret, get_error_message(ret));
  1887. return;
  1888. }
  1889. /* Set the Sync Adapter Service App ID for launching it */
  1890. ret = app_control_set_app_id(app_control, SYNC_ADAPTER_SERVICE_APP_ID);
  1891. if (ret != APP_CONTROL_ERROR_NONE) {
  1892. dlog_print(DLOG_INFO, LOG_TAG, "Setting app id is failed [%d : %s]", ret, get_error_message(ret));
  1893. return;
  1894. }
  1895. /* Send application launch request */
  1896. ret = app_control_send_launch_request(app_control, NULL, NULL);
  1897. if (ret == APP_CONTROL_ERROR_NONE)
  1898. dlog_print(DLOG_INFO, LOG_TAG, "Launching sync service app successfully [%s]", SYNC_ADAPTER_SERVICE_APP_ID);
  1899. else {
  1900. dlog_print(DLOG_INFO, LOG_TAG, "Launching sync service app is failed [%d : %s]", ret, get_error_message(ret));
  1901. return;
  1902. }
  1903.  
  1904. /* Initialize list to show it on the menu "Manage sync jobs" */
  1905. memset(list_of_sync_jobs, '\0', sizeof(list_of_sync_jobs));
  1906.  
  1907. Evas_Object *nf = ad->nf, *genlist;
  1908. Elm_Object_Item *nf_it, *it;
  1909. Elm_Genlist_Item_Class *itc;
  1910.  
  1911. itc = elm_genlist_item_class_new();
  1912. itc->item_style = "type1";
  1913. itc->func.text_get = get_main_menu_text;
  1914. itc->func.del = gl_del_cb;
  1915.  
  1916. genlist = elm_genlist_add(nf);
  1917. elm_genlist_block_count_set(genlist, MAX_NUM_LINE);
  1918. elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
  1919. elm_genlist_homogeneous_set(genlist, EINA_TRUE);
  1920.  
  1921. memset(data_change_id, -1, sizeof(data_change_id));
  1922.  
  1923. /* This logic is for appending genlist items */
  1924. int idx;
  1925. for (idx = 0; idx < NUM_OF_ITEMS; idx++) {
  1926. main_id = calloc(sizeof(list_item_data_s), 1);
  1927. main_id->index = idx;
  1928.  
  1929. switch (idx) {
  1930. case 0:
  1931. it = elm_genlist_item_append(genlist, itc, main_id, NULL, ELM_GENLIST_ITEM_NONE, on_create_account_sync_cb, nf);
  1932. break;
  1933. case 1:
  1934. it = elm_genlist_item_append(genlist, itc, main_id, NULL, ELM_GENLIST_ITEM_NONE, on_select_accountless_sync_cb, nf);
  1935. break;
  1936. case 2:
  1937. it = elm_genlist_item_append(genlist, itc, main_id, NULL, ELM_GENLIST_ITEM_NONE, on_select_settings_sync_cb, nf);
  1938. break;
  1939. case 3:
  1940. it = elm_genlist_item_append(genlist, itc, main_id, NULL, ELM_GENLIST_ITEM_NONE, on_select_manage_sync_jobs_cb, nf);
  1941. break;
  1942. default:
  1943. break;
  1944. }
  1945.  
  1946. main_id->item = it;
  1947. }
  1948. evas_object_smart_callback_add(genlist, "selected", genlist_selected_cb, NULL);
  1949. elm_genlist_item_class_free(itc);
  1950.  
  1951. nf_it = elm_naviframe_item_push(nf, "Sync Adapter", NULL, NULL, genlist, NULL);
  1952. elm_naviframe_item_pop_cb_set(nf_it, win_delete_request_cb, ad->win);
  1953. }
  1954.  
  1955.  
  1956. /*
  1957. * Create base GUI to include main menu
  1958. */
  1959. static void
  1960. create_base_gui(app_data_s *ad)
  1961. {
  1962. /* Window */
  1963. ad->win = elm_win_util_standard_add(PKG_NAME, PKG_NAME);
  1964. elm_win_conformant_set(ad->win, EINA_TRUE);
  1965. elm_win_autodel_set(ad->win, EINA_TRUE);
  1966.  
  1967. if (elm_win_wm_rotation_supported_get(ad->win)) {
  1968. int rots[4] = { 0, 90, 180, 270 };
  1969. elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
  1970. }
  1971.  
  1972. /* Conformant */
  1973. ad->conform = elm_conformant_add(ad->win);
  1974. elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
  1975. elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
  1976. evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1977. elm_win_resize_object_add(ad->win, ad->conform);
  1978. evas_object_show(ad->conform);
  1979.  
  1980. /* Base Layout */
  1981. ad->layout = elm_layout_add(ad->conform);
  1982. evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  1983. elm_layout_theme_set(ad->layout, "layout", "application", "default");
  1984. evas_object_show(ad->layout);
  1985. elm_object_content_set(ad->conform, ad->layout);
  1986.  
  1987. /* Naviframe */
  1988. ad->nf = elm_naviframe_add(ad->layout);
  1989. elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
  1990. elm_naviframe_event_enabled_set(ad->nf, EINA_TRUE);
  1991. eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
  1992. eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
  1993.  
  1994. /* Add sync main menu */
  1995. create_sync_main_menu(ad);
  1996.  
  1997. /* Show window after base GUI is set up */
  1998. evas_object_show(ad->win);
  1999. }
  2000.  
  2001.  
  2002. /*
  2003. * App create callback
  2004. */
  2005. static bool
  2006. app_create(void *data)
  2007. {
  2008. /*
  2009. * Hook to take necessary actions before main event loop starts
  2010. * Initialize UI resources and application's data
  2011. * If this function returns true, the main loop of application starts
  2012. * If this function returns false, the application is terminated
  2013. */
  2014. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : app_create is invoked");
  2015.  
  2016. app_data_s *ad = data;
  2017. create_base_gui(ad);
  2018.  
  2019. return true;
  2020. }
  2021.  
  2022.  
  2023. /*
  2024. * App terminate callback
  2025. */
  2026. static void
  2027. app_terminate(void *data)
  2028. {
  2029. /* Release all resources */
  2030. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : app_terminate is invoked");
  2031. account_destroy(account);
  2032. }
  2033.  
  2034.  
  2035. /*
  2036. * App control callback
  2037. */
  2038. static void
  2039. app_control(app_control_h app_control, void *data)
  2040. {
  2041. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : app_control is invoked");
  2042.  
  2043. /* Get app control operation */
  2044. char *operation;
  2045. int ret = app_control_get_operation(app_control, &operation);
  2046. if (ret != APP_CONTROL_ERROR_NONE) {
  2047. dlog_print(DLOG_INFO, LOG_TAG, "Get app control operation is failed [%d : %s]", ret, get_error_message(ret));
  2048. return;
  2049. } else {
  2050. dlog_print(DLOG_INFO, LOG_TAG, "App Control operation [%s]", operation);
  2051. }
  2052.  
  2053. /*
  2054. * In the case of non-default App Control operation,
  2055. * it has a respective operation depending on its kind of sync jobs
  2056. */
  2057. if (strcmp(operation, "http://tizen.org/appcontrol/operation/default")) {
  2058. /*
  2059. * Below popup object for displaying the sort of sync jobs
  2060. * Pop-up is maintained during 2 seconds
  2061. */
  2062. Evas_Object *win = g_ad->nf, *popup;
  2063. popup = elm_popup_add(win);
  2064. elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
  2065. eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
  2066. evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  2067.  
  2068. /*
  2069. * Sync complete message will be popped up depending on the kind of sync jobs,
  2070. * On demand, Periodic, Data change sync job, which come from the Sync Adapter Service
  2071. */
  2072. if (operation && !strcmp(operation, "http://tizen.org/appcontrol/operation/on_demand_sync_complete"))
  2073. elm_object_text_set(popup, "On Demand Sync is completed");
  2074. else if (operation && !strcmp(operation, "http://tizen.org/appcontrol/operation/periodic_sync_complete"))
  2075. elm_object_text_set(popup, "Periodic Sync is completed");
  2076. else if (operation && !strcmp(operation, "http://tizen.org/appcontrol/operation/data_change_sync_complete"))
  2077. elm_object_text_set(popup, "Data Change Sync is completed");
  2078.  
  2079. /* Pop-up is maintained for 2 seconds */
  2080. if (strcmp(operation, "http://tizen.org/appcontrol/operation/account/add")
  2081. && strcmp(operation, "http://tizen.org/appcontrol/operation/account/configure")) {
  2082. elm_popup_timeout_set(popup, TIME_FOR_POPUP);
  2083. evas_object_show(popup);
  2084. }
  2085. }
  2086.  
  2087. dlog_print(DLOG_INFO, LOG_TAG, "Sync operation complete");
  2088. }
  2089.  
  2090.  
  2091. /*
  2092. * App pause callback
  2093. */
  2094. static void
  2095. app_pause(void *data)
  2096. {
  2097. /* Take necessary actions when application becomes invisible */
  2098. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : app_pause is invoked");
  2099. }
  2100.  
  2101.  
  2102. /*
  2103. * App resume callback
  2104. */
  2105. static void
  2106. app_resume(void *data)
  2107. {
  2108. /* Take necessary actions when application becomes visible */
  2109. dlog_print(DLOG_INFO, LOG_TAG, "Sync Adapter : app_resume is invoked");
  2110. }
  2111.  
  2112.  
  2113. /*
  2114. * App low battery callback
  2115. */
  2116. static void
  2117. ui_app_low_battery(app_event_info_h event_info, void *user_data)
  2118. {
  2119. /* APP_EVENT_LOW_BATTERY */
  2120. }
  2121.  
  2122.  
  2123. /*
  2124. * App low memory callback
  2125. */
  2126. static void
  2127. ui_app_low_memory(app_event_info_h event_info, void *user_data)
  2128. {
  2129. /* APP_EVENT_LOW_MEMORY */
  2130. }
  2131.  
  2132.  
  2133. /*
  2134. * App orientation changed callback
  2135. */
  2136. static void
  2137. ui_app_orient_changed(app_event_info_h event_info, void *user_data)
  2138. {
  2139. /* APP_EVENT_DEVICE_ORIENTATION_CHANGED */
  2140. return;
  2141. }
  2142.  
  2143.  
  2144. /*
  2145. * App language changed callback
  2146. */
  2147. static void
  2148. ui_app_lang_changed(app_event_info_h event_info, void *user_data)
  2149. {
  2150. /* APP_EVENT_LANGUAGE_CHANGED */
  2151. char *locale = NULL;
  2152. system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
  2153. elm_language_set(locale);
  2154. free(locale);
  2155. return;
  2156. }
  2157.  
  2158.  
  2159. /*
  2160. * App region format changed callback
  2161. */
  2162. static void
  2163. ui_app_region_changed(app_event_info_h event_info, void *user_data)
  2164. {
  2165. /* APP_EVENT_REGION_FORMAT_CHANGED */
  2166. }
  2167.  
  2168.  
  2169. /*
  2170. * Sync Adapter main()
  2171. */
  2172. int main(int argc, char *argv[])
  2173. {
  2174. app_data_s ad = {0,};
  2175. int ret = 0;
  2176.  
  2177. /* Life cycle callback structure */
  2178. ui_app_lifecycle_callback_s event_callback = {0,};
  2179. /* Event handler */
  2180. app_event_handler_h handlers[5] = {NULL, };
  2181.  
  2182. /* Set event callback functions */
  2183. event_callback.create = app_create;
  2184. event_callback.terminate = app_terminate;
  2185. event_callback.pause = app_pause;
  2186. event_callback.resume = app_resume;
  2187. event_callback.app_control = app_control;
  2188.  
  2189. /* Set low battery event */
  2190. ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
  2191. /* Set low memory event */
  2192. ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
  2193. /* Set orientation changed event */
  2194. ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
  2195. /* Set language changed event */
  2196. ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
  2197. /* Set region format changed event */
  2198. ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
  2199. ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
  2200.  
  2201. g_ad = &ad;
  2202. ret = ui_app_main(argc, argv, &event_callback, &ad);
  2203. if (ret != APP_ERROR_NONE)
  2204. dlog_print(DLOG_ERROR, LOG_TAG, "ui_app_main() is failed = [%d : %s]", ret, get_error_message(ret));
  2205.  
  2206. return ret;
  2207. }