mtpfws/mtpfw/dataproviders/proxydp/src/cmtpproxydp.cpp
author hgs
Fri, 03 Sep 2010 18:38:04 +0800
changeset 49 c20dd21d1eb4
parent 0 d0791faffa3f
permissions -rw-r--r--
201035_05

// Copyright (c) 2006-2009 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:
//

#include <mtp/mmtpconnection.h>
#include <mtp/mmtpdataproviderframework.h>
#include <mtp/mtpdataproviderapitypes.h>
#include <mtp/tmtptyperequest.h>

#include "cmtpproxydp.h"
#include "cmtprequestprocessor.h"
#include "mtpproxydppanic.h"
#include "mtpproxydpprocessor.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "cmtpproxydpTraces.h"
#endif
 

static const TInt KMTPProxyDpSessionGranularity = 3;	

/**
Standard NewL method
@param aParams	The pointer to MMTPDataProviderFramework
*/	
TAny* CMTPProxyDataProvider::NewL(TAny* aParams)
	{
	CMTPProxyDataProvider* self = new (ELeave) CMTPProxyDataProvider(aParams);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
	}
	
	
void CMTPProxyDataProvider::ConstructL()
	{  
	OstTraceFunctionEntry0( CMTPPROXYDATAPROVIDER_CONSTRUCTL_ENTRY );
	iDpSingletons.OpenL(Framework());
	iSingletons.OpenL(Framework());
	OstTraceFunctionExit0( CMTPPROXYDATAPROVIDER_CONSTRUCTL_EXIT );
	}

/**
Destructor
*/	
CMTPProxyDataProvider::~CMTPProxyDataProvider()
	{
	OstTraceFunctionEntry0( CMTPPROXYDATAPROVIDER_CMTPPROXYDATAPROVIDER_DES_ENTRY );
	TInt count = iActiveProcessors.Count();
	while(count--)
		{
		iActiveProcessors[count]->Release();
		}
	iActiveProcessors.Close();	
	iDpSingletons.Close();
	iSingletons.Close();
	OstTraceFunctionExit0( CMTPPROXYDATAPROVIDER_CMTPPROXYDATAPROVIDER_DES_EXIT );
	}
    
void CMTPProxyDataProvider::Cancel()
    {
    
    }

/**
Process the event from initiator
@param aEvent	The event to be processed
@param aConnection	The connection from which the event comes
*/	
void CMTPProxyDataProvider::ProcessEventL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
	{
	TInt index = LocateRequestProcessorL(aEvent, aConnection);
	if(index != KErrNotFound)
		{
		iActiveProcessors[index]->HandleEventL(aEvent);
		}
	}
     
void CMTPProxyDataProvider::ProcessNotificationL(TMTPNotification aNotification, const TAny* aParams)
    {
    switch (aNotification)
        {
    case EMTPSessionClosed:
        SessionClosedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams));
        break;
        
    case EMTPSessionOpened:
        SessionOpenedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams));
        break;
        
    default:
        // Ignore all other notifications.
        break;
        }
    }

