mpx/playbackframework/playbackengine/src/mpxplaybackpluginhandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:55:47 +0200
changeset 0 a2952bb97e68
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* 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:  Implements the playback plugin handler.
*
*  There is just one plaback plugin loaded for each plugin handler / engine and
*  whenever a new plugin is selected for the engine the old one is automatically
*  unloaded. Different engines can load multiple instances of the same playback
*  plugin, however there is no connection between these instances as they
*  are tied to different songs.
*
*  There is no point in applying the reference counting mechanism for playback.
*
*
*/


#include <mpxplaybackplugin.h>
#include <mpxplaybackpluginobserver.h>
#include <mpxpluginmonitor.h>
#include <mpxlog.h>
#include "mpxplaybackplugininfo.h"
#include "mpxplaybackpluginhandler.h"

// ============================ MEMBER FUNCTIONS ==============================

// ----------------------------------------------------------------------------
// Two-phased constructor.
// ----------------------------------------------------------------------------
//
CMPXPlaybackPluginHandler* CMPXPlaybackPluginHandler::NewL(
    CMPXPluginMonitor& aPluginMonitor,
    MMPXPlaybackPluginObserver& aPluginObserver,
    MMPXPluginHandlerObserver& aObserver)
    {
    CMPXPlaybackPluginHandler* p=new(ELeave)CMPXPlaybackPluginHandler(
                                                                aPluginMonitor,
                                                                aPluginObserver,
                                                                aObserver);
    CleanupStack::PushL(p);
    p->ConstructL();
    CleanupStack::Pop(p);
    return p;
    }

// ----------------------------------------------------------------------------
// Constructor.
// ----------------------------------------------------------------------------
//
CMPXPlaybackPluginHandler::CMPXPlaybackPluginHandler(
    CMPXPluginMonitor& aPluginMonitor,
    MMPXPlaybackPluginObserver& aPluginObserver,
    MMPXPluginHandlerObserver& aObserver)
:   CMPXPluginHandlerBase(KMPXPlaybackInterfaceUid,
                          ESelectionType,
                          EPbLocal,
                          aObserver,
                          &aPluginMonitor),
    iPluginObserver(&aPluginObserver),
    iSelectedSubPlayerIndex(KErrNotFound)
    {
    }

// ----------------------------------------------------------------------------
// 2nd phase constructor.
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::ConstructL()
    {
    BaseConstructL();
    }

// ----------------------------------------------------------------------------
// Destructor.
// ----------------------------------------------------------------------------
//
CMPXPlaybackPluginHandler::~CMPXPlaybackPluginHandler()
    {
    MPX_FUNC_EX("CMPXPlaybackPluginHandler::Destructor");
    //close plugins
    for (TInt i = iLoadedPlugins.Count(); --i >= 0;)
        {
        CMPXPlaybackPlugin* p=iLoadedPlugins[i];
        TRAP_IGNORE(p->CommandL(EPbCmdClose));
        }
    iLoadedPlugins.ResetAndDestroy();
    iLoadedPluginsUids.Close();
    delete iDisplayName;
    }

// ----------------------------------------------------------------------------
// Resolve a plugin to iPlugin, based on properties (iDataType, iExt and iScheme)
// and selection criteria. If selection is by type, then there is always a
// plug-in resolved (if there are any of that type). Room for optimisation.
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::ResolvePluginL()
    {
    MPX_FUNC_EX("CMPXPlaybackPluginHandler::ResolvePluginL()");
    //
    // Resolve plugin
    //
    TUid pluginUid( KNullUid );
    TInt index( KErrNotFound );
    TPtrC displayName;
    TInt pluginType( EPbUnknown );

    DoResolvePluginL(pluginUid, index, displayName, pluginType );

    //
    // Load resolved plug-in
    //
    CMPXPlaybackPlugin* p=CreatePlayerPluginL(pluginUid);
    UsePlugin(pluginUid);

    MPX_DEBUG5("CMPXPlaybackPluginHandler::ResolvePluginL() p(%08x), iPlugin(%08x), pluginUid 0x%08x %S",
                p, iPlugin, pluginUid.iUid, &displayName);
    if (p!=iPlugin)
        {
        if (iPlugin)
            {
            UnloadPlugin(iPluginUid);
            }
        iPlugin=p;
        iPluginUid=pluginUid;

        delete iDisplayName;
        iDisplayName=NULL;
        iDisplayName=displayName.AllocL();
        iPluginType=static_cast<TMPXPlaybackPlayerType>(pluginType);
        }

    if (iSelectedSubPlayerIndex!=KErrNotFound)
        {
        iPlugin->SelectSubPlayerL(iSelectedSubPlayerIndex);
        }
    }

