add APIs for getting SIM init status and importing SIM contacts by sim slot no
[platform/core/pim/contacts-service.git] / client / ctsvc_client_setting.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 #include <glib.h>
20 #include <pims-ipc-data.h>
21
22 #include "contacts.h"
23 #include "ctsvc_internal.h"
24 #include "ctsvc_notify.h"
25 #include "ctsvc_ipc_define.h"
26 #include "ctsvc_ipc_marshal.h"
27 #include "ctsvc_client_ipc.h"
28 #include "ctsvc_mutex.h"
29
30 typedef struct {
31         contacts_setting_name_display_order_changed_cb cb;
32         void *user_data;
33 } ctsvc_name_display_order_changed_cb_info_s;
34
35 typedef struct {
36         contacts_setting_name_sorting_order_changed_cb cb;
37         void *user_data;
38 } ctsvc_name_sorting_order_changed_cb_info_s;
39
40 static GSList *__setting_name_display_order_subscribe_list = NULL;
41 static GSList *__setting_name_sorting_order_subscribe_list = NULL;
42
43 API int contacts_setting_get_name_display_order(
44                 contacts_name_display_order_e *name_display_order)
45 {
46         int ret = CONTACTS_ERROR_NONE;
47         pims_ipc_data_h outdata = NULL;
48
49         RETV_IF(name_display_order == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
50         *name_display_order = 0;
51
52         if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_GET_NAME_DISPLAY_ORDER,
53                                 NULL, &outdata) != 0) {
54                 ERR("ctsvc_ipc_call Fail");
55                 return CONTACTS_ERROR_IPC;
56         }
57
58         if (outdata) {
59                 if (CONTACTS_ERROR_NONE != ctsvc_ipc_unmarshal_int(outdata, &ret)) {
60                         ERR("ctsvc_ipc_unmarshal_int() Fail");
61                         pims_ipc_data_destroy(outdata);
62                         return CONTACTS_ERROR_IPC;
63                 }
64
65                 if (CONTACTS_ERROR_NONE == ret) {
66                         if (CONTACTS_ERROR_NONE != ctsvc_ipc_unmarshal_int(outdata, (int*)name_display_order)) {
67                                 ERR("ctsvc_ipc_unmarshal_int() Fail");
68                                 pims_ipc_data_destroy(outdata);
69                                 return CONTACTS_ERROR_IPC;
70                         }
71                 }
72                 pims_ipc_data_destroy(outdata);
73         }
74
75         return ret;
76 }
77
78 API int contacts_setting_get_name_sorting_order(
79                 contacts_name_sorting_order_e *name_sorting_order)
80 {
81         int ret = CONTACTS_ERROR_NONE;
82         pims_ipc_data_h outdata = NULL;
83
84         RETV_IF(name_sorting_order == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
85         *name_sorting_order = 0;
86
87         if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_GET_NAME_SORTING_ORDER,
88                                 NULL, &outdata) != 0) {
89                 ERR("ctsvc_ipc_call Fail");
90                 return CONTACTS_ERROR_IPC;
91         }
92
93         if (outdata) {
94                 if (CONTACTS_ERROR_NONE != ctsvc_ipc_unmarshal_int(outdata, &ret)) {
95                         ERR("ctsvc_ipc_unmarshal_int() Fail");
96                         pims_ipc_data_destroy(outdata);
97                         return CONTACTS_ERROR_IPC;
98                 }
99                 if (CONTACTS_ERROR_NONE == ret) {
100                         if (CONTACTS_ERROR_NONE != ctsvc_ipc_unmarshal_int(outdata, (int*)name_sorting_order)) {
101                                 ERR("ctsvc_ipc_unmarshal_int() Fail");
102                                 pims_ipc_data_destroy(outdata);
103                                 return CONTACTS_ERROR_IPC;
104                         }
105                 }
106                 pims_ipc_data_destroy(outdata);
107         }
108
109         return ret;
110 }
111
112 API int contacts_setting_set_name_display_order(
113                 contacts_name_display_order_e name_display_order)
114 {
115         int ret = CONTACTS_ERROR_NONE;
116         pims_ipc_data_h indata = NULL;
117         pims_ipc_data_h outdata = NULL;
118
119         RETVM_IF(name_display_order != CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST
120                         && name_display_order != CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST,
121                         CONTACTS_ERROR_INVALID_PARAMETER,
122                         "name display order is invalid : %d", name_display_order);
123
124         indata = pims_ipc_data_create(0);
125         if (indata == NULL) {
126                 ERR("pims_ipc_data_create() Fail");
127                 return CONTACTS_ERROR_OUT_OF_MEMORY;
128         }
129
130         ret = ctsvc_ipc_marshal_int(name_display_order, indata);
131         if (ret != CONTACTS_ERROR_NONE) {
132                 ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
133                 pims_ipc_data_destroy(indata);
134                 return ret;
135         }
136
137         if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_SET_NAME_DISPLAY_ORDER,
138                                 indata, &outdata) != 0) {
139                 ERR("ctsvc_ipc_call Fail");
140                 pims_ipc_data_destroy(indata);
141                 return CONTACTS_ERROR_IPC;
142         }
143         pims_ipc_data_destroy(indata);
144
145         if (outdata) {
146                 if (CONTACTS_ERROR_NONE != ctsvc_ipc_unmarshal_int(outdata, &ret)) {
147                         ERR("ctsvc_ipc_unmarshal_int() Fail");
148                         pims_ipc_data_destroy(outdata);
149                         return CONTACTS_ERROR_IPC;
150                 }
151                 pims_ipc_data_destroy(outdata);
152         }
153
154         return ret;
155 }
156
157 API int contacts_setting_set_name_sorting_order(
158                 contacts_name_sorting_order_e name_sorint_order)
159 {
160         int ret = CONTACTS_ERROR_NONE;
161         pims_ipc_data_h indata = NULL;
162         pims_ipc_data_h outdata = NULL;
163
164         RETVM_IF(name_sorint_order != CONTACTS_NAME_SORTING_ORDER_FIRSTLAST
165                         && name_sorint_order != CONTACTS_NAME_SORTING_ORDER_LASTFIRST,
166                         CONTACTS_ERROR_INVALID_PARAMETER,
167                         "name sorting order is invalid : %d", name_sorint_order);
168
169         indata = pims_ipc_data_create(0);
170         if (indata == NULL) {
171                 ERR("pims_ipc_data_create() Fail");
172                 return CONTACTS_ERROR_OUT_OF_MEMORY;
173         }
174
175         ret = ctsvc_ipc_marshal_int(name_sorint_order, indata);
176         if (ret != CONTACTS_ERROR_NONE) {
177                 ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
178                 pims_ipc_data_destroy(indata);
179                 return ret;
180         }
181
182         if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_SET_NAME_SORTING_ORDER,
183                                 indata, &outdata) != 0) {
184                 ERR("ctsvc_ipc_call Fail");
185                 pims_ipc_data_destroy(indata);
186                 return CONTACTS_ERROR_IPC;
187         }
188         pims_ipc_data_destroy(indata);
189
190         if (outdata) {
191                 if (CONTACTS_ERROR_NONE != ctsvc_ipc_unmarshal_int(outdata, &ret)) {
192                         ERR("ctsvc_ipc_unmarshal_int() Fail");
193                         pims_ipc_data_destroy(outdata);
194                         return CONTACTS_ERROR_IPC;
195                 }
196                 pims_ipc_data_destroy(outdata);
197         }
198
199         return ret;
200 }
201
202 static void _csetting_name_display_order_subscribe_cb(pims_ipc_h ipc,
203                 pims_ipc_data_h data, void *user_data)
204 {
205         int ret;
206         int value = -1;
207
208         if (data) {
209                 ret = ctsvc_ipc_unmarshal_int(data, &value);
210                 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_ipc_unmarshal_int() Fail(%d)", ret);
211         }
212         if (__setting_name_display_order_subscribe_list) {
213                 GSList *l;
214                 for (l = __setting_name_display_order_subscribe_list; l; l = l->next) {
215                         ctsvc_name_display_order_changed_cb_info_s *cb_info = l->data;
216                         if (cb_info->cb)
217                                 cb_info->cb((contacts_name_display_order_e)value, cb_info->user_data);
218                 }
219         }
220 }
221
222 static void _csetting_name_sorting_order_subscribe_cb(pims_ipc_h ipc,
223                 pims_ipc_data_h data, void *user_data)
224 {
225         int ret;
226         int value = -1;
227
228         if (data) {
229                 ret = ctsvc_ipc_unmarshal_int(data, &value);
230                 WARN_IF(CONTACTS_ERROR_NONE != ret, "() Fail(%d)", ret);
231         }
232
233         if (__setting_name_sorting_order_subscribe_list) {
234                 GSList *l;
235                 for (l = __setting_name_sorting_order_subscribe_list; l; l = l->next) {
236                         ctsvc_name_sorting_order_changed_cb_info_s *cb_info = l->data;
237                         if (cb_info->cb)
238                                 cb_info->cb((contacts_name_sorting_order_e)value, cb_info->user_data);
239                 }
240         }
241 }
242
243 int ctsvc_setting_recover_for_change_subscription()
244 {
245         GSList *it;
246
247         for (it = __setting_name_display_order_subscribe_list; it; it = it->next) {
248                 ctsvc_name_display_order_changed_cb_info_s *cb_info = it->data;
249                 if (cb_info->cb) {
250                         if (pims_ipc_subscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
251                                                 CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_DISPLAY_ORDER_CHANGED,
252                                                 _csetting_name_display_order_subscribe_cb, NULL) != 0) {
253                                 ERR("pims_ipc_subscribe() Fail");
254                                 return CONTACTS_ERROR_IPC;
255                         }
256                         break;
257                 }
258         }
259
260         for (it = __setting_name_sorting_order_subscribe_list; it; it = it->next) {
261                 ctsvc_name_sorting_order_changed_cb_info_s *cb_info = it->data;
262                 if (cb_info->cb) {
263                         if (pims_ipc_subscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
264                                                 CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_SORTING_ORDER_CHANGED,
265                                                 _csetting_name_sorting_order_subscribe_cb, NULL) != 0) {
266                                 ERR("pims_ipc_subscribe() Fail");
267                                 return CONTACTS_ERROR_IPC;
268                         }
269                         break;
270                 }
271         }
272
273         return CONTACTS_ERROR_NONE;
274 }
275
276 API int contacts_setting_add_name_display_order_changed_cb(
277                 contacts_setting_name_display_order_changed_cb cb, void *user_data)
278 {
279         GSList *l;
280         int ret;
281         bool result = false;
282         ctsvc_name_display_order_changed_cb_info_s *cb_info;
283
284         RETV_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
285
286         ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
287         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission() Fail(%d)", ret);
288         RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
289
290         ret = ctsvc_ipc_create_for_change_subscription();
291         if (CONTACTS_ERROR_NONE != ret) {
292                 ERR("ctsvc_ipc_create_for_change_subscription() Fail(%d)", ret);
293                 return ret;
294         }
295
296         ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
297
298         if (NULL == __setting_name_display_order_subscribe_list) {
299                 if (pims_ipc_subscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
300                                         CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_DISPLAY_ORDER_CHANGED,
301                                         _csetting_name_display_order_subscribe_cb, NULL) != 0) {
302                         ERR("pims_ipc_subscribe() Fail");
303                         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
304                         return CONTACTS_ERROR_IPC;
305                 }
306         }
307
308         for (l = __setting_name_display_order_subscribe_list; l; l = l->next) {
309                 ctsvc_name_display_order_changed_cb_info_s *cb_info = l->data;
310                 if (cb_info->cb == cb && cb_info->user_data == user_data) {
311                         ERR("The same callback(%x) is already exist", cb);
312                         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
313                         return CONTACTS_ERROR_INVALID_PARAMETER;
314                 }
315         }
316
317         cb_info = calloc(1, sizeof(ctsvc_name_display_order_changed_cb_info_s));
318         if (NULL == cb_info) {
319                 ERR("calloc() Fail");
320                 ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
321                 return CONTACTS_ERROR_OUT_OF_MEMORY;
322         }
323         cb_info->user_data = user_data;
324         cb_info->cb = cb;
325         __setting_name_display_order_subscribe_list = g_slist_append(__setting_name_display_order_subscribe_list, cb_info);
326
327         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
328         return CONTACTS_ERROR_NONE;
329 }
330
331 API int contacts_setting_remove_name_display_order_changed_cb(
332                 contacts_setting_name_display_order_changed_cb cb, void *user_data)
333 {
334         int ret;
335
336         RETV_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
337
338         ret = ctsvc_ipc_destroy_for_change_subscription(false);
339         if (CONTACTS_ERROR_NONE != ret) {
340                 ERR("ctsvc_ipc_destroy_for_change_subscription() Fail(%d)", ret);
341                 return ret;
342         }
343
344         ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
345
346         if (__setting_name_display_order_subscribe_list) {
347                 GSList *l;
348                 for (l = __setting_name_display_order_subscribe_list; l; l = l->next) {
349                         ctsvc_name_display_order_changed_cb_info_s *cb_info = l->data;
350                         if (cb == cb_info->cb && user_data == cb_info->user_data) {
351                                 __setting_name_display_order_subscribe_list = g_slist_remove(__setting_name_display_order_subscribe_list, cb_info);
352                                 free(cb_info);
353                                 break;
354                         }
355                 }
356                 if (g_slist_length(__setting_name_display_order_subscribe_list) == 0) {
357                         pims_ipc_unsubscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
358                                         CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_DISPLAY_ORDER_CHANGED);
359                         g_slist_free(__setting_name_display_order_subscribe_list);
360                         __setting_name_display_order_subscribe_list = NULL;
361                 }
362         }
363
364         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
365         return CONTACTS_ERROR_NONE;
366 }
367
368 API int contacts_setting_add_name_sorting_order_changed_cb(
369                 contacts_setting_name_sorting_order_changed_cb cb, void *user_data)
370 {
371         GSList *l;
372         int ret;
373         bool result = false;
374         ctsvc_name_sorting_order_changed_cb_info_s *cb_info;
375
376         RETV_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
377
378         ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
379         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission Fail(%d)", ret);
380         RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
381
382         ret = ctsvc_ipc_create_for_change_subscription();
383         if (CONTACTS_ERROR_NONE != ret) {
384                 ERR("ctsvc_ipc_create_for_change_subscription() Fail(%d)", ret);
385                 return ret;
386         }
387
388         ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
389
390         if (NULL == __setting_name_sorting_order_subscribe_list) {
391                 if (pims_ipc_subscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
392                                         CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_SORTING_ORDER_CHANGED,
393                                         _csetting_name_sorting_order_subscribe_cb, NULL) != 0) {
394                         ERR("pims_ipc_subscribe() Fail");
395                         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
396                         return CONTACTS_ERROR_IPC;
397                 }
398         }
399
400         for (l = __setting_name_sorting_order_subscribe_list; l; l = l->next) {
401                 ctsvc_name_sorting_order_changed_cb_info_s *cb_info = l->data;
402                 if (cb_info->cb == cb && cb_info->user_data == user_data) {
403                         ERR("The same callback(%x) is already exist", cb);
404                         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
405                         return CONTACTS_ERROR_INVALID_PARAMETER;
406                 }
407         }
408
409         cb_info = calloc(1, sizeof(ctsvc_name_sorting_order_changed_cb_info_s));
410         if (NULL == cb_info) {
411                 ERR("calloc() Fail");
412                 ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
413                 return CONTACTS_ERROR_OUT_OF_MEMORY;
414         }
415         cb_info->user_data = user_data;
416         cb_info->cb = cb;
417         __setting_name_sorting_order_subscribe_list = g_slist_append(__setting_name_sorting_order_subscribe_list, cb_info);
418
419         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
420         return CONTACTS_ERROR_NONE;
421 }
422
423 API int contacts_setting_remove_name_sorting_order_changed_cb(
424                 contacts_setting_name_sorting_order_changed_cb cb, void *user_data)
425 {
426         int ret;
427         RETV_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
428
429         ret = ctsvc_ipc_destroy_for_change_subscription(false);
430         if (CONTACTS_ERROR_NONE != ret) {
431                 ERR("ctsvc_ipc_destroy_for_change_subscription() Fail(%d)", ret);
432                 return ret;
433         }
434
435         ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
436
437         if (__setting_name_sorting_order_subscribe_list) {
438                 GSList *l;
439                 for (l = __setting_name_sorting_order_subscribe_list; l; l = l->next) {
440                         ctsvc_name_sorting_order_changed_cb_info_s *cb_info = l->data;
441                         if (cb == cb_info->cb && user_data == cb_info->user_data) {
442                                 __setting_name_sorting_order_subscribe_list = g_slist_remove(__setting_name_sorting_order_subscribe_list, cb_info);
443                                 free(cb_info);
444                                 break;
445                         }
446                 }
447                 if (g_slist_length(__setting_name_sorting_order_subscribe_list) == 0) {
448                         pims_ipc_unsubscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
449                                         CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_SORTING_ORDER_CHANGED);
450                         g_slist_free(__setting_name_sorting_order_subscribe_list);
451                         __setting_name_sorting_order_subscribe_list = NULL;
452                 }
453         }
454
455         ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
456         return CONTACTS_ERROR_NONE;
457 }
458