Tizen 2.0 Release
[framework/system/sync-agent.git] / src / fw-plugins / common-public / account / src / plugin_interface.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <stdio.h>              /*for debugging */
19 #include <string.h>
20
21 #include <account.h>
22
23 #include "account/service.h"
24
25 /* for log */
26 #include "utility/sync_util.h"
27 #include "utility/fw_file.h"
28
29 #include "plugin/account_interface.h"
30
31 #ifndef EXPORT_API
32 #define EXPORT_API __attribute__ ((visibility("default")))
33 #endif
34
35 #ifndef SYNC_AGENT_LOG
36 #undef LOG_TAG
37 #define LOG_TAG "PLUGIN_ACCOUNT"
38 #endif
39
40 /*
41  * Key          : DEFAULT_ACCOUNT_PLUGIN_FOLDER/.[Agent Name]_Service_[Service_Type]_[FW AccountID]
42  * Value        : Service Account ID
43  */
44 #define ACCOUNT_ID_SERVICE_ACCOUNT_ID   ".%s_service_%d_%d"
45
46 /*
47  * KEY : DEFAULT_ACCOUNT_PLUGIN_FOLDER/.[Agent Name]_FW_[Service_Type]_[Service AccountID]_[Index]
48  * Value : FW Account ID
49  */
50 #define ACCOUNT_ID_FW_ACCOUNT_ID        ".%s_fw_%d_%d_%d"
51
52 /*
53  * Key          : DEFAULT_ACCOUNT_PLUGIN_FOLDER/.[Agent Name]_FW_Count_[Service_Type]_[Service AccountID]
54  * Value        : FW Account Count Included in one service Account
55  */
56 #define ACCOUNT_ID_FW_ACCOUNT_COUNT             ".%s_fw_count_%d_%d"
57
58 #define FW_CONTACT              0
59 #define FW_CALENDAR     1
60 #define FW_MEMO                 2
61 #define FW_CONTENT_COUNT        3
62
63 #define MAX_ACCOUNT_COUNT       20
64
65 static const char *agent_name = 0;
66
67 static void _set_account_id_service(int service_type, int fw_account_id, int service_account_id);
68
69 static void _arrange_account_id_fw(int service_type, int service_account_id, int index, int fw_account_id);
70
71 static void _set_account_id_fw(int service_type, int service_account_id, int count, int fw_account_id);
72
73 static int _increase_account_count_fw(int service_type, int service_account_id);
74
75 static int _get_account_count_fw(int service_type, int service_account_id);
76
77 static void _unset_account_id_service(int service_type, int fw_account_id);
78
79 static void _unset_account_id_fw(int service_type, int service_account_id, int index);
80
81 static int _decrease_account_count_fw(int service_type, int service_account_id);
82
83 static int _get_account_info(int service_account_id, sync_agent_service_account_info_s ** account_info);
84
85 EXPORT_API void sync_agent_plugin_set_account_repository_name(const char *input_agent_name)
86 {
87         _EXTERN_FUNC_ENTER;
88
89         agent_name = input_agent_name;
90
91         _EXTERN_FUNC_EXIT;
92 }
93
94 EXPORT_API void sync_agent_plugin_add_platform_account(int fw_account_id)
95 {
96         _EXTERN_FUNC_ENTER;
97
98         int slp_id = -1;
99
100         int slp_contact_id = sync_agent_plugin_get_service_account_id(FW_CONTACT, fw_account_id);
101         int slp_calendar_id = sync_agent_plugin_get_service_account_id(FW_CALENDAR, fw_account_id);
102         int slp_memo_id = sync_agent_plugin_get_service_account_id(FW_MEMO, fw_account_id);
103
104         /*
105          * if not existed ?
106          */
107         if (slp_contact_id == -100) {
108                 _set_account_id_service(FW_CONTACT, fw_account_id, slp_id);
109                 int contact_index = _increase_account_count_fw(FW_CONTACT, slp_id);
110                 if (contact_index < 1 || contact_index > MAX_ACCOUNT_COUNT) {
111                         _DEBUG_ERROR("[account_plugIn] _increase_account_count_fw() returned OUT OF BOUND int !!!");
112                         return;
113                 }
114                 _set_account_id_fw(FW_CONTACT, slp_id, contact_index, fw_account_id);
115         }
116
117         if (slp_calendar_id == -100) {
118                 _set_account_id_service(FW_CALENDAR, fw_account_id, slp_id);
119                 int calendar_index = _increase_account_count_fw(FW_CALENDAR, slp_id);
120                 if (calendar_index < 1 || calendar_index > MAX_ACCOUNT_COUNT) {
121                         _DEBUG_ERROR("[account_plugIn] _increase_account_count_fw() returned OUT OF BOUND int !!!");
122                         return;
123                 }
124                 _set_account_id_fw(FW_CALENDAR, slp_id, calendar_index, fw_account_id);
125         }
126
127         if (slp_memo_id == -100) {
128                 _set_account_id_service(FW_MEMO, fw_account_id, slp_id);
129                 int memo_index = _increase_account_count_fw(FW_MEMO, slp_id);
130                 if (memo_index < 1 || memo_index > MAX_ACCOUNT_COUNT) {
131                         _DEBUG_ERROR("[account_plugIn] _increase_account_count_fw() returned OUT OF BOUND int !!!");
132                         return;
133                 }
134                 _set_account_id_fw(FW_MEMO, slp_id, memo_index, fw_account_id);
135         }
136
137         _EXTERN_FUNC_EXIT;
138 }
139
140 EXPORT_API void sync_agent_plugin_set_platform_account_service(int fw_account_id, int service_type, int service_account_id)
141 {
142         _EXTERN_FUNC_ENTER;
143
144         _set_account_id_service(service_type, fw_account_id, service_account_id);
145
146         int service_index = _increase_account_count_fw(service_type, service_account_id);
147         if (service_index < 1 || service_index > MAX_ACCOUNT_COUNT) {
148                 _DEBUG_ERROR("[account_plugIn] _increase_account_count_fw() returned OUT OF BOUND int !!!");
149                 return;
150         }
151         _set_account_id_fw(service_type, service_account_id, service_index, fw_account_id);
152
153         _EXTERN_FUNC_EXIT;
154 }
155
156 EXPORT_API void sync_agent_plugin_delete_platform_account(int fw_account_id)
157 {
158         _EXTERN_FUNC_ENTER;
159
160         _DEBUG_INFO("fw_account_id = %d", fw_account_id);
161         int deleted = 0;
162
163         int i = 0;
164         for (; i < FW_CONTENT_COUNT; i++) {
165
166                 deleted = 0;
167                 int service_account_id = sync_agent_plugin_get_service_account_id(i, fw_account_id);
168                 _DEBUG_INFO("service_account_id =%d", service_account_id);
169
170                 _unset_account_id_service(i, fw_account_id);
171
172                 int count = _get_account_count_fw(i, service_account_id);
173                 if (count < 0 || count > MAX_ACCOUNT_COUNT) {
174                         _DEBUG_ERROR("[account_plugIn] _get_account_count_fw() returned OUT OF BOUND int !!!");
175                         return;
176                 }
177
178                 _DEBUG_INFO("count =%d", count);
179                 int k = 0;
180                 for (; k < count; k++) {
181                         int target_fw_account_id = sync_agent_plugin_get_fw_account_id(i, service_account_id, k);
182                         _DEBUG_INFO("target_fw_account_id =%d", target_fw_account_id);
183                         if (target_fw_account_id == fw_account_id) {
184                                 _unset_account_id_fw(i, service_account_id, k);
185                                 _decrease_account_count_fw(i, service_account_id);
186                                 _DEBUG_INFO("deleted !!!");
187                                 deleted = 1;
188                         } else {
189                                 if (deleted == 1)
190                                         _arrange_account_id_fw(i, service_account_id, k, target_fw_account_id);
191                         }
192                 }
193         }
194
195         _EXTERN_FUNC_EXIT;
196 }
197
198 EXPORT_API void sync_agent_plugin_delete_platform_account_service(int fw_account_id, int service_type)
199 {
200         _EXTERN_FUNC_ENTER;
201
202         _unset_account_id_service(service_type, fw_account_id);
203
204         _EXTERN_FUNC_EXIT;
205 }
206
207 EXPORT_API int sync_agent_plugin_has_platform_account_service(int fw_account_id, int service_type)
208 {
209         _EXTERN_FUNC_ENTER;
210
211         int result = sync_agent_plugin_get_service_account_id(service_type, fw_account_id);
212         if (result == -100) {
213                 _EXTERN_FUNC_EXIT;
214                 return 0;
215         }
216
217         _EXTERN_FUNC_EXIT;
218         return 1;
219 }
220
221 EXPORT_API int sync_agent_plugin_get_service_account_id(int service_type, int fw_account_id)
222 {
223         _EXTERN_FUNC_ENTER;
224
225         int service_account_id;
226         _DEBUG_INFO("[account_plugIn] service_type : %d\n", service_type);
227         _DEBUG_INFO("[account_plugIn] fw_account_id : %d\n", fw_account_id);
228
229         char path[100];
230         snprintf(path, sizeof(path), ACCOUNT_ID_SERVICE_ACCOUNT_ID, agent_name, service_type, fw_account_id);
231
232         if (!sync_agent_get_int_from_file(path, &service_account_id)) {
233                 _DEBUG_ERROR("[account_plugIn] __get_int_from_file FAIL\n");
234                 return -100;
235         }
236
237         _DEBUG_INFO("[account_plugIn] path : %s\n", path);
238         _DEBUG_INFO("[account_plugIn] service_account_id : %d\n", service_account_id);
239
240         _EXTERN_FUNC_EXIT;
241
242         return service_account_id;
243 }
244
245 EXPORT_API int sync_agent_plugin_get_fw_account_id(int service_type, int service_account_id, int index)
246 {
247         _EXTERN_FUNC_ENTER;
248
249         char path[100];
250         snprintf(path, sizeof(path), ACCOUNT_ID_FW_ACCOUNT_ID, agent_name, service_type, service_account_id, index);
251
252         int fw_account_id;
253         if (!sync_agent_get_int_from_file(path, &fw_account_id)) {
254                 _DEBUG_ERROR("[account_plugIn] __get_int_from_file FAIL\n");
255                 return -1;
256         }
257
258         _EXTERN_FUNC_EXIT;
259
260         return fw_account_id;
261 }
262
263 EXPORT_API int sync_agent_plugin_get_service_account_info(int fw_account_id, int service_type, sync_agent_service_account_info_s ** account_info)
264 {
265         _EXTERN_FUNC_ENTER;
266
267         retvm_if(*account_info == NULL, 0, "*account_info is NULL. FAIL !!!");
268
269         int service_account_id = sync_agent_plugin_get_service_account_id(service_type, fw_account_id);
270         _DEBUG_INFO("[account_plugIn] service_account_id : %d\n", service_account_id);
271         if (service_account_id == -100) {
272                 return 0;
273         }
274
275         int result = _get_account_info(service_account_id, account_info);
276
277         if (result == 1) {
278                 _DEBUG_INFO("[account_plugIn] account_info->type : %d\n", (*account_info)->type);
279                 _DEBUG_INFO("[account_plugIn] account_info->email : %s\n", (*account_info)->email);
280         } else {
281                 _DEBUG_ERROR("[account_plugIn] account_info is empty\n");
282                 _EXTERN_FUNC_EXIT;
283                 return 0;
284         }
285
286         _EXTERN_FUNC_EXIT;
287         return 1;
288 }
289
290 /******************************************* Impl static function ********************************************/
291
292 static void _set_account_id_service(int service_type, int fw_account_id, int service_account_id)
293 {
294         _INNER_FUNC_ENTER;
295
296         char path[100];
297         snprintf(path, sizeof(path), ACCOUNT_ID_SERVICE_ACCOUNT_ID, agent_name, service_type, fw_account_id);
298
299         if (!sync_agent_set_int_into_file(path, service_account_id))
300                 _DEBUG_ERROR("[account_plugIn] __set_int_into_file FAIL\n");
301
302         _DEBUG_TRACE("\n[account_plugIn] Sucess __set_int_into_file\n");
303         _DEBUG_TRACE("[account_plugIn] service_type : %d, fw_account_id : %d, service_account_id : %d\n\n", service_type, fw_account_id, service_account_id);
304
305         _INNER_FUNC_EXIT;
306 }
307
308 static void _arrange_account_id_fw(int service_type, int service_account_id, int index, int fw_account_id)
309 {
310         _INNER_FUNC_ENTER;
311
312         retm_if(index < 0, "index = %d", index);
313         _DEBUG_INFO("service_type = %d", service_type);
314         _DEBUG_INFO("service_account_id = %d", service_account_id);
315         _DEBUG_INFO("index = %d", index);
316         _DEBUG_INFO("fw_account_id = %d", fw_account_id);
317
318         char path[100];
319         snprintf(path, sizeof(path), ACCOUNT_ID_FW_ACCOUNT_ID, agent_name, service_type, service_account_id, index - 1);
320
321         if (!sync_agent_set_int_into_file(path, fw_account_id)) {
322                 _DEBUG_ERROR("[account_plugIn] __set_int_into_file FAIL\n");
323                 return;
324         }
325
326         _unset_account_id_fw(service_type, service_account_id, index);
327
328         _INNER_FUNC_EXIT;
329 }
330
331 static void _set_account_id_fw(int service_type, int service_account_id, int count, int fw_account_id)
332 {
333         _INNER_FUNC_ENTER;
334
335         _DEBUG_TRACE("count : %d", count);
336
337         char path[100] = { 0 };
338
339         int index = 0;
340         for (; index < count; index++) {
341                 int i = 0;
342                 for (; i < 100; i++) {
343                         path[i] = 0;
344                 }
345
346                 int data;
347                 snprintf(path, sizeof(path), ACCOUNT_ID_FW_ACCOUNT_ID, agent_name, service_type, service_account_id, index);
348                 _DEBUG_TRACE("================== 01 [%s]\n", path);
349                 if (!sync_agent_get_int_from_file(path, &data)) {
350                         _DEBUG_TRACE("================== 02\n");
351                         break;
352                 }
353         }
354
355         if (!sync_agent_set_int_into_file(path, fw_account_id)) {
356                 _DEBUG_ERROR("[account_plugIn] __set_int_into_file FAIL\n");
357                 return;
358         }
359
360         _DEBUG_TRACE("\n[account_plugIn] Sucess __set_int_into_file\n");
361         _DEBUG_TRACE("[account_plugIn] service_type : %d, service_account_id : %d, fw_account_id[%d] : %d\n\n", service_type, service_account_id, index, fw_account_id);
362
363         _INNER_FUNC_EXIT;
364 }
365
366 static int _increase_account_count_fw(int service_type, int service_account_id)
367 {
368         _INNER_FUNC_ENTER;
369
370         char path[100];
371         snprintf(path, sizeof(path), ACCOUNT_ID_FW_ACCOUNT_COUNT, agent_name, service_type, service_account_id);
372
373         int fw_account_count;
374         if (!sync_agent_get_int_from_file(path, &fw_account_count)) {
375                 _DEBUG_TRACE("[account_plugIn] first added\n");
376                 if (!sync_agent_set_int_into_file(path, 1))
377                         _DEBUG_ERROR("[account_plugIn] __set_int_into_file FAIL\n");
378                 _EXTERN_FUNC_EXIT;
379                 return 1;
380         }
381
382         if (fw_account_count < 1 || fw_account_count > MAX_ACCOUNT_COUNT) {
383                 _DEBUG_ERROR("[account_plugIn] Out of MAX_ACCOUNT_COUNT range !!!");
384                 return -1;
385         }
386
387         if (!sync_agent_set_int_into_file(path, fw_account_count + 1))
388                 _DEBUG_ERROR("[account_plugIn] __set_int_into_file FAIL\n");
389
390         _INNER_FUNC_EXIT;
391
392         return fw_account_count + 1;
393
394 }
395
396 static int _get_account_count_fw(int service_type, int service_account_id)
397 {
398         _INNER_FUNC_ENTER;
399
400         char path[100];
401         snprintf(path, sizeof(path), ACCOUNT_ID_FW_ACCOUNT_COUNT, agent_name, service_type, service_account_id);
402
403         int fw_account_count;
404         if (!sync_agent_get_int_from_file(path, &fw_account_count)) {
405                 _DEBUG_ERROR("[account_plugIn] empty\n");
406                 _EXTERN_FUNC_EXIT;
407                 return 0;
408         }
409
410         _INNER_FUNC_EXIT;
411
412         return fw_account_count;
413 }
414
415 static void _unset_account_id_service(int service_type, int fw_account_id)
416 {
417         _INNER_FUNC_ENTER;
418
419         char path[100];
420         snprintf(path, sizeof(path), ACCOUNT_ID_SERVICE_ACCOUNT_ID, agent_name, service_type, fw_account_id);
421
422         if (!sync_agent_unset_file(path))
423                 _DEBUG_ERROR("[account_plugIn] __unset_file FAIL\n");
424
425         _INNER_FUNC_EXIT;
426 }
427
428 static void _unset_account_id_fw(int service_type, int service_account_id, int index)
429 {
430         _INNER_FUNC_ENTER;
431
432         char path[100];
433         snprintf(path, sizeof(path), ACCOUNT_ID_FW_ACCOUNT_ID, agent_name, service_type, service_account_id, index);
434
435         if (!sync_agent_unset_file(path)) {
436                 _DEBUG_ERROR("[account_plugIn] __unset_file FAIL : %s\n", path);
437         }
438
439         _INNER_FUNC_EXIT;
440 }
441
442 static int _decrease_account_count_fw(int service_type, int service_account_id)
443 {
444         _INNER_FUNC_ENTER;
445
446         char path[100];
447         snprintf(path, sizeof(path), ACCOUNT_ID_FW_ACCOUNT_COUNT, agent_name, service_type, service_account_id);
448
449         int fw_account_count = 0;
450         if (!sync_agent_get_int_from_file(path, &fw_account_count)) {
451                 _DEBUG_ERROR("[account_plugIn] attempt delete when empty\n");
452                 return 0;
453         }
454
455         if (fw_account_count < 1 || fw_account_count > MAX_ACCOUNT_COUNT) {
456                 _DEBUG_ERROR("[account_plugIn] Out of MAX_ACCOUNT_COUNT range !!!");
457                 return -1;
458         }
459
460         fw_account_count = fw_account_count - 1;
461
462         if (fw_account_count == 0) {
463                 if (!sync_agent_unset_file(path)) {
464                         _DEBUG_ERROR("[account_plugIn] __unset_file FAIL : %s\n", path);
465                 }
466                 return 0;
467         }
468
469         if (!sync_agent_set_int_into_file(path, fw_account_count))
470                 _DEBUG_ERROR("[account_plugIn] vconf_set_id FAIL\n");
471
472         _INNER_FUNC_EXIT;
473
474         return fw_account_count;
475 }
476
477 static int _get_account_info(int service_account_id, sync_agent_service_account_info_s ** account_info)
478 {
479         _INNER_FUNC_ENTER;
480
481         retvm_if(*account_info == NULL, 0, "*account_info is NULL. FAIL !!!");
482
483         if (service_account_id == -1) {
484                 (*account_info)->email = 0;
485                 (*account_info)->type = SYNC_AGENT_ACC_TYPE_LOCAL;
486                 _EXTERN_FUNC_EXIT;
487                 return 1;
488         }
489
490         char *domain_name = 0;
491         char *email = 0;
492         account_h account_handle = 0;
493
494         int error_code = account_connect();
495         if (error_code != ACCOUNT_ERROR_NONE) {
496                 _DEBUG_ERROR("Failed to call account_connect()");
497                 goto error_part2;
498         }
499
500         account_create(&account_handle);
501         error_code = account_query_account_by_account_id(service_account_id, &account_handle);
502         if (error_code != ACCOUNT_ERROR_NONE) {
503                 _DEBUG_ERROR("Failed to call account_query_account_by_account_id()");
504                 goto error_part1;
505         }
506
507         error_code = account_get_domain_name(account_handle, &domain_name);
508         if (error_code != ACCOUNT_ERROR_NONE) {
509                 _DEBUG_ERROR("Failed to call account_get_domain_name()");
510                 goto error_part1;
511         }
512
513         if (!strcmp(domain_name, "Gmail")) {
514                 (*account_info)->type = SYNC_AGENT_ACC_TYPE_GOOGLE;
515         } else if (!strcmp(domain_name, "exchange")) {
516                 (*account_info)->type = SYNC_AGENT_ACC_TYPE_EAS;
517         } else {
518                 (*account_info)->type = SYNC_AGENT_ACC_TYPE_NONE;
519         }
520
521         error_code = account_get_email_address(account_handle, &email);
522         if (error_code != ACCOUNT_ERROR_NONE) {
523                 _DEBUG_ERROR("Failed to call account_get_email_address()");
524                 goto error_part1;
525         }
526
527         if (email != NULL) {
528                 (*account_info)->email = strdup(email);
529         }
530
531         error_code = account_destroy(account_handle);
532         if (error_code != ACCOUNT_ERROR_NONE) {
533                 _DEBUG_ERROR("Failed to call account_destroy() = %d", error_code);
534         }
535         error_code = account_disconnect();
536         if (error_code != ACCOUNT_ERROR_NONE) {
537                 _DEBUG_ERROR("Failed to call account_disconnect() = %d", error_code);
538                 goto error_part2;
539         }
540 //      if (domain_name != NULL)
541         free(domain_name);
542         if (email != NULL)
543                 free(email);
544
545         _INNER_FUNC_EXIT;
546
547         return 1;
548
549  error_part1:
550
551         error_code = account_destroy(account_handle);
552         if (error_code != ACCOUNT_ERROR_NONE) {
553                 _DEBUG_ERROR("Failed to call account_destroy() = %d", error_code);
554         }
555         error_code = account_disconnect();
556         if (error_code != ACCOUNT_ERROR_NONE) {
557                 _DEBUG_ERROR("Failed to call account_disconnect() = %d", error_code);
558         }
559
560  error_part2:
561
562         if (domain_name != NULL)
563                 free(domain_name);
564         if (email != NULL)
565                 free(email);
566
567         _DEBUG_ERROR("Returning through ERROR_PART");
568         return 0;
569 }