261281762fc53563f0561d1a630fce94e03cc72e
[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[] =
137                 "SELECT pkg_name, app_path, arg, launch_time, instance_id,"
138                 "  instance_name, icon, uri "
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", sqlite3_errmsg(db));
161                 sqlite3_close_v2(db);
162                 return -1;
163         }
164
165         *table = db_result;
166
167         sqlite3_close_v2(db);
168
169         return r;
170 }
171
172 API int rua_history_load_db(char ***table, int *nrows, int *ncols)
173 {
174         return rua_history_load_db_for_uid(table, nrows, ncols, getuid());
175 }
176
177 API int rua_register_update_cb_for_uid(rua_history_update_cb callback, void *user_data, int *callback_id, uid_t uid)
178 {
179         int r;
180
181         if (callback == NULL)
182                 return -1;
183
184         r = _rua_util_check_uid(uid);
185         if (r == -1)
186                 return r;
187
188         r = rua_dbus_signal_subscribe(callback, user_data, callback_id);
189
190         return r;
191 }
192
193 API int rua_register_update_cb(rua_history_update_cb callback, void *user_data, int *callback_id)
194 {
195         return rua_register_update_cb_for_uid(callback, user_data, callback_id, getuid());
196 }
197
198 API int rua_unregister_update_cb_for_uid(int callback_id, uid_t uid)
199 {
200         int r;
201
202         r = _rua_util_check_uid(uid);
203         if (r == -1)
204                 return r;
205
206         r = rua_dbus_signal_unsubscribe(callback_id);
207
208         return r;
209 }
210
211 API int rua_unregister_update_cb(int callback_id)
212 {
213         return rua_unregister_update_cb_for_uid(callback_id, getuid());
214 }
215
216 API int rua_history_get_rec(struct rua_rec *rec, char **table, int nrows, int ncols,
217                         int row)
218 {
219         char **db_result = NULL;
220         char *tmp = NULL;
221
222         if (rec == NULL)
223                 return -1;
224         if (table == NULL)
225                 return -1;
226         if (row >= nrows)
227                 return -1;
228
229         db_result = table + ((row + 1) * ncols);
230
231         tmp = db_result[RUA_COL_PKGNAME];
232         if (tmp)
233                 rec->pkg_name = tmp;
234
235         LOGI("get rec pkg_name %s", rec->pkg_name);
236         tmp = db_result[RUA_COL_APPPATH];
237         if (tmp)
238                 rec->app_path = tmp;
239
240         tmp = db_result[RUA_COL_ARG];
241         if (tmp)
242                 rec->arg = tmp;
243
244         tmp = db_result[RUA_COL_LAUNCHTIME];
245         if (tmp)
246                 rec->launch_time = atoi(tmp);
247
248         tmp = db_result[RUA_COL_INSTANCE_ID];
249         if (tmp && tmp[0] != '\0')
250                 rec->instance_id = tmp;
251         else
252                 rec->instance_id = NULL;
253
254         tmp = db_result[RUA_COL_INSTANCE_NAME];
255         if (tmp && tmp[0] != '\0')
256                 rec->instance_name = tmp;
257         else
258                 rec->instance_name = NULL;
259
260         tmp = db_result[RUA_COL_ICON];
261         if (tmp && tmp[0] != '\0')
262                 rec->icon = tmp;
263         else
264                 rec->icon = NULL;
265
266         tmp = db_result[RUA_COL_URI];
267         if (tmp && tmp[0] != '\0')
268                 rec->uri = tmp;
269         else
270                 rec->uri = NULL;
271
272         return 0;
273 }
274
275 API int rua_history_unload_db(char ***table)
276 {
277         if (*table) {
278                 sqlite3_free_table(*table);
279                 *table = NULL;
280                 return 0;
281         }
282         return -1;
283 }
284
285 API int rua_is_latest_app_for_uid(const char *pkg_name, uid_t uid)
286 {
287         static const char query[] =
288                 "SELECT pkg_name FROM rua_history "
289                 "ORDER BY launch_time DESC LIMIT 1";
290         int r = -1;
291         sqlite3_stmt *stmt;
292         const unsigned char *ct;
293         sqlite3 *db = NULL;
294
295         if (!pkg_name)
296                 return -1;
297
298         r = _rua_util_check_uid(uid);
299         if (r == -1)
300                 return r;
301
302         r = _rua_util_open_db(&db, SQLITE_OPEN_READONLY, uid, RUA_DB_NAME);
303         if (r != SQLITE_OK)
304                 return -1;
305
306         r = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
307         if (r != SQLITE_OK) {
308                 sqlite3_close_v2(db);
309                 return -1;
310         }
311
312         r = sqlite3_step(stmt);
313         if (r != SQLITE_ROW) {
314                 if (r != SQLITE_DONE)
315                         LOGE("step failed: %s", sqlite3_errmsg(db));
316                 sqlite3_finalize(stmt);
317                 sqlite3_close_v2(db);
318                 return -1;
319         }
320
321         ct = sqlite3_column_text(stmt, 0);
322         if (ct == NULL || ct[0] == '\0')
323                 r = -1;
324         else if (strncmp(pkg_name, (const char *)ct, strlen(pkg_name)) == 0)
325                 r = 0;
326         else
327                 r = -1;
328
329         sqlite3_finalize(stmt);
330         sqlite3_close_v2(db);
331
332         return r;
333 }
334
335 API int rua_is_latest_app(const char *pkg_name)
336 {
337         return rua_is_latest_app_for_uid(pkg_name, getuid());
338 }
339
340 API int rua_init(void)
341 {
342         return 0;
343 }
344
345 API int rua_fini(void)
346 {
347         return 0;
348 }
349
350 API int rua_delete_history_with_instance_id(const char *app_id,
351                 const char *instance_id)
352 {
353         int ret;
354         bundle *b;
355
356         if (app_id == NULL) {
357                 LOGE("Invalid parameter");
358                 return -1;
359         }
360
361         b = bundle_create();
362         if (b == NULL) {
363                 LOGE("Out of memory");
364                 return -1;
365         }
366
367         bundle_add_str(b, AUL_K_RUA_PKGNAME, app_id);
368         if (instance_id)
369                 bundle_add_str(b, AUL_K_RUA_INSTANCE_ID, instance_id);
370
371         ret = aul_delete_rua_history_for_uid(b, getuid());
372         bundle_free(b);
373         if (ret < 0) {
374                 LOGE("Failed to delete rua history - result(%d)", ret);
375                 return -1;
376         }
377
378         return 0;
379 }