Bug fix: TIVI-1996.
[profile/ivi/ico-uxf-homescreen.git] / lib / system-controller / CicoSCPolicyManager.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   CicoSCPolicyManager.cpp
13  *
14  *  @brief  This file implementation of CicoSCPolicyManager class
15  */
16 //==========================================================================
17
18 #include <string>
19 using namespace std;
20
21 #include "CicoSCPolicyManager.h"
22 #include "CicoStateMachine.h"
23 #include "CicoState.h"
24 #include "CicoHistoryState.h"
25 #include "CicoStateMachineCreator.h"
26 #include "CicoSCPolicyDef.h"
27 #include "CicoSCResourceManager.h"
28 #include "CicoLog.h"
29 #include "ico_syc_error.h"
30 #include "CicoSCServer.h"
31 #include "CicoSCMessage.h"
32 #include "ico_syc_msg_cmd_def.h"
33 #include "ico_syc_type.h"
34 #include "CicoSCCommonDef.h"
35
36 //==========================================================================
37 //  define
38 //==========================================================================
39
40 // Defines of D-Bus target.
41 #define DBUS_SERVICE    "org.automotive.message.broker"
42 #define DBUS_INTERFACE  "org.freedesktop.DBus.Properties"
43 #define DBUS_METHOD     "Get"
44
45 // Defines of maximum number.
46 #define AMB_MAX_VHCLINFO    10  /**< maximum number of vehicle info */
47
48 // Enumerations of Vehicle information key.
49 typedef enum {
50     AMB_VHCL_SPEED  = 1,  /**< Vehicle speed */
51     AMB_SHIFT_POSITION,   /**< Shift position */
52     AMB_LIGHT_LEFT,       /**< Light left(Turn left) */
53     AMB_LIGHT_RIGHT,      /**< Light right(Turn right) */
54     AMB_NIGHT_MODE,       /**< Night mode */
55     AMB_MAX_INFO          /**< Maximum number of type */
56 } _amb_vhcl_key_e;
57
58 // 
59 typedef struct _vehicle_info_property_t {
60     int     key;        /* Vehicle Information key */
61     const char    *property;  /* D-Bus property name     */
62     const char    *path;      /* D-Bus path name         */
63     const char    *interface; /* D-Bus interface name    */
64 } vhcl_info_prop_t;
65
66 // structure of Vehicle information data.
67 typedef struct _vehicle_info_data {
68     int             key;    /* Vehicle Information key */
69     DBusPendingCall *pending;
70     E_DBus_Signal_Handler *handler;
71     int             request;
72     double          val;
73 } _vhcldata_t;
74
75 _vhcldata_t vhcl_data[AMB_MAX_INFO];
76
77 //*========================================================================
78 //  global variable
79 //========================================================================
80
81 static const vhcl_info_prop_t apf_vhcl_info[] = {
82     {
83         AMB_VHCL_SPEED,
84         "VehicleSpeed",
85         "/org/automotive/runningstatus/VehicleSpeed",
86         "org.automotive.VehicleSpeed"
87     },
88     {
89         AMB_SHIFT_POSITION,
90         "ShiftPosition",
91         "/org/automotive/runningstatus/Transmission",
92         "org.automotive.Transmission"
93     },
94 #if 0   // use LightStatus
95 /* use LightStatus, because AMB not support access of TurnSignal by D-Bus   */
96     {
97         ICO_SYC_VEHICLEINFO_TURN_SIGNAL,
98         "TurnSignal",
99         "/org/automotive/runningstatus/TurnSignal",
100         "org.automotive.TurnSignal"
101     },
102 #else   // use LightStatus
103     {
104         AMB_LIGHT_LEFT,
105         "LeftTurn",
106         "/org/automotive/runningstatus/LightStatus",
107         "org.automotive.LightStatus"
108     },
109     {
110         AMB_LIGHT_RIGHT,
111         "RightTurn",
112         "/org/automotive/runningstatus/LightStatus",
113         "org.automotive.LightStatus"
114     },
115 #endif   // use LightStatus
116     {
117         AMB_NIGHT_MODE,
118         "NightMode",
119         "/org/automotive/custom/NightMode",
120         "org.automotive.NightMode"
121     },
122     { 0, "\0", "\0", "\0" }
123 };
124
125 //--------------------------------------------------------------------------
126 /**
127  *  @brief  default constructor
128  */
129 //--------------------------------------------------------------------------
130 CicoSCPolicyManager::CicoSCPolicyManager(CicoSCResourceManager* resourceMgr)
131     : m_initialized(false),
132       m_dbusConnection(NULL),
133       m_ecoreTimer(NULL),
134       m_stateMachine(NULL),
135       m_resourceMgr(resourceMgr)
136 {
137 }
138
139 //--------------------------------------------------------------------------
140 /**
141  *  @brief  destructor
142  */
143 //--------------------------------------------------------------------------
144 CicoSCPolicyManager::~CicoSCPolicyManager()
145 {
146 }
147
148 //--------------------------------------------------------------------------
149 /**
150  *  @brief  initialize policy manager
151  */
152 //--------------------------------------------------------------------------
153 int
154 CicoSCPolicyManager::initialize(void)
155 {
156     ICO_DBG("CicoSCPolicyManager::initialize Enter");
157
158     int ret = ICO_SYC_EOK;
159     ret = initAMB();
160     if (ICO_SYC_EOK != ret) {
161         return ret;
162     }
163
164     ret = initStateMachine();
165     if (ICO_SYC_EOK != ret) {
166         return ret;
167     }
168
169     ICO_DBG("CicoSCPolicyManager::initialize Leave");
170     return ret;
171 }
172   
173 //--------------------------------------------------------------------------
174 /**
175  *  @brief  terminate policy manager
176  */
177 //--------------------------------------------------------------------------
178 void
179 CicoSCPolicyManager::terminate(void)
180 {
181     int idx = 0;
182
183     ICO_DBG("CicoSCPolicyManager::terminate Enter");
184
185     for (idx = 0; vhcl_data[idx].key; idx++) {
186         if (vhcl_data[idx].handler != NULL) {
187             e_dbus_signal_handler_del(m_dbusConnection, 
188                                       vhcl_data[idx].handler);
189         }
190     }
191
192     ICO_DBG("CicoSCPolicyManager::terminate Leave");
193 }
194
195 //--------------------------------------------------------------------------
196 /**
197  *  @brief  initialize amb connection
198  */
199 //--------------------------------------------------------------------------
200 int
201 CicoSCPolicyManager::initAMB(void)
202 {
203     ICO_DBG("CicoSCPolicyManager::initAMB Enter");
204
205     int ret = 0;
206     int idx;
207     char signalname[64];
208
209     if (true == m_initialized) {
210         ICO_DBG("CicoSCPolicyManager::initAMB Leave(EOK)");
211         return ICO_SYC_EOK;
212     }
213
214     /* Zero clear vhcl_data */
215     memset(vhcl_data, 0, sizeof(vhcl_data));
216
217     e_dbus_init();
218
219     /* Get D-Bus connection */
220     m_dbusConnection = e_dbus_bus_get(DBUS_BUS_SYSTEM);
221     if (! m_dbusConnection) {
222         ICO_ERR("dbus_bus_get failed.");
223         ICO_ERR("CicoSCPolicyManager::initAMB Leave(EIO)");
224         return ICO_SYC_EIO;
225     }
226
227     /* receive propertychanged request to AMB */
228     for (idx = 0; apf_vhcl_info[idx].key; idx++) {
229         memset(signalname, 0, sizeof(signalname));
230         /* set vehicleinfo set key */
231         vhcl_data[idx].key = apf_vhcl_info[idx].key;
232
233         if (apf_vhcl_info[idx].path[0] == 0) {
234             /* currently not support this vehicle information */
235             continue;
236         }
237
238         strcpy(signalname, apf_vhcl_info[idx].property);
239         strcat(signalname, "Changed");
240         vhcl_data[idx].handler = e_dbus_signal_handler_add(m_dbusConnection, 
241                                                            DBUS_SERVICE, NULL,
242                                                            apf_vhcl_info[idx].interface,
243                                                            signalname, 
244                                                            AMBpropertyChanged, 
245                                                            (void*)&vhcl_data[idx].key);
246
247     }
248
249     /* recv response from AMB timer start */
250     ret = ecore_init();
251     if (ret == 0) {
252         ICO_ERR("ecore_init");
253         ICO_ERR("CicoSCPolicyManager::initAMB Leave(ENOSYS)");
254         return ICO_SYC_ENOSYS;
255     }
256
257     m_ecoreTimer = ecore_timer_add(0.2, //TODO
258                                    CicoSCPolicyManager::ecoreTimerCB, this);
259     if (! m_ecoreTimer)    {
260         ICO_ERR("ecore_timer_add failed.");
261         ICO_ERR("CicoSCPolicyManager::initAMB Leave(ENOSYS)");
262         return ICO_SYC_ENOSYS;
263     }
264
265     m_initialized = true;
266
267     ICO_DBG("CicoSCPolicyManager::initAMB Leave(EOK)");
268     return ICO_SYC_EOK;
269 }
270
271 //--------------------------------------------------------------------------
272 /**
273  *  @brief  send AMB request
274  */
275 //--------------------------------------------------------------------------
276 int
277 CicoSCPolicyManager::sendAMBRequest(void)
278 {
279 #if 0
280 //    ICO_DBG("CicoSCPolicyManager::sendAMBRequest Enter");
281
282     DBusMessage *dbus_message = NULL;
283     int     idx;
284     int     ret = ICO_SYC_EOK;
285
286     for (idx = 0; apf_vhcl_info[idx].key; idx++) {
287         /* set vehicle info key */
288         vhcl_data[idx].key = apf_vhcl_info[idx].key;
289
290         /* status is pending ? */
291         if (vhcl_data[idx].pending)  {
292             ICO_WRN("(%s) not complete", apf_vhcl_info[idx].property);
293             continue;
294         }
295
296         if (apf_vhcl_info[idx].path[0] == 0) {
297             /* currently not support this vehicle information */
298             continue;
299         }
300
301         /* Create send message */
302         dbus_message = dbus_message_new_method_call(DBUS_SERVICE,
303                                                     apf_vhcl_info[idx].path,
304                                                     DBUS_INTERFACE,
305                                                     DBUS_METHOD);
306         if (! dbus_message) {
307             ICO_ERR("dbus_message_new_method_call");
308             ret = ICO_SYC_EIO;
309         }
310         /* Set parameters into message */
311         else if (! dbus_message_append_args(dbus_message,
312                                             DBUS_TYPE_STRING,
313                                             &apf_vhcl_info[idx].interface,
314                                             DBUS_TYPE_STRING,
315                                             &apf_vhcl_info[idx].property,
316                                             DBUS_TYPE_INVALID)) {
317             ICO_ERR("dbus_message_append_args");
318             ret = ICO_SYC_EIO;
319         }
320         /* Set destination */
321         else if (! dbus_message_set_destination(dbus_message, 
322                                                 DBUS_SERVICE)) {
323             ICO_ERR("dbus_message_set_destination");
324             ret = ICO_SYC_EIO;
325         }
326         /* Send message */
327         else if (! dbus_connection_send_with_reply(m_dbusConnection, 
328                                                     dbus_message,
329                                                     &vhcl_data[idx].pending,
330                                                     200)) {
331             ICO_ERR("dbus_connection_send");
332             vhcl_data[idx].pending = NULL;
333             ret = ICO_SYC_EIO;
334         }
335         else {
336             //ICO_DBG("REQUEST req (%s)", apf_vhcl_info[idx].property);
337         }
338
339         if (dbus_message) {
340             /* Release message */
341             dbus_message_unref(dbus_message);
342         }
343     }
344
345     /* dispatch if data queue exist */
346     do  {
347         dbus_connection_read_write_dispatch(m_dbusConnection, 0);
348     } while (dbus_connection_get_dispatch_status(m_dbusConnection)
349              == DBUS_DISPATCH_DATA_REMAINS);
350
351     //ICO_DBG("CicoSCPolicyManager::sendAMBRequest Leave");
352     return ret;
353 #endif
354     return 0;
355 }
356
357 //--------------------------------------------------------------------------
358 /**
359  *  @brief  get vehicle information
360  */
361 //--------------------------------------------------------------------------
362 int
363 CicoSCPolicyManager::getVehicleInfo(void)
364 {
365     #if 0
366     DBusMessage *dbus_message = NULL;
367     DBusMessageIter iter_head;
368     DBusMessageIter iter;
369     int         idx;
370     char        type;
371     int32_t     i32;
372     int16_t     i16;
373     uint32_t    u32;
374     uint16_t    u16;
375     dbus_bool_t b;
376     uint8_t     u8;
377     double      d64;
378
379     /* dispatch if data queue exist */
380     do {
381         dbus_connection_read_write_dispatch(m_dbusConnection, 0);
382     } while (dbus_connection_get_dispatch_status(m_dbusConnection)
383              == DBUS_DISPATCH_DATA_REMAINS);
384
385     /* analyze reply data */
386     for (idx = 0; apf_vhcl_info[idx].key; idx++) {
387         if (! vhcl_data[idx].pending)    {
388             continue;
389         }
390         if (! dbus_pending_call_get_completed(vhcl_data[idx].pending))   {
391             //ICO_WRN("(%s) NOT complete", apf_vhcl_info[idx].property);
392             continue;
393         }
394
395         dbus_message = dbus_pending_call_steal_reply(vhcl_data[idx].pending);
396         if (! dbus_message) {
397             //ICO_WRN("(%s) NO reply", apf_vhcl_info[idx].property);
398             continue;
399         }
400
401         if (dbus_message_get_type(dbus_message) == DBUS_MESSAGE_TYPE_ERROR) {
402             dbus_message_unref(dbus_message);
403             dbus_pending_call_cancel(vhcl_data[idx].pending);
404             vhcl_data[idx].pending = NULL;
405             //ICO_ERR("(%s) reply error", apf_vhcl_info[idx].property);
406             continue;
407         }
408
409         dbus_message_iter_init(dbus_message, &iter_head);
410         dbus_message_iter_recurse(&iter_head, &iter);
411
412         type = dbus_message_iter_get_arg_type(&iter);
413         switch (type)   {
414         case DBUS_TYPE_INT32:
415             dbus_message_iter_get_basic(&iter, &i32);
416             vhcl_data[idx].val = (double)i32;
417             break;
418         case DBUS_TYPE_INT16:
419             dbus_message_iter_get_basic(&iter, &i16);
420             vhcl_data[idx].val = (double)i16;
421             break;
422         case DBUS_TYPE_UINT32:
423             dbus_message_iter_get_basic(&iter, &u32);
424             break;
425         case DBUS_TYPE_UINT16:
426             dbus_message_iter_get_basic(&iter, &u16);
427             vhcl_data[idx].val = (double)u16;
428             break;
429         case DBUS_TYPE_BOOLEAN:
430             dbus_message_iter_get_basic(&iter, &b);
431             if (b)      vhcl_data[idx].val = (double)1.0;
432             else        vhcl_data[idx].val = (double)0.0;
433             break;
434         case DBUS_TYPE_BYTE:
435             dbus_message_iter_get_basic(&iter, &u8);
436             vhcl_data[idx].val = (double)u8;
437             break;
438         case DBUS_TYPE_DOUBLE:
439             dbus_message_iter_get_basic(&iter, &d64);
440             vhcl_data[idx].val = (double)d64;
441             break;
442         default:
443             ICO_ERR("(%s) illegal data type(0x%02x)",
444                     apf_vhcl_info[idx].property, ((int)type) & 0x0ff);
445             break;
446         }
447         //ICO_DBG("REQUEST ans (%s) = %.2f",
448         //        apf_vhcl_info[idx].property, vhcl_data[idx].val);
449
450         /* free message and pending */
451         dbus_message_unref(dbus_message);
452         dbus_pending_call_cancel(vhcl_data[idx].pending);
453         vhcl_data[idx].pending = NULL;
454     };
455
456     return ICO_SYC_EOK;
457 #endif
458     return ICO_SYC_EOK;
459 }
460
461 //--------------------------------------------------------------------------
462 /**
463  *  @brief  ecore timer callback
464  */
465 //--------------------------------------------------------------------------
466 Eina_Bool
467 CicoSCPolicyManager::ecoreTimerCB(void *user_data)
468 {
469     CicoSCPolicyManager *policyMgr =
470         static_cast<CicoSCPolicyManager*>(user_data);
471     policyMgr->recvAMBVehicleInfo();
472
473     return ECORE_CALLBACK_RENEW;
474 }
475 //--------------------------------------------------------------------------
476 /**
477  *  @brief  receive AMB vehicle information
478  */
479 //--------------------------------------------------------------------------
480 void
481 CicoSCPolicyManager::AMBpropertyChanged(void *data, DBusMessage *msg) 
482 {
483     DBusMessageIter iter, variant;
484     int idx;
485     char        type;
486     int32_t     i32;
487     int16_t     i16;
488     uint32_t    u32;
489     uint16_t    u16;
490     dbus_bool_t b;
491     uint8_t     u8;
492     double      d64;
493
494     int key;
495     key = *((int *)data);
496
497     if (!msg || !dbus_message_iter_init(msg, &iter)) {
498         ICO_ERR("received illegal message.");
499         return;
500     }
501
502     for (idx = 0; vhcl_data[idx].key; idx++) {
503         if (vhcl_data[idx].key == key) {
504             break;
505         }
506     }
507     if (idx == AMB_MAX_INFO) {
508         return;
509     }
510
511     dbus_message_iter_recurse(&iter, &variant);
512     type = dbus_message_iter_get_arg_type(&variant);
513     switch (type)   {
514     case DBUS_TYPE_INT32:
515         dbus_message_iter_get_basic(&variant, &i32);
516         vhcl_data[idx].val = (double)i32;
517         break;
518     case DBUS_TYPE_INT16:
519         dbus_message_iter_get_basic(&variant, &i16);
520         vhcl_data[idx].val = (double)i16;
521         break;
522     case DBUS_TYPE_UINT32:
523         dbus_message_iter_get_basic(&variant, &u32);
524         break;
525     case DBUS_TYPE_UINT16:
526         dbus_message_iter_get_basic(&variant, &u16);
527         vhcl_data[idx].val = (double)u16;
528         break;
529     case DBUS_TYPE_BOOLEAN:
530         dbus_message_iter_get_basic(&variant, &b);
531         if (b)      vhcl_data[idx].val = (double)1.0;
532         else        vhcl_data[idx].val = (double)0.0;
533         break;
534     case DBUS_TYPE_BYTE:
535         dbus_message_iter_get_basic(&variant, &u8);
536         vhcl_data[idx].val = (double)u8;
537         break;
538     case DBUS_TYPE_DOUBLE:
539         dbus_message_iter_get_basic(&variant, &d64);
540         vhcl_data[idx].val = (double)d64;
541         break;
542     default:
543         ICO_ERR("(%s) illegal data type(0x%02x)",
544                 apf_vhcl_info[idx].property, ((int)type) & 0x0ff);
545         break;
546     }
547 }
548
549 //--------------------------------------------------------------------------
550 /**
551  *  @brief  receive AMB vehicle information
552  */
553 //--------------------------------------------------------------------------
554 void
555 CicoSCPolicyManager::recvAMBVehicleInfo(void)
556 {
557 //    ICO_DBG("CicoSCPolicyManager::recvAMBVehicleInfo Enter");
558
559     int idx = 0;
560     int key = 0;
561     bool chgCamera     = false;
562     bool chgRegulation = false;
563     bool chgNightMode  = false;
564
565     //getVehicleInfo();
566
567     /* get vehicle info values  */
568     for (idx = 0; idx < AMB_MAX_VHCLINFO; idx++)   {
569         if (vhcl_data[idx].key == 0) break;
570         key = vhcl_data[idx].key;
571         switch (key) {
572         case AMB_VHCL_SPEED:
573             (void)sendSMEvent(EVID_VELOCTY, (int)vhcl_data[idx].val);
574             if (true == sendSMEvent(EVID_DRVREGULATION)) {
575                 chgRegulation = true;
576             }
577             break;
578         case AMB_SHIFT_POSITION:
579             (void)sendSMEvent(EVID_SHIFTPOS, (int)vhcl_data[idx].val);
580             if (true == sendSMEvent(EVID_CAMERA)) {
581                 chgCamera = true;
582             }
583             break;
584         case AMB_LIGHT_LEFT:
585             if (0.0 == vhcl_data[idx].val) {
586                 (void)sendSMEvent(EVID_TURN_OFF);
587             }
588             else {
589                 (void)sendSMEvent(EVID_TURN_LEFT);
590             }
591             if (true == sendSMEvent(EVID_CAMERA)) {
592                 chgCamera = true;
593             }
594             break;
595         case AMB_LIGHT_RIGHT:
596             if (0.0 == vhcl_data[idx].val) {
597                 (void)sendSMEvent(EVID_TURN_OFF);
598             }
599             else {
600                 (void)sendSMEvent(EVID_TURN_LEFT);
601             }
602             if (true == sendSMEvent(EVID_CAMERA)) {
603                 chgCamera = true;
604             }
605             break;
606         case AMB_NIGHT_MODE:
607             chgNightMode = sendSMEvent(EVID_NIGHTMODE, (int)vhcl_data[idx].val);
608             break;
609         default:
610             ICO_WRN("not such key (%d)", key);
611             break;
612         }
613     }
614
615     if (true == chgRegulation) {
616         ICO_DBG("true == chgRegulation");
617         // notify changed state to resource manager
618         CicoState* state =
619                 (CicoState*)m_stateMachine->getState(STID_DRVREGULATION);
620         if (NULL != state) {
621             vector<const CicoState*> currents;
622             state->getCurrentState(currents, CicoStateCore::ELvlTop);
623             if (0 != currents.size()) {
624                 ICO_DBG("current=%s", currents[0]->getName().c_str());
625                 notifyChangedState(currents[0]->getValue());
626             }
627         }
628
629         // Notify regulation changed state
630         CicoSCMessage *message = new CicoSCMessage();
631         message->addRootObject("command", MSG_CMD_NOTIFY_CHANGED_STATE);
632         message->addArgObject(MSG_PRMKEY_STATEID, ICO_SYC_STATE_REGULATION);
633         if (true == m_policyStates[STID_DRVREGULATION_ON]->isActive()) {
634             message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_ON);
635         }
636         else {
637             message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_OFF);
638         }
639         CicoSCServer::getInstance()->sendMessageToHomeScreen(message);
640     }
641
642     if (true == chgCamera) {
643         ICO_DBG("true == chgCamera");
644         // notify changed state to resource manager
645         CicoState* state = (CicoState*)m_stateMachine->getState(STID_CAMERA);
646         if (NULL != state) {
647             vector<const CicoState*> currents;
648             state->getCurrentState(currents, CicoStateCore::ELvlTop);
649             if (0 != currents.size()) {
650                 ICO_DBG("current=%s", currents[0]->getName().c_str());
651                 notifyChangedState(currents[0]->getValue());
652             }
653         }
654     }
655
656     if (true == chgNightMode) {
657         ICO_DBG("true == chgNightMode");
658         // Notify NightMode changed state
659         CicoSCMessage *message = new CicoSCMessage();
660         message->addRootObject("command", MSG_CMD_NOTIFY_CHANGED_STATE);
661         message->addArgObject(MSG_PRMKEY_STATEID, ICO_SYC_STATE_NIGHTMODE);
662         if (true == m_policyStates[STID_NIGHTMODE_ON]->isActive()) {
663             message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_ON);
664         }
665         else {
666             message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_OFF);
667         }
668         CicoSCServer::getInstance()->sendMessageToHomeScreen(message);
669     }
670         
671     /* send request to AMB */
672     //sendAMBRequest();
673
674 //    ICO_DBG("CicoSCPolicyManager::recvAMBVehicleInfo Leave");
675 }
676
677 //--------------------------------------------------------------------------
678 /**
679  *  @brief  get policy states
680  */
681 //--------------------------------------------------------------------------
682 const std::map<int, const CicoState*>&
683 CicoSCPolicyManager::getPolicyStates(void)
684 {
685     return m_policyStates;
686 }
687
688 //--------------------------------------------------------------------------
689 /**
690  *  @brief  initialize state machine
691  */
692 //--------------------------------------------------------------------------
693 int
694 CicoSCPolicyManager::initStateMachine(void)
695 {
696     ICO_DBG("CicoSCPolicyManager::initStateMachine Enter");
697
698     CicoStateMachineCreator creator;
699
700     //TODO
701     m_stateMachine = creator.createFile("/usr/apps/org.tizen.ico.system-controller/res/config/policy.json");
702     if (NULL == m_stateMachine) {
703         ICO_ERR("CicoStateMachineCreator::createFile failed.(reason:%s)",
704                 creator.getError().c_str());
705         return ICO_SYC_ENOSYS;
706     }
707
708     int ret = m_stateMachine->start();
709     if (ret == 0) {
710         ICO_ERR("CicoStateMachine::start failed.");
711         return ICO_SYC_ENOSYS;
712     }
713
714     vector<CicoStateCore*> objects;
715     m_stateMachine->getObjects(objects);
716     vector<CicoStateCore*>::iterator itr;
717     itr = objects.begin();
718     for (; itr != objects.end(); ++itr) {
719         const CicoState* state = static_cast<const CicoState*>(*itr);
720         m_policyStates[state->getValue()] = state;
721 #if 1   //-- { debug dump
722         ICO_DBG("State=[%-45s] Active=%s",
723                 state->getName().c_str(),
724                 state->isActive() ? "true" : "false");
725 #endif  //-- } debug dump
726     }
727
728     {
729         std::map<int, const CicoState*>::iterator itr;
730         itr = m_policyStates.find(STID_DISPLAY0_ZONE1);
731         m_dispZoneStates[1] = itr != m_policyStates.end() ? itr->second : NULL;
732         itr = m_policyStates.find(STID_DISPLAY0_ZONE2);
733         m_dispZoneStates[2] = itr != m_policyStates.end() ? itr->second : NULL;
734         itr = m_policyStates.find(STID_DISPLAY0_ZONE3);
735         m_dispZoneStates[3] = itr != m_policyStates.end() ? itr->second : NULL;
736         itr = m_policyStates.find(STID_DISPLAY0_ZONE4);
737         m_dispZoneStates[4] = itr != m_policyStates.end() ? itr->second : NULL;
738         itr = m_policyStates.find(STID_DISPLAY0_ZONE5);
739         m_dispZoneStates[5] = itr != m_policyStates.end() ? itr->second : NULL;
740         itr = m_policyStates.find(STID_DISPLAY0_ZONE6);
741         m_dispZoneStates[6] = itr != m_policyStates.end() ? itr->second : NULL;
742         itr = m_policyStates.find(STID_DISPLAY0_ZONE7);
743         m_dispZoneStates[7] = itr != m_policyStates.end() ? itr->second : NULL;
744         itr = m_policyStates.find(STID_DISPLAY0_ZONE8);
745         m_dispZoneStates[8] = itr != m_policyStates.end() ? itr->second : NULL;
746         itr = m_policyStates.find(STID_DISPLAY0_ZONE9);
747         m_dispZoneStates[9] = itr != m_policyStates.end() ? itr->second : NULL;
748         itr = m_policyStates.find(STID_DISPLAY0_ZONE10);
749         m_dispZoneStates[10] = itr != m_policyStates.end() ? itr->second : NULL;
750         itr = m_policyStates.find(STID_DISPLAY0_ZONE11);
751         m_dispZoneStates[11] = itr != m_policyStates.end() ? itr->second : NULL;
752         itr = m_policyStates.find(STID_DISPLAY0_ZONE12);
753         m_dispZoneStates[12] = itr != m_policyStates.end() ? itr->second : NULL;
754         itr = m_policyStates.find(STID_DISPLAY0_ZONE13);
755         m_dispZoneStates[13] = itr != m_policyStates.end() ? itr->second : NULL;
756         itr = m_policyStates.find(STID_DISPLAY0_ZONE14);
757         m_dispZoneStates[14] = itr != m_policyStates.end() ? itr->second : NULL;
758         itr = m_policyStates.find(STID_DISPLAY0_ZONE15);
759         m_dispZoneStates[15] = itr != m_policyStates.end() ? itr->second : NULL;
760         itr = m_policyStates.find(STID_DISPLAY0_ZONE16);
761         m_dispZoneStates[16] = itr != m_policyStates.end() ? itr->second : NULL;
762         itr = m_policyStates.find(STID_DISPLAY0_ZONE17);
763         m_dispZoneStates[17] = itr != m_policyStates.end() ? itr->second : NULL;
764         itr = m_policyStates.find(STID_DISPLAY0_ZONE18);
765         m_dispZoneStates[18] = itr != m_policyStates.end() ? itr->second : NULL;
766         itr = m_policyStates.find(STID_DISPLAY0_ZONE19);
767         m_dispZoneStates[19] = itr != m_policyStates.end() ? itr->second : NULL;
768         itr = m_policyStates.find(STID_DISPLAY0_ZONE20);
769         m_dispZoneStates[20] = itr != m_policyStates.end() ? itr->second : NULL;
770
771         itr = m_policyStates.find(STID_DISPLAY1_ZONE1);
772         m_dispZoneStates[21] = itr != m_policyStates.end() ? itr->second : NULL;
773         itr = m_policyStates.find(STID_DISPLAY1_ZONE2);
774         m_dispZoneStates[22] = itr != m_policyStates.end() ? itr->second : NULL;
775         itr = m_policyStates.find(STID_DISPLAY1_ZONE3);
776         m_dispZoneStates[23] = itr != m_policyStates.end() ? itr->second : NULL;
777         itr = m_policyStates.find(STID_DISPLAY1_ZONE4);
778         m_dispZoneStates[24] = itr != m_policyStates.end() ? itr->second : NULL;
779         itr = m_policyStates.find(STID_DISPLAY1_ZONE5);
780         m_dispZoneStates[25] = itr != m_policyStates.end() ? itr->second : NULL;
781         itr = m_policyStates.find(STID_DISPLAY1_ZONE6);
782         m_dispZoneStates[26] = itr != m_policyStates.end() ? itr->second : NULL;
783         itr = m_policyStates.find(STID_DISPLAY1_ZONE7);
784         m_dispZoneStates[27] = itr != m_policyStates.end() ? itr->second : NULL;
785         itr = m_policyStates.find(STID_DISPLAY1_ZONE8);
786         m_dispZoneStates[28] = itr != m_policyStates.end() ? itr->second : NULL;
787         itr = m_policyStates.find(STID_DISPLAY1_ZONE9);
788         m_dispZoneStates[29] = itr != m_policyStates.end() ? itr->second : NULL;
789         itr = m_policyStates.find(STID_DISPLAY1_ZONE10);
790         m_dispZoneStates[30] = itr != m_policyStates.end() ? itr->second : NULL;
791         itr = m_policyStates.find(STID_DISPLAY1_ZONE11);
792         m_dispZoneStates[31] = itr != m_policyStates.end() ? itr->second : NULL;
793         itr = m_policyStates.find(STID_DISPLAY1_ZONE12);
794         m_dispZoneStates[32] = itr != m_policyStates.end() ? itr->second : NULL;
795         itr = m_policyStates.find(STID_DISPLAY1_ZONE13);
796         m_dispZoneStates[33] = itr != m_policyStates.end() ? itr->second : NULL;
797         itr = m_policyStates.find(STID_DISPLAY1_ZONE14);
798         m_dispZoneStates[34] = itr != m_policyStates.end() ? itr->second : NULL;
799         itr = m_policyStates.find(STID_DISPLAY1_ZONE15);
800         m_dispZoneStates[35] = itr != m_policyStates.end() ? itr->second : NULL;
801         itr = m_policyStates.find(STID_DISPLAY1_ZONE16);
802         m_dispZoneStates[36] = itr != m_policyStates.end() ? itr->second : NULL;
803         itr = m_policyStates.find(STID_DISPLAY1_ZONE17);
804         m_dispZoneStates[37] = itr != m_policyStates.end() ? itr->second : NULL;
805         itr = m_policyStates.find(STID_DISPLAY1_ZONE18);
806         m_dispZoneStates[38] = itr != m_policyStates.end() ? itr->second : NULL;
807         itr = m_policyStates.find(STID_DISPLAY1_ZONE19);
808         m_dispZoneStates[39] = itr != m_policyStates.end() ? itr->second : NULL;
809         itr = m_policyStates.find(STID_DISPLAY1_ZONE20);
810         m_dispZoneStates[40] = itr != m_policyStates.end() ? itr->second : NULL;
811     }
812
813     m_soundZoneStates.push_back(NULL);
814     m_soundZoneStates.push_back(m_policyStates[STID_SOUND_ZONE1]);
815     m_soundZoneStates.push_back(m_policyStates[STID_SOUND_ZONE2]);
816     m_soundZoneStates.push_back(m_policyStates[STID_SOUND_ZONE3]);
817
818     m_inputStates.push_back(NULL);
819     m_inputStates.push_back(m_policyStates[STID_INPUT1_USING]);
820     m_inputStates.push_back(m_policyStates[STID_INPUT2_USING]);
821
822     ICO_DBG("CicoSCPolicyManager::initStateMachine Leave");
823     return ICO_SYC_EOK;
824 }
825
826 //--------------------------------------------------------------------------
827 /**
828  *  @brief  query whether a state transition
829  *
830  *  @param [in] event_id    trigger event id
831  *
832  *  @return true on test success, false on test failed
833  */
834 //--------------------------------------------------------------------------
835 bool
836 CicoSCPolicyManager::testSMEvent(unsigned short event_id)
837 {
838     CicoEvent event(event_id);
839     return m_stateMachine->eventTest(event);
840 }
841
842 //--------------------------------------------------------------------------
843 /**
844  *  @brief  query whether a state transition
845  *
846  *  @param [in] event_id    trigger event id
847  *  @param [in] value       trigger optional integer value
848  *
849  *  @return true on test success, false on test failed
850  */
851 //--------------------------------------------------------------------------
852 bool
853 CicoSCPolicyManager::testSMEvent(unsigned short event_id, int value)
854 {
855     CicoEvent event(event_id, value);
856     return m_stateMachine->eventTest(event);
857 }
858
859 //--------------------------------------------------------------------------
860 /**
861  *  @brief  send tigger event
862  *
863  *  @param [in] event_id    trigger event id
864  *
865  *  @return true on state transition, false on not state transition
866  */
867 //--------------------------------------------------------------------------
868 bool
869 CicoSCPolicyManager::sendSMEvent(unsigned short event_id)
870 {
871     CicoEvent event(event_id);
872     return m_stateMachine->eventEntry(event);
873 }
874
875 //--------------------------------------------------------------------------
876 /**
877  *  @brief  send tigger event
878  *
879  *  @param [in] event_id    trigger event id
880  *  @param [in] value       trigger optional integer value
881  *
882  *  @return true on state transition, false on not state transition
883  */
884 //--------------------------------------------------------------------------
885 bool
886 CicoSCPolicyManager::sendSMEvent(unsigned short event_id, int value)
887 {
888     CicoEvent event(event_id, value);
889     return m_stateMachine->eventEntry(event);
890 }
891
892 bool
893 CicoSCPolicyManager::acquireDisplayResource(int type, int zoneid, int priority)
894 {
895     ICO_DBG("CicoSCPolicyManager::acquireDisplayResource Enter"
896             "(type=0x%08X zoneid=%d priority=%d)", type, zoneid, priority);
897
898     bool chg = false;
899
900     if (RESID_TYPE_BASIC == type) {
901         bool zoneChg = testSMEvent(EVID_DISPLAY_ZONE_ACQUIRE, zoneid);
902         bool cateChg = testSMEvent(EVID_DISPLAY0_CATEGORY, priority);
903         ICO_DBG("zoneChg=%d cateChg=%d", zoneChg, cateChg);
904         if ((true == zoneChg) && (true == cateChg)) {
905             sendSMEvent(EVID_DISPLAY_ZONE_ACQUIRE, zoneid);
906             sendSMEvent(EVID_DISPLAY0_CATEGORY, priority);
907             chg = true;
908         }
909 #if 0   //-- { debug dump
910         else {
911             std::map<int, const CicoState*>::iterator itr;
912             itr = m_policyStates.begin();
913             for (; itr != m_policyStates.end(); ++itr) {
914                 ICO_DBG("State=[%-45s] Active=%s",
915                         itr->second->getName().c_str(),
916                         itr->second->isActive() ? "true" : "false");
917             }
918         }
919 #endif  //-- } debug dump
920     }
921     else if (RESID_TYPE_INTERRUPT == type) {
922         if (1 == zoneid) {
923             chg = sendSMEvent(EVID_INTTERPUT_D0_Z1, priority);
924         }
925         else if (2 == zoneid) {
926             chg = sendSMEvent(EVID_INTTERPUT_D0_Z2, priority);
927         }
928         else if (3 == zoneid) {
929             chg = sendSMEvent(EVID_INTTERPUT_D0_Z3, priority);
930         }
931     }
932     else if (RESID_TYPE_ONSCREEN == type) {
933         chg = sendSMEvent(EVID_ONSCREEN, priority);
934     }
935     ICO_DBG("CicoSCPolicyManager::acquireDisplayResource Leave(%s)",
936             chg ? "true" : "false");
937     return chg;
938 }
939
940 bool
941 CicoSCPolicyManager::releaseDisplayResource(int zoneid, int priority)
942 {
943     return sendSMEvent(EVID_DISPLAY_ZONE_RELEASE, zoneid);
944 }
945
946 bool
947 CicoSCPolicyManager::acquireSoundResource(int type, int zoneid, int priority)
948 {
949     ICO_DBG("CicoSCPolicyManager::acquireSoundResource Enter"
950             "(type=0x%08X zoneid=%d priority=%d)", type, zoneid, priority);
951
952     bool chg = false;
953
954     if (RESID_TYPE_BASIC == type) {
955         bool zoneChg = testSMEvent(EVID_SOUND_ZONE, zoneid);
956         bool cateChg = testSMEvent(EVID_SOUND_CATEGORY, priority);
957         ICO_DBG("zoneChg=%d cateChg=%d", zoneChg, cateChg);
958         if ((true == zoneChg) && (true == cateChg)) {
959             sendSMEvent(EVID_SOUND_ZONE, zoneid);
960             sendSMEvent(EVID_SOUND_CATEGORY, priority);
961             chg = true;
962         }
963     }
964     else if (RESID_TYPE_INTERRUPT == type) {
965         if (1 == zoneid) {
966             chg = sendSMEvent(EVID_INTTERPUT_S_Z1, priority);
967         }
968         else if (2 == zoneid) {
969             chg = sendSMEvent(EVID_INTTERPUT_S_Z2, priority);
970         }
971         else if (3 == zoneid) {
972             chg = sendSMEvent(EVID_INTTERPUT_S_Z3, priority);
973         }
974     }
975
976     ICO_DBG("CicoSCPolicyManager::acquireSoundResource Leave(%s)",
977             chg ? "true" : "false");
978     return chg;
979 }
980
981 bool
982 CicoSCPolicyManager::releaseSoundResource(int type, int zoneid)
983 {
984     ICO_DBG("CicoSCPolicyManager::acquireSoundResource Enter"
985             "(type=%d zoneid=%d)", type, zoneid);
986
987     bool chg = false;
988     if (RESID_TYPE_BASIC == type) {
989         chg = sendSMEvent(EVID_SOUND_ZONE_NOUSE);
990         chg = sendSMEvent(EVID_SOUND_CATEGORY_UNKNOWN);
991     }
992     else if (RESID_TYPE_INTERRUPT == type) {
993         if (1 == zoneid) {
994             chg = sendSMEvent(EVID_INTTERPUT_S_Z1_NOOUTPUT);
995         }
996         else if (2 == zoneid) {
997             chg = sendSMEvent(EVID_INTTERPUT_S_Z2_NOOUTPUT);
998         }
999         else if (3 == zoneid) {
1000             chg = sendSMEvent(EVID_INTTERPUT_S_Z3_NOOUTPUT);
1001         }
1002     }
1003
1004     ICO_DBG("CicoSCPolicyManager::acquireSoundResource Leave(%s)",
1005             chg ? "true" : "false");
1006
1007     return true;
1008 }
1009
1010 bool
1011 CicoSCPolicyManager::acquireInputResource(int input, int priority)
1012 {
1013     ICO_DBG("CicoSCPolicyManager::acquireInputResource Enter"
1014             "input=%d priority=%d", input, priority);
1015
1016     bool chg = false;
1017
1018     if (1 == input) {
1019         chg = sendSMEvent(EVID_INPUT1_ACQUIRE, input);
1020     }
1021     else if (2 == input) {
1022         chg = sendSMEvent(EVID_INPUT2_ACQUIRE, input);
1023     }
1024
1025     ICO_DBG("CicoSCPolicyManager::acquireInputResource Leave(%s)",
1026             chg ? "true" : "false");
1027     return chg;
1028 }
1029
1030 bool
1031 CicoSCPolicyManager::releaseInputResource(int input)
1032 {
1033     if (1 == input) {
1034         (void)sendSMEvent(EVID_INPUT1_RELEASE, input);
1035     }
1036     else if (2 == input) {
1037         (void)sendSMEvent(EVID_INPUT2_RELEASE, input);
1038     }
1039     return true;
1040 }
1041
1042 void
1043 CicoSCPolicyManager::notifyChangedState(int state)
1044 {
1045     m_resourceMgr->receiveChangedState(state);
1046 }
1047
1048 bool
1049 CicoSCPolicyManager::getDispZoneState(int zoneid)
1050 {
1051     if (0 >= zoneid) {
1052         return false;
1053     }
1054
1055     // find state instance
1056     std::map<int, const CicoState*>::iterator itr;
1057     itr = m_dispZoneStates.find(zoneid);
1058     if (itr == m_dispZoneStates.end()) {
1059         return false;
1060     }
1061
1062     // if state instance is null
1063     if (NULL == itr->second) {
1064         return false;
1065     }
1066         
1067     return itr->second->isActive();
1068 }
1069
1070 bool
1071 CicoSCPolicyManager::getSoundZoneState(int zoneid) const
1072 {
1073     if ((0 < zoneid) && ((int)m_soundZoneStates.size()-1 > zoneid)) {
1074         return m_soundZoneStates[zoneid]->isActive();
1075     }
1076     return false;
1077 }
1078
1079 bool
1080 CicoSCPolicyManager::getInputState(int input) const
1081 {
1082     if ((0 < input) && ((int)m_inputStates.size()-1 > input)) {
1083         return m_inputStates[input]->isActive();
1084     }
1085     return false;
1086 }
1087
1088 bool
1089 CicoSCPolicyManager::getRegulation(void)
1090 {
1091     return m_policyStates[STID_DRVREGULATION_ON]->isActive();
1092 }
1093
1094 bool
1095 CicoSCPolicyManager::isExistDisplayZoneOwer(int zoneid)
1096 {
1097     if ((zoneid >= ICO_DISPLAY0_ZONEID_MIN) &&
1098         (zoneid <= ICO_DISPLAY0_ZONEID_MAX)) {
1099         return !m_policyStates[STID_DISPLAY0_NOOWER]->isActive();
1100     }
1101     if ((zoneid >= ICO_DISPLAY1_ZONEID_MIN) &&
1102         (zoneid <= ICO_DISPLAY1_ZONEID_MAX)) {
1103         return !m_policyStates[STID_DISPLAY1_NOOWER]->isActive();
1104     }
1105     return true;
1106 }
1107
1108 //--------------------------------------------------------------------------
1109 /**
1110  *  @brief  notify connected
1111  */
1112 //--------------------------------------------------------------------------
1113 void
1114 CicoSCPolicyManager::notifyConnected(const string & appid)
1115 {
1116     // Notify regulation changed state
1117     CicoSCMessage *message = new CicoSCMessage();
1118     message->addRootObject("command", MSG_CMD_NOTIFY_CHANGED_STATE);
1119     message->addArgObject(MSG_PRMKEY_STATEID, ICO_SYC_STATE_REGULATION);
1120     if (true == m_policyStates[STID_DRVREGULATION_ON]->isActive()) {
1121         message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_ON);
1122     }
1123     else {
1124         message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_OFF);
1125     }
1126     CicoSCServer::getInstance()->sendMessageToHomeScreen(message);
1127
1128     // Notify NightMode changed state
1129     message = new CicoSCMessage();
1130     message->addRootObject("command", MSG_CMD_NOTIFY_CHANGED_STATE);
1131     message->addArgObject(MSG_PRMKEY_STATEID, ICO_SYC_STATE_NIGHTMODE);
1132     if (true == m_policyStates[STID_NIGHTMODE_ON]->isActive()) {
1133         message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_ON);
1134     }
1135     else {
1136         message->addArgObject(MSG_PRMKEY_STATE, ICO_SYC_STATE_OFF);
1137     }
1138     CicoSCServer::getInstance()->sendMessageToHomeScreen(message);
1139 }
1140 // vim:set expandtab ts=4 sw=4: