6e360dd101bccc35f05879c4c9fe266efa9853ad
[profile/ivi/ico-uxf-homescreen.git] / ico-app-framework / ico_uxf_launcher.c
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9 /**
10  * @brief   user experience library for HomeScreen
11  *
12  * @date    Feb-28-2013
13  */
14
15 #include    <stdio.h>
16 #include    <stdlib.h>
17 #include    <unistd.h>
18 #include    <string.h>
19 #include    <errno.h>
20
21 #include    "wayland-client.h"
22 #include    "wayland-util.h"
23 #include    "ico_uxf.h"                 /* UX-FW open definition header         */
24 #include    "ico_uxf_private.h"         /* UX-FW inner definition header        */
25 #include    "ico_uxf_conf.h"
26
27 /* valiable & table                     */
28 /* UX-FW API inner management table     */
29 extern Ico_Uxf_Api_Mng         gIco_Uxf_Api_Mng;
30
31
32 /*--------------------------------------------------------------------------*/
33 /**
34  * @brief   ico_uxf_process_execute: launch a program
35  *
36  * @param[in]   name        program name
37  * @return  result
38  * @retval  ICO_UXF_EOK         success
39  * @retval  ICO_UXF_ESRCH       error(not initialized)
40  * @retval  ICO_UXF_ENOENT      error(does not exist)
41  * @retval  ICO_UXF_EBUSY       error(already launch)
42  * @retval  ICO_UXF_EPERM       error(no authority)
43  */
44 /*--------------------------------------------------------------------------*/
45 ICO_APF_API int
46 ico_uxf_process_execute(const char *name)
47 {
48     Ico_Uxf_Mng_Process *proc;              /* process management table         */
49     int         hash;
50     bundle      *appBundle = NULL;
51     Ico_Uxf_conf_application    *apptbl = NULL;
52
53     uifw_trace("ico_uxf_process_execute: Enter(%s)", name);
54
55     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
56         uifw_warn("ico_uxf_process_execute: Leave(ESRCH)");
57         return ICO_UXF_ESRCH;
58     }
59
60     for (hash = 0; hash < ICO_UXF_MISC_HASHSIZE; hash++)    {
61         proc = gIco_Uxf_Api_Mng.Hash_ProcessId[hash];
62         while (proc)    {
63             uifw_trace("ico_uxf_process_execute: PROC(%s)", proc->attr.process);
64             if (strcasecmp(proc->attr.process, name) == 0)  break;
65             proc = proc->nextidhash;
66         }
67         if (proc) break;
68     }
69
70     if (! proc) {
71         uifw_warn("ico_uxf_process_execute: Leave(ENOENT)");
72         return ICO_UXF_ENOENT;
73     }
74
75     ico_uxf_enter_critical();               /* enter critical section           */
76
77     if (proc->attr.status != ICO_UXF_PROCSTATUS_STOP)   {
78         ico_uxf_leave_critical();           /* leave critical section           */
79         uifw_warn("ico_uxf_process_execute: Leave(EBUSY)");
80         return ICO_UXF_EBUSY;
81     }
82
83     /* in order to avoid double execute, status set starting    */
84     proc->attr.status = ICO_UXF_PROCSTATUS_INIT;
85     ico_uxf_leave_critical();               /* leave critical section           */
86
87     /* setup option */
88     appBundle = bundle_create();
89     apptbl = (Ico_Uxf_conf_application *)ico_uxf_getAppByAppid(name);
90     if ((appBundle != NULL) && (apptbl != NULL))    {
91         char *opt = strdup(apptbl->exec);
92         char *str = strtok(opt, " ");
93         while (str != NULL) {
94             str = strtok(NULL, " ");
95             if (str != NULL)    {
96                 bundle_add(appBundle, str, "Application");
97                 uifw_trace("ico_uxf_process_execute: option(%s)", str);
98             }
99         }
100         free(opt);
101     }
102
103     /* execute program                      */
104     proc->attr.internalid = aul_launch_app(name ,appBundle);
105     if (proc->attr.internalid < 0)  {
106         uifw_error("ico_uxf_process_execute: Leave(ENOSYS), Launch App Error(%d)",
107                    proc->attr.internalid);
108         return ICO_UXF_ENOSYS;
109     }
110
111     proc->attr.status = ICO_UXF_PROCSTATUS_RUN;
112
113     uifw_trace("ico_uxf_process_execute: Leave(%s)", proc->attr.process);
114     return ICO_UXF_EOK;
115 }
116
117 /*--------------------------------------------------------------------------*/
118 /**
119  * @brief   ico_uxf_process_terminate: finish a program
120  *
121  * @param[in]   process     process id
122  * @return  result
123  * @retval  ICO_UXF_EOK         success
124  * @retval  ICO_UXF_ESRCH       error(not initialized)
125  * @retval  ICO_UXF_ENOENT      error(does not exist)
126  * @retval  ICO_UXF_EAGAIN      error(already launch)
127  * @retval  ICO_UXF_EPERM       error(no authority)
128  */
129 /*--------------------------------------------------------------------------*/
130 ICO_APF_API int
131 ico_uxf_process_terminate(const char *process)
132 {
133     Ico_Uxf_Mng_Process     *proc;          /* process management table         */
134     int                     ret;            /* process management table         */
135
136     uifw_trace("ico_uxf_process_terminate: Enter(%s)", process);
137
138     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
139         uifw_warn("ico_uxf_process_terminate: Leave(ESRCH)");
140         return ICO_UXF_ESRCH;
141     }
142
143     /* target is other process */
144     proc = ico_uxf_mng_process(process, 0);
145     if (! proc)    {
146         uifw_warn("ico_uxf_process_terminate: Leave(ENOENT)");
147         return ICO_UXF_ENOENT;
148     }
149
150     ret = aul_terminate_pid(proc->attr.internalid);
151     if (ret < 0) {
152         uifw_warn("ico_uxf_process_terminate: Leave(ENOSYS) cannot terminate pid=%d",
153                   proc->attr.internalid);
154         return ICO_UXF_ENOSYS;
155     }
156
157     proc->attr.status = ICO_UXF_PROCSTATUS_STOP;
158     proc->attr.internalid = -1;
159     proc->attr.mainwin.window = 0;
160     ico_uxf_free_procwin(proc);
161
162     uifw_trace("ico_uxf_process_terminate: Leave(EOK)");
163     return ICO_UXF_EOK;
164 }
165
166 /*--------------------------------------------------------------------------*/
167 /**
168  * @brief   ico_uxf_process_attribute_get: get a process's current state
169  *
170  * @param[in]   process     process's identity
171  * @param[out]  attr        target process's current state
172  * @return  result
173  * @retval  ICO_UXF_EOK         success
174  * @retval  ICO_UXF_ESRCH       error(not initialized)
175  * @retval  ICO_UXF_ENOENT      error(does not exist)
176  * @retval  ICO_UXF_EPERM       error(no authority)
177  */
178 /*--------------------------------------------------------------------------*/
179 ICO_APF_API int
180 ico_uxf_process_attribute_get(const char *process, Ico_Uxf_ProcessAttr *attr)
181 {
182     Ico_Uxf_Mng_Process *proc;              /* process management table             */
183
184     uifw_trace("ico_uxf_process_attribute_get: Enter(%s)", process);
185
186     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
187         uifw_warn("ico_uxf_process_attribute_get: Leave(ESRCH)");
188         return ICO_UXF_ESRCH;
189     }
190
191     proc = ico_uxf_mng_process(process, 0);
192     if (! proc)    {
193         uifw_warn("ico_uxf_process_attribute_get: Leave(ENOENT)");
194         return ICO_UXF_ENOENT;
195     }
196
197     memcpy((char *)attr, (char *)&(proc->attr), sizeof(Ico_Uxf_ProcessAttr));
198
199     uifw_trace("ico_uxf_process_attribute_get: Leave(EOK)");
200     return ICO_UXF_EOK;
201 }
202
203 /*--------------------------------------------------------------------------*/
204 /**
205  * @brief   ico_uxf_process_is_active: get application activity
206  *
207  * @param[in]   process     process's identity
208  * @return  result
209  * @retval  1               process is active
210  * @retval  0               process is not active
211  */
212 /*--------------------------------------------------------------------------*/
213 ICO_APF_API int
214 ico_uxf_process_is_active(const char *process)
215 {
216     Ico_Uxf_Mng_Process *proc;              /* process management table             */
217
218     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
219         uifw_warn("ico_uxf_process_is_active: False(ESRCH)");
220         return 0;
221     }
222
223     proc = ico_uxf_mng_process(process, 0);
224     if (! proc)    {
225         uifw_warn("ico_uxf_process_is_active: False(ENOENT)");
226         return 0;
227     }
228
229     uifw_trace("ico_uxf_process_is_active: %s is %s",
230                process, proc->attr.active ? "Active" : "Inactive");
231     return proc->attr.active;
232 }
233
234 /*--------------------------------------------------------------------------*/
235 /**
236  * @brief   ico_uxf_process_window_get: get a window defined by the process
237  *
238  * @param[in]   process     process identity
239  * @param[out]  attr        return a window definition
240  *                          First is main window of the process,
241  *                          second henceforth is sub window of the process.
242  *                          At present support only main window.
243  * @param[in]   num         number of window definition(= array size)
244  * @return  result
245  * @retval  >= 0            success(number of windows)
246  * @retval  ICO_UXF_E2BIG   The number of the process has exceeded num
247  *                          The attribute of the process up to a num piece is returned to attr
248  * @retval  ICO_UXF_ENOENT  error(does not exist)
249  * @retval  ICO_UXF_EINVAL  error(num is 0 or less)
250  * @retval  ICO_UXF_ESRCH   error(not initialized)
251  * @retval  ICO_UXF_EPERM   error(no authority)
252  */
253 /*--------------------------------------------------------------------------*/
254 ICO_APF_API int
255 ico_uxf_process_window_get(const char *process, Ico_Uxf_ProcessWin *attr, const int num)
256 {
257     Ico_Uxf_Mng_Process *proc;              /* process management table         */
258     Ico_Uxf_Mng_ProcWin *pwin;              /* Process possession window table  */
259     int         n;                          /* number of window                 */
260
261     uifw_trace("ico_uxf_process_window_get: Enter(%s,,%d)", process, num);
262
263     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
264         uifw_warn("ico_uxf_process_window_get: Leave(ESRCH)");
265         return ICO_UXF_ESRCH;
266     }
267
268     if (num <= 0)  {
269         uifw_warn("ico_uxf_process_window_get: Leave(EINVAL)");
270         return ICO_UXF_EINVAL;
271     }
272
273     proc = ico_uxf_mng_process(process, 0);
274     if (! proc)    {
275         uifw_trace("ico_uxf_process_window_get: Leave(ENOENT)");
276         return ICO_UXF_ENOENT;
277     }
278
279     memcpy((char *)&(attr[0]), (char *)&(proc->attr.mainwin), sizeof(Ico_Uxf_ProcessWin));
280
281     pwin = proc->procwin;
282     for (n = 1; n < num; n++)  {
283         if (! pwin)    break;
284         memcpy((char *)&(attr[n]), (char *)&(pwin->attr), sizeof(Ico_Uxf_ProcessWin));
285         pwin = pwin->next;
286     }
287
288     if (pwin)  {
289         n = ICO_UXF_E2BIG;
290         uifw_trace("ico_uxf_process_window_get: Leave(E2BIG)");
291     }
292     else    {
293         uifw_trace("ico_uxf_process_window_get: Leave(%d)", n);
294     }
295     return n;
296 }
297
298 /*--------------------------------------------------------------------------*/
299 /**
300  * @brief   ico_uxf_process_window_get_one: get a window defined by the process
301  *
302  * @param[in]   process     process identity(appid)
303  * @param[out]  attr        return a window definition
304  * @param[in]   winidx      window index(0 is main window, 1-N is sub window)
305  * @return  result
306  * @retval  ICO_UXF_EOK     success
307  * @retval  ICO_UXF_ENOENT  error(does not exist)
308  * @retval  ICO_UXF_EINVAL  error(winidx is negative)
309  * @retval  ICO_UXF_ESRCH   error(not initialized)
310  * @retval  ICO_UXF_EPERM   error(no authority)
311  */
312 /*--------------------------------------------------------------------------*/
313 ICO_APF_API int
314 ico_uxf_process_window_get_one(const char *process,
315                                Ico_Uxf_ProcessWin *attr, const int winidx)
316 {
317     Ico_Uxf_Mng_Process *proc;              /* process management table         */
318     Ico_Uxf_Mng_ProcWin *pwin;              /* Process possession window table  */
319     int         n;                          /* number of window                 */
320
321     uifw_trace("ico_uxf_process_window_get_one: Enter(%s,,%d)", process, winidx);
322
323     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
324         uifw_warn("ico_uxf_process_window_get_one: Leave(ESRCH)");
325         return ICO_UXF_ESRCH;
326     }
327
328     if (winidx < 0)    {
329         uifw_warn("ico_uxf_process_window_get_one: Leave(EINVAL)");
330         return ICO_UXF_EINVAL;
331     }
332
333     proc = ico_uxf_mng_process(process, 0);
334     if (! proc)    {
335         uifw_warn("ico_uxf_process_window_get_one: Leave(ENOENT, no appid)");
336         return ICO_UXF_ENOENT;
337     }
338     if (winidx >= proc->attr.numwindows) {
339         uifw_warn("ico_uxf_process_window_get_one: Leave(ENOENT, winidx over)");
340         return ICO_UXF_ENOENT;
341     }
342
343     if (winidx == 0)    {
344         memcpy(attr, &proc->attr.mainwin, sizeof(Ico_Uxf_ProcessWin));
345     }
346     else    {
347         pwin = proc->procwin;
348         for (n = 1; n < winidx; n++)   {
349             if (! pwin) {
350                 uifw_warn("ico_uxf_process_window_get_one: Leave(ENOENT, winidx over)");
351                 return ICO_UXF_ENOENT;
352             }
353             pwin = pwin->next;
354         }
355         memcpy(attr, &pwin->attr, sizeof(Ico_Uxf_ProcessWin));
356     }
357     uifw_trace("ico_uxf_process_window_get_one: Leave(EOK)");
358     return ICO_UXF_EOK;
359 }
360
361 /*--------------------------------------------------------------------------*/
362 /**
363  * @brief   ico_uxf_process_query_processes: get all process current status
364  *
365  * @param[out]  attr        process's current status
366  * @return  result
367  * @retval  >= 0            success(number of process)
368  * @retval  ICO_UXF_E2BIG   The number of the process has exceeded num
369  *                          The attribute of the process up to a num piece is returned to attr
370  * @retval  ICO_UXF_EOK     success
371  * @retval  ICO_UXF_ESRCH   error(not initialized)
372  * @retval  ICO_UXF_EINVAL  error(num is 0 or less)
373  * @retval  ICO_UXF_EPERM   error(no authority)
374  */
375 /*--------------------------------------------------------------------------*/
376 ICO_APF_API int
377 ico_uxf_process_query_processes(Ico_Uxf_ProcessAttr attr[], const int num)
378 {
379     int         n;                          /* number of process                */
380     Ico_Uxf_Mng_Process *mng;               /* process management table         */
381     int         hash;
382
383     uifw_trace("ico_uxf_process_query_processes: Enter(,%d)", num);
384
385     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
386         uifw_warn("ico_uxf_process_query_processes: Leave(ESRCH)");
387         return ICO_UXF_ESRCH;
388     }
389
390     if (num <= 0)  {
391         uifw_warn("ico_uxf_process_query_processes: Leave(EINVAL)");
392         return ICO_UXF_EINVAL;
393     }
394
395     n = 0;
396     for (hash = 0; hash < ICO_UXF_MISC_HASHSIZE; hash++)   {
397         mng = gIco_Uxf_Api_Mng.Hash_ProcessId[hash];
398         while (mng)    {
399             if (n >= num)  break;
400             memcpy((char *)(&attr[n]), (char *)&(mng->attr), sizeof(Ico_Uxf_ProcessAttr));
401             n ++;
402             mng = mng->nextidhash;
403         }
404         if (mng)   break;
405     }
406
407     if (mng)   {
408         n = ICO_UXF_E2BIG;
409         uifw_trace("ico_uxf_process_query_processes: Leave(E2BIG)");
410     }
411     else    {
412         uifw_trace("ico_uxf_process_query_processes: Leave(%d)", n);
413     }
414     return n;
415 }
416