cec: always refresh the power state of a device when it hasn't been updated for 30...
[deb_libcec.git] / src / lib / devices / CECBusDevice.cpp
index 044cd9c0b938e341ac58ca0e4512687c106bd5d5..d6e447f96303f44cf91735807601704451a01df0 100644 (file)
@@ -54,6 +54,7 @@ CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogi
   m_menuState(CEC_MENU_STATE_ACTIVATED),
   m_bActiveSource(false),
   m_iLastActive(0),
+  m_iLastPowerStateUpdate(0),
   m_cecVersion(CEC_VERSION_UNKNOWN),
   m_deviceStatus(CEC_DEVICE_STATUS_UNKNOWN),
   m_handlerMutex(false)
@@ -314,7 +315,9 @@ cec_power_status CCECBusDevice::GetPowerStatus(bool bUpdate /* = false */)
     CLockObject lock(&m_mutex);
     bRequestUpdate = (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
         (bUpdate || m_powerStatus == CEC_POWER_STATUS_UNKNOWN ||
-            m_powerStatus == CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON));
+            m_powerStatus == CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON ||
+            m_powerStatus == CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY ||
+            GetTimeMs() - m_iLastPowerStateUpdate >= CEC_POWER_STATE_REFRESH_TIME));
   }
 
   if (bRequestUpdate)
@@ -513,6 +516,12 @@ void CCECBusDevice::SetInactiveSource(void)
 void CCECBusDevice::SetActiveSource(void)
 {
   CLockObject lock(&m_mutex);
+  if (!m_bActiveSource)
+  {
+    CStdString strLog;
+    strLog.Format("making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
+    AddLog(CEC_LOG_DEBUG, strLog);
+  }
 
   for (int iPtr = 0; iPtr < 16; iPtr++)
     if (iPtr != m_iLogicalAddress)
@@ -613,6 +622,7 @@ void CCECBusDevice::SetPowerStatus(const cec_power_status powerStatus)
   CLockObject lock(&m_mutex);
   if (m_powerStatus != powerStatus)
   {
+    m_iLastPowerStateUpdate = GetTimeMs();
     CStdString strLog;
     strLog.Format(">> %s (%X): power status changed from '%s' to '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(m_powerStatus), ToString(powerStatus));
     m_processor->AddLog(CEC_LOG_DEBUG, strLog);
@@ -627,39 +637,42 @@ bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */)
 
   if (m_vendor != m_handler->GetVendorId())
   {
-    CStdString strLog;
-    if (m_handler->InUse())
+    if (CCECCommandHandler::HasSpecificHandler(m_vendor))
     {
-      strLog.Format("handler for device '%s' (%x) is being used. not replacing the command handler", GetLogicalAddressName(), GetLogicalAddress());
-      m_processor->AddLog(CEC_LOG_DEBUG, strLog);
-      return false;
-    }
+      CStdString strLog;
+      if (m_handler->InUse())
+      {
+        strLog.Format("handler for device '%s' (%x) is being used. not replacing the command handler", GetLogicalAddressName(), GetLogicalAddress());
+        m_processor->AddLog(CEC_LOG_DEBUG, strLog);
+        return false;
+      }
 
-    strLog.Format("replacing the command handler for device '%s' (%x)", GetLogicalAddressName(), GetLogicalAddress());
-    m_processor->AddLog(CEC_LOG_DEBUG, strLog);
-    delete m_handler;
+      strLog.Format("replacing the command handler for device '%s' (%x)", GetLogicalAddressName(), GetLogicalAddress());
+      m_processor->AddLog(CEC_LOG_DEBUG, strLog);
+      delete m_handler;
 
-    switch (m_vendor)
-    {
-    case CEC_VENDOR_SAMSUNG:
-      m_handler = new CANCommandHandler(this);
-      break;
-    case CEC_VENDOR_LG:
-      m_handler = new CSLCommandHandler(this);
-      break;
-    case CEC_VENDOR_PANASONIC:
-      m_handler = new CVLCommandHandler(this);
-      break;
-    default:
-      m_handler = new CCECCommandHandler(this);
-      break;
-    }
+      switch (m_vendor)
+      {
+      case CEC_VENDOR_SAMSUNG:
+        m_handler = new CANCommandHandler(this);
+        break;
+      case CEC_VENDOR_LG:
+        m_handler = new CSLCommandHandler(this);
+        break;
+      case CEC_VENDOR_PANASONIC:
+        m_handler = new CVLCommandHandler(this);
+        break;
+      default:
+        m_handler = new CCECCommandHandler(this);
+        break;
+      }
 
-    m_handler->SetVendorId(m_vendor);
-    m_handler->InitHandler();
+      m_handler->SetVendorId(m_vendor);
+      m_handler->InitHandler();
 
-    if (bActivateSource && m_processor->GetLogicalAddresses().IsSet(m_iLogicalAddress) && m_processor->IsInitialised())
-      m_handler->ActivateSource();
+      if (bActivateSource && m_processor->GetLogicalAddresses().IsSet(m_iLogicalAddress) && m_processor->IsInitialised() && IsActiveSource())
+        m_handler->ActivateSource();
+    }
   }
 
   return true;