--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mpxplugins/serviceplugins/collectionplugins/mpxinmemoryplugin/src/mpxinmemoryplugin.cpp Thu Dec 17 08:45:05 2009 +0200
@@ -0,0 +1,632 @@
+/*
+* 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: Simple plugin to cache media objects
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32cmn.h>
+#include <mpxcollectionpath.h>
+#include <mpxcollectionpluginobserver.h>
+#include <mpxcmn.h>
+#include <mpxmediageneraldefs.h>
+#include <mpxmediacontainerdefs.h>
+#include <mpxmediamusicdefs.h>
+#include <mpxmediaaudiodefs.h>
+#include <mpxmessagegeneraldefs.h>
+#include <mpxcollectionmessagedefs.h>
+#include <mpxmediacollectiondetaildefs.h>
+#include <mpxcollectioncommanddefs.h>
+#include <mpxcommandgeneraldefs.h>
+#include <mpxmedia.h>
+#include <mpxmediaarray.h>
+#include <mpxdrmmediautility.h>
+#include <mpxmediadrmdefs.h>
+#include <mpxlog.h>
+
+#include "mpxinmemoryplugin.h"
+
+// CONSTANTS
+const TInt KIMPluginUid = 0x101FFCD8;
+
+// ============================ MEMBER FUNCTIONS ==============================
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXInMemoryPlugin* CMPXInMemoryPlugin::NewL()
+ {
+ CMPXInMemoryPlugin* p = new (ELeave) CMPXInMemoryPlugin();
+ CleanupStack::PushL(p);
+ p->ConstructL();
+ CleanupStack::Pop(p);
+ return p;
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CMPXInMemoryPlugin::~CMPXInMemoryPlugin()
+ {
+ delete iDrmMediaUtility;
+
+ // Cleanup Arrays
+ iTemporaryData.ResetAndDestroy();
+ iTemporaryData.Close();
+ iEmbeddedContext.Reset();
+ iEmbeddedContext.Close();
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor
+// ----------------------------------------------------------------------------
+//
+CMPXInMemoryPlugin::CMPXInMemoryPlugin()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::ConstructL()
+ {
+ iDrmMediaUtility = CMPXDrmMediaUtility::NewL();
+ }
+
+// ----------------------------------------------------------------------------
+// Navigates to the given path
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::OpenL(
+ const CMPXCollectionPath& aPath,
+ const TArray<TMPXAttribute>& /*aAttrs*/,
+ CMPXFilter* /*aFilter*/)
+ {
+ // Media object to return
+ RArray<TInt> supportedIds;
+ CleanupClosePushL(supportedIds);
+ supportedIds.AppendL(KMPXMediaIdContainer);
+ supportedIds.AppendL(KMPXMediaIdGeneral);
+ CMPXMedia* entries=CMPXMedia::NewL(supportedIds.Array());
+ CleanupStack::PushL(entries);
+
+ // Media array for items
+ CMPXMediaArray* array=CMPXMediaArray::NewL();
+ CleanupStack::PushL(array);
+
+ // Based on Path, what is the embedded client context id?
+ TInt depth = aPath.Levels();
+ TBool oneSong = EFalse;
+ TInt err = KErrNone;
+ switch( depth )
+ {
+ case 1: // should not have anything
+ {
+ User::Leave( KErrArgument );
+ break;
+ }
+ case 2: // an item or a playlist
+ {
+ TInt context = aPath.Id(1);
+ TInt contextIndex = iEmbeddedContext.Find( context );
+ if( contextIndex >= KErrNone )
+ {
+ CMPXMedia& media = *iTemporaryData[contextIndex];
+
+ TMPXGeneralCategory cat = *media.Value<TMPXGeneralCategory>( KMPXMediaGeneralCategory );
+ if( cat == EMPXPlaylist )
+ {
+ const CMPXMediaArray* plarray = media.Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ for( TInt i=0; i<plarray->Count(); ++i )
+ {
+ CMPXMedia* item = (*plarray)[i];
+ CMPXMedia* copy = CMPXMedia::NewL(*item);
+
+ // item id is the index in the array
+ copy->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, i );
+ array->AppendL( copy ); // ownership x-fer
+ }
+
+
+ // Insert dummy media objects if the "specified" count is > actual
+ // number of media objects
+ TInt count(0);
+ if( media.IsSupported(KMPXMediaArrayCount) )
+ {
+ count = *media.Value<TInt>(KMPXMediaArrayCount);
+ }
+ if( count > 0 && count > plarray->Count() )
+ {
+ for( TInt i=plarray->Count(); i<count; ++i )
+ {
+ // Insert dummies
+ CMPXMedia* copy = CMPXMedia::NewL();
+ copy->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, i );
+ copy->SetTObjectValueL( KMPXMediaGeneralType,
+ EMPXItem );
+ copy->SetTObjectValueL( KMPXMediaGeneralCategory,
+ EMPXSong );
+ array->AppendL( copy ); // ownership x-fer
+ }
+ }
+
+ // Set the title for the playlist
+ //
+ if( media.IsSupported( KMPXMediaGeneralTitle ) )
+ {
+ const TDesC& title = media.ValueText( KMPXMediaGeneralTitle );
+ entries->SetTextValueL( KMPXMediaGeneralTitle,
+ title );
+ }
+ }
+ else // assume it is an item then
+ {
+ // Set one song to true
+ oneSong = ETrue;
+ }
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+ break;
+ }
+ case 3: // item in a playlist
+ {
+ oneSong = ETrue;
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Set array if not one song
+ if( !oneSong )
+ {
+ entries->SetCObjectValueL(KMPXMediaArrayContents,array);
+ entries->SetTObjectValueL(KMPXMediaArrayCount,
+ array->Count());
+ entries->SetTObjectValueL( KMPXMediaGeneralType,
+ EMPXGroup );
+ entries->SetTObjectValueL( KMPXMediaGeneralCategory,
+ EMPXPlaylist );
+ }
+ else
+ {
+ entries->SetTObjectValueL( KMPXMediaGeneralType,
+ EMPXItem );
+ entries->SetTObjectValueL( KMPXMediaGeneralCategory,
+ EMPXSong );
+ }
+
+ if(oneSong)
+ {
+ iObs->HandleOpen(const_cast<CMPXCollectionPath*>(&aPath), err );
+ }
+ else
+ {
+ entries->SetCObjectValueL( KMPXMediaGeneralContainerPath,
+ const_cast<CMPXCollectionPath*>(&aPath) );
+ iObs->HandleOpen(entries, err );
+ }
+ CleanupStack::PopAndDestroy(array);
+ CleanupStack::PopAndDestroy(entries);
+ CleanupStack::PopAndDestroy(&supportedIds);
+ }
+
+// ----------------------------------------------------------------------------
+// Extended properties of the current file (async)
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::MediaL (
+ const CMPXCollectionPath& aPath,
+ const TArray<TMPXAttribute>& aAttrs,
+ const TArray<TCapability>& /*aCaps*/,
+ CMPXAttributeSpecs* /*aSpecs*/)
+ {
+ RArray<TInt> supportedIds;
+ CleanupClosePushL(supportedIds);
+ supportedIds.AppendL(KMPXMediaIdGeneral);
+ CMPXMedia* entries=CMPXMedia::NewL(supportedIds.Array());
+ CleanupStack::PopAndDestroy(&supportedIds);
+ CleanupStack::PushL(entries);
+
+ // Based on Path, what is the embedded client context id?
+ //
+ TInt err = KErrNone;
+ TInt depth = aPath.Levels();
+ switch( depth )
+ {
+ case 2: // Playlist / Song level
+ case 3: // Song in a playlist level, fall through
+ {
+ TInt context = aPath.Id(1);
+ TInt contextIndex = iEmbeddedContext.Find( context );
+ if( contextIndex >= KErrNone )
+ {
+ CMPXMedia& media = *iTemporaryData[contextIndex];
+
+ TMPXGeneralCategory cat;
+ cat = *media.Value<TMPXGeneralCategory>( KMPXMediaGeneralCategory );
+
+ // Playlist media
+ //
+ if( cat == EMPXPlaylist && depth == 2)
+ {
+ // Get
+ const TDesC& title = media.ValueText( KMPXMediaGeneralTitle );
+ const TDesC& uri = media.ValueText( KMPXMediaGeneralUri );
+ // Set
+ entries->SetTextValueL( KMPXMediaGeneralTitle,
+ title );
+ entries->SetTextValueL( KMPXMediaGeneralUri,
+ uri );
+ entries->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId,
+ TUid::Uid(KIMPluginUid) );
+ }
+ // Item in a playlist media
+ //
+ else if( cat == EMPXPlaylist && depth == 3 )
+ {
+ const CMPXMediaArray* plarray = media.Value<CMPXMediaArray>(
+ KMPXMediaArrayContents );
+ TInt selection = aPath.Id( 2 );
+ TInt count = plarray->Count();
+ if( selection < count )
+ {
+ *entries = *(*plarray)[selection];
+
+ entries->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId,
+ TUid::Uid(KIMPluginUid) );
+ }
+ else
+ {
+ // Bounds check
+ err = KErrArgument;
+ }
+ }
+ // Otherwise, assume it is a song
+ //
+ else // cat == song/image/video/etc
+ {
+ *entries = media;
+
+ entries->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId,
+ TUid::Uid(KIMPluginUid) );
+ }
+ }
+ break;
+ }
+ default:
+ {
+ // Return Nothing because a MediaL at this depth contains nothing
+ break;
+ }
+ }
+ //
+ for (TInt i=aAttrs.Count();--i>=0;)
+ {
+ if (aAttrs[i]==KMPXMediaGeneralPath)
+ {
+ entries->SetCObjectValueL(KMPXMediaGeneralPath,
+ const_cast<CMPXCollectionPath*>(&aPath));
+ break;
+ }
+ }
+
+ // Full metadata is not available from this plugin
+ entries->SetTObjectValueL( KMPXMediaColDetailMediaNotAvailable,
+ ETrue );
+ //
+ iObs->HandleMedia(entries, err );
+ CleanupStack::PopAndDestroy(entries);
+ }
+
+// ----------------------------------------------------------------------------
+// Cancel outstanding request
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::CancelRequest()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// Executes a command on the selected collection
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::CommandL(TMPXCollectionCommand /*aCmd*/, TInt /*aArg*/)
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// Executes a command on the selected collection
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::CommandL(CMPXCommand& aCmd)
+ {
+ if (!aCmd.IsSupported(TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId)))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TMPXCommandId commandId =
+ *aCmd.Value<TMPXCommandId>(
+ TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId));
+
+ TBool syncOp(EFalse);
+ if( aCmd.IsSupported(KMPXCommandGeneralDoSync) )
+ {
+ syncOp = *aCmd.Value<TBool>(KMPXCommandGeneralDoSync);
+ }
+
+ // Handle each operation
+ //
+ switch( commandId )
+ {
+ case KMPXCommandIdCollectionAdd:
+ {
+ DoAddL( *aCmd.Value<CMPXMedia>(KMPXCommandColAddMedia) );
+ break;
+ }
+ case KMPXCommandIdCollectionSet:
+ {
+ DoSetL( *aCmd.Value<CMPXMedia>(KMPXCommandColSetMedia) );
+ break;
+ }
+ default:
+ {
+ User::Leave(KErrNotSupported);
+ }
+ }
+
+ // Complete Async operations
+ //
+ if( !syncOp )
+ {
+ iObs->HandleCommandComplete( NULL, KErrNone );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Adds item(s) to the collection
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::AddL(
+ const CMPXMedia& aNewMedia)
+ {
+ DoAddL( aNewMedia );
+ }
+
+// ----------------------------------------------------------------------------
+// Remove by collection path
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::RemoveL(const CMPXCollectionPath& aPath )
+ {
+ (void) aPath;
+ }
+
+// ----------------------------------------------------------------------------
+// Remove an item or items under a group from the collection
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::RemoveL(const CMPXMedia& aMedia)
+ {
+ (void)aMedia;
+ }
+
+// ----------------------------------------------------------------------------
+// Sets/updates the media for the item
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::SetL(
+ const CMPXMedia& aMedia)
+ {
+ DoSetL( aMedia );
+ }
+
+// ----------------------------------------------------------------------------
+// Find based on media properties
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::FindAllL(const CMPXMedia& aMedia,
+ const TArray<TMPXAttribute>& aAttrs )
+ {
+ (void)aMedia;
+ (void)aAttrs;
+ }
+
+// ----------------------------------------------------------------------------
+// Find based on media properties
+// ----------------------------------------------------------------------------
+//
+CMPXMedia* CMPXInMemoryPlugin::FindAllSyncL(const CMPXMedia& aMedia,
+ const TArray<TMPXAttribute>& aAttrs )
+ {
+ (void)aMedia;
+ (void)aAttrs;
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+// ----------------------------------------------------------------------------
+// Find the capabilities of this plugin
+// ----------------------------------------------------------------------------
+//
+TCollectionCapability CMPXInMemoryPlugin::GetCapabilities()
+ {
+ return 0; // nothing special supported
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// Handle change
+// ----------------------------------------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::HandleChangeL(const TMPXItemId& aId, TMPXChangeEventType aChange )
+ {
+ // Construct the message
+ //
+ CMPXMessage* message = CMPXMedia::NewL();
+ CleanupStack::PushL( message );
+
+ // Set attributes
+ //
+ message->SetTObjectValueL<TMPXMessageId>(KMPXMessageGeneralId, KMPXMessageIdItemChanged);
+
+ message->SetTObjectValueL<TUid>(KMPXMessageCollectionId, TUid::Uid(KIMPluginUid));
+
+ message->SetTObjectValueL<TMPXChangeEventType>(KMPXMessageChangeEventType, aChange);
+
+ message->SetTObjectValueL<TMPXItemId>(KMPXMessageMediaGeneralId, aId);
+
+ // Callback to observer and destroy
+ //
+ iObs->HandleMessage( *message );
+ CleanupStack::PopAndDestroy( message );
+ }
+
+// ----------------------------------------------------------------------------
+// Adds item(s) to the collection
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::DoAddL(
+ const CMPXMedia& aNewMedia)
+ {
+ TInt context = *aNewMedia.Value<TInt>( TMPXAttribute(KMPXMediaIdGeneral,
+ EMPXMediaGeneralId ) );
+
+ // Only 1 set of data per embedded context
+ TInt index = iEmbeddedContext.Find( context );
+ if( index != KErrNotFound )
+ {
+ iEmbeddedContext.Remove( index );
+ iTemporaryData.Remove( index );
+ iEmbeddedContext.Compress();
+ iTemporaryData.Compress();
+ }
+ // Push onto list
+ iEmbeddedContext.Append( context );
+
+ CMPXMedia* copy = CMPXMedia::NewL();
+ *copy = aNewMedia;
+ iTemporaryData.AppendL( copy ); // ownership transferred.
+ }
+
+// ----------------------------------------------------------------------------
+// Sets/updates the media for the item
+// ----------------------------------------------------------------------------
+//
+void CMPXInMemoryPlugin::DoSetL(
+ const CMPXMedia& aMedia)
+ {
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL <---");
+ if( !aMedia.IsSupported(KMPXMediaGeneralId) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TInt context = *aMedia.Value<TMPXItemId>(KMPXMediaGeneralId);
+ TInt index = iEmbeddedContext.Find( context );
+
+ MPX_DEBUG2("CMPXInMemoryPlugin::DoSetL index %i", index);
+ if( index != KErrNotFound )
+ {
+ TMPXAttribute att( KMPXMediaArrayContents );
+
+ // Make sure it has a media array
+ //
+ if( aMedia.IsSupported( att ) )
+ {
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 1");
+
+ // Grab the 2 media arrays
+ //
+ CMPXMediaArray* currentMedia =
+ const_cast<CMPXMediaArray*>(iTemporaryData[index]->Value<CMPXMediaArray>(att));
+ const CMPXMediaArray* newMedia = aMedia.Value<CMPXMediaArray>(att);
+
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 2");
+ // Copy all entries from newMedia into currentMedia
+ //
+ TInt newCount = newMedia->Count();
+ for( TInt i=0; i<newCount; ++i )
+ {
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 3");
+ CMPXMedia* copy = CMPXMedia::NewL(*(*newMedia)[i]);
+ CleanupStack::PushL( copy );
+
+ // If the item contains an item ID, we use it as an index to insert
+ // into the array, otherwise, append item to the end
+ //
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 4");
+ if( copy->IsSupported(KMPXMediaGeneralId) )
+ {
+ TInt index = *copy->Value<TMPXItemId>(KMPXMediaGeneralId);
+ MPX_DEBUG2("CMPXInMemoryPlugin::DoSetL index count %i", index);
+ // index is 0th based, like an array
+ //
+ TInt currentCount = currentMedia->Count();
+ if( index > currentCount )
+ {
+ // Fill in blanks then append the item we want
+ //
+ for( TInt j=currentCount; j<index; ++j )
+ {
+ CMPXMedia* blank = CMPXMedia::NewL();
+ CleanupStack::PushL( blank );
+ currentMedia->AppendL( blank ); // ownership xfer
+ CleanupStack::Pop( blank );
+ }
+ currentMedia->AppendL( copy ); // ownership xfer
+ }
+ else
+ {
+ // Replace item at index with this new version
+ //
+ currentMedia->Remove(index);
+ currentMedia->Insert( copy, index ); // ownership xfer
+ }
+ }
+ else
+ {
+ currentMedia->AppendL( copy ); // ownership xfer
+ }
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 5");
+ CleanupStack::Pop(copy);
+ }
+
+ // Set the new array into the media
+ //
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 6");
+ iTemporaryData[index]->SetCObjectValueL(att, currentMedia );
+
+ // Tell collection client context that something was added
+ //
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 7");
+ HandleChangeL( context, EMPXItemInserted );
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL 8");
+ }
+ }
+ else
+ {
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL KErrArgument");
+ User::Leave( KErrArgument );
+ }
+ MPX_DEBUG1("CMPXInMemoryPlugin::DoSetL --->");
+ }
+
+// End of file