[Task-mgr] Merge 3.0 into 2.4
[apps/core/preloaded/taskmanager.git] / src / list.c
1 /*
2  *  Task Manager
3  *
4  * Copyright (c) 2000 - 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
20 #include <Elementary.h>
21 #include <pkgmgr-info.h>
22 #include <rua.h>
23
24 #include "list.h"
25 #include "log.h"
26 #include "main.h"
27 #include "util.h"
28
29 typedef struct pkginfo {
30         char *appid;
31         bool taskmanage;
32         char *pkgid;
33         char *icon;
34         char *name;
35         bool nodisplay;
36 } private_pkginfo_s;
37
38 typedef struct {
39         char *appid;
40         int pid;
41 } private_pid_s;
42
43 static struct {
44         Eina_Hash *pkginfo_table;
45 } private_table_s = {
46         .pkginfo_table = NULL,
47 };
48
49
50
51 static void _pkglist_unretrieve_item(list_type_default_s *default_info)
52 {
53         if (!default_info) {
54                 return;
55         }
56
57         if (default_info->name) {
58                 free(default_info->name);
59                 default_info->name = NULL;
60         }
61         if (default_info->icon) {
62                 free(default_info->icon);
63                 default_info->icon = NULL;
64         }
65         if (default_info->pkgid) {
66                 free(default_info->pkgid);
67                 default_info->pkgid = NULL;
68         }
69         if (default_info->arg) {
70                 free(default_info->arg);
71                 default_info->arg = NULL;
72         }
73         if (default_info->appid) {
74                 free(default_info->appid);
75                 default_info->appid = NULL;
76         }
77         if (default_info) {
78                 free(default_info);
79                 default_info = NULL;
80         }
81 }
82
83
84
85 static list_type_default_s *_pkglist_retrieve_item(const char *appid, const char *arg, time_t launch_time)
86 {
87         retv_if(!appid, NULL);
88
89         private_pkginfo_s *pkg_info = NULL;
90         list_type_default_s *default_info = NULL;
91
92         pkg_info = eina_hash_find(private_table_s.pkginfo_table, appid);
93         if (!pkg_info) {
94                 _D("app(%s) is not taskmanage app", appid);
95                 return NULL;
96         }
97
98         if (!pkg_info->taskmanage) {
99                 _D("app(%s) is not taskmanage app", appid);
100                 return NULL;
101         }
102
103         default_info = calloc(1, sizeof(*default_info));
104         retv_if(!default_info, NULL);
105
106         default_info->taskmanage = pkg_info->taskmanage;
107         default_info->launch_time = launch_time;
108         default_info->nodisplay = pkg_info->nodisplay;
109
110         default_info->appid = strdup(appid);
111         goto_if(!default_info->appid, ERROR);
112
113         if (arg) {
114                 default_info->arg = strdup(arg);
115                 goto_if(!default_info->arg, ERROR);
116         }
117
118         if (pkg_info->pkgid) {
119                 default_info->pkgid = strdup(pkg_info->pkgid);
120                 goto_if(!default_info->pkgid, ERROR);
121         } else {
122                 _E("Fail to get pkgid from pkg info table");
123                 goto ERROR;
124         }
125
126         if (pkg_info->icon) {
127                 default_info->icon = strdup(pkg_info->icon);
128                 goto_if(!default_info->icon, ERROR);
129         } else {
130                 _E("Fail to get icon from pkg info table");
131                 goto ERROR;
132         }
133
134         if (pkg_info->name) {
135                 default_info->name = strdup(pkg_info->name);
136                 goto_if(!default_info->name, ERROR);
137         } else {
138                 _E("Fail to get name from pkg info table");
139                 goto ERROR;
140         }
141
142         _D("list add id : [%s], icon : [%s], name : [%s]", pkg_info->pkgid, pkg_info->icon, pkg_info->name);
143
144         return default_info;
145
146 ERROR:
147
148         _pkglist_unretrieve_item(default_info);
149         return NULL;
150 }
151
152
153
154 int _get_pkginfo_cb(pkgmgrinfo_appinfo_h app_handle, void *user_data)
155 {
156         char *appid = NULL;
157         char *pkgid = NULL;
158         char *name = NULL;
159         char *icon = NULL;
160         private_pkginfo_s *pkg_info = NULL;
161
162         pkg_info = calloc(1, sizeof(*pkg_info));
163         retv_if(!pkg_info, PMINFO_R_ERROR);
164
165         memset(pkg_info, 0, sizeof(private_pkginfo_s));
166
167         pkgmgrinfo_appinfo_get_appid(app_handle, &appid);
168         goto_if(!appid, ERROR);
169
170         pkg_info->appid = strdup(appid);
171         goto_if(!pkg_info->appid, ERROR);
172
173         if (PMINFO_R_OK != pkgmgrinfo_appinfo_is_taskmanage(app_handle, &pkg_info->taskmanage)) {
174                 goto ERROR;
175         }
176
177         if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_pkgid(app_handle, &pkgid)) {
178                 goto ERROR;
179         }
180         pkg_info->pkgid = strdup(pkgid);
181         goto_if(!pkg_info->pkgid, ERROR);
182
183         if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_icon(app_handle, &icon)) {
184                 goto ERROR;
185         }
186         if (icon) {
187                 pkg_info->icon= strdup(icon);
188                 goto_if(!pkg_info->icon, ERROR);
189         }
190
191         if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_label(app_handle, &name)) {
192                 goto ERROR;
193         }
194         if (name) {
195                 pkg_info->name= strdup(name);
196                 goto_if(!pkg_info->name, ERROR);
197         }
198
199         if (PMINFO_R_OK != pkgmgrinfo_appinfo_is_nodisplay(app_handle, &pkg_info->nodisplay)) {
200                 goto ERROR;
201         }
202
203         eina_hash_add(private_table_s.pkginfo_table, pkg_info->appid, pkg_info);
204
205         return PMINFO_R_OK;
206
207 ERROR:
208         if (pkg_info->name) free(pkg_info->name);
209         if (pkg_info->icon) free(pkg_info->icon);
210         if (pkg_info->pkgid) free(pkg_info->pkgid);
211         if (pkg_info->appid) free(pkg_info->appid);
212         free(pkg_info);
213
214         return PMINFO_R_ERROR;
215 }
216
217
218
219 static task_mgr_error_e _create_pkginfo_table(void)
220 {
221         _D("");
222         pkgmgrinfo_appinfo_filter_h handle;
223
224         int ret = 0;
225
226         private_table_s.pkginfo_table = eina_hash_string_superfast_new(NULL);
227
228         ret = pkgmgrinfo_appinfo_filter_create(&handle);
229         if (PMINFO_R_OK != ret) {
230                 return TASK_MGR_ERROR_FAIL;
231         }
232
233         ret = pkgmgrinfo_appinfo_filter_add_bool(handle, PMINFO_APPINFO_PROP_APP_TASKMANAGE, 1);
234         if (PMINFO_R_OK != ret) {
235                 pkgmgrinfo_appinfo_filter_destroy(handle);
236                 return TASK_MGR_ERROR_FAIL;
237         }
238
239         ret = pkgmgrinfo_appinfo_filter_foreach_appinfo(handle, _get_pkginfo_cb, NULL);
240         if (ret != PMINFO_R_OK) {
241                 pkgmgrinfo_appinfo_filter_destroy(handle);
242                 return TASK_MGR_ERROR_FAIL;
243         }
244
245         pkgmgrinfo_appinfo_filter_destroy(handle);
246
247         return TASK_MGR_ERROR_NONE;
248 }
249
250
251
252 static Eina_Bool _remove_pkginfo(const Eina_Hash *hash, const void *key, void *data, void *fdata)
253 {
254         retv_if(!data, EINA_FALSE);
255
256         private_pkginfo_s *pkg_info = data;
257
258         if (pkg_info->name) free(pkg_info->name);
259         if (pkg_info->icon) free(pkg_info->icon);
260         if (pkg_info->pkgid) free(pkg_info->pkgid);
261         if (pkg_info->appid) free(pkg_info->appid);
262
263         return EINA_TRUE;
264 }
265
266
267
268 static void _destroy_pkginfo_table(void)
269 {
270         _D("");
271
272         eina_hash_foreach(private_table_s.pkginfo_table, _remove_pkginfo, NULL);
273         eina_hash_free(private_table_s.pkginfo_table);
274         private_table_s.pkginfo_table = NULL;
275 }
276
277
278
279 static int _launch_time_sort_cb(const void *d1, const void *d2)
280 {
281         list_type_default_s *tmp1 = (list_type_default_s *) d1;
282         list_type_default_s *tmp2 = (list_type_default_s *) d2;
283
284         if (!tmp1) return -1;
285         if (!tmp2) return 1;
286
287         if (!tmp1->appid) return 1;
288         else if (!tmp2->appid) return -1;
289
290         return tmp1->launch_time >= tmp2->launch_time ? -1 : 1;
291 }
292
293
294
295 extern task_mgr_error_e list_sort(Eina_List *list, int (*_sort_cb)(const void *d1, const void *d2))
296 {
297         retv_if(!list, TASK_MGR_ERROR_INVALID_PARAMETER);
298
299         list = eina_list_sort(list, eina_list_count(list), _sort_cb);
300         retv_if(!list, TASK_MGR_ERROR_FAIL);
301
302         return TASK_MGR_ERROR_NONE;
303 }
304
305
306
307 extern task_mgr_error_e list_create(Eina_List **pkg_list)
308 {
309         _D("");
310
311         rua_init();
312         char **table = NULL;
313         list_type_default_s *default_info = NULL;
314
315         int nrows = 0, ncols = 0;
316         int row = 0;
317
318         retv_if (TASK_MGR_ERROR_NONE != _create_pkginfo_table(), TASK_MGR_ERROR_FAIL);
319
320         if (-1 == rua_history_load_db(&table, &nrows, &ncols)) {
321                 if (table) {
322                         rua_history_unload_db(&table);
323                 }
324                 return TASK_MGR_ERROR_FAIL;
325         }
326
327         _D("Apps in rua history is %d", nrows);
328
329         for (; row < nrows; row++) {
330                 struct rua_rec rec_result = {0, };
331                 rua_history_get_rec(&rec_result, table, nrows, ncols, row);
332                 default_info = _pkglist_retrieve_item(rec_result.pkg_name, rec_result.arg, rec_result.launch_time);
333                 if (default_info) {
334                         *pkg_list = eina_list_append(*pkg_list, default_info);
335                 }
336         }
337
338         if (*pkg_list && TASK_MGR_ERROR_NONE != list_sort(*pkg_list, _launch_time_sort_cb)) {
339                 _E("Cannot sort pkg_list");
340         }
341
342         if (!eina_list_count(*pkg_list)) {
343                 _D("list is empty.");
344                 _pkglist_unretrieve_item(default_info);
345                 return TASK_MGR_ERROR_NO_DATA;
346
347         }
348
349         return TASK_MGR_ERROR_NONE;
350 }
351
352
353
354 extern void list_destroy(Eina_List *pkg_list)
355 {
356         _D("");
357         list_type_default_s *default_info = NULL;
358
359         _destroy_pkginfo_table();
360
361         if (!pkg_list) {
362                 _D("pkg_list is null");
363                 return;
364         }
365
366         EINA_LIST_FREE(pkg_list, default_info) {
367                 if (!default_info) {
368                         continue;
369                 }
370                 _pkglist_unretrieve_item(default_info);
371         }
372
373         pkg_list = NULL;
374         rua_fini();
375 }