Bug fix TIVI-839 ,change the design and permit operation of the music player while...
[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             if (strcasecmp(proc->attr.process, name) == 0)  break;
64             proc = proc->nextidhash;
65         }
66         if (proc) break;
67     }
68
69     if (! proc) {
70         uifw_warn("ico_uxf_process_execute: Leave(ENOENT)");
71         return ICO_UXF_ENOENT;
72     }
73
74     ico_uxf_enter_critical();               /* enter critical section           */
75
76     if (proc->attr.status != ICO_UXF_PROCSTATUS_STOP)   {
77         ico_uxf_leave_critical();           /* leave critical section           */
78         uifw_warn("ico_uxf_process_execute: Leave(EBUSY)");
79         return ICO_UXF_EBUSY;
80     }
81
82     /* in order to avoid double execute, status set starting    */
83     proc->attr.status = ICO_UXF_PROCSTATUS_INIT;
84     ico_uxf_leave_critical();               /* leave critical section           */
85
86     /* setup option */
87     appBundle = bundle_create();
88     apptbl = (Ico_Uxf_conf_application *)ico_uxf_getAppByAppid(name);
89     if ((appBundle != NULL) && (apptbl != NULL))    {
90         char *opt = strdup(apptbl->exec);
91         char *str = strtok(opt, " ");
92         while (str != NULL) {
93             str = strtok(NULL, " ");
94             if (str != NULL)    {
95                 bundle_add(appBundle, str, "Application");
96                 uifw_trace("ico_uxf_process_execute: option(%s)", str);
97             }
98         }
99         free(opt);
100     }
101
102     /* execute program                      */
103     proc->attr.internalid = aul_launch_app(name ,appBundle);
104     if (appBundle != NULL) {
105         bundle_free(appBundle);
106     }
107     if (proc->attr.internalid < 0)  {
108         uifw_error("ico_uxf_process_execute: Leave(ENOSYS), Launch App Error(%d)",
109                    proc->attr.internalid);
110         return ICO_UXF_ENOSYS;
111     }
112
113     proc->attr.status = ICO_UXF_PROCSTATUS_RUN;
114
115     uifw_trace("ico_uxf_process_execute: Leave(%s)", proc->attr.process);
116     return ICO_UXF_EOK;
117 }
118
119 /*--------------------------------------------------------------------------*/
120 /**
121  * @brief   ico_uxf_process_terminate: finish a program
122  *
123  * @param[in]   process     process id
124  * @return  result
125  * @retval  ICO_UXF_EOK         success
126  * @retval  ICO_UXF_ESRCH       error(not initialized)
127  * @retval  ICO_UXF_ENOENT      error(does not exist)
128  * @retval  ICO_UXF_EAGAIN      error(already launch)
129  * @retval  ICO_UXF_EPERM       error(no authority)
130  */
131 /*--------------------------------------------------------------------------*/
132 ICO_APF_API int
133 ico_uxf_process_terminate(const char *process)
134 {
135     Ico_Uxf_Mng_Process     *proc;          /* process management table         */
136     int                     ret;            /* process management table         */
137
138     uifw_trace("ico_uxf_process_terminate: Enter(%s)", process);
139
140     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
141         uifw_warn("ico_uxf_process_terminate: Leave(ESRCH)");
142         return ICO_UXF_ESRCH;
143     }
144
145     /* target is other process */
146     proc = ico_uxf_mng_process(process, 0);
147     if (! proc)    {
148         uifw_warn("ico_uxf_process_terminate: Leave(ENOENT)");
149         return ICO_UXF_ENOENT;
150     }
151
152     ret = aul_terminate_pid(proc->attr.internalid);
153     if (ret < 0) {
154         uifw_warn("ico_uxf_process_terminate: Leave(ENOSYS) cannot terminate pid=%d",
155                   proc->attr.internalid);
156         return ICO_UXF_ENOSYS;
157     }
158
159     proc->attr.status = ICO_UXF_PROCSTATUS_STOP;
160     proc->attr.internalid = -1;
161     proc->attr.mainwin.window = 0;
162     ico_uxf_free_procwin(proc);
163
164     uifw_trace("ico_uxf_process_terminate: Leave(EOK)");
165     return ICO_UXF_EOK;
166 }
167
168 /*--------------------------------------------------------------------------*/
169 /**
170  * @brief   ico_uxf_process_attribute_get: get a process's current state
171  *
172  * @param[in]   process     process's identity
173  * @param[out]  attr        target process's current state
174  * @return  result
175  * @retval  ICO_UXF_EOK         success
176  * @retval  ICO_UXF_ESRCH       error(not initialized)
177  * @retval  ICO_UXF_ENOENT      error(does not exist)
178  * @retval  ICO_UXF_EPERM       error(no authority)
179  */
180 /*--------------------------------------------------------------------------*/
181 ICO_APF_API int
182 ico_uxf_process_attribute_get(const char *process, Ico_Uxf_ProcessAttr *attr)
183 {
184     Ico_Uxf_Mng_Process *proc;              /* process management table             */
185
186     uifw_trace("ico_uxf_process_attribute_get: Enter(%s)", process);
187
188     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
189         uifw_warn("ico_uxf_process_attribute_get: Leave(ESRCH)");
190         return ICO_UXF_ESRCH;
191     }
192
193     proc = ico_uxf_mng_process(process, 0);
194     if (! proc)    {
195         uifw_warn("ico_uxf_process_attribute_get: Leave(ENOENT)");
196         return ICO_UXF_ENOENT;
197     }
198
199     memcpy((char *)attr, (char *)&(proc->attr), sizeof(Ico_Uxf_ProcessAttr));
200
201     uifw_trace("ico_uxf_process_attribute_get: Leave(EOK)");
202     return ICO_UXF_EOK;
203 }
204
205 /*--------------------------------------------------------------------------*/
206 /**
207  * @brief   ico_uxf_process_is_active: get application activity
208  *
209  * @param[in]   process     process's identity
210  * @return  result
211  * @retval  2               process is child process
212  * @retval  1               process is active
213  * @retval  0               process is not active
214  */
215 /*--------------------------------------------------------------------------*/
216 ICO_APF_API int
217 ico_uxf_process_is_active(const char *process)
218 {
219     Ico_Uxf_Mng_Process *proc;              /* process management table             */
220
221     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
222         uifw_warn("ico_uxf_process_is_active: False(ESRCH)");
223         return 0;
224     }
225
226     proc = ico_uxf_mng_process(process, 0);
227     if (! proc)    {
228         uifw_warn("ico_uxf_process_is_active: False(ENOENT)");
229         return 0;
230     }
231
232     if (proc->attr.child)   {
233         uifw_trace("ico_uxf_process_is_active: %s is Child", process);
234         return 2;
235     }
236     uifw_trace("ico_uxf_process_is_active: %s is %s",
237                process, proc->attr.active ? "Active" : "Inactive");
238     return proc->attr.active;
239 }
240
241 /*--------------------------------------------------------------------------*/
242 /**
243  * @brief   ico_uxf_process_window_get: get a window defined by the process
244  *
245  * @param[in]   process     process identity
246  * @param[out]  attr        return a window definition
247  *                          First is main window of the process,
248  *                          second henceforth is sub window of the process.
249  *                          At present support only main window.
250  * @param[in]   num         number of window definition(= array size)
251  * @return  result
252  * @retval  >= 0            success(number of windows)
253  * @retval  ICO_UXF_E2BIG   The number of the process has exceeded num
254  *                          The attribute of the process up to a num piece is returned to attr
255  * @retval  ICO_UXF_ENOENT  error(does not exist)
256  * @retval  ICO_UXF_EINVAL  error(num is 0 or less)
257  * @retval  ICO_UXF_ESRCH   error(not initialized)
258  * @retval  ICO_UXF_EPERM   error(no authority)
259  */
260 /*--------------------------------------------------------------------------*/
261 ICO_APF_API int
262 ico_uxf_process_window_get(const char *process, Ico_Uxf_ProcessWin *attr, const int num)
263 {
264     Ico_Uxf_Mng_Process *proc;              /* process management table         */
265     Ico_Uxf_Mng_ProcWin *pwin;              /* Process possession window table  */
266     int         n;                          /* number of window                 */
267
268     uifw_trace("ico_uxf_process_window_get: Enter(%s,,%d)", process, num);
269
270     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
271         uifw_warn("ico_uxf_process_window_get: Leave(ESRCH)");
272         return ICO_UXF_ESRCH;
273     }
274
275     if (num <= 0)  {
276         uifw_warn("ico_uxf_process_window_get: Leave(EINVAL)");
277         return ICO_UXF_EINVAL;
278     }
279
280     proc = ico_uxf_mng_process(process, 0);
281     if (! proc)    {
282         uifw_trace("ico_uxf_process_window_get: Leave(ENOENT)");
283         return ICO_UXF_ENOENT;
284     }
285
286     memcpy((char *)&(attr[0]), (char *)&(proc->attr.mainwin), sizeof(Ico_Uxf_ProcessWin));
287
288     pwin = proc->procwin;
289     for (n = 1; n < num; n++)  {
290         if (! pwin)    break;
291         memcpy((char *)&(attr[n]), (char *)&(pwin->attr), sizeof(Ico_Uxf_ProcessWin));
292         pwin = pwin->next;
293     }
294
295     if (pwin)  {
296         n = ICO_UXF_E2BIG;
297         uifw_trace("ico_uxf_process_window_get: Leave(E2BIG)");
298     }
299     else    {
300         uifw_trace("ico_uxf_process_window_get: Leave(%d)", n);
301     }
302     return n;
303 }
304
305 /*--------------------------------------------------------------------------*/
306 /**
307  * @brief   ico_uxf_process_window_get_one: get a window defined by the process
308  *
309  * @param[in]   process     process identity(appid)
310  * @param[out]  attr        return a window definition
311  * @param[in]   winidx      window index(0 is main window, 1-N is sub window)
312  * @return  result
313  * @retval  ICO_UXF_EOK     success
314  * @retval  ICO_UXF_ENOENT  error(does not exist)
315  * @retval  ICO_UXF_EINVAL  error(winidx is negative)
316  * @retval  ICO_UXF_ESRCH   error(not initialized)
317  * @retval  ICO_UXF_EPERM   error(no authority)
318  */
319 /*--------------------------------------------------------------------------*/
320 ICO_APF_API int
321 ico_uxf_process_window_get_one(const char *process,
322                                Ico_Uxf_ProcessWin *attr, const int winidx)
323 {
324     Ico_Uxf_Mng_Process *proc;              /* process management table         */
325     Ico_Uxf_Mng_ProcWin *pwin;              /* Process possession window table  */
326     int         n;                          /* number of window                 */
327
328     uifw_trace("ico_uxf_process_window_get_one: Enter(%s,,%d)", process, winidx);
329
330     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
331         uifw_warn("ico_uxf_process_window_get_one: Leave(ESRCH)");
332         return ICO_UXF_ESRCH;
333     }
334
335     if (winidx < 0)    {
336         uifw_warn("ico_uxf_process_window_get_one: Leave(EINVAL)");
337         return ICO_UXF_EINVAL;
338     }
339
340     proc = ico_uxf_mng_process(process, 0);
341     if (! proc)    {
342         uifw_warn("ico_uxf_process_window_get_one: Leave(ENOENT, no appid)");
343         return ICO_UXF_ENOENT;
344     }
345     if (winidx >= proc->attr.numwindows) {
346         uifw_warn("ico_uxf_process_window_get_one: Leave(ENOENT, winidx over)");
347         return ICO_UXF_ENOENT;
348     }
349
350     if (winidx == 0)    {
351         memcpy(attr, &proc->attr.mainwin, sizeof(Ico_Uxf_ProcessWin));
352     }
353     else    {
354         pwin = proc->procwin;
355         for (n = 1; n < winidx; n++)   {
356             if (! pwin) {
357                 uifw_warn("ico_uxf_process_window_get_one: Leave(ENOENT, winidx over)");
358                 return ICO_UXF_ENOENT;
359             }
360             pwin = pwin->next;
361         }
362         memcpy(attr, &pwin->attr, sizeof(Ico_Uxf_ProcessWin));
363     }
364     uifw_trace("ico_uxf_process_window_get_one: Leave(EOK)");
365     return ICO_UXF_EOK;
366 }
367
368 /*--------------------------------------------------------------------------*/
369 /**
370  * @brief   ico_uxf_process_query_processes: get all process current status
371  *
372  * @param[out]  attr        process's current status
373  * @return  result
374  * @retval  >= 0            success(number of process)
375  * @retval  ICO_UXF_E2BIG   The number of the process has exceeded num
376  *                          The attribute of the process up to a num piece is returned to attr
377  * @retval  ICO_UXF_EOK     success
378  * @retval  ICO_UXF_ESRCH   error(not initialized)
379  * @retval  ICO_UXF_EINVAL  error(num is 0 or less)
380  * @retval  ICO_UXF_EPERM   error(no authority)
381  */
382 /*--------------------------------------------------------------------------*/
383 ICO_APF_API int
384 ico_uxf_process_query_processes(Ico_Uxf_ProcessAttr attr[], const int num)
385 {
386     int         n;                          /* number of process                */
387     Ico_Uxf_Mng_Process *mng;               /* process management table         */
388     int         hash;
389
390     uifw_trace("ico_uxf_process_query_processes: Enter(,%d)", num);
391
392     if (gIco_Uxf_Api_Mng.Initialized <= 0) {
393         uifw_warn("ico_uxf_process_query_processes: Leave(ESRCH)");
394         return ICO_UXF_ESRCH;
395     }
396
397     if (num <= 0)  {
398         uifw_warn("ico_uxf_process_query_processes: Leave(EINVAL)");
399         return ICO_UXF_EINVAL;
400     }
401
402     n = 0;
403     for (hash = 0; hash < ICO_UXF_MISC_HASHSIZE; hash++)   {
404         mng = gIco_Uxf_Api_Mng.Hash_ProcessId[hash];
405         while (mng)    {
406             if (n >= num)  break;
407             memcpy((char *)(&attr[n]), (char *)&(mng->attr), sizeof(Ico_Uxf_ProcessAttr));
408             n ++;
409             mng = mng->nextidhash;
410         }
411         if (mng)   break;
412     }
413
414     if (mng)   {
415         n = ICO_UXF_E2BIG;
416         uifw_trace("ico_uxf_process_query_processes: Leave(E2BIG)");
417     }
418     else    {
419         uifw_trace("ico_uxf_process_query_processes: Leave(%d)", n);
420     }
421     return n;
422 }
423