Release version 0.5.13
[platform/core/appfw/librua.git] / src / rua.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 <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include <sqlite3.h>
23 #include <aul.h>
24 #include <dlog.h>
25
26 #include "rua_util.h"
27 #include "rua.h"
28 #include "db-schema.h"
29 #include "rua_dbus.h"
30 #include "rua_private.h"
31
32 API int rua_add_history_for_uid(char *pkg_name, char *app_path, char *arg, uid_t uid)
33 {
34         int r;
35         char time_str[32] = {0,};
36         bundle *b = NULL;
37
38         if (pkg_name == NULL || app_path == NULL) {
39                 LOGE("invalid param");
40                 return -1;
41         }
42
43         r = _rua_util_check_uid(uid);
44         if (r == -1)
45                 return r;
46
47         b = bundle_create();
48         if (b == NULL) {
49                 LOGE("bundle_create fail out of memory.");
50                 return -1;
51         }
52         snprintf(time_str, sizeof(time_str), "%d", (int)time(NULL));
53         bundle_add_str(b, AUL_K_RUA_PKGNAME, pkg_name);
54         bundle_add_str(b, AUL_K_RUA_APPPATH, app_path);
55         bundle_add_str(b, AUL_K_RUA_ARG, arg);
56         bundle_add_str(b, AUL_K_RUA_TIME, time_str);
57
58         r = aul_add_rua_history_for_uid(b, uid);
59         LOGI("rua_add_history_for_uid result : %d ", r);
60         bundle_free(b);
61         return r;
62 }
63
64 API int rua_delete_history_with_pkgname_for_uid(char *pkg_name, uid_t uid)
65 {
66         int r;
67         bundle *b;
68
69         r = _rua_util_check_uid(uid);
70         if (r == -1)
71                 return r;
72
73         b = bundle_create();
74         if (b == NULL) {
75                 LOGE("bundle_create fail out of memory.");
76                 return -1;
77         }
78         bundle_add_str(b, AUL_K_RUA_PKGNAME, pkg_name);
79         r = aul_delete_rua_history_for_uid(b, uid);
80         LOGI("rua_delete_history_with_pkgname result : %d ", r);
81         bundle_free(b);
82         return r;
83 }
84
85 API int rua_delete_history_with_pkgname(char *pkg_name)
86 {
87         return rua_delete_history_with_pkgname_for_uid(pkg_name, getuid());
88 }
89
90 API int rua_delete_history_with_apppath_for_uid(char *app_path, uid_t uid)
91 {
92         int r;
93         bundle *b;
94
95         r = _rua_util_check_uid(uid);
96         if (r == -1)
97                 return r;
98
99         b = bundle_create();
100         if (b == NULL) {
101                 LOGE("bundle_create fail out of memory.");
102                 return -1;
103         }
104         bundle_add_str(b, AUL_K_RUA_APPPATH, app_path);
105         r = aul_delete_rua_history_for_uid(b, uid);
106         LOGI("rua_delete_history_with_apppath result : %d ", r);
107         bundle_free(b);
108         return r;
109 }
110
111 API int rua_delete_history_with_apppath(char *app_path)
112 {
113         return rua_delete_history_with_apppath_for_uid(app_path, getuid());
114 }
115
116 API int rua_clear_history_for_uid(uid_t uid)
117 {
118         int r;
119
120         r = _rua_util_check_uid(uid);
121         if (r == -1)
122                 return r;
123
124         r = aul_delete_rua_history_for_uid(NULL, uid);
125         LOGI("rua_clear_history result : %d ", r);
126         return r;
127 }
128
129 API int rua_clear_history(void)
130 {
131         return rua_clear_history_for_uid(getuid());
132 }
133
134 API int rua_history_load_db_for_uid(char ***table, int *nrows, int *ncols, uid_t uid)
135 {
136         static const char query[] = "SELECT "
137                 "pkg_name, app_path, arg, launch_time, instance_id, "
138                 "instance_name, icon, uri, image, comp_id "
139                 "FROM rua_history ORDER BY launch_time DESC";
140         int r;
141         char *db_err = NULL;
142         char **db_result = NULL;
143         sqlite3 *db = NULL;
144
145         if (table == NULL || nrows == NULL || ncols == NULL) {
146                 LOGE("invalid parameter");
147                 return -1;
148         }
149
150         r = _rua_util_check_uid(uid);
151         if (r == -1)
152                 return r;
153
154         r = _rua_util_open_db(&db, SQLITE_OPEN_READONLY, uid, RUA_DB_NAME);
155         if (r != SQLITE_OK)
156                 return -1;
157
158         r = sqlite3_get_table(db, query, &db_result, nrows, ncols, &db_err);
159         if (r != SQLITE_OK) {
160                 LOGE("get table failed: %s", db_err);
161                 sqlite3_free(db_err);
162                 sqlite3_close_v2(db);
163                 return -1;
164         }
165
166         *table = db_result;
167
168         sqlite3_close_v2(db);
169
170         return r;
171 }
172
173 API int rua_history_load_db(char ***table, int *nrows, int *ncols)
174 {
175         return rua_history_load_db_for_uid(table, nrows, ncols, getuid());
176 }
177
178 API int rua_register_update_cb_for_uid(rua_history_update_cb callback, void *user_data, int *callback_id, uid_t uid)
179 {
180         int r;
181
182         if (callback == NULL)
183                 return -1;
184
185         r = _rua_util_check_uid(uid);
186         if (r == -1)
187                 return r;
188
189         r = rua_dbus_signal_subscribe(callback, user_data, callback_id);
190
191         return r;
192 }
193
194 API int rua_register_update_cb(rua_history_update_cb callback, void *user_data, int *callback_id)
195 {
196         return rua_register_update_cb_for_uid(callback, user_data, callback_id, getuid());
197 }
198
199 API int rua_unregister_update_cb_for_uid(int callback_id, uid_t uid)
200 {
201         int r;
202
203         r = _rua_util_check_uid(uid);
204         if (r == -1)
205                 return r;
206
207         r = rua_dbus_signal_unsubscribe(callback_id);
208
209         return r;
210 }
211
212 API int rua_unregister_update_cb(int callback_id)
213 {
214         return rua_unregister_update_cb_for_uid(callback_id, getuid());
215 }
216
217 API int rua_history_get_rec(struct rua_rec *rec, char **table, int nrows, int ncols,
218                         int row)
219 {
220         char **db_result = NULL;
221         char *tmp = NULL;
222
223         if (rec == NULL)
224                 return -1;
225         if (table == NULL)
226                 return -1;
227         if (row >= nrows)
228                 return -1;
229
230         db_result = table + ((row + 1) * ncols);
231
232         tmp = db_result[RUA_COL_PKGNAME];
233         if (tmp) {
234                 rec->pkg_name = tmp;
235                 LOGI("get rec pkg_name %s", rec->pkg_name);
236         }
237
238         tmp = db_result[RUA_COL_APPPATH];
239         if (tmp)
240                 rec->app_path = tmp;
241
242         tmp = db_result[RUA_COL_ARG];
243         if (tmp)
244                 rec->arg = tmp;
245
246         tmp = db_result[RUA_COL_LAUNCHTIME];
247         if (tmp)
248                 rec->launch_time = atoi(tmp);
249
250         tmp = db_result[RUA_COL_COMP_ID];
251         if (tmp && tmp[0] != '\0')
252                 rec->comp_id = tmp;
253         else
254                 rec->comp_id = NULL;
255
256         tmp = db_result[RUA_COL_INSTANCE_ID];
257         if (tmp && tmp[0] != '\0')
258                 rec->instance_id = tmp;
259         else
260                 rec->instance_id = NULL;
261
262         tmp = db_result[RUA_COL_INSTANCE_NAME];
263         if (tmp && tmp[0] != '\0')
264                 rec->instance_name = tmp;
265         else
266                 rec->instance_name = NULL;
267
268         tmp = db_result[RUA_COL_ICON];
269         if (tmp && tmp[0] != '\0')
270                 rec->icon = tmp;
271         else
272                 rec->icon = NULL;
273
274         tmp = db_result[RUA_COL_URI];
275         if (tmp && tmp[0] != '\0')
276                 rec->uri = tmp;
277         else
278                 rec->uri = NULL;
279
280         tmp = db_result[RUA_COL_IMAGE];
281         if (tmp && tmp[0] != '\0')
282                 rec->image = tmp;
283         else
284                 rec->image = NULL;
285
286         tmp = db_result[RUA_COL_COMP_ID];
287         if (tmp && tmp[0] != '\0')
288                 rec->comp_id = tmp;
289         else
290                 rec->comp_id = NULL;
291
292         return 0;
293 }
294
295 API int rua_history_unload_db(char ***table)
296 {
297         if (*table) {
298                 sqlite3_free_table(*table);
299                 *table = NULL;
300                 return 0;
301         }
302         return -1;
303 }
304
305 API int rua_is_latest_app_for_uid(const char *pkg_name, uid_t uid)
306 {
307         static const char query[] =
308                 "SELECT pkg_name FROM rua_history "
309                 "ORDER BY launch_time DESC LIMIT 1";
310         int r = -1;
311         sqlite3_stmt *stmt;
312         const unsigned char *ct;
313         sqlite3 *db = NULL;
314
315         if (!pkg_name)
316                 return -1;
317
318         r = _rua_util_check_uid(uid);
319         if (r == -1)
320                 return r;
321
322         r = _rua_util_open_db(&db, SQLITE_OPEN_READONLY, uid, RUA_DB_NAME);
323         if (r != SQLITE_OK)
324                 return -1;
325
326         r = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
327         if (r != SQLITE_OK) {
328                 sqlite3_close_v2(db);
329                 return -1;
330         }
331
332         r = sqlite3_step(stmt);
333         if (r != SQLITE_ROW) {
334                 if (r != SQLITE_DONE)
335                         LOGE("step failed: %s", sqlite3_errmsg(db));
336                 sqlite3_finalize(stmt);
337                 sqlite3_close_v2(db);
338                 return -1;
339         }
340
341         ct = sqlite3_column_text(stmt, 0);
342         if (ct == NULL || ct[0] == '\0')
343                 r = -1;
344         else if (strncmp(pkg_name, (const char *)ct, strlen(pkg_name)) == 0)
345                 r = 0;
346         else
347                 r = -1;
348
349         sqlite3_finalize(stmt);
350         sqlite3_close_v2(db);
351
352         return r;
353 }
354
355 API int rua_is_latest_app(const char *pkg_name)
356 {
357         return rua_is_latest_app_for_uid(pkg_name, getuid());
358 }
359
360 API int rua_init(void)
361 {
362         return 0;
363 }
364
365 API int rua_fini(void)
366 {
367         return 0;
368 }
369
370 API int rua_delete_history_with_instance_id(const char *app_id,
371                 const char *instance_id)
372 {
373         int ret;
374         bundle *b;
375
376         if (app_id == NULL) {
377                 LOGE("Invalid parameter");
378                 return -1;
379         }
380
381         b = bundle_create();
382         if (b == NULL) {
383                 LOGE("Out of memory");
384                 return -1;
385         }
386
387         bundle_add_str(b, AUL_K_RUA_PKGNAME, app_id);
388         if (instance_id)
389                 bundle_add_str(b, AUL_K_RUA_INSTANCE_ID, instance_id);
390
391         ret = aul_delete_rua_history_for_uid(b, getuid());
392         bundle_free(b);
393         if (ret < 0) {
394                 LOGE("Failed to delete rua history - result(%d)", ret);
395                 return -1;
396         }
397
398         return 0;
399 }