Additional functions of policy and resource management.
[profile/ivi/ico-uxf-homescreen.git] / lib / system-controller / CicoSCResourceManager.cpp
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 //==========================================================================
11 /**
12  *  @file   CicoSCResourceManager.cpp
13  *
14  *  @brief  This file implementation of CicoSCResourceManager class
15  */
16 //==========================================================================
17
18 #include <sstream>
19 using namespace std;
20
21 #include "CicoSCResourceManager.h"
22 #include "CicoLog.h"
23 #include "ico_syc_error.h"
24 #include "ico_syc_mrp_resource_private.h"
25
26 #include "ico_syc_msg_cmd_def.h"
27 #include "CicoSCSystemConfig.h"
28 #include "CicoSCConf.h"
29 #include "CicoSCCommand.h"
30 #include "CicoSCPolicyManager.h"
31 #include "CicoSCLifeCycleController.h"
32 #include "CicoSCAilItems.h"
33 #include "CicoSCWindowController.h"
34 #include "CicoSCInputController.h"
35 #include "CicoSCPolicyDef.h"
36
37 struct CompDisplayResourceRequest
38 {
39     CompDisplayResourceRequest(const resource_request_t *req)
40         : m_req(req) {}
41
42     bool operator() (const resource_request_t *req)
43     {
44         if (NULL == req) {
45             return false;
46         }
47         ICO_DBG("appid=%s:%s", req->appid, m_req->appid);
48         if ((0 == strcmp(m_req->appid, req->appid)) &&
49             (m_req->pid == req->pid) &&
50             ((m_req->resid & RESID_TYPE_MASK) == (req->resid & RESID_TYPE_MASK)) &&
51             (m_req->surfaceid == req->surfaceid)) {
52             return true;
53         }
54         return false;
55     }
56
57     const resource_request_t *m_req;
58 };
59
60 struct CompSoundResourceRequest
61 {
62     CompSoundResourceRequest(const resource_request_t *req)
63         : m_req(req) {}
64
65     bool operator() (const resource_request_t *req)
66     {
67         if (NULL == req) {
68             return false;
69         }
70
71         ICO_DBG("appid=%s:%s", req->appid, m_req->appid);
72         if ((0 == strcmp(m_req->appid, req->appid)) &&
73             (m_req->pid == req->pid) &&
74             ((m_req->resid & RESID_TYPE_MASK) == (req->resid & RESID_TYPE_MASK)) &&
75             (m_req->soundid == req->soundid)) {
76             return true;
77         }
78         return false;
79     }
80
81     const resource_request_t *m_req;
82 };
83
84 struct CompInputResourceRequest
85 {
86     CompInputResourceRequest(const resource_request_t *req)
87         : m_req(req) {}
88
89     bool operator() (const resource_request_t *req)
90     {
91         if (NULL == req) {
92             return false;
93         }
94
95         ICO_DBG("appid=%s:%s", req->appid, m_req->appid);
96         if ((0 == strcmp(m_req->appid, req->appid)) &&
97             (0 == strcmp(m_req->device, req->device)) &&
98             (m_req->pid == req->pid) &&
99             ((m_req->resid & RESID_TYPE_MASK) == (req->resid & RESID_TYPE_MASK))) {
100             return true;
101         }
102         return false;
103     }
104
105     const resource_request_t *m_req;
106 };
107
108
109 CicoSCResourceManager::CicoSCResourceManager()
110     : m_winCtrl(NULL), m_inputCtrl(NULL)
111 {
112     m_policyMgr = new CicoSCPolicyManager(this);
113
114     CicoSCSystemConfig *sysConf = CicoSCSystemConfig::getInstance();
115     list<resource_request_t*> l;
116
117     {
118         // initialize display current request and waiting queue
119         const vector<CicoSCDisplayConf*>& dispConfList
120             = sysConf->getDisplayConfList();
121         vector<CicoSCDisplayConf*>::const_iterator itr;
122         itr = dispConfList.begin();
123         for (; itr != dispConfList.end(); ++itr) {
124             vector<CicoSCDisplayZoneConf*>::iterator itr2;
125             itr2 = (*itr)->zoneConfList.begin();
126             for (; itr2 != (*itr)->zoneConfList.end(); ++itr2) {
127                 m_curDispResReq[(*itr2)->id] = NULL;
128                 m_dispReqQueue[(*itr2)->id]  = l;
129             }
130         }
131     }
132
133     {
134         // initialize sound current request and waiting queue
135         const vector<CicoSCSoundConf*>& soundConfList
136             = sysConf->getSoundConfList();
137         vector<CicoSCSoundConf*>::const_iterator itr;
138         itr = soundConfList.begin();
139         for (; itr != soundConfList.end(); ++itr) {
140             vector<CicoSCSoundZoneConf*>::iterator itr2;
141             itr2 = (*itr)->zoneConfList.begin();
142             for (; itr2 != (*itr)->zoneConfList.end(); ++itr2) {
143                 m_curSoundResReq[(*itr2)->id] = NULL;
144                 m_soundReqQueue[(*itr2)->id]  = l;
145             }
146         }
147     }
148
149    {
150         // initialize input current request and waiting queue
151         const vector<CicoSCInputDevConf*>& inputDevConfList
152             = sysConf->getInputDevConfList();
153         vector<CicoSCInputDevConf*>::const_iterator itr;
154         itr = inputDevConfList.begin();
155         for (; itr != inputDevConfList.end(); ++itr) {
156             vector<CicoSCSwitchConf*>::iterator itr2;
157             itr2 = (*itr)->switchConfList.begin();
158             for (; itr2 != (*itr)->switchConfList.end(); ++itr2) {
159                 m_curInputResReq[(*itr2)->id] = NULL;
160                 m_inputReqQueue[(*itr2)->id]  = l;
161             }
162         }
163     }
164 }
165
166 CicoSCResourceManager::~CicoSCResourceManager()
167 {
168     delete m_policyMgr;
169 }
170
171 int
172 CicoSCResourceManager::initialize(void)
173 {
174     ICO_DBG("CicoSCResourceManager::initialize Enter");
175
176     int ret = ICO_SYC_EOK;
177
178     ret = ico_syc_mrp_init(enforceSound, this);
179     if (ICO_SYC_EOK != ret) {
180         return ret;
181     }
182
183     ret = m_policyMgr->initialize();
184     if (ICO_SYC_EOK != ret) {
185         return ret;
186     }
187
188
189     ICO_DBG("CicoSCResourceManager::initialize Leave");
190     return ret;
191 }
192   
193 void
194 CicoSCResourceManager::terminate(void)
195 {
196     ICO_DBG("CicoSCResourceManager::terminate Enter");
197     m_policyMgr->terminate();
198     ICO_DBG("CicoSCResourceManager::terminate Leave");
199 }
200
201 void
202 CicoSCResourceManager::handleCommand(const CicoSCCommand &cmd,
203                                      bool internal)
204 {
205     ICO_DBG("CicoSCResourceManager::handleCommand Enter"
206             "(cmdid=0x%08X internal=%s)",
207             cmd.cmdid, internal ? "true" : "false");
208
209     CicoSCCmdResCtrlOpt *opt = (CicoSCCmdResCtrlOpt*)cmd.opt;
210
211     // request command from application or internal
212     int reqtype = internal ? REQTYPE_AUTO : REQTYPE_APP;
213
214     if ((MSG_CMD_CREATE_RES == cmd.cmdid) ||
215         (MSG_CMD_ACQUIRE_RES == cmd.cmdid)) {
216         
217         if (true == opt->dispres) {
218             resource_request_t *req = newResourceRequest(RESID_KIND_DISPLAY,
219                                                          reqtype,
220                                                          cmd);
221             if (MSG_CMD_CREATE_RES == cmd.cmdid) {
222                 acquireDisplayResource(req, false);
223             }
224             else {
225                 acquireDisplayResource(req);
226             }
227
228         }
229         if (true == opt->soundres) {
230             resource_request_t *req = newResourceRequest(RESID_KIND_SOUND,
231                                                          reqtype,
232                                                          cmd);
233             acquireSoundResource(req);
234         }
235         if (true == opt->inputres) {
236             resource_request_t *req = newResourceRequest(RESID_KIND_INPUT,
237                                                          reqtype,
238                                                          cmd);
239             acquireInputResource(req);
240         }
241     }
242     else if ((MSG_CMD_RELEASE_RES == cmd.cmdid) ||
243              (MSG_CMD_DESTORY_RES == cmd.cmdid)) {
244
245         if (true == opt->dispres) {
246             resource_request_t *req = newResourceRequest(RESID_KIND_DISPLAY,
247                                                          reqtype,
248                                                          cmd);
249             releaseDisplayResource(req);
250         }
251         if (true == opt->soundres) {
252             resource_request_t *req = newResourceRequest(RESID_KIND_SOUND,
253                                                          reqtype,
254                                                          cmd);
255             releaseSoundResource(req);
256         }
257         if (true == opt->inputres) {
258             resource_request_t *req = newResourceRequest(RESID_KIND_INPUT,
259                                                          reqtype,
260                                                          cmd);
261             releaseInputResource(req);
262         }
263     }
264     else {
265         ICO_WRN("Unknown command");
266     }
267
268     ICO_DBG("CicoSCResourceManager::handleCommand Leave");
269 }
270
271 void
272 CicoSCResourceManager::setWindowController(CicoSCWindowController *winCtrl)
273 {
274     m_winCtrl = winCtrl;
275 }
276
277 void
278 CicoSCResourceManager::setInputController(CicoSCInputController *inputCtrl)
279 {
280     m_inputCtrl = inputCtrl;
281 }
282
283 resource_request_t * 
284 CicoSCResourceManager::popDispResReq(resource_request_t *req)
285 {
286     ICO_DBG("CicoSCResourceManager::popDispResReq Enter");
287
288     map<int, list<resource_request_t*> >::iterator itr;
289     itr = m_dispReqQueue.begin();
290     CompDisplayResourceRequest comp(req);
291     for (; itr != m_dispReqQueue.end(); ++itr) {
292         list<resource_request_t*>::iterator itr2;
293         itr2 = find_if(itr->second.begin(), itr->second.end(), comp);
294         if (itr->second.end() != itr2) {
295             ICO_DBG("Dequeue waiting display request queue zone=%d req=0x%08x",
296                     itr->first, *itr2);
297             m_dispReqQueue[req->dispzoneid].erase(itr2);
298             ICO_DBG("CicoSCResourceManager::popDispResReq Leave"
299                     "(0x%08x)", *itr2);
300             return *itr2;
301         }
302     }
303
304     ICO_DBG("CicoSCResourceManager::popDispResReq Leave(NULL)");
305     return NULL;
306 }
307
308 resource_request_t *
309 CicoSCResourceManager::popSoundResReq(resource_request_t *req)
310 {
311     ICO_DBG("CicoSCResourceManager::popSoundResReq Enter");
312
313     map<int, list<resource_request_t*> >::iterator itr;
314     itr = m_soundReqQueue.begin();
315     CompSoundResourceRequest comp(req);
316     for (; itr != m_soundReqQueue.end(); ++itr) {
317         list<resource_request_t*>::iterator itr2;
318         itr2 = find_if(itr->second.begin(), itr->second.end(), comp);
319         if (itr->second.end() != itr2) {
320             ICO_DBG("Dequeue waiting sound request queue zone=%d req=0x%08x",
321                     itr->first, *itr2);
322             m_soundReqQueue[req->soundzoneid].erase(itr2);
323             ICO_DBG("CicoSCResourceManager::popSoundResReq Leave"
324                     "(0x%08x)", *itr2);
325             return *itr2;
326         }
327     }
328     ICO_DBG("CicoSCResourceManager::popSoundResReq Leave(NULL)");
329     return NULL;
330 }
331
332 resource_request_t * 
333 CicoSCResourceManager::popInputResReq(resource_request_t *req)
334 {
335     ICO_DBG("CicoSCResourceManager::popInputResReq Enter");
336
337     map<int, list<resource_request_t*> >::iterator itr;
338     itr = m_inputReqQueue.begin();
339     CompInputResourceRequest comp(req);
340     for (; itr != m_inputReqQueue.end(); ++itr) {
341         list<resource_request_t*>::iterator itr2;
342         itr2 = find_if(itr->second.begin(), itr->second.end(), comp);
343         if (itr->second.end() != itr2) {
344             ICO_DBG("Dequeue waiting input request queue input=%d req=0x%08x",
345                     itr->first, *itr2);
346             m_inputReqQueue[req->input].erase(itr2);
347             ICO_DBG("CicoSCResourceManager::popInputResReq Leave"
348                     "(0x%08x)", *itr2);
349             return *itr2;
350         }
351     }
352
353     ICO_DBG("CicoSCResourceManager::popDispResReq Leave(NULL)");
354     return NULL;
355 }
356
357
358 bool
359 CicoSCResourceManager::acquireDisplayResource(resource_request_t *newreq,
360                                               bool control)
361 {
362     ICO_DBG("CicoSCResourceManager::acquireDisplayResource Enter");
363
364     CicoSCSystemConfig *sysConf = CicoSCSystemConfig::getInstance();
365     const CicoSCAppKindConf *appKindConf = NULL;
366     appKindConf = sysConf->findAppKindConfbyId(newreq->appkind);
367     if (NULL == appKindConf) {
368         ICO_ERR("not found CicoSCAppKindConf instance");
369         ICO_DBG("CicoSCResourceManager::acquireDisplayResource Leave(false)");
370         return false;
371     }
372
373     if ((appKindConf->privilege == CicoSCAppKindConf::PRIVILEGE_ALMIGHTY) ||
374         (appKindConf->privilege == CicoSCAppKindConf::PRIVILEGE_SYSTEM)   ||
375         (appKindConf->privilege == CicoSCAppKindConf::PRIVILEGE_SYSTEM_VISIBLE)) {
376
377         if ((NULL != m_winCtrl) && (true == control)) {
378             m_winCtrl->show(newreq->surfaceid,
379                             newreq->animation,
380                             newreq->animationTime);
381         }
382         delResourceRequest(newreq);
383
384         ICO_DBG("kind of system application");
385         ICO_DBG("CicoSCResourceManager::acquireDisplayResource Leave(true)");
386         return true;
387     }
388
389     resource_request_t *req = NULL;
390     // equal current request?
391     CompDisplayResourceRequest comp(newreq);
392     resource_request_t *curreq = m_curDispResReq[newreq->dispzoneid];
393     if ((NULL != curreq) && (true == comp(curreq))) {
394         ICO_DBG("already acquired appid=%s pid=%d surfaceid=0x%08X",
395                 curreq->appid, curreq->pid, curreq->surfaceid);
396         ICO_DBG("CicoSCResourceManager::acquireDisplayResource Leave(true)");
397         // is change zone?
398         if (newreq->dispzoneid == curreq->dispzoneid) {
399             // free new request
400             delResourceRequest(newreq);
401             return true;
402         }
403         req = curreq;
404         curreq->dispzoneid = newreq->dispzoneid;
405         delResourceRequest(newreq);
406     }
407     else {
408         // watting request?
409         req = popDispResReq(newreq);
410         if (NULL == req) {
411             req = newreq;
412         }
413     }
414
415     if (false == control) {
416         ICO_DBG("Enqueue waiting display request queue zone=%d req=0x%08x",
417                 req->dispzoneid, req);
418         m_dispReqQueue[req->dispzoneid].push_front(req);
419         return true;
420     }
421
422     int type = req->resid & RESID_TYPE_MASK;
423     bool state = m_policyMgr->acquireDisplayResource(type,
424                                                      req->dispzoneid,
425                                                      req->prio);
426     if (true == state) {
427         updateDisplayResource(req);
428     }
429     else {
430         ICO_DBG("Enqueue waiting display request queue zone=%d req=0x%08x",
431                 req->dispzoneid, req);
432         m_dispReqQueue[req->dispzoneid].push_front(req);
433     }
434
435
436     ICO_DBG("CicoSCResourceManager::acquireDisplayResource Leave");
437     return true;
438 }
439
440 void
441 CicoSCResourceManager::releaseDisplayResource(resource_request_t *newreq)
442 {
443     ICO_DBG("CicoSCResourceManager::releaseDisplayResource Enter");
444
445     bool curchg = false;
446     CompDisplayResourceRequest comp(newreq);
447     for (int i = 0; i < (int)m_curDispResReq.size(); ++i) {
448          if (NULL == m_curDispResReq[i]) {
449             continue;
450          }
451
452          if (true == comp(m_curDispResReq[i])) {
453             if (NULL != m_winCtrl) {
454                 // hide current window
455                 m_winCtrl->hide(m_curDispResReq[i]->surfaceid, NULL, 0);
456             }
457             delResourceRequest(newreq);
458             delResourceRequest(m_curDispResReq[i]);
459             m_curDispResReq[i] = NULL;
460             curchg = true;
461             break;
462          }
463     }
464
465     // If current request is not changed, 
466     // remove the request from the waiting queue.
467     if (false == curchg) {
468        resource_request_t *req = popDispResReq(newreq);
469         if (NULL != req) {
470             delResourceRequest(req);
471             req = NULL;
472         }
473         delResourceRequest(newreq);
474         ICO_DBG("CicoSCResourceManager::releaseDisplayResource Leave");
475         return;
476     }
477
478     map<int, list<resource_request_t*> >::iterator itr;
479     itr = m_dispReqQueue.begin();
480     for (; itr != m_dispReqQueue.end(); ++itr) {
481         list<resource_request_t*>::iterator itr2;
482         itr2 = itr->second.begin();
483         for (; itr2 !=  itr->second.end(); ++itr2) {
484             int type = (*itr2)->resid & RESID_TYPE_MASK;
485             bool active = m_policyMgr->acquireDisplayResource(type,
486                                                          (*itr2)->dispzoneid,
487                                                          (*itr2)->prio);
488             if (true == active) {
489                 resource_request_t* req = *itr2;
490                 ICO_DBG("Dequeue waiting display request queue "
491                         "zone=%d req=0x%08x", itr->first, *itr2);
492                 itr->second.erase(itr2);
493                 updateDisplayResource(req);
494                 break;
495             }
496         }
497     }
498
499     ICO_DBG("CicoSCResourceManager::releaseDisplayResource Leave");
500 }
501
502 bool
503 CicoSCResourceManager::acquireSoundResource(resource_request_t *newreq)
504 {
505     ICO_DBG("CicoSCResourceManager::acquireSoundResource Enter");
506
507     CicoSCSystemConfig *sysConf = CicoSCSystemConfig::getInstance();
508     const CicoSCAppKindConf *appKindConf = NULL;
509     appKindConf = sysConf->findAppKindConfbyId(newreq->appkind);
510     if (NULL == appKindConf) {
511         ICO_ERR("not found CicoSCAppKindConf instance");
512         ICO_DBG("CicoSCResourceManager::acquireSoundResource Leave(false)");
513         return false;
514     }
515
516     if ((appKindConf->privilege == CicoSCAppKindConf::PRIVILEGE_ALMIGHTY) ||
517         (appKindConf->privilege == CicoSCAppKindConf::PRIVILEGE_SYSTEM)   ||
518         (appKindConf->privilege == CicoSCAppKindConf::PRIVILEGE_SYSTEM_AUDIO)) {
519
520         delResourceRequest(newreq);
521
522         ICO_DBG("kind of system application");
523         ICO_DBG("CicoSCResourceManager::acquireSoundResource Leave(true)");
524         return true;
525     }
526
527     resource_request_t *req = popSoundResReq(newreq);
528     if (NULL == req) {
529         req = newreq;
530     }
531
532     // is change zone?
533     CompSoundResourceRequest comp(req);
534     if (true == comp(m_curSoundResReq[req->soundzoneid])) {
535         ICO_DBG("already acquired appid=%s pid=%d soundid=0x%08X",
536                 req->appid, req->pid, req->soundid);
537         ICO_DBG("CicoSCResourceManager::acquireSoundResource Leave(true)");
538         // free new request
539         delResourceRequest(newreq);
540         return true;
541     }
542
543     int type = req->resid & RESID_TYPE_MASK;
544     bool state = m_policyMgr->acquireSoundResource(type,
545                                                    req->soundzoneid,
546                                                    req->prio);
547     if (true == state) {
548         updateSoundResource(req);
549     }
550     else {
551         ICO_DBG("Enqueue waiting sound request queue zone=%d req=0x%08x",
552                 req->soundzoneid, req);
553         m_soundReqQueue[req->soundzoneid].push_front(req);
554     }
555
556     ICO_DBG("CicoSCResourceManager::acquireSoundResource Leave");
557     return true;
558 }
559
560 void
561 CicoSCResourceManager::releaseSoundResource(resource_request_t *newreq)
562 {
563     ICO_DBG("CicoSCResourceManager::releaseSoundResource Enter");
564
565     bool curchg = false;
566     CompSoundResourceRequest comp(newreq);
567     for (int i = 0; i < (int)m_curSoundResReq.size(); ++i) {
568          if (NULL == m_curSoundResReq[i]) {
569             continue;
570          }
571
572          if (true == comp(m_curSoundResReq[i])) {
573             ico_syc_mrp_release_sound_resource(m_curSoundResReq[i]);
574             delResourceRequest(newreq);
575             delResourceRequest(m_curSoundResReq[i]);
576             m_curSoundResReq[i] = NULL;
577             curchg = true;
578             break;
579          }
580     }
581
582     // If current request is not changed, 
583     // remove the request from the waiting queue.
584     if (false == curchg) {
585        resource_request_t *req = popSoundResReq(newreq);
586         if (NULL != req) {
587             ico_syc_mrp_release_sound_resource(req);
588             delResourceRequest(req);
589             req = NULL;
590         }
591         delResourceRequest(newreq);
592         ICO_DBG("CicoSCResourceManager::releaseSoundResource Leave");
593         return;
594     }
595
596     map<int, list<resource_request_t*> >::iterator itr;
597     itr = m_soundReqQueue.begin();
598     for (; itr != m_soundReqQueue.end(); ++itr) {
599         list<resource_request_t*>::iterator itr2;
600         itr2 = itr->second.begin();
601         for (; itr2 !=  itr->second.end(); ++itr2) {
602             int type = (*itr2)->resid & RESID_TYPE_MASK;
603             bool active = m_policyMgr->acquireSoundResource(type,
604                                                             (*itr2)->soundzoneid,
605                                                             (*itr2)->prio);
606             if (true == active) {
607                 resource_request_t* req = *itr2;
608                 ICO_DBG("Dequeue waiting sound request queue "
609                         "zone=%d req=0x%08x", itr->first, *itr2);
610                 itr->second.erase(itr2);
611                 updateSoundResource(req);
612                 break;
613             }
614         }
615     }
616
617     ICO_DBG("CicoSCResourceManager::releaseSoundResource Leave");
618 }
619
620 bool
621 CicoSCResourceManager::acquireInputResource(resource_request_t *newreq)
622 {
623     ICO_DBG("CicoSCResourceManager::acquireInputResource Enter");
624
625     resource_request_t *req = popInputResReq(newreq);
626     if (NULL == req) {
627         req = newreq;
628     }
629
630     // is change zone?
631     CompInputResourceRequest comp(req);
632     if (true == comp(m_curInputResReq[req->input])) {
633         ICO_DBG("already acquired appid=%s pid=%d input=0x%08X",
634                 req->appid, req->pid, req->input);
635         ICO_DBG("CicoSCResourceManager::acquireInputResource Leave(true)");
636         // free new request
637         delResourceRequest(newreq);
638         return true;
639     }
640
641     bool state = m_policyMgr->acquireInputResource(req->input, req->prio);
642     if (true == state) {
643         updateInputResource(req);
644     }
645     else {
646         ICO_DBG("Enqueue waiting input request queue input=%d req=0x%08x",
647                 req->input, req);
648         m_inputReqQueue[req->input].push_front(req);
649     }
650
651     ICO_DBG("CicoSCResourceManager::acquireInputResource Leave");
652     return true;
653 }
654
655 void
656 CicoSCResourceManager::releaseInputResource(resource_request_t *newreq)
657 {
658     bool curchg = false;
659     CompInputResourceRequest comp(newreq);
660     for (int i = 0; i < (int)m_curInputResReq.size(); ++i) {
661          if (NULL == m_curInputResReq[i]) {
662             continue;
663          }
664
665          if (true == comp(m_curInputResReq[i])) {
666             if (NULL != m_inputCtrl) {
667                 m_inputCtrl->delInputApp(m_curInputResReq[i]->appid,
668                                          m_curInputResReq[i]->device,
669                                          m_curInputResReq[i]->input);
670             }
671             delResourceRequest(newreq);
672             delResourceRequest(m_curInputResReq[i]);
673             m_curInputResReq[i] = NULL;
674             curchg = true;
675             break;
676          }
677     }
678
679     // If current request is not changed, 
680     // remove the request from the waiting queue.
681     if (false == curchg) {
682        resource_request_t *req = popInputResReq(newreq);
683         if (NULL != req) {
684             delResourceRequest(req);
685             req = NULL;
686         }
687         delResourceRequest(newreq);
688         ICO_DBG("CicoSCResourceManager::releaseInputResource Leave");
689         return;
690     }
691
692     map<int, list<resource_request_t*> >::iterator itr;
693     itr = m_inputReqQueue.begin();
694     for (; itr != m_inputReqQueue.end(); ++itr) {
695         list<resource_request_t*>::iterator itr2;
696         itr2 = itr->second.begin();
697         for (; itr2 !=  itr->second.end(); ++itr2) {
698             bool active = m_policyMgr->acquireInputResource((*itr2)->input,
699                                                             (*itr2)->prio);
700             if (true == active) {
701                 resource_request_t* req = *itr2;
702                 ICO_DBG("Dequeue waiting input request queue "
703                         "input=%d req=0x%08x", itr->first, *itr2);
704                 itr->second.erase(itr2);
705                 updateInputResource(req);
706                 break;
707             }
708         }
709     }
710 }
711
712 resource_request_t *
713 CicoSCResourceManager::newResourceRequest(int resid,
714                                           int reqtype,
715                                           const CicoSCCommand &cmd)
716 {
717     ICO_DBG("CicoSCResourceManager::newResourceRequest Enter");
718
719     resource_request_t *req = NULL;
720     req = (resource_request_t*)calloc(1, sizeof(resource_request_t));
721     CicoSCCmdResCtrlOpt *opt = (CicoSCCmdResCtrlOpt*)cmd.opt;
722     CicoSCSystemConfig *systemConfig = CicoSCSystemConfig::getInstance();
723
724     req->reqtype = reqtype;
725
726     CicoSCLifeCycleController *lifeCycle =
727         CicoSCLifeCycleController::getInstance();
728     const CicoSCAilItems* ailItem = lifeCycle->findAIL(cmd.appid);
729     if (NULL != ailItem) {
730         req->category = ailItem->m_categoryID;
731         req->appkind = ailItem->m_kindID;
732     }
733
734     req->prio = req->category;
735  
736     req->released = 0;
737
738     /* set resource id */
739     req->resid = RESID_TYPE_BASIC;
740     if (1 == opt->type) {
741         req->resid = RESID_TYPE_INTERRUPT;
742     }
743     req->resid |= resid;
744
745     req->resid |= RESID_CMD_RELEASE;
746     if (MSG_CMD_ACQUIRE_RES == cmd.cmdid) {
747         req->resid |= RESID_CMD_ACQUIRE;
748     }
749
750     /* set application information */
751     req->appid = strdup(cmd.appid.c_str());
752     req->pid   = cmd.pid;
753     req->state = RES_STATE_WAITING;
754
755     if (resid == RESID_KIND_DISPLAY) {
756         req->dispzone   = strdup(opt->dispzone.c_str());
757         req->dispzoneid = systemConfig->getDizplayZoneIdbyFullName(req->dispzone);
758         req->winname    = strdup(opt->winname.c_str());
759         req->surfaceid  = opt->surfaceid;
760         req->id         = opt->surfaceid;;
761         req->animation  = strdup(opt->animation.c_str());
762         req->animationTime = opt->animationTime;
763     }
764     else if (resid == RESID_KIND_SOUND) {
765         req->soundzone   = strdup(opt->soundzone.c_str());
766         req->soundzoneid = systemConfig->getSoundZoneIdbyFullName(req->soundzone);
767         ICO_DBG("req->soundzoneid=%d", req->soundzoneid);
768         req->soundname   = strdup(opt->soundname.c_str());
769         req->soundid     = opt->soundid;
770         req->soundadjust = opt->adjust;
771         req->id          = opt->soundid;
772     }
773     else if (resid == RESID_KIND_INPUT) {
774         req->device = strdup(opt->device.c_str());
775         req->input  = opt->input;
776         req->id     = opt->input;
777     }
778
779     ICO_DBG("CicoSCResourceManager::newResourceRequest Leave");
780     return req;
781 }
782
783 void
784 CicoSCResourceManager::delResourceRequest(resource_request_t *req)
785 {
786     if (NULL == req) return;
787
788     if (NULL != req->appid)     free(req->appid);
789     if (NULL != req->dispzone)  free(req->dispzone);
790     if (NULL != req->winname)   free(req->winname);
791     if (NULL != req->animation) free(req->animation);
792     if (NULL != req->soundzone) free(req->soundzone);
793     if (NULL != req->soundname) free(req->soundname);
794     if (NULL != req->device)    free(req->device);
795  
796     free(req);
797 }
798
799 void
800 CicoSCResourceManager::enforceSound(unsigned short state,
801                                     resource_request_t *req,
802                                     void *user_data)
803 {
804     ICO_DBG("CicoSCResourceManager::enforceSound Enter");
805     /* NOP */
806     ICO_DBG("CicoSCResourceManager::enforceSound Leave");
807 }
808             
809 // receive changed state
810 void
811 CicoSCResourceManager::receiveChangedState(int state)
812 {
813     ICO_DBG("CicoSCResourceManager::receiveChangedState Enter"
814             "(state=%d)", state);
815
816     if ((STID_DRVREGULATION_ON == state)||
817         (STID_DRVREGULATION_OFF == state)) {
818
819         updateDisplayResourceRegulation(state);
820         updateSoundResourceRegulation(state);
821         updateInputResourceRegulation(state);
822 #if 0
823         bool curchg = false;
824         for (int i = 0; i < (int)m_curDispResReq.size(); ++i) {
825              if (NULL == m_curDispResReq[i]) {
826                 continue;
827              }
828              int type = m_curDispResReq[i]->resid & RESID_TYPE_MASK;
829              bool active = m_policyMgr->acquireDisplayResource(type,
830                                                              m_curDispResReq[i]->dispzoneid,
831                                                              m_curDispResReq[i]->prio);
832             if (false == active) {
833                 if (NULL != m_winCtrl) {
834                     // hide current window
835                     m_winCtrl->hide(m_curDispResReq[i]->surfaceid, NULL, 0);
836                 }
837                 // state change to waiting
838                 m_curDispResReq[i]->state = RES_STATE_WAITING;
839                 // enqueue request
840                 ICO_DBG("Enqueue waiting display request queue "
841                         "zone=%d req=0x%08x", i, m_curDispResReq[i]);
842                 m_dispReqQueue[i].push_front(m_curDispResReq[i]);
843                 // initialize current zone request
844                 m_curDispResReq[i] = NULL;
845                 curchg = true;
846              }
847         }
848
849         if ((false == curchg) && (STID_DRVREGULATION_ON == state)) {
850             ICO_DBG("CicoSCResourceManager::receiveChangedState Leave");
851             return;
852         }
853
854         map<int, list<resource_request_t*> >::iterator itr;
855         itr = m_dispReqQueue.begin();
856         for (; itr != m_dispReqQueue.end(); ++itr) {
857             list<resource_request_t*>::iterator itr2;
858             itr2 = itr->second.begin();
859             for (; itr2 !=  itr->second.end(); ++itr2) {
860                 if (NULL != m_curDispResReq[itr->first]) {
861                     continue;
862                 }
863                 int type = (*itr2)->resid & RESID_TYPE_MASK;
864                 bool active = m_policyMgr->acquireDisplayResource(type,
865                                                              (*itr2)->dispzoneid,
866                                                              (*itr2)->prio);
867                 if (true == active) {
868                     resource_request_t* req = *itr2;
869                     ICO_DBG("Dequeue waiting display request queue "
870                             "zone=%d req=0x%08x", itr->first, *itr2);
871                     itr->second.erase(itr2);
872                     updateDisplayResource(req);
873                     break;
874                 }
875             }
876         }
877 #endif
878     }
879
880     ICO_DBG("CicoSCResourceManager::receiveChangedState Leave");
881 }
882
883 void
884 CicoSCResourceManager::updateDisplayResource(resource_request_t *req)
885 {
886     ICO_DBG("CicoSCResourceManager::updateDisplayResource Enter"
887             "(req=0x%08x)", req);
888     for (int i = 0; i < (int)m_curDispResReq.size(); ++i) {
889         ICO_DBG("zoneid=%d active=%d current=0x%08x",
890                 i, m_policyMgr->getDispZoneState(i), m_curDispResReq[i]);
891
892         if (NULL == m_curDispResReq[i]) {
893             continue;
894         }
895
896         if ((i == req->dispzoneid) ||
897             (false == m_policyMgr->getDispZoneState(i))) {
898
899             if (NULL != m_winCtrl) {
900                 // hide current window
901                 m_winCtrl->hide(m_curDispResReq[i]->surfaceid, NULL, 0);
902             }
903             // state change to waiting
904             m_curDispResReq[i]->state = RES_STATE_WAITING;
905             // enqueue request
906             ICO_DBG("Enqueue waiting display request queue "
907                     "zone=%d req=0x%08x", i, m_curDispResReq[i]);
908             m_dispReqQueue[i].push_front(m_curDispResReq[i]);
909             // initialize current zone request
910             m_curDispResReq[i] = NULL;
911         }
912     }
913
914     if (req != m_curDispResReq[req->dispzoneid]) {
915         if (NULL != m_winCtrl) {
916             // show request window
917             m_winCtrl->show(req->surfaceid, req->animation,req->animationTime);
918         }
919         // state change to acquired
920         req->state = RES_STATE_ACQUIRED;
921         // update current zone request
922         m_curDispResReq[req->dispzoneid] = req;
923     }
924     ICO_DBG("CicoSCResourceManager::updateDisplayResource Leave");
925 }
926
927 void
928 CicoSCResourceManager::updateSoundResource(resource_request_t *req)
929 {
930     ICO_DBG("CicoSCResourceManager::updateSoundResource Enter"
931             "(req=0x%08x)", req);
932     for (int i = 0; i < (int)m_curSoundResReq.size(); ++i) {
933         ICO_DBG("zoneid=%d active=%d current=0x%08x",
934                 i, m_policyMgr->getSoundZoneState(i), m_curSoundResReq[i]);
935
936         if (NULL == m_curSoundResReq[i]) {
937             continue;
938         }
939
940         if ((i == req->soundzoneid) ||
941             (false == m_policyMgr->getSoundZoneState(i))) {
942
943             // state change to waiting
944             m_curSoundResReq[i]->state = RES_STATE_WAITING;
945             // enqueue request
946             ICO_DBG("Enqueue waiting sound request queue "
947                     "zone=%d req=0x%08x", i, m_curSoundResReq[i]);
948             m_soundReqQueue[i].push_front(m_curSoundResReq[i]);
949             // initialize current zone request
950             m_curSoundResReq[i] = NULL;
951         }
952     }
953
954     if (req != m_curSoundResReq[req->soundzoneid]) {
955         ico_syc_mrp_acquire_sound_resource(req);
956         ico_syc_mrp_active_app(req->appid);
957
958         // state change to acquired
959         req->state = RES_STATE_ACQUIRED;
960         // update current zone request
961         m_curSoundResReq[req->soundzoneid] = req;
962     }
963     ICO_DBG("CicoSCResourceManager::updateSoundResource Leave");
964 }
965
966 void
967 CicoSCResourceManager::updateInputResource(resource_request_t *req)
968 {
969     ICO_DBG("CicoSCResourceManager::updateInputResource Enter"
970             "(req=0x%08x)", req);
971     for (int i = 0; i < (int)m_curInputResReq.size(); ++i) {
972         ICO_DBG("input=%d active=%d current=0x%08x",
973                 i, m_policyMgr->getInputState(i), m_curInputResReq[i]);
974
975         if (NULL == m_curInputResReq[i]) {
976             continue;
977         }
978
979         if ((i == req->input) ||
980             (false == m_policyMgr->getInputState(i))) {
981
982             if (NULL != m_inputCtrl) {
983                 // add input control
984                 m_inputCtrl->delInputApp(req->appid, req->device, req->input);
985             }
986
987             // state change to waiting
988             m_curInputResReq[i]->state = RES_STATE_WAITING;
989             // enqueue request
990             ICO_DBG("Enqueue waiting input request queue "
991                     "zone=%d req=0x%08x", i, m_curInputResReq[i]);
992             m_inputReqQueue[i].push_front(m_curInputResReq[i]);
993             // initialize current zone request
994             m_curInputResReq[i] = NULL;
995         }
996     }
997
998     if (req != m_curInputResReq[req->input]) {
999         // delete input control
1000         m_inputCtrl->addInputApp(req->appid, req->device, req->input, 0, 0);
1001         // state change to acquired
1002         req->state = RES_STATE_ACQUIRED;
1003         // update current zone request
1004         m_curInputResReq[req->input] = req;
1005     }
1006     ICO_DBG("CicoSCResourceManager::updateInputResource Leave");
1007 }
1008
1009 void
1010 CicoSCResourceManager::updateDisplayResourceRegulation(int state)
1011 {
1012     ICO_DBG("CicoSCResourceManager::updateDisplayResourceRegulation Enter"
1013             "(state=%d)", state);
1014
1015     bool curchg = false;
1016     for (int i = 0; i < (int)m_curDispResReq.size(); ++i) {
1017         resource_request_t *current = m_curDispResReq[i];
1018         if (NULL == current) {
1019             continue;
1020         }
1021
1022         int type = current->resid & RESID_TYPE_MASK;
1023         bool active = false;
1024         active = m_policyMgr->acquireDisplayResource(type,
1025                                                      current->dispzoneid,
1026                                                      current->prio);
1027         if (false == active) {
1028             if (NULL != m_winCtrl) {
1029                 // hide current window
1030                 m_winCtrl->hide(current->surfaceid, NULL, 0);
1031             }
1032             // state change to waiting
1033             current->state = RES_STATE_WAITING;
1034             // enqueue request
1035             ICO_DBG("Enqueue waiting display request queue "
1036                     "zone=%d req=0x%08x", i, current);
1037             m_dispReqQueue[i].push_front(current);
1038             // initialize current zone request
1039             m_curDispResReq[i] = NULL;
1040             curchg = true;
1041          }
1042     }
1043
1044     if ((false == curchg) && (STID_DRVREGULATION_ON == state)) {
1045         ICO_DBG("CicoSCResourceManager::updateDisplayResourceRegulation Leave");
1046         return;
1047     }
1048
1049     map<int, list<resource_request_t*> >::iterator itr;
1050     itr = m_dispReqQueue.begin();
1051     for (; itr != m_dispReqQueue.end(); ++itr) {
1052         if (NULL != m_curDispResReq[itr->first]) {
1053             continue;
1054         }
1055
1056         list<resource_request_t*>::iterator itr2;
1057         itr2 = itr->second.begin();
1058         for (; itr2 !=  itr->second.end(); ++itr2) {
1059             int type = (*itr2)->resid & RESID_TYPE_MASK;
1060             bool active = false;
1061             active = m_policyMgr->acquireDisplayResource(type,
1062                                                          (*itr2)->dispzoneid,
1063                                                          (*itr2)->prio);
1064             if (true == active) {
1065                 resource_request_t* req = *itr2;
1066                 ICO_DBG("Dequeue waiting display request queue "
1067                         "zone=%d req=0x%08x", itr->first, *itr2);
1068                 itr->second.erase(itr2);
1069                 updateDisplayResource(req);
1070                 break;
1071             }
1072         }
1073     }
1074
1075     ICO_DBG("CicoSCResourceManager::updateDisplayResourceRegulation Leave");
1076 }
1077
1078 void
1079 CicoSCResourceManager::updateSoundResourceRegulation(int state)
1080 {
1081     ICO_DBG("CicoSCResourceManager::updateSoundResourceRegulation Enter"
1082             "(state=%d)", state);
1083
1084     bool curchg = false;
1085     for (int i = 0; i < (int)m_curSoundResReq.size(); ++i) {
1086         resource_request_t *current = m_curSoundResReq[i];
1087         if (NULL == current) {
1088             continue;
1089         }
1090
1091         int type = current->resid & RESID_TYPE_MASK;
1092         bool active = false;
1093         active = m_policyMgr->acquireSoundResource(type,
1094                                                    current->soundzoneid,
1095                                                    current->prio);
1096         if (false == active) {
1097             // state change to waiting
1098             current->state = RES_STATE_WAITING;
1099             // enqueue request
1100             ICO_DBG("Enqueue waiting sound request queue "
1101                     "zone=%d req=0x%08x", i, current);
1102             m_soundReqQueue[i].push_front(current);
1103             // initialize current zone request
1104             m_curSoundResReq[i] = NULL;
1105             curchg = true;
1106          }
1107     }
1108
1109     if ((false == curchg) && (STID_DRVREGULATION_ON == state)) {
1110         ICO_DBG("CicoSCResourceManager::updateSoundResourceRegulation Leave");
1111         return;
1112     }
1113
1114     map<int, list<resource_request_t*> >::iterator itr;
1115     itr = m_soundReqQueue.begin();
1116     for (; itr != m_soundReqQueue.end(); ++itr) {
1117         if (NULL != m_curSoundResReq[itr->first]) {
1118             continue;
1119         }
1120
1121         list<resource_request_t*>::iterator itr2;
1122         itr2 = itr->second.begin();
1123         for (; itr2 !=  itr->second.end(); ++itr2) {
1124             int type = (*itr2)->resid & RESID_TYPE_MASK;
1125             bool active = false;
1126             active = m_policyMgr->acquireSoundResource(type,
1127                                                        (*itr2)->soundzoneid,
1128                                                        (*itr2)->prio);
1129             if (true == active) {
1130                 resource_request_t* req = *itr2;
1131                 ICO_DBG("Dequeue waiting sound request queue "
1132                         "zone=%d req=0x%08x", itr->first, *itr2);
1133                 itr->second.erase(itr2);
1134                 updateSoundResource(req);
1135                 break;
1136             }
1137         }
1138     }
1139
1140     ICO_DBG("CicoSCResourceManager::updateSoundResourceRegulation Leave");
1141 }
1142
1143 void
1144 CicoSCResourceManager::updateInputResourceRegulation(int state)
1145 {
1146     ICO_DBG("CicoSCResourceManager::updateInputResourceRegulation Enter"
1147             "(state=%d)", state);
1148
1149     bool curchg = false;
1150     for (int i = 0; i < (int)m_curInputResReq.size(); ++i) {
1151         resource_request_t *current = m_curInputResReq[i];
1152         if (NULL == current) {
1153             continue;
1154         }
1155
1156         bool active = false;
1157         active = m_policyMgr->acquireInputResource(current->input,
1158                                                    current->prio);
1159         if (false == active) {
1160             if (NULL != m_inputCtrl) {
1161                 // hide current window
1162                 m_inputCtrl->delInputApp(current->appid,
1163                                          current->device,
1164                                          current->input);
1165             }
1166             // state change to waiting
1167             current->state = RES_STATE_WAITING;
1168             // enqueue request
1169             ICO_DBG("Enqueue waiting input request queue "
1170                     "zone=%d req=0x%08x", i, current);
1171             m_inputReqQueue[i].push_front(current);
1172             // initialize current zone request
1173             m_curInputResReq[i] = NULL;
1174             curchg = true;
1175          }
1176     }
1177
1178     if ((false == curchg) && (STID_DRVREGULATION_ON == state)) {
1179         ICO_DBG("CicoSCResourceManager::updateInputResourceRegulation Leave");
1180         return;
1181     }
1182
1183     map<int, list<resource_request_t*> >::iterator itr;
1184     itr = m_inputReqQueue.begin();
1185     for (; itr != m_inputReqQueue.end(); ++itr) {
1186         if (NULL != m_curInputResReq[itr->first]) {
1187             continue;
1188         }
1189
1190         list<resource_request_t*>::iterator itr2;
1191         itr2 = itr->second.begin();
1192         for (; itr2 !=  itr->second.end(); ++itr2) {
1193             bool active = false;
1194             active = m_policyMgr->acquireInputResource((*itr2)->input,
1195                                                        (*itr2)->prio);
1196             if (true == active) {
1197                 resource_request_t* req = *itr2;
1198                 ICO_DBG("Dequeue waiting input request queue "
1199                         "zone=%d req=0x%08x", itr->first, *itr2);
1200                 itr->second.erase(itr2);
1201                 updateInputResource(req);
1202                 break;
1203             }
1204         }
1205     }
1206
1207     ICO_DBG("CicoSCResourceManager::updateDisplayResourceRegulation Leave");
1208 }
1209 // vim:set expandtab ts=4 sw=4: