--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mpxplugins/serviceplugins/playbackplugins/progressdownload/src/mpxprogressdownload.cpp Thu Dec 17 08:45:05 2009 +0200
@@ -0,0 +1,1316 @@
+/*
+* 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: This class manages progress download
+*
+*/
+
+
+// INCLUDE FILES
+#include <f32plugin.h>
+#include <AudioPreference.h>
+#include <badesca.h>
+#include <apgcli.h>
+#include <mmf/common/mmfcontrollerframeworkbase.h>
+#include <mmf/common/mmfmeta.h>
+#include <mpxcommandgeneraldefs.h>
+#include <mpxmedia.h>
+#include <mpxplaybackpluginobserver.h>
+#include <mpxmediaaudiodefs.h>
+#include <mpxmediamusicdefs.h>
+#include <mpxmediageneraldefs.h>
+#include <mpxmediadrmdefs.h>
+#include <mpxcmn.h>
+#include <mpxdrmmediautility.h>
+#include <mpxprivatecrkeys.h>
+#include <mpxcenrepwatcher.h>
+#include <mpxlog.h>
+
+#include "mpxprogressdownload.h"
+
+
+// CONSTANTS
+const TUid KProgressDownloadUid={0x101FFC09};
+const TInt KProgressPlayEndThreshold=8000000; // 8 seconds, in milliseconds
+
+_LIT(KMMFMetaEntryAuthor, "author"); // For WMA progressive download
+
+// ============================ LOCAL FUNCTIONS ==============================
+LOCAL_C TInt Balance(TInt aMMFBalance)
+ {
+ return (aMMFBalance-KMMFBalanceCenter) *
+ (EPbBalanceMaxRight-EPbBalanceMaxLeft) /
+ (KMMFBalanceMaxRight-KMMFBalanceMaxLeft);
+ }
+
+LOCAL_C TInt MMFBalance(TInt aBalance)
+ {
+ return KMMFBalanceCenter+(KMMFBalanceMaxRight-KMMFBalanceMaxLeft)/
+ (EPbBalanceMaxRight-EPbBalanceMaxLeft)*aBalance;
+ }
+
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXProgressDownload* CMPXProgressDownload::NewL(TAny* /*aInitParams*/)
+ {
+ CMPXProgressDownload* p=new(ELeave)CMPXProgressDownload();
+ CleanupStack::PushL(p);
+ p->ConstructL();
+ CleanupStack::Pop(p);
+ return p;
+ }
+
+// ----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::ConstructL()
+ {
+ iVolumeWatcher = CMPXCenRepWatcher::NewL(KCRUidMPXSettings,
+ KMPXPlaybackVolume,
+ this);
+ iMuteWatcher = CMPXCenRepWatcher::NewL(KCRUidMPXSettings,
+ KMPXPlaybackMute,
+ this);
+ iFeatureFlag = EPbFeatureBalance | EPbFeatureVolumeRamp;
+ iDrmMediaUtility = CMPXDrmMediaUtility::NewL();
+ }
+
+// ----------------------------------------------------------------------------
+// C++ constructor
+// ----------------------------------------------------------------------------
+//
+CMPXProgressDownload::CMPXProgressDownload()
+ {}
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CMPXProgressDownload::~CMPXProgressDownload()
+ {
+ delete iMuteWatcher;
+ delete iVolumeWatcher;
+ if ( iDrmMediaUtility )
+ {
+ if ( EPbDlStateDownloadCompleted == iDownloadState )
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EStop ) );
+ }
+ delete iDrmMediaUtility;
+ }
+ if (iPdPlayer)
+ {
+ iPdPlayer->Close();
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPActive,EFalse,KErrNone);
+ delete iPdPlayer;
+ }
+ delete iPdUtil;
+ delete iPdPath;
+ }
+
+// ----------------------------------------------------------------------------
+// Initializes a song for playback
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::InitialiseL(const TDesC& aSong)
+ {
+ MPX_DEBUG2("CMPXProgressDownload::InitialiseL(%S) entering", &aSong );
+
+ // Re-initialize ProgressiveDownloadUtility to make sure multiple sequential
+ // downloads work
+ delete iPdPlayer;
+ iPdPlayer = NULL;
+ delete iPdUtil;
+ iPdUtil = NULL;
+ iPdUtil = CProgressiveDownloadUtility::NewL();
+
+ iPdPlayer = iPdUtil->OpenL( aSong, *this );
+ delete iPdPath;
+ iPdPath = NULL;
+ iPdPath = aSong.AllocL();
+ iDownloadState = EPbDlStateBuffering;
+ iState = EStateInitialising;
+ iConsumeStarted = EFalse;
+
+ MPX_DEBUG1("CMPXProgressDownload::InitialiseL() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Initializes a song for playback
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::InitialiseL(RFile& aSong)
+ {
+ MPX_DEBUG1("CMPXProgressDownload::InitialiseL(RFile) entering");
+
+ // Re-initialize ProgressiveDownloadUtility to make sure multiple sequential
+ // downloads work
+ delete iPdPlayer;
+ iPdPlayer = NULL;
+ delete iPdUtil;
+ iPdUtil = NULL;
+ iPdUtil = CProgressiveDownloadUtility::NewL();
+
+ iPdPlayer = iPdUtil->OpenL( aSong, *this );
+ delete iPdPath;
+ iPdPath = NULL;
+ TFileName filename;
+ aSong.FullName(filename);
+ iPdPath = filename.AllocL();
+ iDownloadState = EPbDlStateBuffering;
+ iState = EStateInitialising;
+ iConsumeStarted = EFalse;
+
+ MPX_DEBUG1("CMPXProgressDownload::InitialiseL() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Executes a command on the selected song
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::CommandL(TMPXPlaybackCommand aCmd, TInt /*aData*/)
+ {
+ MPX_DEBUG2("CMPXProgressDownload::CommandL(%d) entering", aCmd);
+
+ if (iPdPlayer)
+ {
+ switch(aCmd)
+ {
+ case EPbCmdPlay:
+ {
+ if ( EPbDlStateDownloadCompleted == iDownloadState )
+ {
+ if (iConsumeStarted)
+ {
+ ConsumeRightsL( ContentAccess::EContinue );
+ }
+ else
+ {
+ MPX_TRAPD( AEErr, ConsumeRightsL( ContentAccess::EPlay ) );
+ if (AEErr == KErrDiskFull)
+ {
+ iDrmMediaUtility->Close();
+ iPdPlayer->Close();
+ iState = EStateNotInitialised;
+ iDownloadState = EPbDlStateNotDownloading;
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPClosed,
+ 0, KErrDiskFull);
+ break;
+ }
+ iConsumeStarted = ETrue;
+ }
+ }
+ iPdPlayer->Play();
+ iState = EStateInitialised;
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPPlaying,
+ 0, KErrNone);
+ break;
+ }
+ case EPbCmdPause:
+ if ( EPbDlStateDownloadCompleted == iDownloadState && iConsumeStarted )
+ {
+ ConsumeRightsL( ContentAccess::EPause );
+ }
+ iPdPlayer->Pause();
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPPaused,
+ 0, KErrNone);
+ break;
+ case EPbCmdStop:
+ if ( EPbDlStateDownloadCompleted == iDownloadState && iConsumeStarted )
+ {
+ ConsumeRightsL( ContentAccess::EStop );
+ iConsumeStarted = EFalse;
+ }
+ iDrmMediaUtility->Close();
+ iPdPlayer->Stop();
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPStopped,
+ 0, KErrNone);
+ break;
+ case EPbCmdClose:
+ if ( EPbDlStateDownloadCompleted == iDownloadState && iConsumeStarted )
+ {
+ ConsumeRightsL( ContentAccess::EStop );
+ iConsumeStarted = EFalse;
+ }
+ iDrmMediaUtility->Close();
+ iPdPlayer->Close();
+ iState = EStateNotInitialised;
+ iDownloadState = EPbDlStateNotDownloading;
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPClosed,
+ 0, KErrNone);
+ break;
+ }
+ }
+
+ MPX_DEBUG1("CMPXProgressDownload::CommandL() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Executes a command
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::CommandL( CMPXCommand& aCmd )
+ {
+ MPX_FUNC("CMPXProgressDownload::CommandL(CMPXCommand)");
+
+ ASSERT( aCmd.IsSupported( KMPXCommandGeneralId ));
+ TInt id( aCmd.ValueTObjectL<TInt>( KMPXCommandGeneralId ));
+ if ( KMPXCommandIdPlaybackPD == id )
+ {
+ ASSERT(aCmd.IsSupported(KMPXCommandPlaybackGeneralType));
+ TMPXPlaybackPdCommand cmd(
+ static_cast<TMPXPlaybackPdCommand>(
+ aCmd.ValueTObjectL<TInt>(KMPXCommandPlaybackGeneralType)));
+ switch ( cmd )
+ {
+ case ( EPbCmdStartPd ):
+ {
+ ASSERT( aCmd.IsSupported( KMPXCommandPlaybackPDTransactionID ));
+ iTransactionId = aCmd.ValueTObjectL<TUint>( KMPXCommandPlaybackPDTransactionID );
+ break;
+ }
+ case ( EPbCmdFinishPd ):
+ {
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPPlayComplete,
+ 0,
+ KErrNone);
+ break;
+ }
+ case ( EPbCmdHandlePdEvent ):
+ {
+ ASSERT( aCmd.IsSupported( KMPXCommandPlaybackPDTransactionID ) &&
+ aCmd.IsSupported( KMPXCommandPlaybackPDEvent ) &&
+ aCmd.IsSupported( KMPXCommandPlaybackGeneralData ));
+ TUint transId( aCmd.ValueTObjectL<TUint>( KMPXCommandPlaybackPDTransactionID ));
+ TBrCtlDownloadEvent event(
+ aCmd.ValueTObjectL<TBrCtlDownloadEvent>( KMPXCommandPlaybackPDEvent ));
+ TUint val( aCmd.ValueTObjectL<TUint>( KMPXCommandPlaybackGeneralData ));
+ HandleDownloadEventL( transId, event, val );
+ break;
+ }
+ case ( EPbCmdGetPdStatus ):
+ {
+ aCmd.SetTObjectValueL<TUint>(
+ KMPXCommandPlaybackPDTransactionID,
+ iTransactionId );
+ aCmd.SetTObjectValueL<TMPXPlaybackPdDownloadState>(
+ KMPXCommandPlaybackPDState,
+ static_cast<TMPXPlaybackPdDownloadState>(iDownloadState));
+ aCmd.SetTObjectValueL<TInt>(
+ KMPXCommandPlaybackPDDownloadedBytes,
+ iDownloadBytes );
+ aCmd.SetTObjectValueL<TInt>(
+ KMPXCommandPlaybackPDTotalBytes,
+ iDownloadSize );
+ break;
+ }
+ case ( EPbCmdPausePd ):
+ {
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadCmdPauseDownload,
+ iTransactionId,
+ KErrNone );
+ break;
+ }
+ case ( EPbCmdResumePd ):
+ {
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadCmdResumeDownload,
+ iTransactionId,
+ KErrNone );
+ break;
+ }
+ case ( EPbCmdCancelPd ):
+ {
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadCmdCancelDownload,
+ iTransactionId,
+ KErrNone);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Sets a property of the plugin
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::SetL(TMPXPlaybackProperty aProperty, TInt aValue)
+ {
+ MPX_DEBUG3("CMPXProgressDownload::SetL(%d, %d) entering", aProperty, aValue);
+
+ TBool isSupported=ETrue;
+ switch(aProperty)
+ {
+ case EPbPropertyVolume:
+ {
+ SetVolume( aValue );
+ break;
+ }
+ case EPbPropertyVolumeRamp:
+ iPdPlayer->SetVolumeRamp(TTimeIntervalMicroSeconds(TInt64(aValue)));
+ break;
+ case EPbPropertyMute:
+ SetMute( aValue );
+ break;
+ case EPbPropertyBalance:
+ iPdPlayer->SetBalance(MMFBalance(aValue));
+ break;
+ case EPbPropertyPosition:
+ {
+ TInt64 pos(aValue);
+ pos *= KPbMilliMultiplier;
+ iPdPlayer->SetPosition(pos);
+ }
+ break;
+ default:
+ isSupported=EFalse;
+ }
+
+ if (!isSupported)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPSetComplete,
+ aProperty, KErrNone);
+
+ MPX_DEBUG1("CMPXProgressDownload::SetL() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Gets a property of the plugin (async)
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::PropertyL(TMPXPlaybackProperty aProperty) const
+ {
+ MPX_DEBUG2("CMPXProgressDownload::ValueL(%d) entering", aProperty);
+
+ TBool isSupported=ETrue;
+ TInt value=KErrNotFound;
+ TInt err(KErrNone);
+ switch(aProperty)
+ {
+ case EPbPropertyVolume:
+ {
+ value = iVolumeWatcher->CurrentValueL();
+ break;
+ }
+ case EPbPropertyMaxVolume:
+ value=iPdPlayer->MaxVolume();
+ break;
+ case EPbPropertyMute:
+ value = iMuteWatcher->CurrentValueL();
+ break;
+ case EPbPropertyBalance:
+ err = iPdPlayer->GetBalance(value);
+ value=Balance(value);
+ break;
+ case EPbPropertyDuration:
+ {
+ TTimeIntervalMicroSeconds duration = iPdPlayer->Duration();
+ value = duration.Int64() / KPbMilliMultiplier;
+ }
+ break;
+ case EPbPropertyPosition:
+ {
+ TTimeIntervalMicroSeconds pos;
+ iPdPlayer->GetPosition(pos);
+ value = pos.Int64() / KPbMilliMultiplier;
+ }
+ break;
+ case EPbPropertySupportedFeatures:
+ value = iFeatureFlag;
+ break;
+ default:
+ isSupported=EFalse;
+ }
+ if (!isSupported)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ iObs->HandleProperty(aProperty,value,err);
+
+ MPX_DEBUG1("CMPXProgressDownload::ValueL() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Gets a list of sub players, UPnP only
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::SubPlayerNamesL()
+ {
+ iObs->HandleSubPlayerNames(KProgressDownloadUid, NULL, ETrue, KErrNone);
+ }
+
+// ----------------------------------------------------------------------------
+// Select a sub player
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::SelectSubPlayerL(TInt /*aIndex*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+// ----------------------------------------------------------------------------
+// Returns current sub player name
+// ----------------------------------------------------------------------------
+//
+const TDesC& CMPXProgressDownload::SubPlayerName()
+ {
+ return KNullDesC; //No subplayer name for local playback
+ }
+
+// ----------------------------------------------------------------------------
+// Current sub player index
+// ----------------------------------------------------------------------------
+//
+TInt CMPXProgressDownload::SubPlayerIndex() const
+ {
+ return KErrNotFound;
+ }
+
+// ----------------------------------------------------------------------------
+// Gets media properties
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::MediaL(const TArray<TMPXAttribute>& aAttrs)
+ {
+ MPX_DEBUG1("CMPXProgressDownload::MediaL() entering");
+
+ RArray<TInt> suppIds;
+ CleanupClosePushL(suppIds);
+ suppIds.AppendL(KMPXMediaIdMusic);
+ suppIds.AppendL(KMPXMediaIdGeneral);
+ suppIds.AppendL(KMPXMediaIdAudio);
+ CMPXMedia* media=CMPXMedia::NewL(suppIds.Array());
+ CleanupStack::PopAndDestroy(&suppIds);
+ CleanupStack::PushL(media);
+
+ TUint attrG(0); // General attributes
+ TUint attrA(0); // Audio attributes
+ TUint attrM(0); // Music attributes
+ TUint attrD(0); // DRM attributes
+
+ for (TInt i=aAttrs.Count(); --i>=0;)
+ {
+ TMPXAttribute attr(aAttrs[i]);
+ if (attr.ContentId() == KMPXMediaIdGeneral)
+ {
+ attrG |= attr.AttributeId();
+ }
+ else if (attr.ContentId() == KMPXMediaIdMusic)
+ {
+ attrM |= attr.AttributeId();
+ }
+ else if (attr.ContentId() == KMPXMediaIdAudio)
+ {
+ attrA |= attr.AttributeId();
+ }
+ else if ( attr.ContentId() == KMPXMediaIdDrm )
+ {
+ attrD |= attr.AttributeId();
+ }
+ }
+
+ // Get number of metadata
+ TInt metaCount = 0;
+
+ // Get metadata from MMF
+ TInt error = iPdPlayer->GetNumberOfMetaDataEntries(metaCount);
+ MPX_DEBUG3("CMPXProgressDownload::MediaL(): metaCount = %d, error = %d", metaCount, error);
+ CMMFMetaDataEntry* metaData = NULL;
+
+ if (!error)
+ {
+ if ( metaCount > 0 )
+ {
+ for (TInt i = 0; i < metaCount; ++i)
+ {
+ metaData = iPdPlayer->GetMetaDataEntryL(i);
+ CleanupStack::PushL(metaData);
+
+ if (metaData->Name().CompareF(KMMFMetaEntrySongTitle()) == 0 &&
+ attrG & EMPXMediaGeneralTitle)
+ { // TODO to check request
+ if ( metaData->Value().Length() > 0 )
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ metaData->Value());
+ }
+ else if ( iPdPath )
+ {
+ TParsePtrC ptr( *iPdPath );
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ ptr.Name() );
+ }
+ else
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ KNullDesC );
+ }
+ }
+ else if( ( metaData->Name().CompareF( KMMFMetaEntryArtist() ) == 0 ||
+ metaData->Name().CompareF( KMMFMetaEntryAuthor() ) == 0 ) &&
+ attrM & EMPXMediaMusicArtist)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicArtist),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryAlbum()) == 0 &&
+ attrM & EMPXMediaMusicAlbum)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicAlbum),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryYear()) == 0 &&
+ attrM & EMPXMediaMusicYear)
+ {
+ TInt year;
+ TLex lex( metaData->Value() );
+ lex.Val( year );
+
+ TDateTime dt;
+ dt.SetYear( year );
+ TTime time( dt );
+
+ media->SetTObjectValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicYear),
+ time.Int64());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryComment()) == 0 &&
+ attrG & EMPXMediaGeneralComment)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralComment),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryComposer()) == 0 &&
+ attrM & EMPXMediaMusicComposer)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicComposer),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryAlbumTrack()) == 0 &&
+ attrM & EMPXMediaMusicAlbumTrack)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicAlbumTrack),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryGenre()) == 0 &&
+ attrM & EMPXMediaMusicGenre)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicGenre),
+ metaData->Value());
+ }
+ //else if (metaData->Name().CompareF(KMMFMetaEntryWOAF()) == 0 &&
+ // attrM & EMPXMediaMusicGenre)
+ // {
+ //media->SetTextValueL(
+ // TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicGenre),
+ // metaData->Value());
+ //}
+ else if (metaData->Name().CompareF(KMMFMetaEntryAPIC()) == 0 &&
+ attrM & EMPXMediaMusicAlbumArtFileName)
+ {
+ // TODO check collection if user defined album art available
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicAlbumArtFileName),
+ *iPdPath);
+ }
+ CleanupStack::PopAndDestroy(metaData);
+ metaData = NULL;
+ }
+ }
+ else // metaCount == 0
+ {
+ // no metadata available, use file path for a couple of the attributes
+ if ( attrG & EMPXMediaGeneralTitle )
+ { // TODO to check request
+ MPX_DEBUG2( "CMPXProgressDownload::MediaL() iPdPath = 0x%x", iPdPath );
+ if ( iPdPath )
+ {
+ TParsePtrC ptr( *iPdPath );
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ ptr.Name() );
+ }
+ else
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ KNullDesC );
+ }
+ }
+ if ( ( attrM & EMPXMediaMusicAlbumArtFileName ) && iPdPath )
+ {
+ // TODO check collection if user defined album art available
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicAlbumArtFileName),
+ *iPdPath);
+ }
+ }
+ }
+ else // if error, then use the file path to display (for the Active Idle case)
+ {
+ if ( attrG & EMPXMediaGeneralTitle )
+ {
+ MPX_DEBUG2( "**** CMPXProgressDownload::MediaL() iPdPath = 0x%x", iPdPath );
+ if ( iPdPath )
+ {
+ TParsePtrC ptr( *iPdPath );
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ ptr.Name() );
+ }
+ else
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ KNullDesC );
+ }
+ }
+ }
+
+
+ if (attrG & EMPXMediaGeneralUri)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralUri),
+ *iPdPath);
+ }
+
+ if (attrG & EMPXMediaGeneralDuration)
+ {
+ TTimeIntervalMicroSeconds duration = iPdPlayer->Duration();
+ media->SetTObjectValueL<TInt>(
+ TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration),
+ duration.Int64() / KPbMilliMultiplier);
+ }
+
+ // Set bitrate
+ TPckgBuf<TMMFAudioConfig> data;
+
+ const TMMFMessageDestinationPckg
+ destinationPckg(KUidInterfaceMMFAudioController);
+
+ if (attrA & EMPXMediaAudioBitrate)
+ {
+ error = iPdPlayer->CustomCommandSync(destinationPckg,
+ EMMFAudioControllerGetSourceBitRate, KNullDesC8, KNullDesC8, data);
+ if (!error)
+ {
+ media->SetTObjectValueL<TInt>(
+ TMPXAttribute(KMPXMediaIdAudio, EMPXMediaAudioBitrate),
+ data().iSampleRate);
+ }
+ }
+
+ if (attrA & EMPXMediaAudioSamplerate)
+ {
+
+ // Set sampling rate
+ error = iPdPlayer->CustomCommandSync(destinationPckg,
+ EMMFAudioControllerGetSourceSampleRate, KNullDesC8, KNullDesC8, data);
+ if (!error)
+ {
+ media->SetTObjectValueL<TInt>(
+ KMPXMediaAudioSamplerate,
+ data().iSampleRate);
+ }
+ }
+
+ if (attrG & EMPXMediaGeneralSize)
+ {
+ RFs fs;
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEntry entry;
+ fs.Entry(iPdPath->Des(), entry);
+ media->SetTObjectValueL<TInt>(
+ TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralSize),
+ entry.iSize);
+ CleanupStack::PopAndDestroy(&fs);
+ }
+
+ if (attrG & EMPXMediaGeneralMimeType)
+ {
+ RApaLsSession aps;
+ error = aps.Connect(); // always fail in console test
+ if (KErrNone == error)
+ {
+ CleanupClosePushL(aps);
+ TDataType dataType;
+ TUid ignore;
+ if(aps.AppForDocument(iPdPath->Des(),ignore,dataType)==KErrNone)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralMimeType),
+ dataType.Des());
+ }
+ CleanupStack::PopAndDestroy(&aps);
+ } // Notes, STIF console test always fail
+ }
+
+ // Set DRM info
+ // Only try to get DRM info if the song has completed downloading
+ MPX_DEBUG2("CMPXProgressDownload::MediaL(): iDownloadState = %d", iDownloadState);
+ if ( EPbDlStateDownloadCompleted == iDownloadState )
+ {
+ const CMPXMedia* drmMedia( iDrmMediaUtility->GetMediaL( attrD ));
+ if ( drmMedia )
+ {
+ TInt count( drmMedia->Count() );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ TUint attrId( drmMedia->Attribute(i).AttributeId() );
+ if ( attrD & attrId )
+ {
+ TMPXAttribute mpxAtt( KMPXMediaIdDrm, attrId );
+ switch ( attrId )
+ {
+ case EMPXMediaDrmType:
+ case EMPXMediaDrmRightsStatus:
+ case EMPXMediaDrmRightsType:
+ case EMPXMediaDrmCount:
+ {
+ TInt val(
+ drmMedia->ValueTObjectL<TInt>( mpxAtt ));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ case EMPXMediaDrmProtected:
+ case EMPXMediaDrmSendingAllowed:
+ case EMPXMediaDrmCanSetAutomated:
+ case EMPXMediaDrmHasInfoUrl:
+ case EMPXMediaDrmHasPreviewUrl:
+ case EMPXMediaDrmAboutToExpire:
+ {
+ TBool val(
+ drmMedia->ValueTObjectL<TBool>( mpxAtt ));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ case EMPXMediaDrmStartTime:
+ case EMPXMediaDrmEndTime:
+ case EMPXMediaDrmIntervalStartTime:
+ case EMPXMediaDrmAccumulatedTime:
+ {
+ TInt64 val(
+ drmMedia->ValueTObjectL<TInt64>( mpxAtt ));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ case EMPXMediaDrmInterval:
+ {
+ TTimeIntervalSeconds val(
+ drmMedia->ValueTObjectL<TTimeIntervalSeconds>(mpxAtt));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ } // end switch (attriId)
+ } // end if ( attrD & attrId )
+ }
+ }
+ }
+
+ iObs->HandleMedia(*media, KErrNone);
+ CleanupStack::PopAndDestroy(media);
+
+ MPX_DEBUG1("CMPXProgressDownload::MediaL() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Cancel request
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::CancelRequest()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// File open complete event
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::MapcInitComplete(TInt aError,
+ const TTimeIntervalMicroSeconds& aDuration)
+ {
+ MPX_DEBUG2("CMPXProgressDownload::MapcInitComplete(%d) entering", aError);
+
+ iState = EStateInitialised;
+
+ // Restore volume level
+ if ( KErrNone == aError )
+ {
+ TInt currentVol( 0 );
+ MPX_TRAPD( volError, currentVol = iVolumeWatcher->CurrentValueL() );
+ if ( volError == KErrNone )
+ {
+ SetVolume( currentVol );
+ TBool mute( EFalse);
+ MPX_TRAPD( muteError, mute = iMuteWatcher->CurrentValueL() );
+ if ( muteError == KErrNone && mute )
+ {
+ SetMute(mute);
+ }
+ }
+ }
+
+ if ( iPdPlayer )
+ {
+ MMMFDRMCustomCommand* drmCustom = iPdPlayer->GetDRMCustomCommand();
+ if ( drmCustom )
+ {
+ drmCustom->DisableAutomaticIntent( ETrue );
+ }
+ }
+ if ( EPbDlStateDownloadCompleted == iDownloadState )
+ {
+ TRAP_IGNORE( iDrmMediaUtility->InitL( *iPdPath ));
+ }
+
+ if ( EPbDlStateBuffering == iDownloadState )
+ {
+ iDownloadState = EPbDlStateDownloading;
+ TRAP_IGNORE(
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPDownloadStateChanged,
+ iDownloadState, aError));
+ }
+
+ TRAP_IGNORE(
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPActive,
+ ETrue,aError);
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPInitialised,
+ aDuration.Int64()/KPbMilliMultiplier,aError);
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPPaused,
+ 0,aError));
+
+ MPX_DEBUG1("CMPXProgressDownload::MapcInitComplete() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// File play complete event
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::MapcPlayComplete(TInt aError)
+ {
+ MPX_DEBUG2("CMPXProgressDownload::MapcPlayComplete(%d) entering", aError);
+
+ iState = EStateNotInitialised;
+
+ // START WORKAROUND
+ // Check if error is KErrDied and played to the end, then just
+ // treat that as a normal play complete and overwrite the error
+ // handling here
+ // NOTE: This is only a temporary workaround for S60 3.1.
+ // S60 3.2 will have a proper fix in the PD Utility
+ if ( KErrDied == aError )
+ {
+ MPX_DEBUG2("MPXProgressDownload::MapcPlayComplete(): iDownloadState = %d", iDownloadState);
+ if ( EPbDlStateDownloadCompleted == iDownloadState )
+ {
+ TTimeIntervalMicroSeconds dur( iPdPlayer->Duration() );
+ TTimeIntervalMicroSeconds pos;
+ iPdPlayer->GetPosition(pos);
+ if ( Abs( dur.Int64() - pos.Int64() ) < KProgressPlayEndThreshold &&
+ dur.Int64() > KProgressPlayEndThreshold )
+ {
+ MPX_DEBUG1("CMPXProgressDownload::MapcPlayComplete(): Resetting error to KErrNone");
+ aError = KErrNone;
+ }
+ }
+ }
+ // END WORKAROUND
+
+ // KErrEof is sometimes returned when play finishes at the end
+ if ( KErrEof == aError )
+ {
+ aError = KErrNone;
+ }
+
+ if ( iConsumeStarted )
+ {
+ if ( KErrNone != aError )
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EPause ) );
+ }
+ else
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EStop ) );
+ }
+ iConsumeStarted = EFalse;
+ }
+
+ // If killed by audio policy, mimic a paused state
+ if ( KErrDied == aError )
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPaused,
+ 0,
+ aError );
+ }
+ else
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPlayComplete,
+ 0,
+ aError);
+ }
+
+ MPX_DEBUG1("CMPXProgressDownload::MapcPlayComplete() exiting");
+ }
+
+// -----------------------------------------------------------------------------
+// CMPXProgressDownload::Paused
+// -----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::Paused()
+ {
+ MPX_DEBUG1("CMPXProgressDownload::Paused() entering");
+
+ // This callback will only be called when the PD Utility runs out
+ // of data (i.e. all downloaded content has been played).
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPaused,
+ 0,
+ KErrUnderflow);
+ MPX_DEBUG1("CMPXProgressDownload::Paused() exiting");
+ }
+
+// -----------------------------------------------------------------------------
+// CMPXProgressDownload::Playing
+// -----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::Playing()
+ {
+ MPX_DEBUG1("CMPXProgressDownload::Playing() entering");
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPPlaying,
+ 0,
+ KErrNone);
+ MPX_DEBUG1("CMPXProgressDownload::Playing() exiting");
+ }
+
+// -----------------------------------------------------------------------------
+// CMPXProgressDownload::HandleDownloadEventL
+// -----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::HandleDownloadEventL(TUint aTransactionID,
+ TBrCtlDownloadEvent aEvent,
+ TUint aValue)
+ {
+ MPX_DEBUG4("CMPXProgressDownload::HandleDownloadEventL(%d, %d, %d) entering",
+ aTransactionID, aEvent, aValue);
+
+ // Notes. It is API in current music player which is called by MusicShop
+ //
+ if (iPdPlayer)
+ {
+ iPdPlayer->HandleDownloadEventL( aTransactionID, aEvent, aValue );
+
+ __ASSERT_DEBUG(
+ aTransactionID == iTransactionId,
+ User::Panic(_L("CMPlayerAudioUIController::HandleProgressiveDownloadEventL"),
+ KErrArgument));
+
+ switch (aEvent)
+ {
+ case EDownloadEventStarted:
+ {
+ iDownloadState = EPbDlStateBuffering;
+ iDownloadSize = static_cast<TInt>( aValue );
+
+ // send new state
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadStateChanged,
+ iDownloadState,
+ KErrNone);
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadStarted,
+ iDownloadSize,
+ KErrNone );
+ break;
+ }
+ case EDownloadEventCompleted:
+ {
+ iDownloadState = EPbDlStateDownloadCompleted;
+ iDownloadSize = static_cast<TInt>( aValue );
+ iDownloadBytes = iDownloadSize;
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadStateChanged,
+ iDownloadState,
+ KErrNone);
+ break;
+ }
+ case EDownloadEventCanceled:
+ {
+ iDownloadState = EPbDlStateNotDownloading;
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadStateChanged,
+ iDownloadState,
+ KErrNone);
+ break;
+ }
+ case EDownloadEventError:
+ {
+ iDownloadState = EPbDlStateDownloadError;
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadStateChanged,
+ iDownloadState,
+ KErrNone);
+ break;
+ }
+ case EDownloadEventProgress:
+ {
+ if ( EPbDlStateDownloadPaused == iDownloadState )
+ {
+ iDownloadState = EPbDlStateDownloading;
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadStateChanged,
+ iDownloadState,
+ KErrNone);
+ }
+ iDownloadBytes = static_cast<TInt>( aValue );
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadPositionChanged,
+ iDownloadBytes,
+ KErrNone);
+ break;
+ }
+ case EDownloadEventPaused:
+ {
+ iDownloadState = EPbDlStateDownloadPaused;
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPDownloadStateChanged,
+ iDownloadState,
+ KErrNone);
+ break;
+ }
+ case EDownloadEventPausable:
+ {
+ iFeatureFlag |= EPbFeaturePdPausable;
+ iObs->HandlePluginEvent(
+ MMPXPlaybackPluginObserver::EPSupportedFeaturesChanged,
+ iFeatureFlag,
+ KErrNone);
+ break;
+ }
+ default:
+ {
+ // pass
+ break;
+ }
+ }
+ }
+ MPX_DEBUG1("CMPXProgressDownload::HandleDownloadEventL() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Handle a change in a setting value.
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::HandleSettingChange(
+ const TUid& aRepositoryUid,
+ TUint32 aSettingId )
+ {
+ MPX_DEBUG1("CMPXProgressDownload::HandleSettingChange() entering");
+
+ if ( KCRUidMPXSettings == aRepositoryUid &&
+ KMPXPlaybackVolume == aSettingId )
+ {
+ MPX_DEBUG1("CMPXProgressDownload::HandleSettingChange() Volume setting changed");
+ TInt currentVol( 0 );
+ MPX_TRAPD( volError, currentVol = iVolumeWatcher->CurrentValueL() );
+ if ( KErrNone == volError )
+ {
+ SetVolume( currentVol );
+ }
+ }
+ else if ( KCRUidMPXSettings == aRepositoryUid &&
+ KMPXPlaybackMute == aSettingId )
+ {
+ MPX_DEBUG1("CMPXProgressDownload::HandleSettingChange() Mute setting changed");
+ TBool mute( EFalse );
+ MPX_TRAPD( error, mute = static_cast<TBool>(iMuteWatcher->CurrentValueL()) );
+ if ( error == KErrNone )
+ {
+ TInt oldVolume( 0 );
+ iPdPlayer->GetVolume( oldVolume );
+ if ( (mute && oldVolume != 0) || (!mute && oldVolume == 0) )
+ {
+ SetMute( mute );
+ }
+ }
+ }
+ MPX_DEBUG1("CMPXProgressDownload::HandleSettingChange() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Sets the volume level in audio controller
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::SetVolume( TInt aVolume )
+ {
+ MPX_DEBUG2("CMPXProgressDownload::SetVolume(%d) entering", aVolume);
+
+ // Ensure that level is within min and max values
+ if ( aVolume > KPbPlaybackVolumeLevelMax )
+ {
+ aVolume = KPbPlaybackVolumeLevelMax;
+ }
+ if ( aVolume < KPbPlaybackVolumeLevelMin )
+ {
+ aVolume = KPbPlaybackVolumeLevelMin;
+ }
+
+ TBool changed( EFalse );
+ // Change MMF Audio player's volume
+ if ( EStateInitialised == iState )
+ {
+ TInt newVolume( aVolume * iPdPlayer->MaxVolume() / 100 );
+ MPX_DEBUG2("CMPXProgressDownload::SetVolume(): Setting volume = %d", newVolume);
+
+ // First check if MMF Audio player's volume is changed by new value
+ TInt oldVolume( 0 );
+ iPdPlayer->GetVolume( oldVolume );
+ if ( newVolume != oldVolume )
+ {
+ iPdPlayer->SetVolume( newVolume );
+ changed = ETrue;
+ }
+ }
+
+ // Change setting in cenrep
+ TInt currentVol( 0 );
+ MPX_TRAPD( volError, currentVol = iVolumeWatcher->CurrentValueL() );
+ if ( volError == KErrNone && aVolume != currentVol )
+ {
+ MPX_TRAP( volError, iVolumeWatcher->SetValueL( aVolume ) );
+ }
+
+ // Notify observer if value changed
+ if ( changed )
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPVolumeChanged,
+ aVolume,
+ KErrNone);
+ }
+
+ MPX_DEBUG1("CMPXProgressDownload::SetVolume() exiting");
+ }
+
+// ----------------------------------------------------------------------------
+// Sets the volume level in audio controller
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::SetMute( TBool aMute )
+ {
+ MPX_DEBUG3("-->CMPXProgressDownload::SetMute 0x%08x vol (%d)", this, aMute);
+
+ TBool changed( EFalse );
+ // Change MMF Audio player's volume
+ TInt currentVolume(0);
+ iPdPlayer->GetVolume(currentVolume);
+ if ( aMute && currentVolume != 0 )
+ {
+ iVolume = currentVolume;
+ iPdPlayer->SetVolume(0);
+ changed = ETrue;
+ }
+ else if ( !aMute && currentVolume == 0 ) // UnMute
+ {
+ iPdPlayer->SetVolume(iVolume);
+ changed = ETrue;
+ }
+
+ // Change setting in cenrep
+ TBool currentMute( EFalse );
+ MPX_TRAPD( muteError, currentMute = iMuteWatcher->CurrentValueL() );
+ if ( muteError == KErrNone )
+ {
+ if ( aMute && !currentMute )
+ {
+ MPX_TRAP( muteError, iMuteWatcher->SetValueL( aMute ) );
+ }
+ else if ( !aMute && currentMute )
+ {
+ MPX_TRAP( muteError, iMuteWatcher->SetValueL( aMute ) );
+ }
+ }
+
+ // Notify observer if value changed
+ if ( changed )
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPMuteChanged,
+ aMute,
+ KErrNone);
+ }
+
+ MPX_DEBUG3("<--CMPXProgressDownload::SetMute 0x%08x vol (%d)", this, aMute);
+ }
+
+// ----------------------------------------------------------------------------
+// Consumes the rights for the current media
+// ----------------------------------------------------------------------------
+//
+void CMPXProgressDownload::ConsumeRightsL(ContentAccess::TIntent aIntent)
+ {
+ MPX_DEBUG2("-->CMPXProgressDownload::ConsumeRightsL(%d)", aIntent);
+ if ( iPdPlayer )
+ {
+ MMMFDRMCustomCommand* drmCustom = iPdPlayer->GetDRMCustomCommand();
+ if ( drmCustom )
+ {
+ switch ( aIntent )
+ {
+ case ContentAccess::EPlay:
+ case ContentAccess::EStop:
+ case ContentAccess::EPause:
+ case ContentAccess::EContinue:
+ {
+ break;
+ }
+ default:
+ {
+ aIntent = ContentAccess::EUnknown;
+ iConsumeStarted = EFalse;
+ break;
+ }
+ }
+ MPX_DEBUG2("-->CMPXProgressDownload::ConsumeRightsL(): Executing intent %d", aIntent);
+ TInt returnCode( drmCustom->ExecuteIntent(aIntent) );
+ MPX_DEBUG2("CMPXProgressDownload::ConsumeRightsL() ExecuteIntent return (%d)", returnCode);
+ User::LeaveIfError(returnCode);
+ }
+ }
+ MPX_DEBUG2("<--CMPXProgressDownload::ConsumeRightsL(%d)", aIntent);
+ }
+
+// End of file