Add multi-user feature
[platform/core/api/notification.git] / src / notification_setting_service.c
1 /*
2  * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <errno.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <string.h>
21
22 #include <sqlite3.h>
23 #include <db-util.h>
24 #include <tizen.h>
25
26 #include <notification.h>
27 #include <notification_db.h>
28 #include <notification_error.h>
29 #include <notification_debug.h>
30 #include <notification_private.h>
31 #include <notification_setting.h>
32 #include <notification_setting_internal.h>
33 #include <notification_setting_service.h>
34
35
36 static int _get_table_field_data_int(char  **table, int *buf, int index)
37 {
38         if ((table == NULL) || (buf == NULL) || (index < 0))  {
39                 NOTIFICATION_ERR("table[%p], buf[%p], index[%d]", table, buf, index);
40                 return false;
41         }
42
43         if (table[index] != NULL) {
44                 *buf = atoi(table[index]);
45                 return true;
46         }
47
48         *buf = 0;
49         return false;
50 }
51
52 static int _get_table_field_data_string(char **table, char **buf, int ucs2, int index)
53 {
54         int ret = false;
55
56         if ((table == NULL) || (buf == NULL) || (index < 0))  {
57                 NOTIFICATION_ERR("table[%p], buf[%p], index[%d]", table, buf, index);
58                 return false;
59         }
60
61         char *pTemp = table[index];
62         int sLen = 0;
63         if (pTemp == NULL) {
64                 *buf = NULL;
65         } else {
66                 sLen = strlen(pTemp);
67                 if (sLen) {
68                         *buf = (char *) malloc(sLen + 1);
69                         if (*buf == NULL) {
70                                 NOTIFICATION_ERR("malloc is failed");
71                                 goto out;
72                         }
73                         memset(*buf, 0, sLen + 1);
74                         strncpy(*buf, pTemp, sLen);
75                 } else {
76                         *buf = NULL;
77                 }
78         }
79
80         ret = true;
81 out:
82
83         return ret;
84 }
85
86 EXPORT_API int noti_setting_service_get_setting_by_package_name(const char *package_name, notification_setting_h *setting, uid_t uid)
87 {
88         int err = NOTIFICATION_ERROR_NONE;
89         sqlite3 *local_db_handle = NULL;
90         char *sql_query = NULL;
91         char **query_result = NULL;
92         int sql_return;
93         int row_count = 0;
94         int column_count = 0;
95         int i = 0;
96         int col_index = 0;
97         notification_setting_h result_setting_array = NULL;
98
99         if (package_name == NULL || setting == NULL) {
100                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
101                 err =  NOTIFICATION_ERROR_INVALID_PARAMETER;
102                 goto out;
103         }
104
105         sql_return = db_util_open(DBPATH, &local_db_handle, 0);
106
107         if (sql_return != SQLITE_OK || local_db_handle == NULL) {
108                 NOTIFICATION_ERR("db_util_open failed [%d]", sql_return);
109                 err = NOTIFICATION_ERROR_FROM_DB;
110                 goto out;
111         }
112
113         sql_query = sqlite3_mprintf("SELECT package_name, allow_to_notify, do_not_disturb_except, visibility_class "
114                         "FROM %s "
115                         "WHERE package_name = %Q AND uid = %d", NOTIFICATION_SETTING_DB_TABLE, package_name, uid);
116
117         if (!sql_query) {
118                 NOTIFICATION_ERR("fail to alloc query");
119                 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
120                 goto out;
121         }
122
123         sql_return = sqlite3_get_table(local_db_handle, sql_query, &query_result, &row_count, &column_count, NULL);
124
125         if (sql_return != SQLITE_OK && sql_return != -1) {
126                 NOTIFICATION_ERR("sqlite3_get_table failed [%d][%s]", sql_return, sql_query);
127                 err = NOTIFICATION_ERROR_FROM_DB;
128                 goto out;
129         }
130
131         if (!row_count) {
132                 NOTIFICATION_DBG("No setting found for [%s]", package_name);
133                 err = NOTIFICATION_ERROR_NOT_EXIST_ID;
134                 goto out;
135         }
136
137         NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count);
138
139         row_count = 1;
140
141         if (!(result_setting_array = (struct notification_setting *)malloc(sizeof(struct notification_setting) * row_count))) {
142                 NOTIFICATION_ERR("malloc failed...");
143                 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
144                 goto out;
145         }
146
147         col_index = column_count;
148
149         _get_table_field_data_string(query_result, &(result_setting_array[i].package_name), 1, col_index++);
150         _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].allow_to_notify), col_index++);
151         _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].do_not_disturb_except), col_index++);
152         _get_table_field_data_int(query_result, &(result_setting_array[i].visibility_class), col_index++);
153
154         *setting = result_setting_array;
155
156 out:
157         if (query_result)
158                 sqlite3_free_table(query_result);
159
160         if (sql_query)
161                 sqlite3_free(sql_query);
162
163         if (local_db_handle) {
164                 sql_return = db_util_close(local_db_handle);
165                 if (sql_return != SQLITE_OK)
166                         NOTIFICATION_WARN("fail to db_util_close - [%d]", sql_return);
167         }
168
169         return err;
170 }
171
172
173
174 EXPORT_API int noti_setting_get_setting_array(notification_setting_h *setting_array, int *count, uid_t uid)
175 {
176         int err = NOTIFICATION_ERROR_NONE;
177         sqlite3 *local_db_handle = NULL;
178         char *sql_query = NULL;
179         char **query_result = NULL;
180         int sql_return;
181         int row_count = 0;
182         int column_count = 0;
183         int i = 0;
184         int col_index = 0;
185         notification_setting_h result_setting_array = NULL;
186
187         if (setting_array == NULL || count == NULL) {
188                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
189                 err =  NOTIFICATION_ERROR_INVALID_PARAMETER;
190                 goto out;
191         }
192
193         sql_return = db_util_open(DBPATH, &local_db_handle, 0);
194
195         if (sql_return != SQLITE_OK || local_db_handle == NULL) {
196                 NOTIFICATION_ERR("db_util_open failed [%d]", sql_return);
197                 err = NOTIFICATION_ERROR_FROM_DB;
198                 goto out;
199         }
200
201         sql_query = sqlite3_mprintf("SELECT package_name, allow_to_notify, do_not_disturb_except, visibility_class "
202                         "FROM %s WHERE uid = %d "
203                         "ORDER BY package_name", NOTIFICATION_SETTING_DB_TABLE, uid);
204
205         if (!sql_query) {
206                 NOTIFICATION_ERR("fail to alloc query");
207                 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
208                 goto out;
209         }
210
211         sql_return = sqlite3_get_table(local_db_handle, sql_query, &query_result, &row_count, &column_count, NULL);
212
213         if (sql_return != SQLITE_OK && sql_return != -1) {
214                 NOTIFICATION_ERR("NOTIFICATION_ERROR_FROM_DB failed [%d][%s]", sql_return, sql_query);
215                 err = NOTIFICATION_ERROR_FROM_DB;
216                 goto out;
217         }
218
219         if (!row_count) {
220                 NOTIFICATION_DBG("No setting found...");
221                 err = NOTIFICATION_ERROR_NOT_EXIST_ID;
222                 goto out;
223         }
224
225         NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count);
226         if (!(result_setting_array = (struct notification_setting *)malloc(sizeof(struct notification_setting) * row_count))) {
227                 NOTIFICATION_ERR("malloc failed...");
228                 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
229                 goto out;
230         }
231
232         col_index = column_count;
233
234         for (i = 0; i < row_count; i++) {
235                 _get_table_field_data_string(query_result, &(result_setting_array[i].package_name), 1, col_index++);
236                 _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].allow_to_notify), col_index++);
237                 _get_table_field_data_int(query_result, (int *)&(result_setting_array[i].do_not_disturb_except), col_index++);
238                 _get_table_field_data_int(query_result, &(result_setting_array[i].visibility_class), col_index++);
239         }
240
241         *setting_array = result_setting_array;
242         *count = row_count;
243
244 out:
245         if (query_result)
246                         sqlite3_free_table(query_result);
247
248         if (sql_query)
249                 sqlite3_free(sql_query);
250
251         if (local_db_handle) {
252                 sql_return = db_util_close(local_db_handle);
253                 if (sql_return != SQLITE_OK)
254                         NOTIFICATION_WARN("fail to db_util_close - [%d]", sql_return);
255         }
256
257         return err;
258 }
259
260
261 EXPORT_API int noti_system_setting_load_system_setting(notification_system_setting_h *system_setting, uid_t uid)
262 {
263         int err = NOTIFICATION_ERROR_NONE;
264         sqlite3 *local_db_handle = NULL;
265         char *sql_query = NULL;
266         char **query_result = NULL;
267         int sql_return;
268         int row_count = 0;
269         int column_count = 0;
270         int col_index = 0;
271         notification_system_setting_h result_system_setting = NULL;
272
273         if (system_setting == NULL) {
274                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
275                 err =  NOTIFICATION_ERROR_INVALID_PARAMETER;
276                 goto out;
277         }
278
279         sql_return = db_util_open(DBPATH, &local_db_handle, 0);
280
281         if (sql_return != SQLITE_OK || local_db_handle == NULL) {
282                 NOTIFICATION_ERR("db_util_open failed [%d]", sql_return);
283                 err = NOTIFICATION_ERROR_FROM_DB;
284                 goto out;
285         }
286
287         sql_query = sqlite3_mprintf("SELECT do_not_disturb, visibility_class "
288                         "FROM %s WHERE uid = %d", NOTIFICATION_SYSTEM_SETTING_DB_TABLE, uid);
289
290         if (!sql_query) {
291                 NOTIFICATION_ERR("fail to alloc query");
292                 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
293                 goto out;
294         }
295
296         sql_return = sqlite3_get_table(local_db_handle, sql_query, &query_result, &row_count, &column_count, NULL);
297
298         if (sql_return != SQLITE_OK && sql_return != -1) {
299                 NOTIFICATION_ERR("sqlite3_get_table failed [%d][%s]", sql_return, sql_query);
300                 err = NOTIFICATION_ERROR_FROM_DB;
301                 goto out;
302         }
303
304         NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count);
305         if (!(result_system_setting = (struct notification_system_setting *)malloc(sizeof(struct notification_system_setting)))) {
306                 NOTIFICATION_ERR("malloc failed...");
307                 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
308                 goto out;
309         }
310
311         /* no system setting record. allow everyting */
312         if (!row_count) {
313                 NOTIFICATION_DBG("No setting found...");
314                 result_system_setting->do_not_disturb = 0;
315                 result_system_setting->visibility_class = 0;
316         } else {
317                 col_index = column_count;
318                 _get_table_field_data_int(query_result, (int *)&(result_system_setting->do_not_disturb), col_index++);
319                 _get_table_field_data_int(query_result, &(result_system_setting->visibility_class), col_index++);
320         }
321
322         *system_setting = result_system_setting;
323 out:
324         if (query_result)
325                         sqlite3_free_table(query_result);
326
327         if (sql_query)
328                 sqlite3_free(sql_query);
329
330         if (local_db_handle) {
331                 sql_return = db_util_close(local_db_handle);
332                 if (sql_return != SQLITE_OK)
333                         NOTIFICATION_WARN("fail to db_util_close - [%d]", sql_return);
334         }
335
336         return err;
337 }
338