accessoryservices/pluggeddisplay/pluggeddisplayengine/src/tvoutconfigforhdmi.cpp
changeset 0 4e1aa6a622a0
child 6 6bb05bdcbe09
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accessoryservices/pluggeddisplay/pluggeddisplayengine/src/tvoutconfigforhdmi.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ * 
+ * Description:
+ * CPDConfigurationForHDMI class implementation.
+ *
+ */
+
+
+// INCLUDE FILES
+#include <tvoutconfig.h>
+#include <e32base.h>
+#include "pdeconstants.h"
+#include "tvoutconfigforhdmi.h"
+#include "multifinitestatemachine.h"
+#include "hdmicablestatusfsm.h"
+#include "myasynconeshottimer.h"
+#include "trace.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+//
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+// CTVOutConfigListenerForHDMI::NewL
+//
+// ----------------------------------------------------------------------------
+//
+CTVOutConfigForHDMI* CTVOutConfigForHDMI::NewL(
+        MFSMForBody& aFSM )
+    {
+    FUNC_LOG;
+    CTVOutConfigForHDMI* self = new(ELeave) CTVOutConfigForHDMI( aFSM );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self);
+
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::CTVOutConfigForHDMI
+//
+// ----------------------------------------------------------------------------
+//
+CTVOutConfigForHDMI::CTVOutConfigForHDMI(
+        MFSMForBody& aFSM )
+    : CActive( CActive::EPriorityLow ),
+    iTvConfig ( NULL ),
+    iFSM( aFSM )
+    {
+    FUNC_LOG;
+    // Nothing
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::ListenHDMICableStatusIfNoMissedEvents
+//
+// ----------------------------------------------------------------------------
+//
+TFSMEventId CTVOutConfigForHDMI::ListenHDMICableStatusIfNoMissedEvents()
+    {
+    FUNC_LOG;
+    TFSMEventId retEvent( EIfTVOutConfigEventUndefined );
+    TFSMState currentStateId = iFSM.CurrentStateID();
+
+    if  ( ( EHDMICableStateIdle == currentStateId ) && ( iTvConfig->HdmiCableConnected() ) )
+        {
+        INFO("Cable connected while disconnect actions were going on in ASY or is already connected when ASY starts.");
+        retEvent = EIfTVOutConfigEventCableConnected;
+        }
+    else if ( ( EHDMICableStateConnected == currentStateId ) && ( !iTvConfig->HdmiCableConnected() ) )
+        {
+        INFO("Cable disconnected while connect actions were going on in ASY.");
+        retEvent = EIfTVOutConfigEventCableDisconnected;
+        }
+    else if ( !IsActive() )
+        {
+        iStatus = KRequestPending;
+        iNextOpt = EOptStartListenHdmiCable;
+        SetActive();
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );                  
+        }
+    INFO_1("Returning event id: %d", retEvent);
+    return retEvent;
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::SetAvailableTvConfigList
+//
+// ----------------------------------------------------------------------------
+//
+TInt CTVOutConfigForHDMI::SetAvailableTvConfigList(
+        const RArray<TTvSettings>& aAnalogConfigs, 
+        const RArray<THdmiDviTimings>& aHdmiConfigs )
+    {
+    FUNC_LOG;
+    TInt retVal( KErrNotFound );
+    if ( iTvConfig )
+        {
+        retVal = iTvConfig->SetAvailableTvConfigList(
+                aAnalogConfigs,
+                aHdmiConfigs );
+        }
+    
+    return retVal;
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::Enable
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::Enable()
+    {
+    FUNC_LOG;
+    Cancel();
+    iStatus = KRequestPending;
+    iNextOpt = EOptEnableTv;
+    SetActive();
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );        
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::Disable
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::Disable()
+    {
+    FUNC_LOG;
+    Cancel();
+    iStatus = KRequestPending;
+    iNextOpt = EOptDisableTv;
+    SetActive();
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );        
+    }
+
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::Disable
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::ListenForDisconnection()
+    {
+    Cancel();
+    iNextOpt = EOptStartListenForDisconnection;
+    iStatus = KRequestPending;
+    SetActive();
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );        
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::GetTvOutConfig
+//
+// ----------------------------------------------------------------------------
+//
+CTvOutConfig* CTVOutConfigForHDMI::GetTvOutConfig()
+    {
+    FUNC_LOG;
+    return iTvConfig;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::ListenCopyProtectionIfNoMissedEvents
+//
+// ----------------------------------------------------------------------------
+//
+TCopyProtctListenRetValues CTVOutConfigForHDMI::ListenCopyProtectionIfNoMissedEvents()
+    {
+    FUNC_LOG;
+    TCopyProtctListenRetValues retStruct;
+    retStruct.iFSMEventId = EIfTVOutConfigEventUndefined;
+    retStruct.iError = KErrNone;
+    TBool currentCopyProtectStatus = iTvConfig->CopyProtectionStatus();
+
+    if  ( iLastRecordedCopyProtectEnabledStatus != currentCopyProtectStatus )
+        {
+        INFO("Copy Protection status changed while not listening.");
+        retStruct.iFSMEventId = EIfTVOutConfigEventSetCopyProtectStatusChanged;
+        }
+    else if ( !IsActive() )
+        {
+        iLastRecordedCopyProtectEnabledStatus = currentCopyProtectStatus;
+        iStatus = KRequestPending;
+        TInt err = iTvConfig->CopyProtectionStatusListener( iStatus );
+        if ( KErrNone == err )
+            {
+            SetActive();
+            iNextOpt = EOptListenCopyProtection;
+            }
+        else
+            {
+            iStatus = KErrNone;
+            INFO_1("Error status %d", err);
+            INFO("Copy Protection Status listening failed.");
+            retStruct.iError = err;
+            retStruct.iFSMEventId = EIfTVOutConfigEventCopyProtectionListenFailed;            
+            }
+        }
+    return retStruct;
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::GetLatestRecordedCopyProtectionStatus
+//
+// ----------------------------------------------------------------------------
+//
+TBool CTVOutConfigForHDMI::GetLatestRecordedCopyProtectionStatus() const
+    {
+    FUNC_LOG;
+    return iLastRecordedCopyProtectEnabledStatus;
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::ResetLatestRecordedCopyProtectionStatus
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::ResetLatestRecordedCopyProtectionStatus()
+    {
+    FUNC_LOG;
+    iLastRecordedCopyProtectEnabledStatus = EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::ListenSettingsChanges
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::ListenSettingsChanges()
+    {
+    FUNC_LOG;
+    Cancel();    
+    iNextOpt = EOptStartListenForSettingsChanges;
+    iStatus = KRequestPending;
+    SetActive();
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );        
+    
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::GetSupportedHdmiModes
+//
+// ----------------------------------------------------------------------------
+//
+TInt CTVOutConfigForHDMI::GetSupportedHdmiModes( RArray<TSupportedHdmiDviMode>& asupportedModes )
+    {
+    FUNC_LOG;
+
+	TUint count;
+	TInt  retVal( KErrNone );
+	
+	retVal = iTvConfig->GetNumberOfHdmiModes( count );
+	ERROR( retVal, "Getting supported hdmi modes failed" );
+
+	if( KErrNone == retVal )
+		{
+		for( TInt i = 0; (i < count); i++)
+			{
+			TSupportedHdmiDviMode mode;			
+			iTvConfig->GetSupportedHdmiMode( i, mode );
+			TInt err = asupportedModes.Append( mode );
+			if(KErrNone != err)
+			    {
+			    ERROR( err, "Failed to append supported modes in array" );
+			    retVal = err;
+			    break;
+			    }
+			}
+		}
+
+	return retVal;
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::ConstructL
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::ConstructL()
+    {
+    FUNC_LOG;
+     // Tv out config
+    iTvConfig = CTvOutConfig::NewL();
+    iMyAsyncOneShotTimer = new (ELeave) CMyAsyncOneShotTimer( CActive::EPriorityLow, *this );
+    CActiveScheduler::Add( this );
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::~CTVOutConfigForHDMI
+//
+// ----------------------------------------------------------------------------
+//
+CTVOutConfigForHDMI::~CTVOutConfigForHDMI()
+    {
+    FUNC_LOG;
+    if ( iTvConfig )
+        {
+        Cancel();
+        delete iTvConfig;        
+        }
+    if ( iMyAsyncOneShotTimer )
+        {
+        if ( iMyAsyncOneShotTimer->IsActive() )
+            {
+            iMyAsyncOneShotTimer->Cancel();      
+            }
+        delete iMyAsyncOneShotTimer;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::DoCancel
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::DoCancel()
+    {
+    FUNC_LOG;
+    TInt err( KErrNone );
+    iLastRecordedCopyProtectEnabledStatus = EFalse;
+    if (    ( EOptListenHdmiCable == iNextOpt )||
+            ( EOptListenForDisconnection == iNextOpt ) )
+        {
+        err = iTvConfig->HdmiCableListenerCancel();            
+        }
+    else if ( EOptListenCopyProtection == iNextOpt )
+        {
+        err = iTvConfig->CopyProtectionStatusCancel();            
+        }
+    else if ( EOptListenForSettingsChanges == iNextOpt )
+        {
+        err = iTvConfig->SettingsChangedListenerCancel();
+        }
+    if ( iMyAsyncOneShotTimer )
+        {
+        iMyAsyncOneShotTimer->Cancel();
+        }
+    iNextOpt = EOptIdle;
+    if ( KErrNone != err )
+        {
+        INFO_1("Error status %d", err);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::RunL
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::RunL()
+    {
+    FUNC_LOG;
+
+    switch ( iNextOpt )
+        {
+        case EOptStartListenHdmiCable:
+            {
+            INFO("EOptStartListenHdmiCable");
+            iStatus = KRequestPending;
+            TInt err = iTvConfig->HdmiCableListener( iStatus );
+            INFO_1("Error status %d", err);
+            if(err == KErrNone)
+                {
+                SetActive();
+                iNextOpt = EOptListenHdmiCable;
+                }
+            else
+                {
+                iStatus = KErrNone;
+                User::LeaveIfError( err );
+                }       
+            break;
+            }
+        case EOptListenHdmiCable:
+            {
+            INFO("EOptListenHdmiCable");
+            if ( KErrNone != iStatus.Int())
+                {
+                if ( EHDMICableStateIdle == iFSM.CurrentStateID() )
+                    {
+                    // HDMI Cable FSM may not fail in idle state.
+                    // Try to listen after a while, and do this again (possibly) forever
+                    iTimeOutReason = EOptStartListenHdmiCable;
+                    iNextOpt = EOptIdle;
+                    iMyAsyncOneShotTimer->Call();
+                    }
+                else
+                    {
+                    iFSM.Input( 
+                            EPDEIfTVOutConfig, 
+                            EIfTVOutConfigEventCableStatusListenFailed );
+                    }
+                }
+            else if ( iTvConfig->HdmiCableConnected() )
+                {
+                iFSM.Input( 
+                        EPDEIfTVOutConfig, 
+                        EIfTVOutConfigEventCableConnected );
+                }
+            else
+                {
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventCableDisconnected );
+                }
+            break;
+            }
+        case EOptListenCopyProtection:
+            {
+            INFO("EOptListenCopyProtection");
+            iNextOpt = EOptIdle;
+            if ( KErrNone != iStatus.Int())
+                {
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventCopyProtectionListenFailed );                
+                }
+            else
+                {
+                iLastRecordedCopyProtectEnabledStatus = iTvConfig->CopyProtectionStatus();
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventSetCopyProtectStatusChanged );                
+                }
+            break;
+            }
+         case EOptEnableTv:
+            {
+            INFO("EOptEnableTv");
+            TInt retVal = iTvConfig->Enable();
+            INFO_1("iTvConfig->Enable() retVal: %d", retVal);
+            switch ( retVal )
+                {
+                case KErrNone:
+                case KErrAlreadyExists:    
+                    {
+                    iFSM.Input(
+                            EPDEIfTVOutConfig,
+                            EIfTVOutConfigEventEnabled );                                             
+                    }
+                    break;
+                case KErrServerBusy:
+                    {
+                    iTimeOutReason = iNextOpt;
+                    iNextOpt = EOptIdle;
+                    iMyAsyncOneShotTimer->Call();
+                    }
+                    break;
+                case KErrNotSupported:
+                case KErrNotReady:
+                default:
+                    {
+                        iFSM.Input(
+                                EPDEIfTVOutConfig,
+                                EIfTVOutConfigEventEnableFailed );                                             
+                    }
+                    break;
+                }            
+            break;
+            }
+        case EOptDisableTv:
+            {
+            INFO("EOptDisableTv");
+            TInt retVal = iTvConfig->Disable();
+            INFO_1("iTvConfig->Disable() retVal: %d", retVal);
+            switch ( retVal )
+                {
+                case KErrNone:
+                case KErrAlreadyExists:    
+                    {
+                    iFSM.Input(
+                            EPDEIfTVOutConfig,
+                            EIfTVOutConfigEventDisabled );                                             
+                    }
+                    break;
+                case KErrServerBusy:
+                    {
+                    iTimeOutReason = iNextOpt;
+                    iNextOpt = EOptIdle;
+                    iMyAsyncOneShotTimer->Call();
+                    }
+                    break;
+                case KErrNotSupported:
+                case KErrNotReady:
+                default:
+                    {
+                    iFSM.Input(
+                            EPDEIfTVOutConfig,
+                            EIfTVOutConfigEventDisableFailed );                                             
+                    }
+                    break;
+                }            
+            break;
+            }
+        case EOptStartListenForDisconnection:
+            {
+            INFO("EOptStartListenForDisconnection");
+            iStatus = KRequestPending;
+            TInt err = iTvConfig->HdmiCableListener( iStatus );
+            if(err == KErrNone)
+                {
+                SetActive();
+                if(iTvConfig->HdmiCableConnected())
+                    {
+                    iNextOpt = EOptListenForDisconnection;
+                    }
+                else
+                    {
+                    Cancel();
+                    iFSM.Input( 
+                            EPDEIfTVOutConfig, 
+                            EIfTVOutConfigEventCableDisconnected );                    
+                    }
+                }
+            else
+                {
+                iStatus = KErrNone;
+                User::LeaveIfError( err );
+                }
+            break;
+            }
+        case EOptListenForDisconnection:
+            {
+            INFO("EOptListenForDisconnection");
+            TInt err( iStatus.Int() );
+            if ( KErrNone != err )
+                {
+                INFO_1("Error status %d", err);
+                iFSM.Input(
+                            EPDEIfTVOutConfig,
+                            EIfTVOutConfigEventCableStatusListenFailed );
+                }
+            else if ( iTvConfig->HdmiCableConnected() )
+                {
+                // This should not come at all, because waiting for the first occurred
+                // disconnection since entering this state.
+                ListenForDisconnection();
+                }
+            else
+                {
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventCableDisconnected );
+                }
+            break;
+            }
+        case EOptStartListenForSettingsChanges:
+            {
+            INFO("EOptStartListenForSettingsChanges");
+            iStatus = KRequestPending;
+            TInt err = iTvConfig->SettingsChangedListener( iStatus );
+            if ( KErrNone != err )
+                {
+                INFO_1("iTvConfig->SettingsChangedListener( iStatus ) error status %i", err);
+                iStatus = KErrNone;
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventSettingsChangesListenFailed );
+                }
+            else
+                {
+                SetActive();
+                iNextOpt = EOptListenForSettingsChanges;
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventSettingsChangesListenStarted );
+                }
+            break;
+            }
+        case EOptListenForSettingsChanges:
+            {
+            INFO("EOptListenForSettingsChanges");
+            iNextOpt = EOptIdle;
+            TInt err( iStatus.Int() );
+            if ( KErrNone != err )
+                {
+                INFO_1("Error status %d", err);
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventSettingsChangesListenFailed );
+                }
+            else
+                {
+                iFSM.Input(
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventSettingsChanged );
+                }
+            break;
+            }
+        default:
+            INFO_1("Default case, iNextOpt = %i", iNextOpt);
+            break;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::RunError
+//
+// ----------------------------------------------------------------------------
+//
+TInt CTVOutConfigForHDMI::RunError( TInt aError )
+    {
+    FUNC_LOG;
+
+    switch ( iNextOpt )
+        {
+        case EOptStartListenHdmiCable:
+        case EOptStartListenForDisconnection:
+            {
+            iFSM.Input( 
+                        EPDEIfTVOutConfig,
+                        EIfTVOutConfigEventCableStatusListenFailed );
+            }
+            break;
+          
+        default:
+            break;
+        }
+    
+    return KErrNone; 
+    }
+
+// ----------------------------------------------------------------------------
+// CTVOutConfigForHDMI::OneShotTimeout
+//
+// ----------------------------------------------------------------------------
+//
+void CTVOutConfigForHDMI::OneShotTimeout()
+    {
+    iNextOpt = iTimeOutReason;
+    iTimeOutReason = EOptIdle;
+    RunL();
+    }