diff -r 1934667b0e2b -r 4b59561a31c0 bluetoothengine/btsac/btrcc/src/btrccplayerstarter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/btsac/btrcc/src/btrccplayerstarter.cpp Wed Oct 13 14:43:49 2010 +0300 @@ -0,0 +1,303 @@ +/* +* Copyright (c) 2008 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: This class launchs music player, then send play command +* to the player at 2 seconds timeout. +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include +#include "btrccplayerstarter.h" +#include "btaudioremconpskeys.h" +#include "debug.h" + +// MODULE DATA STRUCTURES + +// mpx playeris name is mpx.exe in 5.0. +// it is musicplayer.exe in 3.2. +_LIT(KMpxPlayerExeName, "mpx.exe"); + +_LIT(KMpxPlayerSearchPatternBySID, "*102072c3*"); +_LIT(KVideoPlayerSearchPatternBySID, "*200159B2*"); + +static const TInt KPlayCmdToPlayerDelay = 6000000; // value will be tuned later + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// CPlayerStarter::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CPlayerStarter* CPlayerStarter::NewL() + { + CPlayerStarter* self = new (ELeave) CPlayerStarter(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CPlayerStarter::SetCoreTarget(CRemConCoreApiTarget& aTarget) + { + iCoreTarget = &aTarget; + } + +// ----------------------------------------------------------------------------- +// CPlayerStarter::CPlayerStarter +// C++ constructor. +// ----------------------------------------------------------------------------- +// +CPlayerStarter::CPlayerStarter() + :CActive(EPriorityNormal) + { + CActiveScheduler::Add(this); + } + +// ----------------------------------------------------------------------------- +// CPlayerStarter::ConstructL +// Symbian 2nd phase constructor. +// ----------------------------------------------------------------------------- +// +void CPlayerStarter::ConstructL() + { + TRACE_FUNC + iTimer.CreateLocal(); + } + +// ----------------------------------------------------------------------------- +// Destructor. +// ----------------------------------------------------------------------------- +// +CPlayerStarter::~CPlayerStarter() + { + TRACE_FUNC + // Starting player is not finished yet, send play command. Just wish the player + // can receive it. + if (IsActive() && iState != ERespondPlayNok) + { + RProperty::Set(KBTAudioRemCon, KBTAudioPlayerControl, + EBTAudioResumePlayer); + } + Cancel(); + iTimer.Close(); + } + +// ----------------------------------------------------------------------------- +// CPlayerStarter::RunL +// ----------------------------------------------------------------------------- +// +void CPlayerStarter::RunL() + { + TRACE_INFO((_L("CPlayerStarter::RunL() state %d, status %d"), iState, iStatus.Int())); + if (iStatus != KErrNone) + { + iState = EIdle; + return; + } + switch (iState) + { + case ERespondPlayOk: + { + // Response OK has been sent to the remote device, start timer waiting + // for player's initialization. + iTimer.After(iStatus, KPlayCmdToPlayerDelay); + SetActive(); + iState = EPlayMusicTiming; + TRACE_INFO(_L("schedule PLAY command ...")); + break; + } + case EPlayMusicTiming: + { + // Player should have fully up and running. Send PLAY command to it + // through our internal Play API. + RProperty::Set(KBTAudioRemCon, KBTAudioPlayerControl, + EBTAudioResumePlayer); + TRACE_INFO(_L("PLAY command sent to btmonobearer")); + iState = EIdle; + break; + } + default: + { + iState = EIdle; + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CPlayerStarter::RunError +// ----------------------------------------------------------------------------- +// +TInt CPlayerStarter::RunError(TInt aError) + { + TRACE_FUNC + (void) aError; + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CPlayerStarter::DoCancel +// ----------------------------------------------------------------------------- +// +void CPlayerStarter::DoCancel() + { + TRACE_FUNC + switch (iState) + { + case ERespondPlayOk: + case ERespondPlayNok: + { + // This cancel won't cancel the response sending to the remote + // device. (RemCon FW's cancel mechanism is only completing client's request. + // the real operation in its server side won't be stopped.) + iCoreTarget->Cancel(); + break; + } + case EPlayMusicTiming: + { + iTimer.Cancel(); + break; + } + } + } +// --------------------------------------------------------------------------- +// A 'play' command has been received. +// --------------------------------------------------------------------------- +// +void CPlayerStarter::MrccatoPlay( + TRemConCoreApiPlaybackSpeed /* aSpeed */, + TRemConCoreApiButtonAction aButtonAct ) + { + TRACE_FUNC + if ( ( aButtonAct == ERemConCoreApiButtonClick ) || + ( aButtonAct == ERemConCoreApiButtonPress ) ) + { + StartPlayIfNeeded(); + } + } + +// --------------------------------------------------------------------------- +// A command has been received. +// --------------------------------------------------------------------------- +// +void CPlayerStarter::MrccatoCommand( + TRemConCoreApiOperationId aOperationId, + TRemConCoreApiButtonAction aButtonAct ) + { + TRACE_INFO((_L("CPlayerStarter::MrccatoCommand opId %d, button %d"), + aOperationId, aButtonAct)); + switch (aOperationId) + { + case ERemConCoreApiPlay: + { + if ( ( aButtonAct == ERemConCoreApiButtonClick ) || + ( aButtonAct == ERemConCoreApiButtonPress ) ) + { + StartPlayIfNeeded(); + } + break; + } + case ERemConCoreApiStop: + case ERemConCoreApiPause: + { + if ( ( aButtonAct == ERemConCoreApiButtonClick ) || + ( aButtonAct == ERemConCoreApiButtonPress ) ) + { + // if starting player is ongoing, possibly PLAY command has been scheduled + // need to abort it. + Cancel(); + } + break; + } + default: + { + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CPlayerStarter::StartPlayIfNeeded +// ----------------------------------------------------------------------------- +// +void CPlayerStarter::StartPlayIfNeeded() + { + TRACE_FUNC + // unfinished business ongoing, eat the event. + if (IsActive()) + { + return; + } + if (!IsMusicPlayerRunning() && !IsVideoPlayerRunning()) + { + TRAPD(err, LaunchMusicPlayerL()); + // Send the response of play command to remote device + iCoreTarget->PlayResponse(iStatus, err); + SetActive(); + iState = (err) ? ERespondPlayNok : ERespondPlayOk; + } + } + +TBool CPlayerStarter::IsMusicPlayerRunning() + { + TRACE_FUNC + // Music player is running if we can find a thread whose name contains + // S60 Music Player's SID. + TFindThread findt(KMpxPlayerSearchPatternBySID); + TFullName result; + TBool running(EFalse); + if (!findt.Next(result)) + { + TRACE_INFO((_L("Thread '%S'is found"), &result)); + running = ETrue; + } + return running; + } + +TBool CPlayerStarter::IsVideoPlayerRunning() + { + TRACE_FUNC + // Video player is running if we can find a thread whose name contains + // Video Player's SID. + TFindThread findt(KVideoPlayerSearchPatternBySID); + TFullName result; + TBool running(EFalse); + if (!findt.Next(result)) + { + TRACE_INFO((_L("Thread '%S'is found"), &result)); + running = ETrue; + } + return running; + } + +void CPlayerStarter::LaunchMusicPlayerL() + { + RApaLsSession ls; + User::LeaveIfError(ls.Connect()); + CleanupClosePushL(ls); + CApaCommandLine* cmd = CApaCommandLine::NewL(); + CleanupStack::PushL(cmd); + cmd->SetExecutableNameL( KMpxPlayerExeName ); + cmd->SetCommandL( EApaCommandOpen ); + User::LeaveIfError(ls.StartApp( *cmd )); + CleanupStack::PopAndDestroy(2); // cmd, ls + } + + +// End of File