diff -r 14979e23cb5e -r 3de6c4cf6b67 mpxplugins/serviceplugins/collectionplugins/mpxsqlitepodcastdbplugin/src/mpxpodcastdbplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpxplugins/serviceplugins/collectionplugins/mpxsqlitepodcastdbplugin/src/mpxpodcastdbplugin.cpp Wed Sep 01 12:32:02 2010 +0100 @@ -0,0 +1,3197 @@ +/* +* 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: Implementation of podcast collection DB Plugin interface +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef RD_MULTIPLE_DRIVE +#include +#endif //RD_MULTIPLE_DRIVE + +#include "mpxdbcommondef.h" +#include "mpxresource.h" +#include "mpxdbcommonstd.h" +#include "mpxdbcommonutil.h" + +#include "mpxpodcastcollectiondbstd.h" +#include "mpxpodcastdbhandler.h" +#include "mpxdbutil.h" +#include "mpxpodcastcollectiondbdef.h" +#include "mpxpodcastcollectiondb.hrh" +#include "mpxpodcastdbplugin.h" + +// CONSTANTS +_LIT(KMPlayerDbPluginMbmFile, "mpxpodcastdbplugin.mif"); +const TInt KIncrementalDeleteCount = 400; + +// ============================ MEMBER FUNCTIONS ============================== + +// ---------------------------------------------------------------------------- +// Two-phased constructor. +// ---------------------------------------------------------------------------- +// +CMPXPodcastDbPlugin* CMPXPodcastDbPlugin::NewL( + TAny* /* aInitParams */) + { + MPX_FUNC("CMPXPodcastDbPlugin::NewL"); + + CMPXPodcastDbPlugin* self = new (ELeave) CMPXPodcastDbPlugin(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// Destructor. +// ---------------------------------------------------------------------------- +// +CMPXPodcastDbPlugin::~CMPXPodcastDbPlugin() + { + MPX_FUNC("CMPXPodcastDbPlugin::~CMPXPodcastDbPlugin"); + + iSelections.Reset(); + iSelections.Close(); + iFs.Close(); + delete iDbHandler; + delete iDrmMediaUtility; + if (iResource) + { + iResource->Release(); + } + iPodcastLibraryMainMenuItemIds.Close(); + delete iPodcastLibraryMainMenuItemTitles; + delete iPodcastLibraryTitles; + iPodcastPublishDateIds.Close(); + delete iPodcastTitlePublishDateCat; + iPodcastEpisodeViewPublishDateIds.Close(); + delete iPodcastEpisodeViewPublishDateTitle; + delete iTitleMyPodcast; + delete iTitleAllEpisodes; + delete iTitlePubDate; + delete iTitleTitles; + delete iTitleAdded; + delete iTitleUnplayed; + + if (iActiveTask) + { + iActiveTask->Cancel(); + delete iActiveTask; + } + } + +// ---------------------------------------------------------------------------- +// Constructor. +// ---------------------------------------------------------------------------- +// +CMPXPodcastDbPlugin::CMPXPodcastDbPlugin() + { + MPX_FUNC("CMPXPodcastDbPlugin::CMPXPodcastDbPlugin"); + } + +// ---------------------------------------------------------------------------- +// Symbian 2nd phase constructor can leave. +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::ConstructL () + { + MPX_FUNC("CMPXPodcastDbPlugin::ConstructL"); + iFirstDeleteStep = ETrue; + User::LeaveIfError(iFs.Connect()); + iDrmMediaUtility = CMPXDrmMediaUtility::NewL(); + + TParse parse; + parse.Set( KMPXCollectionDbResourceFile, &KDC_APP_RESOURCE_DIR, NULL ); + TFileName resFile(parse.FullName()); + User::LeaveIfError(MPXUser::CompleteWithDllPath(resFile)); + BaflUtils::NearestLanguageFile(iFs, resFile); + iResource = CMPXResource::NewL(resFile); + + iDbHandler = CMPXPodcastDbHandler::NewL(iFs, *iResource); + + iPodcastLibraryMainMenuItemTitles = iResource->ReadMenuArrayL(R_MC_MENU_ITEMS_ARRAY, + iPodcastLibraryMainMenuItemIds); + iPodcastTitlePublishDateCat = iResource->ReadMenuArrayL(R_MPX_QTN_NMP_PUBLISH_DATE_ARRAY, + iPodcastPublishDateIds); + iPodcastEpisodeViewPublishDateTitle = iResource->ReadMenuArrayL( + R_MPX_QTN_NMP_EPISODES_TITLE_PUBLISHED_DATE_ARRAY, iPodcastEpisodeViewPublishDateIds); + iTitleMyPodcast = iResource->ReadHBufCL(R_MPX_QTN_MP_TITLE_MY_PODCAST); + iTitleAllEpisodes = iResource->ReadHBufCL(R_MPX_QTN_MP_TITLE_ALL_EPISODES); + iTitlePubDate = iResource->ReadHBufCL(R_MPX_QTN_MUS_TITLE_PUBLISH_DATE); + iTitleTitles = iResource->ReadHBufCL(R_MPX_QTN_MP_TITLE_PODCASTS); + iTitleAdded = iResource->ReadHBufCL(R_MPX_QTN_MP_TITLE_RECENTLY_ADDED); + iTitleUnplayed = iResource->ReadHBufCL(R_MPX_QTN_MP_TITLE_UNPLAYED); + iPodcastLibraryTitles = iResource->ReadMenuArrayL(R_MC_MENU_TITLES_ARRAY, + iPodcastLibraryMainMenuItemIds); + + iActiveTask = CMPXDbActiveTask::NewL(*this); + } + +// ---------------------------------------------------------------------------- +// Navigates to the given path +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::OpenL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXFilter* /*aFilter*/) + { + MPX_FUNC("CMPXPodcastDbPlugin::OpenL"); + MPX_DEBUG_PATH (aPath); + + RArray openAttrs; + CleanupClosePushL(openAttrs); + + RArray supportedIds; + CleanupClosePushL(supportedIds); + + SetAttributesL(aPath, openAttrs, supportedIds); + + CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array()); + CleanupStack::PopAndDestroy(&supportedIds); + CleanupStack::PushL(entries); + + TInt error(KErrNone); + TBool isEpisode(EFalse); + CMPXCollectionPath* newPath(NULL); + + TBool openingForPlayback(EFalse); + + if(aAttrs.Count() == 1 && + aAttrs[0].ContentId() == KMPXMediaIdPodcast) + { + if(aAttrs[0].AttributeId() & EMPXMediaPodcastSetIsPlayingTrue) + { + openingForPlayback = ETrue; + } + } + + // Make sure we handle the correct open mode + // + TMPXOpenMode openmode = aPath.OpenNextMode(); + switch (openmode) + { + case EMPXOpenGroupOrPlaylist: + { + MPX_TRAP(error, isEpisode = DoOpenL ( + aPath, openAttrs.Array(), *entries, openingForPlayback)); + break; + } + + case EMPXOpenPlaylistOnly: + { + if( aPath.Count() > 0 ) + { + // Try to open + MPX_TRAP(error, newPath = DoOpenPlaylistL(aPath, openAttrs.Array(), openingForPlayback)); + CleanupStack::PushL(newPath); + isEpisode = ETrue; + } + else // no items, so open in normal mode + { + MPX_TRAP(error, isEpisode = DoOpenL ( + aPath, openAttrs.Array(), *entries, openingForPlayback)); + } + break; + } + default: + // do nothing + break; + } + + if (isEpisode) + { + if (openmode == EMPXOpenGroupOrPlaylist) + { + iObs->HandleOpen(const_cast(&aPath), error); + } + else // openmode == EMPXOpenPlaylistOnly + { + iObs->HandleOpen(newPath, error); + } + } + else + { + MPX_DEBUG_PATH (aPath); + + entries->SetCObjectValueL(KMPXMediaGeneralContainerPath, + const_cast(&aPath)); + iObs->HandleOpen(entries, error); + } + + if (newPath) + { + CleanupStack::PopAndDestroy(newPath); + } + + CleanupStack::PopAndDestroy(entries); + CleanupStack::PopAndDestroy(&openAttrs); + } + +// ---------------------------------------------------------------------------- +// Get the extended properties of the current file (async) +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::MediaL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + const TArray& /*aCaps*/, + CMPXAttributeSpecs* /*aSpecs*/) + { + MPX_FUNC("CMPXPodcastDbPlugin::MediaL"); + MPX_DEBUG_PATH(aPath); + + RArray supportedIds; + CleanupClosePushL(supportedIds); + if (aPath.Selection().Count()) + { + // it's a container if there are multiple selection, else it's not a container + supportedIds.AppendL(KMPXMediaIdContainer); + } + MPXDbCommonUtil::FillInSupportedUIDsL (aAttrs, supportedIds); + CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array()); + CleanupStack::PopAndDestroy(&supportedIds); + CleanupStack::PushL(entries); + + DoMediaL(aPath, aAttrs, *entries); + + // Also fetch collection details + DoHandleOtherMediaAttributesL(aAttrs, aPath, *entries); + + iObs->HandleMedia(entries, KErrNone); + CleanupStack::PopAndDestroy(entries); + } + +// ---------------------------------------------------------------------------- +// Cancel outstanding request +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::CancelRequest() + { + MPX_FUNC("CMPXPodcastDbPlugin::CancelRequest"); + iActiveTask->Cancel(); + } + +// ---------------------------------------------------------------------------- +// Executes the given command on the collection +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::CommandL( + TMPXCollectionCommand aCmd, + TInt aArg /* = 0 */) + { + MPX_FUNC("CMPXPodcastDbPlugin::CommandL"); + + switch (aCmd) + { + case EMcCmdRemoveAll: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - EMcCmdRemoveAll"); + // Remove EVERYthing from the collection + iDbHandler->RemoveEntireCollectionL(); + break; + } + case EMcCmdClose: + case EMcCloseCollection: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - EMcCloseCollection"); + // Close the specified database + #ifdef RD_MULTIPLE_DRIVE + MPX_DEBUG1("Multiple drives closing databases"); + if ( aArg <0) + { + DriveInfo::TDriveArray driveArray; + User::LeaveIfError ( DriveInfo::GetUserVisibleDrives ( iFs, driveArray)); + TInt count( driveArray.Count ()); + for (TInt i=0; iIsRemoteDrive(static_cast(driveArray[i])))) + { + MPX_DEBUG2("Closing database %i", driveArray[i]); + TRAP_IGNORE( iDbHandler->CloseDatabaseL( driveArray[i] ) ); + } + } + } + else + { + iDbHandler->CloseDatabaseL (aArg); + } + #else + iDbHandler->CloseDatabaseL(aArg); + #endif // RD_MULTIPLE_DRIVE + break; + } + case EMcReOpenCollection: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - EMcReOpenCollection"); + // Open the specified database +#ifdef RD_MULTIPLE_DRIVE + MPX_DEBUG1("Multiple drives opening databases"); + DriveInfo::TDriveArray driveArray; + User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveArray ) ); + TInt count( driveArray.Count() ); + for( TInt i=0; iIsRemoteDrive(static_cast(driveArray[i])))) + { + TUint driveStatus(0); + User::LeaveIfError( DriveInfo::GetDriveStatus( + iFs, driveArray[i], driveStatus ) ); + if( driveStatus & DriveInfo::EDrivePresent ) + { + MPX_DEBUG2("Opening database %i", driveArray[i]); + TRAP_IGNORE( iDbHandler->OpenDatabaseL( driveArray[i] ) ); + } + } + } +#else + iDbHandler->OpenDatabaseL(aArg); +#endif // RD_MULTIPLE_DRIVE + break; + } + case EMcRefreshStarted: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - EMcRefreshStarted"); + iDbHandler->RefreshStartL(); + iRefreshing = ETrue; + break; + } + case EMcRefreshEnded: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - EMcRefreshEnded"); + // ask the handler to finalize the transaction + iDbHandler->RefreshEndL(); + iRefreshing = EFalse; + break; + } + case EMcCmdReCreateDB: + { + // Recreate all databases + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - EMcCmdReCreateDB"); + iDbHandler->ReCreateDatabasesL(); + break; + } + case EMcCmdDbCorrupted: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - EMcCmdDbCorrupted"); + iDbHandler->SetDBCorruptedL(ETrue); + break; + } + case EMcCmdCollectionInit: + case EMcCmdRefresh: + case EMcCmdCollectionResyn: + { + // deprecated + break; + } + case EMcCmdMtpStart: + iMtpInUse = ETrue; + break; + case EMcCmdMtpEnd: + iMtpInUse = EFalse; + break; + default: + { + User::Leave(KErrNotSupported); + } + } + } + +// ---------------------------------------------------------------------------- +// Executes the given command on the collection +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::CommandL( + CMPXCommand& aCmd) + { + MPX_FUNC("CMPXPodcastDbPlugin::CommandL"); + + if (!aCmd.IsSupported(KMPXCommandGeneralId)) + { + User::Leave(KErrArgument); + } + + TMPXCommandId commandId = aCmd.ValueTObjectL(KMPXCommandGeneralId); + + TBool syncOp(EFalse); + if( aCmd.IsSupported(KMPXCommandGeneralDoSync) ) + { + syncOp = aCmd.ValueTObjectL(KMPXCommandGeneralDoSync); + } + + // Handle this operation synchronously or asynchronously + if( !syncOp ) + { + iActiveTask->StartL(commandId, aCmd); + } + else // Sync operation + { + switch (commandId) + { + case KMPXCommandIdCollectionRetrieveUriForDeletion: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdCollectionRetrieveUriForDeletion"); + DoRetrieveUriForDeletionL(aCmd); + break; + } + case KMPXCommandIdCollectionRemove: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdCollectionRemove"); + if (iFirstDeleteStep ) + { + iFirstDeleteStep = EFalse; + } + DoRemovePathL(aCmd); + break; + } + case KMPXCommandIdCollectionRemoveMedia: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdCollectionRemoveMedia"); + DoRemoveMediaL(aCmd); + break; + } + case KMPXCommandIdCollectionCleanupDeletedMedias: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdCollectionCleanupDeletedMedias"); + CleanupDeletedRecordsL(aCmd); + break; + } + case KMPXCommandIdCollectionAdd: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdCollectioAdd"); + CMPXMedia* media = aCmd.Value(KMPXCommandColAddMedia); + User::LeaveIfNull( media ); + TInt id = DoAddL(*media); + aCmd.SetTObjectValueL(KMPXCommandColAddRtnId, id); + break; + } + case KMPXCommandIdCollectionSet: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdCollectionSet"); + CMPXMedia* media = aCmd.Value(KMPXCommandColSetMedia); + User::LeaveIfNull( media ); + DoSetL(*media); + break; + } + case KMPXCommandIdCollectionCompleteDelete: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdCollectionCompleteDelete"); + DoHandleDeleteCompleteL(aCmd); + break; + } + case KMPXCommandIdUpdateRefreshTime: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdUpdateRefreshTime"); + TTime curTime; + curTime.HomeTime(); + iDbHandler->SetLastRefreshedTimeL(curTime); + break; + } + case KMPXCommandCollectionGetCount: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandCollectionGetCount"); + DoGetCollectionCountL(aCmd); + break; + } + case KMPXCommandCollectionGetURIs: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandCollectionGetURIs"); + DoGetCollectionUriL(aCmd); + break; + } + default: + { + User::Leave(KErrNotSupported); + } + } + } + } + +// ---------------------------------------------------------------------------- +// Adds a podcast to the collection +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::AddL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::AddL"); + DoAddL(aMedia); + } + +// ---------------------------------------------------------------------------- +// Remove an item from the collection database using the given path +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::RemoveL( + const CMPXCollectionPath& aPath) + { + MPX_FUNC("CMPXPodcastDbPlugin::RemoveL(by path)"); + MPX_DEBUG_PATH(aPath); + + CMPXMessageArray* msgAry = CMPXMessageArray::NewL(); + CleanupStack::PushL( msgAry ); + + // Return file path for deleted item(s) + CDesCArray* fp = DoRemoveL(aPath,*msgAry); + + iObs->HandleRemove(*fp, KErrNone); + delete fp; + + // Send Change Messages + iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible); + DoHandleChangeL(msgAry); + CleanupStack::PopAndDestroy( msgAry ); + } + +// ---------------------------------------------------------------------------- +// Remove an item from the collection database using the given media properties +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::RemoveL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::RemoveL(by media)"); + DoRemoveL(aMedia, EFalse); + } + +// ---------------------------------------------------------------------------- +// Sets/updates the media for an item in the collection +// DEPRECATED for week 18 +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::SetL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::SetL"); + DoSetL(aMedia); + } + +// ---------------------------------------------------------------------------- +// Find the items matching the media specifications +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::FindAllL( + const CMPXMedia& aCriteria, + const TArray& aAttrs) + { + MPX_FUNC("CMPXPodcastDbPlugin::FindAllL"); + + CMPXMedia* entries = FindAllSyncL(aCriteria, aAttrs); + + // notify client. if FindAllL leaves, framework will notify client of the error + iObs->HandleFindAll(entries, KErrNone); + delete entries; + } + +// ---------------------------------------------------------------------------- +// Find the items matching the media specifications +// ---------------------------------------------------------------------------- +// +CMPXMedia* CMPXPodcastDbPlugin::FindAllSyncL( + const CMPXMedia& aCriteria, + const TArray& aAttrs) + { + MPX_FUNC("CMPXPodcastDbPlugin::FindAllSyncL"); + + CMPXMedia* entries = iDbHandler->FindAllLC(aCriteria, aAttrs); + CleanupStack::Pop(entries); + + return entries; + } + +// ---------------------------------------------------------------------------- +// Get the list of supported capabilities +// ---------------------------------------------------------------------------- +// +TCollectionCapability CMPXPodcastDbPlugin::GetCapabilities() + { + // This one supports simple search + return EMcSearch; + } + +// ---------------------------------------------------------------------------- +// Get the list of supported capabilities +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::HandleStepL() + { + MPX_FUNC("CMPXPodcastDbPlugin::HandleStepL"); + + TBool done(ETrue); + + switch (iActiveTask->GetTask()) + { + case KMPXCommandIdCollectionSet: + { + done = DoSetAsyncL(); + break; + } + case KMPXCommandIdCollectionAdd: + { + done = DoAddAsyncL(); + break; + } + case KMPXCommandIdCollectionRemove: + { + DoRemovePathL(iActiveTask->GetCommand()); + done = ETrue; + break; + } + case KMPXCommandIdCollectionRemoveMedia: + { + DoRemoveMediaL(iActiveTask->GetCommand()); + done = ETrue; + break; + } + case KMPXCommandIdCollectionRetrieveUriForDeletion: + { + DoRetrieveUriForDeletionL(iActiveTask->GetCommand()); + done = ETrue; + break; + } + case KMPXCommandIdCollectionCleanupDeletedMedias: + { + CleanupDeletedRecordsL(iActiveTask->GetCommand()); + done = ETrue; + break; + } + case KMPXCommandIdCollectionCompleteDelete: + { + DoHandleDeleteCompleteL( iActiveTask->GetCommand() ); + break; + } + case KMPXCommandIdUpdateRefreshTime: + { + MPX_DEBUG1("CMPXPodcastDbPlugin::CommandL - KMPXCommandIdUpdateRefreshTime"); + TTime curTime; + curTime.HomeTime(); + iDbHandler->SetLastRefreshedTimeL(curTime); + break; + } + default: + { + // Should never happen! + ASSERT(0); + break; + } + } + return done; + } + +// ---------------------------------------------------------------------------- +// Handler for async operations completed +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::HandleOperationCompleted( + TInt aErr) + { + MPX_FUNC("CMPXPodcastDbPlugin::HandleOperationCompleted"); + TRAP_IGNORE(DoHandleOperationCompletedL(aErr)); + } + +// ---------------------------------------------------------------------------- +// Process the OpenL command +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoOpenL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + TBool aFlagToSignalToBePlayed) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoOpenL"); + + CMPXMediaArray* array = CMPXMediaArray::NewL(); + CleanupStack::PushL(array); + + TInt count(0); + TInt levels(aPath.Levels()); + TBool isEpisode(EFalse); + + aEntries.SetTObjectValueL(KMPXMediaGeneralId, aPath.Id(levels - 1)); + + if (1 == levels) + { + isEpisode = DoOpenBrowseTitleL(aPath, aAttrs, aEntries, *array); + } + else if (levels >= 2) + { + isEpisode = DoOpenBrowseTitleL(aPath, aAttrs, aEntries, *array); + } + else + { + User::Leave(KErrNotSupported); + } + + if(isEpisode && + aFlagToSignalToBePlayed) + { + // opening an episode to be played so set the IsPlaying flag to + // prevent this episode from being picked up as Not Yet Played + // (need to do this because setting last playback position causes + // visible change and the playlist to update) + if(array->Count() == 1) + { + // ignore the error because if there is a problem + // updating the media file, the error will show up + // when opening the track for playing and be handled + // properly by the playback engine and skipped + TRAP_IGNORE(iDbHandler->SetIsPlayingL(*((*array)[0]), ETrue)); + } + } + + aEntries.SetCObjectValueL(KMPXMediaArrayContents, array); + aEntries.SetTObjectValueL(KMPXMediaArrayCount, array->Count()); + + CleanupStack::PopAndDestroy(array); + + return isEpisode; + } + +// ---------------------------------------------------------------------------- +// Handles OpenL called for EBrowseAll +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoOpenBrowseAllL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoOpenBrowseAllL"); + + TInt levels(aPath.Levels()); + switch (levels) + { + // All Episodes + case 2: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseAllL_All); + + iDbHandler->GetAllEpisodesL(aAttrs, aArray); + SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXPodcastGroup, EMPXAll, + *iTitleAllEpisodes, aArray.Count()); + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseAllL_All); + break; + } + + // An episode in all episodes + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseAllL_Episode); + + iDbHandler->GetEpisodeL(aPath.Id(levels - 1), aAttrs, aArray); + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseAllL_Episode); + break; + } + + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoOpenBrowseAllL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } + + return (levels == 3); + } + +// ---------------------------------------------------------------------------- +// Handles OpenL called for EBrowsePubDate +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoOpenBrowsePubDateL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoOpenBrowsePubDateL"); + + TBool isEpisode(EFalse); + TInt levels(aPath.Levels()); + + switch (levels) + { + // All By Publish Date Categories + case 2: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowsePubDateL_All); + + TInt numEpisodes(iDbHandler->GetEpisodesMatchingPublishPlaylistL(KPublishAllPlaylistUID, aAttrs, + EFalse, aArray)); + SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXPodcastGroup, EMPXPubDate, + *iTitlePubDate); + aEntries.SetTObjectValueL(KMPXMediaGeneralNonPermissibleActions, EMPXCache ); + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowsePubDateL_All); + break; + } + // All episodes within a specific By Publish Date category + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowsePubDateL_Playlist); + iNumberOfEpisodesInCurrentPublishDateCategory = + iDbHandler->GetEpisodesMatchingPublishPlaylistL( + (aPath.Id(levels - 1).iId2 & 0x00FFFFFF) + KPublishTodayPlaylistUID, // offset by KPublishTodayPlaylistUID + aAttrs, EFalse, aArray); + + SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXPodcastItem, EMPXEpisode, + iPodcastEpisodeViewPublishDateTitle->MdcaPoint(aPath.Id(levels - 1).iId2 & 0x00FFFFFF), + iNumberOfEpisodesInCurrentPublishDateCategory); + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowsePubDateL_Playlist); + break; + } + // An episode + case 4: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowsePubDateL_Episode); + + iDbHandler->GetEpisodeL(aPath.Id(levels - 1), aAttrs, aArray); + isEpisode = ETrue; + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowsePubDateL_Episode); + break; + } + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoOpenBrowsePubDateL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } + return isEpisode; + } + +// ---------------------------------------------------------------------------- +// Handles OpenL called for EBrowseTitle +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoOpenBrowseTitleL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoOpenBrowseTitleL"); + + TBool isEpisode(EFalse); + TInt levels(aPath.Levels()); + + switch (levels) + { + // All Titles + case 1: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseTitleL_All); + + iDbHandler->GetAllPodcastTitlesL(aAttrs, aArray); + + SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXPodcastGroup, EMPXTitle, + *iTitleTitles); + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseTitleL_All); + break; + } + // All episodes in a title + case 2: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseTitleL_Title); + + iDbHandler->GetEpisodesMatchingTitleL(aPath.Id(levels - 1).iId2, + aAttrs, aArray); + + HBufC* title = iDbHandler->GetTitleNameMatchingIdL(aPath.Id(levels - 1)); + CleanupStack::PushL(title); + SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXPodcastItem, EMPXEpisode, + *title, aArray.Count()); + CleanupStack::PopAndDestroy(title); + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseTitleL_Title); + break; + } + // An episode within a title + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseTitleL_Episode); + iDbHandler->GetEpisodeL(aPath.Id(levels - 1), aAttrs, aArray); + isEpisode = ETrue; + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseTitleL_Episode); + break; + } + + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoOpenBrowseTitleL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } + + return isEpisode; + } + +// ---------------------------------------------------------------------------- +// Handles OpenL called for EBrowseRecentlyAdded +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoOpenBrowseRecentlyAddedL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoOpenBrowseRecentlyAddedL"); + + TBool isEpisode(EFalse); + TInt levels(aPath.Levels()); + + switch (levels) + { + case 2: + { + // All recently added episodes + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseRecentlyAddedL_All); + + TInt indexOfCurrentlyPlayingItem(KErrNotFound); + iDbHandler->GetEpisodesMatchingPlaylistL(KRecentlyAddedPlaylistUID, + aAttrs, aArray, indexOfCurrentlyPlayingItem); + SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXPodcastGroup, EMPXRecentlyAdded, + *iTitleAdded, aArray.Count()); + aEntries.SetTObjectValueL(KMPXMediaPodcastCurrentlyPlayingIndex, + indexOfCurrentlyPlayingItem); + // Fix for Autoplaylist, set the permission to not writable and cacheable + aEntries.SetTObjectValueL( + KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions)(EMPXWrite | EMPXCache)); + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseRecentlyAddedL_All); + break; + } + // An episode in the recently added episodes list + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseRecentlyAddedL_Episode); + iDbHandler->GetEpisodeL(aPath.Id(levels - 1), aAttrs, aArray); + isEpisode = ETrue; + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseRecentlyAddedL_Episode); + break; + } + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoOpenBrowseRecentlyAddedL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } + + return isEpisode; + } + +// ---------------------------------------------------------------------------- +// Handles OpenL called for EBrowseNotPlayed +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoOpenBrowseNotPlayedL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoOpenBrowseNotPlayedL"); + + TBool isEpisode(EFalse); + TInt levels(aPath.Levels()); + + switch (levels) + { + case 2: + { + // All episodes that haven't been played + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseNotPlayedL_All); + + TInt indexOfCurrentlyPlayingItem(KErrNotFound); + iDbHandler->GetEpisodesMatchingPlaylistL(KNotPlayedPlaylistUID, aAttrs, aArray, + indexOfCurrentlyPlayingItem); + SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXPodcastGroup, EMPXNotYetPlayed, + *iTitleUnplayed, aArray.Count()); + aEntries.SetTObjectValueL(KMPXMediaPodcastCurrentlyPlayingIndex, + indexOfCurrentlyPlayingItem); + // Fix for Autoplaylist, set the permission to not writable and cacheable + aEntries.SetTObjectValueL( + KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions)(EMPXWrite | EMPXCache)); + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseNotPlayedL_All); + break; + } + // An episode in the recently added episodes list + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoOpenBrowseNotPlayedL_Episode); + iDbHandler->GetEpisodeL(aPath.Id(levels - 1), aAttrs, aArray); + isEpisode = ETrue; + + MPX_PERF_END(CMPXPodcastDbPlugin_DoOpenBrowseNotPlayedL_Episode); + break; + } + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoOpenBrowseNotPlayedL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } + + return isEpisode; + } + +// ---------------------------------------------------------------------------- +// Process the OpenL method with open mode EMPXOpenPlaylistOnly +// ---------------------------------------------------------------------------- +// +CMPXCollectionPath* CMPXPodcastDbPlugin::DoOpenPlaylistL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + TBool aFlagToSignalToBePlayed) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoOpenPlaylistL"); + + RArray ids; + CleanupClosePushL(ids); + + CMPXMedia* entries = CMPXMedia::NewL(); + CleanupStack::PushL(entries); + + CMPXCollectionPath* path = CMPXCollectionPath::NewL( aPath ); + CleanupStack::PushL( path ); + + // Go through the browse path + TInt levels(aPath.Levels()); + if (levels == 2) + { + // Create a new collection path + CleanupStack::PopAndDestroy(path); + path = CMPXCollectionPath::NewL(); + CleanupStack::PushL(path); + + // Always return all episodes here + // + ids.Reset(); + ids.AppendL( KDBPluginUid ); + path->AppendL(ids.Array()); + path->SelectL((TMPXItemId)KDBPluginUid); + + ids.Reset(); + ids.AppendL(EBrowseAll); + path->AppendL(ids.Array()); + path->SelectL((TMPXItemId) EBrowseAll); + path->Set(EMPXOpenPlaylistOnly); + + // Get all item IDs + CMPXMediaArray* array = CMPXMediaArray::NewL(); + CleanupStack::PushL(array); + + DoOpenBrowseAllL(*path, aAttrs, *entries, *array); + + entries->SetCObjectValueL(KMPXMediaArrayContents, array); + entries->SetTObjectValueL(KMPXMediaArrayCount, array->Count()); + + CleanupStack::PopAndDestroy(array); + + DoAppendLevelL(*path, *entries); + } + else if (levels > 2) + { + TInt selectedId(aPath.Id(1)); + switch (selectedId) + { + case EBrowseAll: + { + path->Set(EMPXOpenPlaylistOnly); + if(aFlagToSignalToBePlayed) + { + // Set the episode ID to be played + entries->SetTObjectValueL( KMPXMediaGeneralId, aPath.Id(2) ); + + // ignore the error because if there is a problem + // updating the media file, the error will show up + // when opening the track for playing and be handled + // properly by the playback engine and skipped + TRAP_IGNORE(iDbHandler->SetIsPlayingL(*entries, ETrue)); + } + break; + } + case EBrowseTitle: + case EBrowsePubDate: + case EBrowseRecentlyAdded: + case EBrowseNotPlayed: + { + if (!DoOpenL(aPath, aAttrs, *entries, aFlagToSignalToBePlayed)) + { + path->Set(EMPXOpenPlaylistOnly); + // If it is not at a episode level + // Append all entries to create collection path + // + DoAppendLevelL(*path, *entries); + } + break; + } + default: + { + User::Leave(KErrNotSupported); + } + } + } + else // levels < 2 + { + User::Leave(KErrNotSupported); + } + + // Cleanup + CleanupStack::Pop(path); + CleanupStack::PopAndDestroy(entries); + CleanupStack::PopAndDestroy(&ids); + + return path; + } + +// ---------------------------------------------------------------------------- +// Process the MediaL command +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoMediaL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoMediaL"); + + CMPXMediaArray* array = CMPXMediaArray::NewL(); + CleanupStack::PushL(array); + + DoTitlesMediaL(aPath, aAttrs, aEntries, *array); + + if (array->Count() > 0) + { + aEntries.SetCObjectValueL(KMPXMediaArrayContents, array); + aEntries.SetTObjectValueL(KMPXMediaArrayCount, array->Count()); + } + CleanupStack::PopAndDestroy(array); + } + +// ---------------------------------------------------------------------------- +// Find the collection media for root level +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRootMediaL( + const TArray& aAttrs, + CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRootMediaL"); +#ifndef __ENABLE_PODCAST_IN_MUSIC_MENU + aMedia.SetTObjectValueL ( + KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions)(EMPXWrite | EMPXCache) ); +#endif // __ENABLE_PODCAST_IN_MUSIC_MENU + TInt count(aAttrs.Count()); + for (TInt i = 0; i < count; ++i) + { + if (aAttrs[i].ContentId() == KMPXMediaIdGeneral) + { + TUint att = aAttrs[i].AttributeId(); + + if (att & EMPXMediaGeneralTitle) + { + // set the collection plugin name + HBufC* title(iResource->ReadHBufCL(R_MPX_QTN_MUS_PODCASTS)); + CleanupStack::PushL(title); + aMedia.SetTextValueL(KMPXMediaGeneralTitle, *title); + CleanupStack::PopAndDestroy(title); + } + if (att & EMPXMediaGeneralSubTitle) + { + TInt numEpisodes(iDbHandler->NumberOfItemsL(EMPXEpisode)); + + HBufC* text(iResource->ReadHBufCL((numEpisodes == 1) ? + R_MPX_QTN_MUS_PODCAST_ONE_EPISODE : R_MPX_QTN_MUS_PODCAST_NUM_EPISODES)); + CleanupStack::PushL(text); + aMedia.SetTextValueL(KMPXMediaGeneralSubTitle, *text); + aMedia.SetTObjectValueL(KMPXMediaGeneralCount, numEpisodes); + CleanupStack::PopAndDestroy(text); + } + if (att & EMPXMediaGeneralIcon) + { + // set the collection plugin icon + TIconInfo icon; + icon.bmpfile = KMPlayerDbPluginMbmFile; + icon.bitmapId = EMbmMpxpodcastdbpluginQgn_graf_mup_dlst_podcast; + icon.maskId = EMbmMpxpodcastdbpluginQgn_graf_mup_dlst_podcast_mask; + aMedia.SetTObjectValueL(KMPXMediaGeneralIcon, icon ); + } + } // if + } // for + } + +// ---------------------------------------------------------------------------- +// Find the collection media for all episodes category +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoAllEpisodesMediaL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoAllEpisodesMediaL"); + + TInt levels(aPath.Levels()); + switch (levels) + { + // All episodes + case 2: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoAllEpisodesMediaL_All); + DoRootCategoryMediaL(aAttrs, aPath.Id(1), EMPXAll, aEntries); + MPX_PERF_END(CMPXPodcastDbPlugin_DoAllEpisodesMediaL_All); + break; + } + // An episode in all episodes + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoAllEpisodesMediaL_Episode); + GetEpisodeInfoL(aPath, aAttrs, aEntries, aMediaArray); + MPX_PERF_END(CMPXPodcastDbPlugin_DoAllEpisodesMediaL_Episode); + break; + } + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoAllEpisodesMediaL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } // end switch(levels) + } + +// ---------------------------------------------------------------------------- +// Find the collection media for by publish date category +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoByPublishDateMediaL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoByPublishDateMediaL"); + + TInt levels(aPath.Levels()); + TInt idIndex(levels - 1); + + // All By Publish Date Categories + if (levels == 2) + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoByPublishDateMediaL_All); + DoRootCategoryMediaL(aAttrs, aPath.Id(1), EMPXPubDate, aEntries); + MPX_PERF_END(CMPXPodcastDbPlugin_DoByPublishDateMediaL_All); + } + else if (levels == 3) // by publish date category selected + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoByPublishDateMediaL_Category); + const TDesC& title = iPodcastEpisodeViewPublishDateTitle->MdcaPoint( + aPath.Id(idIndex).iId2 & 0x00FFFFFF); + aEntries.SetTextValueL(KMPXMediaGeneralTitle, title); + MPX_PERF_END(CMPXPodcastDbPlugin_DoByPublishDateMediaL_Category); + } + else if (levels == 4) // an episode within the category + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoByPublishDateMediaL_Episode); + GetEpisodeInfoL(aPath, aAttrs, aEntries, aMediaArray); + MPX_PERF_END(CMPXPodcastDbPlugin_DoByPublishDateMediaL_Episode); + } + else + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoByPublishDateMediaL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } + +// ---------------------------------------------------------------------------- +// Find the collection media for titles category +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoTitlesMediaL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoTitlesMediaL"); + + TInt levels(aPath.Levels()); + TInt idIndex(levels - 1); + + // All Titles Categories + if (levels == 1) + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoTitlesMediaL_All); + DoRootCategoryMediaL(aAttrs, aPath.Id(1), EMPXTitle, aEntries); + MPX_PERF_END(CMPXPodcastDbPlugin_DoTitlesMediaL_All); + } + else if (levels == 2) // All episodes within selected title + { + MPX_PERF_START (CMPXPodcastDbPlugin_DoTitlesMediaL_Title); + iDbHandler->GetAllPodcastTitlesL(aAttrs, aMediaArray); + HBufC* title = iDbHandler->GetTitleNameMatchingIdL(aPath.Id(idIndex)); + CleanupStack::PushL(title); + aEntries.SetTextValueL(KMPXMediaGeneralTitle, *title); + CleanupStack::PopAndDestroy(title); + MPX_PERF_END (CMPXPodcastDbPlugin_DoTitlesMediaL_Title); + } + else if (levels == 3) // an episode within a selected title + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoTitlesMediaL_Episode); + GetEpisodeInfoL (aPath, aAttrs, aEntries, aMediaArray); + MPX_PERF_END(CMPXPodcastDbPlugin_DoTitlesMediaL_Episode); + } + else + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoTitlesMediaL: Invalid levels[%d]", levels); + User::Leave(KErrNotSupported); + } + } + +// ---------------------------------------------------------------------------- +// Find the collection media for recently added +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRecentlyAddedMediaL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRecentlyAddedMediaL"); + + switch (aPath.Levels()) + { + // All episodes + case 2: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoRecentlyAddedMediaL_All); + DoRootCategoryMediaL(aAttrs, aPath.Id(1), EMPXRecentlyAdded, aEntries); + MPX_PERF_END(CMPXPodcastDbPlugin_DoRecentlyAddedMediaL_All); + break; + } + + // An episode that was recently added + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoRecentlyAddedMediaL_Episode); + GetEpisodeInfoL(aPath, aAttrs, aEntries, aMediaArray); + MPX_PERF_END(CMPXPodcastDbPlugin_DoRecentlyAddedMediaL_Episode); + break; + } + + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoRecentlyAddedMediaL: Invalid levels[%d]", aPath.Levels()); + User::Leave(KErrNotSupported); + } + } // end switch(levels) + } + +// ---------------------------------------------------------------------------- +// Find the collection media for recently added +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoNotYetPlayedMediaL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntries, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoNotYetPlayedMediaL"); + + switch (aPath.Levels()) + { + // All episodes + case 2: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoNotYetPlayedMediaL_All); + DoRootCategoryMediaL(aAttrs, aPath.Id(1), EMPXNotYetPlayed, aEntries); + MPX_PERF_END(CMPXPodcastDbPlugin_DoNotYetPlayedMediaL_All); + break; + } + + // An episode that was never played + case 3: + { + MPX_PERF_START(CMPXPodcastDbPlugin_DoNotYetPlayedMediaL_Episode); + MPX_TRAPD(err, GetEpisodeInfoL(aPath, aAttrs, aEntries, aMediaArray)); + + if (err != KErrNotFound) + { + // it's o.k if the episode isn't found because the episode + // might have finished playing and is no longer + // part of the "Not yet played" playlist + User::LeaveIfError(err); + } + + MPX_PERF_END(CMPXPodcastDbPlugin_DoNotYetPlayedMediaL_Episode); + break; + } + + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoNotYetPlayedMediaL: Invalid levels[%d]", aPath.Levels()); + User::Leave(KErrNotSupported); + } + } // end switch(levels) + } + +// ---------------------------------------------------------------------------- +// Find the collection media for the root menu +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRootCategoryMediaL( + const TArray& aAttrs, + TMPXItemId aRootCategoryId, + TMPXPodcastCategory aCategory, + CMPXMedia& aEntries) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRootCategoryMediaL"); + + TInt count(aAttrs.Count()); + for (TInt i = 0; i < count; ++i) + { + if (aAttrs[i].ContentId() == KMPXMediaIdGeneral) + { + TUint att(aAttrs[i].AttributeId()); + + if (att & EMPXMediaGeneralId) + { + aEntries.SetTObjectValueL(KMPXMediaGeneralId, + aRootCategoryId); + } + if (att & EMPXMediaGeneralTitle) + { + aEntries.SetTextValueL(KMPXMediaGeneralTitle, + iPodcastLibraryTitles->MdcaPoint(BrowseTypeForCategory(aCategory))); + } + } // end if + } // end for + + aEntries.SetTObjectValueL(KMPXMediaGeneralType, EMPXGroup); + aEntries.SetTObjectValueL(KMPXMediaGeneralCategory, aCategory); + } + +// ---------------------------------------------------------------------------- +// Set all the attributes in CMPXMedia corresponding to KMPXMediaIdDrm +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoSetMediaDrmL( + CMPXMedia& aMedia, + TUint aDrmAttributes, + const TDesC& aLocation) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoSetMediaDrmL"); + + iDrmMediaUtility->InitL(aLocation); + CleanupClosePushL(*iDrmMediaUtility); + const CMPXMedia* drmMedia(iDrmMediaUtility->GetMediaL(aDrmAttributes)); + + // Only get attributes if it's a DRM file + if (drmMedia) + { + if ((aDrmAttributes & EMPXMediaDrmType) && + drmMedia->IsSupported(KMPXMediaDrmType)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmType, + drmMedia->ValueTObjectL(KMPXMediaDrmType)); + } + if ((aDrmAttributes & EMPXMediaDrmRightsStatus) && + drmMedia->IsSupported(KMPXMediaDrmRightsStatus)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmRightsStatus, + drmMedia->ValueTObjectL(KMPXMediaDrmRightsStatus)); + } + if ((aDrmAttributes & EMPXMediaDrmRightsType) && + drmMedia->IsSupported(KMPXMediaDrmRightsType)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmRightsType, + drmMedia->ValueTObjectL(KMPXMediaDrmRightsType)); + } + if ((aDrmAttributes & EMPXMediaDrmCount) && + drmMedia->IsSupported(KMPXMediaDrmCount)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmCount, + drmMedia->ValueTObjectL(KMPXMediaDrmCount)); + } + if ((aDrmAttributes & EMPXMediaDrmProtected) && + drmMedia->IsSupported(KMPXMediaDrmProtected)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmProtected, + drmMedia->ValueTObjectL(KMPXMediaDrmProtected)); + } + if ((aDrmAttributes & EMPXMediaDrmSendingAllowed) && + drmMedia->IsSupported(KMPXMediaDrmSendingAllowed)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmSendingAllowed, + drmMedia->ValueTObjectL(KMPXMediaDrmSendingAllowed)); + } + if ((aDrmAttributes & EMPXMediaDrmCanSetAutomated) && + drmMedia->IsSupported(KMPXMediaDrmCanSetAutomated)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmCanSetAutomated, + drmMedia->ValueTObjectL(KMPXMediaDrmCanSetAutomated)); + } + if ((aDrmAttributes & EMPXMediaDrmHasInfoUrl) && + drmMedia->IsSupported(KMPXMediaDrmHasInfoUrl)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmHasInfoUrl, + drmMedia->ValueTObjectL(KMPXMediaDrmHasInfoUrl)); + } + if ((aDrmAttributes & EMPXMediaDrmHasPreviewUrl) && + drmMedia->IsSupported(KMPXMediaDrmHasPreviewUrl)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmHasPreviewUrl, + drmMedia->ValueTObjectL(KMPXMediaDrmHasPreviewUrl)); + } + if ((aDrmAttributes & EMPXMediaDrmAboutToExpire) && + drmMedia->IsSupported(KMPXMediaDrmAboutToExpire)) + { + aMedia.SetTObjectValueL( KMPXMediaDrmAboutToExpire, + drmMedia->ValueTObjectL(KMPXMediaDrmAboutToExpire)); + } + if ((aDrmAttributes & EMPXMediaDrmStartTime) && + drmMedia->IsSupported(KMPXMediaDrmStartTime)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmStartTime, + drmMedia->ValueTObjectL(KMPXMediaDrmStartTime)); + } + if ((aDrmAttributes & EMPXMediaDrmEndTime) && + drmMedia->IsSupported(KMPXMediaDrmEndTime)) + { + aMedia.SetTObjectValueL( KMPXMediaDrmEndTime, + drmMedia->ValueTObjectL(KMPXMediaDrmEndTime)); + } + if ((aDrmAttributes & EMPXMediaDrmIntervalStartTime) && + drmMedia->IsSupported(KMPXMediaDrmIntervalStartTime)) + { + aMedia.SetTObjectValueL( KMPXMediaDrmIntervalStartTime, + drmMedia->ValueTObjectL(KMPXMediaDrmIntervalStartTime)); + } + if ((aDrmAttributes & EMPXMediaDrmAccumulatedTime) && + drmMedia->IsSupported(KMPXMediaDrmAccumulatedTime)) + { + aMedia.SetTObjectValueL(KMPXMediaDrmAccumulatedTime, + drmMedia->ValueTObjectL(KMPXMediaDrmAccumulatedTime)); + } + if ((aDrmAttributes & EMPXMediaDrmInterval) && + drmMedia->IsSupported(KMPXMediaDrmInterval)) + { + aMedia.SetTObjectValueL( KMPXMediaDrmInterval, + drmMedia->ValueTObjectL(KMPXMediaDrmInterval)); + } + } + + CleanupStack::PopAndDestroy(iDrmMediaUtility); + } + +// ---------------------------------------------------------------------------- +// Add media objects to the array with attributes from episode details +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::GetEpisodeInfoL( + const CMPXCollectionPath& aPath, + const TArray& aAttrs, + CMPXMedia& aEntry, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::GetEpisodeInfoL"); + + RArray supportedIds; + CleanupClosePushL(supportedIds); + MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds); + + RArray selections; + CleanupClosePushL(selections); + aPath.SelectionL(selections); + + TInt countSelection(aPath.Selection().Count()); + if (countSelection) + { + for (TInt selectionIndex = 0; selectionIndex < countSelection; ++selectionIndex) + { + CMPXMedia* newEntry = CMPXMedia::NewL(supportedIds.Array()); + CleanupStack::PushL(newEntry); + + DoGetEpisodeInfoL(aAttrs, selections[selectionIndex].iId2, *newEntry); + + aMediaArray.AppendL(*newEntry); + CleanupStack::PopAndDestroy(newEntry); + } + } + else + { + // No selection, get the attributes for the one song + DoGetEpisodeInfoL(aAttrs, aPath.Id(aPath.Levels() - 1).iId2, aEntry); + } + + CleanupStack::PopAndDestroy(&selections); + CleanupStack::PopAndDestroy(&supportedIds); + } + +// ---------------------------------------------------------------------------- +// Retrieves the attributes for a media object. +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoGetEpisodeInfoL( + const TArray& aAttrs, + TInt aEntryId, + CMPXMedia& aEntry) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoGetEpisodeInfoL"); + + iDbHandler->GetEpisodeL(aEntryId, aAttrs, aEntry); + + const TDesC& location(aEntry.ValueText(KMPXMediaGeneralUri)); + + // Check DRM Only if we have a location + if (location != KNullDesC) + { + TUint drmAttributes(0); + + // Compact the attribute set + TInt count(aAttrs.Count()); + for (TInt i = 0; i < count; ++i) + { + if (aAttrs[i].ContentId() == KMPXMediaIdDrm) + { + drmAttributes |= aAttrs[i].AttributeId(); + } + } + + // Set the correct attributes to media, only if requested + if (drmAttributes) + { + DoSetMediaDrmL(aEntry, drmAttributes, location); + } + } + } + +// ---------------------------------------------------------------------------- +// Retrieve the collection details +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoHandleOtherMediaAttributesL( + const TArray& aAttrs, + const CMPXCollectionPath& aPath, + CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoHandleOtherMediaAttributesL"); + + TInt count(aAttrs.Count()); + for (TInt i = 0; i < count; ++i) + { + if (aAttrs[i].ContentId() == KMPXMediaIdCollectionDetails) + { + TUint att(aAttrs[i].AttributeId()); + + if (att & EMPXMediaColDetailNumberOfItems) + { + aMedia.SetTObjectValueL(KMPXMediaColDetailNumberOfItems, + iDbHandler->NumberOfItemsL(EMPXEpisode) ); + } + if (att & EMPXMediaColDetailDuration) + { + aMedia.SetTObjectValueL(KMPXMediaColDetailDuration, + DoDurationL( aMedia, EMPXEpisode ) ); + } + if (att & EMPXMediaColTotalSize) + { + TInt totalSize(0); + // todo + aMedia.SetTObjectValueL(KMPXMediaColDetailTotalSize, totalSize ); + } + if (att & EMPXMediaLastRefreshed) + { + TTime lastRefreshed = iDbHandler->GetLastRefreshedTimeL(); + aMedia.SetTObjectValueL(KMPXMediaColDetailLastRefreshed, + lastRefreshed.Int64() ); + } + if (att & EMPXMediaColDetailDBCreated) + { + aMedia.SetTObjectValueL(KMPXMediaColDetailDBCreated, + iDbHandler->DatabaseCreated()); + } + if (att & EMPXMediaColDetailDBCorrupted) + { + aMedia.SetTObjectValueL(KMPXMediaColDetailDBCorrupted, + iDbHandler->IsDBCorruptedL()); + } + } + else if (aAttrs[i] == KMPXMediaGeneralPath) + { + aMedia.SetCObjectValueL(KMPXMediaGeneralPath, + const_cast(&aPath)); + } + } + } + +// ---------------------------------------------------------------------------- +// Remove an item from the collection database using the given path +// ---------------------------------------------------------------------------- +// +CDesCArray* CMPXPodcastDbPlugin::DoRemoveL( + const CMPXCollectionPath& aPath, + CMPXMessageArray& aChangeMsgArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRemoveL"); + + if (aPath.Levels() <= 0) + { + User::Leave(KErrNotSupported); + } + + // Return file path for deleted item(s) + // + CDesCArray* fp = new(ELeave) CDesCArrayFlat(1); + CleanupStack::PushL(fp); + + // Ids of the selected items + RArray selections; + CleanupClosePushL(selections); + aPath.SelectionL(selections); + + DoRemoveFromCategoriesL(aPath, selections.Array(), EMPXAlbum, *fp, aChangeMsgArray); + + MPX_DEBUG2("CMPXPodcastDbPlugin::DoRemoveL itemId[%d]", aPath.Id (aPath.Levels() - 1).iId2); + + CleanupStack::PopAndDestroy(&selections); + CleanupStack::Pop(fp); + + return fp; + } + +// ---------------------------------------------------------------------------- +// Remove media by path through a command +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRemoveL( + const CMPXMedia& aMedia, + TBool aDeleteRecord) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRemoveL(by command)"); + + // Return deleted file paths to caller + CDesCArray* fp = new(ELeave) CDesCArrayFlat(1); + CleanupStack::PushL(fp); + + // a list of change event messages a result of the item being removed + CMPXMessageArray* itemChangedMessages = CMPXMediaArray::NewL(); + CleanupStack::PushL(itemChangedMessages); + + TUint32 podcastEpisodeId(0); + + // Removing a container of items + // + if (aMedia.IsSupported(KMPXMediaArrayContents)) + { + MPX_DEBUG1("CMPXPodcastDbPlugin::RemoveL -- Removing a container of items"); + const CMPXMediaArray* media = (aMedia.Value(KMPXMediaArrayContents)); + if( !media ) + { + User::Leave( KErrNoMemory ); + } + const TInt mediaCount(media->Count()); + for (TInt i = 0; i < mediaCount; ++i) + { + CMPXMedia* entry = media->AtL(i); + if( entry->IsSupported(KMPXMediaGeneralId)) + { + podcastEpisodeId = entry->ValueTObjectL(KMPXMediaGeneralId); + } + else if (entry->IsSupported(KMPXMediaGeneralUri)) + { + podcastEpisodeId = iDbHandler->GetEpisodeIdMatchingUriL( + entry->ValueText(KMPXMediaGeneralUri)); + } + else + { + // Unable to process this item + continue; + } + + iDbHandler->RemoveEpisodeL(podcastEpisodeId, *fp, *itemChangedMessages, + aDeleteRecord); + } + } + // Removing an item with known item id + // + else if (aMedia.IsSupported(KMPXMediaGeneralId)) + { + MPX_DEBUG1("CMPXPodcastDbPlugin::RemoveL -- Removing an item by item id"); + podcastEpisodeId = aMedia.ValueTObjectL(KMPXMediaGeneralId); + + if ((podcastEpisodeId >> 28) != EMPXPlaylist) + { + iDbHandler->RemoveEpisodeL(podcastEpisodeId, *fp, + *itemChangedMessages, aDeleteRecord); + } + else + { + MPX_DEBUG1("CMPXPodcastDbPlugin::RemoveL -- Playlists not supported within podcast collection"); + User::Leave(KErrNotSupported); + } + } + // Removing an item with known uri + // + else if (aMedia.IsSupported(KMPXMediaGeneralUri)) + { + MPX_DEBUG1("CMPXPodcastDbPlugin::RemoveL -- Removing an item by uri"); + podcastEpisodeId = iDbHandler->GetEpisodeIdMatchingUriL( + aMedia.ValueText(KMPXMediaGeneralUri)); + iDbHandler->RemoveEpisodeL(podcastEpisodeId, *fp, *itemChangedMessages, + aDeleteRecord); + } + else + { + MPX_DEBUG1("CMPXPodcastDbPlugin::RemoveL -- Unknown item for removal"); + User::Leave(KErrNotSupported); + } + + iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible); + DoHandleChangeL(itemChangedMessages); + + CleanupStack::PopAndDestroy(itemChangedMessages); + CleanupStack::PopAndDestroy(fp); + } + +// ---------------------------------------------------------------------------- +// Remove an item from the collection database using the given media properties +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRemovePathL( + CMPXCommand& aCmd) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRemovePathL(by command)"); + + TInt removeError(KErrNone); + TBool removeCompleted(ETrue); + + if (!aCmd.IsSupported(KMPXCommandCollectionRemovePath) || + !aCmd.IsSupported(KMPXCommandCollectionRemoveMediaCount)) + { + removeError = KErrArgument; + } + else + { + CMPXCollectionPath* path = + aCmd.ValueCObjectL(KMPXCommandCollectionRemovePath); + CleanupStack::PushL(path); + + // in order to support cancel delete for a category, we need to adjust path. If + // the path ends in a category, retrieve all episodes under the selected category + // and append a new level with all episodes under the selected category + DoAppendLevelL(*path); + + CMPXCollectionPath* iterationPath = CMPXCollectionPath::NewL(*path); + CleanupStack::PushL(iterationPath); + iterationPath->ClearSelection(); + + // indices of the selected items + TArray selectionIndices = path->Selection(); + TInt count(selectionIndices.Count()); + + // number of medias to remove in this iteration + TInt removeCount = (aCmd.ValueTObjectL(KMPXCommandCollectionRemoveMediaCount)); + + // remove all in one shut if removeCount is 0 or negative + if (removeCount <= 0) + { + removeCount = count; + } + + // If the given path contains multiple selections, remove the first n selected media + // and update the path so that client can use this path to call remove iteratively + // until all selections are processed + // + if (count) + { + for (TInt i = 0; i < removeCount; ++i) + { + TInt index(selectionIndices[i]); + + MPX_DEBUG4(" path: selected item [index %d] [selectioncount %d] [remove count %d]", index, count, removeCount); + + iterationPath->SelectL(index); + path->Remove(index); + } + + aCmd.SetCObjectValueL(KMPXCommandCollectionRemovePath, path); + + // indicate to the client that subsequent remove command is required + if ((count - removeCount) > 0) + { + removeCompleted = EFalse; + } + } + + // Remove the media specified by the path + CDesCArray* fp(NULL); + TBool supressMsgs(EFalse); + CMPXMessageArray* msgAry(NULL); + if (aCmd.IsSupported(KMPXCommandCollectionRemoveSuppressMsgs) && + aCmd.ValueTObjectL(KMPXCommandCollectionRemoveSuppressMsgs) ) + { + // Msgs are stored in the command + supressMsgs = ETrue; + CMPXMessageArray* msgs( aCmd.Value(KMPXCommandCollectionChangeMsgs) ); + User::LeaveIfNull( msgs ); + fp = DoRemoveL(*iterationPath, *msgs ); + } + else + { + // Msgs will be sent after delete + msgAry = CMPXMessageArray::NewL(); + CleanupStack::PushL( msgAry ); + fp = DoRemoveL(*iterationPath, *msgAry); + } + + CleanupStack::PushL(fp); + if (fp->MdcaCount() > removeCount) + { + removeError = KErrCorrupt; + } + CleanupStack::PopAndDestroy(fp); + + if (!supressMsgs) + { + // Send Change Messages + iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible); + DoHandleChangeL(msgAry); + CleanupStack::PopAndDestroy(msgAry); + } + + // Cleanup + CleanupStack::PopAndDestroy(iterationPath); + CleanupStack::PopAndDestroy(path); + } + + // mandatory return parameters + aCmd.SetTObjectValueL(KMPXCommandCollectionRemoveError, removeError); + aCmd.SetTObjectValueL(KMPXCommandCollectionRemoveCompleted, removeCompleted); + } + +// ---------------------------------------------------------------------------- +// Remove media by CMPXMedia through a command +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRemoveMediaL( + CMPXCommand& aCmd) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRemoveMediaL(by command)"); + + TInt error(KErrArgument); + + if (aCmd.IsSupported(KMPXCommandCollectionRemoveMedia)) + { + CMPXMedia* media = aCmd.ValueCObjectL(KMPXCommandCollectionRemoveMedia); + CleanupStack::PushL(media); + + MPX_TRAP(error, DoRemoveL(*media, + aCmd.ValueTObjectL(KMPXCommandCollectionRemoveMediaDeleteRecord))); + + CleanupStack::PopAndDestroy(media); + } + + aCmd.SetTObjectValueL(KMPXCommandCollectionRemoveMediaError, error); + } + +// ---------------------------------------------------------------------------- +// Remove a media/media items from All Episodes view +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRemoveFromAllEpisodesL( + const CMPXCollectionPath& aPath, + const TArray& aSelections, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRemoveFromAllEpisodesL"); + + switch (aPath.Levels()) + { + case 2: + { + // when the collection is removed, it's intended not to delete the files + iDbHandler->RemoveEntireCollectionL(); + } + break; + + case 3: + { + TInt count(aSelections.Count()); + if (count) + { + for (TInt i = 0; i < count; ++i) + { + iDbHandler->RemoveEpisodeL (aSelections[i], aUriArray, + aItemChangedMessages); + } // end for + } + else + { + iDbHandler->RemoveEpisodeL(aPath.Id(aPath.Levels() - 1), aUriArray, + aItemChangedMessages); + } + } + break; + + default: + { + MPX_DEBUG2("CMPXPodcastDbPlugin_DoRemoveFromAllEpisodesL: Invalid levels[%d]", aPath.Levels()); + User::Leave(KErrNotSupported); + } + } + } + +// ---------------------------------------------------------------------------- +// Remove a media/media items from By Publish Date view +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRemoveFromPublishDateL( + const CMPXCollectionPath& aPath, + const TArray& aSelections, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRemoveFromPublishDateL"); + + TInt levels(aPath.Levels()); + + if (levels == 2) + { + // when the collection is removed, it's intended no to delete the files + iDbHandler->RemoveEntireCollectionL(); + } + else + { + TInt count(aSelections.Count()); + if (count) + { + for (TInt i = 0; i < count; ++i) + { + RemoveFromPublishDateL(aPath, aSelections[i].iId2, aUriArray, aItemChangedMessages); + } + } + else + { + RemoveFromPublishDateL(aPath, aPath.Id(levels - 1).iId2, aUriArray, aItemChangedMessages); + } + } + + MPX_DEBUG2("CMPXPodcastDbPlugin__RemoveL__EBrowsePubDate: levels[%d]", aPath.Levels()); + } + +// ---------------------------------------------------------------------------- +// Remove a media item from By Publish Date view +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::RemoveFromPublishDateL( + const CMPXCollectionPath& aPath, + TInt aItemId, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbPlugin::RemoveFromPublishDateL"); + + switch (aPath.Levels()) + { + case 3: + { + iDbHandler->RemoveEpisodesMatchingPublishDateCategoryL(aItemId, aUriArray, + aItemChangedMessages); + break; + } + case 4: + { + iDbHandler->RemoveEpisodeL(aItemId, aUriArray, + aItemChangedMessages); + break; + } + default: + { + User::Leave(KErrArgument); + } + } + } + +// ---------------------------------------------------------------------------- +// Remove a media/media items from Titles/Genre etc.. view +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRemoveFromCategoriesL( + const CMPXCollectionPath& aPath, + const TArray& aSelections, + TMPXGeneralCategory aCategory, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRemoveFromCategoriesL"); + + TInt levels(aPath.Levels()); + if (levels == 1) + { + // when the collection is removed, it's intended no to delete the files + iDbHandler->RemoveEntireCollectionL(); + } + else + { + TInt count(aSelections.Count()); + if (count) + { + for (TInt i = 0; i < count; ++i) + { + RemoveFromCategoriesL(aPath, aSelections[i], aCategory, aUriArray, + aItemChangedMessages); + } + } + + else + { + RemoveFromCategoriesL(aPath, aPath.Id (aPath.Levels() - 1), aCategory, aUriArray, + aItemChangedMessages); + } + } + + MPX_DEBUG2("CMPXPodcastDbPlugin_DoRemoveFromCategoriesL: levels[%d]", aPath.Levels()); + } + +// ---------------------------------------------------------------------------- +// Remove a media item from Albums/Genres/Composers view +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::RemoveFromCategoriesL( + const CMPXCollectionPath& aPath, + TInt aItemId, + TMPXGeneralCategory aCategory, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbPlugin::RemoveFromCategoriesL"); + + switch (aPath.Levels()) + { + case 2: + { + iDbHandler->RemoveEpisodesMatchingCategoryL(aCategory, aItemId, + aUriArray, aItemChangedMessages); + break; + } + case 3: + { + iDbHandler->RemoveEpisodeL(aItemId, aUriArray, aItemChangedMessages); + break; + } + default: + { + User::Leave(KErrArgument); + } + } + } + +// ---------------------------------------------------------------------------- +// Retrieve URIs associated with this file path for file deletion +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoRetrieveUriForDeletionL( + CMPXCommand& aCmd) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoRetrieveUriForDeletionL"); + + // initialize mandatory return parameters + aCmd.SetTObjectValueL(KMPXCommandCollectionRetrieveUriError, KErrNone); + + if (!aCmd.IsSupported(KMPXCommandCollectionRetrievePath)) + { + aCmd.SetTObjectValueL(KMPXCommandCollectionRetrieveUriError, KErrArgument); + } + else + { + CMPXCollectionPath* path = aCmd.ValueCObjectL( + KMPXCommandCollectionRetrievePath); + CleanupStack::PushL(path); + + if (iFirstDeleteStep ) + { + iSelections.Reset( ); + // in order to support cancel delete for a category, we need to adjust path. If + // the path ends in a category, retrieve all songs under the selected category + // and append a new level with all songs under the selected category + DoAppendLevelL(*path ); + + // Ids of the selected items + path->SelectionL(iSelections ); + + // single selection + if (iSelections.Count()== 0 ) + { + iSelections.AppendL(path->Id (path->Levels()- 1 ) ); + } + } + CDesCArray* fp = new(ELeave) CDesCArrayFlat(4); + CleanupStack::PushL(fp); + + TInt count = iSelections.Count(); + TInt itemCount = count > KIncrementalDeleteCount ? KIncrementalDeleteCount : count; + for (TInt i = 0; i < itemCount; ++i) + { + HBufC* uri = iDbHandler->GetUriMatchingIdL(iSelections[0]); + CleanupStack::PushL(uri); + fp->AppendL(*uri); + CleanupStack::PopAndDestroy(uri); + iSelections.Remove(0); + + } + aCmd.SetNoNewLCObjectL (KMPXCommandCollectionRetrieveMediaUriArray, fp); + if (iFirstDeleteStep) + { + aCmd.SetCObjectValueL(KMPXCommandCollectionRetrievePath, path); + } + CleanupStack::PopAndDestroy(fp); + CleanupStack::PopAndDestroy(path); + } + } + +// ---------------------------------------------------------------------------- +// Cleanup deleted medias +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::CleanupDeletedRecordsL( + CMPXCommand& aCmd) + { + MPX_FUNC("CMPXPodcastDbPlugin::CleanupDeletedRecordsL"); + + MPX_TRAPD(error, iDbHandler->CleanupDeletedRecordsL()); + aCmd.SetTObjectValueL(KMPXCommandCollectionCleanupError, error); + } + +// ---------------------------------------------------------------------------- +// Retrieve the duration +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbPlugin::DoDurationL( + CMPXMedia& aMedia, + TMPXPodcastCategory aCategory, + TMPXItemId aId) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoDurationL"); + + TInt duration(0); + switch (aCategory) + { + case EMPXEpisode: + { + duration = iDbHandler->GetAllEpisodesDurationL(); + break; + } + case EMPXTitle: + { + duration = iDbHandler->GetTitleDurationL(aId.iId2); + break; + } + case EMPXNotYetPlayed: + { + duration = iDbHandler->GetNotPlayedDurationL(); + break; + } + case EMPXRecentlyAdded: + { + duration = iDbHandler->GetRecentlyAddedDurationL(); + break; + } + default: + { + User::Leave(KErrNotSupported); + } + } + + aMedia.SetTObjectValueL(KMPXMediaGeneralDuration, duration); + return duration; + } + +// ---------------------------------------------------------------------------- +// Append a level to a collection path and set selection to the first level +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbPlugin::DoAppendLevelL( + CMPXCollectionPath& aPath, + CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoAppendLevelL"); + + RArray ids; + CleanupClosePushL(ids); + + // Extract media array, and get all item ids + // + const CMPXMediaArray* mediaArray = aMedia.Value(KMPXMediaArrayContents); + if( !mediaArray ) + { + User::Leave(KErrNoMemory); + } + TInt count(mediaArray->Count()); + + if (count >= 0) + { + for (TInt i = 0; i < count; ++i) + { + TMPXItemId id = mediaArray->AtL(i)->ValueTObjectL(KMPXMediaGeneralId); + ids.AppendL(id); + } + + // Put item id array into the path and select the first one + aPath.AppendL(ids.Array()); + if (count > 0) + { + aPath.Set(0); + } + } + + CleanupStack::PopAndDestroy(&ids); + return count; + } + +// ---------------------------------------------------------------------------- +// Append a level to a collection path and set selection to all episodes under the selected category/categories +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoAppendLevelL( + CMPXCollectionPath& aPath) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoAppendLevelL"); + + TMPXItemId contextId(aPath.Id(1)); + TInt levels(aPath.Levels()); + + if (contextId == EBrowseAll) + { + return; + } + else if (levels == 2) + { + // retrieve episodes in the selected category + CMPXMediaArray* episodes = CMPXMediaArray::NewL(); + CleanupStack::PushL(episodes); + + RArray attributes; + CleanupClosePushL(attributes); + attributes.AppendL(KMPXMediaGeneralId); + + // Ids of the selected items + RArray selections; + CleanupClosePushL(selections); + aPath.SelectionL(selections); + + // single selection + if (selections.Count() == 0) + { + selections.AppendL(aPath.Id(aPath.Levels() - 1)); + } + + TInt count(selections.Count()); + + for (TInt i = 0; i < count; ++i) + { + iDbHandler->GetEpisodesMatchingTitleL(selections[i], attributes.Array(), *episodes); + } + + CleanupStack::PopAndDestroy(2, &attributes); // selections & attributes + + // transform from CMPXMediaArray to RArray + RArray episodeIds; + CleanupClosePushL(episodeIds); + + TInt episodeCount(episodes->Count()); + for (TInt i = 0; i < episodeCount; ++i) + { + CMPXMedia* episode = (*episodes)[i]; + + if (episode->IsSupported(KMPXMediaGeneralId)) + { + episodeIds.AppendL(episode->ValueTObjectL(KMPXMediaGeneralId)); + } + } + + // modify the collection path. append another level with all episodes under the selected + // category/categories selected + episodeCount = episodeIds.Count(); + + if (episodeCount) + { + aPath.ClearSelection(); + aPath.AppendL(episodeIds.Array()); + + // select all + for (TInt i = 0; i < episodeCount; ++i) + { + aPath.SelectL(episodeIds[i]); + } + } + + CleanupStack::PopAndDestroy(2, episodes); // episodeIds & episodes + } + else + { + // else do nothing + } + } + +// ---------------------------------------------------------------------------- +// Execute an Add task step +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoAddAsyncL() + { + MPX_FUNC("CMPXPodcastDbPlugin::DoAddAsyncL"); + + TBool done(EFalse); + CMPXMedia* task = iActiveTask->GetCommand().Value(KMPXCommandColAddMedia); + User::LeaveIfNull(task); + + CMPXMessageArray& msgArray = iActiveTask->GetChangeMessages(); + + if (!task->IsSupported(KMPXMediaGeneralType)) + { + User::Leave(KErrArgument); + } + + // Group of items or a single item + // + if (task->ValueTObjectL(KMPXMediaGeneralType) == EMPXGroup) + { + if(!task->IsSupported(KMPXMediaArrayContents)) + { + User::Leave(KErrArgument); + } + + CMPXMediaArray* ary = task->Value(KMPXMediaArrayContents); + User::LeaveIfNull( ary ); + + TInt step( iActiveTask->GetStep() ); + DoAddItemL(*ary->AtL(step), msgArray); + + if (++step == ary->Count()) + { + done = ETrue; + } + } + else // type == EMPXItem + { + TUint32 item = DoAddItemL( *task, msgArray ); + iActiveTask->GetCommand().SetTObjectValueL( KMPXCommandColAddRtnId, item ); + done = ETrue; + } + + iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible); + return done; + } + +// ---------------------------------------------------------------------------- +// Add an item to the collection +// ---------------------------------------------------------------------------- +// +TUint32 CMPXPodcastDbPlugin::DoAddL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoAddL"); + + TUint32 itemId(0); + CMPXMessageArray* changeMsgAry = CMPXMessageArray::NewL(); + CleanupStack::PushL( changeMsgAry ); + + if (!aMedia.IsSupported(KMPXMediaGeneralType)) + { + User::Leave(KErrArgument); + } + + // Group of items + // + if (aMedia.ValueTObjectL(KMPXMediaGeneralType) == EMPXGroup) + { + CMPXMediaArray* ary = aMedia.Value(KMPXMediaArrayContents); + User::LeaveIfNull( ary ); + + TInt count(ary->Count()); + for (TInt i = 0; i < count; ++i) + { + DoAddItemL(*ary->AtL(i), *changeMsgAry); + } + } + else // single item + { + itemId = DoAddItemL(aMedia, *changeMsgAry); + } + + iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible); + DoHandleChangeL(changeMsgAry); + CleanupStack::PopAndDestroy(changeMsgAry); + + return itemId; + } + +// ---------------------------------------------------------------------------- +// Add an item to the collection +// ---------------------------------------------------------------------------- +// +TUint32 CMPXPodcastDbPlugin::DoAddItemL( + const CMPXMedia& aMedia, + CMPXMessageArray& aMessageArray) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoAddItemL"); + + TInt itemId(0); + + if (!aMedia.IsSupported(KMPXMediaGeneralCategory)) + { + User::Leave(KErrArgument); + } + + switch ( aMedia.ValueTObjectL(KMPXMediaGeneralCategory)) + { + case EMPXPodcast: + case EMPXSong: + { + itemId = iDbHandler->AddEpisodeL(aMedia); + MPXDbCommonUtil::AddItemChangedMessageL(aMessageArray, itemId, EMPXItemInserted, + EMPXPodcast, KDBPluginUid); + break; + } + default: + { + User::Leave(KErrNotSupported); + } + } + + return itemId; + } +// ---------------------------------------------------------------------------- +// Sets/updates the media for an item in the collection +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoSetL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoSetL"); + + if (!aMedia.IsSupported(KMPXMediaGeneralType) || + !aMedia.IsSupported(KMPXMediaGeneralCategory)) + { + User::Leave(KErrArgument); + } + + CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile); + + switch ( aMedia.ValueTObjectL(KMPXMediaGeneralCategory)) + { + case EMPXPodcast: + case EMPXSong: + { + // a list of changed messages as a result of the episode being updated + CMPXMessageArray* itemChangedMessages = CMPXMediaArray::NewL(); + CleanupStack::PushL(itemChangedMessages); + + if (aMedia.ValueTObjectL(KMPXMediaGeneralType) == EMPXGroup) + { + if (!aMedia.IsSupported(KMPXMediaArrayContents)) + { + User::Leave(KErrArgument); + } + + CMPXMediaArray* array = aMedia.Value(KMPXMediaArrayContents); + User::LeaveIfNull( array ); + + TInt count(array->Count()); + for (TInt i = 0; i < count; ++i) + { + visibleChange = (CMPXDbActiveTask::TChangeVisibility)(visibleChange | + iDbHandler->UpdateEpisodeL(*array->AtL(i), *itemChangedMessages)); + } + } + else + { + visibleChange = iDbHandler->UpdateEpisodeL(aMedia, + *itemChangedMessages); + } + + if (visibleChange) + { + iActiveTask->SetVisibleChange(visibleChange); + DoHandleChangeL(itemChangedMessages); + } + + CleanupStack::PopAndDestroy(itemChangedMessages); + } + break; + + default: + { + User::Leave(KErrNotSupported); + } + break; + } + } + +// ---------------------------------------------------------------------------- +// Execute a task step for async set +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbPlugin::DoSetAsyncL() + { + MPX_FUNC("CMPXPodcastDbPlugin::DoSetAsyncL"); + + TBool done(EFalse); + CMPXMedia* task = (iActiveTask->GetCommand().Value(KMPXCommandColSetMedia)); + User::LeaveIfNull( task ); + + CMPXMessageArray& msgArray = iActiveTask->GetChangeMessages(); + CMPXDbActiveTask::TChangeVisibility visibleChange(iActiveTask->GetVisibleChange()); + + // Multiple steps can be in a transaction for faster response + if( iDbHandler && !iDbHandler->InTransaction() ) + { + iDbHandler->BeginTransactionL(); + } + + if (!task->IsSupported(KMPXMediaGeneralType)) + { + User::Leave(KErrArgument); + } + + if (task->ValueTObjectL(KMPXMediaGeneralType) == EMPXGroup) + { + if (!task->IsSupported(KMPXMediaArrayContents)) + { + User::Leave(KErrArgument); + } + + // Multiple items + CMPXMediaArray* array = task->Value(KMPXMediaArrayContents); + User::LeaveIfNull( array ); + + TInt step = iActiveTask->GetStep(); + visibleChange = (CMPXDbActiveTask::TChangeVisibility)( visibleChange | iDbHandler->UpdateEpisodeL(*array->AtL(step), msgArray)); + + if (++step == array->Count()) + { + done = ETrue; + } + } + else // Single item + { + if(iDbHandler) + { + visibleChange = iDbHandler->UpdateEpisodeL(*task, msgArray); + done = ETrue; + } + } + iActiveTask->SetVisibleChange(visibleChange); + return done; + } + +// ---------------------------------------------------------------------------- +// Handle change events +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::HandleChangeL( + const CMPXMessage& aMessage) + { + MPX_FUNC("CMPXPodcastDbPlugin::HandleChange"); + + // check if message is filled + if (aMessage.IsSupported(KMPXMessageGeneralId)) + { +#ifdef _DEBUG + PrintMessagesL(aMessage); +#endif // _DEBUG + if(iRefreshing) + { + if (aMessage.IsSupported(KMPXMessageArrayContents)) + { + const CMPXMessageArray* messageArray = aMessage.Value(KMPXMessageArrayContents); + if(messageArray) + { + CMPXMessage& message = *((*messageArray)[0]); + TMPXChangeEventType changeType( message.ValueTObjectL( KMPXMessageChangeEventType ) ); + TMPXGeneralCategory cat(message.ValueTObjectL(KMPXMessageMediaGeneralCategory)); + if(changeType == EMPXItemInserted && (cat == EMPXPodcast || cat == EMPXSong || cat == EMPXPlaylist)) + { + iObs->HandleMessage(aMessage); + } + } + } + else + { + TMPXChangeEventType changeType( aMessage.ValueTObjectL( KMPXMessageChangeEventType ) ); + TMPXGeneralCategory cat(aMessage.ValueTObjectL(KMPXMessageMediaGeneralCategory)); + if(changeType == EMPXItemInserted && (cat == EMPXPodcast || cat == EMPXSong || cat == EMPXPlaylist)) + { + iObs->HandleMessage(aMessage); + } + } + } + else + { + if(!iMtpInUse) + { + iObs->HandleMessage(aMessage); + } + } + } + } + +// ---------------------------------------------------------------------------- +// Construct a CMPXMedia and call HandleChange +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoHandleChangeL( + CMPXMessageArray* aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoHandleChangeL"); + + TMPXCommandId cmdId = iActiveTask->GetTask(); + if((iActiveTask->GetVisibleChange() & CMPXDbActiveTask::EAllVisible) + && (cmdId == KMPXCommandIdCollectionSet || + cmdId == KMPXCommandIdCollectionAdd || + cmdId == KMPXCommandIdCollectionRemove || + cmdId == KMPXCommandIdCollectionRemoveMedia || + cmdId == KMPXCommandIdCollectionCompleteDelete )) + { + MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, EBrowseAll, + EMPXItemModified, EMPXCollection, KDBPluginUid); + } + + // group change messages and send to collection client context + CMPXMessage* message = CMPXMessage::NewL(); + CleanupStack::PushL(message); + + message->SetTObjectValueL(KMPXMessageGeneralId, KMPXMessageIdItemChanged); + message->SetCObjectValueL(KMPXMessageArrayContents, aItemChangedMessages); + message->SetTObjectValueL(KMPXMessageArrayCount, aItemChangedMessages->Count()); + + HandleChangeL(*message); + + CleanupStack::PopAndDestroy(message); + } + +// ---------------------------------------------------------------------------- +// Handle out of disk events during db merging +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::HandleOutOfDiskMessageL() + { + MPX_FUNC("CMPXPodcastDbPlugin::HandleOutOfDiskMessageL"); + + if (iObs) + { + // Create the msg + CMPXMessage* msg = CMPXMessage::NewL(); + CleanupStack::PushL( msg ); + + // Setup the message parameters + msg->SetTObjectValueL(KMPXMessageGeneralId, KMPXCustomMessageId); + msg->SetTObjectValueL(KMPXCustomMessageCollectionId, KDBPluginUid); + msg->SetTObjectValueL(KMPXCustomMessageEventType, EMcsOpen); + msg->SetTObjectValueL(KMPXCustomMessageErrorCode, KErrDiskFull); + + // Callback and Cleanup + iObs->HandleMessage(*msg); + CleanupStack::PopAndDestroy(msg); + } + } + +// ---------------------------------------------------------------------------- +// Handle completion of operation +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoHandleOperationCompletedL( + TInt aErr) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoHandleOperationCompletedL"); + + if( iDbHandler && iDbHandler->InTransaction() ) + { + // Commit if cancelled + TInt err(aErr); + if( err == KErrCancel ) + { + err = KErrNone; + } + iDbHandler->EndTransactionL( err ); + } + + // Broadcase change messages + // + if (iActiveTask->GetVisibleChange()) + { + DoHandleChangeL(&iActiveTask->GetChangeMessages()); + } + + // Callback to engine to signal completion + // NOTE: Collection server immediately completes the async message when + // Cancel is called, no need to callback to observer + if (aErr != KErrCancel) + { + iObs->HandleCommandComplete(NULL, aErr); + } + } + + +// ---------------------------------------------------------------------------------------------------------- +// Complete a delete operation +// ---------------------------------------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoHandleDeleteCompleteL( + CMPXCommand& aCmd) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoHandleDeleteCompleteL"); + iFirstDeleteStep = ETrue; + iSelections.Reset(); + // Change messages + if (aCmd.IsSupported(KMPXCommandCollectionDeleteMsgArray)) + { + CMPXMessageArray* msgs = aCmd.Value(KMPXCommandCollectionDeleteMsgArray); + User::LeaveIfNull( msgs ); + iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible); + DoHandleChangeL(msgs); + } + } + +// ---------------------------------------------------------------------------- +// Maps a given browse type to a category ID. +// ---------------------------------------------------------------------------- +// +TMPXPodcastCategory CMPXPodcastDbPlugin::CategoryForBrowseType( + TMCBrowseType aBrowseType) + { + MPX_FUNC("CMPXPodcastDbPlugin::CategoryForBrowseType"); + + TMPXPodcastCategory cat(EMPXUnknown); + + switch (aBrowseType) + { + case EBrowseAll: + { + cat = EMPXAll; + break; + } + case EBrowseTitle: + { + cat = EMPXTitle; + break; + } + case EBrowsePubDate: + { + cat = EMPXPubDate; + break; + } + case EBrowseRecentlyAdded: + { + cat = EMPXRecentlyAdded; + break; + } + case EBrowseNotPlayed: + { + cat = EMPXNotYetPlayed; + break; + } + default: + { + // do nothing + break; + } + } + + return cat; + } + +// ---------------------------------------------------------------------------- +// Maps a given category ID to a browse type. +// ---------------------------------------------------------------------------- +// +TMCBrowseType CMPXPodcastDbPlugin::BrowseTypeForCategory( + TMPXPodcastCategory aCategory) + { + MPX_FUNC("CMPXPodcastDbPlugin::BrowseTypeForCategory"); + + TMCBrowseType browseType(EBrowseNotPlayed); + + switch (aCategory) + { + case EMPXAll: + { + browseType = EBrowseAll; + break; + } + case EMPXTitle: + { + browseType = EBrowseTitle; + break; + } + case EMPXPubDate: + { + browseType = EBrowsePubDate; + break; + } + case EMPXRecentlyAdded: + { + browseType = EBrowseRecentlyAdded; + break; + } + default: + { + // do nothing + break; + } + } + + return browseType; + } + +// ---------------------------------------------------------------------------- +// Sets the type, category and title attributes in the specified media instance +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::SetMediaGeneralAttributesL( + CMPXMedia& aMedia, + TMPXGeneralType aGeneralType, + TMPXPodcastType aType, + TMPXPodcastCategory aCategory, + const TDesC& aTitle, + TInt aCount /* = -1 */) + { + MPX_FUNC("CMPXPodcastDbPlugin::SetMediaGeneralAttributesL"); + + aMedia.SetTObjectValueL(KMPXMediaGeneralType, aGeneralType); + aMedia.SetTObjectValueL(KMPXMediaPodcastType, aType); + aMedia.SetTObjectValueL(KMPXMediaPodcastCategoryGroup, aCategory); + aMedia.SetTextValueL(KMPXMediaGeneralTitle, aTitle); + + if (aCount >= 0) + { + aMedia.SetTObjectValueL(KMPXMediaGeneralCount, aCount); + } + } + +// ---------------------------------------------------------------------------- +// Sets the type, category and title attributes in the specified media instance +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::SetMediaGeneralAttributesL( + CMPXMedia& aMedia, + TMPXGeneralType aGeneralType, + TMPXPodcastType aType, + TMPXPodcastCategory aCategory, + TInt aId, + TInt aCount /* = -1 */) + { + MPX_FUNC("CMPXPodcastDbPlugin::SetMediaGeneralAttributesL"); + + HBufC* title = iDbHandler->GetTitleNameMatchingIdL(aId); + CleanupStack::PushL(title); + SetMediaGeneralAttributesL(aMedia, aGeneralType, aType, aCategory, *title, aCount); + CleanupStack::PopAndDestroy(title); + } + +// ---------------------------------------------------------------------------------------------------------- +// Get total podcast count for a database +// ---------------------------------------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoGetCollectionCountL( const CMPXCommand& aCmd ) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoGetCollectionCountL"); + //as there is only one table containing uri data, KMPXCommandCollectionCountTable is ignored + if (!aCmd.IsSupported(KMPXCommandCollectionCountDrive)) + { + User::Leave(KErrArgument); + } + + TInt drive = aCmd.ValueTObjectL(KMPXCommandCollectionCountDrive); + TInt count = (TInt)iDbHandler->GetTotalCountL(drive); + ((CMPXMedia&)aCmd).SetTObjectValueL(KMPXCommandCollectionCountValue, count); + } + +// ---------------------------------------------------------------------------------------------------------- +// Get URIs for all podcasts in a database +// ---------------------------------------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::DoGetCollectionUriL( const CMPXCommand& aCmd ) + { + MPX_FUNC("CMPXPodcastDbPlugin::DoGetCollectionCountL"); + //as there is only one table containing uri data, KMPXCommandCollectionCountTable is ignored + if (!aCmd.IsSupported(KMPXCommandCollectionURIDrive) || + !aCmd.IsSupported(KMPXCommandCollectionURIFromID) || + !aCmd.IsSupported(KMPXCommandCollectionURIRecords) ) + { + User::Leave(KErrArgument); + } + + TInt drive = aCmd.ValueTObjectL(KMPXCommandCollectionURIDrive); + TInt fromID = aCmd.ValueTObjectL(KMPXCommandCollectionURIFromID); + TInt recnum = aCmd.ValueTObjectL(KMPXCommandCollectionURIRecords); + + CDesCArray* uris = new(ELeave) CDesCArrayFlat(4); + CleanupStack::PushL(uris); + TInt lastID = 0; + + iDbHandler->GetPodcastUriArrayL(drive, fromID, recnum, *uris, lastID); + + ((CMPXMedia&)aCmd).SetNoNewLCObjectL(KMPXCommandCollectionURIList, uris); + ((CMPXMedia&)aCmd).SetTObjectValueL(KMPXCommandCollectionURILastID, lastID); + CleanupStack::PopAndDestroy(uris); + } + +void CMPXPodcastDbPlugin::SetAttributesL( + const CMPXCollectionPath& aPath, + RArray& aAttrs, + RArray& aSupportedIds ) + { + aAttrs.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralTitle | + EMPXMediaGeneralDuration | EMPXMediaGeneralSize | + EMPXMediaGeneralType | EMPXMediaGeneralCategory | EMPXMediaGeneralId | + EMPXMediaGeneralUri | EMPXMediaGeneralFlags | EMPXMediaGeneralCount | + EMPXMediaGeneralPlayCount | EMPXMediaGeneralLastPlaybackPosition | + EMPXMediaGeneralCollectionId | EMPXMediaGeneralDate)); + + aAttrs.AppendL(TMPXAttribute(KMPXMediaIdPodcast, + EMPXMediaPodcastType | EMPXMediaPodcastCategoryGroup | EMPXMediaPodcastIsPlaying)); + + aSupportedIds.AppendL(KMPXMediaIdContainer); + aSupportedIds.AppendL(KMPXMediaIdGeneral); + aSupportedIds.AppendL(KMPXMediaIdPodcast); + + TInt levels(aPath.Levels()); + if ( 1 < levels ) + { + // All episodes in a title + aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic, EMPXMediaMusicAlbumArtFileName ) ); + aSupportedIds.AppendL( KMPXMediaIdMusic ); + } + } + +#ifdef _DEBUG + +// ---------------------------------------------------------------------------- +// Print change events +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::PrintMessagesL( + const CMPXMessage& aMessage) + { + MPX_FUNC("CMPXPodcastDbPlugin::PrintMessages"); + + if (aMessage.IsSupported(KMPXMessageArrayContents)) + { + const CMPXMessageArray* messageArray = + aMessage.Value(KMPXMessageArrayContents); + if( !messageArray ) + { + User::Leave( KErrNoMemory ); + } + + TInt count(messageArray->Count()); + MPX_DEBUG2("%d messages:", count); + + for (TInt i = 0; i < count; ++i) + { + PrintMessage(*((*messageArray)[i])); + } + } + else + { + PrintMessage(aMessage); + } + } + +// ---------------------------------------------------------------------------- +// Print one change event +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbPlugin::PrintMessage( + const CMPXMessage& aMessage) + { + MPX_FUNC("CMPXPodcastDbPlugin::PrintMessage"); + + if (aMessage.IsSupported(KMPXMessageGeneralId)) + { + TMPXItemId id = aMessage.ValueTObjectL(KMPXMessageGeneralId); + MPX_DEBUG3(" message id[0x%x, 0x%x]", id.iId1, id.iId2); + } + + if (aMessage.IsSupported(KMPXMessageCollectionId)) + { + TUid uid = aMessage.ValueTObjectL(KMPXMessageCollectionId); + MPX_DEBUG2(" uid [0x%x]", uid.iUid); + } + + if (aMessage.IsSupported(KMPXMessageChangeEventType)) + { + MPX_DEBUG2(" change event type [%d]", + aMessage.ValueTObjectL(KMPXMessageChangeEventType)); + } + + if (aMessage.IsSupported(KMPXMessageMediaGeneralCategory)) + { + MPX_DEBUG2(" category [%d]", + aMessage.ValueTObjectL(KMPXMessageMediaGeneralCategory)); + } + + if (aMessage.IsSupported(KMPXMessageMediaGeneralId)) + { + TMPXItemId id = aMessage.ValueTObjectL(KMPXMessageMediaGeneralId); + MPX_DEBUG3(" media id[0x%x, 0x%x]", id.iId1, id.iId2); + } + + if (aMessage.IsSupported(KMPXMessageMediaDeprecatedId)) + { + TMPXItemId id = aMessage.ValueTObjectL(KMPXMessageMediaGeneralId); + MPX_DEBUG3(" deprecated id [0x%x, 0x%x]", id.iId1, id.iId2); + } + } + +#endif// _DEBUG + +// End of file