mtpfws/mtpfw/dataproviders/devdp/src/cmtpdevicedp.cpp
changeset 0 d0791faffa3f
child 2 4843bb5893b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpfws/mtpfw/dataproviders/devdp/src/cmtpdevicedp.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,526 @@
+// 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/cmtpstoragemetadata.h>
+#include <mtp/mmtpconnection.h>
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/mtpdataproviderapitypes.h>
+#include <mtp/tmtptyperequest.h>
+
+#include "cmtpdevdpexclusionmgr.h"
+#include "cmtpdevicedatastore.h"
+#include "cmtpdevicedp.h"
+#include "cmtpdevicedpconfigmgr.h"
+#include "cmtpfsenumerator.h"
+#include "cmtprequestprocessor.h"
+#include "cmtpstoragewatcher.h"
+#include "mtpdevicedpconst.h"
+#include "mtpdevicedpprocessor.h"
+#include "mtpdevdppanic.h"
+
+#include "cmtpextndevdp.h"
+#include <mtp/cmtptypestring.h>
+
+
+// Class constants.
+__FLOG_STMT(_LIT8(KComponent,"DeviceDataProvider");)
+static const TInt KMTPDeviceDpSessionGranularity(3);
+static const TInt KMTPDeviceDpActiveEnumeration(0);
+
+/**
+MTP device data provider plug-in factory method.
+@return A pointer to an MTP device data provider plug-in. Ownership IS
+transfered.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+TAny* CMTPDeviceDataProvider::NewL(TAny* aParams)
+    {
+    CMTPDeviceDataProvider* self = new (ELeave) CMTPDeviceDataProvider(aParams);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+Destructor
+*/
+CMTPDeviceDataProvider::~CMTPDeviceDataProvider()
+    {
+    __FLOG(_L8("~CMTPDeviceDataProvider - Entry"));
+    iPendingEnumerations.Close();
+    TInt count = iActiveProcessors.Count();
+    while(count--)
+        {
+        iActiveProcessors[count]->Release();
+        }
+    iActiveProcessors.Close();
+    delete iStorageWatcher;
+    iDevDpSingletons.Close();
+    iDpSingletons.Close();
+    delete iEnumerator;
+    delete iExclusionMgr;
+
+    iExtnPluginMapArray.ResetAndDestroy();
+    iExtnPluginMapArray.Close();
+	iEvent.Reset();
+
+    __FLOG(_L8("~CMTPDeviceDataProvider - Exit"));
+    __FLOG_CLOSE;
+    }
+
+void CMTPDeviceDataProvider::Cancel()
+    {
+
+    }
+
+void CMTPDeviceDataProvider::ProcessEventL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
+    {
+    __FLOG(_L8("ProcessEventL - Entry"));
+    TInt index = LocateRequestProcessorL(aEvent, aConnection);
+    if(index != KErrNotFound)
+        {
+        iActiveProcessors[index]->HandleEventL(aEvent);
+        }
+    __FLOG(_L8("ProcessEventL - Exit"));
+    }
+
+void CMTPDeviceDataProvider::ProcessNotificationL(TMTPNotification aNotification, const TAny* aParams)
+    {
+    __FLOG(_L8("ProcessNotificationL - Entry"));
+    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;
+        }
+    __FLOG(_L8("ProcessNotificationL - Exit"));
+    }
+
+void CMTPDeviceDataProvider::ProcessRequestPhaseL(TMTPTransactionPhase aPhase, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
+    {
+    __FLOG(_L8("ProcessRequestPhaseL - Entry"));
+    TInt index = LocateRequestProcessorL(aRequest, aConnection);
+    __ASSERT_DEBUG(index != KErrNotFound, Panic(EMTPDevDpNoMatchingProcessor));
+    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;
+    __FLOG(_L8("ProcessRequestPhaseL - Exit"));
+    }
+
+void CMTPDeviceDataProvider::StartObjectEnumerationL(TUint32 aStorageId, TBool /*aPersistentFullEnumeration*/)
+    {
+    __FLOG(_L8("StartObjectEnumerationL - Entry"));
+    iPendingEnumerations.AppendL(aStorageId);
+    if (iEnumeratingState == EUndefined)
+        {
+        iDevDpSingletons.DeviceDataStore().StartEnumerationL(aStorageId, *this);
+        iEnumeratingState = EEnumeratingDeviceDataStore;
+        iStorageWatcher->Start();
+        }
+    else if (iPendingEnumerations.Count() == 1)
+        {
+    	iEnumeratingState = EEnumeratingFolders;
+    	iEnumerator->StartL(iPendingEnumerations[KMTPDeviceDpActiveEnumeration]);
+        }
+    __FLOG(_L8("StartObjectEnumerationL - Exit"));
+    }
+
+void CMTPDeviceDataProvider::StartStorageEnumerationL()
+    {
+    __FLOG(_L8("StartStorageEnumerationL - Entry"));
+    iStorageWatcher->EnumerateStoragesL();
+    Framework().StorageEnumerationCompleteL();
+    __FLOG(_L8("StartStorageEnumerationL - Exit"));
+    }
+
+void CMTPDeviceDataProvider::Supported(TMTPSupportCategory aCategory, RArray<TUint>& aArray) const
+    {
+    __FLOG(_L8("Supported - Entry"));
+    TInt mode = Framework().Mode();
+    switch (aCategory)
+        {
+    case EAssociationTypes:
+        aArray.Append(EMTPAssociationTypeGenericFolder);        
+        break;
+
+    case EDeviceProperties:
+        {
+        TInt count = sizeof(KMTPDeviceDpSupportedProperties) / sizeof(TUint16);
+        for(TInt i = 0; i < count; i++)
+            {
+            if(( (EModePTP == mode) ||(EModePictBridge == mode) )
+				&& ( 0x4000 == (KMTPDeviceDpSupportedProperties[i] & 0xE000)))
+            	{
+            	//in ptp mode support only ptp properties
+            	aArray.Append(KMTPDeviceDpSupportedProperties[i]);
+            	}
+            else
+            	{
+            	aArray.Append(KMTPDeviceDpSupportedProperties[i]);
+            	}
+            }
+           
+        TInt noOfEtxnPlugins = iExtnPluginMapArray.Count();
+        for(TInt i=0; i < noOfEtxnPlugins; i++)
+	        {
+	        iExtnPluginMapArray[i]->ExtPlugin()->Supported(aCategory, *iExtnPluginMapArray[i]->SupportedOpCodes(), (TMTPOperationalMode)mode );// or pass the incoming array
+	        TInt count =iExtnPluginMapArray[i]->SupportedOpCodes()->Count();
+       												  														//bcoz it needs to b updated
+	        for (TInt r=0; r <count; r++ )
+	        	{
+	        	aArray.Append((*iExtnPluginMapArray[i]->SupportedOpCodes())[r]);
+	        	}
+	       }
+
+       TRAP_IGNORE(iPtrDataStore->SetSupportedDevicePropertiesL(aArray));
+       }
+        break;
+
+    case EEvents:
+        {
+        TInt count = sizeof(KMTPDeviceDpSupportedEvents) / sizeof(TUint16);
+        for(TInt i = 0; i < count; i++)
+            {
+            TUint16 event = KMTPDeviceDpSupportedEvents[i];
+            switch(mode)
+                {
+            case EModePTP:
+            case EModePictBridge:
+                // In the initial implementation all device DP events pass this test, but this
+                // catches any others added in the future that fall outside this range.
+                if(event <= EMTPEventCodePTPEnd)
+                    {
+                    aArray.Append(event);
+                    }
+                break;
+
+            case EModeMTP:
+                // In the initial implementation all device DP events pass this test, but this
+                // catches any others added in the future that fall outside this range.
+                if(event <= EMTPEventCodeMTPEnd)
+                    {
+                    aArray.Append(event);
+                    }
+                break;
+
+            default:
+            	// No other valid modes are defined
+                break;
+                }
+            }
+        }
+        break;
+
+    case EObjectCaptureFormats:
+    case EObjectPlaybackFormats:
+  		// Only supports association objects
+        aArray.Append(EMTPFormatCodeAssociation);
+        break;
+
+
+    case EOperations:
+        {
+        TInt count = sizeof(KMTPDeviceDpSupportedOperations) / sizeof(TUint16);
+        for(TInt i = 0; i < count; i++)
+            {
+            aArray.Append(KMTPDeviceDpSupportedOperations[i]);
+            }
+        }
+        break;
+
+    case EStorageSystemTypes:
+        aArray.Append(CMTPStorageMetaData::ESystemTypeDefaultFileSystem);
+        break;
+
+    case EObjectProperties:
+        {
+        TInt count(sizeof(KMTPDeviceDpSupportedObjectProperties) / sizeof(KMTPDeviceDpSupportedObjectProperties[0]));
+        for (TInt i(0); (i < count); i++)
+            {
+            aArray.Append(KMTPDeviceDpSupportedObjectProperties[i]);
+            }
+        }
+        break;
+
+    default:
+        // Unrecognised category, leave aArray unmodified.
+        break;
+        }
+    __FLOG(_L8("Supported - Exit"));
+    }
+
+#ifdef __FLOG_ACTIVE
+void CMTPDeviceDataProvider::NotifyEnumerationCompleteL(TUint32 aStorageId, TInt aError)
+#else
+void CMTPDeviceDataProvider::NotifyEnumerationCompleteL(TUint32 aStorageId, TInt /*aError*/)
+#endif // __FLOG_ACTIVE
+	{
+    __FLOG(_L8("NotifyEnumerationCompleteL - Entry"));
+    __ASSERT_DEBUG((aStorageId == iPendingEnumerations[KMTPDeviceDpActiveEnumeration]), User::Invariant());
+	switch(iEnumeratingState)
+		{
+	case EEnumeratingDeviceDataStore:
+		iEnumeratingState = EEnumeratingFolders;
+		iEnumerator->StartL(iPendingEnumerations[KMTPDeviceDpActiveEnumeration]);
+		break;
+
+	case EEnumeratingFolders:
+        __FLOG_VA((_L8("Enumeration of storage 0x%08X completed with error status %d"), aStorageId, aError));
+        iPendingEnumerations.Remove(KMTPDeviceDpActiveEnumeration);
+        Framework().ObjectEnumerationCompleteL(aStorageId);
+        if (iPendingEnumerations.Count() > 0)
+            {
+        	iEnumerator->StartL(iPendingEnumerations[KMTPDeviceDpActiveEnumeration]);
+            }
+        else
+            {
+    		iEnumeratingState = EEnumerationComplete;
+            }
+		break;
+
+	case EEnumerationComplete:
+	default:
+		__DEBUG_ONLY(User::Invariant());
+		break;
+		}
+    __FLOG(_L8("NotifyEnumerationCompleteL - Exit"));
+	}
+
+/**
+Constructor.
+*/
+CMTPDeviceDataProvider::CMTPDeviceDataProvider(TAny* aParams) :
+    CMTPDataProviderPlugin(aParams),
+    iActiveProcessors(KMTPDeviceDpSessionGranularity),
+    iActiveProcessor(-1)
+    {
+
+    }
+
+/**
+Load devdp extension plugins if present
+*/
+void CMTPDeviceDataProvider::LoadExtnPluginsL()
+	{
+
+	RArray<TUint> extnUidArray;
+	CleanupClosePushL(extnUidArray);
+	iDevDpSingletons.ConfigMgr().GetRssConfigInfoArrayL( extnUidArray, EDevDpExtnUids);
+
+	TInt count = extnUidArray.Count();
+	for (TInt i = 0; i < count; i++)
+		{
+
+		CDevDpExtnPluginMap* extnpluginMap = NULL;
+		extnpluginMap = CDevDpExtnPluginMap::NewL(*this, TUid::Uid(extnUidArray[i]));
+
+		if(extnpluginMap )
+			{
+			iExtnPluginMapArray.Append(extnpluginMap);
+			}
+
+		}
+	CleanupStack::PopAndDestroy(&extnUidArray);
+	}
+
+/**
+Second phase constructor.
+*/
+void CMTPDeviceDataProvider::ConstructL()
+    {
+    __FLOG_OPEN(KMTPSubsystem, KComponent);
+    __FLOG(_L8("ConstructL - Entry"));
+    iDevDpSingletons.OpenL(Framework());
+    iPtrDataStore = &(iDevDpSingletons.DeviceDataStore());
+    iDpSingletons.OpenL(Framework());
+
+    iExclusionMgr = CMTPDevDpExclusionMgr::NewL(Framework());
+    iDpSingletons.SetExclusionMgrL(*iExclusionMgr);
+
+    iStorageWatcher = CMTPStorageWatcher::NewL(Framework());
+
+    const TUint KProcessLimit = iDevDpSingletons.ConfigMgr().UintValueL(CMTPDeviceDpConfigMgr::EEnumerationIterationLength);
+
+ 	TRAPD(err, LoadExtnPluginsL());
+ //	__ASSERT_DEBUG((err == KErrNone), Panic(_L("Invalid resource file ")));
+ 	if(KErrNone != err)
+		{
+	    __FLOG(_L8("\nTere is an issue in loading the plugin !!!!!\n"));
+		}
+
+    iEnumerator = CMTPFSEnumerator::NewL(Framework(), iDpSingletons.ExclusionMgrL(), *this, KProcessLimit);
+    __FLOG(_L8("ConstructL - Exit"));
+
+    }
+
+void CMTPDeviceDataProvider::OnDevicePropertyChangedL (TMTPDevicePropertyCode& aPropCode)
+	{
+	iEvent.Reset();
+	iEvent.SetUint16(TMTPTypeEvent::EEventCode, EMTPEventCodeDevicePropChanged );
+	iEvent.SetUint32(TMTPTypeEvent::EEventSessionID, KMTPSessionAll);
+	iEvent.SetUint32(TMTPTypeEvent::EEventTransactionID, KMTPTransactionIdNone);
+	iEvent.SetUint32(TMTPTypeEvent::EEventParameter1, aPropCode);
+	Framework().SendEventL(iEvent);
+	}
+
+/**
+ *This method will return the reference to MMTPDataProviderFramework from CMTPDataProviderPlugin
+ */
+MMTPDataProviderFramework& CMTPDeviceDataProvider::DataProviderFramework ()
+	{
+	return Framework();
+	}
+
+TInt CMTPDeviceDataProvider::FindExtnPlugin(TUint aOpcode)
+	{
+	TInt noOfEtxnPlugins = iExtnPluginMapArray.Count();
+	for(TInt i=0; i < noOfEtxnPlugins; i++)
+		{
+		if(iExtnPluginMapArray[i]->SupportedOpCodes()->Find(aOpcode)!= KErrNotFound)
+			{
+			return i;
+			}
+		}
+	return KErrNotFound;
+	}
+/**
+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 CMTPDeviceDataProvider::LocateRequestProcessorL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
+    {
+    __FLOG(_L8("LocateRequestProcessorL - Entry"));
+    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 = MTPDeviceDpProcessor::CreateL(Framework(), aRequest, aConnection);
+        __ASSERT_DEBUG(processor, Panic(EMTPDevDpNoMatchingProcessor));
+        CleanupReleasePushL(*processor);
+        iActiveProcessors.AppendL(processor);
+        TUint16 operationCode(aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode));
+
+       if (operationCode >= EMTPOpCodeGetDevicePropDesc && operationCode <=EMTPOpCodeResetDevicePropValue)
+		{
+		TUint propCode = aRequest.Uint32(TMTPTypeRequest::ERequestParameter1);
+		TInt foundplugin = FindExtnPlugin (propCode);
+		if(foundplugin!= KErrNotFound)
+			{
+			iDevDpSingletons.DeviceDataStore().SetExtnDevicePropDp(iExtnPluginMapArray[foundplugin]->ExtPlugin());
+			}
+		}
+	        CleanupStack::Pop();
+	        index = count;
+        }
+    __FLOG(_L8("LocateRequestProcessorL - Exit"));
+    return index;
+    }
+
+/**
+Finds 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 CMTPDeviceDataProvider::LocateRequestProcessorL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
+    {
+    __FLOG(_L8("LocateRequestProcessorL - Entry"));
+    TInt index = KErrNotFound;
+    TInt count = iActiveProcessors.Count();
+    for(TInt i = 0; i < count; i++)
+	{
+	if(iActiveProcessors[i]->Match(aEvent, aConnection))
+		{
+		index = i;
+		break;
+		}
+	}
+    __FLOG(_L8("LocateRequestProcessorL - Exit"));
+    return index;
+    }
+
+/**
+Cleans up outstanding request processors when a session is closed.
+@param aSession notification parameter block
+*/
+void CMTPDeviceDataProvider::SessionClosedL(const TMTPNotificationParamsSessionChange& aSession)
+    {
+    __FLOG(_L8("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();
+    		} 
+		}
+        }
+    __FLOG(_L8("SessionClosedL - Exit"));
+    }
+
+/**
+Prepares for a newly-opened session.
+@param aSession notification parameter block
+*/
+#ifdef __FLOG_ACTIVE
+void CMTPDeviceDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& aSession)
+#else
+void CMTPDeviceDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& /*aSession*/)
+#endif
+    {
+    __FLOG(_L8("SessionOpenedL - Entry"));
+    __FLOG_VA((_L8("SessionID = %d"), aSession.iMTPId));
+    __FLOG(_L8("SessionOpenedL - Exit"));
+    }
+