--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videocollection/mpxmyvideoscollection/src/vcxmyvideoscollectionplugin.cpp Mon Jan 18 20:21:12 2010 +0200
@@ -0,0 +1,1678 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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 My Videos collection Plugin interface*
+*/
+
+
+
+
+// INCLUDE FILES
+#include <e32cmn.h>
+#include <s32mem.h>
+#include <mpxlog.h>
+#include <mpxmediacontainerdefs.h>
+#include <mpxmediageneraldefs.h>
+#include <mpxmediageneralextdefs.h>
+#include <mpxcollectionpluginobserver.h>
+#include <mpxmessagegeneraldefs.h>
+#include <mpxcommandgeneraldefs.h>
+#include <mpxcollectioncommanddefs.h>
+#include <mpxmessagecontainerdefs.h>
+#include <vcxmyvideosuids.h>
+#include <drmutility.h>
+#include <bautils.h>
+#include "vcxmyvideoscollectionplugin.h"
+#include "vcxmyvideoscollection.hrh"
+#include "vcxmyvideoscollectionutil.h"
+#include "vcxmyvideosdownloadutil.h"
+#include "vcxmyvideosvideocache.h"
+#include "vcxmyvideoscategories.h"
+#include "vcxmyvideosmessagelist.h"
+#include "vcxmyvideosasyncfileoperations.h"
+#include "vcxmyvideosopenhandler.h"
+
+const TInt KMaxFileDeleteAttempts = 4;
+const TInt KFileDeleteLoopDelay = 100000;
+
+// Add 2000 new videos to memory card. Reboot phone, mds starts harvesting,
+// open my videos -> mds server crashes and lots of events is sent to client.
+// If one waits until all are harvested before opening my videos, it works.
+
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosCollectionPlugin* CVcxMyVideosCollectionPlugin::NewL(
+ TAny* /* aInitParams */)
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::NewL");
+
+ CVcxMyVideosCollectionPlugin* self = new (ELeave) CVcxMyVideosCollectionPlugin();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor.
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosCollectionPlugin::~CVcxMyVideosCollectionPlugin()
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::~CVcxMyVideosCollectionPlugin");
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: this = %x", this);
+
+ delete iMyVideosMdsDb;
+ delete iDownloadUtil;
+ delete iCache;
+ delete iMessageList;
+ delete iCategories;
+ delete iAsyncFileOperations;
+ delete iActiveTask;
+ delete iOpenHandler;
+ iFs.Close();
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosCollectionPlugin::CVcxMyVideosCollectionPlugin()
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::CVcxMyVideosCollectionPlugin");
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: this = %x", this);
+ }
+
+// ----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::ConstructL ()
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::ConstructL");
+
+ User::LeaveIfError( iFs.Connect() );
+
+ iMyVideosMdsDb = CVcxMyVideosMdsDb::NewL( this, iFs );
+ iActiveTask = CVcxMyVideosActiveTask::NewL( *this );
+ iCache = CVcxMyVideosVideoCache::NewL( *this );
+ iMessageList = CVcxMyVideosMessageList::NewL( *this );
+ iOpenHandler = CVcxMyVideosOpenHandler::NewL( *this, *iCache, *iMyVideosMdsDb );
+ }
+
+// ----------------------------------------------------------------------------
+// Navigates to the given path
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::OpenL(
+ const CMPXCollectionPath& aPath,
+ const TArray<TMPXAttribute>& /* aAttrs */,
+ CMPXFilter* /*aFilter*/)
+ {
+ iOpenHandler->OpenL( aPath );
+ }
+
+// ----------------------------------------------------------------------------
+// Get the extended properties of the current file (async)
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::MediaL(
+ const CMPXCollectionPath& aPath,
+ const TArray<TMPXAttribute>& aAttrs,
+ const TArray<TCapability>& /*aCaps*/,
+ CMPXAttributeSpecs* /*aSpecs*/)
+ {
+ MPX_FUNC("CMPXMyVideosDbPlugin::MediaL");
+ MPX_DEBUG_PATH(aPath);
+
+ RArray<TInt> supportedIds;
+ CleanupClosePushL( supportedIds ); // 1->
+
+ if ( aPath.Selection().Count() > 1 )
+ {
+ // it's a container if there are multiple selections, else it's not a container
+ //supportedIds.AppendL(KMPXMediaIdContainer);
+ //multiple selections not supported yet
+ CleanupStack::PopAndDestroy( &supportedIds ); // <-1
+ iObs->HandleMedia( NULL, KErrNotSupported );
+ return;
+ }
+
+ RArray<TMPXItemId> ids;
+ CleanupClosePushL(ids); // 2->
+
+ aPath.SelectionL( ids );
+
+ // MPX playback server asks it by path without selecting the media.
+ if ( ids.Count() == 0 && aPath.Id() != KMPXInvalidItemId )
+ {
+ CMPXCollectionPath* path = CMPXCollectionPath::NewL( aPath );
+ CleanupStack::PushL( path );
+ path->SelectL( aPath.Id() );
+ path->SelectionL( ids );
+ CleanupStack::PopAndDestroy( path );
+ }
+
+ if ( ids.Count() == 0 )
+ {
+ MPX_DEBUG1("CMPXMyVideosDbPlugin:: request didn't contain any items ids, aborting");
+
+ iObs->HandleMedia( NULL, KErrArgument );
+ CleanupStack::PopAndDestroy( &ids ); // <-2
+ CleanupStack::PopAndDestroy( &supportedIds ); // <-1
+ return;
+ }
+
+ TBool useCachedVideo( EFalse );
+
+ TInt pos;
+ CMPXMedia* videoInCache = iCache->FindVideoByMdsIdL( ids[0].iId1, pos );
+
+ if ( videoInCache )
+ {
+ // 0 attributes means "get all" -> can't use cache
+ MPX_DEBUG2("CMPXMyVideosDbPlugin:: client is requesting %d attributes", aAttrs.Count());
+ if ( aAttrs.Count() > 0 )
+ {
+ TBool nonSupportedAttrCanBeFoundFromMds;
+ if ( TVcxMyVideosCollectionUtil::AreSupported( *videoInCache, aAttrs,
+ nonSupportedAttrCanBeFoundFromMds ) )
+ {
+ MPX_DEBUG1("CMPXMyVideosDbPlugin:: all attributes found from cache");
+ useCachedVideo = ETrue;
+ }
+ else
+ {
+ MPX_DEBUG1("CMPXMyVideosDbPlugin:: all attributes NOT found from cache");
+ if ( !nonSupportedAttrCanBeFoundFromMds )
+ {
+ MPX_DEBUG1("CMPXMyVideosDbPlugin:: none of the non cached attrs can be found from MDS -> use cached version");
+ useCachedVideo = ETrue;
+ }
+ else
+ {
+ MPX_DEBUG1("CMPXMyVideosDbPlugin:: at least one of the non cached attributes can be found from MDS");
+ }
+ }
+ }
+ }
+
+ CMPXMedia* video;
+
+ if ( useCachedVideo )
+ {
+ MPX_DEBUG1("CMPXMyVideosDbPlugin:: using cached video");
+ video = CMPXMedia::CopyL( *videoInCache );
+ }
+ else
+ {
+ MPX_DEBUG1("CMPXMyVideosDbPlugin:: fetching from MDS");
+ video = iMyVideosMdsDb->CreateVideoL( ids[0].iId1, ETrue /* full details */ );
+ }
+
+ iObs->HandleMedia( video, KErrNone );
+
+ CleanupStack::PopAndDestroy( &ids ); // <-2
+ CleanupStack::PopAndDestroy( &supportedIds ); // <-1
+ }
+
+// ----------------------------------------------------------------------------
+// Cancel the pending request, this is called by mpx framework when client calls
+// Cancel.
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::CancelRequest()
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::CancelRequest");
+
+ iActiveTask->Cancel();
+ iMyVideosMdsDb->Cancel();
+ }
+
+// ----------------------------------------------------------------------------
+// Executes the given command on the collection
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::CommandL(
+ CMPXCommand& aCmd)
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::CommandL 2");
+
+ if ( !aCmd.IsSupported( KMPXCommandGeneralId ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TMPXCommandId commandId = *aCmd.Value<TMPXCommandId>(KMPXCommandGeneralId);
+
+ TBool syncOp( EFalse );
+ if( aCmd.IsSupported( KMPXCommandGeneralDoSync ) )
+ {
+ syncOp = *aCmd.Value<TBool>( KMPXCommandGeneralDoSync );
+ }
+
+ if ( !syncOp )
+ {
+ // async
+ iActiveTask->StartL( commandId, aCmd );
+ }
+ else
+ {
+ // sync, operations to a single media object only
+ TMPXCommandId commandId = *aCmd.Value<TMPXCommandId>(KMPXCommandGeneralId);
+
+ switch ( commandId )
+ {
+ case KMPXCommandIdCollectionAdd:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: sync KMPXCommandIdCollectionAdd arrived");
+
+#ifdef _DEBUG
+ CMPXMedia* video = aCmd.Value<CMPXMedia>( KMPXCommandColAddMedia );
+ TUint32 mdsId( 0 );
+ iMyVideosMdsDb->AddVideoL( *video, mdsId );
+#else
+ User::Leave( KErrNotSupported );
+#endif
+ }
+ break;
+
+ case KMPXCommandIdCollectionSet:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: sync KMPXCommandIdCollectionSet arrived");
+
+ CMPXMedia* video = aCmd.Value<CMPXMedia>( KMPXCommandColSetMedia );
+ SetVideoL( *video );
+ }
+ break;
+
+ case KVcxCommandIdMyVideos:
+ {
+ switch ( aCmd.ValueTObjectL<TUint32>( KVcxMediaMyVideosCommandId ) )
+ {
+ case KVcxCommandMyVideosCancelMoveOrCopy:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: sync KVcxCommandMyVideosCancelMoveOrCopy arrived");
+ iActiveTask->Cancel();
+ }
+ break;
+
+ case KVcxCommandMyVideosCancelDelete:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: sync KVcxCommandMyVideosCancelDelete arrived");
+ iActiveTask->Cancel();
+ }
+ break;
+ }
+ }
+ break;
+
+ default:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: UNKNOWN SYNC COMMAND ARRIVED");
+ User::Leave( KErrNotSupported );
+ }
+ }
+ }
+
+ }
+
+// ----------------------------------------------------------------------------
+// Find the items matching the media specifications
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::FindAllL(
+ const CMPXMedia& /* aCriteria */,
+ const TArray<TMPXAttribute>& /* aAttrs */)
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::FindAllL");
+ }
+
+// ----------------------------------------------------------------------------
+// Find the items matching the media specifications
+// ----------------------------------------------------------------------------
+//
+CMPXMedia* CVcxMyVideosCollectionPlugin::FindAllSyncL(
+ const CMPXMedia& /* aCriteria */,
+ const TArray<TMPXAttribute>& /* aAttrs */)
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::FindAllSyncL");
+ return NULL;
+ }
+
+// ----------------------------------------------------------------------------
+// Get the list of supported capabilities
+// ----------------------------------------------------------------------------
+//
+TCollectionCapability CVcxMyVideosCollectionPlugin::GetCapabilities()
+ {
+ // This one supports simple search
+ return EMcSearch;
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SendMessages
+// ----------------------------------------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SendMessages( CMPXMessage& aMessages )
+ {
+#if _DEBUG
+ TRAP_IGNORE(
+
+ if ( aMessages.IsSupported( KMPXMessageArrayContents ) )
+ {
+ const CMPXMessageArray* messageArray =
+ aMessages.Value<CMPXMessageArray>(KMPXMessageArrayContents);
+
+ for( TInt i = 0; i < messageArray->Count(); i++ )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: sending message ID: %d in array", ++iTotalMessagesSent);
+ messageArray->AtL( i )->SetTObjectValueL<TUint32>( KVcxMediaMyVideosMessageId, iTotalMessagesSent );
+ iMessagesInArraySent++;
+ }
+
+ MPX_DEBUG3("CVcxMyVideosCollectionPlugin:: total messages sent (MSG ID): %d, messages in array sent: %d",
+ iTotalMessagesSent, iMessagesInArraySent);
+ }
+ else
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: NO ARRAY IN MESSAGE!!!");
+ return;
+ }
+
+ );
+#endif
+
+ iObs->HandleMessage( aMessages );
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::HandleMyVideosDbEvent
+// ----------------------------------------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::HandleMyVideosDbEvent(
+ TMPXChangeEventType aEvent,
+ RArray<TUint32>& aId )
+ {
+ //MPX_FUNC("CVcxMyVideosCollectionPlugin::HandleMyVideosDbEvent");
+ TRAPD( err, DoHandleMyVideosDbEventL( aEvent, aId ));
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() leaved with error code: %d", err);
+ }
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL
+// ----------------------------------------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL(
+ TMPXChangeEventType aEvent,
+ RArray<TUint32>& aId )
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL");
+
+ switch ( aEvent )
+ {
+ case EMPXItemDeleted:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() --------------------------------------------.");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() Items from MDS deleted, deleting from cache |" );
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() --------------------------------------------'");
+
+ iCache->RemoveL( aId );
+ }
+ break;
+
+ case EMPXItemInserted:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() ------------------------------------.");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() Items added to MDS, adding to cache |");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() ------------------------------------'");
+
+ if ( iMyVideosMdsDb->iVideoListFetchingIsOngoing )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: video list fetching is ongoing, ignoring add event");
+ return;
+ }
+
+ TBool videoListFetchingWasCancelled = EFalse;
+
+ // After the call, aId will contain only items which were actually inserted to cache.
+ // We receive add events for all object types. When fetching the item from MDS we use
+ // video condition and only video objects are added to cache.
+ iCache->AddVideosFromMdsL( aId, videoListFetchingWasCancelled );
+ if ( videoListFetchingWasCancelled )
+ {
+ RestartVideoListFetchingL();
+ }
+
+ SyncWithDownloadsL( aId );
+ }
+ break;
+
+ case EMPXItemModified:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() --------------------------------------.");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() Items modified in MDS, updating cache |");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin::DoHandleMyVideosDbEventL() --------------------------------------'");
+ CMPXMedia* video;
+ for ( TInt i = 0; i < aId.Count(); i++ )
+ {
+ video = iMyVideosMdsDb->CreateVideoL( aId[i], ETrue /* full details */ );
+
+ if ( video )
+ {
+ CleanupStack::PushL( video ); // 1->
+ iCache->UpdateVideoL( *video );
+ CleanupStack::PopAndDestroy( video ); // <-1
+ }
+ else
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: couldn't find the modified item from MDS");
+ }
+ }
+ }
+ SyncWithDownloadsL( aId );
+ break;
+ }
+
+ TInt pos;
+ for ( TInt i = 0; i < aId.Count(); i++ )
+ {
+ if ( aEvent == EMPXItemInserted )
+ {
+ // add item from cache to the message if we have it.
+ CMPXMedia* video = iCache->FindVideoByMdsIdL( aId[i], pos );
+ TRAP_IGNORE( iMessageList->AddEventL( TMPXItemId( aId[i], 0), aEvent, 0, video ) );
+ }
+ else
+ {
+ TRAP_IGNORE( iMessageList->AddEventL( TMPXItemId( aId[i], 0), aEvent ) );
+ }
+ }
+
+ iMessageList->SendL();
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::HandleStepL
+// ----------------------------------------------------------------------------
+//
+TBool CVcxMyVideosCollectionPlugin::HandleStepL()
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::HandleStepL");
+
+ TBool done(ETrue);
+
+ switch ( iActiveTask->GetTask() )
+ {
+ case KMPXCommandIdCollectionSet:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: async KMPXCommandIdCollectionSet in");
+
+ CMPXMedia* video = CMPXMedia::NewL( *(iActiveTask->GetCommand().Value<CMPXMedia>(
+ KMPXCommandColSetMedia)) );
+
+ CleanupStack::PushL( video );
+
+ SetVideoL( *video );
+
+ CleanupStack::PopAndDestroy( video );
+
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: async KMPXCommandIdCollectionSet out");
+
+ done = ETrue;
+
+ break;
+ }
+ case KVcxCommandIdMyVideos:
+ {
+ CMPXCommand& cmd = iActiveTask->GetCommand();
+ if ( !cmd.IsSupported( KVcxMediaMyVideosCommandId ) )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: KVcxMediaMyVideosCommandId attribute not supported in cmd, aborting");
+ User::Leave( KErrArgument );
+ }
+
+ TInt myVideosCmd( cmd.ValueTObjectL<TUint>( KVcxMediaMyVideosCommandId ) );
+
+ switch ( myVideosCmd )
+ {
+ case KVcxCommandMyVideosStartDownload:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: Handling KVcxCommandMyVideosStartDownload command.");
+
+ CMPXMedia* video = CMPXMedia::NewL( *(iActiveTask->GetCommand().Value<CMPXMedia>(
+ KMPXCommandColAddMedia)) );
+ CleanupStack::PushL( video ); // 1->
+
+ if ( !iCache->iVideoList )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: iVideoListCache = NULL -> creating new empty iVideoListCache");
+ iCache->iVideoListIsPartial = ETrue;
+ iCache->iVideoList = TVcxMyVideosCollectionUtil::CreateEmptyMediaListL();
+ }
+
+ TBool resume = EFalse;
+
+ if ( video->IsSupported( KVcxMediaMyVideosDownloadId ) )
+ {
+ TUint32 downloadId = video->ValueTObjectL<TUint32>( KVcxMediaMyVideosDownloadId );
+ if ( downloadId != 0 )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: download id %d given by the client -> this is download resume",
+ downloadId);
+ resume = ETrue;
+
+ // load the existing item to cache if its not there already
+ }
+ }
+
+ if ( !resume )
+ {
+ if ( !video->IsSupported( KVcxMediaMyVideosRemoteUrl ) )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: KVcxMediaMyVideosRemoteUrl not supported -> leaving with KErrArgument");
+ User::Leave( KErrArgument );
+ }
+
+ if ( video->ValueText( KVcxMediaMyVideosRemoteUrl ).Length() >
+ KVcxMvcMaxUrlLength )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: url longer than 1024 -> leaving with KErrArgument");
+ User::Leave( KErrArgument );
+ }
+
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: starting download for url: %S",
+ &video->ValueText( KVcxMediaMyVideosRemoteUrl ) );
+
+ video->SetTObjectValueL<TUint8>( KVcxMediaMyVideosOrigin, EVcxMyVideosOriginDownloaded );
+ video->SetTObjectValueL<TUint8>( KVcxMediaMyVideosDownloadState,
+ static_cast<TUint8>(EVcxMyVideosDlStateDownloading) );
+ video->SetTObjectValueL<TUint32>( KMPXMediaGeneralFlags, EVcxMyVideosVideoNew );
+
+ HBufC* fileName = DownloadUtilL().CreateFilePathL( *video );
+ CleanupStack::PushL( fileName ); // 2->
+ video->SetTextValueL( KMPXMediaGeneralUri, *fileName );
+ CleanupStack::PopAndDestroy( fileName ); // <-2
+ }
+
+ TRAPD( err, DownloadUtilL().StartDownloadL( *video ) ); //download id is written to video object
+
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: StartDownloadL left: %d", err);
+ User::Leave( err );
+ }
+
+ if ( !resume )
+ {
+ TUint32 newDownloadId = video->ValueTObjectL<TUint32>( KVcxMediaMyVideosDownloadId );
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: new download ID: %d",
+ newDownloadId);
+
+ AddVideoToMdsAndCacheL( *video );
+ }
+ else
+ {
+ // clear old error codes from the dl item
+ TInt pos;
+
+ CMPXMedia* videoInCache = iCache->FindVideoByMdsIdL(
+ TVcxMyVideosCollectionUtil::IdL( *video ), pos );
+ if ( videoInCache )
+ {
+ videoInCache->SetTObjectValueL<TInt>( KVcxMediaMyVideosDownloadError, 0 );
+ videoInCache->SetTObjectValueL<TInt>( KVcxMediaMyVideosDownloadGlobalError, 0 );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( video ); // <-1
+ done = ETrue;
+ }
+ break;
+
+ case KVcxCommandMyVideosCancelDownload:
+ {
+ // Error code is returned to client if dl item was left to system.
+ // If file delete fails, then mds item is also left to system.
+
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: Handling KVcxCommandMyVideosCancelDownload command.");
+
+ CMPXMedia* video = CMPXMedia::NewL( *(iActiveTask->GetCommand().Value<CMPXMedia>(
+ KMPXCommandColAddMedia)) );
+ CleanupStack::PushL( video ); // 1->
+
+ if ( !video->IsSupported( KVcxMediaMyVideosDownloadId ) ||
+ !video->IsSupported( KMPXMediaGeneralId ) ||
+ !video->IsSupported( KMPXMediaGeneralUri ) )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: parameter missing, can't cancel dl, leaving with KErrArgument");
+ User::Leave( KErrArgument );
+ }
+
+ TUint32 downloadId = video->ValueTObjectL<TUint32>(
+ KVcxMediaMyVideosDownloadId );
+ DownloadUtilL().CancelDownload( downloadId, ETrue /* remove file */ );
+
+ if ( BaflUtils::FileExists( iFs, video->ValueText( KMPXMediaGeneralUri ) ) )
+ {
+ TMPXItemId mpxItemId = video->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
+ TInt err( KErrNone );
+
+ for ( TInt i = 0; i < KMaxFileDeleteAttempts; i++ )
+ {
+ TRAP( err, AsyncFileOperationsL().DeleteVideoL( mpxItemId.iId1, ETrue ) );
+
+ if ( err == KErrInUse )
+ {
+ MPX_DEBUG1( "CVcxMyVideosCollectionPlugin:: file is already in use, waiting a moment and try again");
+ User::After( KFileDeleteLoopDelay );
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if ( err != KErrNone && err != KErrNotFound )
+ {
+#ifdef _DEBUG
+ if ( err == KErrInUse )
+ {
+ TVcxMyVideosCollectionUtil::PrintOpenFileHandlesL(
+ video->ValueText( KMPXMediaGeneralUri ), iFs );
+ }
+#endif
+
+ // Some error occured when cancelling download operation, dl item is however gone and file is left
+ // -> change dl id to 0 and leave mpx collection item there. Report operation to client as a success.
+ MPX_DEBUG1( "CVcxMyVideosCollectionPlugin:: dl item is gone from dl manager, file and mpx item are left, setting dl id to 0");
+ TRAP_IGNORE( SetDownloadIdToZeroL( downloadId ) );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( video ); // <-1
+ done = ETrue;
+ }
+ break;
+
+ case KVcxCommandMyVideosPauseDownload:
+ {
+ CMPXMedia& cmd = iActiveTask->GetCommand();
+ if ( !cmd.IsSupported( KVcxMediaMyVideosDownloadId ) )
+ {
+ User::Leave( KErrArgument );
+ }
+ else
+ {
+ TInt err = DownloadUtilL().PauseDownload(
+ cmd.ValueTObjectL<TUint32>( KVcxMediaMyVideosDownloadId ) );
+ User::LeaveIfError( err );
+ }
+ done = ETrue;
+ }
+ break;
+
+ case KVcxCommandMyVideosGetMediaFullDetailsByMpxId:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: KVcxCommandMyVideosGetMediaFullDetailsByMpxId received");
+ CMPXMedia& cmd = iActiveTask->GetCommand();
+ TMPXItemId mpxId( TVcxMyVideosCollectionUtil::IdL( cmd ) );
+ if ( !mpxId.iId1 && !mpxId.iId2 )
+ {
+ User::Leave( KErrArgument );
+ }
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: KVcxCommandMyVideosGetMediaFullDetailsByMpxId cmd: MDS ID %d requested", mpxId.iId1 );
+
+ CMPXMedia* video = iMyVideosMdsDb->CreateVideoL(
+ mpxId.iId1, ETrue /* full details */ );
+
+ if ( !video )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ CleanupStack::PushL( video ); // 1->
+
+ TBool eventsAdded;
+ SyncVideoWithDownloadsL( *video, eventsAdded,
+ EFalse /* dont add event to iMessageList */ );
+
+ cmd.SetCObjectValueL<CMPXMedia>( KMPXCommandColAddMedia, video );
+ CleanupStack::PopAndDestroy( video ); // <-1
+
+ cmd.SetTObjectValueL<TUid>(KMPXMessageCollectionId, TUid::Uid(
+ KVcxUidMyVideosMpxCollection));
+
+ done = ETrue;
+ }
+ break;
+
+ case KVcxCommandMyVideosGetMediasByMpxId:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: KVcxCommandMyVideosGetMediasByMpxId received");
+
+ // Get ids from the request
+ CMPXMedia& cmd = iActiveTask->GetCommand();
+ if ( !cmd.IsSupported( KMPXMediaArrayContents ) )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: error, no array defined");
+ User::Leave( KErrArgument );
+ }
+
+ CMPXMediaArray* idMediaArray = cmd.Value<CMPXMediaArray>(
+ KMPXMediaArrayContents );
+
+ if ( idMediaArray->Count() == 0 )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: error, no items in array ");
+ User::Leave( KErrArgument );
+ }
+
+ TMPXItemId mpxId;
+ RArray<TUint32> mdsIds;
+ RArray<TUint32> mdsIds2;
+ mdsIds.Reset();
+ CleanupClosePushL( mdsIds ); // 1->
+ mdsIds2.Reset();
+ CleanupClosePushL( mdsIds2 ); // 2->
+
+ for ( TInt i = 0; i < idMediaArray->Count(); i++ )
+ {
+ mpxId = (*idMediaArray)[i]->ValueTObjectL<TMPXItemId>(
+ KMPXMessageMediaGeneralId );
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: KVcxCommandMyVideosGetMediasByMpxId cmd: MDS ID %d requested",
+ mpxId.iId1 );
+ mdsIds.AppendL( mpxId.iId1 );
+ mdsIds2.AppendL( mpxId.iId1 );
+ }
+
+ if ( !iCache->iVideoList )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: iVideoListCache = NULL -> creating new empty iCache->iVideoList");
+ iCache->iVideoListIsPartial = ETrue;
+ iCache->iVideoList = TVcxMyVideosCollectionUtil::CreateEmptyMediaListL();
+ }
+
+ TBool videoListFetchingWasCancelled = EFalse;
+
+ if ( iCache->iVideoListIsPartial )
+ {
+ // Load items to cache
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: loading requested items to iCache->iVideoList");
+
+ iCache->AddVideosFromMdsL( mdsIds, videoListFetchingWasCancelled );
+ if ( mdsIds.Count() > 0 )
+ {
+ SyncWithDownloadsL( mdsIds );
+ }
+ }
+ else
+ {
+ // iCache->iVideoList contains all
+ }
+
+ CMPXMessage* message = iCache->GetVideosL( mdsIds2 );
+ CleanupStack::PushL( message ); // 3->
+
+ // Set message attributes
+ //
+ TMPXItemId itemId;
+ itemId.iId1 = KVcxCommandIdMyVideos;
+ message->SetTObjectValueL<TMPXMessageId>( KMPXMessageGeneralId, itemId );
+ message->SetTObjectValueL<TInt>( KVcxMediaMyVideosCommandId,
+ KVcxMessageMyVideosGetMediasByMpxIdResp );
+
+ SetTransactionIdL( cmd, *message );
+
+ iMessageList->AddL( message );
+ iMessageList->SendL();
+
+ if ( videoListFetchingWasCancelled )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: video list fetching was cancelled, restarting");
+ RestartVideoListFetchingL();
+ }
+
+ CleanupStack::Pop( message ); // <-3
+ CleanupStack::PopAndDestroy( &mdsIds2 ); // <-2
+ CleanupStack::PopAndDestroy( &mdsIds ); // <-1
+
+ done = ETrue;
+ }
+ break;
+
+ case KVcxCommandMyVideosCopy:
+ case KVcxCommandMyVideosMove:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: KVcxCommandMyVideosMove or Copy step");
+ done = AsyncFileOperationsL().HandleMoveOrCopyStepL();
+ }
+ break;
+
+ case KVcxCommandMyVideosDelete:
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: KVcxCommandMyVideosDelete step");
+ done = AsyncFileOperationsL().HandleDeleteStepL();
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case KMPXCommandIdCollectionRemoveMedia:
+ {
+ TMPXItemId mpxId = iActiveTask->GetCommand().ValueTObjectL<TMPXItemId>(
+ KMPXMediaGeneralId );
+ AsyncFileOperationsL().DeleteVideoL( mpxId.iId1 );
+ done = ETrue;
+ break;
+ }
+
+ default:
+ {
+ // Should never happen!
+ ASSERT(0);
+ break;
+ }
+ }
+ return done;
+ }
+
+
+// ----------------------------------------------------------------------------
+// Handler for async operations completed
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::HandleOperationCompleted(
+ TInt aErr )
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::HandleOperationCompleted");
+
+ if ( aErr != KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: Leave or cancel happened during the operation: %d", aErr);
+ TRAPD( err, AsyncFileOperationsL().CancelOperationL( aErr ) ); // generates resp message for move,copy or delete operations
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: failed to generate resp msg: %d", err);
+ }
+ }
+
+
+
+ CMPXCommand& cmd = iActiveTask->GetCommand();
+ TRAP_IGNORE( cmd.SetTObjectValueL<TInt32>( KVcxMediaMyVideosInt32Value, aErr ) );
+
+ iObs->HandleCommandComplete( &cmd, KErrNone );
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::HandleDlEvent
+// From CVcxMyVideosDownloadUtilObserver
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::HandleDlEvent( TVcxMyVideosDownloadState aState,
+ TUint32 aDownloadId,
+ TInt aProgress,
+ TInt64 aDownloaded,
+ TInt32 aError,
+ TInt32 aGlobalError )
+ {
+ TRAPD( err, DoHandleDlEventL( aState, aDownloadId, aProgress,
+ aDownloaded, aError, aGlobalError ) );
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: DoHandleDlEventL left with error code: %d", err);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::DoHandleDlEventL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::DoHandleDlEventL( TVcxMyVideosDownloadState aState,
+ TUint32 aDownloadId,
+ TInt aProgress,
+ TInt64 aDownloaded,
+ TInt32 aError,
+ TInt32 aGlobalError )
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::DoHandleDlEventL");
+
+ CMPXMedia* video = iCache->FindVideoByDownloadIdL( aDownloadId );
+
+ MPX_DEBUG3("CVcxMyVideosCollectionPlugin:: dl event for download ID %d, pointer = %x) arrived.", aDownloadId, video);
+
+ TBool sendEvent = EFalse;
+ if ( video )
+ {
+ TMPXItemId mpxId( TVcxMyVideosCollectionUtil::IdL( *video ) );
+ MPX_DEBUG4("CVcxMyVideosCollectionPlugin:: MPX item (MDS ID %d) (DL ID %d) %S",
+ mpxId.iId1, aDownloadId, &TVcxMyVideosCollectionUtil::Title( *video ) );
+
+ TUint8 currentState = TVcxMyVideosCollectionUtil::DownloadStateL( *video );
+
+ if ( currentState == EVcxMyVideosDlStateDownloaded )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: already in Downloaded state, discarding event");
+ return;
+ }
+
+ if ( currentState != aState )
+ {
+ MPX_DEBUG5("CVcxMyVideosCollectionPlugin:: updating (mds id: %d) (dl id: %d) state: %S -> %S",
+ mpxId.iId1, aDownloadId, &DownloadState( currentState ), &DownloadState( aState ) );
+ video->SetTObjectValueL<TUint8>( KVcxMediaMyVideosDownloadState, static_cast<TUint8>(aState) );
+ sendEvent = ETrue;
+
+ if ( aState == EVcxMyVideosDlStateDownloaded )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: downloaded state received -> setting download id to 0");
+
+ //1. set download id to 0
+ video->SetTObjectValueL<TUint32>( KVcxMediaMyVideosDownloadId, 0 );
+
+ //2. update drm flag
+#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ RFile64 dlFile;
+#else
+ RFile dlFile;
+#endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ TInt err = dlFile.Open( iFs, video->ValueText( KMPXMediaGeneralUri ), EFileRead );
+ if ( err == KErrNone )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: file opened ok for drm reading");
+ CleanupClosePushL( dlFile ); // 1->
+ DRM::CDrmUtility* drmUtil = DRM::CDrmUtility::NewLC(); // 2->
+ if ( drmUtil->IsProtectedL( dlFile ) )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: file is DRM protected, setting the property flag");
+ TUint32 flags = video->ValueTObjectL<TUint32>( KMPXMediaGeneralFlags );
+ flags |= EVcxMyVideosVideoDrmProtected;
+ video->SetTObjectValueL<TUint32>( KMPXMediaGeneralFlags, flags );
+ }
+ else
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: file is not DRM protected");
+ }
+ CleanupStack::PopAndDestroy( drmUtil ); // <-2
+ CleanupStack::PopAndDestroy( &dlFile ); // <-1
+ }
+ else
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: file didnt open for drm reading, %d", err);
+ }
+ NotifyDownloadCompletedL( *video );
+
+ //3. Update file size using iCache->UpdateVideoL function since it changes item position and
+ // sends category modified events if necessarry.
+ CMPXMedia* updateObject = CMPXMedia::NewL();
+ CleanupStack::PushL( updateObject ); // 1->
+ updateObject->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, mpxId );
+#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ updateObject->SetTObjectValueL<TInt64>( KMPXMediaGeneralExtSizeInt64,
+ static_cast<TInt64>( aDownloaded ) );
+ // set current value to 0 to force event sending and video list position updating
+ video->SetTObjectValueL<TInt64>( KMPXMediaGeneralExtSizeInt64, 0 );
+#else
+ updateObject->SetTObjectValueL<TInt>( KMPXMediaGeneralSize,
+ static_cast<TInt>( aDownloaded ) );
+ // set current value to 0 to force event sending and video list position updating
+ video->SetTObjectValueL<TInt>( KMPXMediaGeneralSize, 0 );
+#endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ iCache->UpdateVideoL( *updateObject );
+ CleanupStack::PopAndDestroy( updateObject ); // <-1
+ // find video again since it might have been deleted in iCache->UpdateVideoL
+ TInt pos;
+ video = iCache->FindVideoByMdsIdL( mpxId.iId1, pos );
+
+ //file size and download id are saved to database
+ iMyVideosMdsDb->UpdateVideoL( *video );
+ sendEvent = EFalse; // MDS will send the event, this avoids duplicate
+ }
+
+ if ( aState == EVcxMyVideosDlStateFailed )
+ {
+ video->SetTObjectValueL<TInt32>( KVcxMediaMyVideosDownloadError, aError );
+ video->SetTObjectValueL<TInt32>( KVcxMediaMyVideosDownloadGlobalError,
+ aGlobalError );
+ }
+ }
+ else
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: state was already same(%S), skipping state update.", &DownloadState( currentState ));
+ }
+
+ TInt8 currentProgress = video->ValueTObjectL<TInt8>( KVcxMediaMyVideosDownloadProgress );
+ if ( currentProgress != aProgress )
+ {
+ MPX_DEBUG4("CVcxMyVideosCollectionPlugin:: (dl id: %d) progress: %d -> %d",
+ aDownloadId, currentProgress, aProgress );
+
+ video->SetTObjectValueL<TInt8>( KVcxMediaMyVideosDownloadProgress,
+ static_cast<TInt8>( aProgress ) );
+ // Don't send the update event for progress.
+ //sendEvent = ETrue;
+ }
+ else
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: progress was already same(%d), skipping progress update.", currentProgress);
+ }
+
+ TInt64 currentFileSize = 0;
+#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ if ( video->IsSupported( KMPXMediaGeneralExtSizeInt64 ) )
+ {
+ currentFileSize = video->ValueTObjectL<TInt64>( KMPXMediaGeneralExtSizeInt64 );
+ }
+#else
+ if ( video->IsSupported( KMPXMediaGeneralSize ) )
+ {
+ currentFileSize = video->ValueTObjectL<TInt>( KMPXMediaGeneralSize );
+ }
+#endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ if ( currentFileSize != aDownloaded )
+ {
+ MPX_DEBUG4("CVcxMyVideosCollectionPlugin:: updating (dl id: %d) size: %ld -> %ld",
+ aDownloadId, currentFileSize, aDownloaded );
+
+#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ video->SetTObjectValueL<TInt64>( KMPXMediaGeneralExtSizeInt64, aDownloaded );
+#else
+ TInt newFileSize( aDownloaded );
+ video->SetTObjectValueL<TInt>( KMPXMediaGeneralSize, newFileSize );
+#endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ //sendEvent = ETrue;
+ }
+
+ if ( sendEvent )
+ {
+ iMessageList->AddEventL( mpxId, EMPXItemModified );
+ iMessageList->SendL();
+ }
+ }
+ else
+ {
+ if ( (aState != EVcxMyVideosDlStateDownloaded) && (aProgress < 100) &&
+ !iCache->iVideoListIsPartial )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: -----------------------------------------------------------------------.");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: Event for progressing download arrived, but the MPX/MDS item not found!|");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: -> deleting download. |");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: -----------------------------------------------------------------------'");
+
+ RHttpDownload* download = DownloadUtilL().Download( aDownloadId );
+ if ( download )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: Download ID (%d) not found from MPX/MDS, deleting download!",
+ aDownloadId );
+ DownloadUtilL().DeleteDownloadAsync( aDownloadId, ETrue );
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SyncWithDownloadsL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SyncWithDownloadsL(
+ RArray<TUint32>& aItemsInCache )
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::SyncWithDownloadsL()");
+
+ TBool eventsAdded = EFalse;
+ for ( TInt i = 0; i < aItemsInCache.Count(); i++ )
+ {
+ TInt pos;
+ CMPXMedia* video = iCache->FindVideoByMdsIdL( aItemsInCache[i], pos );
+ if ( video )
+ {
+ SyncVideoWithDownloadsL( *video, eventsAdded );
+ }
+ }
+ if ( eventsAdded )
+ {
+ iMessageList->SendL();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SyncVideoWithDownloadsL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SyncVideoWithDownloadsL( CMPXMedia& aVideo,
+ TBool& aEventAdded, TBool aAddEvent )
+ {
+ TInt downloadId( TVcxMyVideosCollectionUtil::DownloadIdL( aVideo ) );
+
+ if ( downloadId )
+ {
+ RHttpDownload* download( DownloadUtilL().Download( downloadId ) );
+
+ if ( download )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin::SyncVideoWithDownloadsL() item (DL ID: %d) found from dl manager", downloadId);
+
+ TBool modified = EFalse;
+ SyncVideoAndDownloadL( aVideo, *download, modified );
+ if ( modified && aAddEvent )
+ {
+ iMessageList->AddEventL( TVcxMyVideosCollectionUtil::IdL( aVideo ),
+ EMPXItemModified );
+ aEventAdded = ETrue;
+ }
+ }
+ else
+ {
+ //download id != 0 and it is not found from download manager -> we set download id to 0
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: download id %d != 0 and no corresponding download found from Download Manager",
+ downloadId);
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: -> setting download id to 0");
+ aVideo.SetTObjectValueL<TUint32>( KVcxMediaMyVideosDownloadId, 0 );
+ iMyVideosMdsDb->UpdateVideoL( aVideo ); // if video list fetching is ongoing, this will leave with KErrNotReady
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SyncVideoAndDownloadL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SyncVideoAndDownloadL(
+ CMPXMedia& aVideo,
+ RHttpDownload& aDownload,
+ TBool& aModified )
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::SyncVideoAndDownloadL()");
+
+ aModified = EFalse;
+
+ TBuf<KMaxUrlLength> downloadUrl;
+ aDownload.GetStringAttribute( EDlAttrReqUrl, downloadUrl );
+ if ( aVideo.ValueText( KVcxMediaMyVideosRemoteUrl )
+ != downloadUrl )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: urls in MPX and DL Manager differ!");
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: remote url in MPX: %S",
+ &(aVideo.ValueText( KVcxMediaMyVideosRemoteUrl )));
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: remote url in DL Manager: %S",
+ &downloadUrl);
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: -> updating MPX cache");
+
+ aVideo.SetTextValueL( KVcxMediaMyVideosRemoteUrl, downloadUrl );
+ aModified = ETrue;
+ }
+ else
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: remote urls already same in dl manager and mpx");
+ }
+
+ // KVcxMediaMyVideosDownloadState
+ TVcxMyVideosDownloadState dlStateInDlManager;
+ DownloadUtilL().GetDownloadState( aDownload, dlStateInDlManager );
+
+ TUint8 dlStateInMpxCache;
+ if ( aVideo.IsSupported( KVcxMediaMyVideosDownloadState ))
+ {
+ dlStateInMpxCache = aVideo.ValueTObjectL<TUint8>( KVcxMediaMyVideosDownloadState );
+ }
+ else
+ {
+ dlStateInMpxCache = static_cast<TUint8>( EVcxMyVideosDlStateNone );
+ }
+
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: dl state in dl manager: %S", &DownloadState( dlStateInDlManager ));
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: dl state in mpx cache: %S", &DownloadState( dlStateInMpxCache ));
+
+ if ( static_cast<TUint8>( dlStateInDlManager ) != dlStateInMpxCache )
+ {
+ if ( dlStateInDlManager == EVcxMyVideosDlStateDownloaded )
+ {
+ // Download finished event has arrived when we weren't around, call event handler to get things right.
+ // Collection is updated and download is deleted from Download Manager.
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: Download is in Finished state and collection has download id != 0");
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: -> we have missed download finished event, lets generate it by ourselves.");
+
+ TUint64 downloaded( 0 );
+ TUint8 progress( DownloadUtilL().DownloadProgress( aDownload, downloaded, EFalse ) );
+ TUint32 downloadId( aVideo.ValueTObjectL<TUint32>( KVcxMediaMyVideosDownloadId ) );
+ HandleDlEvent( dlStateInDlManager, downloadId,
+ progress, downloaded, KErrNone, KErrNone );
+ DownloadUtilL().DeleteDownloadAsync( downloadId, EFalse /* don't delete content */ );
+ }
+ else
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: dl state in dl manager differs of mpx cache-> updating mpx cache");
+ aVideo.SetTObjectValueL<TUint8>( KVcxMediaMyVideosDownloadState,
+ static_cast<TUint8>( dlStateInDlManager ) );
+ aModified = ETrue;
+ }
+ }
+ else
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: download state already same in dl manager and mds");
+ }
+
+ // KVcxMediaMyVideosDownloadProgress
+ TUint64 downloaded = 0;
+ TInt8 dlProgressInDlManager = DownloadUtilL().DownloadProgress(
+ aDownload, downloaded, EFalse );
+
+ TInt8 dlProgressInMpxCache;
+ if ( aVideo.IsSupported( KVcxMediaMyVideosDownloadProgress ) )
+ {
+ dlProgressInMpxCache = aVideo.ValueTObjectL<TInt8>( KVcxMediaMyVideosDownloadProgress );
+ }
+ else
+ {
+ aVideo.SetTObjectValueL<TInt8>( KVcxMediaMyVideosDownloadProgress, 0 );
+ dlProgressInMpxCache = 0;
+ }
+
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: dl progress in dl manager: %d", dlProgressInDlManager);
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: dl progress in mpx cache: %d", dlProgressInMpxCache);
+
+ if ( dlProgressInDlManager != dlProgressInMpxCache )
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: dl progress in dl manager differs of mpx cache-> updating mpx cache");
+ aVideo.SetTObjectValueL<TInt8>( KVcxMediaMyVideosDownloadProgress,
+ static_cast<TInt8>( dlProgressInDlManager ) );
+ aModified = ETrue;
+ }
+ else
+ {
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: download progress already same in dl manager and mds");
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SyncVideoListWithDownloadsL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SyncVideoListWithDownloadsL( CMPXMedia& aVideoList,
+ TBool aSendEvents, TInt aStartPos )
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::SyncVideoListWithDownloadsL");
+
+ CMPXMediaArray* videoArray = aVideoList.Value<CMPXMediaArray>(
+ KMPXMediaArrayContents);
+
+ CMPXMedia* video;
+
+ TBool eventsAdded = EFalse;
+ for ( TInt i = aStartPos; i < videoArray->Count(); i++ )
+ {
+ video = (*videoArray)[i];
+ SyncVideoWithDownloadsL( *video, eventsAdded, aSendEvents );
+ }
+ if ( eventsAdded )
+ {
+ iMessageList->SendL();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::DownloadUtil
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosDownloadUtil& CVcxMyVideosCollectionPlugin::DownloadUtilL()
+ {
+ if ( !iDownloadUtil )
+ {
+ iDownloadUtil = CVcxMyVideosDownloadUtil::NewL( *this, iFs );
+ }
+
+ if ( !iOrphanDownloadsCleared )
+ {
+ if ( !iCache->iVideoListIsPartial )
+ {
+ iOrphanDownloadsCleared = ETrue;
+ iDownloadUtil->ClearOrphanDownloadsL( *iCache->iVideoList );
+ }
+ }
+
+ return *iDownloadUtil;
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::CategoriesL
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosCategories& CVcxMyVideosCollectionPlugin::CategoriesL()
+ {
+ if ( !iCategories )
+ {
+ iCategories = CVcxMyVideosCategories::NewL( *this );
+ }
+ return *iCategories;
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::HandleCreateVideoListResp
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::HandleCreateVideoListResp(
+ CMPXMedia* aVideoList, TInt aNewItemsStartIndex, TBool aComplete )
+ {
+ TRAPD( err, iOpenHandler->DoHandleCreateVideoListRespL( aVideoList, aNewItemsStartIndex, aComplete ));
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: DoHandleCreateVideoListRespL() left with error code: %d", err );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::RestartVideoListFetchingL
+// Called when video list fetching is interrupted due to "get item by mpx id"
+// request, or sorting order change. Or by some other reason that requires
+// new video list fetching. iCache->iVideoList media array has been reset, Ie lists are the
+// the same but items have been deleted.
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::RestartVideoListFetchingL()
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::RestartVideoListFetchingL()");
+
+ // Client already had something on the list.
+ // -> tell client to fetch everything from scratch again.
+ MPX_DEBUG1("CVcxMyVideosCollectionPlugin:: open was not pending, client had something on the list");
+ MPX_DEBUG1(" -> telling client to fetch everything from the scratch again");
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: adding modify event for path root, extra info = %d",
+ EVcxMyVideosVideoListOrderChanged );
+
+ iCache->ResetVideoListL();
+
+ iMessageList->AddEventL( TMPXItemId( KVcxUidMyVideosMpxCollection,
+ KVcxUidMyVideosMpxCollection ), EMPXItemModified,
+ EVcxMyVideosVideoListOrderChanged );
+ iMessageList->SendL();
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SetVideoL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SetVideoL( CMPXMedia& aVideo )
+ {
+ TRAPD( leave, iCache->UpdateVideoL( aVideo ) );
+
+ if ( leave == KErrNone )
+ {
+ TMPXItemId mpxId( TVcxMyVideosCollectionUtil::IdL( aVideo ) );
+
+ TInt pos;
+ CMPXMedia* videoInCache = iCache->FindVideoByMdsIdL( mpxId, pos );
+
+ if ( videoInCache )
+ {
+ iMyVideosMdsDb->UpdateVideoL( *videoInCache );
+ }
+ }
+ else if ( leave == KErrNotFound )
+ {
+ iMyVideosMdsDb->UpdateVideoL( aVideo );
+ }
+ else
+ {
+ User::Leave( leave );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::NotifyDownloadCompletedL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::NotifyDownloadCompletedL( CMPXMedia& aVideo )
+ {
+ const TInt KMediaExtSize( 8 );
+
+ HBufC8* buffer = HBufC8::NewL( KMediaExtSize );
+ CleanupStack::PushL( buffer );
+ TPtr8 des = buffer->Des();
+
+ RDesWriteStream stream;
+ CleanupClosePushL( stream );
+ stream.Open( des );
+
+ aVideo.ExternalizeL( stream );
+
+ stream.CommitL();
+
+ CleanupStack::PopAndDestroy( &stream );
+
+ DownloadUtilL().NotifyDownloadCompleted( *buffer );
+
+ CleanupStack::PopAndDestroy( buffer );
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::NotifyNewVideosCountDecreasedL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::NotifyNewVideosCountDecreasedL( CMPXMedia& aVideo )
+ {
+ const TInt KMediaExtSize( 8 );
+
+ HBufC8* buffer = HBufC8::NewL( KMediaExtSize );
+ CleanupStack::PushL( buffer );
+ TPtr8 des = buffer->Des();
+
+ RDesWriteStream stream;
+ CleanupClosePushL( stream );
+ stream.Open( des );
+
+ aVideo.ExternalizeL( stream );
+
+ stream.CommitL();
+
+ CleanupStack::PopAndDestroy( &stream );
+
+ DownloadUtilL().NotifyNewVideosCountDecreased( *buffer );
+
+ CleanupStack::PopAndDestroy( buffer );
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::AddVideoToMdsAndCacheL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::AddVideoToMdsAndCacheL( CMPXMedia& aVideo )
+ {
+ MPX_FUNC("CVcxMyVideosCollectionPlugin::AddVideoToMdsAndCacheL");
+
+ TMPXItemId mpxId;
+ iMyVideosMdsDb->AddVideoL( aVideo, mpxId.iId1 );
+
+ aVideo.SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, mpxId );
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: new MDS ID: %d", mpxId.iId1 );
+
+ RArray<TUint32> ids;
+ ids.Reset();
+ CleanupClosePushL( ids ); // 1->
+ ids.AppendL( mpxId.iId1 );
+ HandleMyVideosDbEvent( EMPXItemInserted, ids ); //this will fetch from mds to cache and sync with downloads
+ CleanupStack::PopAndDestroy( &ids ); // <-1
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SetTransactionIdL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SetTransactionIdL( CMPXMedia& aRequest, CMPXMedia& aResp )
+ {
+ if ( aRequest.IsSupported( KVcxMediaMyVideosTransactionId ) )
+ {
+ TUint32 transactionId( aRequest.ValueTObjectL<TUint32>( KVcxMediaMyVideosTransactionId ));
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: transaction ID: %d", transactionId );
+ aResp.SetTObjectValueL<TUint32>( KVcxMediaMyVideosTransactionId, transactionId );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SendMyVideosMessageL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SendMyVideosMessageL(
+ TUint32 aMessageId, CMPXCommand* aCommand )
+ {
+ CMPXMessage* message = CMPXMessage::NewL();
+ CleanupStack::PushL( message ); // 1->
+ TMPXItemId itemId;
+ itemId.iId1 = KVcxCommandIdMyVideos;
+ message->SetTObjectValueL<TMPXMessageId>( KMPXMessageGeneralId, itemId );
+ message->SetTObjectValueL<TInt>( KVcxMediaMyVideosCommandId,
+ aMessageId );
+
+ if ( aCommand )
+ {
+ SetTransactionIdL( *aCommand, *message );
+ }
+ else
+ {
+ message->SetTObjectValueL<TUint32>( KVcxMediaMyVideosTransactionId, 0 );
+ }
+
+ iMessageList->AddL( message );
+ CleanupStack::Pop( message ); // <-1
+ iMessageList->SendL();
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::AsyncFileOperationsL
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosAsyncFileOperations& CVcxMyVideosCollectionPlugin::AsyncFileOperationsL()
+ {
+ if ( !iAsyncFileOperations )
+ {
+ iAsyncFileOperations = CVcxMyVideosAsyncFileOperations::NewL( *this );
+ }
+ return *iAsyncFileOperations;
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::HandleObjectPresentNotification
+// From MVcxMyVideosMdsDbObserver. Called when media is inserted/removed.
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::HandleObjectPresentNotification()
+ {
+ TRAPD( err, DoHandleObjectPresentNotificationL() );
+
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin::DoHandleObjectPresentNotificationL() left with code %d", err);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::DoHandleObjectPresentNotificationL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::DoHandleObjectPresentNotificationL()
+ {
+ iCache->ResetVideoListL();
+
+ MPX_DEBUG2("CVcxMyVideosCollectionPlugin:: adding modify event for path root, extra info = %d",
+ EVcxMyVideosVideoListOrderChanged );
+ iMessageList->AddEventL( TMPXItemId( KVcxUidMyVideosMpxCollection,
+ KVcxUidMyVideosMpxCollection ), EMPXItemModified, EVcxMyVideosVideoListOrderChanged );
+
+ MPX_DEBUG3("CVcxMyVideosCollectionPlugin:: adding modify event for category[%d], extra info = %d",
+ KVcxMvcCategoryIdAll, EVcxMyVideosVideoListOrderChanged );
+ iMessageList->AddEventL( TMPXItemId( KVcxMvcCategoryIdAll, 1 ), EMPXItemModified,
+ EVcxMyVideosVideoListOrderChanged );
+
+ MPX_DEBUG3("CVcxMyVideosCollectionPlugin:: adding modify event for category[%d], extra info = %d",
+ KVcxMvcCategoryIdDownloads, EVcxMyVideosVideoListOrderChanged );
+ iMessageList->AddEventL( TMPXItemId( KVcxMvcCategoryIdDownloads, 1 ), EMPXItemModified,
+ EVcxMyVideosVideoListOrderChanged );
+
+ MPX_DEBUG3("CVcxMyVideosCollectionPlugin:: adding modify event for category[%d], extra info = %d",
+ KVcxMvcCategoryIdTvRecordings, EVcxMyVideosVideoListOrderChanged );
+ iMessageList->AddEventL( TMPXItemId( KVcxMvcCategoryIdTvRecordings, 1 ), EMPXItemModified,
+ EVcxMyVideosVideoListOrderChanged );
+
+ MPX_DEBUG3("CVcxMyVideosCollectionPlugin:: adding modify event for category[%d], extra info = %d",
+ KVcxMvcCategoryIdCaptured, EVcxMyVideosVideoListOrderChanged );
+ iMessageList->AddEventL( TMPXItemId( KVcxMvcCategoryIdCaptured, 1 ), EMPXItemModified,
+ EVcxMyVideosVideoListOrderChanged );
+
+ MPX_DEBUG3("CVcxMyVideosCollectionPlugin:: adding modify event for category[%d], extra info = %d",
+ KVcxMvcCategoryIdOther, EVcxMyVideosVideoListOrderChanged );
+ iMessageList->AddEventL( TMPXItemId( KVcxMvcCategoryIdOther, 1 ), EMPXItemModified,
+ EVcxMyVideosVideoListOrderChanged );
+
+ iMessageList->SendL();
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::SetDownloadIdToZeroL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosCollectionPlugin::SetDownloadIdToZeroL( TUint aDownloadId )
+ {
+ CMPXMedia* video = iCache->FindVideoByDownloadIdL( aDownloadId );
+ if ( video )
+ {
+ video->SetTObjectValueL<TUint32>( KVcxMediaMyVideosDownloadId, 0 );
+ video->SetTObjectValueL<TUint8>( KVcxMediaMyVideosDownloadState,
+ static_cast<TUint8>( EVcxMyVideosDlStateNone ) );
+ iMyVideosMdsDb->UpdateVideoL( *video );
+ iMessageList->AddEventL( TVcxMyVideosCollectionUtil::IdL(
+ *video ), EMPXItemModified );
+ iMessageList->SendL();
+ }
+ }
+
+#ifdef _DEBUG
+// ----------------------------------------------------------------------------
+// CVcxMyVideosCollectionPlugin::DownloadState
+// ----------------------------------------------------------------------------
+//
+const TDesC& CVcxMyVideosCollectionPlugin::DownloadState( TUint8 aDlState )
+ {
+ _LIT(KDlStateNoneDes, "None");
+ _LIT(KDlStateDownloadingDes, "Downloading");
+ _LIT(KDlStateFailedDes, "Failed");
+ _LIT(KDlStatePausedDes, "Paused");
+ _LIT(KDlStateDownloadedDes, "Downloaded");
+
+ switch ( aDlState )
+ {
+ case EVcxMyVideosDlStateNone:
+ return KDlStateNoneDes;
+ case EVcxMyVideosDlStateDownloading:
+ return KDlStateDownloadingDes;
+ case EVcxMyVideosDlStateFailed:
+ return KDlStateFailedDes;
+ case EVcxMyVideosDlStatePaused:
+ return KDlStatePausedDes;
+ case EVcxMyVideosDlStateDownloaded:
+ return KDlStateDownloadedDes;
+ default:
+ return KNullDesC;
+ }
+ }
+#endif
+