7014c4753cdb86b6c0cd52718069059662b4c58d
[platform/core/api/app-manager.git] / src / app_context.c
1 /*
2  * Copyright (c) 2011 - 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
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <pthread.h>
23
24 #include <glib.h>
25
26 #include <aul.h>
27 #include <dlog.h>
28 #include <pkgmgr-info.h>
29
30 #include "app_context.h"
31 #include "app_manager.h"
32 #include "app_manager_internal.h"
33
34 #ifdef LOG_TAG
35 #undef LOG_TAG
36 #endif
37
38 #define LOG_TAG "CAPI_APPFW_APP_MANAGER"
39
40 #define APPID_MAX 128
41
42 static int app_context_create(const char *app_id, pid_t pid, const char *pkg_id, app_state_e app_state, bool is_sub_app, app_context_h *app_context);
43
44 struct app_context_s {
45         char *app_id;
46         pid_t pid;
47         char *pkg_id;
48         app_state_e app_state;
49         bool is_sub_app;
50 };
51
52 typedef struct _foreach_context_ {
53         app_manager_app_context_cb callback;
54         void *user_data;
55         bool iteration;
56 } foreach_context_s;
57
58 typedef struct _retrieval_context_ {
59         const char *app_id;
60         pid_t pid;
61         char *pkg_id;
62         app_state_e app_state;
63         bool is_sub_app;
64         bool matched;
65         const char *instance_id;
66 } retrieval_context_s;
67
68 static app_manager_app_context_status_cb _status_cb;
69
70 static app_state_e app_context_get_app_status(int status)
71 {
72         app_state_e app_state;
73
74         switch (status) {
75         case STATUS_VISIBLE:
76                 app_state = APP_STATE_FOREGROUND;
77                 break;
78         case STATUS_LAUNCHING:
79         case STATUS_BG:
80                 app_state = APP_STATE_BACKGROUND;
81                 break;
82         case STATUS_SERVICE:
83                 app_state = APP_STATE_SERVICE;
84                 break;
85         case STATUS_TERMINATE:
86                 app_state = APP_STATE_TERMINATED;
87                 break;
88         default:
89                 app_state = APP_STATE_UNDEFINED;
90                 break;
91         }
92
93         return app_state;
94 }
95
96 static int app_context_foreach_app_context_cb(const aul_app_info *aul_app_context, void *cb_data)
97 {
98         foreach_context_s *foreach_context = cb_data;
99         app_context_h app_context;
100         app_state_e app_state;
101         bool is_sub_app = false;
102
103         if (foreach_context == NULL) {
104                 app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
105                 return 0;
106         }
107
108         if (foreach_context->iteration == true) {
109                 app_state = app_context_get_app_status(aul_app_context->status);
110
111                 if (aul_app_context->is_sub_app)
112                         is_sub_app = true;
113
114                 if (app_context_create(aul_app_context->appid,
115                                         aul_app_context->pid,
116                                         aul_app_context->pkgid,
117                                         app_state,
118                                         is_sub_app,
119                                         &app_context) == APP_MANAGER_ERROR_NONE) {
120                         foreach_context->iteration = foreach_context->callback(app_context, foreach_context->user_data);
121                         app_context_destroy(app_context);
122                 }
123         }
124
125         return 0;
126 }
127
128 int app_context_foreach_app_context(app_manager_app_context_cb callback, void *user_data)
129 {
130         foreach_context_s foreach_context = {
131                 .callback = callback,
132                 .user_data = user_data,
133                 .iteration = true
134         };
135
136         if (callback == NULL)
137                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
138
139         if (aul_app_get_running_app_info(app_context_foreach_app_context_cb, &foreach_context) != AUL_R_OK)
140                 return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
141
142         return APP_MANAGER_ERROR_NONE;
143 }
144
145 static int app_context_foreach_running_app_context_cb(const aul_app_info *aul_app_context, void *cb_data)
146 {
147         foreach_context_s *foreach_context = cb_data;
148         app_context_h app_context;
149         app_state_e app_state;
150         bool is_sub_app = false;
151
152         if (foreach_context == NULL) {
153                 app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
154                 return 0;
155         }
156
157         if (foreach_context->iteration == true) {
158                 app_state = app_context_get_app_status(aul_app_context->status);
159
160                 if (aul_app_context->is_sub_app)
161                         is_sub_app = true;
162
163                 if (app_context_create(aul_app_context->appid,
164                                         aul_app_context->pid,
165                                         aul_app_context->pkgid,
166                                         app_state,
167                                         is_sub_app,
168                                         &app_context) == APP_MANAGER_ERROR_NONE) {
169                         foreach_context->iteration = foreach_context->callback(app_context, foreach_context->user_data);
170                         app_context_destroy(app_context);
171                 }
172         }
173
174         return 0;
175 }
176
177 int app_context_foreach_running_app_context(app_manager_app_context_cb callback, void *user_data)
178 {
179         int ret;
180         foreach_context_s foreach_context = {
181                 .callback = callback,
182                 .user_data = user_data,
183                 .iteration = true
184         };
185
186         if (callback == NULL)
187                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
188
189         ret = aul_app_get_all_running_app_info(app_context_foreach_running_app_context_cb, &foreach_context);
190         if (ret != AUL_R_OK)
191                 return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
192
193         return APP_MANAGER_ERROR_NONE;
194 }
195
196 static int app_context_retrieve_app_context(const aul_app_info *aul_app_context, void *cb_data)
197 {
198         retrieval_context_s *retrieval_context = cb_data;
199         app_state_e app_state;
200
201         if (aul_app_context != NULL && retrieval_context != NULL && retrieval_context->matched == false) {
202                 if (retrieval_context->instance_id &&
203                                 !strcmp(aul_app_context->instance_id, retrieval_context->instance_id) &&
204                                 !strcmp(aul_app_context->appid, retrieval_context->app_id)) {
205                         app_state = app_context_get_app_status(aul_app_context->status);
206
207                         retrieval_context->pid = aul_app_context->pid;
208                         retrieval_context->pkg_id = strdup(aul_app_context->pkgid);
209                         retrieval_context->app_state = app_state;
210                         if (aul_app_context->is_sub_app)
211                                 retrieval_context->is_sub_app = true;
212                         retrieval_context->matched = true;
213                 } else if (retrieval_context->instance_id == NULL &&
214                                 !strcmp(aul_app_context->appid, retrieval_context->app_id)) {
215                         app_state = app_context_get_app_status(aul_app_context->status);
216
217                         retrieval_context->pid = aul_app_context->pid;
218                         retrieval_context->pkg_id = strdup(aul_app_context->pkgid);
219                         retrieval_context->app_state = app_state;
220                         if (aul_app_context->is_sub_app)
221                                 retrieval_context->is_sub_app = true;
222                         retrieval_context->matched = true;
223                 }
224         }
225
226         return 0;
227 }
228
229 int app_context_get_app_context(const char *app_id, app_context_h *app_context)
230 {
231         int ret;
232         retrieval_context_s retrieval_context =  {
233                 .app_id = app_id,
234                 .pid = 0,
235                 .pkg_id = NULL,
236                 .app_state = APP_STATE_UNDEFINED,
237                 .is_sub_app = false,
238                 .matched = false,
239                 .instance_id = NULL
240         };
241
242         if (app_id == NULL || app_context == NULL)
243                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
244
245         if (aul_app_is_running(app_id) == 0)
246                 return app_manager_error(APP_MANAGER_ERROR_NO_SUCH_APP, __FUNCTION__, NULL);
247
248         aul_app_get_running_app_info(app_context_retrieve_app_context, &retrieval_context);
249
250         if (retrieval_context.matched == false)
251                 return app_manager_error(APP_MANAGER_ERROR_NO_SUCH_APP, __FUNCTION__, NULL);
252
253         ret = app_context_create(retrieval_context.app_id,
254                                         retrieval_context.pid,
255                                         retrieval_context.pkg_id,
256                                         retrieval_context.app_state,
257                                         retrieval_context.is_sub_app,
258                                          app_context);
259         free(retrieval_context.pkg_id);
260
261         return ret;
262 }
263
264 static int app_context_create(const char *app_id, pid_t pid, const char *pkg_id, app_state_e app_state, bool is_sub_app, app_context_h *app_context)
265 {
266         app_context_h app_context_created;
267
268         if (app_id == NULL || pid <= 0 || pkg_id == NULL || app_context == NULL)
269                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
270
271         app_context_created = calloc(1, sizeof(struct app_context_s));
272         if (app_context_created == NULL)
273                 return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
274
275         app_context_created->app_id = strdup(app_id);
276         if (app_context_created->app_id == NULL) {
277                 free(app_context_created);
278                 return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
279         }
280
281         app_context_created->pkg_id = strdup(pkg_id);
282         if (app_context_created->pkg_id == NULL) {
283                 free(app_context_created->app_id);
284                 free(app_context_created);
285                 return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
286         }
287
288         app_context_created->pid = pid;
289         app_context_created->app_state = app_state;
290         app_context_created->is_sub_app = is_sub_app;
291
292         *app_context = app_context_created;
293
294         return APP_MANAGER_ERROR_NONE;
295 }
296
297 API int app_context_destroy(app_context_h app_context)
298 {
299         if (app_context == NULL)
300                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
301
302         free(app_context->app_id);
303         free(app_context->pkg_id);
304         free(app_context);
305
306         return APP_MANAGER_ERROR_NONE;
307 }
308
309 API int app_context_get_package(app_context_h app_context, char **package)
310 {
311         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.");
312         /* TODO: this function must be deprecated */
313         return app_context_get_app_id(app_context, package);
314 }
315
316
317 API int app_context_get_app_id(app_context_h app_context, char **app_id)
318 {
319         char *app_id_dup;
320
321         if (app_context == NULL || app_id == NULL)
322                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
323
324         app_id_dup = strdup(app_context->app_id);
325         if (app_id_dup == NULL)
326                 return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
327
328         *app_id = app_id_dup;
329
330         return APP_MANAGER_ERROR_NONE;
331 }
332
333 API int app_context_get_pid(app_context_h app_context, pid_t *pid)
334 {
335         if (app_context == NULL || pid == NULL)
336                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
337
338         *pid = app_context->pid;
339
340         return APP_MANAGER_ERROR_NONE;
341 }
342
343 API int app_context_get_package_id(app_context_h app_context, char **pkg_id)
344 {
345         char *pkg_id_dup;
346
347         if (app_context == NULL || pkg_id == NULL)
348                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
349
350         pkg_id_dup = strdup(app_context->pkg_id);
351         if (pkg_id_dup == NULL)
352                 return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
353
354         *pkg_id = pkg_id_dup;
355
356         return APP_MANAGER_ERROR_NONE;
357 }
358
359 API int app_context_get_app_state(app_context_h app_context, app_state_e *state)
360 {
361         if (app_context == NULL || state == NULL)
362                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
363
364         *state = app_context->app_state;
365
366         return APP_MANAGER_ERROR_NONE;
367 }
368
369 API int app_context_is_terminated(app_context_h app_context, bool *terminated)
370 {
371         char appid[APPID_MAX] = {0, };
372
373         if (app_context == NULL || terminated == NULL)
374                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
375
376         if (aul_app_is_running(app_context->app_id) == 1) {
377                 *terminated = false;
378         } else {
379                 if (aul_app_get_appid_bypid(app_context->pid, appid, sizeof(appid)) == AUL_R_OK)
380                         *terminated = false;
381                 else
382                         *terminated = true;
383         }
384
385         return APP_MANAGER_ERROR_NONE;
386 }
387
388 API int app_context_is_equal(app_context_h lhs, app_context_h rhs, bool *equal)
389 {
390         if (lhs == NULL || rhs == NULL || equal == NULL)
391                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
392
393         if (!strcmp(lhs->app_id, rhs->app_id) && lhs->pid == rhs->pid)
394                 *equal = true;
395         else
396                 *equal = false;
397
398         return APP_MANAGER_ERROR_NONE;
399 }
400
401 API int app_context_is_sub_app(app_context_h app_context, bool *is_sub_app)
402 {
403         if (app_context == NULL || is_sub_app == NULL)
404                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
405
406         *is_sub_app = app_context->is_sub_app;
407
408         return APP_MANAGER_ERROR_NONE;
409 }
410
411 API int app_context_clone(app_context_h *clone, app_context_h app_context)
412 {
413         int retval;
414
415         if (clone == NULL || app_context == NULL)
416                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
417
418         retval = app_context_create(app_context->app_id,
419                                         app_context->pid,
420                                         app_context->pkg_id,
421                                         app_context->app_state,
422                                         app_context->is_sub_app,
423                                         clone);
424         if (retval != APP_MANAGER_ERROR_NONE)
425                 return app_manager_error(retval, __FUNCTION__, NULL);
426
427         return APP_MANAGER_ERROR_NONE;
428 }
429
430 typedef struct _event_cb_context_ {
431         GHashTable *pid_table;
432         app_manager_app_context_event_cb callback;
433         void *user_data;
434 } event_cb_context_s;
435
436 static pthread_mutex_t event_cb_context_mutex = PTHREAD_MUTEX_INITIALIZER;
437 static event_cb_context_s *event_cb_context = NULL;
438
439 static void app_context_lock_event_cb_context()
440 {
441         pthread_mutex_lock(&event_cb_context_mutex);
442 }
443
444 static void app_context_unlock_event_cb_context()
445 {
446         pthread_mutex_unlock(&event_cb_context_mutex);
447 }
448
449 static bool app_context_load_all_app_context_cb_locked(app_context_h app_context, void *user_data)
450 {
451         app_context_h app_context_cloned;
452
453         if (app_context_clone(&app_context_cloned, app_context) == APP_MANAGER_ERROR_NONE) {
454                 SECURE_LOGI("[%s] app_id(%s), pid(%d)", __FUNCTION__, app_context->app_id, app_context->pid);
455
456                 if (event_cb_context != NULL && event_cb_context->pid_table != NULL) {
457                         g_hash_table_insert(event_cb_context->pid_table, GINT_TO_POINTER(&(app_context_cloned->pid)), app_context_cloned);
458                 } else {
459                         app_context_destroy(app_context_cloned);
460                         app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "invalid callback context");
461                 }
462         }
463
464         return true;
465 }
466
467 static void app_context_pid_table_entry_destroyed_cb(void *data)
468 {
469         app_context_h app_context = data;
470
471         if (app_context != NULL)
472                 app_context_destroy(app_context);
473 }
474
475 static int app_context_get_pkgid_by_appid(const char *app_id, char **pkg_id)
476 {
477         pkgmgrinfo_appinfo_h appinfo;
478         char *pkg_id_dup;
479
480         if (app_id == NULL || pkg_id == NULL)
481                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
482
483         if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &appinfo) < 0)
484                 return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "fail to get appinfo");
485
486         if (pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkg_id_dup) < 0) {
487                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
488                 return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "fail to get pkgid");
489         }
490
491         *pkg_id = strdup(pkg_id_dup);
492
493         pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
494         return APP_MANAGER_ERROR_NONE;
495 }
496
497 static int app_context_launched_event_cb(pid_t pid, const char *app_id, void *data)
498 {
499         app_context_h app_context = NULL;
500         char *pkg_id = NULL;
501
502         if (pid < 0 || app_id == NULL)
503                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
504
505         if (app_context_get_pkgid_by_appid(app_id, &pkg_id) < 0)
506                 return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "no such pkg_id");
507
508         app_context_lock_event_cb_context();
509
510         if (app_context_create(app_id, pid, pkg_id, APP_STATE_UNDEFINED, false, &app_context) == APP_MANAGER_ERROR_NONE) {
511                 if (event_cb_context != NULL && event_cb_context->pid_table != NULL) {
512                         g_hash_table_insert(event_cb_context->pid_table, GINT_TO_POINTER(&(app_context->pid)), app_context);
513                         event_cb_context->callback(app_context, APP_CONTEXT_EVENT_LAUNCHED, event_cb_context->user_data);
514                 } else {
515                         app_context_destroy(app_context);
516                         app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "invalid callback context");
517                 }
518         }
519
520         app_context_unlock_event_cb_context();
521
522         free(pkg_id);
523         return 0;
524 }
525
526 static int app_context_terminated_event_cb(pid_t pid, void *data)
527 {
528         app_context_h app_context;
529         int lookup_key = pid;
530
531         app_context_lock_event_cb_context();
532
533         if (event_cb_context != NULL && event_cb_context->pid_table != NULL) {
534                 app_context = g_hash_table_lookup(event_cb_context->pid_table, GINT_TO_POINTER(&lookup_key));
535
536                 if (app_context != NULL) {
537                         event_cb_context->callback(app_context, APP_CONTEXT_EVENT_TERMINATED, event_cb_context->user_data);
538                         g_hash_table_remove(event_cb_context->pid_table, GINT_TO_POINTER(&(app_context->pid)));
539                 }
540         } else {
541                 app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "invalid callback context");
542         }
543
544         app_context_unlock_event_cb_context();
545
546         return 0;
547 }
548
549 int app_context_set_event_cb(app_manager_app_context_event_cb callback, void *user_data)
550 {
551         if (callback == NULL)
552                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
553
554         app_context_lock_event_cb_context();
555
556         if (event_cb_context == NULL) {
557                 event_cb_context = calloc(1, sizeof(event_cb_context_s));
558
559                 if (event_cb_context == NULL) {
560                         app_context_unlock_event_cb_context();
561                         return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
562                 }
563
564                 event_cb_context->pid_table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, app_context_pid_table_entry_destroyed_cb);
565                 if (event_cb_context->pid_table == NULL) {
566                         free(event_cb_context);
567                         event_cb_context = NULL;
568                         app_context_unlock_event_cb_context();
569                         return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "failed to initialize pid-table");
570                 }
571
572                 app_context_foreach_app_context(app_context_load_all_app_context_cb_locked, NULL);
573
574                 aul_listen_app_dead_signal(app_context_terminated_event_cb, NULL);
575                 aul_listen_app_launch_signal_v2(app_context_launched_event_cb, NULL);
576
577         }
578
579         event_cb_context->callback = callback;
580         event_cb_context->user_data = user_data;
581
582         app_context_unlock_event_cb_context();
583
584         return APP_MANAGER_ERROR_NONE;
585 }
586
587 void app_context_unset_event_cb(void)
588 {
589         app_context_lock_event_cb_context();
590
591         if (event_cb_context != NULL) {
592                 /* aul_listen_app_dead_signal(NULL, NULL); */
593                 /* aul_listen_app_launch_signal(NULL, NULL); */
594
595                 g_hash_table_destroy(event_cb_context->pid_table);
596                 free(event_cb_context);
597                 event_cb_context = NULL;
598         }
599
600         app_context_unlock_event_cb_context();
601 }
602
603 static int app_context_status_cb(const char *appid, const char *pkgid, int pid, int status, int is_subapp, void *data)
604 {
605         app_context_h app_context = NULL;
606         app_state_e state;
607         app_context_status_e context_status;
608         int ret;
609
610         state = app_context_get_app_status(status);
611         if (state == APP_STATE_TERMINATED)
612                 context_status = APP_CONTEXT_STATUS_TERMINATED;
613         else
614                 context_status = APP_CONTEXT_STATUS_LAUNCHED;
615
616         ret = app_context_create(appid, pid, pkgid, state, is_subapp, &app_context);
617         if (ret != APP_MANAGER_ERROR_NONE)
618                 return app_manager_error(ret, __FUNCTION__, NULL);
619
620         _status_cb(app_context, context_status, data);
621         app_context_destroy(app_context);
622
623         return APP_MANAGER_ERROR_NONE;
624 }
625
626 int app_context_set_status_cb(app_manager_app_context_status_cb callback, const char *appid, void *user_data)
627 {
628         int ret;
629
630         if (callback == NULL || appid == NULL)
631                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
632
633         _status_cb = callback;
634
635         ret = aul_listen_app_status(appid, app_context_status_cb, user_data);
636         switch (ret) {
637         case AUL_R_OK:
638                 ret = APP_MANAGER_ERROR_NONE;
639                 break;
640         case AUL_R_EINVAL:
641                 ret = APP_MANAGER_ERROR_INVALID_PARAMETER;
642                 break;
643         default:
644                 ret = APP_MANAGER_ERROR_IO_ERROR;
645                 break;
646         }
647
648         return ret;
649 }
650
651 int app_context_get_app_context_by_instance_id(const char *app_id, const char *instance_id, app_context_h *app_context)
652 {
653         int ret;
654         retrieval_context_s retrieval_context = {
655                 .app_id = app_id,
656                 .pid = 0,
657                 .pkg_id = NULL,
658                 .app_state = APP_STATE_UNDEFINED,
659                 .is_sub_app = false,
660                 .matched = false,
661                 .instance_id = instance_id
662         };
663
664         if (app_id == NULL || instance_id == NULL || app_context == NULL)
665                 return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
666
667         aul_app_get_running_app_instance_info(app_context_retrieve_app_context, &retrieval_context);
668         if (retrieval_context.matched == false)
669                 return app_manager_error(APP_MANAGER_ERROR_NO_SUCH_APP, __FUNCTION__, NULL);
670
671         ret = app_context_create(retrieval_context.app_id,
672                         retrieval_context.pid,
673                         retrieval_context.pkg_id,
674                         retrieval_context.app_state,
675                         retrieval_context.is_sub_app,
676                         app_context);
677         free(retrieval_context.pkg_id);
678
679         return ret;
680 }