diff -r 000000000000 -r ff3acec5bc43 mpxplugins/serviceplugins/playbackplugins/progressdownload/src/mpxprogressdownload.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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( KMPXCommandGeneralId )); + if ( KMPXCommandIdPlaybackPD == id ) + { + ASSERT(aCmd.IsSupported(KMPXCommandPlaybackGeneralType)); + TMPXPlaybackPdCommand cmd( + static_cast( + aCmd.ValueTObjectL(KMPXCommandPlaybackGeneralType))); + switch ( cmd ) + { + case ( EPbCmdStartPd ): + { + ASSERT( aCmd.IsSupported( KMPXCommandPlaybackPDTransactionID )); + iTransactionId = aCmd.ValueTObjectL( 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( KMPXCommandPlaybackPDTransactionID )); + TBrCtlDownloadEvent event( + aCmd.ValueTObjectL( KMPXCommandPlaybackPDEvent )); + TUint val( aCmd.ValueTObjectL( KMPXCommandPlaybackGeneralData )); + HandleDownloadEventL( transId, event, val ); + break; + } + case ( EPbCmdGetPdStatus ): + { + aCmd.SetTObjectValueL( + KMPXCommandPlaybackPDTransactionID, + iTransactionId ); + aCmd.SetTObjectValueL( + KMPXCommandPlaybackPDState, + static_cast(iDownloadState)); + aCmd.SetTObjectValueL( + KMPXCommandPlaybackPDDownloadedBytes, + iDownloadBytes ); + aCmd.SetTObjectValueL( + 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& aAttrs) + { + MPX_DEBUG1("CMPXProgressDownload::MediaL() entering"); + + RArray 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( + TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration), + duration.Int64() / KPbMilliMultiplier); + } + + // Set bitrate + TPckgBuf data; + + const TMMFMessageDestinationPckg + destinationPckg(KUidInterfaceMMFAudioController); + + if (attrA & EMPXMediaAudioBitrate) + { + error = iPdPlayer->CustomCommandSync(destinationPckg, + EMMFAudioControllerGetSourceBitRate, KNullDesC8, KNullDesC8, data); + if (!error) + { + media->SetTObjectValueL( + TMPXAttribute(KMPXMediaIdAudio, EMPXMediaAudioBitrate), + data().iSampleRate); + } + } + + if (attrA & EMPXMediaAudioSamplerate) + { + + // Set sampling rate + error = iPdPlayer->CustomCommandSync(destinationPckg, + EMMFAudioControllerGetSourceSampleRate, KNullDesC8, KNullDesC8, data); + if (!error) + { + media->SetTObjectValueL( + KMPXMediaAudioSamplerate, + data().iSampleRate); + } + } + + if (attrG & EMPXMediaGeneralSize) + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + TEntry entry; + fs.Entry(iPdPath->Des(), entry); + media->SetTObjectValueL( + 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( mpxAtt )); + media->SetTObjectValueL( mpxAtt, val ); + break; + } + case EMPXMediaDrmProtected: + case EMPXMediaDrmSendingAllowed: + case EMPXMediaDrmCanSetAutomated: + case EMPXMediaDrmHasInfoUrl: + case EMPXMediaDrmHasPreviewUrl: + case EMPXMediaDrmAboutToExpire: + { + TBool val( + drmMedia->ValueTObjectL( mpxAtt )); + media->SetTObjectValueL( mpxAtt, val ); + break; + } + case EMPXMediaDrmStartTime: + case EMPXMediaDrmEndTime: + case EMPXMediaDrmIntervalStartTime: + case EMPXMediaDrmAccumulatedTime: + { + TInt64 val( + drmMedia->ValueTObjectL( mpxAtt )); + media->SetTObjectValueL( mpxAtt, val ); + break; + } + case EMPXMediaDrmInterval: + { + TTimeIntervalSeconds val( + drmMedia->ValueTObjectL(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( aValue ); + + // send new state + iObs->HandlePluginEvent( + MMPXPlaybackPluginObserver::EPDownloadStateChanged, + iDownloadState, + KErrNone); + iObs->HandlePluginEvent( + MMPXPlaybackPluginObserver::EPDownloadStarted, + iDownloadSize, + KErrNone ); + break; + } + case EDownloadEventCompleted: + { + iDownloadState = EPbDlStateDownloadCompleted; + iDownloadSize = static_cast( 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( 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(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