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