/**
Process the request from initiator.  The method first searches if there is any matching active processor;
if not, it creates a new processor.  It deletes the processor once it finishes.
@param aPhase	The request transaction phase
@param aRequest	The request to be processed
@param aConnection	The connection from which the request comes
*/	
void CMTPProxyDataProvider::ProcessRequestPhaseL(TMTPTransactionPhase aPhase, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
	{	
	TInt index = LocateRequestProcessorL(aRequest, aConnection);
	__ASSERT_DEBUG(index != KErrNotFound, Panic(EMTPNoMatchingProcessor));
	MMTPRequestProcessor* processor = iActiveProcessors[index];
	iActiveProcessor = index;
	iActiveProcessorRemoved = EFalse;
	TBool result = processor->HandleRequestL(aRequest, aPhase);
	if (iActiveProcessorRemoved)
		    {
		    processor->Release(); // destroy the processor
		    }
	else if (result)
		    {    
		    processor->Release();    	
		    iActiveProcessors.Remove(index);
		    }
	iActiveProcessor = -1;

	}
	
void CMTPProxyDataProvider::StartObjectEnumerationL(TUint32 aStorageId, TBool /*aPersistentFullEnumeration*/)
    {
    // The proxy data provider does not manage any data objects.
    Framework().ObjectEnumerationCompleteL(aStorageId);
    }
    
void CMTPProxyDataProvider::StartStorageEnumerationL()
    {
    Framework().StorageEnumerationCompleteL();
    }

/**
Append all the operations that are supported by the proxy data provider to
the operations array.
@param aCategory category of operations of interest
@param aArray array to hold the operations
*/
void CMTPProxyDataProvider::Supported(TMTPSupportCategory aCategory, RArray<TUint>& /*aArray*/) const
    {
    OstTraceFunctionEntry0( CMTPPROXYDATAPROVIDER_SUPPORTED_ENTRY );
    switch (aCategory) 
        {        
    case EEvents:
        break;
        
    case EObjectCaptureFormats:
    case EObjectPlaybackFormats:

        break;
        
    case EObjectProperties:
        break; 
        
    case EOperations:
        break;  
        
    case EStorageSystemTypes:
        break; 
        
    default:
    
        // Unrecognised category, leave aArray unmodified.
        break;
        }

    OstTraceFunctionExit0( CMTPPROXYDATAPROVIDER_SUPPORTED_EXIT );
    }
    

void CMTPProxyDataProvider::SupportedL(TMTPSupportCategory /*aCategory*/, CDesCArray& /*aStrings*/) const
	{
	OstTraceFunctionEntry0( CMTPPROXYDATAPROVIDER_SUPPORTEDL_ENTRY );
	OstTraceFunctionExit0( CMTPPROXYDATAPROVIDER_SUPPORTEDL_EXIT );
	}
  
    

/**
Standard c++ constructor
*/
CMTPProxyDataProvider::CMTPProxyDataProvider(TAny* aParams)
	:CMTPDataProviderPlugin(aParams),
	iActiveProcessors(KMTPProxyDpSessionGranularity),
	iActiveProcessor(-1)
	{
	}

/**
Find or create a request processor that can process the request
@param aRequest	The request to be processed
@param aConnection The connection from which the request comes
@return the index of the found/created request processor
*/
TInt CMTPProxyDataProvider::LocateRequestProcessorL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
    {
    TInt index = KErrNotFound;
    TInt count = iActiveProcessors.Count();
    for(TInt i = 0; i < count; i++)
        {
        if(iActiveProcessors[i]->Match(aRequest, aConnection))
            {
            index = i;
            break;
            }
        }
    if(index == KErrNotFound)
        {
        MMTPRequestProcessor* processor = MTPProxyDpProcessor::CreateL(Framework(), aRequest, aConnection);
        __ASSERT_DEBUG(processor, Panic(EMTPNoMatchingProcessor));
        CleanupReleasePushL(*processor);
        iActiveProcessors.AppendL(processor);
        CleanupStack::Pop();
        index = count;
        }
    return index;

    }

/**
Find a request processor that can process the event
@param aEvent	The event to be processed
@param aConnection The connection from which the request comes
@return the index of the found request processor, KErrNotFound if not found
*/	
TInt CMTPProxyDataProvider::LocateRequestProcessorL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
    {
    TInt index = KErrNotFound;
    TInt count = iActiveProcessors.Count();
    for(TInt i = 0; i < count; i++)
        {
        if(iActiveProcessors[i]->Match(aEvent, aConnection))
            {
            index = i;
            break;
            }
        }
    return index;
    }
       
void CMTPProxyDataProvider::SessionClosedL(const TMTPNotificationParamsSessionChange& aSession)
    {
    OstTraceFunctionEntry0( CMTPPROXYDATAPROVIDER_SESSIONCLOSEDL_ENTRY );
    TInt count = iActiveProcessors.Count();
    while(count--)
        {
        MMTPRequestProcessor* processor = iActiveProcessors[count];
        TUint32 sessionId = processor->SessionId();
        if((sessionId == aSession.iMTPId) && (processor->Connection().ConnectionId() == aSession.iConnection.ConnectionId()))
            {
            iActiveProcessors.Remove(count);
            if (count == iActiveProcessor)
    			{
    			iActiveProcessorRemoved = ETrue;
    			}
			else
    			{    			
    			processor->Release();
    			} 
            }
        }  
    OstTraceFunctionExit0( CMTPPROXYDATAPROVIDER_SESSIONCLOSEDL_EXIT );
    }

/**
Prepares for a newly-opened session.
@param aSession notification parameter block
*/
#ifdef OST_TRACE_COMPILER_IN_USE
void CMTPProxyDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& /*aSession*/)
#else
void CMTPProxyDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& /*aSession*/)
#endif
    {
    OstTraceFunctionEntry0( CMTPPROXYDATAPROVIDER_SESSIONOPENEDL_ENTRY );
    OstTraceFunctionExit0( CMTPPROXYDATAPROVIDER_SESSIONOPENEDL_EXIT );
    }