8d9febec58ee5329c310951ed279a6ed76f0bc3b
[apps/core/preloaded/taskmanager.git] / src / _logic.c
1 /*
2  * org.tizen.taskmgr
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Flora License, Version 1.1 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://floralicense.org/license/
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an AS IS BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18
19
20
21 #include <appcore-common.h>
22 #include <ail.h>
23 #include <aul.h>
24 #include <Ecore_X.h>
25 #include <vconf.h>
26
27 #include "taskmanager.h"
28 #include "_util_log.h"
29 #include "_util_efl.h"
30 #include "_genlist.h"
31 #include "_eina.h"
32 #include "_progressbar.h"
33 #include "_info.h"
34
35 int _dead_cb(int pid, void *data)
36 {
37 _D("func\n");
38         /* redraw list */
39         struct appdata *ad = (struct appdata *)data;
40         retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
41
42         int ret = -1;
43
44         if (ad->update_timer) {
45                 ecore_timer_del(ad->update_timer);
46                 ad->update_timer = NULL;
47         }
48
49         ret = _subt_einalist_item(ad, pid);
50         _D("mode(%d) count(%d) pid(%d) \n", ad->mode, ad->endcnt, pid);
51
52         if (ret != -1) {
53                 switch (ad->mode) {
54                 default:
55                 case MODE_END_INUSE:
56                 case MODE_DEL_HISTORY:
57                 case MODE_DEL_ALL_HISTORY:
58                 case MODE_KILL_INUSE:
59                         _D("aa\n");
60                         _del_popup_timer(ad);
61                         _del_progressbar(ad);
62                         refresh_app_info(ad);
63                         //_restart_pthread(ad);
64                         break;
65
66                 case MODE_END_ALL_INUSE:
67                 case MODE_KILL_ALL_INUSE:
68                         _D("bb\n");
69                         if (ad->endcnt <= 1) {
70                                 _D("count set 0\n");
71
72                                 if(ad->killall_timer)
73                                 {
74                                         ecore_timer_del(ad->killall_timer);
75                                         ad->killall_timer = NULL;
76                                 }
77
78                                 _del_popup_timer(ad);
79                                 _del_progressbar(ad);
80                                 if (ad->popup_ask) {
81                                         evas_object_del(ad->popup_ask);
82                                         ad->popup_ask = NULL;
83                                 }
84                                 refresh_app_info(ad);
85
86                         } else {
87                                 ad->endcnt--;
88                         }
89                         break;
90                 }
91         }
92
93         return ret;
94 }
95
96 static void _back_cb(void *data, Evas_Object *obj, void *event_info)
97 {
98         elm_exit();
99 }
100
101 int _app_create(struct appdata *ad)
102 {
103         Evas_Object *ly, *bg, *nv, *bt, *gl;
104         Evas_Object *conform = NULL;
105         int w, h;
106
107         ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
108
109         retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
110         ad->ending = EINA_FALSE;
111
112         conform = elm_conformant_add(ad->win);
113         retvm_if(conform == NULL, -1, "Failed to add conformant \n");
114         evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
115         elm_win_resize_object_add(ad->win, conform);
116         evas_object_show(conform);
117
118         ly = _add_layout_main(conform, EINA_TRUE, EINA_FALSE);
119         retvm_if(ly == NULL, -1, "Failed to add layout main\n");
120         elm_object_content_set(conform, ly);
121         evas_object_resize(ly, w, h);
122
123         bg = _add_bg(ad->win, "group_list");
124         retvm_if(bg == NULL, -1, "Failed to add bg\n");
125         elm_object_part_content_set(ly, "elm.swallow.bg", bg);
126
127         nv = _add_naviframe(ly);
128         retvm_if(nv == NULL, -1, "Failed to add naviframe\n");
129         ad->nv = nv;
130
131         ly = _add_layout(ad->nv, EDJ_NAME, GRP_TM);
132         retvm_if(ly == NULL, -1, "Failed to add layout\n");
133         ad->ly = ly;
134
135         /* Load default content (running task) */
136         gl = _add_genlist(ly);
137         retvm_if(gl == NULL, -1, "Failed to add genlist\n");
138         elm_genlist_block_count_set(gl, 20);
139         evas_object_data_set(gl, "appdata", ad);
140         elm_object_part_content_set(ly, "list", gl);
141         ad->gl = gl;
142
143         bt = elm_button_add(nv);
144         retvm_if(bt == NULL, -1, "Failed to add button\n");
145         elm_object_style_set(bt, "naviframe/end_btn/default");
146         evas_object_smart_callback_add(bt, "clicked", _back_cb, ad);
147
148         elm_naviframe_item_push(nv,
149                         T_("IDS_TASKMGR_HEADER_TASK_SWITCHER"),
150                         bt, NULL, ly, NULL);
151
152         return 0;
153 }
154 static void _get_win_geometry(struct appdata *ad)
155 {
156         Ecore_X_Window focus_win;
157         Ecore_X_Window root_win;
158
159         focus_win = ecore_x_window_focus_get();
160         root_win = ecore_x_window_root_get(focus_win);
161         ecore_x_window_size_get(root_win, &ad->root_w, &ad->root_h);
162 }
163
164 /* this func is to exit taskmanager after launching application */
165 static Eina_Bool __climsg_cb(void *data, int type, void *event)
166 {
167 _D("%s\n", __func__);
168         static Atom a_deact;
169         pid_t pid_a, pid_d;
170
171         struct appdata *ad = (struct appdata *)data;
172         Ecore_X_Event_Client_Message *ev = event;
173
174         if(ev == NULL) {
175                 _E("Invalid argument: event is NULL\n");
176                 _exit_cb(ad);
177                 return ECORE_CALLBACK_CANCEL;
178         }
179
180         pid_a = ev->data.l[1];
181         pid_d = ev->data.l[3];
182         a_deact = ecore_x_atom_get("_X_ILLUME_DEACTIVATE_WINDOW");
183
184         /* when pid_a == pid_d, this is useless data */
185         if (pid_a == pid_d) {
186                 return ECORE_CALLBACK_RENEW;
187         }
188
189         if (ev->message_type == a_deact) {
190                 _exit_cb(ad);
191                 return ECORE_CALLBACK_CANCEL;
192         } else {
193                 _D("messagre is act\n");
194
195         }
196
197         return ECORE_CALLBACK_CANCEL;
198 }
199
200 static int runapp_count = 0;
201
202 int _runapp_info_get_count(const aul_app_info *ainfo, void *data)
203 {
204         ail_appinfo_h handle;
205         ail_error_e ret;
206         bool is_taskmanage;
207
208         retvm_if(ainfo == NULL, -1, "Invalid argument: ainfo is NULL\n");
209
210         retvm_if(ainfo->pid <= 0, -1, "Invalid pid(%u)\n", ainfo->pid);
211
212         /* filtering */
213         if (ainfo->pid == getpid())
214         {
215                 return 0;
216         }
217
218         retvm_if(ainfo->pkg_name == NULL, 0, "Invalid pkg_name(%s)\n", ainfo->pkg_name);
219
220         ret = ail_package_get_appinfo(ainfo->pkg_name, &handle);
221         retvm_if(ret != AIL_ERROR_OK, -1,
222                         "Failed to get appinfo, pkg_name:%s\n", ainfo->pkg_name);
223
224         ret = ail_appinfo_get_bool(handle, AIL_PROP_X_SLP_TASKMANAGE_BOOL, &is_taskmanage);
225         if (is_taskmanage == 0) {
226                 ret = ail_package_destroy_appinfo(handle);
227                 retvm_if(ret != AIL_ERROR_OK, -1, "Failed to destroy appinfo\n");
228                 return 0;
229         }
230
231         ++runapp_count;
232         _D("running(%s)\n", ainfo->pkg_name);
233         _D("runapp count : %d\n", runapp_count);
234
235         ret = ail_package_destroy_appinfo(handle);
236         retvm_if(ret != AIL_ERROR_OK, -1, "Failed to destroy appinfo\n");
237         return 0;
238 }
239
240 Eina_Bool _kill_all_timer_cb(void *data)
241 {
242         _D("func\n");
243
244         struct appdata *ad = data;
245
246         int ret = AUL_R_ERROR;
247         int retry_cnt = 0;
248         int sleep_value = 500;
249
250         runapp_count = 0;
251
252         while(ret != AUL_R_OK && retry_cnt < 5)
253         {
254                 usleep(sleep_value);
255                 ret = aul_app_get_running_app_info(_runapp_info_get_count, ad);
256
257                 if(ret != AUL_R_OK)
258                 {
259                         _D("Fail to get running app information\n");
260                 }
261
262                 retry_cnt++;
263                 sleep_value *= 2;
264         }
265         _D("runapp count : %d\n", runapp_count);
266
267         /* count inuse app number */
268         /** if(count == 0) dead_cb */
269         if(runapp_count == 0)
270         {
271                 _D("runapp_count == 0\n");
272                 _del_popup_timer(ad);
273                 _del_progressbar(ad);
274                 if (ad->popup_ask) {
275                         evas_object_del(ad->popup_ask);
276                         ad->popup_ask = NULL;
277                 }
278                 refresh_app_info(ad);
279                 //_restart_pthread(ad);
280                 return ECORE_CALLBACK_CANCEL;
281         }
282
283         return ECORE_CALLBACK_RENEW;
284 }
285
286 void _ok_response_cb(void *data, Evas_Object *obj, void *event_info)
287 {
288         struct appdata *ad = (struct appdata *)data;
289
290         retm_if(data == NULL, "Invalid argument: appdata is NULL\n");
291
292         switch (ad->mode) {
293                 case MODE_END_INUSE:
294                         if (ad->popup_ask) {
295                                 evas_object_del(ad->popup_ask);
296                                 ad->popup_ask = NULL;
297                         }
298                         _D("end inuse\n");
299                         _del_popup_timer(ad);
300                         _show_progressbar(ad);
301                         response_end_inuse(ad);
302                         //_restart_pthread(ad);
303                         break;
304
305                 case MODE_END_ALL_INUSE:
306                         _D("end all inuse\n");
307                         _del_popup_timer(ad);
308                         _show_progressbar(ad);
309                         _diable_popup(ad->popup_ask);
310                         response_end_all_inuse(ad);
311                         ad->killall_timer = ecore_timer_add(2.0, _kill_all_timer_cb, ad);
312                         break;
313
314                 case MODE_DEL_HISTORY:
315                         if (ad->popup_ask) {
316                                 evas_object_del(ad->popup_ask);
317                                 ad->popup_ask = NULL;
318                         }
319                         _D("del inuse\n");
320                         _del_popup_timer(ad);
321                         response_del_history(ad);
322                         break;
323
324                 case MODE_DEL_ALL_HISTORY:
325                         if (ad->popup_ask) {
326                                 evas_object_del(ad->popup_ask);
327                                 ad->popup_ask = NULL;
328                         }
329                         _D("del all inuse\n");
330                         _del_popup_timer(ad);
331                         response_del_all_history(ad);
332                         break;
333
334                 case MODE_KILL_INUSE:
335                         if (ad->popup_ask) {
336                                 evas_object_del(ad->popup_ask);
337                                 ad->popup_ask = NULL;
338                         }
339                         _D("kill all inuse\n");
340                         response_kill_inuse(ad);
341                         break;
342
343                 case MODE_KILL_ALL_INUSE:
344                         if (ad->popup_ask) {
345                                 evas_object_del(ad->popup_ask);
346                                 ad->popup_ask = NULL;
347                         }
348                         _D("kill all inuse\n");
349                         response_kill_all_inuse(ad);
350                         break;
351
352                 default:
353                         if (ad->popup_ask) {
354                                 evas_object_del(ad->popup_ask);
355                                 ad->popup_ask = NULL;
356                         }
357                         printf("[Wanning] taskmanager: check mode [%d]\n",
358                                         ad->mode);
359                         break;
360         }
361 }
362
363 void _cancel_response_cb(void *data, Evas_Object *obj, void *event_info)
364 {
365         struct appdata *ad = (struct appdata *)data;
366
367         retm_if(data == NULL, "Invalid argument: appdata is NULL\n");
368         if (ad->popup_ask) {
369                 evas_object_del(ad->popup_ask);
370                 ad->popup_ask = NULL;
371         }
372 }
373
374 Eina_Bool _create_idler_cb(void *data)
375 {
376         struct appdata *ad = (struct appdata *)data;
377         retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument\n");
378
379         _check_show_state();
380
381         evas_object_show(ad->win);
382
383         _key_grab(ad);
384
385         _get_win_geometry(ad);
386         ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, __climsg_cb, ad);
387
388         return ECORE_CALLBACK_CANCEL;
389 }
390
391
392