// ----------------------------------------------------------------------------
// Return a plugin with the specific id
// ----------------------------------------------------------------------------
//
CMPXPlaybackPlugin* CMPXPlaybackPluginHandler::CreatePlayerPluginL(
    const TUid& aUid)
    {
    MPX_DEBUG3("==>CMPXPlaybackPluginHandler::CreatePlayerPluginL 0x%08x (aUid 0x%08x)",
               this, aUid.iUid);
    CMPXPlaybackPlugin* p=NULL;
    TInt i=iLoadedPluginsUids.Find(aUid);
    if (i==KErrNotFound)
        {
        p=CMPXPlaybackPlugin::NewL(aUid,*iPluginObserver);
        CleanupStack::PushL(p);
        iLoadedPlugins.AppendL(p);
        TInt err = iLoadedPluginsUids.Append(aUid);
        if (err != KErrNone) // if the second append failed, it should revert the first append
             {
             iLoadedPlugins.Remove(iLoadedPlugins.Count()-1);
             User::Leave(err);
             }
        CleanupStack::Pop(p);
        }
     else
        {
        p=iLoadedPlugins[i];
        }
    MPX_DEBUG3("<==CMPXPlaybackPluginHandler::CreatePlayerPluginL 0x%08x (aUid 0x%08x)",
               this, aUid.iUid);
    return p;
    }

// ----------------------------------------------------------------------------
// CMPXPlaybackPluginHandler::IsPluginLoaded
// ----------------------------------------------------------------------------
//
TBool CMPXPlaybackPluginHandler::IsPluginLoaded(
    const TUid& aPluginUid)
    {
    MPX_FUNC_EX("CMPXPlaybackPluginHandler::IsPluginLoaded");
    return (iLoadedPluginsUids.Find(aPluginUid) != KErrNotFound);
    }

// ----------------------------------------------------------------------------
// CMPXPlaybackPluginHandler::LoadPluginL
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::LoadPluginL(
    const TUid& aPluginUid)
    {
    MPX_DEBUG2("===>CMPXPlaybackPluginHandler::LoadPluginL 0x%08x", this);

    if (iPlugin)
        {
        UnloadPlugin(iPluginUid);
        }

    iPlugin = CreatePlayerPluginL(aPluginUid);
    iPluginUid = aPluginUid;

    delete iDisplayName;
    iDisplayName = NULL;
    iDisplayName = PluginName(aPluginUid).AllocL();
    MPX_DEBUG3("<===CMPXPlaybackPluginHandler::LoadPluginL 0x%08x plugin name %S",
               this, iDisplayName);
    }

// ----------------------------------------------------------------------------
// Constructs the collection plugin info class
// ----------------------------------------------------------------------------
//
CMPXPluginInfo* 
CMPXPlaybackPluginHandler::ConstructPluginInfoLC(
    const CImplementationInformation& aData  )
    {
    return CMPXPlaybackPluginInfo::NewLC( aData );
    }

// ----------------------------------------------------------------------------
// Unload the plugin
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::UnloadPlugin(
    const TUid& aUid)
    {
    MPX_FUNC_EX("CMPXPlaybackPluginHandler::UnloadPlugin");

    TInt index(iLoadedPluginsUids.Find(aUid));
    if (index != KErrNotFound)
        {
        UnloadPlugin(index);
        }
    }

// ----------------------------------------------------------------------------
// Return player name
// ----------------------------------------------------------------------------
//
EXPORT_C const TDesC& CMPXPlaybackPluginHandler::PlayerName(
    TMPXPlaybackPlayerType aType) const
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::PlayerName()");
    return PluginName(aType);
    }

// ----------------------------------------------------------------------------
// Get player list with the specific type
// ----------------------------------------------------------------------------
//
EXPORT_C void CMPXPlaybackPluginHandler::GetPlayerListL(
    RArray<TUid>& aPlayers,
    TMPXPlaybackPlayerType aType)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::GetPlayerListL()");
    GetPluginUidsL(aPlayers, aType);
    }

// ----------------------------------------------------------------------------
// Select players with the specific type
// ----------------------------------------------------------------------------
//
EXPORT_C void CMPXPlaybackPluginHandler::SelectPlayersL(
    TMPXPlaybackPlayerType aType)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::SelectPlayersL(TMPXPlaybackPlayerType aType)");
    iSelectedSubPlayerIndex=KErrNotFound;
    SelectPluginL(aType);
    }

// ----------------------------------------------------------------------------
// Returns plug-in appropriate for a Uri and data type
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::SelectPlayerL(
    const TDesC& aUri,
    const TDesC8& aDataType)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::SelectPlayerL(const TDesC& aUri)");
    MPX_DEBUG2("CMPXPlaybackPluginHandler::SelectPlayerL(aUri %S)", &aUri);
    SelectPluginL( aUri, aDataType );
    }

