7575#define HDMICECSINK_NUMBER_TV_ADDR 2
7676#define HDMICECSINK_UPDATE_POWER_STATUS_INTERVA_MS (60 * 1000 )
7777#define HDMISINK_ARC_START_STOP_MAX_WAIT_MS 4000
78+ #define HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS 500
7879
7980
8081#define SAD_FMT_CODE_AC3 2
@@ -174,9 +175,7 @@ static std::vector<DeviceFeatures> deviceFeatures = {DEVICE_FEATURES_TV};
174175
175176#define API_VERSION_NUMBER_MAJOR 1
176177#define API_VERSION_NUMBER_MINOR 3
177- #define API_VERSION_NUMBER_PATCH 7
178-
179- using PowerState = WPEFramework::Exchange::IPowerManager::PowerState;
178+ #define API_VERSION_NUMBER_PATCH 10
180179
181180namespace WPEFramework
182181{
@@ -710,7 +709,10 @@ namespace WPEFramework
710709 m_currentActiveSource = -1 ;
711710 m_isHdmiInConnected = false ;
712711 hdmiCecAudioDeviceConnected = false ;
713- m_audioDevicePowerStatusRequested = false ;
712+ m_isAudioStatusInfoUpdated = false ;
713+ m_audioStatusReceived = false ;
714+ m_audioStatusTimerStarted = false ;
715+ m_audioDevicePowerStatusRequested = false ;
714716 m_pollNextState = POLL_THREAD_STATE_NONE;
715717 m_pollThreadState = POLL_THREAD_STATE_NONE;
716718 m_video_latency = DEFAULT_VIDEO_LATENCY;
@@ -745,22 +747,23 @@ namespace WPEFramework
745747 Register (HDMICECSINK_METHOD_SET_LATENCY_INFO, &HdmiCecSink::setLatencyInfoWrapper, this );
746748 logicalAddressDeviceType = " None" ;
747749 logicalAddress = 0xFF ;
750+ // load persistence setting
751+ loadSettings ();
752+
753+ int err;
754+ dsHdmiInGetNumberOfInputsParam_t hdmiInput;
755+ InitializeIARM ();
748756 m_sendKeyEventThreadExit = false ;
749757 m_sendKeyEventThread = std::thread (threadSendKeyEvent);
750758
751759 m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED;
752760 m_semSignaltoArcRoutingThread.acquire ();
753761 m_arcRoutingThread = std::thread (threadArcRouting);
754762
755-
763+ m_audioStatusDetectionTimer.connect ( std::bind ( &HdmiCecSink::audioStatusTimerFunction, this ) );
764+ m_audioStatusDetectionTimer.setSingleShot (true );
756765 m_arcStartStopTimer.connect ( std::bind ( &HdmiCecSink::arcStartStopTimerFunction, this ) );
757766 m_arcStartStopTimer.setSingleShot (true );
758- // load persistence setting
759- loadSettings ();
760-
761- int err;
762- dsHdmiInGetNumberOfInputsParam_t hdmiInput;
763- InitializeIARM ();
764767 // get power state:
765768 uint32_t res = Core::ERROR_GENERAL;
766769 PowerState pwrStateCur = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN;
@@ -812,7 +815,7 @@ namespace WPEFramework
812815 }
813816 }
814817 getCecVersion ();
815- getHdmiArcPortID ( );
818+ LOGINFO ( " HdmiCecSink plugin Initialize completed \n " );
816819 return (std::string ());
817820
818821 }
@@ -1147,6 +1150,18 @@ namespace WPEFramework
11471150 JsonObject params;
11481151 if (!HdmiCecSink::_instance)
11491152 return ;
1153+ if (m_audioStatusTimerStarted)
1154+ {
1155+ m_audioStatusReceived = true ;
1156+ m_isAudioStatusInfoUpdated = true ;
1157+ m_audioStatusTimerStarted = false ;
1158+ if (m_audioStatusDetectionTimer.isActive ())
1159+ {
1160+ LOGINFO (" AudioStatus received from the Audio Device and the timer is still active. So stopping the timer!\n " );
1161+ m_audioStatusDetectionTimer.stop ();
1162+ }
1163+ LOGINFO (" AudioStatus received from the Audio Device. Updating the AudioStatus info! m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d " , m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted);
1164+ }
11501165 LOGINFO (" Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n " ,GetOpName (msg.opCode ()),msg.status .getAudioMuteStatus (),msg.status .toString ().c_str (),msg.status .getAudioVolume ());
11511166 params[" muteStatus" ] = msg.status .getAudioMuteStatus ();
11521167 params[" volumeLevel" ] = msg.status .getAudioVolume ();
@@ -2477,7 +2492,14 @@ namespace WPEFramework
24772492 params[" status" ] = string (" success" );
24782493 params[" audioDeviceConnected" ] = string (" false" );
24792494 hdmiCecAudioDeviceConnected = false ;
2480- sendNotify (eventString[HDMICECSINK_EVENT_AUDIO_DEVICE_CONNECTED_STATUS], params);
2495+ if (m_audioStatusDetectionTimer.isActive ()){
2496+ m_audioStatusDetectionTimer.stop ();
2497+ }
2498+ m_isAudioStatusInfoUpdated = false ;
2499+ m_audioStatusReceived = false ;
2500+ m_audioStatusTimerStarted = false ;
2501+ LOGINFO (" Audio device removed, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d " , m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted);
2502+ sendNotify (eventString[HDMICECSINK_EVENT_AUDIO_DEVICE_CONNECTED_STATUS], params)
24812503 }
24822504
24832505 _instance->deviceList [logicalAddress].m_isRequestRetry = 0 ;
@@ -2720,29 +2742,44 @@ namespace WPEFramework
27202742 _instance->allocateLogicalAddress (DeviceType::TV);
27212743 if ( _instance->m_logicalAddressAllocated != LogicalAddress::UNREGISTERED)
27222744 {
2723- logicalAddress = LogicalAddress (_instance->m_logicalAddressAllocated );
2724- LibCCEC::getInstance ().addLogicalAddress (logicalAddress);
2725- _instance->smConnection ->setSource (logicalAddress);
2726- _instance->m_numberOfDevices = 0 ;
2727- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_deviceType = DeviceType::TV;
2728- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_isDevicePresent = true ;
2729- _instance->deviceList [_instance->m_logicalAddressAllocated ].update (physical_addr);
2730- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_cecVersion = Version::V_1_4;
2731- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_vendorID = appVendorId;
2732- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_powerStatus = PowerStatus (powerState);
2733- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_currentLanguage = defaultLanguage;
2734- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_osdName = osdName.toString ().c_str ();
2735- if (cecVersion == 2.0 ) {
2736- _instance->deviceList [_instance->m_logicalAddressAllocated ].m_cecVersion = Version::V_2_0;
2737- _instance->smConnection ->sendTo (LogicalAddress (LogicalAddress::BROADCAST),
2738- MessageEncoder ().encode (ReportFeatures (Version::V_2_0,allDevicetype,rcProfile,deviceFeatures)), 500 );
2739- }
2740- _instance->smConnection ->addFrameListener (_instance->msgFrameListener );
2741- _instance->smConnection ->sendTo (LogicalAddress (LogicalAddress::BROADCAST),
2742- MessageEncoder ().encode (ReportPhysicalAddress (physical_addr, _instance->deviceList [_instance->m_logicalAddressAllocated ].m_deviceType )), 100 );
2743-
2744- _instance->m_sleepTime = 0 ;
2745- _instance->m_pollThreadState = POLL_THREAD_STATE_PING;
2745+ try {
2746+
2747+ logicalAddress = LogicalAddress (_instance->m_logicalAddressAllocated );
2748+ LibCCEC::getInstance ().addLogicalAddress (logicalAddress);
2749+ _instance->smConnection ->setSource (logicalAddress);
2750+ _instance->m_numberOfDevices = 0 ;
2751+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_deviceType = DeviceType::TV;
2752+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_isDevicePresent = true ;
2753+ _instance->deviceList [_instance->m_logicalAddressAllocated ].update (physical_addr);
2754+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_cecVersion = Version::V_1_4;
2755+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_vendorID = appVendorId;
2756+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_powerStatus = PowerStatus (powerState);
2757+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_currentLanguage = defaultLanguage;
2758+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_osdName = osdName.toString ().c_str ();
2759+ if (cecVersion == 2.0 ) {
2760+ _instance->deviceList [_instance->m_logicalAddressAllocated ].m_cecVersion = Version::V_2_0;
2761+ _instance->smConnection ->sendTo (LogicalAddress (LogicalAddress::BROADCAST),
2762+ MessageEncoder ().encode (ReportFeatures (Version::V_2_0,allDevicetype,rcProfile,deviceFeatures)), 500 );
2763+ }
2764+ _instance->smConnection ->addFrameListener (_instance->msgFrameListener );
2765+ _instance->smConnection ->sendTo (LogicalAddress (LogicalAddress::BROADCAST),
2766+ MessageEncoder ().encode (ReportPhysicalAddress (physical_addr, _instance->deviceList [_instance->m_logicalAddressAllocated ].m_deviceType )), 100 );
2767+
2768+ _instance->m_sleepTime = 0 ;
2769+ _instance->m_pollThreadState = POLL_THREAD_STATE_PING;
2770+ }
2771+ catch (InvalidStateException &e){
2772+ LOGWARN (" InvalidStateException caught while allocated logical address. %s" , e.what ());
2773+ _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT;
2774+ }
2775+ catch (IOException &e){
2776+ LOGWARN (" IOException caught while allocated logical address. %s" , e.what ());
2777+ _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT;
2778+ }
2779+ catch (...){
2780+ LOGWARN (" Exception caught while allocated logical address." );
2781+ _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT;
2782+ }
27462783 }
27472784 else
27482785 {
@@ -2978,9 +3015,14 @@ namespace WPEFramework
29783015 {
29793016 LibCCEC::getInstance ().init (" HdmiCecSink" );
29803017 }
2981- catch (const std::exception& e)
2982- {
2983- LOGWARN (" CEC exception caught from LibCCEC::getInstance().init()" );
3018+ catch (InvalidStateException &e){
3019+ LOGWARN (" InvalidStateException caught in LibCCEC::init %s" , e.what ());
3020+ }
3021+ catch (IOException &e){
3022+ LOGWARN (" IOException caught in LibCCEC::init %s" , e.what ());
3023+ }
3024+ catch (...){
3025+ LOGWARN (" Exception caught in LibCCEC::init" );
29843026 }
29853027 }
29863028 libcecInitStatus++;
@@ -3074,6 +3116,14 @@ namespace WPEFramework
30743116
30753117 m_logicalAddressAllocated = LogicalAddress::UNREGISTERED;
30763118 m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED;
3119+ if (m_audioStatusDetectionTimer.isActive ()){
3120+ m_audioStatusDetectionTimer.stop ();
3121+ }
3122+ m_isAudioStatusInfoUpdated = false ;
3123+ m_audioStatusReceived = false ;
3124+ m_audioStatusTimerStarted = false ;
3125+ LOGINFO (" CEC Disabled, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d " , m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted);
3126+
30773127
30783128 for (int i=0 ; i< 16 ; i++)
30793129 {
@@ -3089,9 +3139,14 @@ namespace WPEFramework
30893139 {
30903140 LibCCEC::getInstance ().term ();
30913141 }
3092- catch (const std::exception& e)
3093- {
3094- LOGWARN (" CEC exception caught from LibCCEC::getInstance().term() " );
3142+ catch (InvalidStateException &e){
3143+ LOGWARN (" InvalidStateException caught in LibCCEC::term %s" , e.what ());
3144+ }
3145+ catch (IOException &e){
3146+ LOGWARN (" IOException caught in LibCCEC::term %s" , e.what ());
3147+ }
3148+ catch (...){
3149+ LOGWARN (" Exception caught in LibCCEC::term" );
30953150 }
30963151 }
30973152
@@ -3324,12 +3379,43 @@ namespace WPEFramework
33243379
33253380 if ((_instance->m_SendKeyQueue .size ()<=1 || (_instance->m_SendKeyQueue .size () % 2 == 0 )) && ((keyInfo.keyCode == VOLUME_UP) || (keyInfo.keyCode == VOLUME_DOWN) || (keyInfo.keyCode == MUTE)) )
33263381 {
3327- _instance->sendGiveAudioStatusMsg ();
3328- }
3382+ if (keyInfo.keyCode == MUTE)
3383+ {
3384+ _instance->sendGiveAudioStatusMsg ();
3385+ }
3386+ else
3387+ {
3388+ LOGINFO (" m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d " ,_instance->m_isAudioStatusInfoUpdated ,_instance->m_audioStatusReceived ,_instance->m_audioStatusTimerStarted );
3389+ if (!_instance->m_isAudioStatusInfoUpdated )
3390+ {
3391+ if ( !(_instance->m_audioStatusDetectionTimer .isActive ()))
3392+ {
3393+ LOGINFO (" Audio status info not updated. Starting the Timer!" );
3394+ _instance->m_audioStatusTimerStarted = true ;
3395+ _instance->m_audioStatusDetectionTimer .start ((HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS));
3396+ }
3397+ LOGINFO (" m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d " , _instance->m_isAudioStatusInfoUpdated ,_instance->m_audioStatusReceived ,_instance->m_audioStatusTimerStarted );
3398+ }
3399+ else
3400+ {
3401+ if (!_instance->m_audioStatusReceived ){
3402+ _instance->sendGiveAudioStatusMsg ();
3403+ }
3404+ }
3405+ }
3406+ }
33293407
33303408 }// while(!_instance->m_sendKeyEventThreadExit)
33313409 }// threadSendKeyEvent
33323410
3411+ void HdmiCecSink::audioStatusTimerFunction ()
3412+ {
3413+ m_audioStatusTimerStarted = false ;
3414+ m_isAudioStatusInfoUpdated = true ;
3415+ LOGINFO (" Timer Expired. Requesting the AudioStatus since not received.\n " );
3416+ sendGiveAudioStatusMsg ();
3417+ LOGINFO (" m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d " , m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted);
3418+ }
33333419
33343420 void HdmiCecSink::threadArcRouting ()
33353421 {
@@ -3340,7 +3426,7 @@ namespace WPEFramework
33403426 return ;
33413427
33423428 LOGINFO (" Running threadArcRouting" );
3343-
3429+ _instance-> getHdmiArcPortID ();
33443430
33453431 while (1 )
33463432 {
0 commit comments