Add APIs for System Session
[platform/core/appfw/aul-1.git] / app_launcher.c
1 /*
2  *  app_launcher
3  *
4  * Copyright (c) 2014, Intel Corporation.
5  *
6  * Contact: Baptiste DURAND <baptiste.durand@open.eurogiciel.org>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <getopt.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <string.h>
29 #include <glib.h>
30
31 #include <pkgmgr-info.h>
32 #include <bundle.h>
33
34 #include "aul.h"
35
36 static GMainLoop *mainloop = NULL;
37
38 struct launch_arg {
39         char appid[256];
40         char **argv;
41         int argc;
42         int flag_debug;
43         int sync;
44 } launch_arg;
45
46 static bundle *_create_internal_bundle(struct launch_arg *args)
47 {
48         bundle *b;
49         int i;
50
51         if (!args->flag_debug && args->argc < 2)
52                 return NULL;
53
54         b = bundle_create();
55         if (args->flag_debug)
56                 bundle_add(b, AUL_K_DEBUG, "1");
57
58         for (i = 0; i + 1 < args->argc; i += 2) {
59                 bundle_add(b, args->argv[i], args->argv[i + 1]);
60                 if (!strcmp(args->argv[i], "__LAUNCH_APP_MODE__") &&
61                                 !strcmp(args->argv[i + 1], "SYNC"))
62                         args->sync = 1;
63         }
64
65         return b;
66 }
67
68 static int __launch_app_dead_handler(int pid, void *data)
69 {
70         int listen_pid = (intptr_t)data;
71
72         if (listen_pid == pid)
73                 g_main_loop_quit(mainloop);
74
75         return 0;
76 }
77
78 static gboolean run_func(void *data)
79 {
80         int pid;
81         bundle *kb;
82         struct launch_arg *launch_arg_data = (struct launch_arg *)data;
83
84         kb = _create_internal_bundle(launch_arg_data);
85         pid = aul_launch_app((char *)launch_arg_data->appid, kb);
86
87         if (kb) {
88                 bundle_free(kb);
89                 kb = NULL;
90         }
91
92         if (pid > 0) {
93                 printf("... successfully launched pid = %d with debug %d\n",
94                                 pid, launch_arg_data->flag_debug);
95                 if (launch_arg_data->sync) {
96                         aul_listen_app_dead_signal(__launch_app_dead_handler, (void *)(intptr_t)pid);
97                         return FALSE;
98                 }
99         } else {
100                 printf("... launch failed\n");
101         }
102
103         g_main_loop_quit(mainloop);
104
105         return FALSE;
106 }
107
108 static void print_usage(char *program)
109 {
110         printf("Usage : %s [ OPTIONS... ] [ ARGS... ]\n", program);
111         printf(
112                         "   -h                        --help              Display this usage information.\n"
113                         "   -l                        --list              Display installed apps list\n"
114                         "   -S                        --status            Display running apps list\n"
115                         "   -s [tizen application ID] --start             Launch widget with tizen application ID\n"
116                         "   -k [tizen application ID] --kill              Kill widget with tizen application ID\n"
117                         "   -t [tizen application ID] --terminate         Terminate widget with tizen application ID\n"
118                         "   -r [tizen application ID] --is-running        Check whether application is running by tizen application ID,\n"
119                         "                                                 If widget is running, 0(zero) will be returned.\n"
120                         "   -d                        --debug             Activate debug mode\n"
121               );
122 }
123
124 static int __appinfo_list_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
125 {
126         char *label;
127         char *appid;
128
129         if (pkgmgrinfo_appinfo_get_label(handle, &label))
130                 label = "";
131
132         if (pkgmgrinfo_appinfo_get_appid(handle, &appid)) {
133                 printf("Failed to get appid\n");
134                 return -1;
135         }
136
137         printf("\t'%s'\t '%s'\n", label, appid);
138
139         return 0;
140 }
141
142 static int list_app(void)
143 {
144         int ret = 0;
145
146         printf("\tApplication List for user %lu\n", (long)getuid());
147         printf("\tUser's Application \n");
148         printf("\t Name \t AppID \n");
149         printf("\t=================================================\n");
150         if (pkgmgrinfo_appinfo_get_usr_installed_list(__appinfo_list_cb,
151                                 getuid(), NULL) != PMINFO_R_OK)
152                 ret = -1;
153         printf("\t=================================================\n");
154         return ret;
155 }
156
157 static int __iterfunc_status(const aul_app_info *info, void *data)
158 {
159         printf("\t  %s (%d)\n", info->appid, info->pid);
160         return 0;
161 }
162
163 static int __iterfunc_kill(const aul_app_info *info, void *data)
164 {
165         if (!data)
166                 return 0;
167         if (strcmp(info->appid, data) == 0) {
168                 aul_kill_pid(info->pid);
169                 printf("\t Kill appId: %s (%d)\n", info->appid, info->pid);
170         }
171         return 0;
172 }
173
174 static int __iterfunc_term(const aul_app_info *info, void *data)
175 {
176         if (!data)
177                 return 0;
178         if (strcmp(info->appid, data) == 0) {
179                 aul_terminate_pid(info->pid);
180                 printf("\t Terminate appId: %s (%d)\n", info->appid, info->pid);
181         }
182         return 0;
183 }
184
185 static int is_app_installed(char *appid)
186 {
187         int is_installed = 0;
188         pkgmgrinfo_appinfo_filter_h filter;
189
190         if (pkgmgrinfo_appinfo_filter_create(&filter)) {
191                 printf("Failed to create filter\n");
192                 return -1;
193         }
194
195         if (pkgmgrinfo_appinfo_filter_add_string(filter,
196                                 PMINFO_APPINFO_PROP_APP_ID, appid)) {
197                 printf("Failed to add filter string\n");
198                 pkgmgrinfo_appinfo_filter_destroy(filter);
199                 return -1;
200         }
201
202         if (pkgmgrinfo_appinfo_usr_filter_count(filter, &is_installed,
203                                 getuid())) {
204                 printf("Failed to get filter count\n");
205                 pkgmgrinfo_appinfo_filter_destroy(filter);
206                 return -1;
207         }
208
209         pkgmgrinfo_appinfo_filter_destroy(filter);
210
211         return is_installed;
212 }
213
214 int main(int argc, char **argv)
215 {
216         bool disp_help = false;
217         bool disp_list = false;
218         bool disp_run_list = false;
219         bool is_running;
220         int next_opt;
221         int opt_idx = 0;
222         char op = '\0';
223         struct launch_arg args;
224         static struct option long_options[] = {
225                 { "help", no_argument, 0, 'h' },
226                 { "list", no_argument, 0, 'l' },
227                 { "status", no_argument, 0, 'S' },
228                 { "start", required_argument, 0, 's' },
229                 { "args", required_argument, 0, 'a' },
230                 { "kill", required_argument, 0, 'k' },
231                 { "terminate", required_argument, 0, 't' },
232                 { "is-running", required_argument, 0, 'r' },
233                 { "debug", no_argument, 0, 'd' },
234                 { 0, 0, 0, 0 }
235         };
236         memset(&args, 0, sizeof(struct launch_arg));
237
238         do {
239                 next_opt = getopt_long(argc,
240                                 argv,
241                                 "hlSs:k:t:r:d",
242                                 long_options,
243                                 &opt_idx);
244
245                 switch (next_opt) {
246                 case 'h':
247                         if (!disp_help) {
248                                 print_usage(argv[0]);
249                                 disp_help = true;
250                         }
251                         break;
252                 case 'l':
253                         if (disp_list)
254                                 break;
255                         if (list_app()) {
256                                 printf("Fail to display the list of "
257                                                 "installed applications\n");
258                                 return -1;
259                         }
260                         disp_list = true;
261                         break;
262                 case 'S':
263                         if (disp_run_list)
264                                 break;
265                         printf("\t appId (PID)\n");
266                         if (aul_app_get_running_app_info(__iterfunc_status,
267                                                 NULL)) {
268                                 printf("Fail to display the list of "
269                                                 "Running applications\n");
270                                 return -1;
271                         }
272                         disp_run_list = true;
273                         break;
274                 case 's':
275                 case 'k':
276                 case 't':
277                 case 'r':
278                         if (strlen(optarg) > 255) {
279                                 print_usage(argv[0]);
280                                 return -1;
281                         } else {
282                                 strncpy(args.appid, optarg, sizeof(args.appid) - 1);
283                         }
284                         op = next_opt;
285                         break;
286                 case 'd':
287                         args.flag_debug = 1;
288                         break;
289                 case '?':
290                         break;
291                 case -1:
292                         break;
293                 default:
294                         print_usage(argv[0]);
295                         break;
296                 }
297         } while (next_opt != -1);
298
299         if (argc == 1)
300                 print_usage(argv[0]);
301
302         if (optind < argc) {
303                 args.argc = argc - optind;
304                 args.argv = &argv[optind];
305         }
306         if ((op == 's') || (op == 'k') || (op == 'r')) {
307                 if (is_app_installed(args.appid) <= 0) {
308                         printf("The app with ID: %s is not avaible "
309                                         "for the user %d \n",
310                                         args.appid, getuid());
311                         return -1;
312                 }
313         }
314
315         if (op == 's') {
316                 if (strlen(args.appid) <= 0) {
317                         printf("result: %s\n", "failed");
318                         return -1;
319                 }
320                 aul_launch_init(NULL, NULL);
321                 g_idle_add(run_func, args.appid);
322                 mainloop = g_main_loop_new(NULL, FALSE);
323                 if (!mainloop) {
324                         printf("failed to create glib main loop\n");
325                         exit(EXIT_FAILURE);
326                 }
327                 g_main_loop_run(mainloop);
328                 return 0;
329         } else if (op == 'k') {
330                 is_running = aul_app_is_running(args.appid);
331                 if (true == is_running) {
332                         aul_app_get_running_app_info(__iterfunc_kill,
333                                         args.appid);
334                 } else {
335                         printf("result: %s\n", "App isn't running");
336                         return 1;
337                 }
338         } else if (op == 't') {
339                 is_running = aul_app_is_running(args.appid);
340                 if (true == is_running) {
341                         aul_app_get_running_app_info(__iterfunc_term,
342                                         args.appid);
343                 } else {
344                         printf("result: %s\n", "App isn't running");
345                         return 1;
346                 }
347         } else if (op == 'r') {
348                 is_running = aul_app_is_running(args.appid);
349                 if (true == is_running) {
350                         printf("result: %s\n", "running");
351                         return 0;
352                 } else {
353                         printf("result: %s\n", "not running");
354                         return 1;
355                 }
356         }
357
358         return 0;
359 }