// ----------------------------------------------------------------------------
// Returns plug-in appropriate for a file; may already be loaded or not
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::SelectPlayerL(RFile& aFile)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::SelectPlayerL(RFile& aFile)");
    SelectPluginL( aFile );
    }

// ----------------------------------------------------------------------------
// Select players with the specific UID
// ----------------------------------------------------------------------------
//
EXPORT_C void CMPXPlaybackPluginHandler::SelectPlayerL(TUid aPlayerUid)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::SelectPlayerL(TUid aPlayerUid)");
    SelectSubPlayerL(aPlayerUid,KErrNotFound);
    iSelectedType = iPluginType;
    }

// ----------------------------------------------------------------------------
// Select subplayer
// ----------------------------------------------------------------------------
//
EXPORT_C void CMPXPlaybackPluginHandler::SelectSubPlayerL(
    TUid aPlayerUid,
    TInt aSubPlayerIndex)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::SelectPlayerL(TUid aPlayerUid, TInt aSubPlayerIndex)");
    MPX_DEBUG3("CMPXPlaybackPluginHandler::SelectPlayerL(0x%08x, %d)", aPlayerUid.iUid, aSubPlayerIndex);
    iSelectedSubPlayerIndex=aSubPlayerIndex;
    SelectPluginL(aPlayerUid);
    }

// ----------------------------------------------------------------------------
// Clear selection
// ----------------------------------------------------------------------------
//
EXPORT_C void CMPXPlaybackPluginHandler::ClearSelectPlayersL()
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::ClearSelectPlayersL()");
    SelectPlayersL(EPbLocal);
    }

// ----------------------------------------------------------------------------
// Get current selection
// ----------------------------------------------------------------------------
//
EXPORT_C void CMPXPlaybackPluginHandler::GetSelection(
    TMPXPlaybackPlayerType& aType,
    TUid& aPlayer,
    TInt& aSubPlayerIndex,
    TPtrC& aSubPlayerName)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::GetSelectionL()");
    aType=iPluginType;
    aPlayer=iSelectedUid;
    aSubPlayerIndex=iSelectedSubPlayerIndex;
    if ( iPlugin )
        {
        aSubPlayerName.Set(iPlugin->SubPlayerName());
        }
    else
        {
        aSubPlayerName.Set(KNullDesC);
        }
    }

// ----------------------------------------------------------------------------
// Return a list of interfaces supported by the plugins
// ----------------------------------------------------------------------------
//
EXPORT_C CDesCArray* CMPXPlaybackPluginHandler::SupportedInterfacesL()
    {
    CDesCArray* descArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
    for(TInt i=iPluginInfoArray.Count();--i>=0;)
        {
        CMPXPlaybackPluginInfo* pi = 
            static_cast<CMPXPlaybackPluginInfo*>(iPluginInfoArray[i]);
        MPXUser::MergeArray(pi->SupportedInterfaces(), *descArray);
        }
    return descArray;
    }

// ----------------------------------------------------------------------------
// Return a list of interfaces supported by the plugins
// ----------------------------------------------------------------------------
//
EXPORT_C CDesCArray* CMPXPlaybackPluginHandler::SupportedInterfacesL(const TUid& aUid)
    {
    CDesCArray* descArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
    CleanupStack::PushL(descArray);
    for(TInt i=iPluginInfoArray.Count();--i>=0;)
        {
        if (aUid == iPluginInfoArray[i]->ImplementationUid())
            {
            CMPXPlaybackPluginInfo* pi = 
                static_cast<CMPXPlaybackPluginInfo*>(iPluginInfoArray[i]);            
            MPXUser::CopyArrayL(pi->SupportedInterfaces(), *descArray);
            break;
            }
        }
    CleanupStack::Pop(descArray);
    return descArray;
    }

// ----------------------------------------------------------------------------
// CMPXPlaybackPluginHandler::UnloadPlugin
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::UnloadPlugin(
    TInt aIndex)
    {
    CMPXPlaybackPlugin* p = iLoadedPlugins[aIndex];
    TRAP_IGNORE(p->CommandL(EPbCmdClose));
    iLoadedPlugins.Remove(aIndex);
    iLoadedPluginsUids.Remove(aIndex);
    if (p == iPlugin)
        {
        iPlugin = NULL;
        }
    delete p;
    }

#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
// ----------------------------------------------------------------------------
// Returns plug-in appropriate for a file; may already be loaded or not
// ----------------------------------------------------------------------------
//
void CMPXPlaybackPluginHandler::SelectPlayer64L(RFile64& aFile)
    {
    MPX_FUNC("CMPXPlaybackPluginHandler::SelectPlayer64L(RFile64& aFile)");
    SelectPlugin64L( aFile );
    }
#endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API

// end of file