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