Bug fix for TIVI-1002
[profile/ivi/ico-uxf-homescreen.git] / apps_controller / ico_syc_apc_control.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   Initialize/Terminate and Control for Apps Controller of System Controller
11  *
12  * @date    Feb-28-2013
13  */
14
15 #include    <stdio.h>
16 #include    <stdlib.h>
17 #include    <unistd.h>
18 #include    <stdbool.h>
19 #include    <string.h>
20 #include    <errno.h>
21 #include    <pthread.h>
22 #include    <sys/ioctl.h>
23 #include    <sys/time.h>
24 #include    <sys/resource.h>
25 #include    <fcntl.h>
26
27 #include    <wayland-client.h>
28 #include    <ico_window_mgr-client-protocol.h>
29 #include    <dbus/dbus.h>
30 #include    <Ecore.h>
31 #include    "ico_apf.h"
32 #include    "ico_uxf.h"
33 #include    "ico_apf_ecore.h"
34 #include    "ico_syc_apc.h"
35 #include    "ico_syc_apc_private.h"
36
37 /*==============================================================================*/
38 /* static tables                                                                */
39 /*==============================================================================*/
40 /* flag for initiailze                  */
41 static int  ico_apps_controller_init = 0;
42
43 /* zone management table                */
44 static ico_apc_dispzone_t       *dispzone = NULL;
45 static int                      ndispzone = 0;
46 static ico_apc_soundzone_t      *soundzone = NULL;
47 static int                      nsoundzone = 0;
48 static ico_apc_inputsw_t        *inputsw = NULL;
49 static int                      ninputsw = 0;
50
51 /* free request save table              */
52 static ico_apc_request_t        *free_request = NULL;
53
54 /* user(HomeScreen) control functions   */
55 static ico_apc_resource_control_t   displaycontrol = NULL;
56 static ico_apc_resource_control_t   soundcontrol = NULL;
57 static ico_apc_resource_control_t   inputcontrol = NULL;
58
59 /* Ecore timer                          */
60 static int  timer_count = 0;
61 static Ecore_Timer *ecore_timer = NULL;
62
63 /* configuration                        */
64 static Ico_Uxf_Sys_Config       *confsys = NULL;
65 static Ico_Uxf_App_Config       *confapp = NULL;
66
67 /*==============================================================================*/
68 /* define static function prototype                                             */
69 /*==============================================================================*/
70 static void resource_reqcb(ico_apf_resource_notify_info_t* info, void *user_data);
71 static void app_getdisplay(ico_apc_request_t *req, const int addprio);
72 static void app_freedisplay(ico_apc_request_t *req, const int send);
73 static void change_disprequest(ico_apc_request_t *req, const int active);
74 static void recalc_dispzone(const int idx);
75 static void app_getsound(ico_apc_request_t *req, const int addprio);
76 static void app_freesound(ico_apc_request_t *req, const int send);
77 static void change_soundrequest(ico_apc_request_t *req, const int active);
78 static void recalc_soundzone(const int idx);
79 static void app_getinput(ico_apc_request_t *req, const int addprio);
80 static void app_freeinput(ico_apc_request_t *req, const int send);
81 static void change_inputrequest(ico_apc_request_t *req, const int active);
82 static void recalc_inputsw(const int idx);
83 static void regulation_listener(const int appcategory,
84                                 const ico_apc_reguration_control_t control,
85                                 void *user_data);
86 static Eina_Bool request_timer(void *user_data);
87 static void app_display_hook(const char *appid, const int surface, const int object);
88 static ico_apc_request_t *get_freereq(void);
89 static ico_apc_request_t *search_disprequest(const Ico_Uxf_conf_application *conf,
90                                              const int resid, const int id);
91 static ico_apc_request_t *search_soundrequest(const Ico_Uxf_conf_application *conf,
92                                               const int resid, const int id,
93                                               ico_apc_request_t **first_req);
94
95 /*==============================================================================*/
96 /* define fixed value                                                           */
97 /*==============================================================================*/
98 /* initiale allocate request blocks     */
99 #define INIT_REQCB  50
100
101 /* maximum number of request blocks     */
102 #if ICO_UXF_DISPLAY_ZONE_MAX > ICO_UXF_SOUND_ZONE_MAX
103   #if ICO_UXF_INPUT_SW_MAX > ICO_UXF_DISPLAY_ZONE_MAX
104     #define MAXREQ  ICO_UXF_INPUT_SW_MAX
105   #else
106     #define MAXREQ  ICO_UXF_DISPLAY_ZONE_MAX
107   #endif
108 #else
109   #if ICO_UXF_INPUT_SW_MAX > ICO_UXF_SOUND_ZONE_MAX
110     #define MAXREQ  ICO_UXF_INPUT_SW_MAX
111   #else
112     #define MAXREQ  ICO_UXF_SOUND_ZONE_MAX
113   #endif
114 #endif
115
116 /*--------------------------------------------------------------------------*/
117 /**
118  * @brief   get_appconf: application configure(static function)
119  *
120  * @param       appid           application id
121  * @return      result
122  * @retval      != NULL         success(request block address)
123  * @retval      == NULL         error(out of memory)
124  */
125 /*--------------------------------------------------------------------------*/
126 static Ico_Uxf_conf_application *
127 get_appconf(const char *appid)
128 {
129     Ico_Uxf_conf_application *appconf = NULL;
130
131     appconf = (Ico_Uxf_conf_application *)ico_uxf_getAppByAppid(appid);
132     if (! appconf)  {
133         /* application id dose not exist, search application name   */
134         appconf = (Ico_Uxf_conf_application *)ico_uxf_getAppByName(appid);
135     }
136
137     return appconf;
138 }
139
140 /*--------------------------------------------------------------------------*/
141 /**
142  * @brief   get_freereq: get free request block(static function)
143  *
144  * @param       none
145  * @return      result
146  * @retval      != NULL         success(request block address)
147  * @retval      == NULL         error(out of memory)
148  */
149 /*--------------------------------------------------------------------------*/
150 static ico_apc_request_t *
151 get_freereq(void)
152 {
153     ico_apc_request_t   *req;
154     int     i;
155
156     if (! free_request)   {
157         free_request = malloc(sizeof(ico_apc_request_t)*ICO_UXF_MNG_BLOCK_ALLOCS);
158         if (! free_request)  {
159             apfw_error("get_freereq: No Memory");
160             return NULL;
161         }
162         req = free_request;
163         for (i = 0; i < ICO_UXF_MNG_BLOCK_ALLOCS; i++, req++)   {
164             if (i < (ICO_UXF_MNG_BLOCK_ALLOCS-1))   {
165                 req->next = (req+1);
166             }
167             else    {
168                 req->next = NULL;
169             }
170         }
171     }
172     req = free_request;
173     memset(req, 0, sizeof(ico_apc_request_t));
174     free_request = free_request->next;
175
176     return req;
177 }
178
179 /*--------------------------------------------------------------------------*/
180 /**
181  * @brief   search_disprequest: search client display request(static function)
182  *
183  * @param[in]   conf            application configuration
184  * @param[in]   resid           resource type
185  * @param[in]   id              resource id requested from client
186  * @return      result
187  * @retval      != NULL         success(request block)
188  * @retval      == NULL         error(request was not found)
189  */
190 /*--------------------------------------------------------------------------*/
191 static ico_apc_request_t *
192 search_disprequest(const Ico_Uxf_conf_application *conf, const int resid, const int id)
193 {
194     int                 i;
195     ico_apc_request_t   *p;
196     ico_apc_request_t   *sameres = NULL;
197
198     for (i = 0; i < ndispzone; i++) {
199         p = dispzone[i].req;
200         while (p)   {
201             if ((strcmp(p->appid, conf->appid) == 0) &&
202                 ((int)p->resid == resid))    {
203                 if ((id < 0) || (p->id == id))  {
204                     return p;
205                 }
206                 if (! sameres)  sameres = p;
207             }
208             p = p->next;
209         }
210     }
211     return sameres;
212 }
213
214 /*--------------------------------------------------------------------------*/
215 /**
216  * @brief   search_soundrequest: search client sound request(static function)
217  *
218  * @param[in]   conf            application configuration
219  * @param[in]   resid           resource type
220  * @param[in]   id              resource id requested from client
221  * @param[out]  first_req       request of top on same sound zone
222  * @return      result
223  * @retval      != NULL         success(request block)
224  * @retval      == NULL         error(request was not found)
225  */
226 /*--------------------------------------------------------------------------*/
227 static ico_apc_request_t *
228 search_soundrequest(const Ico_Uxf_conf_application *conf, const int resid,
229                     const int id, ico_apc_request_t **first_req)
230 {
231     int                 i;
232     ico_apc_request_t   *p;
233     ico_apc_request_t   *sameres = NULL;
234
235     for (i = 0; i < nsoundzone; i++) {
236         p = soundzone[i].req;
237         while (p)   {
238             if ((strcmp(p->appid, conf->appid) == 0) &&
239                 ((int)p->resid == resid))    {
240                 if ((id < 0) || (p->id == id))  {
241                     if (first_req)  {
242                         *first_req = soundzone[i].req;
243                     }
244                     return p;
245                 }
246                 if (! sameres)  sameres = p;
247             }
248             p = p->next;
249         }
250     }
251     return sameres;
252 }
253
254 /*--------------------------------------------------------------------------*/
255 /**
256  * @brief   resource_reqcb: resource request callback(static function)
257  *
258  * @param[in]   info            request information
259  * @param[in]   user_data       user data(unused)
260  * @return      none
261  */
262 /*--------------------------------------------------------------------------*/
263 static void
264 resource_reqcb(ico_apf_resource_notify_info_t* info, void *user_data)
265 {
266     Ico_Uxf_conf_application    *appconf;
267     ico_apc_request_t           *req;
268     ico_apc_request_t           *p;
269     ico_apc_request_t           *freq;
270     int                         i;
271     int                         count;
272     ico_apc_request_t           *reqsave[MAXREQ];
273
274     apfw_trace("resource_reqcb: Entry(cmd=%d res=%d id=%d bid=%d app=%s[%d])",
275                info->state, info->resid, info->id, info->bid, info->appid, info->pid);
276
277     if (info->state == ICO_APF_RESOURCE_STATE_CONNECTED)    {
278         apfw_trace("resource_reqcb: Leave(application connected)");
279         return;
280     }
281
282     if (info->state >= ICO_APF_SOUND_COMMAND_MIN)   {
283         /* Multi Sound Manager, data check          */
284         if ((int)info->state == (int)ICO_APF_SOUND_REPLY_LIST)  {
285             apfw_trace("resource_reqcb: Leave(Sound Reply, no need)");
286             return;
287         }
288         if (info->appid[0] == 0)    {
289             apfw_warn("resource_reqcb: Leave(Sound Event, but no appid)");
290             return;
291         }
292         if ((int)info->state == (int)ICO_APF_SOUND_EVENT_FREE)  {
293             apfw_trace("resource_reqcb: Leave(Sound Free, no need)");
294             return;
295         }
296     }
297
298     /* check and search application id      */
299     appconf = (Ico_Uxf_conf_application *)ico_uxf_getAppByAppid(info->appid);
300     if (! appconf)  {
301         /* application id dose not exist, search application name   */
302         appconf = (Ico_Uxf_conf_application *)ico_uxf_getAppByName(info->appid);
303         if (! appconf)  {
304             apfw_error("resource_reqcb: Leave(appid[%s] dose not exist)",
305                        info->appid);
306             return;
307         }
308     }
309     if ((info->state >= ICO_APF_SOUND_COMMAND_MIN) &&
310         ((confsys->kind[appconf->kindId].priv == ICO_UXF_PRIVILEGE_ALMIGHTY) ||
311          (confsys->kind[appconf->kindId].priv == ICO_UXF_PRIVILEGE_SYSTEM) ||
312          (confsys->kind[appconf->kindId].priv == ICO_UXF_PRIVILEGE_SYSTEM_AUDIO)))  {
313         /* System Program(ex. HomeScreen) no need resource control  */
314         apfw_trace("resource_reqcb: Leave(appid[%s] is system program)",
315                    info->appid);
316         return;
317     }
318
319     if (info->state == ICO_APF_RESOURCE_STATE_DISCONNECTED) {
320         apfw_trace("resource_reqcb: DISCONNECTED[%s]", info->appid);
321
322         /* free all screen request from this application    */
323         count = 0;
324         for (i = 0; i < ndispzone; i++) {
325             p = dispzone[i].req;
326             while (p)   {
327                 if (strcmp(p->appid, appconf->appid) == 0) {
328                     reqsave[count++] = p;
329                 }
330                 p = p->next;
331             }
332         }
333         for (i = 0; i < count; i++) {
334             app_freedisplay(reqsave[i], 0);
335         }
336         /* free all sound request from this application     */
337         count = 0;
338         for (i = 0; i < nsoundzone; i++)    {
339             p = soundzone[i].req;
340             while (p)   {
341                 if (strcmp(p->appid, appconf->appid) == 0) {
342                     reqsave[count++] = p;
343                 }
344                 p = p->next;
345             }
346         }
347         for (i = 0; i < count; i++) {
348             app_freesound(reqsave[i], 0);
349         }
350         /* free all input switch request from this application*/
351         count = 0;
352         for (i = 0; i < ninputsw; i++)  {
353             p = inputsw[i].req;
354             while (p)   {
355                 if (strcmp(p->appid, appconf->appid) == 0) {
356                     reqsave[count++] = p;
357                 }
358                 p = p->next;
359             }
360         }
361         for (i = 0; i < count; i++) {
362             app_freeinput(reqsave[i], 0);
363         }
364         apfw_trace("resource_reqcb: Leave");
365         return;
366     }
367
368     req = get_freereq();
369     if (! req)  {
370         return;
371     }
372     strncpy(req->appid, appconf->appid, ICO_UXF_MAX_PROCESS_NAME);
373     req->resid = info->resid;
374     if (info->device[0])    {
375         strcpy(req->device, info->device);
376     }
377     else    {
378         strcpy(req->device, "UnKnown");
379     }
380     req->id = info->id;
381     req->bid = info->bid;
382     req->pid = info->pid;
383     req->reqtype = ICO_APC_REQTYPE_REQUEST;
384
385     switch (info->resid)    {
386     case ICO_APF_RESID_BASIC_SCREEN:                /* basic screen             */
387         switch (info->state)    {
388         case ICO_APF_RESOURCE_COMMAND_GET:          /* get resource             */
389             apfw_trace("resource_reqcb: app(%s) get BasicScreen(%d)",
390                        info->appid, info->id);
391             app_getdisplay(req, 0);
392             req = NULL;
393             break;
394         case ICO_APF_RESOURCE_COMMAND_RELEASE:      /* release resource         */
395             apfw_trace("resource_reqcb: app(%s) release BasicScreen(%d)",
396                        info->appid, info->id);
397             app_freedisplay(req, 1);
398             req = NULL;
399             break;
400         case ICO_APF_RESOURCE_REPLY_OK:             /* ack reply                */
401         case ICO_APF_RESOURCE_REPLY_NG:             /* nak reply                */
402             apfw_trace("resource_reqcb: app(%s) BasicScreen(%d) reply(%s)", info->appid,
403                        info->id, info->state == ICO_APF_RESOURCE_REPLY_OK ? "OK" : "NG");
404             p = search_disprequest(appconf, ICO_APF_RESID_BASIC_SCREEN, info->id);
405             if (p)  {
406                 if (p->state & ICO_APC_REQSTATE_REPLYACTIVE)    {
407                     ico_uxf_window_control(appconf->appid, p->id,
408                                            ICO_UXF_APPSCTL_INVISIBLE, 0);
409                     if (displaycontrol) {
410                         (*displaycontrol)(appconf, 1);
411                     }
412                 }
413                 p->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
414                 p->timer = 0;
415             }
416             break;
417         default:
418             apfw_error("resource_reqcb: illegal command(%d)", info->state);
419             break;
420         }
421         break;
422     case ICO_APF_RESID_INT_SCREEN:                  /* interrupt screen         */
423         switch (info->state)    {
424         case ICO_APF_RESOURCE_COMMAND_GET:          /* get resource             */
425             apfw_trace("resource_reqcb: app(%s) get IntScreen(%d) on basic screen(%d)",
426                        info->appid, info->id, info->bid);
427             app_getdisplay(req, ICO_UXF_PRIO_INTSCREEN);
428             req = NULL;
429             break;
430         case ICO_APF_RESOURCE_COMMAND_RELEASE:      /* release resource         */
431             apfw_trace("resource_reqcb: app(%s) release IntScreen(%d)",
432                        info->appid, info->id);
433             app_freedisplay(req, 1);
434             req = NULL;
435             break;
436         case ICO_APF_RESOURCE_REPLY_OK:             /* ack reply                */
437         case ICO_APF_RESOURCE_REPLY_NG:             /* nak reply                */
438             apfw_trace("resource_reqcb: app(%s) IntScreen(%d) reply(%s)", info->appid,
439                        info->id, info->state == ICO_APF_RESOURCE_REPLY_OK ? "OK" : "NG");
440             p = search_disprequest(appconf, ICO_APF_RESID_INT_SCREEN, info->id);
441             if (p)  {
442                 if (p->state & ICO_APC_REQSTATE_REPLYACTIVE)    {
443                     ico_uxf_window_control(appconf->appid, p->id,
444                                            ICO_UXF_APPSCTL_INVISIBLE, 0);
445                     if (displaycontrol) {
446                         (*displaycontrol)(appconf, 1);
447                     }
448                 }
449                 p->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
450                 p->timer = 0;
451             }
452             break;
453         default:
454             apfw_error("resource_reqcb: illegal command(%d)", info->state);
455             break;
456         }
457         break;
458     case ICO_APF_RESID_ON_SCREEN:                   /* on screen                */
459         switch (info->state)    {
460         case ICO_APF_RESOURCE_COMMAND_GET:          /* get resource             */
461             apfw_trace("resource_reqcb: app(%s) get OnScreen(%d)",
462                        info->appid, info->id);
463             app_getdisplay(req, ICO_UXF_PRIO_ONSCREEN);
464             req = NULL;
465             break;
466         case ICO_APF_RESOURCE_COMMAND_RELEASE:      /* release resource         */
467             apfw_trace("resource_reqcb: app(%s) release OnScreen(%d)",
468                        info->appid, info->id);
469             app_freedisplay(req, 1);
470             req = NULL;
471             break;
472         case ICO_APF_RESOURCE_REPLY_OK:             /* ack reply                */
473         case ICO_APF_RESOURCE_REPLY_NG:             /* nak reply                */
474             apfw_trace("resource_reqcb: app(%s) OnScreen(%d) reply(%s)", info->appid,
475                        info->id, info->state == ICO_APF_RESOURCE_REPLY_OK ? "OK" : "NG");
476             p = search_disprequest(appconf, ICO_APF_RESID_ON_SCREEN, info->id);
477             if (p)  {
478                 if (p->state & ICO_APC_REQSTATE_REPLYACTIVE)    {
479                     ico_uxf_window_control(appconf->appid, p->id,
480                                            ICO_UXF_APPSCTL_INVISIBLE, 0);
481                     if (displaycontrol) {
482                         (*displaycontrol)(appconf, 1);
483                     }
484                 }
485                 p->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
486                 p->timer = 0;
487             }
488             break;
489         default:
490             apfw_error("resource_reqcb: illegal command(%d)", info->state);
491             break;
492         }
493         break;
494     case ICO_APF_RESID_BASIC_SOUND:                 /* basic sound              */
495         switch ((int)info->state)    {
496         case ICO_APF_RESOURCE_COMMAND_GET:          /* get resource             */
497             apfw_trace("resource_reqcb: app(%s) get BasicSound(%d)",
498                        info->appid, info->id);
499             app_getsound(req, 0);
500             req = NULL;
501             break;
502         case ICO_APF_RESOURCE_COMMAND_RELEASE:      /* release resource         */
503             apfw_trace("resource_reqcb: app(%s) release BasicSound(%d)",
504                        info->appid, info->id);
505             app_freesound(req, 1);
506             req = NULL;
507             break;
508         case ICO_APF_RESOURCE_REPLY_OK:             /* ack reply                */
509         case ICO_APF_RESOURCE_REPLY_NG:             /* nak reply                */
510             apfw_trace("resource_reqcb: app(%s) BasicSound(%d) reply(%s)", info->appid,
511                        info->id, info->state == ICO_APF_RESOURCE_REPLY_OK ? "OK" : "NG");
512             p = search_soundrequest(appconf, ICO_APF_RESID_BASIC_SOUND, info->id, NULL);
513             if (p)  {
514                 if (p->state & ICO_APC_REQSTATE_REPLYACTIVE)    {
515                     if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEOFF,
516                                                           p->pid)
517                             != ICO_APF_RESOURCE_E_NONE) {
518                         apfw_warn("resource_reqcb: send MSM Error");
519                     }
520                     if (soundcontrol) {
521                         (*soundcontrol)(get_appconf(req->appid), 1);
522                     }
523                 }
524                 p->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
525                 p->timer = 0;
526             }
527             break;
528         case ICO_APF_SOUND_EVENT_NEW:               /* create new sound stream  */
529             apfw_trace("resource_reqcb: app(%s) create BasicSound", info->appid);
530             p = search_soundrequest(appconf, ICO_APF_RESID_BASIC_SOUND, -1, &freq);
531             if (p)  {
532                 apfw_trace("resource_reqcb: app(%s,state=%x,prio=%08x,pid=%d=>%d) "
533                            "requested sound, Nop", p->appid, p->state, p->prio,
534                            p->pid, info->pid);
535                 p->pid = info->pid;
536                 if (p->state & ICO_APC_REQSTATE_WAITREQ)    {
537                     if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEON,
538                                                           p->pid)
539                             != ICO_APF_RESOURCE_E_NONE) {
540                         apfw_warn("resource_reqcb: send MSM Error");
541                     }
542                     if (soundcontrol) {
543                         (*soundcontrol)(get_appconf(p->appid), 0);
544                     }
545                     if ((freq->state & ICO_APC_REQSTATE_WAITREQ) == 0)  {
546                         if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEOFF,
547                                                               freq->pid)
548                                     != ICO_APF_RESOURCE_E_NONE) {
549                             apfw_warn("resource_reqcb: send MSM Error");
550                         }
551                         if (soundcontrol) {
552                             (*soundcontrol)(get_appconf(freq->appid), 1);
553                         }
554                     }
555                 }
556             }
557             else    {
558                 apfw_trace("resource_reqcb: app(%s) not requested sound", info->appid);
559                 req->resid = ICO_APF_RESID_BASIC_SOUND;
560                 req->reqtype = ICO_APC_REQTYPE_CREATE;
561                 strcpy(req->device,
562                        confsys->sound[confsys->misc.default_soundId].
563                             zone[confsys->misc.default_soundId].name);
564                 app_getsound(req, 0);
565                 req = NULL;
566             }
567             break;
568         default:
569             apfw_error("resource_reqcb: illegal command(%d)", info->state);
570             break;
571         }
572         break;
573     case ICO_APF_RESID_INT_SOUND:                   /* interrupt sound          */
574         switch (info->state)    {
575         case ICO_APF_RESOURCE_COMMAND_GET:          /* get resource             */
576             apfw_trace("resource_reqcb: app(%s) get IntSound(%d)",
577                        info->appid, info->id);
578             app_getsound(req, ICO_UXF_PRIO_ONSCREEN);
579             req = NULL;
580             break;
581         case ICO_APF_RESOURCE_COMMAND_RELEASE:      /* release resource         */
582             apfw_trace("resource_reqcb: app(%s) release IntSound(%d)",
583                        info->appid, info->id);
584             app_freesound(req, 1);
585             req = NULL;
586             break;
587         case ICO_APF_RESOURCE_REPLY_OK:             /* ack reply                */
588         case ICO_APF_RESOURCE_REPLY_NG:             /* nak reply                */
589             apfw_trace("resource_reqcb: app(%s) IntSound(%d) reply(%s)", info->appid,
590                        info->id, info->state == ICO_APF_RESOURCE_REPLY_OK ? "OK" : "NG");
591             p = search_soundrequest(appconf, ICO_APF_RESID_INT_SOUND, info->id, NULL);
592             if (p)  {
593                 if (p->state & ICO_APC_REQSTATE_REPLYACTIVE)    {
594                     if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEOFF,
595                                                           p->pid)
596                             != ICO_APF_RESOURCE_E_NONE) {
597                         apfw_warn("resource_reqcb: send MSM Error");
598                     }
599                     if (soundcontrol) {
600                         (*soundcontrol)(get_appconf(p->appid), 1);
601                     }
602                 }
603                 p->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
604                 p->timer = 0;
605             }
606             break;
607         default:
608             apfw_error("resource_reqcb: illegal command(%d)", info->state);
609             break;
610         }
611         break;
612     case ICO_APF_RESID_INPUT_DEV:                   /* input switch             */
613         if ((info->id < 0) || (info->id >= appconf->inputdevNum))   {
614             apfw_error("resource_reqcb: app(%s) cmd=%d InputSW(%d) but no exist",
615                        info->appid, info->state, info->id);
616         }
617         else    {
618             switch (info->state)    {
619             case ICO_APF_RESOURCE_COMMAND_ADD:      /* get switch               */
620                 apfw_trace("resource_reqcb: app(%s) get InputSW(%d)",
621                            info->appid, info->id);
622                 app_getinput(req, 0);
623                 req = NULL;
624                 break;
625             case ICO_APF_RESOURCE_COMMAND_CHANGE:   /* change switch            */
626                 apfw_trace("resource_reqcb: app(%s) change InputSW(%d)",
627                            info->appid, info->id);
628                 app_getinput(req, 0);
629                 req = NULL;
630                 break;
631             case ICO_APF_RESOURCE_COMMAND_DELETE:   /* delete switch            */
632                 apfw_trace("resource_reqcb: app(%s) delete InputSW(%d)",
633                            info->appid, info->id);
634                 app_freeinput(req, 1);
635                 req = NULL;
636                 break;
637             default:
638                 apfw_error("resource_reqcb: illegal command(%d)", info->state);
639                 break;
640             }
641         }
642         break;
643     default:
644         apfw_error("resource_reqcb: illegal resource(%d)", info->resid);
645         break;
646     }
647     if (req)    {
648         req->next = free_request;
649         free_request = req;
650     }
651     apfw_trace("resource_reqcb: Leave");
652 }
653
654 /*--------------------------------------------------------------------------*/
655 /**
656  * @brief   app_getdisplay: get display zone resource(static function)
657  *
658  * @param[in]   req             request block
659  * @param[in]   addprio         a priority to add to the priority of the request
660  * @return      none
661  */
662 /*--------------------------------------------------------------------------*/
663 static void
664 app_getdisplay(ico_apc_request_t *req, const int addprio)
665 {
666     int     prio;
667     int     i, j;
668     Ico_Uxf_conf_application    *conf = (Ico_Uxf_conf_application *)get_appconf(req->appid);
669     Ico_Uxf_conf_display_zone   *zone;
670     ico_apc_dispzone_t          *czone;
671     ico_apc_request_t           *p;
672     ico_apc_request_t           *bp;
673
674     /* priority     */
675     prio = getpriority(PRIO_PROCESS, req->pid);
676     if (prio > 19)          prio = 19;
677     else if (prio < -20)    prio = -20;
678     prio = confsys->category[conf->categoryId].priority * ICO_UXF_PRIO_CATEGORY + 19 - prio;
679     prio += addprio;
680     if (ico_syc_apc_regulation_app_visible(conf->categoryId))   {
681         prio |= ICO_UXF_PRIO_REGULATION;
682     }
683     if (ico_uxf_process_is_active(conf->appid)) {
684         for (i = 0; i < ndispzone; i++) {
685             p = dispzone[i].req;
686             while (p)   {
687                 if (p->prio & ICO_UXF_PRIO_ACTIVEAPP)  {
688                     p->prio -= ICO_UXF_PRIO_ACTIVECOUNT;
689                 }
690                 p = p->next;
691             }
692         }
693         prio |= ICO_UXF_PRIO_ACTIVEAPP;
694     }
695
696     /* get display zone from device name        */
697     for (i = 0; i < ndispzone; i++) {
698         if (strcasecmp(dispzone[i].conf->name, req->device) == 0)  break;
699     }
700     if (i >= ndispzone) {
701         i = confsys->misc.default_dispzoneId;
702         apfw_trace("app_getdisplay: Entry(app=%s zone=%s(%s none) res=%d prio=%x(+%x))",
703                    conf->appid, dispzone[i].conf->name, req->resid, req->device,
704                    prio, addprio);
705     }
706     else    {
707         apfw_trace("app_getdisplay: Entry(app=%s zone=%s res=%d prio=%x(+%x))",
708                    conf->appid, dispzone[i].conf->name, req->resid, prio, addprio);
709     }
710     req->zoneidx = i;
711
712     czone = &dispzone[i];
713     zone = czone->conf;
714
715     /* search same request          */
716     p = czone->req;
717     bp = NULL;
718     while (p)   {
719         if ((strcmp(p->appid, req->appid) == 0) && (p->resid == req->resid) &&
720             (p->zoneidx == req->zoneidx))   {
721             break;
722         }
723         bp = p;
724         p = p->next;
725     }
726     if (p)  {
727         if (p->reqtype != ICO_APC_REQTYPE_REQUEST)  {
728             apfw_trace("app_getdisplay: Leave(found same request)");
729             return;
730         }
731
732         if (p->prio > prio) {
733             prio = p->prio;
734         }
735         apfw_trace("app_getdisplay: found same request(app=%s zone=%s res=%d prio=%d)",
736                    conf->appid, dispzone[i].conf->name, req->resid, prio);
737         if (bp) {
738             bp->next = p->next;
739         }
740         else    {
741             czone->req = p->next;
742         }
743         p->next = free_request;
744         free_request = p;
745     }
746
747     /* link request to zone table   */
748     req->prio = prio;
749     p = czone->req;
750     bp = NULL;
751     while (p)   {
752         if (p->prio <= prio)    break;
753         bp = p;
754         p = p->next;
755     }
756     if (bp) {
757         req->next = bp->next;
758         bp->next = req;
759         apfw_trace("app_getdisplay: app(%s) set after(%s) of zone(%s)",
760                    conf->appid, bp->appid, req->device);
761     }
762     else    {
763         req->next = czone->req;
764         czone->req = req;
765         apfw_trace("app_getdisplay: app(%s) set top of zone(%s) next %s",
766                    conf->appid, req->device, req->next ? req->next->appid : "(NULL)");
767     }
768
769     /* check if maximum priority    */
770     if (! bp)   {
771         j = -1;
772         for (i = 0; i < czone->noverlap; i++)    {
773             if (((czone->overlap[i])->req != NULL) &&
774                 ((czone->overlap[i])->req->prio > prio))    {
775                 j = i;
776                 prio = czone->overlap[i]->req->prio;
777             }
778         }
779     }
780     else    {
781         j = 9999;
782     }
783     if ((j >= 0) || ((req->prio & ICO_UXF_PRIO_REGULATION) == 0))   {
784         /* lower priority, waitting this application.           */
785         /* insert application to zone application list and      */
786         /* change zone priority, if request application is top priority */
787         req->state |= ICO_APC_REQSTATE_WAITREQ;
788         if (j >= 0) {
789             /* lower priority       */
790             apfw_trace("app_getdisplay: priority low, waitting %s", conf->appid);
791             ico_uxf_window_control(conf->appid, req->id, ICO_UXF_APPSCTL_INVISIBLE, 1);
792             if (displaycontrol) {
793                 (*displaycontrol)(conf, 0);
794             }
795         }
796         if ((req->prio & ICO_UXF_PRIO_REGULATION) == 0) {
797             /* regulation control   */
798             apfw_trace("app_getdisplay: regulation, waitting %s", conf->appid);
799             ico_uxf_window_control(conf->appid, req->id, ICO_UXF_APPSCTL_REGULATION, 1);
800             if ((j < 0) && (displaycontrol)) {
801                 (*displaycontrol)(conf, 0);
802             }
803         }
804         if (req->reqtype == ICO_APC_REQTYPE_REQUEST)    {
805             if (ico_apf_resource_send_to_client(
806                     conf->appid, ICO_APF_RESOURCE_STATE_WAITTING,
807                     req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE)   {
808                 apfw_warn("app_getdisplay: Leave(send(%s) Error)", conf->appid);
809             }
810             else    {
811                 req->state &= ~ICO_APC_REQSTATE_REPLYACTIVE;
812                 req->state |= ICO_APC_REQSTATE_REPLYQUIET;
813                 req->timer = ICO_APC_REQREPLY_MAXTIME;
814                 timer_count ++;
815             }
816         }
817     }
818     else    {
819         /* maximum priority, ok             */
820         apfw_trace("app_getdisplay: priority heigh");
821         if (req->reqtype == ICO_APC_REQTYPE_REQUEST)    {
822             if (ico_apf_resource_send_to_client(
823                         conf->appid, ICO_APF_RESOURCE_STATE_ACQUIRED,
824                         req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE) {
825                 apfw_warn("app_getdisplay: Leave(send(%s) Error)", conf->appid);
826                 ico_uxf_window_control(conf->appid, req->id, ICO_UXF_APPSCTL_INVISIBLE, 0);
827                 if (displaycontrol) {
828                     (*displaycontrol)(conf, 1);
829                 }
830             }
831             else    {
832                 req->state &= ~ICO_APC_REQSTATE_REPLYQUIET;
833                 req->state |= ICO_APC_REQSTATE_REPLYACTIVE;
834                 req->timer = ICO_APC_REQREPLY_MAXTIME;
835                 timer_count ++;
836             }
837         }
838         else    {
839             ico_uxf_window_control(conf->appid, req->id, ICO_UXF_APPSCTL_INVISIBLE, 0);
840             if (displaycontrol) {
841                 (*displaycontrol)(conf, 1);
842             }
843         }
844         /* send change event to invisible application   */
845         apfw_trace("app_getdisplay: next=%08x %s next_state=%x",
846                    req->next, req->next ? req->next->appid : " ",
847                    req->next ? req->next->state : 0x9999);
848         if ((req->next) && ((req->next->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
849             p = req->next;
850         }
851         else    {
852             p = NULL;
853         }
854         /* send all waitting applications   */
855         i = 0;
856         while (1)   {
857             if (p != NULL)  {
858                 if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0)   {
859                     p->state |= ICO_APC_REQSTATE_WAITREQ;
860                     apfw_trace("app_getdisplay: overlaped(%s), waitting", p->appid);
861                     if (p->reqtype == ICO_APC_REQTYPE_REQUEST)  {
862                         if (ico_apf_resource_send_to_client(
863                                 p->appid, ICO_APF_RESOURCE_STATE_DEPRIVED,
864                                 p->resid, p->device, p->id) != ICO_APF_RESOURCE_E_NONE) {
865                             apfw_warn("app_getdisplay: send(%s) Error)", p->appid);
866                         }
867                         else    {
868                             req->state &= ~ICO_APC_REQSTATE_REPLYACTIVE;
869                             p->state |= ICO_APC_REQSTATE_REPLYQUIET;
870                             p->timer = ICO_APC_REQREPLY_MAXTIME;
871                             timer_count ++;
872                         }
873                     }
874                     ico_uxf_window_control(p->appid, -1, ICO_UXF_APPSCTL_INVISIBLE, 1);
875                     if (displaycontrol) {
876                         (*displaycontrol)(get_appconf(p->appid), 0);
877                     }
878                 }
879             }
880             if (i >= czone->noverlap)   break;
881             p = czone->overlap[i]->req;
882             i ++;
883         }
884     }
885     apfw_trace("app_getdisplay: Leave");
886 }
887
888 /*--------------------------------------------------------------------------*/
889 /**
890  * @brief   app_freedisplay: free display zone resource(static function)
891  *
892  * @param[in]   req             request block
893  * @param[in]   send            send release event to client(1=send/0=no send)
894  * @return      none
895  */
896 /*--------------------------------------------------------------------------*/
897 static void
898 app_freedisplay(ico_apc_request_t *req, const int send)
899 {
900     int     idx;
901     Ico_Uxf_conf_application    *conf = get_appconf(req->appid);
902     ico_apc_dispzone_t          *czone;
903     ico_apc_request_t           *p;
904     ico_apc_request_t           *bp;
905
906     apfw_trace("app_freedisplay: Entry(app=%s)", req->appid);
907
908     czone = &dispzone[req->zoneidx];
909     idx = czone->conf->display->id;
910
911     ico_uxf_window_control(conf->appid, req->id, ICO_UXF_APPSCTL_INVISIBLE, 0);
912     if (displaycontrol) {
913         (*displaycontrol)(conf, 0);
914     }
915     if ((send !=0) && (req->reqtype == ICO_APC_REQTYPE_REQUEST))   {
916         (void) ico_apf_resource_send_to_client(
917                                 req->appid, ICO_APF_RESOURCE_STATE_RELEASED,
918                                 req->resid, req->device, req->id);
919     }
920
921     /* find request                     */
922     p = czone->req;
923     bp = NULL;
924     while (p)   {
925         if (p == req)   break;
926         bp = p;
927         p = p->next;
928     }
929     if (! p)    {
930         apfw_warn("app_freedisplay: Leave(request dose not exist)");
931         return;
932     }
933
934     /* release request table from zone table    */
935     if (bp) {
936         bp->next = p->next;
937
938         /* request is waitted, no need other control*/
939         p->next = free_request;
940         free_request = p;
941         apfw_trace("app_freedisplay: Leave(request waited)");
942         return;
943     }
944     czone->req = p->next;
945     p->next = free_request;
946     free_request = p;
947
948     /* recalculate visible zone         */
949     recalc_dispzone(idx);
950
951     apfw_trace("app_freedisplay: Leave");
952 }
953
954 /*--------------------------------------------------------------------------*/
955 /**
956  * @brief   change_disprequest: change display zone resource(static function)
957  *
958  * @param[in]   req             request block
959  * @param[in]   active          active(1) or inactive(0)
960  * @return      none
961  */
962 /*--------------------------------------------------------------------------*/
963 static void
964 change_disprequest(ico_apc_request_t *req, const int active)
965 {
966     apfw_trace("change_disprequest: change to %s(%s)", active ? "active" : "inactive",
967                req->appid);
968
969     req->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
970
971     if (req->reqtype == ICO_APC_REQTYPE_REQUEST)   {
972         if (ico_apf_resource_send_to_client(
973                         req->appid,
974                         active ? ICO_APF_RESOURCE_STATE_ACQUIRED :
975                                  ICO_APF_RESOURCE_STATE_DEPRIVED,
976                         req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE) {
977             apfw_warn("change_disprequest: send(%s) Error", req->appid);
978         }
979         else    {
980             req->state |= (active ? ICO_APC_REQSTATE_REPLYACTIVE :
981                                     ICO_APC_REQSTATE_REPLYQUIET);
982             req->timer = ICO_APC_REQREPLY_MAXTIME;
983             timer_count ++;
984         }
985     }
986     if ((req->state & ICO_APC_REQSTATE_REPLYACTIVE) == 0)   {
987         ico_uxf_window_control(req->appid, req->id, ICO_UXF_APPSCTL_INVISIBLE,
988                                active ? 0 : 1);
989         if (displaycontrol) {
990             (*displaycontrol)(get_appconf(req->appid), active);
991         }
992     }
993     if (active)   {
994         req->state &= ~ICO_APC_REQSTATE_WAITREQ;
995     }
996     else    {
997         req->state |= ICO_APC_REQSTATE_WAITREQ;
998     }
999 }
1000
1001 /*--------------------------------------------------------------------------*/
1002 /**
1003  * @brief   recalc_dispzone: calculate all display zone request priority(static function)
1004  *
1005  * @param[in]   idx         display index number
1006  * @return      none
1007  */
1008 /*--------------------------------------------------------------------------*/
1009 static void
1010 recalc_dispzone(const int idx)
1011 {
1012     int     i;
1013     int     prio;
1014     ico_apc_dispzone_t  *czone;
1015     ico_apc_dispzone_t  *czone2;
1016     ico_apc_request_t   *p;
1017     Ico_Uxf_conf_display *disp = &confsys->display[idx];
1018
1019     apfw_trace("recalc_dispzone: Enter(disp=%s)", disp->name);
1020
1021     /* get top of priority of this display  */
1022     prio = -1;
1023     czone2 = NULL;
1024     for (i = 0; i < disp->zoneNum; i++)    {
1025         czone = &dispzone[disp->zone[i].zoneidx];
1026         p = czone->req;
1027         if (! p)    continue;
1028         p->state |= ICO_APC_REQSTATE_WAITPROC;
1029         if (p->prio > prio)    {
1030             czone2 = czone;
1031             prio = p->prio;
1032         }
1033     }
1034     if (czone2 == NULL) {
1035         /* no visible zone, end         */
1036         apfw_trace("recalc_dispzone: Leave(no request)");
1037         return;
1038     }
1039     if ((czone2->req->state & ICO_APC_REQSTATE_WAITREQ) == 0)   {
1040         /* not unvisible zone           */
1041         for (i = 0; i < disp->zoneNum; i++)    {
1042             czone = &dispzone[disp->zone[i].zoneidx];
1043             p = czone->req;
1044             if (! p)    continue;
1045             p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1046         }
1047         apfw_trace("recalc_dispzone: Leave(%s no need visible control)",
1048                    czone2->req->appid);
1049         return;
1050     }
1051
1052     /* change to show for top priority  */
1053     p = czone2->req;
1054     p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1055     change_disprequest(p, 1);
1056
1057     /* hide overlap zone                */
1058     for (i = 0; i < czone2->noverlap; i++)  {
1059         p = czone2->overlap[i]->req;
1060         if (p)    {
1061             if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
1062                 p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1063                 change_disprequest(p, 0);
1064             }
1065         }
1066     }
1067
1068     /* show not overlap zone            */
1069     for (i = 0; i < disp->zoneNum; i++)    {
1070         czone = &dispzone[disp->zone[i].zoneidx];
1071         p = czone->req;
1072         if ((p == NULL) || ((p->state & ICO_APC_REQSTATE_WAITPROC) == 0))   continue;
1073         p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1074         change_disprequest(p, 1);
1075     }
1076     apfw_trace("recalc_dispzone: Leave");
1077 }
1078
1079 /*--------------------------------------------------------------------------*/
1080 /**
1081  * @brief   app_getsound: get sound zone resource(static function)
1082  *
1083  * @param[in]   req             request block
1084  * @param[in]   addprio         a priority to add to the priority of the request
1085  * @return      none
1086  */
1087 /*--------------------------------------------------------------------------*/
1088 static void
1089 app_getsound(ico_apc_request_t *req, const int addprio)
1090 {
1091     int     prio;
1092     int     i, j;
1093     Ico_Uxf_conf_application    *conf = get_appconf(req->appid);
1094     Ico_Uxf_conf_sound_zone     *zone;
1095     ico_apc_soundzone_t         *czone;
1096     ico_apc_request_t           *p;
1097     ico_apc_request_t           *bp;
1098
1099     /* priority     */
1100     prio = getpriority(PRIO_PROCESS, req->pid);
1101     if (prio > 19)          prio = 19;
1102     else if (prio < -20)    prio = -20;
1103     prio = (confsys->category[conf->categoryId].priority * ICO_UXF_PRIO_CATEGORY) + 19 - prio;
1104     prio += addprio;
1105     if (ico_syc_apc_regulation_app_sound(conf->categoryId)) {
1106         prio |= ICO_UXF_PRIO_REGULATION;
1107     }
1108     if (ico_uxf_process_is_active(conf->appid)) {
1109         for (i = 0; i < nsoundzone; i++) {
1110             p = soundzone[i].req;
1111             while (p)   {
1112                 if (p->prio & ICO_UXF_PRIO_ACTIVEAPP)  {
1113                     p->prio -= ICO_UXF_PRIO_ACTIVECOUNT;
1114                 }
1115                 p = p->next;
1116             }
1117         }
1118         prio |= ICO_UXF_PRIO_ACTIVEAPP;
1119     }
1120
1121     /* get sound zone from device name      */
1122     for (i = 0; i < nsoundzone; i++) {
1123         if (strcasecmp(soundzone[i].conf->name, req->device) == 0)  break;
1124     }
1125     if (i >= nsoundzone) {
1126         i = confsys->misc.default_soundzoneId;
1127         apfw_trace("app_getsound: Entry(app=%s zone=%s(%s none) prio=%x(+%x) pid=%d)",
1128                    conf->appid, soundzone[i].conf->name, req->device, prio, addprio,
1129                    req->pid);
1130     }
1131     else    {
1132         apfw_trace("app_getsound: Entry(app=%s zone=%s prio=%x(+%x) pid=%d)",
1133                    conf->appid, soundzone[i].conf->name, prio, addprio, req->pid);
1134     }
1135     req->zoneidx = i;
1136
1137     czone = &soundzone[i];
1138     zone = czone->conf;
1139
1140     /* search same request          */
1141     p = czone->req;
1142     bp = NULL;
1143     while (p)   {
1144         if ((strcmp(p->appid, req->appid) == 0) && (p->resid == req->resid) &&
1145             (p->zoneidx == req->zoneidx))   {
1146             break;
1147         }
1148         bp = p;
1149         p = p->next;
1150     }
1151     if (p)  {
1152         if (p->reqtype != ICO_APC_REQTYPE_REQUEST)  {
1153             apfw_trace("app_getsound: Leave(found same request)");
1154             return;
1155         }
1156
1157         if (p->prio > prio) {
1158             prio = p->prio;
1159         }
1160         apfw_trace("app_getsound: found same request(app=%s zone=%s res=%d prio=%d)",
1161                    conf->appid, soundzone[i].conf->name, req->resid, prio);
1162         if (bp) {
1163             bp->next = p->next;
1164         }
1165         else    {
1166             czone->req = p->next;
1167         }
1168         p->next = free_request;
1169         free_request = p;
1170     }
1171
1172     /* link request to zone table   */
1173     req->prio = prio;
1174     p = czone->req;
1175     bp = NULL;
1176     while (p)   {
1177         if (p->prio <= prio)    break;
1178         bp = p;
1179         p = p->next;
1180     }
1181     if (bp) {
1182         req->next = bp->next;
1183         bp->next = req;
1184     }
1185     else    {
1186         req->next = czone->req;
1187         czone->req = req;
1188     }
1189
1190     /* check if maximum priority    */
1191     if (! bp)   {
1192         j = -1;
1193         for (i =0; i < czone->noverlap; i++)    {
1194             if (((czone->overlap[i])->req != NULL) &&
1195                 ((czone->overlap[i])->req->prio > prio))    {
1196                 j = i;
1197                 prio = czone->overlap[i]->req->prio;
1198             }
1199         }
1200     }
1201     else    {
1202         j = 9999;
1203     }
1204     if ((j >= 0) || ((req->prio & ICO_UXF_PRIO_REGULATION) == 0))   {
1205         /* lower priority, waitting this application.           */
1206         /* insert application to zone application list and      */
1207         /* change zone priority, if request application is top priority */
1208         req->state |= ICO_APC_REQSTATE_WAITREQ;
1209         if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEON, req->pid)
1210                 != ICO_APF_RESOURCE_E_NONE) {
1211             apfw_warn("app_getsound: send MSM Error");
1212         }
1213         if (soundcontrol) {
1214             (*soundcontrol)(conf, 0);
1215         }
1216         apfw_trace("app_getsound: priority low, waitting %s", conf->appid);
1217         if (req->reqtype == ICO_APC_REQTYPE_REQUEST)    {
1218             if (ico_apf_resource_send_to_client(
1219                     conf->appid, ICO_APF_RESOURCE_STATE_WAITTING,
1220                     req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE)   {
1221                 apfw_warn("app_getsound: Leave(send(%s) Error)", conf->appid);
1222             }
1223             else    {
1224                 req->state |= ICO_APC_REQSTATE_REPLYQUIET;
1225                 req->timer = ICO_APC_REQREPLY_MAXTIME;
1226                 timer_count ++;
1227             }
1228         }
1229     }
1230     else    {
1231         /* maximum priority, ok             */
1232         apfw_trace("app_getsound: priority heigh(%08x)", req->prio);
1233         if (req->reqtype == ICO_APC_REQTYPE_REQUEST)    {
1234             if (ico_apf_resource_send_to_client(
1235                         conf->appid, ICO_APF_RESOURCE_STATE_ACQUIRED,
1236                         req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE) {
1237                 apfw_warn("app_getsound: Leave(send(%s) Error)", conf->appid);
1238             }
1239         }
1240         /* send change event to mute application    */
1241         apfw_trace("app_getsound: next=%08x %s next_state=%x",
1242                    req->next, req->next ? req->next->appid : " ",
1243                    req->next ? req->next->state : 0x9999);
1244         if ((req->next) && ((req->next->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
1245             p = req->next;
1246         }
1247         else    {
1248             p = NULL;
1249         }
1250         /* send all waitting applications   */
1251         i = 0;
1252         while (1)   {
1253             if (p != NULL)  {
1254                 if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0)   {
1255                     p->state |= ICO_APC_REQSTATE_WAITREQ;
1256                     apfw_trace("app_getsound: overlaped(%s), waitting", p->appid);
1257                     if (p->reqtype == ICO_APC_REQTYPE_REQUEST)  {
1258                         if (ico_apf_resource_send_to_client(
1259                                 p->appid, ICO_APF_RESOURCE_STATE_DEPRIVED,
1260                                 p->resid, p->device, p->id) != ICO_APF_RESOURCE_E_NONE) {
1261                             apfw_warn("app_getsound: send(%s) Error)", p->appid);
1262                         }
1263                         else    {
1264                             p->state |= ICO_APC_REQSTATE_REPLYQUIET;
1265                             p->timer = ICO_APC_REQREPLY_MAXTIME;
1266                             timer_count ++;
1267                         }
1268                     }
1269                 }
1270                 if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEON, p->pid)
1271                         != ICO_APF_RESOURCE_E_NONE) {
1272                     apfw_warn("app_getsound: send MSM Error");
1273                 }
1274                 if (soundcontrol) {
1275                     (*soundcontrol)(get_appconf(p->appid), 0);
1276                 }
1277             }
1278             if (i >= czone->noverlap)   break;
1279             p = czone->overlap[i]->req;
1280             i ++;
1281         }
1282     }
1283     apfw_trace("app_getsound: Leave(req=%08x,state=%x,prio=%08x)",
1284                (int)req, req->state, req->prio);
1285 }
1286
1287 /*--------------------------------------------------------------------------*/
1288 /**
1289  * @brief   app_freesound: free sound zone resource(static function)
1290  *
1291  * @param[in]   req             request block
1292  * @param[in]   send            send release event to client(1=send/0=no send)
1293  * @return      none
1294  */
1295 /*--------------------------------------------------------------------------*/
1296 static void
1297 app_freesound(ico_apc_request_t *req, const int send)
1298 {
1299     int     idx;
1300     Ico_Uxf_conf_application    *conf = get_appconf(req->appid);
1301     ico_apc_soundzone_t         *czone;
1302     ico_apc_request_t           *p;
1303     ico_apc_request_t           *bp;
1304
1305     apfw_trace("app_freesound: Entry(app=%s)", req->appid);
1306
1307     czone = &soundzone[req->zoneidx];
1308     idx = czone->conf->sound->id;
1309
1310     if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEON, req->pid)
1311                 != ICO_APF_RESOURCE_E_NONE) {
1312         apfw_warn("app_freesound: send MSM Error");
1313     }
1314     if (soundcontrol) {
1315         (*soundcontrol)(conf, 0);
1316     }
1317     if ((send !=0) && (req->reqtype == ICO_APC_REQTYPE_REQUEST))   {
1318         (void) ico_apf_resource_send_to_client(
1319                                 req->appid, ICO_APF_RESOURCE_STATE_RELEASED,
1320                                 req->resid, req->device, req->id);
1321     }
1322
1323     /* find request                     */
1324     p = czone->req;
1325     bp = NULL;
1326     while (p)   {
1327         if (p == req)   break;
1328         bp = p;
1329         p = p->next;
1330     }
1331     if (! p)    {
1332         apfw_warn("app_freesound: Leave(request dose not exist)");
1333         return;
1334     }
1335
1336     /* release request table from zone table    */
1337     if (bp) {
1338         bp->next = p->next;
1339
1340         /* request is waitted, no need other control*/
1341         p->next = free_request;
1342         free_request = p;
1343         apfw_trace("app_freesound: Leave(request waited)");
1344         return;
1345     }
1346     czone->req = p->next;
1347     p->next = free_request;
1348     free_request = p;
1349
1350     /* recalculate visible zone         */
1351     recalc_soundzone(idx);
1352
1353     apfw_trace("app_freesound: Leave");
1354 }
1355
1356 /*--------------------------------------------------------------------------*/
1357 /**
1358  * @brief   change_soundrequest: change sound zone resource(static function)
1359  *
1360  * @param[in]   req             request block
1361  * @param[in]   active          active(1) or quiet(0)
1362  * @return      none
1363  */
1364 /*--------------------------------------------------------------------------*/
1365 static void
1366 change_soundrequest(ico_apc_request_t *req, const int active)
1367 {
1368     apfw_trace("change_soundrequest: change to %s(%s)", active ? "active" : "quiet",
1369                req->appid);
1370
1371     req->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
1372
1373     if (req->reqtype == ICO_APC_REQTYPE_REQUEST)   {
1374         if (ico_apf_resource_send_to_client(
1375                         req->appid,
1376                         active ? ICO_APF_RESOURCE_STATE_ACQUIRED :
1377                                  ICO_APF_RESOURCE_STATE_DEPRIVED,
1378                         req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE) {
1379             apfw_warn("change_soundrequest: send(%s) Error", req->appid);
1380         }
1381         else    {
1382             req->state |= (active ? ICO_APC_REQSTATE_REPLYACTIVE :
1383                                     ICO_APC_REQSTATE_REPLYQUIET);
1384             req->timer = ICO_APC_REQREPLY_MAXTIME;
1385             timer_count ++;
1386         }
1387     }
1388     if ((req->state & ICO_APC_REQSTATE_REPLYACTIVE) == 0)   {
1389         if (ico_apf_resource_send_to_soundctl(
1390                     active ? ICO_APF_SOUND_COMMAND_MUTEOFF : ICO_APF_SOUND_COMMAND_MUTEON,
1391                     req->pid) != ICO_APF_RESOURCE_E_NONE)   {
1392             apfw_warn("change_soundrequest: send MSM Error");
1393         }
1394         if (soundcontrol) {
1395             (*soundcontrol)(get_appconf(req->appid), active);
1396         }
1397     }
1398     if (active)   {
1399         req->state &= ~ICO_APC_REQSTATE_WAITREQ;
1400     }
1401     else    {
1402         req->state |= ICO_APC_REQSTATE_WAITREQ;
1403     }
1404 }
1405
1406 /*--------------------------------------------------------------------------*/
1407 /**
1408  * @brief   recalc_soundzone: calculate all sound zone request priority(static function)
1409  *
1410  * @param[in]   idx         sound index number
1411  * @return      none
1412  */
1413 /*--------------------------------------------------------------------------*/
1414 static void
1415 recalc_soundzone(const int idx)
1416 {
1417     int     i;
1418     int     prio;
1419     ico_apc_soundzone_t *czone;
1420     ico_apc_soundzone_t *czone2;
1421     ico_apc_request_t   *p;
1422     Ico_Uxf_conf_sound  *sound = &confsys->sound[idx];
1423
1424     apfw_trace("recalc_soundzone: Enter(sound=%s)", sound->name);
1425
1426     /* get top of priority of this sound  */
1427     prio = -1;
1428     czone2 = NULL;
1429     for (i = 0; i < sound->zoneNum; i++)    {
1430         czone = &soundzone[sound->zone[i].zoneidx];
1431         p = czone->req;
1432         if (! p)    continue;
1433         p->state |= ICO_APC_REQSTATE_WAITPROC;
1434         if (p->prio > prio)    {
1435             czone2 = czone;
1436             prio = p->prio;
1437         }
1438     }
1439     if (czone2 == NULL) {
1440         /* no active zone, end          */
1441         apfw_trace("recalc_soundzone: Leave(no request)");
1442         return;
1443     }
1444     if ((czone2->req->state & ICO_APC_REQSTATE_WAITREQ) == 0)   {
1445         /* not quiet zone               */
1446         for (i = 0; i < sound->zoneNum; i++)    {
1447             czone = &soundzone[sound->zone[i].zoneidx];
1448             p = czone->req;
1449             if (! p)    continue;
1450             p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1451         }
1452         apfw_trace("recalc_soundzone: Leave(%s no need sound control)",
1453                    czone2->req->appid);
1454         return;
1455     }
1456
1457     /* change to active for top priority*/
1458     p = czone2->req;
1459     p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1460     if (p->prio & ICO_UXF_PRIO_REGULATION)  {
1461         apfw_trace("recalc_soundzone: Start %s(prio=%08x and no regulation)",
1462                    p->appid, p->prio);
1463         change_soundrequest(p, 1);
1464     }
1465
1466     /* mute overlap zone                */
1467     for (i = 0; i < czone2->noverlap; i++)  {
1468         p = czone2->overlap[i]->req;
1469         if (p)    {
1470             if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
1471                 p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1472                 if (p->prio & ICO_UXF_PRIO_REGULATION)  {
1473                     apfw_trace("recalc_soundzone: Overlap Stop %s(top and no regulation)",
1474                                p->appid);
1475                     change_soundrequest(p, 0);
1476                 }
1477                 else    {
1478                     p->state |= ICO_APC_REQSTATE_WAITREQ;
1479                 }
1480             }
1481         }
1482     }
1483
1484     /* reset mute not overlap zone      */
1485     for (i = 0; i < sound->zoneNum; i++)    {
1486         czone = &soundzone[sound->zone[i].zoneidx];
1487         p = czone->req;
1488         if ((p == NULL) || ((p->state & ICO_APC_REQSTATE_WAITPROC) == 0))   continue;
1489         p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1490         if (p->state & ICO_APC_REQSTATE_WAITREQ)    {
1491             if (p->prio & ICO_UXF_PRIO_REGULATION)  {
1492                 apfw_trace("recalc_soundzone: Overlap Start %s(top and no regulation)",
1493                            p->appid);
1494                 change_soundrequest(p, 1);
1495             }
1496         }
1497     }
1498     apfw_trace("recalc_soundzone: Leave");
1499 }
1500
1501 /*--------------------------------------------------------------------------*/
1502 /**
1503  * @brief   app_getinput: get input switch resource(static function)
1504  *
1505  * @param[in]   req             request block
1506  * @param[in]   addprio         a priority to add to the priority of the request
1507  * @return      none
1508  */
1509 /*--------------------------------------------------------------------------*/
1510 static void
1511 app_getinput(ico_apc_request_t *req, const int addprio)
1512 {
1513     int     prio;
1514     int     i;
1515     Ico_Uxf_conf_application    *conf = get_appconf(req->appid);
1516     ico_apc_inputsw_t           *czone;
1517     ico_apc_request_t           *p;
1518     ico_apc_request_t           *bp;
1519
1520     /* priority     */
1521     prio = getpriority(PRIO_PROCESS, req->pid);
1522     if (prio > 19)          prio = 19;
1523     else if (prio < -20)    prio = -20;
1524     prio = (confsys->category[conf->categoryId].priority * ICO_UXF_PRIO_CATEGORY) + 19 - prio;
1525     prio += addprio;
1526     if (ico_syc_apc_regulation_app_input(conf->categoryId)) {
1527         prio |= ICO_UXF_PRIO_REGULATION;
1528     }
1529     if (ico_uxf_process_is_active(conf->appid)) {
1530         for (i = 0; i < ninputsw; i++) {
1531             p = inputsw[i].req;
1532             while (p)   {
1533                 if (p->prio & ICO_UXF_PRIO_ACTIVEAPP)  {
1534                     p->prio -= ICO_UXF_PRIO_ACTIVECOUNT;
1535                 }
1536                 p = p->next;
1537             }
1538         }
1539         prio |= ICO_UXF_PRIO_ACTIVEAPP;
1540     }
1541
1542     /* get input switch from device name    */
1543     for (i = 0; i < ninputsw; i++) {
1544         if (strcasecmp(inputsw[i].inputsw->swname, req->device) == 0)  break;
1545     }
1546     if (i >= ninputsw) {
1547         i = confsys->misc.default_inputswId;
1548         apfw_trace("app_getinput: Entry(app=%s inputsw=%s(%s none) prio=%x(+%x) pid=%d)",
1549                    conf->appid, inputsw[i].inputsw->swname, req->device, prio, addprio,
1550                    req->pid);
1551     }
1552     else    {
1553         apfw_trace("app_getinput: Entry(app=%s zone=%s prio=%x(+%x) pid=%d)",
1554                    conf->appid, inputsw[i].inputsw->swname, prio, addprio, req->pid);
1555     }
1556     req->zoneidx = i;
1557
1558     czone = &inputsw[i];
1559
1560     /* search same request          */
1561     p = czone->req;
1562     bp = NULL;
1563     while (p)   {
1564         if ((strcmp(p->appid, req->appid) == 0) && (p->resid == req->resid) &&
1565             (p->zoneidx == req->zoneidx))   {
1566             break;
1567         }
1568         bp = p;
1569         p = p->next;
1570     }
1571     if (p)  {
1572         if (p->reqtype != ICO_APC_REQTYPE_REQUEST)  {
1573             apfw_trace("app_getinput: Leave(found same request)");
1574             return;
1575         }
1576
1577         if (p->prio > prio) {
1578             prio = p->prio;
1579         }
1580         apfw_trace("app_getinput: found same request(app=%s sw=%s res=%d prio=%d)",
1581                    conf->appid, inputsw[i].inputsw->swname, req->resid, prio);
1582         if (bp) {
1583             bp->next = p->next;
1584         }
1585         else    {
1586             czone->req = p->next;
1587         }
1588         p->next = free_request;
1589         free_request = p;
1590     }
1591
1592     /* link request to zone table   */
1593     req->prio = prio;
1594     p = czone->req;
1595     bp = NULL;
1596     while (p)   {
1597         if (p->prio <= prio)    break;
1598         bp = p;
1599         p = p->next;
1600     }
1601     if (bp) {
1602         req->next = bp->next;
1603         bp->next = req;
1604     }
1605     else    {
1606         req->next = czone->req;
1607         czone->req = req;
1608     }
1609
1610     if ((req->prio & ICO_UXF_PRIO_REGULATION) == 0) {
1611         /* lower priority, waitting this application.           */
1612         /* insert application to zone application list and      */
1613         /* change zone priority, if request application is top priority */
1614         req->state |= ICO_APC_REQSTATE_WAITREQ;
1615         if (ico_uxf_input_control(0, req->appid, czone->inputdev->device,
1616                                   czone->inputsw->input) != ICO_UXF_EOK)    {
1617             apfw_warn("app_getinput: send MIM Error");
1618         }
1619         if (inputcontrol) {
1620             (*inputcontrol)(conf, 0);
1621         }
1622         apfw_trace("app_getinput: priority low, waitting %s", conf->appid);
1623         if (req->reqtype == ICO_APC_REQTYPE_REQUEST)    {
1624             if (ico_apf_resource_send_to_client(
1625                     conf->appid, ICO_APF_RESOURCE_STATE_WAITTING,
1626                     req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE)   {
1627                 apfw_warn("app_getinput: Leave(send(%s) Error)", conf->appid);
1628             }
1629             else    {
1630                 req->state |= ICO_APC_REQSTATE_REPLYQUIET;
1631                 req->timer = ICO_APC_REQREPLY_MAXTIME;
1632                 timer_count ++;
1633             }
1634         }
1635     }
1636     else    {
1637         /* maximum priority, ok             */
1638         apfw_trace("app_getinput: priority heigh(%08x)", req->prio);
1639         if (req->reqtype == ICO_APC_REQTYPE_REQUEST)    {
1640             if (ico_apf_resource_send_to_client(
1641                         conf->appid, ICO_APF_RESOURCE_STATE_ACQUIRED,
1642                         req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE) {
1643                 apfw_warn("app_getinput: Leave(send(%s) Error)", conf->appid);
1644             }
1645             else    {
1646                 req->state |= ICO_APC_REQSTATE_REPLYACTIVE;
1647                 req->timer = ICO_APC_REQREPLY_MAXTIME;
1648                 timer_count ++;
1649             }
1650         }
1651         if (ico_uxf_input_control(1, req->appid, czone->inputdev->device,
1652                                   czone->inputsw->input) != ICO_UXF_EOK)    {
1653             apfw_warn("app_getinput: send MIM Error");
1654         }
1655         /* change lower priority stateus            */
1656         if ((req->next) && ((req->next->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
1657             p = req->next;
1658             p->state |= ICO_APC_REQSTATE_WAITREQ;
1659             apfw_trace("app_getinput: lower priority(%s), waitting", p->appid);
1660             if (p->reqtype == ICO_APC_REQTYPE_REQUEST)  {
1661                 if (ico_apf_resource_send_to_client(
1662                             p->appid, ICO_APF_RESOURCE_STATE_DEPRIVED,
1663                             p->resid, p->device, p->id) != ICO_APF_RESOURCE_E_NONE) {
1664                     apfw_warn("app_getinput: send(%s) Error)", p->appid);
1665                 }
1666                 else    {
1667                     p->state |= ICO_APC_REQSTATE_REPLYQUIET;
1668                     p->timer = ICO_APC_REQREPLY_MAXTIME;
1669                     timer_count ++;
1670                 }
1671             }
1672         }
1673     }
1674     apfw_trace("app_getinput: Leave(req=%08x,state=%x,prio=%08x)",
1675                (int)req, req->state, req->prio);
1676 }
1677
1678 /*--------------------------------------------------------------------------*/
1679 /**
1680  * @brief   app_freeinput: free input switch resource(static function)
1681  *
1682  * @param[in]   req             request block
1683  * @param[in]   send            send release event to client(1=send/0=no send)
1684  * @return      none
1685  */
1686 /*--------------------------------------------------------------------------*/
1687 static void
1688 app_freeinput(ico_apc_request_t *req, const int send)
1689 {
1690     Ico_Uxf_conf_application    *conf = get_appconf(req->appid);
1691     ico_apc_inputsw_t           *czone;
1692     ico_apc_request_t           *p;
1693     ico_apc_request_t           *bp;
1694
1695     apfw_trace("app_freeinput: Entry(app=%s)", req->appid);
1696
1697     czone = &inputsw[req->zoneidx];
1698
1699     if (ico_uxf_input_control(0, conf->appid, czone->inputdev->device,
1700                               czone->inputsw->input) != ICO_UXF_EOK)    {
1701         apfw_warn("app_freeinput: send MIM Error");
1702     }
1703     if (inputcontrol) {
1704         (*inputcontrol)(conf, 0);
1705     }
1706     if ((send !=0) && (req->reqtype == ICO_APC_REQTYPE_REQUEST))   {
1707         (void) ico_apf_resource_send_to_client(
1708                                 req->appid, ICO_APF_RESOURCE_STATE_RELEASED,
1709                                 req->resid, req->device, req->id);
1710     }
1711
1712     /* find request                     */
1713     p = czone->req;
1714     bp = NULL;
1715     while (p)   {
1716         if (p == req)   break;
1717         bp = p;
1718         p = p->next;
1719     }
1720     if (! p)    {
1721         apfw_warn("app_freeinput: Leave(request dose not exist)");
1722         return;
1723     }
1724
1725     /* release request table from zone table    */
1726     if (bp) {
1727         bp->next = p->next;
1728
1729         /* request is waitted, no need other control*/
1730         p->next = free_request;
1731         free_request = p;
1732         apfw_trace("app_freeinput: Leave(request waited)");
1733         return;
1734     }
1735     czone->req = p->next;
1736     p->next = free_request;
1737     free_request = p;
1738
1739     /* recalculate visible zone         */
1740     recalc_inputsw(czone->inputsw->input);
1741
1742     apfw_trace("app_freeinput: Leave");
1743 }
1744
1745 /*--------------------------------------------------------------------------*/
1746 /**
1747  * @brief   change_inputrequest: change input switch resource(static function)
1748  *
1749  * @param[in]   req             request block
1750  * @param[in]   active          use(1) or unuse(0)
1751  * @return      none
1752  */
1753 /*--------------------------------------------------------------------------*/
1754 static void
1755 change_inputrequest(ico_apc_request_t *req, const int active)
1756 {
1757     ico_apc_inputsw_t       *czone;
1758
1759     apfw_trace("change_inputrequest: change to %s(%s)", active ? "use" : "unuse",
1760                req->appid);
1761
1762     czone = &inputsw[req->zoneidx];
1763
1764     if (req->reqtype == ICO_APC_REQTYPE_REQUEST)   {
1765         if (ico_apf_resource_send_to_client(
1766                         req->appid,
1767                         active ? ICO_APF_RESOURCE_STATE_ACQUIRED :
1768                                  ICO_APF_RESOURCE_STATE_DEPRIVED,
1769                         req->resid, req->device, req->id) != ICO_APF_RESOURCE_E_NONE) {
1770             apfw_warn("change_inputrequest: send(%s) Error", req->appid);
1771         }
1772         else    {
1773             req->state |= (active ? ICO_APC_REQSTATE_REPLYACTIVE :
1774                                     ICO_APC_REQSTATE_REPLYQUIET);
1775             req->timer = ICO_APC_REQREPLY_MAXTIME;
1776             timer_count ++;
1777         }
1778     }
1779     if (ico_uxf_input_control(active, req->appid, czone->inputdev->device,
1780                               czone->inputsw->input) != ICO_UXF_EOK)    {
1781         apfw_warn("app_getinput: send MIM Error");
1782     }
1783     if (inputcontrol) {
1784         (*inputcontrol)(get_appconf(req->appid), active);
1785     }
1786     if (active)   {
1787         req->state &= ~ICO_APC_REQSTATE_WAITREQ;
1788         req->state |= ICO_APC_REQSTATE_REPLYACTIVE;
1789     }
1790     else    {
1791         req->state |= (ICO_APC_REQSTATE_WAITREQ | ICO_APC_REQSTATE_REPLYQUIET);
1792     }
1793 }
1794
1795 /*--------------------------------------------------------------------------*/
1796 /**
1797  * @brief   recalc_inputsw: calculate all input switch request priority(static function)
1798  *
1799  * @param[in]   idx         input switch index number
1800  * @return      none
1801  */
1802 /*--------------------------------------------------------------------------*/
1803 static void
1804 recalc_inputsw(const int idx)
1805 {
1806     ico_apc_inputsw_t   *czone = &inputsw[idx];
1807     ico_apc_request_t   *p;
1808
1809     apfw_trace("recalc_inputsw: Enter(input=%s)", czone->inputsw->swname);
1810
1811     /* get top of priority of this input    */
1812     p = czone->req;
1813     if (p == NULL) {
1814         /* no active request, end           */
1815         apfw_trace("recalc_inputsw: Leave(no request)");
1816         return;
1817     }
1818     if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0)   {
1819         /* not wait request                 */
1820         apfw_trace("recalc_inputsw: Leave(%s no need input control)", p->appid);
1821         return;
1822     }
1823
1824     /* change to active for top priority*/
1825     p->state &= ~ICO_APC_REQSTATE_WAITPROC;
1826     if (p->prio & ICO_UXF_PRIO_REGULATION)  {
1827         apfw_trace("recalc_inputsw: Start %s(prio=%08x and no regulation)",
1828                    p->appid, p->prio);
1829         change_inputrequest(p, 1);
1830     }
1831
1832     apfw_trace("recalc_inputsw: Leave");
1833 }
1834
1835 /*--------------------------------------------------------------------------*/
1836 /**
1837  * @brief   regulation_listener: change regulation callback(static function)
1838  *
1839  * @param[in]   appcategory     category Id
1840  * @param[in]   control         control(display/sound/input active/inactive)
1841  * @param[in]   user_data       user data(unused)
1842  * @return      none
1843  */
1844 /*--------------------------------------------------------------------------*/
1845 static void
1846 regulation_listener(const int appcategory,
1847                     const ico_apc_reguration_control_t control, void *user_data)
1848 {
1849     int     i, j, k;
1850     int     flag;
1851     int     disp, sound, input;
1852     ico_apc_request_t   *p;
1853     ico_apc_request_t   *bp;
1854     ico_apc_request_t   *p2;
1855     ico_apc_request_t   *bp2;
1856     unsigned short  reqdisp[MAXREQ];
1857     unsigned short  reqsound[MAXREQ];
1858     unsigned short  reqinput[MAXREQ];
1859
1860     disp = 0;
1861     sound = 0;
1862     input = 0;
1863
1864     confapp = (Ico_Uxf_App_Config *)ico_uxf_getAppConfig();
1865
1866     if (control.display != ICO_SYC_APC_REGULATION_NOCHANGE) {
1867         /* display regulation control       */
1868         apfw_trace("regulation_listener: disp category=%d display=%d",
1869                    appcategory, control.display);
1870         for (i = 0; i < confapp->applicationNum; i++)   {
1871             if (confapp->application[i].categoryId != appcategory)  continue;
1872             for (k = 0; k < ndispzone; k++) {
1873                 p = dispzone[k].req;
1874                 if (!p) continue;
1875                 bp = NULL;
1876                 while (p)   {
1877                     if (strcmp(p->appid, confapp->application[i].appid) == 0)    {
1878                         flag = 0;
1879                         if (control.display == ICO_SYC_APC_REGULATION_REGULATION)   {
1880                             if (p->prio & ICO_UXF_PRIO_REGULATION)  {
1881                                 p->prio &= ~ICO_UXF_PRIO_REGULATION;
1882                                 flag ++;
1883                                 ico_uxf_window_control(p->appid, p->id,
1884                                                        ICO_UXF_APPSCTL_REGULATION, 1);
1885                             }
1886                         }
1887                         else    {
1888                             if ((p->prio & ICO_UXF_PRIO_REGULATION) == 0)   {
1889                                 p->prio |= ICO_UXF_PRIO_REGULATION;
1890                                 flag ++;
1891                                 ico_uxf_window_control(p->appid, p->id,
1892                                                        ICO_UXF_APPSCTL_REGULATION, 0);
1893                             }
1894                         }
1895                         if (flag)   {
1896                             for (j = 0; j < disp; j++)  {
1897                                 if (dispzone[k].conf->display->id == reqdisp[j])    break;
1898                             }
1899                             if (j >= disp)  {
1900                                 reqdisp[disp++] = dispzone[k].conf->display->id;
1901                             }
1902                             apfw_trace("regulation_listener: disp %s %08x",
1903                                        p->appid, p->prio);
1904                             if (bp) {
1905                                 bp->next = p->next;
1906                             }
1907                             else    {
1908                                 dispzone[k].req = p->next;
1909                             }
1910                             p2 = dispzone[k].req;
1911                             bp2 = NULL;
1912                             while (p2)  {
1913                                 if (p2->prio < p->prio) {
1914                                     if (bp2)    {
1915                                         bp2->next = p;
1916                                         p->next = p2;
1917                                         if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
1918                                             change_disprequest(p, 0);
1919                                         }
1920                                     }
1921                                     else    {
1922                                         p->next = dispzone[k].req;
1923                                         dispzone[k].req = p;
1924                                         if ((p->next != NULL) &&
1925                                             ((p->next->state & ICO_APC_REQSTATE_WAITREQ)
1926                                                 == 0)) {
1927                                             change_disprequest(p->next, 0);
1928                                         }
1929                                     }
1930                                     break;
1931                                 }
1932                                 bp2 = p2;
1933                                 p2 = p2->next;
1934                             }
1935                             if (! p2)   {
1936                                 if (bp2)    {
1937                                     bp2->next = p;
1938                                     if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
1939                                         change_disprequest(p, 0);
1940                                     }
1941                                 }
1942                                 else    {
1943                                     dispzone[k].req = p;
1944                                 }
1945                                 p->next = NULL;
1946                             }
1947                             break;
1948                         }
1949                     }
1950                     bp = p;
1951                     p = p->next;
1952                 }
1953             }
1954         }
1955     }
1956
1957     if (control.sound != ICO_SYC_APC_REGULATION_NOCHANGE) {
1958         /* sound regulation control         */
1959         apfw_trace("regulation_listener: sound category=%d sound=%d",
1960                    appcategory, control.sound);
1961         for (i = 0; i < confapp->applicationNum; i++)   {
1962             if (confapp->application[i].categoryId != appcategory)  continue;
1963             for (k = 0; k < nsoundzone; k++)    {
1964                 p = soundzone[k].req;
1965                 if (!p) continue;
1966                 bp = NULL;
1967                 while (p)   {
1968                     if (strcmp(p->appid, confapp->application[i].appid) == 0)    {
1969                         flag = 0;
1970                         if (control.sound == ICO_SYC_APC_REGULATION_REGULATION) {
1971                             if (p->prio & ICO_UXF_PRIO_REGULATION)  {
1972                                 p->prio &= ~ICO_UXF_PRIO_REGULATION;
1973                                 flag ++;
1974                                 if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
1975                                     change_soundrequest(p, 0);
1976                                 }
1977                             }
1978                         }
1979                         else    {
1980                             if ((p->prio & ICO_UXF_PRIO_REGULATION) == 0)   {
1981                                 p->prio |= ICO_UXF_PRIO_REGULATION;
1982                                 flag ++;
1983                             }
1984                         }
1985                         if (flag)   {
1986                             apfw_trace("regulation_listener: sound change category=%d "
1987                                        "app(%s) sound=%d prio=%08x",
1988                                        appcategory, p->appid, control.sound, p->prio);
1989                             for (j = 0; j < sound; j++)  {
1990                                 if (soundzone[k].conf->sound->id == reqsound[j])    break;
1991                             }
1992                             if (j >= sound)  {
1993                                 reqsound[sound++] = soundzone[k].conf->sound->id;
1994                             }
1995                             apfw_trace("regulation_listener: sound %s %08x %08x",
1996                                        p->appid, p->prio, (int)bp);
1997                             if (bp) {
1998                                 bp->next = p->next;
1999                             }
2000                             else    {
2001                                 soundzone[k].req = p->next;
2002                             }
2003                             p2 = soundzone[k].req;
2004                             bp2 = NULL;
2005                             while (p2)  {
2006                                 if (p2->prio < p->prio) {
2007                                     if (bp2)    {
2008                                         bp2->next = p;
2009                                         p->next = p2;
2010                                         if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
2011                                             change_soundrequest(p, 0);
2012                                         }
2013                                     }
2014                                     else    {
2015                                         p->next = soundzone[k].req;
2016                                         soundzone[k].req = p;
2017                                         if ((p->next != NULL) &&
2018                                             ((p->next->state & ICO_APC_REQSTATE_WAITREQ)
2019                                                 == 0)) {
2020                                             change_soundrequest(p->next, 0);
2021                                         }
2022                                     }
2023                                     break;
2024                                 }
2025                                 bp2 = p2;
2026                                 p2 = p2->next;
2027                             }
2028                             if (! p2)   {
2029                                 if (bp2)    {
2030                                     bp2->next = p;
2031                                     if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
2032                                         change_soundrequest(p, 0);
2033                                     }
2034                                 }
2035                                 else    {
2036                                     soundzone[k].req = p;
2037                                 }
2038                                 p->next = NULL;
2039                             }
2040                             break;
2041                         }
2042                     }
2043                     bp = p;
2044                     p = p->next;
2045                 }
2046             }
2047         }
2048     }
2049
2050     if (control.input != ICO_SYC_APC_REGULATION_NOCHANGE)   {
2051         /* input reguration control     */
2052         apfw_trace("regulation_listener: input category=%d input=%d",
2053                    appcategory, control.input);
2054         for (i = 0; i < confapp->applicationNum; i++)   {
2055             if (confapp->application[i].categoryId != appcategory)  continue;
2056             for (k = 0; k < ninputsw; k++)    {
2057                 p = inputsw[k].req;
2058                 if (!p) continue;
2059                 bp = NULL;
2060                 while (p)   {
2061                     if (strcmp(p->appid, confapp->application[i].appid) == 0)    {
2062                         flag = 0;
2063                         if (control.input == ICO_SYC_APC_REGULATION_REGULATION) {
2064                             if (p->prio & ICO_UXF_PRIO_REGULATION)  {
2065                                 p->prio &= ~ICO_UXF_PRIO_REGULATION;
2066                                 flag ++;
2067                                 if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
2068                                     change_inputrequest(p, 0);
2069                                 }
2070                             }
2071                         }
2072                         else    {
2073                             if ((p->prio & ICO_UXF_PRIO_REGULATION) == 0)   {
2074                                 p->prio |= ICO_UXF_PRIO_REGULATION;
2075                                 flag ++;
2076                             }
2077                         }
2078                         if (flag)   {
2079                             apfw_trace("regulation_listener: input change category=%d "
2080                                        "app(%s) input=%d prio=%08x",
2081                                        appcategory, p->appid, control.input, p->prio);
2082                             for (j = 0; j < sound; j++)  {
2083                                 if (inputsw[k].inputsw->input == reqinput[j])    break;
2084                             }
2085                             if (j >= input)  {
2086                                 reqinput[input++] = inputsw[k].inputsw->input;
2087                             }
2088                             apfw_trace("regulation_listener: input %s %08x %08x",
2089                                        p->appid, p->prio, (int)bp);
2090                             if (bp) {
2091                                 bp->next = p->next;
2092                             }
2093                             else    {
2094                                 inputsw[k].req = p->next;
2095                             }
2096                             p2 = inputsw[k].req;
2097                             bp2 = NULL;
2098                             while (p2)  {
2099                                 if (p2->prio < p->prio) {
2100                                     if (bp2)    {
2101                                         bp2->next = p;
2102                                         p->next = p2;
2103                                         if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
2104                                             change_inputrequest(p, 0);
2105                                         }
2106                                     }
2107                                     else    {
2108                                         p->next = inputsw[k].req;
2109                                         inputsw[k].req = p;
2110                                     }
2111                                     break;
2112                                 }
2113                                 bp2 = p2;
2114                                 p2 = p2->next;
2115                             }
2116                             if (! p2)   {
2117                                 if (bp2)    {
2118                                     bp2->next = p;
2119                                     if ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0) {
2120                                         change_inputrequest(p, 0);
2121                                     }
2122                                 }
2123                                 else    {
2124                                     inputsw[k].req = p;
2125                                 }
2126                                 p->next = NULL;
2127                             }
2128                             break;
2129                         }
2130                     }
2131                     bp = p;
2132                     p = p->next;
2133                 }
2134             }
2135         }
2136     }
2137
2138     /* re-calculate display zone, sound zone and inout switch priority  */
2139     for (i = 0; i < disp; i++)  {
2140         recalc_dispzone(reqdisp[i]);
2141     }
2142     for (i = 0; i < sound; i++) {
2143         recalc_soundzone(reqsound[i]);
2144     }
2145     for (i = 0; i < input; i++) {
2146         recalc_inputsw(reqinput[i]);
2147     }
2148 }
2149
2150 /*--------------------------------------------------------------------------*/
2151 /**
2152  * @brief   request_timer: request timedout timer(static function)
2153  *
2154  * @param[in]   user_data       user data(unused)
2155  * @return      always ECORE_CALLBACK_RENEW(periodic timer)
2156  */
2157 /*--------------------------------------------------------------------------*/
2158 static Eina_Bool
2159 request_timer(void *user_data)
2160 {
2161     int                 i;
2162     ico_apc_request_t   *p;
2163
2164     if (timer_count <= 0)   {
2165         /* no need timedout check   */
2166         return ECORE_CALLBACK_RENEW;
2167     }
2168     apfw_trace("request_timer: start(%d)", timer_count);
2169     timer_count = 0;
2170
2171     /* check display request timedout   */
2172     for (i = 0; i < ndispzone; i++) {
2173         p = dispzone[i].req;
2174         while (p)   {
2175             if (p->timer > 0)   {
2176                 if (p->timer >= ICO_APC_REQREPLY_INTERVAL)
2177                     p->timer -= ICO_APC_REQREPLY_INTERVAL;
2178                 else
2179                     p->timer = 0;
2180                 apfw_trace("request_timer: dispzone[%d] timer(%d)", i, p->timer);
2181                 if (p->timer == 0)  {
2182                     apfw_trace("request_timer: display timedout(%s %d %d prio=%08x)",
2183                                p->appid, p->resid, p->id, p->prio);
2184                     if ((p->state & ICO_APC_REQSTATE_REPLYACTIVE) &&
2185                         ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
2186                         ico_uxf_window_control(p->appid, p->id,
2187                                                ICO_UXF_APPSCTL_INVISIBLE, 0);
2188                         if (displaycontrol) {
2189                             (*displaycontrol)(get_appconf(p->appid), 1);
2190                         }
2191                     }
2192                     p->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
2193                 }
2194                 else    {
2195                     timer_count ++;
2196                 }
2197             }
2198             p = p->next;
2199         }
2200     }
2201
2202     /* check sound request timedout */
2203     for (i = 0; i < nsoundzone; i++) {
2204         p = soundzone[i].req;
2205         while (p)   {
2206             if (p->timer > 0)   {
2207                 if (p->timer >= ICO_APC_REQREPLY_INTERVAL)
2208                     p->timer -= ICO_APC_REQREPLY_INTERVAL;
2209                 else
2210                     p->timer = 0;
2211                 apfw_trace("request_timer: soundzone[%d] timer(%d)", i, p->timer);
2212                 if (p->timer == 0)  {
2213                     apfw_trace("request_timer: sound timedout(%s %d %d prio=%08x)",
2214                                p->appid, p->resid, p->id, p->prio);
2215                     if ((p->state & ICO_APC_REQSTATE_REPLYACTIVE) &&
2216                         ((p->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
2217                         if (ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_MUTEOFF,
2218                                                               p->pid)
2219                                 != ICO_APF_RESOURCE_E_NONE) {
2220                             apfw_warn("request_timer: send MSM Error");
2221                         }
2222                         if (soundcontrol) {
2223                             (*soundcontrol)(get_appconf(p->appid), 1);
2224                         }
2225                     }
2226                     p->state &= ~(ICO_APC_REQSTATE_REPLYACTIVE|ICO_APC_REQSTATE_REPLYQUIET);
2227                 }
2228                 else    {
2229                     timer_count ++;
2230                 }
2231             }
2232             p = p->next;
2233         }
2234     }
2235     apfw_trace("request_timer: end(%d)", timer_count);
2236     return ECORE_CALLBACK_RENEW;
2237 }
2238
2239 /*--------------------------------------------------------------------------*/
2240 /**
2241  * @brief   ico_syc_apc_is_waitshow: check if application is waiting show
2242  *
2243  * @param[in]   appid           application Id
2244  * @return      answer
2245  * @retval      =1              waiting show
2246  * @retval      =0              not wait
2247  */
2248 /*--------------------------------------------------------------------------*/
2249 int
2250 ico_syc_apc_is_waitshow(const char *appid)
2251 {
2252     int                 i;
2253     ico_apc_request_t   *p;
2254
2255     /* check display request list   */
2256     for (i = 0; i < ndispzone; i++) {
2257         p = dispzone[i].req;
2258         while (p)   {
2259             if (p->timer > 0)   {
2260                 /* waiting show         */
2261                 if (strcmp(p->appid, appid) == 0)   {
2262                     /* found application    */
2263                     uifw_trace("ico_syc_apc_is_waitshow: %s is waiting", appid);
2264                     return 1;
2265                 }
2266             }
2267             p = p->next;
2268         }
2269     }
2270     uifw_trace("ico_syc_apc_is_waitshow: %s is not wait", appid);
2271     return 0;
2272 }
2273
2274 /*--------------------------------------------------------------------------*/
2275 /**
2276  * @brief   ico_syc_apc_active: application change to active
2277  *
2278  * @param[in]   appid           application Id
2279  * @return      none
2280  */
2281 /*--------------------------------------------------------------------------*/
2282 void
2283 ico_syc_apc_active(const char *appid)
2284 {
2285     int     i, j;
2286     int     disp, sound, input;
2287     int     flag;
2288     Ico_Uxf_conf_application    *appconf;
2289     char    *child_appid;
2290     ico_apc_request_t   *p;
2291     ico_apc_request_t   *bp;
2292     ico_apc_request_t   *p2;
2293     ico_apc_request_t   *bp2;
2294     unsigned short  reqdisp[MAXREQ];
2295     unsigned short  reqsound[MAXREQ];
2296     unsigned short  reqinput[MAXREQ];
2297
2298     apfw_trace("ico_syc_apc_active: Enter(%s)", appid ? appid : "(NULL)");
2299
2300     if ((appid != NULL) && (*appid != 0))   {
2301         /* get active application           */
2302         appconf = (Ico_Uxf_conf_application *)ico_uxf_getAppByAppid(appid);
2303         if (! appconf)  {
2304             apfw_trace("ico_syc_apc_active: appid(%s) dose not exist", appid);
2305         }
2306     }
2307     else    {
2308         /* chane to no active application   */
2309         appconf = NULL;
2310     }
2311
2312     if (appconf)    {
2313         /* save child process if exist          */
2314         child_appid = ico_uxf_getchild_appid(appconf->appid);
2315         /* set last active process for child process    */
2316         ico_uxf_set_lastapp(appconf->appid);
2317     }
2318     else    {
2319         /* reset last active process for child process  */
2320         ico_uxf_set_lastapp(NULL);
2321         child_appid = NULL;
2322     }
2323
2324     /* change all screen request from this application  */
2325     disp = 0;
2326     for (i = 0; i < ndispzone; i++) {
2327         p = dispzone[i].req;
2328         flag = 0;
2329         bp = NULL;
2330         while (p)   {
2331             if (appconf && (strcmp(p->appid, appconf->appid) == 0)) {
2332                 apfw_trace("ico_syc_apc_active: disp %s prio=%08x is %s",
2333                            p->appid, p->prio, bp ? "not top" : "top");
2334                 if ((p->prio & ICO_UXF_PRIO_ACTIVEAPP) != ICO_UXF_PRIO_ACTIVEAPP)   {
2335                     p->prio |= ICO_UXF_PRIO_ACTIVEAPP;
2336                     apfw_trace("ico_syc_apc_active: cgange active %s prio to %08x",
2337                                p->appid, p->prio);
2338                     flag ++;
2339
2340                     if (bp) {
2341                         bp->next = p->next;
2342                         p2 = dispzone[i].req;
2343                         bp2 = NULL;
2344                         while (p2)  {
2345                             if (p2->prio <= p->prio)    {
2346                                 p->next = p2;
2347                                 if (bp2) {
2348                                     apfw_trace("ico_syc_apc_active: %s is not top=%s(%08x)",
2349                                                p->appid, dispzone[i].req->appid,
2350                                                dispzone[i].req->prio);
2351                                     bp2->next = p;
2352                                 }
2353                                 else    {
2354                                     if (appconf && (strcmp(p2->appid, appconf->appid) != 0) &&
2355                                         ((p2->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
2356                                         change_disprequest(p2, 0);
2357                                     }
2358                                     dispzone[i].req = p;
2359                                 }
2360                                 break;
2361                             }
2362                             bp2 = p2;
2363                             p2 = p2->next;
2364                         }
2365                         if (! p2)   {
2366                             apfw_trace("ico_syc_apc_active: %s is not top=%s(%08x)",
2367                                        p->appid, dispzone[i].req->appid,
2368                                        dispzone[i].req->prio);
2369                             if (bp2)    {
2370                                 bp2->next = p;
2371                             }
2372                             else    {
2373                                 dispzone[i].req = p;
2374                             }
2375                             p->next = NULL;
2376                         }
2377                     }
2378                     else    {
2379                         apfw_trace("ico_syc_apc_active: app %s is top", p->appid);
2380                     }
2381                 }
2382             }
2383             bp = p;
2384             p = p->next;
2385         }
2386         if (flag)   {
2387             p = dispzone[i].req;
2388             while (p)   {
2389                 if (p->prio & ICO_UXF_PRIO_ACTIVEAPP)  {
2390                     p->prio -= ICO_UXF_PRIO_ACTIVECOUNT;
2391                 }
2392                 p = p->next;
2393             }
2394
2395             for (j = 0; j < disp; j++)  {
2396                 if (dispzone[i].conf->display->id == reqdisp[j])    break;
2397             }
2398             if (j >= disp)  {
2399                 reqdisp[disp++] = dispzone[i].conf->display->id;
2400             }
2401         }
2402     }
2403
2404     /* change all sound request from this application   */
2405     sound = 0;
2406     for (i = 0; i < nsoundzone; i++) {
2407         p = soundzone[i].req;
2408         flag = 0;
2409         bp = NULL;
2410         while (p)   {
2411             if (appconf && (strcmp(p->appid, appconf->appid) == 0)) {
2412                 apfw_trace("ico_syc_apc_active: sound %s prio=%08x is %s",
2413                            p->appid, p->prio, bp ? "not top" : "top");
2414                 if ((p->prio & ICO_UXF_PRIO_ACTIVEAPP) != ICO_UXF_PRIO_ACTIVEAPP)   {
2415                     p->prio |= ICO_UXF_PRIO_ACTIVEAPP;
2416                     apfw_trace("ico_syc_apc_active: cgange active %s prio to %08x",
2417                                p->appid, p->prio);
2418                     flag ++;
2419
2420                     if (bp) {
2421                         bp->next = p->next;
2422                         p2 = soundzone[i].req;
2423                         bp2 = NULL;
2424                         while (p2)  {
2425                             if (p2->prio <= p->prio)    {
2426                                 p->next = p2;
2427                                 if (bp2) {
2428                                     apfw_trace("ico_syc_apc_active: %s is not top=%s(%08x)",
2429                                                p->appid, soundzone[i].req->appid,
2430                                                soundzone[i].req->prio);
2431                                     bp2->next = p;
2432                                 }
2433                                 else    {
2434                                     if (appconf && (strcmp(p2->appid, appconf->appid) != 0) &&
2435                                         ((p2->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
2436                                         change_soundrequest(p2, 0);
2437                                     }
2438                                     soundzone[i].req = p;
2439                                 }
2440                                 break;
2441                             }
2442                             bp2 = p2;
2443                             p2 = p2->next;
2444                         }
2445                         if (! p2)   {
2446                             apfw_trace("ico_syc_apc_active: %s is not top=%s(%08x)",
2447                                        p->appid, soundzone[i].req->appid,
2448                                        soundzone[i].req->prio);
2449                             if (bp2)    {
2450                                 bp2->next = p;
2451                             }
2452                             else    {
2453                                 soundzone[i].req = p;
2454                             }
2455                             p->next = NULL;
2456                         }
2457                     }
2458                     else    {
2459                         apfw_trace("ico_syc_apc_active: app %s is top", p->appid);
2460                     }
2461                 }
2462             }
2463             bp = p;
2464             p = p->next;
2465         }
2466         if (flag)   {
2467             p = soundzone[i].req;
2468             while (p)   {
2469                 if (p->prio & ICO_UXF_PRIO_ACTIVEAPP)  {
2470                     p->prio -= ICO_UXF_PRIO_ACTIVECOUNT;
2471                 }
2472                 p = p->next;
2473             }
2474
2475             for (j = 0; j < sound; j++) {
2476                 if (soundzone[i].conf->sound->id == reqsound[j])    break;
2477             }
2478             if (j >= sound) {
2479                 reqsound[sound++] = soundzone[i].conf->sound->id;
2480             }
2481         }
2482     }
2483
2484     /* change all inputsw request from this application */
2485     input = 0;
2486     for (i = 0; i < ninputsw; i++) {
2487         p = inputsw[i].req;
2488         flag = 0;
2489         bp = NULL;
2490         while (p)   {
2491             if (appconf && (strcmp(p->appid, appconf->appid) == 0)) {
2492                 if ((p->prio & ICO_UXF_PRIO_ACTIVEAPP) != ICO_UXF_PRIO_ACTIVEAPP)   {
2493                     p->prio |= ICO_UXF_PRIO_ACTIVEAPP;
2494                     apfw_trace("ico_syc_apc_active: cgange active %s prio to %08x",
2495                                p->appid, p->prio);
2496                     flag ++;
2497
2498                     if (bp) {
2499                         bp->next = p->next;
2500                         p2 = inputsw[i].req;
2501                         bp2 = NULL;
2502                         while (p2)  {
2503                             if (p2->prio <= p->prio)    {
2504                                 p->next = p2;
2505                                 if (bp2) {
2506                                     apfw_trace("ico_syc_apc_active: %s is not top=%s(%08x)",
2507                                                p->appid, inputsw[i].req->appid,
2508                                                inputsw[i].req->prio);
2509                                     bp2->next = p;
2510                                 }
2511                                 else    {
2512                                     if (appconf && (strcmp(p2->appid, appconf->appid) != 0) &&
2513                                         ((p2->state & ICO_APC_REQSTATE_WAITREQ) == 0))  {
2514                                         change_inputrequest(p2, 0);
2515                                     }
2516                                     inputsw[i].req = p;
2517                                 }
2518                                 break;
2519                             }
2520                             bp2 = p2;
2521                             p2 = p2->next;
2522                         }
2523                         if (! p2)   {
2524                             apfw_trace("ico_syc_apc_active: %s is not top=%s(%08x)",
2525                                        p->appid, inputsw[i].req->appid,
2526                                        inputsw[i].req->prio);
2527                             if (bp2)    {
2528                                 bp2->next = p;
2529                             }
2530                             else    {
2531                                 inputsw[i].req = p;
2532                             }
2533                             p->next = NULL;
2534                         }
2535                     }
2536                     else    {
2537                         apfw_trace("ico_syc_apc_active: app %s is top", p->appid);
2538                     }
2539                 }
2540             }
2541             bp = p;
2542             p = p->next;
2543         }
2544         if (flag)   {
2545             p = inputsw[i].req;
2546             while (p)   {
2547                 if (p->prio & ICO_UXF_PRIO_ACTIVEAPP)  {
2548                     p->prio -= ICO_UXF_PRIO_ACTIVECOUNT;
2549                 }
2550                 p = p->next;
2551             }
2552
2553             for (j = 0; j < input; j++) {
2554                 if (inputsw[i].inputsw->input == reqinput[j])   break;
2555             }
2556             if (j >= input) {
2557                 reqinput[input++] = inputsw[i].inputsw->input;
2558             }
2559         }
2560     }
2561
2562     /* re-calculate display zone, sound zone and inout switch priority  */
2563     for (i = 0; i < disp; i++)  {
2564         recalc_dispzone(reqdisp[i]);
2565     }
2566     for (i = 0; i < sound; i++) {
2567         recalc_soundzone(reqsound[i]);
2568     }
2569     for (i = 0; i < input; i++) {
2570         recalc_inputsw(reqinput[i]);
2571     }
2572     if (child_appid)    {
2573         apfw_trace("ico_syc_apc_active: active child app(%s)", child_appid);
2574         ico_syc_apc_active(child_appid);
2575     }
2576     apfw_trace("ico_syc_apc_active: Leave");
2577 }
2578
2579 /*--------------------------------------------------------------------------*/
2580 /**
2581  * @brief   app_display_hook: hook function for surface create/destroy(static function)
2582  *
2583  * @param[in]   appid           application Id
2584  * @param[in]   surface         surface Id
2585  * @param[in]   object          target surface type and operation
2586  * @return      none
2587  */
2588 /*--------------------------------------------------------------------------*/
2589 static void
2590 app_display_hook(const char *appid, const int surface, const int object)
2591 {
2592     int     i;
2593     int     count;
2594     ico_apc_request_t           *reqsave[MAXREQ];
2595     Ico_Uxf_conf_application    *appconf;
2596     ico_apc_request_t           *req;
2597
2598     apfw_trace("app_display_hook: Enter(%s,%08x,%x)", appid, surface, object);
2599
2600     appconf = (Ico_Uxf_conf_application *)ico_uxf_getAppByAppid(appid);
2601     if (! appconf)  {
2602         apfw_warn("app_display_hook: Leave(appid[%s] dose not exist)", appid);
2603         return;
2604     }
2605     if ((confsys->kind[appconf->kindId].priv == ICO_UXF_PRIVILEGE_ALMIGHTY) ||
2606         (confsys->kind[appconf->kindId].priv == ICO_UXF_PRIVILEGE_SYSTEM) ||
2607         (confsys->kind[appconf->kindId].priv == ICO_UXF_PRIVILEGE_SYSTEM_VISIBLE))  {
2608         /* System Program(ex. HomeScreen) no need resource control  */
2609         apfw_trace("app_display_hook: Leave(appid[%s] is system program)", appid);
2610         return;
2611     }
2612
2613     switch (object) {
2614     case ICO_UXF_HOOK_WINDOW_CREATE_MAIN:   /* created application main window  */
2615         /* search display request   */
2616         for (i = 0; i < ndispzone; i++) {
2617             req = dispzone[i].req;
2618             while (req)   {
2619                 if ((strcmp(req->appid, appconf->appid) == 0) &&
2620                     ((req->resid == ICO_APF_RESID_BASIC_SCREEN) ||
2621                      (req->resid == ICO_APF_RESID_ON_SCREEN)))  break;
2622                 req = req->next;
2623             }
2624             if (req)    break;
2625         }
2626         if (i < ndispzone)  {
2627             apfw_trace("app_display_hook: app(%s) requested display, Nop", appid);
2628         }
2629         else    {
2630             apfw_trace("app_display_hook: app(%s) not requested display, set default[%s]",
2631                        appid,
2632                        confsys->display[appconf->display[0].displayId].
2633                            zone[appconf->display[0].zoneId].name);
2634             req = get_freereq();
2635             if (req)    {
2636                 strncpy(req->appid, appconf->appid, ICO_UXF_MAX_PROCESS_NAME);
2637                 req->resid = ICO_APF_RESID_BASIC_SCREEN;
2638                 req->reqtype = ICO_APC_REQTYPE_CREATE;
2639                 strcpy(req->device,
2640                        confsys->display[appconf->display[0].displayId].
2641                            zone[appconf->display[0].zoneId].name);
2642                 app_getdisplay(req, 0);
2643             }
2644         }
2645         break;
2646     case ICO_UXF_HOOK_WINDOW_DESTORY_MAIN:  /* destoryed application main window*/
2647         /* delete all request from this application */
2648         count = 0;
2649         for (i = 0; i < ndispzone; i++) {
2650             req = dispzone[i].req;
2651             while (req)   {
2652                 if (strcmp(req->appid, appconf->appid) == 0) {
2653                     reqsave[count++] = req;
2654                 }
2655                 req = req->next;
2656             }
2657         }
2658         if (count > 0)  {
2659             apfw_trace("app_display_hook: free app(%s) all display request", appid);
2660             for (i = 0; i < count; i++) {
2661                 app_freedisplay(reqsave[i], 0);
2662             }
2663         }
2664         break;
2665     default:                                /* other, Nop   */
2666         break;
2667     }
2668
2669     apfw_trace("app_display_hook: Leave");
2670 }
2671
2672 /*--------------------------------------------------------------------------*/
2673 /**
2674  * @brief   ico_syc_apc_init: initialize application controller
2675  *
2676  * @param[in]   display     callback function for display control
2677  * @param[in]   sound       callback function for sound control
2678  * @param[in]   input       callback function for input control
2679  * @return      result
2680  * @retval      ICO_SYC_EOK     success
2681  * @retval      ICO_SYC_ENOSYS  error(system error)
2682  * @retval      ICO_SYC_ENOMEM  error(out of memory)
2683  */
2684 /*--------------------------------------------------------------------------*/
2685 int
2686 ico_syc_apc_init(ico_apc_resource_control_t display, ico_apc_resource_control_t sound,
2687                  ico_apc_resource_control_t input)
2688 {
2689     int     count;
2690     int     base_count;
2691     int     i, j, k;
2692     int     ret;
2693     Ico_Uxf_InputDev    *pdev;
2694     Ico_Uxf_InputSw     *psw;
2695
2696     apfw_trace("ico_syc_apc_init: Enter");
2697
2698     if (ico_apps_controller_init)   {
2699         apfw_trace("ico_syc_apc_init: Leave(OK, initialized)");
2700         return ICO_SYC_EOK;
2701     }
2702
2703     /* set callback functions for HomeScreen        */
2704     displaycontrol = display;
2705     soundcontrol = sound;
2706     inputcontrol = input;
2707
2708     ico_apps_controller_init = 1;
2709
2710     /* get configurations                           */
2711     confsys = (Ico_Uxf_Sys_Config *)ico_uxf_getSysConfig();
2712     confapp = (Ico_Uxf_App_Config *)ico_uxf_getAppConfig();
2713
2714     if ((! confsys) || (! confapp)) {
2715         ico_apps_controller_init = 0;
2716         apfw_error("ico_syc_apc_init: Leave(can not read configuration)");
2717         return ICO_SYC_ENOSYS;
2718     }
2719
2720     /* initialize internal tables                   */
2721     /* display zone table                           */
2722     ndispzone = 0;
2723     for (i = 0; i < confsys->displayNum; i++)   {
2724         ndispzone += confsys->display[i].zoneNum;
2725     }
2726     dispzone = malloc(sizeof(ico_apc_dispzone_t) * ndispzone);
2727     if (! dispzone) {
2728         ico_apps_controller_init = 0;
2729         apfw_error("ico_syc_apc_init: Leave(No Memory)");
2730         return ICO_SYC_ENOMEM;
2731     }
2732     memset(dispzone, 0, sizeof(ico_apc_dispzone_t) * ndispzone);
2733     count = 0;
2734     for (i = 0; i < confsys->displayNum; i++)   {
2735         base_count = count;
2736         for (j = 0; j < confsys->display[i].zoneNum; j++)   {
2737             dispzone[count].conf = &confsys->display[i].zone[j];
2738             dispzone[count].noverlap = confsys->display[i].zone[j].overlapNum;
2739             for (k = 0; k < dispzone[count].noverlap; k++)  {
2740                 dispzone[count].overlap[k] =
2741                     &dispzone[base_count + confsys->display[i].zone[j].overlap[k]];
2742             }
2743             count ++;
2744         }
2745     }
2746
2747     /* sound zone table                         */
2748     nsoundzone = 0;
2749     for (i = 0; i < confsys->soundNum; i++) {
2750         nsoundzone += confsys->sound[i].zoneNum;
2751     }
2752     soundzone = malloc(sizeof(ico_apc_soundzone_t) * nsoundzone);
2753     if (! soundzone)    {
2754         ico_apps_controller_init = 0;
2755         apfw_error("ico_syc_apc_init: Leave(No Memory)");
2756         return ICO_SYC_ENOMEM;
2757     }
2758     memset(soundzone, 0, sizeof(ico_apc_soundzone_t) * nsoundzone);
2759     count = 0;
2760     for (i = 0; i < confsys->soundNum; i++) {
2761         base_count = count;
2762         for (j = 0; j < confsys->sound[i].zoneNum; j++) {
2763             soundzone[count].conf = &confsys->sound[i].zone[j];
2764             soundzone[count].noverlap = confsys->sound[i].zone[j].overlapNum;
2765             for (k = 0; k < soundzone[count].noverlap; j++) {
2766                 soundzone[count].overlap[k] =
2767                     &soundzone[base_count + confsys->sound[i].zone[j].overlap[k]];
2768             }
2769             count ++;
2770         }
2771     }
2772     /* input sw table                           */
2773     ninputsw = 0;
2774     for (i = 0; ; i++)  {
2775         pdev = ico_uxf_inputdev_attribute_get(i);
2776         if (pdev == NULL)   break;
2777         apfw_trace("ico_syc_apc_init: input device.%d %s has %d switchs",
2778                    i, pdev->device, pdev->numInputSw);
2779         for (j = 0; j < pdev->numInputSw; j++)  {
2780             psw = ico_uxf_inputsw_attribute_get(pdev, j);
2781             if (psw == NULL)    break;
2782             if (psw->fix == 0)  {
2783                 ninputsw ++;
2784             }
2785         }
2786     }
2787     if (ninputsw > 0)   {
2788         inputsw = malloc(sizeof(ico_apc_inputsw_t) * ninputsw);
2789         if (! inputsw)  {
2790             ico_apps_controller_init = 0;
2791             apfw_error("ico_syc_apc_init: Leave(No Memory)");
2792             return ICO_SYC_ENOMEM;
2793         }
2794         memset(inputsw, 0, sizeof(ico_apc_inputsw_t) * ninputsw);
2795         count = 0;
2796         for (i = 0; ; i++)  {
2797             pdev = ico_uxf_inputdev_attribute_get(i);
2798             if (pdev == NULL)   break;
2799             for (j = 0; j < pdev->numInputSw; j++)  {
2800                 psw = ico_uxf_inputsw_attribute_get(pdev, j);
2801                 if (psw == NULL)    break;
2802                 if (psw->fix)       continue;
2803                 inputsw[count].inputdev = pdev;
2804                 inputsw[count].inputsw = psw;
2805                 count ++;
2806             }
2807         }
2808     }
2809
2810     /* initialize request table                     */
2811     ico_apc_request_t *req = malloc(sizeof(ico_apc_request_t) * INIT_REQCB);
2812     ico_apc_request_t *breq;
2813     if (! req)  {
2814         ico_apps_controller_init = 0;
2815         apfw_error("ico_syc_apc_init: Leave(No Memory)");
2816         return ICO_SYC_ENOMEM;
2817     }
2818     memset(req, 0, sizeof(ico_apc_request_t) * INIT_REQCB);
2819     free_request = req;
2820     for (count = 1; count < INIT_REQCB; count++)    {
2821         breq = req;
2822         req ++;
2823         breq->next = req;
2824     }
2825
2826     /* initialzie application framework library     */
2827     ret = ico_apf_ecore_init_server(NULL);
2828     if (ret != ICO_APF_E_NONE)  {
2829         ico_apps_controller_init = 0;
2830         apfw_error("ico_syc_apc_init: Leave(ico_apf_ecore_init_server Error<%d>)", ret);
2831         return ICO_SYC_ENOSYS;
2832     }
2833
2834     /* regist callback for application resource request */
2835     ret = ico_apf_resource_set_event_cb(resource_reqcb, NULL);
2836     if (ret != ICO_APF_RESOURCE_E_NONE) {
2837         ico_apps_controller_init = 0;
2838         apfw_error("ico_syc_apc_init: Leave(ico_apf_resource_set_event_cb Error<%d>)",
2839                    ret);
2840         ico_apf_resource_term_server();
2841         return ICO_SYC_ENOSYS;
2842     }
2843
2844     /* initialize regulation controller    */
2845     ret = ico_syc_apc_regulation_init();
2846     if (ret != ICO_SYC_EOK) {
2847         ico_apps_controller_init = 0;
2848         apfw_error("ico_syc_apc_init: Leave(ico_syc_apc_regulation_init Error<%d>)",
2849                    ret);
2850         ico_apf_resource_term_server();
2851         return ICO_SYC_ENOSYS;
2852     }
2853
2854     ico_syc_apc_regulation_listener(regulation_listener, NULL);
2855
2856     /* set hook for window create/destory   */
2857     (void) ico_uxf_window_hook(app_display_hook);
2858
2859     /* create timer     */
2860     ecore_timer = ecore_timer_add(((double)ICO_APC_REQREPLY_INTERVAL)/1000.0,
2861                                   request_timer, NULL);
2862     timer_count = 1;
2863
2864     /* send sound stream list request to Multi Sound manager    */
2865     ret = ico_apf_resource_send_to_soundctl(ICO_APF_SOUND_COMMAND_GETLIST, 0);
2866     if (ret != ICO_APF_RESOURCE_E_NONE) {
2867         apfw_error("ico_syc_apc_init: Leave(ico_apf_resource_send_to_soundctl Error<%d>)",
2868                    ret);
2869         return ICO_SYC_ENOSYS;
2870     }
2871
2872     apfw_trace("ico_syc_apc_init: Leave(EOK)");
2873     return ICO_SYC_EOK;
2874 }
2875
2876 /*--------------------------------------------------------------------------*/
2877 /**
2878  * @brief   ico_syc_apc_term: terminate application controller
2879  *
2880  * @param       none
2881  * @return      none
2882  */
2883 /*--------------------------------------------------------------------------*/
2884 void
2885 ico_syc_apc_term(void)
2886 {
2887     apfw_trace("ico_syc_apc_term: Enter");
2888     if (ico_apps_controller_init == 0)  {
2889         apfw_trace("ico_syc_apc_term: Leave(not initialized)");
2890         return;
2891     }
2892     if (ecore_timer)    {
2893         ecore_timer_del(ecore_timer);
2894         ecore_timer = NULL;
2895     }
2896
2897     ico_syc_apc_regulation_term();
2898     ico_apf_resource_term_server();
2899     ico_apps_controller_init = 0;
2900
2901     apfw_trace("ico_syc_apc_term: Leave");
2902 }
2903