accessoryservices/pluggeddisplay/pluggeddisplayengine/src/hdmicablestatusfsm.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accessoryservices/pluggeddisplay/pluggeddisplayengine/src/hdmicablestatusfsm.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,619 @@
+/*
+* 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:  Finite State Machine class for HDMI Cable Status.
+*
+*/
+
+#include <f32file.h>
+#include <e32std.h>
+#include <accpolhdmiobjectcon.h>
+#include <accpolhdmisink.h>
+#include <accpolhdmiaudioformat.h>
+#include <accpolhdmivideoformat.h>
+#include <accpolhdmilatency.h>
+#include <accpolhdmispeakerallocation.h>
+#include <data_caging_path_literals.hrh>
+
+#include "pdeconstants.h"
+#include "accessorycontrolif.h"
+#include "hdmicablestateidle.h"
+#include "hdmicablestateconnected.h"
+#include "hdmicablestaterejected.h"
+#include "hdmicablestatusfsm.h"
+#include "tvoutconfigforhdmi.h"
+#include "pdasycmdhandlerinterface.h"
+#include "edidhandler.h"
+#include "trace.h"
+#include "cleanupresetanddestroy.h"
+#include "tvstandbyfigure.h"
+#include "TVOutStandbyFigure.mbg"  //located in \Data folder
+
+
+//The standby image
+_LIT(KHDMIStandbyFigureName,"z:tvoutstandbyfigure.mbm");
+
+// ======== LOCAL FUNCTIONS ========
+
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// Symbian two-phased constructor
+// ---------------------------------------------------------------------------
+//
+CHDMICableStatusFSM* CHDMICableStatusFSM::NewL(
+        RAccessoryServer& aAccessoryServer, CPDEngine *aPdEngine )
+    {
+    FUNC_LOG;
+    CHDMICableStatusFSM* self = new ( ELeave ) CHDMICableStatusFSM();
+    CleanupStack::PushL( self );
+    self->ConstructL( aAccessoryServer, aPdEngine );
+    CleanupStack::Pop( self );    
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CHDMICableStatusFSM::~CHDMICableStatusFSM()
+    {
+    FUNC_LOG;
+    iCurrentStateId = EHDMICableStateUndefined;
+    // Delete state objects
+    for (TInt i = 0; i < EHDMICableStateMaxValue; i++ )
+        {
+        delete iStateArray[i];
+        }
+    if ( iAccessoryControlIf )
+        {
+        iAccessoryControlIf->Cancel();
+        delete iAccessoryControlIf;
+        }
+    if ( iTVOutConfigForHDMI )
+        {
+        iTVOutConfigForHDMI->Cancel();
+        delete iTVOutConfigForHDMI;
+        }
+    if ( iEDIDHandler )
+        {
+        iEDIDHandler->Cancel();
+        delete iEDIDHandler;        
+        }
+    }
+
+
+//------------------------------------------------------------------------------
+//  From MPdeFSM.
+//------------------------------------------------------------------------------
+//
+TBool CHDMICableStatusFSM::ProcessCommandL( 
+    const TProcessCmdId aCommand,
+    const TASYCmdParams& aCmdParams,
+    MPDAsyCmdHandler& aAsyCmdHandler )
+    {
+    FUNC_LOG;
+    TBool commandHandled( EFalse );
+    TASYCommandParamRecord cmdParams( aCmdParams());
+    if ( iAccessoryControlIf->GetUniqueID() ==  cmdParams.iGenericID.UniqueID() )
+        {
+        commandHandled = ETrue;
+        iAsyCmdHandler = &aAsyCmdHandler;
+        TUint32 name;
+        cmdParams.iNameRecord.GetName( name);
+        TInt retVal( KErrNotFound );
+        TFSMMainAndSubState currentStates = CurrentMainAndSubstateIDs();
+        switch ( aCommand )
+            {
+            case ECmdGetObjectValue:
+                {
+                INFO( "Received command ECmdGetObjectValue" );
+                CAccPolHdmiObjectCon* hdmiObjectCon = CAccPolHdmiObjectCon::NewLC();
+                
+                if (    ( EHDMICableStateConnected == currentStates.iMainState ) &&
+                        ( CHDMICableStateConnected::ESubStateConnected == currentStates.iSubstate ) )
+                    {                    
+                    if ( KAccVideoHdmiAttributes == name )
+                        {
+                        INFO( "Object name KAccVideoHdmiAttributes" );
+                        retVal = KErrNone;
+                        }
+                    else if ( KAccVideoFormat == name )
+                        {
+                        INFO( "Object name KAccVideoFormat" );
+                        retVal = KErrNone;
+                        }
+                    else
+                        {
+                        INFO_1( "Unexpected capability name %i", name );
+                        }
+                    if ( KAccVideoHdmiAttributes == name )
+                        {
+                        CAccPolHdmiSink* hdmiSink = iEDIDHandler->CreateHdmiSinkL();
+                        if( hdmiSink )
+                            {
+                            CleanupStack::PushL( hdmiSink );
+                            hdmiObjectCon->AddL( *hdmiSink );
+                            CleanupStack::PopAndDestroy( hdmiSink );
+                            }
+                        }
+                    
+                    if ( ( KAccVideoHdmiAttributes == name ) ||
+                         ( KAccVideoFormat == name ) )
+                        {
+                        RAccPolHdmiVideoFormatArray hdmiVideoFormatArray;
+                        CleanupResetAndDestroyPushL( hdmiVideoFormatArray );
+                        iEDIDHandler->CreateHdmiVideoFormatL( hdmiVideoFormatArray );
+                        TInt count = hdmiVideoFormatArray.Count();
+                        for ( TInt i = 0; i < count; ++i )
+                            {
+                            hdmiObjectCon->AddL( *hdmiVideoFormatArray[i] );
+                            }
+                        CleanupStack::PopAndDestroy( &hdmiVideoFormatArray );
+                        }
+                    
+                    if ( KAccVideoHdmiAttributes == name )
+                        {
+                        RAccPolHdmiLatencyArray hdmiLatencyArray;
+                        CleanupResetAndDestroyPushL( hdmiLatencyArray );
+                        iEDIDHandler->CreateHdmiLatencyL( hdmiLatencyArray );
+                        TInt count = hdmiLatencyArray.Count();
+                        for( TInt i = 0; i < count; i++ )
+                            {
+                            hdmiObjectCon->AddL( *hdmiLatencyArray[i] );
+                            }
+                        CleanupStack::PopAndDestroy( &hdmiLatencyArray );
+                        }
+                    
+                    if ( KAccVideoHdmiAttributes == name )
+                        {
+                        RAccPolHdmiAudioFormatArray hdmiAudioFormatArray;
+                        CleanupResetAndDestroyPushL( hdmiAudioFormatArray );
+                        iEDIDHandler->CreateHdmiAudioFormatL( hdmiAudioFormatArray );
+                        TInt count = hdmiAudioFormatArray.Count();
+                        for ( TInt i = 0; i < count; ++i )
+                            {
+                            hdmiObjectCon->AddL( *hdmiAudioFormatArray[i] );
+                            }
+                        CleanupStack::PopAndDestroy( &hdmiAudioFormatArray );
+                        }
+                    
+                    if ( KAccVideoHdmiAttributes == name )
+                        {
+                        CAccPolHdmiSpeakerAllocation* hdmiSpeakerAllocation =
+                            iEDIDHandler->CreateHdmiSpeakerAllocationL();
+                        if( hdmiSpeakerAllocation )
+                            {
+                            CleanupStack::PushL( hdmiSpeakerAllocation );
+                            hdmiObjectCon->AddL( *hdmiSpeakerAllocation );
+                            CleanupStack::PopAndDestroy( hdmiSpeakerAllocation );
+                            }
+                        }                    
+                    aAsyCmdHandler.ProcessResponse( *hdmiObjectCon, retVal );
+                    }
+                else
+                    {
+                    INFO( "HDMI Cable is not connected" );
+                    aAsyCmdHandler.ProcessResponse( *hdmiObjectCon, KErrHardwareNotAvailable );                   
+                    }
+                CleanupStack::PopAndDestroy( hdmiObjectCon );
+                }
+                break;
+            case ECmdGetValueBool:
+                {
+                INFO( "Received command ECmdGetValueBool" );
+                TAccValueTypeTBool typeTBool;
+                typeTBool.iValue = EFalse;
+                if ( KAccVideoHdcpSupportStatus == name )
+                    {
+                    if (    ( EHDMICableStateConnected == currentStates.iMainState ) &&
+                            ( CHDMICableStateConnected::ESubStateConnected == currentStates.iSubstate ) )
+                         {
+                         Input( EPDEIfAsyCommandHandler, EIfAsyCommandHandlerEventGetCopyProtectStatus );
+                         // CopyProtectionStatusGot() will be called later and command is responded there
+                         }
+                    else
+                         {
+                         INFO( "HDMI Cable is not connected" );
+                         iAsyCmdHandler->ProcessResponse( typeTBool, KErrHardwareNotAvailable );
+                         }
+                    }
+                else
+                    {
+                    INFO( "Unsupported cabability name" );
+                    iAsyCmdHandler->ProcessResponse( typeTBool, KErrNotSupported );                   
+                    }
+                }
+                break;
+            case ECmdSetValueBool:
+                INFO( "Received command ECmdSetValueBool" );
+                TAccValueTypeTBool typeTBool;
+                typeTBool.iValue = EFalse;
+                if ( KAccVideoHdcpSupport == name )
+                    {
+                    if (    ( EHDMICableStateConnected == currentStates.iMainState ) &&
+                            ( CHDMICableStateConnected::ESubStateConnected == currentStates.iSubstate ) )
+                        {
+                        TBool requestedCopyProtectStatus = (TBool)cmdParams.iCmdValue;
+                        if ( requestedCopyProtectStatus )
+                            {
+                            Input( EPDEIfAsyCommandHandler, EIfAsyCommandHandlerEventSetCopyProtectionOn );
+                            }
+                        else
+                            {
+                            Input( EPDEIfAsyCommandHandler, EIfAsyCommandHandlerEventSetCopyProtectionOff );                    
+                            }
+                        // CopyProtectionSettingDone() will be called later and command is responded there
+                        }
+                    else
+                        {
+                        INFO( "HDMI Cable is not connected" );
+                        iAsyCmdHandler->ProcessResponse( typeTBool, KErrHardwareNotAvailable );
+                        }
+                    }
+                else
+                    {
+                    INFO( "Unsupported cabability name" );
+                    iAsyCmdHandler->ProcessResponse( typeTBool, KErrNotSupported );                   
+                    }
+                break;
+            default:
+                {
+                INFO_1( "Unknown command %i", aCommand );
+                }
+                break;
+            }        
+        }
+    return commandHandled;
+    }
+
+//------------------------------------------------------------------------------
+//  From MPdeFSM.
+//------------------------------------------------------------------------------
+//
+TInt CHDMICableStatusFSM::GetAccPolGenericID( TAccPolGenericID& aAccPolGenericID )
+    {
+    FUNC_LOG;
+    return iAccessoryControlIf->GetAccPolGenericID( aAccPolGenericID );
+    }
+
+
+// ---------------------------------------------------------------------------
+// From MFSMForBody.
+// ---------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::Start()
+    {
+    FUNC_LOG;
+    // Step to the initial state.
+    iCurrentStateId = EHDMICableStateIdle;
+    iStateArray[iCurrentStateId]->Enter();
+    return;
+    }
+
+
+// ---------------------------------------------------------------------------
+// From MFSMForBody.
+// ---------------------------------------------------------------------------
+//
+TFSMId CHDMICableStatusFSM::FSMID()
+    {
+    FUNC_LOG;
+    TFSMId aFSMID( EPDEFSMIdHDMICableStatus );
+    return aFSMID;   
+    }
+
+
+// ---------------------------------------------------------------------------
+// From MFSMForBody.
+// ---------------------------------------------------------------------------
+//
+TFSMState CHDMICableStatusFSM::CurrentStateID()
+    {
+    FUNC_LOG;
+    TFSMState currentState( EHDMICableStateUndefined );
+    if (    ( 0 <= iCurrentStateId ) && 
+            ( EHDMICableStateMaxValue > iCurrentStateId ))
+        {
+        currentState = iCurrentStateId;
+        }
+    INFO_1( "iCurrentStateId %i", iCurrentStateId );
+    return currentState;
+    }
+
+// ---------------------------------------------------------------------------
+// From MFSMForBody.
+// ---------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::Input(
+        TFSMInterfaceId aInterfaceId ,
+        TFSMEventId aEvent )
+    {
+    FUNC_LOG;
+    if ( EHDMICableStateUndefined != iCurrentStateId )
+        {
+        if ( NULL != iStateArray[iCurrentStateId] )
+            {
+            iStateArray[iCurrentStateId]->Input( aInterfaceId, aEvent );
+            }
+        }  
+    return;
+    }
+
+// ---------------------------------------------------------------------------
+// From MFSMForBody.
+// ---------------------------------------------------------------------------
+//
+MFSMState* CHDMICableStatusFSM::CurrentState()
+    {
+    FUNC_LOG;
+    MFSMState* currentState( NULL );
+    if (    ( 0 <= iCurrentStateId ) && 
+            ( EHDMICableStateMaxValue > iCurrentStateId ))
+        {
+        currentState = iStateArray[iCurrentStateId];
+        }
+    return currentState;
+    }
+
+// ---------------------------------------------------------------------------
+// From MFSMForBody.
+// ---------------------------------------------------------------------------
+//
+TPtrC CHDMICableStatusFSM::CurrentStateName()
+    {
+    FUNC_LOG;
+    TPtrC currentStateName( KNullDesC );
+    if ( (  0 <= iCurrentStateId ) && 
+         (  EHDMICableStateMaxValue > iCurrentStateId ))
+        {
+        if ( NULL != iStateArray[iCurrentStateId] )
+             {
+             currentStateName.Set( iStateArray[iCurrentStateId]->Name() );
+             }
+        }
+    return currentStateName;
+    }
+
+// ---------------------------------------------------------------------------
+// From MFSMForBody.
+// ---------------------------------------------------------------------------
+//
+TFSMMainAndSubState CHDMICableStatusFSM::CurrentMainAndSubstateIDs()
+    {
+    FUNC_LOG;
+    TFSMMainAndSubState state;
+    state.iMainState = EHDMICableStateUndefined;
+    state.iSubstate = 0;
+    if ( ( 0 <= iCurrentStateId ) && 
+            ( EHDMICableStateMaxValue > iCurrentStateId ))
+        {
+        state.iMainState = iCurrentStateId;
+        state.iSubstate = iStateArray[iCurrentStateId]->SubId();
+        }
+    INFO_2( "Main state id: %i, substate id: %i", state.iMainState, state.iSubstate );
+    return state;
+    }
+
+// ---------------------------------------------------------------------------
+// From MFSMForState.
+// ---------------------------------------------------------------------------
+//
+TBool CHDMICableStatusFSM::Transit( TFSMState aNextState )
+    {
+    FUNC_LOG;
+    TBool retVal(EFalse);
+    if ( (  0 <= aNextState ) && 
+         (  EHDMICableStateMaxValue > aNextState ) )
+        {
+        iCurrentStateId = aNextState;
+        if ( NULL != iStateArray[iCurrentStateId])
+            {
+            retVal = ETrue;
+            iStateArray[iCurrentStateId]->Enter();
+            }
+        }
+    if ( EFalse == retVal )
+        {
+        //Something is wrong
+        INFO( "Incorrect nextstate");
+        }   
+    INFO_1( "TBool retVal %i", retVal );
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// CopyProtectionSettingDone
+// ---------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::CopyProtectionSettingDone(
+        TInt aError,
+        TBool aCurrentStatus )
+    {
+    FUNC_LOG;
+    if ( iAsyCmdHandler )
+        {
+        INFO_1( "Copy Protection setting returned error code %i", aError );
+        TAccValueTypeTBool typeTBool;
+        typeTBool.iValue = aCurrentStatus;
+        iAsyCmdHandler->ProcessResponse( typeTBool, aError );        
+        iAsyCmdHandler = NULL;
+        }    
+    if ( KErrNone == aError )
+        {
+        CopyProtectionStatusChanged( aCurrentStatus );
+        }        
+    }   
+
+// ---------------------------------------------------------------------------
+// CopyProtectionStatusChanged
+// ---------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::CopyProtectionStatusChanged( TBool aNewStatus )
+    {
+    FUNC_LOG;
+    INFO_1( "Copy Protection new status %i", aNewStatus );
+    TUint32 name( KAccVideoHdcpSupportStatus );
+    TAccValueTypeTBool typeTBool;
+    typeTBool.iValue = aNewStatus;
+    iAccessoryControlIf->NotifyValueChange( name, typeTBool);
+    }   
+
+// ---------------------------------------------------------------------------
+// CopyProtectionListenFailed
+// ---------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::CopyProtectionListenFailed( TInt aError )
+    {
+    FUNC_LOG;
+    TInt error( aError ); // Just to get rid of a compiler warning.
+    if ( KErrNone != error )
+        {
+        INFO_1( "Copy Protection listening returned error code %i", error );        
+        }
+    }   
+
+// ---------------------------------------------------------------------------
+// CopyProtectionStatusGot
+// ---------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::CopyProtectionStatusGot( TBool aCopyProtectionStatus )
+    {
+    FUNC_LOG;
+    if ( iAsyCmdHandler )
+        {
+        INFO_1( "Copy Protection status %i", aCopyProtectionStatus );
+        TAccValueTypeTBool typeTBool;
+        typeTBool.iValue = aCopyProtectionStatus;
+        iAsyCmdHandler->ProcessResponse( typeTBool, KErrNone );
+        iAsyCmdHandler = NULL;
+        }    
+    }   
+
+// ---------------------------------------------------------------------------
+// SettingsChangedL
+// ---------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::SettingsChangedL()
+    {
+    FUNC_LOG;
+    TUint32 name( KAccVideoFormat );
+    CAccPolHdmiObjectCon* hdmiObjectCon = CAccPolHdmiObjectCon::NewLC();
+    TFSMMainAndSubState currentStates = CurrentMainAndSubstateIDs();
+    if (    (hdmiObjectCon) &&
+            ( EHDMICableStateConnected == currentStates.iMainState ) &&
+            ( CHDMICableStateConnected::ESubStateConnected == currentStates.iSubstate ) )
+        {
+        RAccPolHdmiVideoFormatArray hdmiVideoFormatArray;
+        CleanupResetAndDestroyPushL( hdmiVideoFormatArray );
+        iEDIDHandler->CreateHdmiVideoFormatL( hdmiVideoFormatArray );
+        for ( TInt i = 0; i < hdmiVideoFormatArray.Count(); ++i )
+            {
+            hdmiObjectCon->AddL( *hdmiVideoFormatArray[i] );
+            }
+        CleanupStack::PopAndDestroy( &hdmiVideoFormatArray );
+        iAccessoryControlIf->NotifyValueChange( name, *hdmiObjectCon );
+        }                
+    CleanupStack::PopAndDestroy( hdmiObjectCon );
+    }
+
+
+// ---------------------------------------------------------
+// C++ constructor
+// ---------------------------------------------------------
+//
+CHDMICableStatusFSM::CHDMICableStatusFSM()
+    {
+    FUNC_LOG;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CHDMICableStatusFSM::SetStandbyFiguresSettingsL
+//
+// ----------------------------------------------------------------------------
+//
+void CHDMICableStatusFSM::SetStandbyFiguresSettingsL()
+    {
+    FUNC_LOG;
+    
+    TInt err(KErrNone);
+    
+    if( iTVOutConfigForHDMI->GetTvOutConfig() )
+        {
+        //Standby figure
+        TParse parse;
+        TSize figureSize;
+        TStandByFigure figureSettings;
+        
+        parse.Set( KHDMIStandbyFigureName, &KDC_BITMAP_DIR, NULL );
+        TFileName fileName( parse.FullName() );
+    
+        //  Create converter for main standby figure
+        CTvStandbyFigure* mainImage = CTvStandbyFigure::NewLC(
+                    fileName, EMbmGSTvoutStandbyFigureQgn_graf_tvout_logo );
+                    
+        //  Fill the data structure for main standby figure
+        mainImage->GetFigureSize( figureSize );
+    
+        TUint16* RGBData = mainImage->RgbConvertL();
+        figureSettings.iTable = RGBData;
+        
+        figureSettings.iColumns = figureSize.iWidth;
+        figureSettings.iRows = figureSize.iHeight;
+        
+        CleanupStack::PushL(RGBData);
+        figureSettings.iFigureType = TStandByFigure::EStandByFigure;
+        err = iTVOutConfigForHDMI->GetTvOutConfig()->StandByFigure( figureSettings );
+        INFO_1( "iTVOutConfigForHDMI->StandByFigure( figureSettings ) return code %i", err );        
+        figureSettings.iFigureType = TStandByFigure::EProtectedContentFigure;    
+        err = iTVOutConfigForHDMI->GetTvOutConfig()->StandByFigure( figureSettings );
+        INFO_1( "iTVOutConfigForHDMI->StandByFigure( figureSettings ) return code %i", err );        
+
+        CleanupStack::PopAndDestroy( 2 );        
+        }
+    User::LeaveIfError(err);    
+    }
+
+// ---------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------
+//
+void CHDMICableStatusFSM::ConstructL(
+        RAccessoryServer& aAccessoryServer, CPDEngine *aPdEngine )
+    {
+    FUNC_LOG;
+    
+    iPdEngine = aPdEngine;
+    
+    // Create interface objecs
+    iAccessoryControlIf = CAccessoryControlIf::NewL( *this, aAccessoryServer );
+    iTVOutConfigForHDMI = CTVOutConfigForHDMI::NewL( *this );
+    iEDIDHandler = CEDIDHandler::NewL( *this, *iTVOutConfigForHDMI );
+    // Create state objects here.
+    iStateArray[ EHDMICableStateIdle ] = CHDMICableStateIdle::NewL( 
+            *this, *iTVOutConfigForHDMI, *iEDIDHandler );
+    iStateArray[ EHDMICableStateConnected ] = CHDMICableStateConnected::NewL( 
+            *iTVOutConfigForHDMI, *iEDIDHandler, *iAccessoryControlIf, *this );
+    iStateArray[ EHDMICableStateRejected ] = CHDMICableStateRejected::NewL( 
+                *this, *iTVOutConfigForHDMI, *iEDIDHandler  );
+    
+    SetStandbyFiguresSettingsL();
+    
+    return;
+    }
+
+// ======== GLOBAL FUNCTIONS ========
+