mpxplugins/serviceplugins/collectionplugins/mpxinmemoryplugin/src/mpxinmemoryplugin.cpp
changeset 0 ff3acec5bc43
child 18 c54d95799c80
--- /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