diff -r 000000000000 -r a2952bb97e68 mpx/playbackframework/playbackengine/src/mpxautoresumehandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpx/playbackframework/playbackengine/src/mpxautoresumehandler.cpp Thu Dec 17 08:55:47 2009 +0200 @@ -0,0 +1,377 @@ +/* +* Copyright (c) 2006 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: Implemention of the auto resume handler. +* +*/ + + +#include +#include +#include +#include +#include "mpxplaybackengine.h" +#include "mpxautoresumehandler.h" + +// CONSTANTS +const TInt KMPXErrDiedTimeout = 2000000; + +// Time to wait before resume after call has ended. +const TInt KMPXResumeWaitTime = 3000000; // 3.0s + + + +// ================= MEMBER FUNCTIONS ======================= + + +// ----------------------------------------------------------------------------- +// C++ constructor +// ----------------------------------------------------------------------------- +// +CMPXAutoResumeHandler::CMPXAutoResumeHandler( + CMPXPlaybackEngine& aEngine, + TBool aMixerSupport) : + iEngine(aEngine), + iMixerSupport(aMixerSupport), + iAutoResume(ETrue) + { + } + +// ----------------------------------------------------------------------------- +// Symbian OS default constructor +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::ConstructL() + { + // Listen to call state changes + iStateObserver = CMPXPSKeyWatcher::NewL(KPSUidCtsyCallInformation, + KCTsyCallState,this); + + // Listen to call type changes + iTypeObserver = CMPXPSKeyWatcher::NewL(KPSUidCtsyCallInformation, + KCTsyCallType,this); + iResumeTimer = CPeriodic::NewL(CActive::EPriorityStandard); + } + +// ----------------------------------------------------------------------------- +// Constructs a new entry with given values. +// ----------------------------------------------------------------------------- +// +CMPXAutoResumeHandler* CMPXAutoResumeHandler::NewL( + CMPXPlaybackEngine& aEngine, + TBool aMixerSupport) + { + CMPXAutoResumeHandler* self = + new (ELeave) CMPXAutoResumeHandler(aEngine, aMixerSupport); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::CMPXAutoResumeHandler() +// Destructor +// ----------------------------------------------------------------------------- +// +CMPXAutoResumeHandler::~CMPXAutoResumeHandler() + { + delete iStateObserver; + delete iTypeObserver; + if ( iResumeTimer ) + { + CancelResumeTimer(); + delete iResumeTimer; + } + } + +// ----------------------------------------------------------------------------- +// Open file completed +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::HandleOpenFileComplete() + { + MPX_FUNC("CMPXAutoResumeHandler::HandleOpenFileComplete()"); + iPausedForCall = EFalse; + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::MPlayerStateChanged +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::HandlePlaybackStateChange(TMPXPlaybackState aState) + { + MPX_DEBUG2("CMPXAutoResumeHandler::HandlePlaybackStateChange(%d) entering", aState); + + // Any state change means that possible waiting resume is not to be done + // anymore. + CancelResumeTimer(); + + if (aState != EPbStatePaused) + { + iPausedForCall = EFalse; + } + MPX_DEBUG1("CMPXAutoResumeHandler::HandlePlaybackStateChange() exiting"); + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::MPlayerPlayComplete +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::HandlePlaybackComplete(TInt aError) + { + MPX_DEBUG2("CMPXAutoResumeHandler::HandlePlaybackComplete(%d) entering", aError); + iPausedForCall = EFalse; + if ( KErrDied == aError || + KErrAccessDenied == aError ) + { + iKErrDiedTime.HomeTime(); + + TInt callType = EPSCTsyCallTypeNone; + TInt callState = EPSCTsyCallStateNone; + + if (!iTypeObserver->GetValue(callType) && + !iStateObserver->GetValue(callState)) + { + if ((callState == EPSCTsyCallStateRinging && iMixerSupport) || + ShouldPause()) + { + // Getting a play complete with KErrDied here + // means Audio Policy terminated our playback, + // due to phone call being connected. Enable + // autoresume. + iPausedForCall = ETrue; + } + } + } + MPX_DEBUG1("CMPXAutoResumeHandler::HandlePlaybackComplete() exiting"); + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::CancelResumeTimer +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::CancelResumeTimer() + { + if ( iResumeTimer ) + { + iResumeTimer->Cancel(); + } + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::HandlePSEvent +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::HandlePSEvent(TUid /*aUid*/, TInt /*aKey*/) + { + MPX_FUNC("CMPXAutoResumeHandler::HandlePSEvent()"); + TRAP_IGNORE(DoHandleStateChangeL()); + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::DoHandleStateChangeL +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::DoHandleStateChangeL() + { + MPX_FUNC("CMPXAutoResumeHandler::DoHandleStateChangeL()"); + MPX_DEBUG2("CMPXAutoResumeHandler::DoHandleStateChangeL(): iPausedForCall = %d", iPausedForCall); + MPX_DEBUG2("CMPXAutoResumeHandler::DoHandleStateChangeL(): engineState = %d", iEngine.State()); + // if autoresume is disabled, do nothing + if ( !iAutoResume ) + { + return; + } + + TBool shouldPause = ShouldPause(); + if (shouldPause && + !iPausedForCall && + iEngine.State() == EPbStatePlaying) + { + iEngine.HandleCommandL(EPbCmdPause); + iPausedForCall = ETrue; + } + else if ( shouldPause && + !iPausedForCall && + ( iEngine.State() == EPbStateSeekingForward || + iEngine.State() == EPbStateSeekingBackward ) ) + { + iEngine.HandleCommandL( EPbCmdStopSeeking ); + if ( iEngine.State() == EPbStatePlaying ) + { + iEngine.HandleCommandL( EPbCmdPause ); + iPausedForCall = ETrue; + } + } + else if(!shouldPause && + iPausedForCall && + iEngine.State() == EPbStatePaused) + { + MPX_DEBUG1("CMPXAutoResumeHandler::DoHandleStateChangeL(): starting resume timer"); + if ( iResumeTimer->IsActive() ) + iResumeTimer->Cancel(); + iResumeTimer->Start( + KMPXResumeWaitTime, + KMPXResumeWaitTime, + TCallBack(ResumeTimerCallback, this) ); + iPausedForCall = EFalse; + } + else if ( shouldPause && + iEngine.State() == EPbStatePaused && + !iPausedForCall && + iKErrDiedTime.Int64()) + { + // Check if we recently got a playcomplete with KErrDied, + // it was most likely caused by an active call + TTime now; + now.HomeTime(); + TInt64 deltaTime = now.MicroSecondsFrom(iKErrDiedTime).Int64(); + if ( deltaTime > 0 && + deltaTime < KMPXErrDiedTimeout) + { + iResumeTimer->Cancel(); + iPausedForCall = ETrue; + } + } + MPX_DEBUG2("CMPXAutoResumeHandler::DoHandleStateChangeL(): iPausedForCall = %d", iPausedForCall); + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::ShouldPause +// ----------------------------------------------------------------------------- +// +TBool CMPXAutoResumeHandler::ShouldPause() + { + MPX_DEBUG1("CMPXAutoResumeHandler::ShouldPause() entering"); + TBool ret = EFalse; + + if ( !IsPlaybackRemote() ) + { + TInt callType; + TInt callState; + iTypeObserver->GetValue(callType); + iStateObserver->GetValue(callState); + MPX_DEBUG3("CMPXAutoResumeHandler::ShouldPause(): type = %d, state = %d", callType, callState); + + if (callType == EPSCTsyCallTypeCSVoice || + callType == EPSCTsyCallTypeH324Multimedia || + callType == EPSCTsyCallTypeVoIP || + callType == EPSCTsyCallTypeUninitialized) + { + switch (callState) + { + case EPSCTsyCallStateAnswering: + case EPSCTsyCallStateAlerting: + case EPSCTsyCallStateConnected: + case EPSCTsyCallStateDialling: + case EPSCTsyCallStateHold: + case EPSCTsyCallStateDisconnecting: + { + ret = ETrue; + break; + } + case EPSCTsyCallStateRinging: + { + if (iPausedForCall) + { + ret = ETrue; + } + else + { + // Pause playback if we cannot mix music playback + // with ringing tone. + ret = !iMixerSupport; + } + break; + } + default: + { + // Default is no pause + break; + } + } + } + } + MPX_DEBUG2("CMPXAutoResumeHandler::ShouldPause() exiting: %d", ret); + return ret; + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::HandleResumeTimerCallback +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::HandleResumeTimerCallback() + { + MPX_FUNC("CMPXAutoResumeHandler::HandleResumeTimerCallback() entering"); + + CancelResumeTimer(); + TRAP_IGNORE( iEngine.HandleCommandL( EPbCmdPlayWithFadeIn )); + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::ResumeTimerCallbackL +// ----------------------------------------------------------------------------- +// +TInt CMPXAutoResumeHandler::ResumeTimerCallback(TAny* aPtr) + { + MPX_FUNC("CMPXAutoResumeHandler::ResumeTimerCallback()"); + + CMPXAutoResumeHandler* ptr = + static_cast(aPtr); + ptr->HandleResumeTimerCallback(); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMPXAutoResumeHandler::IsPlaybackRemote +// ----------------------------------------------------------------------------- +// +TBool CMPXAutoResumeHandler::IsPlaybackRemote() + { + MPX_DEBUG1("CMPXAutoResumeHandler::IsPlaybackRemote() entering"); + TBool isRemote = EFalse; + + if ( iEngine.State() == EPbStatePlaying ) + { + TMPXPlaybackPlayerType type( EPbLocal ); + TUid uid; + TInt index; + TPtrC subPlayerName( KNullDesC ); + iEngine.PluginHandler()->GetSelection( type, uid, + index, subPlayerName ); + + if ( type != EPbLocal ) + { + isRemote = ETrue; + } + } + + MPX_DEBUG2("CMPXAutoResumeHandler::IsPlaybackRemote() exiting: %d", isRemote); + return isRemote; + } + +// ----------------------------------------------------------------------------- +// Set autoresume value +// ----------------------------------------------------------------------------- +// +void CMPXAutoResumeHandler::SetAutoResume(TBool aAutoResume) + { + MPX_DEBUG2("CMPXAutoResumeHandler::SetAutoResume(): AutoResume = %d", aAutoResume); + iAutoResume = aAutoResume; + } + +// End of File