mpx/playbackframework/playbackengine/src/mpxautoresumehandler.cpp
changeset 0 a2952bb97e68
child 11 780c925249c1
--- /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 <e32std.h>
+#include <ctsydomainpskeys.h>
+#include <mpxpskeywatcher.h>
+#include <mpxlog.h>
+#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<CMPXAutoResumeHandler*>(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