diff -r 000000000000 -r 4e1aa6a622a0 accessoryservices/pluggeddisplay/pluggeddisplayengine/src/tvoutconfigforhdmi.cpp --- /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 +#include +#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& aAnalogConfigs, + const RArray& 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& 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(); + }