Release version 0.13.7
[platform/core/api/app-manager.git] / src / app_context.c
1 /*
2  * Copyright (c) 2011 - 2020 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 <glib.h>
18 #include <pthread.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23
24 #include <aul.h>
25 #include <aul_app_event.h>
26 #include <aul_app_manager.h>
27 #include <aul_window.h>
28
29 #include "app_context.h"
30 #include "app_manager.h"
31 #include "app_manager_internal.h"
32 #include "log_private.h"
33
34 #define HANDLE_TO_AUL_HANDLE(h) ((aul_app_context_h)(app_context_h)(h))
35 #define AUL_HANDLE_TO_HANDLE(h) ((app_context_h)(aul_app_context_h)(h))
36
37 typedef struct app_event_info_s {
38         aul_app_event_h handle;
39         char *appid;
40         app_manager_app_context_status_cb callback;
41         void *user_data;
42 } app_event_info_t;
43
44 static GList *__event_info_list;
45
46 static int __aul_error_convert(int res)
47 {
48         switch (res) {
49         case AUL_R_EINVAL:
50                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
51         case AUL_R_ENOAPP:
52         case AUL_R_ENOENT:
53                 return APP_MANAGER_ERROR_NO_SUCH_APP;
54         case AUL_R_ENOMEM:
55                 return APP_MANAGER_ERROR_OUT_OF_MEMORY;
56         case AUL_R_EILLACC:
57                 return APP_MANAGER_ERROR_PERMISSION_DENIED;
58         default:
59                 return APP_MANAGER_ERROR_IO_ERROR;
60         }
61 }
62
63 static app_state_e app_context_get_app_status(int status)
64 {
65         app_state_e app_state;
66
67         switch (status) {
68         case STATUS_VISIBLE:
69                 app_state = APP_STATE_FOREGROUND;
70                 break;
71         case STATUS_LAUNCHING:
72         case STATUS_BG:
73                 app_state = APP_STATE_BACKGROUND;
74                 break;
75         case STATUS_SERVICE:
76                 app_state = APP_STATE_SERVICE;
77                 break;
78         case STATUS_TERMINATE:
79                 app_state = APP_STATE_TERMINATED;
80                 break;
81         default:
82                 app_state = APP_STATE_UNDEFINED;
83                 break;
84         }
85
86         return app_state;
87 }
88
89 int app_context_foreach_app_context(app_manager_app_context_cb callback,
90                 void *user_data)
91 {
92         int ret;
93
94         if (!callback) {
95                 _E("Invalid parameter");
96                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
97         }
98
99         ret = aul_app_manager_foreach_app_context(
100                         (aul_app_manager_app_context_cb)callback,
101                         user_data);
102         if (ret != AUL_R_OK) {
103                 _E("Failed to retrieve app context. error(%d)", ret);
104                 return APP_MANAGER_ERROR_IO_ERROR;
105         }
106
107         return APP_MANAGER_ERROR_NONE;
108 }
109
110 int app_context_foreach_running_app_context(app_manager_app_context_cb callback,
111                 void *user_data)
112 {
113         int ret;
114
115         if (!callback) {
116                 _E("Invalid parameter");
117                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
118         }
119
120         ret = aul_app_manager_foreach_all_app_context(
121                         (aul_app_manager_app_context_cb)callback,
122                         user_data);
123         if (ret != AUL_R_OK) {
124                 _E("Failed to retrieve all app context. error(%d)", ret);
125                 return APP_MANAGER_ERROR_IO_ERROR;
126         }
127
128         return APP_MANAGER_ERROR_NONE;
129 }
130
131 int app_context_get_app_context(const char *app_id, app_context_h *app_context)
132 {
133         aul_app_context_h handle;
134         int ret;
135
136         if (!app_id || !app_context) {
137                 _E("Invalid parameter");
138                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
139         }
140
141         ret = aul_app_context_create(app_id, &handle);
142         if (ret != AUL_R_OK) {
143                 _E("Failed to create app context. error(%d)", ret);
144                 return __aul_error_convert(ret);
145         }
146
147         *app_context = AUL_HANDLE_TO_HANDLE(handle);
148
149         return ret;
150 }
151
152 API int app_context_destroy(app_context_h app_context)
153 {
154         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
155
156         if (!handle) {
157                 _E("Invalid parameter");
158                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
159         }
160
161         aul_app_context_destroy(handle);
162
163         return APP_MANAGER_ERROR_NONE;
164 }
165
166 API int app_context_get_package(app_context_h app_context, char **package)
167 {
168         dlog_print(DLOG_WARN, LOG_TAG, "DEPRECATION WARNING: app_context_get_package() is deprecated and will be removed from next release. Use app_context_get_app_id() instead.");
169         /* TODO: this function must be deprecated */
170         return app_context_get_app_id(app_context, package);
171 }
172
173 API int app_context_get_app_id(app_context_h app_context, char **app_id)
174 {
175         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
176         int ret;
177
178         if (!app_context || !app_id) {
179                 _E("Invalid parameter");
180                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
181         }
182
183         ret = aul_app_context_get_app_id(handle, app_id);
184         if (ret != AUL_R_OK)
185                 return __aul_error_convert(ret);
186
187         return APP_MANAGER_ERROR_NONE;
188 }
189
190 API int app_context_get_pid(app_context_h app_context, pid_t *pid)
191 {
192         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
193         int ret;
194
195         if (!app_context || !pid) {
196                 _E("Invalid parameter");
197                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
198         }
199
200         ret = aul_app_context_get_pid(handle, pid);
201         if (ret != AUL_R_OK)
202                 return __aul_error_convert(ret);
203
204         return APP_MANAGER_ERROR_NONE;
205 }
206
207 API int app_context_get_package_id(app_context_h app_context, char **pkg_id)
208 {
209         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
210         int ret;
211
212         if (!app_context || !pkg_id) {
213                 _E("Invalid parameter");
214                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
215         }
216
217         ret = aul_app_context_get_pkg_id(handle, pkg_id);
218         if (ret != AUL_R_OK)
219                 return __aul_error_convert(ret);
220
221         return APP_MANAGER_ERROR_NONE;
222 }
223
224 API int app_context_get_app_state(app_context_h app_context, app_state_e *state)
225 {
226         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
227         int status;
228         int ret;
229
230         if (!app_context || !state) {
231                 _E("Invalid parameter");
232                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
233         }
234
235         ret = aul_app_context_get_status(handle, &status);
236         if (ret != AUL_R_OK)
237                 return __aul_error_convert(ret);
238
239         *state = app_context_get_app_status(status);
240
241         return APP_MANAGER_ERROR_NONE;
242 }
243
244 API int app_context_is_terminated(app_context_h app_context, bool *terminated)
245 {
246         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
247         bool is_running;
248         int ret;
249
250         if (!app_context || !terminated) {
251                 _E("Invalid parameter");
252                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
253         }
254
255         ret = aul_app_context_is_running(handle, &is_running);
256         if (ret != AUL_R_OK)
257                 return __aul_error_convert(ret);
258
259         if (is_running)
260                 *terminated = false;
261         else
262                 *terminated = true;
263
264         return APP_MANAGER_ERROR_NONE;
265 }
266
267 API int app_context_is_equal(app_context_h lhs, app_context_h rhs, bool *equal)
268 {
269         aul_app_context_h lh = HANDLE_TO_AUL_HANDLE(lhs);
270         aul_app_context_h rh = HANDLE_TO_AUL_HANDLE(rhs);
271         int ret;
272
273         if (!lhs || !rhs || !equal) {
274                 _E("Invalid parameter");
275                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
276         }
277
278         ret = aul_app_context_is_equal(lh, rh, equal);
279         if (ret != AUL_R_OK)
280                 return __aul_error_convert(ret);
281
282         return APP_MANAGER_ERROR_NONE;
283 }
284
285 API int app_context_is_sub_app(app_context_h app_context, bool *is_sub_app)
286 {
287         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
288         int ret;
289
290         if (!app_context || !is_sub_app) {
291                 _E("Invalid parameter");
292                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
293         }
294
295         ret = aul_app_context_is_sub_app(handle, is_sub_app);
296         if (ret != AUL_R_OK)
297                 return __aul_error_convert(ret);
298
299         return APP_MANAGER_ERROR_NONE;
300 }
301
302 API int app_context_clone(app_context_h *clone, app_context_h app_context)
303 {
304         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
305         aul_app_context_h new_handle;
306         int ret;
307
308         if (!clone || !app_context) {
309                 _E("Invalid parameter");
310                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
311         }
312
313         ret = aul_app_context_clone(handle, &new_handle);
314         if (ret != AUL_R_OK)
315                 return __aul_error_convert(ret);
316
317         *clone = AUL_HANDLE_TO_HANDLE(new_handle);
318
319         return APP_MANAGER_ERROR_NONE;
320 }
321
322 typedef struct _event_cb_context_ {
323         aul_app_event_h handle;
324         GHashTable *pid_table;
325         app_manager_app_context_event_cb callback;
326         void *user_data;
327 } event_cb_context_s;
328
329 static pthread_mutex_t event_cb_context_mutex = PTHREAD_MUTEX_INITIALIZER;
330 static event_cb_context_s *event_cb_context = NULL;
331
332 static void app_context_lock_event_cb_context()
333 {
334         pthread_mutex_lock(&event_cb_context_mutex);
335 }
336
337 static void app_context_unlock_event_cb_context()
338 {
339         pthread_mutex_unlock(&event_cb_context_mutex);
340 }
341
342 static bool __load_all_app_context_cb_locked(app_context_h app_context,
343                 void *user_data)
344 {
345         char *app_id = NULL;
346         int pid;
347         bool sub_app;
348
349         app_context_get_app_id(app_context, &app_id);
350         app_context_get_pid(app_context, &pid);
351         app_context_is_sub_app(app_context, &sub_app);
352         SECURE_LOGI("app_id(%s), pid(%d), sub_app(%s)",
353                         app_id, pid, sub_app ? "true" : "false");
354         free(app_id);
355
356         g_hash_table_insert(event_cb_context->pid_table, GINT_TO_POINTER(pid),
357                         GINT_TO_POINTER(pid));
358         return true;
359 }
360
361 static void __app_context_launched_event_cb(aul_app_context_h app_context,
362                 void *user_data)
363 {
364         int pid;
365
366         aul_app_context_get_pid(app_context, &pid);
367         app_context_lock_event_cb_context();
368         if (event_cb_context && event_cb_context->pid_table) {
369                 g_hash_table_insert(event_cb_context->pid_table,
370                                 GINT_TO_POINTER(pid), GINT_TO_POINTER(pid));
371                 event_cb_context->callback((app_context_h)app_context,
372                                 APP_CONTEXT_EVENT_LAUNCHED,
373                                 event_cb_context->user_data);
374         } else {
375                 _E("Invalid context. pid(%d)", pid);
376         }
377         app_context_unlock_event_cb_context();
378 }
379
380 static void __app_context_terminated_event_cb(aul_app_context_h app_context,
381                 void *user_data)
382 {
383         int pid;
384
385         aul_app_context_get_pid(app_context, &pid);
386         app_context_lock_event_cb_context();
387         if (event_cb_context && event_cb_context->pid_table) {
388                 if (g_hash_table_contains(event_cb_context->pid_table,
389                                         GINT_TO_POINTER(pid))) {
390                         event_cb_context->callback(app_context,
391                                         APP_CONTEXT_EVENT_TERMINATED,
392                                         event_cb_context->user_data);
393                         g_hash_table_remove(event_cb_context->pid_table,
394                                         GINT_TO_POINTER(pid));
395                 }
396         } else {
397                 _E("Invalid context. pid(%d)", pid);
398         }
399         app_context_unlock_event_cb_context();
400 }
401
402 static void __event_cb_context_fini(void)
403 {
404         if (!event_cb_context)
405                 return;
406
407         if (event_cb_context->handle)
408                 aul_app_event_destroy(event_cb_context->handle);
409
410         if (event_cb_context->pid_table)
411                 g_hash_table_destroy(event_cb_context->pid_table);
412
413         free(event_cb_context);
414         event_cb_context = NULL;
415 }
416
417 static int __event_cb_context_init(void)
418 {
419         int ret;
420
421         if (event_cb_context)
422                 return APP_MANAGER_ERROR_NONE;
423
424         event_cb_context = calloc(1, sizeof(event_cb_context_s));
425         if (event_cb_context == NULL) {
426                 _E("Out of memory");
427                 return APP_MANAGER_ERROR_OUT_OF_MEMORY;
428         }
429
430         event_cb_context->pid_table = g_hash_table_new(g_direct_hash,
431                         g_direct_equal);
432         if (event_cb_context->pid_table == NULL) {
433                 _E("Failed to create hash table");
434                 __event_cb_context_fini();
435                 return APP_MANAGER_ERROR_OUT_OF_MEMORY;
436         }
437
438         app_context_foreach_app_context(__load_all_app_context_cb_locked, NULL);
439
440         ret = aul_app_event_create(__app_context_launched_event_cb,
441                         __app_context_terminated_event_cb,
442                         NULL,
443                         &event_cb_context->handle);
444         if (ret != AUL_R_OK) {
445                 _E("aul_app_context_create() is failed. error(%d)", ret);
446                 __event_cb_context_fini();
447                 return APP_MANAGER_ERROR_IO_ERROR;
448         }
449
450         return APP_MANAGER_ERROR_NONE;
451 }
452
453 int app_context_set_event_cb(app_manager_app_context_event_cb callback,
454                 void *user_data)
455 {
456         int ret;
457
458         if (!callback) {
459                 _E("Invalid parameter");
460                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
461         }
462
463         app_context_lock_event_cb_context();
464
465         ret = __event_cb_context_init();
466         if (ret != APP_MANAGER_ERROR_NONE) {
467                 app_context_unlock_event_cb_context();
468                 return ret;
469         }
470
471         event_cb_context->callback = callback;
472         event_cb_context->user_data = user_data;
473
474         app_context_unlock_event_cb_context();
475
476         return APP_MANAGER_ERROR_NONE;
477 }
478
479 void app_context_unset_event_cb(void)
480 {
481         app_context_lock_event_cb_context();
482         __event_cb_context_fini();
483         app_context_unlock_event_cb_context();
484 }
485
486 static void __destroy_app_event_info(gpointer data)
487 {
488         app_event_info_t *info = data;
489
490         if (!info)
491                 return;
492
493         free(info->appid);
494         free(info);
495 }
496
497 static app_event_info_t *__create_app_event_info(const char *appid,
498                 app_manager_app_context_status_cb callback,
499                 void *user_data)
500 {
501         app_event_info_t *info;
502
503         info = calloc(1, sizeof(app_event_info_t));
504         if (!info) {
505                 _E("Out of memory");
506                 return NULL;
507         }
508
509         info->appid = strdup(appid);
510         if (!info->appid) {
511                 _E("Failed to duplicate application ID(%s)", appid);
512                 __destroy_app_event_info(info);
513                 return NULL;
514         }
515
516         info->callback = callback;
517         info->user_data = user_data;
518
519         return info;
520 }
521
522 static app_event_info_t *__pop_app_event_info(const char *appid,
523                 app_manager_app_context_status_cb callback)
524 {
525         app_event_info_t *info;
526         GList *iter;
527
528         app_context_lock_event_cb_context();
529         iter = __event_info_list;
530         while (iter) {
531                 info = (app_event_info_t *)iter->data;
532                 iter = g_list_next(iter);
533                 if (info->callback == callback &&
534                                 !strcmp(info->appid, appid)) {
535                         __event_info_list = g_list_remove(
536                                         __event_info_list, info);
537                         app_context_unlock_event_cb_context();
538                         return info;
539                 }
540         }
541         app_context_unlock_event_cb_context();
542
543         return NULL;
544 }
545
546 static void __push_app_event_info(app_event_info_t *info)
547 {
548         app_context_lock_event_cb_context();
549         __event_info_list = g_list_append(__event_info_list, info);
550         app_context_unlock_event_cb_context();
551 }
552
553 static bool __exist_app_event_info(app_event_info_t *info)
554 {
555         GList *found;
556
557         app_context_lock_event_cb_context();
558         found = g_list_find(__event_info_list, info);
559         app_context_unlock_event_cb_context();
560
561         if (found)
562                 return true;
563
564         return false;
565 }
566
567 static void __aul_app_event_launched_cb(aul_app_context_h app_context,
568                 void *user_data)
569 {
570         app_event_info_t *info = user_data;
571
572         if (!__exist_app_event_info(info)) {
573                 _E("Invalid context");
574                 return;
575         }
576
577         info->callback(AUL_HANDLE_TO_HANDLE(app_context),
578                         APP_CONTEXT_STATUS_LAUNCHED,
579                         info->user_data);
580 }
581
582 static void __aul_app_event_terminated_cb(aul_app_context_h app_context,
583                 void *user_data)
584 {
585         app_event_info_t *info = user_data;
586
587         if (!__exist_app_event_info(info)) {
588                 _E("Invalid context");
589                 return;
590         }
591
592         info->callback(AUL_HANDLE_TO_HANDLE(app_context),
593                         APP_CONTEXT_STATUS_TERMINATED,
594                         info->user_data);
595 }
596
597 int app_context_set_status_cb(app_manager_app_context_status_cb callback,
598                 const char *appid, void *user_data)
599 {
600         app_event_info_t *info;
601         int ret;
602
603         if (!callback || !appid) {
604                 _E("Invalid parameter");
605                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
606         }
607
608         info = __create_app_event_info(appid, callback, user_data);
609         if (!info)
610                 return APP_MANAGER_ERROR_OUT_OF_MEMORY;
611
612         ret = aul_app_event_create_with_appid(appid,
613                         __aul_app_event_launched_cb,
614                         __aul_app_event_terminated_cb,
615                         info,
616                         &info->handle);
617         if (ret != AUL_R_OK) {
618                 __destroy_app_event_info(info);
619                 return __aul_error_convert(ret);
620         }
621
622         __push_app_event_info(info);
623
624         return APP_MANAGER_ERROR_NONE;
625 }
626
627 int app_context_unset_status_cb(app_manager_app_context_status_cb callback,
628                 const char *appid)
629 {
630         app_event_info_t *info;
631
632         if (!callback || !appid) {
633                 _E("Invalid parameter");
634                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
635         }
636
637         info = __pop_app_event_info(appid, callback);
638         if (!info)
639                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
640
641         aul_app_event_destroy(info->handle);
642         __destroy_app_event_info(info);
643
644         return APP_MANAGER_ERROR_NONE;
645 }
646
647 int app_context_get_app_context_by_instance_id(const char *app_id,
648                 const char *instance_id,
649                 app_context_h *app_context)
650 {
651         aul_app_context_h handle;
652         int ret;
653
654         if (!app_id || !instance_id || !app_context) {
655                 _E("Invalid parameter");
656                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
657         }
658
659         ret = aul_app_context_create_with_inst_id(app_id, instance_id, &handle);
660         if (ret != AUL_R_OK)
661                 return __aul_error_convert(ret);
662
663         *app_context = AUL_HANDLE_TO_HANDLE(handle);
664
665         return APP_MANAGER_ERROR_NONE;
666 }
667
668 int app_context_get_instance_id(app_context_h app_context, char **instance_id)
669 {
670         aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context);
671         int ret;
672
673         if (!app_context || !instance_id) {
674                 _E("Invalid parameter");
675                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
676         }
677
678         ret = aul_app_context_get_inst_id(handle, instance_id);
679         if (ret != AUL_R_OK)
680                 return __aul_error_convert(ret);
681
682         return APP_MANAGER_ERROR_NONE;
683 }
684
685 int app_context_get_app_context_by_pid(pid_t pid, app_context_h *app_context)
686 {
687         aul_app_context_h handle;
688         int ret;
689
690         if (pid <= 0 || !app_context) {
691                 _E("Invalid parameter");
692                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
693         }
694
695         ret = aul_app_context_create_with_pid(pid, &handle);
696         if (ret != AUL_R_OK)
697                 return __aul_error_convert(ret);
698
699         *app_context = AUL_HANDLE_TO_HANDLE(handle);
700
701         return ret;
702 }
703
704 static void __foreach_window_info_cb(aul_window_info_h info, void *data)
705 {
706         GList **list = (GList **)data;
707         int visibility;
708         int pid;
709         int ret;
710
711         if (info == NULL || list == NULL) {
712                 LOGE("Invalid parameter");
713                 return;
714         }
715
716         ret = aul_window_info_get_visibility(info, &visibility);
717         if (ret < 0) {
718                 LOGE("Failed to get window visibility");
719                 return;
720         }
721
722         if (visibility < 0 || visibility > 1)
723                 return;
724
725         ret = aul_window_info_get_pid(info, &pid);
726         if (ret < 0) {
727                 LOGE("Failed to get pid");
728                 return;
729         }
730
731         *list = g_list_append(*list, GINT_TO_POINTER(pid));
732 }
733
734 static bool __foreach_app_context_cb(aul_app_context_h aul_app_context,
735                 void *user_data)
736 {
737         GHashTable *app_context_table = (GHashTable *)user_data;
738         aul_app_context_h app_context;
739         int pid;
740         int ret;
741
742         ret = aul_app_context_clone(aul_app_context, &app_context);
743         if (ret != AUL_R_OK) {
744                 _E("Failed to clone app con text. error(%d)", ret);
745                 return true;
746         }
747
748         aul_app_context_get_pid(aul_app_context, &pid);
749         g_hash_table_insert(app_context_table, GINT_TO_POINTER(pid),
750                         app_context);
751
752         return true;
753 }
754
755 int app_context_foreach_visible_app_context(app_manager_app_context_cb callback,
756                 void *user_data)
757 {
758         aul_window_stack_h handle = NULL;
759         GHashTable *app_context_table;
760         app_context_h app_context;
761         GList *pid_list = NULL;
762         GList *iter;
763         int ret;
764
765         if (callback == NULL)
766                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
767
768         app_context_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
769                         NULL, (GDestroyNotify)app_context_destroy);
770         if (app_context_table == NULL)
771                 return APP_MANAGER_ERROR_OUT_OF_MEMORY;
772
773         ret = aul_app_manager_foreach_all_app_context(__foreach_app_context_cb,
774                         app_context_table);
775         if (ret != AUL_R_OK) {
776                 g_hash_table_destroy(app_context_table);
777                 return APP_MANAGER_ERROR_IO_ERROR;
778         }
779
780         ret = aul_window_stack_get(&handle);
781         if (ret < 0) {
782                 g_hash_table_destroy(app_context_table);
783                 return APP_MANAGER_ERROR_IO_ERROR;
784         }
785
786         ret = aul_window_stack_foreach(handle,
787                         __foreach_window_info_cb, &pid_list);
788         if (ret < 0) {
789                 aul_window_stack_del(handle);
790                 g_hash_table_destroy(app_context_table);
791                 return APP_MANAGER_ERROR_IO_ERROR;
792         }
793         aul_window_stack_del(handle);
794
795         iter = g_list_first(pid_list);
796         while (iter) {
797                 app_context = (app_context_h)g_hash_table_lookup(
798                                 app_context_table, iter->data);
799                 if (app_context) {
800                         if (!callback(app_context, user_data))
801                                 break;
802                 }
803                 iter = g_list_next(iter);
804         }
805         g_list_free(pid_list);
806         g_hash_table_destroy(app_context_table);
807
808         return APP_MANAGER_ERROR_NONE;
809 }