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