genericservices/mimerecognitionfw/apmime/APMFNDR.CPP
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericservices/mimerecognitionfw/apmime/APMFNDR.CPP	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,427 @@
+// Copyright (c) 1997-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:
+// concrete file finders for MIME type recognizers
+// 
+//
+
+#include "APMFNDR.H"
+
+#include <e32uid.h>
+#include "APMPAN.H"
+
+#ifdef USING_ECOM_RECOGS
+#include <ecom/ecom.h>
+#endif
+
+const TInt KRecognizerDllGranularity=2;
+
+#ifdef USING_ECOM_RECOGS
+const TUid KUidDataRecogInterFaceUid = {0x101F7D87};
+#endif
+
+//
+// class TRecognizer
+//
+
+CApaScanningDataRecognizer::TRecognizer::TRecognizer(HBufC* aName)
+	{
+	iName=aName;
+	}
+	
+//
+// class CApaRecognizerDll
+//
+
+CApaRecognizerDll::~CApaRecognizerDll()
+	{
+	delete iId.iName;
+	iLibrary.Close();
+	delete iNext;
+	}
+
+CApaRecognizerDll::CApaRecognizerDll(HBufC* aName) 
+	: iId(aName)
+	{
+	}
+
+#ifdef USING_ECOM_RECOGS
+// Used for cleanup support of locally declared arrays
+void CleanUpEComInfoArray(TAny* aInfoArray)
+	{
+	RImplInfoPtrArray* infoArray = (static_cast<RImplInfoPtrArray*>(aInfoArray));
+	infoArray->ResetAndDestroy();
+	infoArray->Close();
+	}
+#endif
+
+// class CApaBackupOperationObserver
+CApaScanningDataRecognizer::CApaBackupOperationObserver::CApaBackupOperationObserver(CApaScanningDataRecognizer& aRecognizer)
+	: iRecognizer(aRecognizer)
+	{
+	TRAP_IGNORE(iSession = CBaBackupSessionWrapper::NewL());
+	}
+
+CApaScanningDataRecognizer::CApaBackupOperationObserver::~CApaBackupOperationObserver()
+	{
+	if( iSession )
+		{
+		iSession->DeRegisterBackupOperationObserver(*this);
+		delete iSession;
+		}
+	}
+
+void CApaScanningDataRecognizer::CApaBackupOperationObserver::RegisterObserverL()
+	{
+	if(iSession)
+		{
+		iSession->RegisterBackupOperationObserverL(*this);
+		}
+	}
+
+void CApaScanningDataRecognizer::CApaBackupOperationObserver::HandleBackupOperationEventL(const TBackupOperationAttributes& aBackupOperationAttributes)
+	{
+	if (!iRecognizer.iExtra->iRecognizersLoaded)
+		{
+		// Then the recognizers have been unloaded, so there's nothing to do
+		return;
+		}
+
+	if ((aBackupOperationAttributes.iFileFlag == MBackupObserver::EReleaseLockReadOnly ||
+		aBackupOperationAttributes.iFileFlag == MBackupObserver::EReleaseLockNoAccess)
+		&& aBackupOperationAttributes.iOperation == EStart)
+		{
+		// release recognisers not in rom
+		TInt count = iRecognizer.RecognizerCount();
+		for (TInt i=count-1; i>=0; i--)
+			{
+				CApaRecognizerDll* lib=iRecognizer.iRecognizerLib[i];
+				TDriveUnit drive(lib->iId.iDrive);
+				TChar driveName=drive.Name()[0];
+				if(driveName != TChar('Z'))
+					{
+					iRecognizer.RemoveRecognizer(lib); // ignore any errors
+					}
+			}
+		}
+
+	if (aBackupOperationAttributes.iFileFlag == MBackupObserver::ETakeLock &&
+		(aBackupOperationAttributes.iOperation == EEnd ||
+		aBackupOperationAttributes.iOperation == EAbort))
+		{
+		iRecognizer.ScanForRecognizersL();
+		}
+	}
+
+TInt CApaScanningDataRecognizer::CApaBackupOperationObserver::UpdateCounter() const
+	{
+	return iUpdateCounter;
+	}
+
+void CApaScanningDataRecognizer::CApaBackupOperationObserver::SetUpdateCounter(TInt aValue)
+	{
+	iUpdateCounter = aValue;
+	}
+
+
+//
+// class CApaScanningDataRecognizer
+// 
+
+EXPORT_C CApaScanningDataRecognizer* CApaScanningDataRecognizer::NewL(RFs& aFs)
+	{
+	return NewL(aFs,ETrue);
+	}
+
+/**
+@internalTechnology
+*/
+EXPORT_C CApaScanningDataRecognizer* CApaScanningDataRecognizer::NewL(RFs& aFs, TBool aLoadDataRecognizers)
+	{
+	CApaScanningDataRecognizer* self=new(ELeave) CApaScanningDataRecognizer(aFs);
+	CleanupStack::PushL(self);
+	self->ConstructL(aLoadDataRecognizers);
+	CleanupStack::Pop(); // self
+	return self;
+	}
+
+EXPORT_C CApaScanningDataRecognizer::~CApaScanningDataRecognizer()
+	{
+	UnloadRecognizers();
+	delete iExtra->iObserver;
+	delete iExtra;
+	}
+
+EXPORT_C void CApaScanningDataRecognizer::ScanForRecognizersL()
+	{
+	// set all recognizers to not present - pending rediscovery
+	TInt count=iRecognizerLib.Count();
+	TInt i;
+	for (i=0; i<count; i++)
+		iRecognizerLib[i]->iPresent=CApaRecognizerDll::ENotPresent;
+
+	ScanForEcomRecognizersL();
+	//
+	// remove any recognizers that are no longer present
+	for (TInt ii=iRecognizerLib.Count()-1;ii>=0;ii--)
+		{
+		CApaRecognizerDll* lib=iRecognizerLib[ii];
+		if (lib->iPresent==CApaRecognizerDll::ENotPresent)
+			{
+			RemoveRecognizer(lib); // ignore any errors
+			}
+		}
+	iMaxBufferSize = -1; // Recognizers were re-loaded so need to recalculate the maximum buffer size
+	}
+
+EXPORT_C TInt CApaScanningDataRecognizer::RecognizerCount()
+	{
+	return iRecognizerLib.Count();
+	}
+
+EXPORT_C CApaScanningDataRecognizer::CRecognizerArray* CApaScanningDataRecognizer::RecognizerListLC()const
+	{
+	CRecognizerArray* list=new(ELeave) CArrayFixFlat<TRecognizer>(2);
+	CleanupStack::PushL(list);
+	TInt count=iRecognizerLib.Count();
+	for (TInt i=0; i<count; i++)
+		list->AppendL(iRecognizerLib[i]->iId);
+	return list;
+	}
+
+EXPORT_C const CApaScanningDataRecognizer::TRecognizer& CApaScanningDataRecognizer::operator[](TInt aIndex)const
+	{
+	return iRecognizerLib[aIndex]->iId;	
+	}
+
+EXPORT_C TInt CApaScanningDataRecognizer::UpdateCounter()const
+	{
+	return iExtra->iObserver->UpdateCounter();
+	}
+
+
+EXPORT_C CApaScanningDataRecognizer::CApaScanningDataRecognizer(RFs& aFs)
+	:CApaDataRecognizer(aFs),
+	iRecognizerLib(KRecognizerDllGranularity)
+	{
+	__DECLARE_NAME(_S("CApaScanningDataRecognizer"));
+	}
+
+EXPORT_C void CApaScanningDataRecognizer::ConstructL()
+	{
+	ConstructL(ETrue);
+	}
+
+void CApaScanningDataRecognizer::ConstructL(TBool aLoadDataRecognizers)
+	{
+	iExtra = new (ELeave) CApaScanningDataRecognizerExtra();
+	iExtra->iObserver = new (ELeave) CApaBackupOperationObserver( *this );
+	iExtra->iObserver->RegisterObserverL();
+	if(aLoadDataRecognizers)
+		{
+		LoadRecognizersL();
+		}
+	}
+
+EXPORT_C void CApaScanningDataRecognizer::SetEcomRecognizersFromListL(const CRecognizerArray& aList)
+	{
+	//for ecom style
+	for (TInt i=0 ; i<aList.Count() ; i++)
+		{
+		TDriveUnit drive(aList[i].iDrive);
+		TRAPD(ret, LoadEcomRecognizerL(drive,aList[i].iUid));
+		if (ret==KErrNoMemory)
+			{
+			User::Leave(ret); 
+			}
+		}
+	}
+
+EXPORT_C void CApaScanningDataRecognizer::SetEcomRecognizerL(const TRecognizer& aRecognizer)
+	{
+	//for ecom style 
+	TDriveUnit drive(aRecognizer.iDrive);
+	LoadEcomRecognizerL(drive,aRecognizer.iUid);
+	}
+
+TInt CApaScanningDataRecognizer::RemoveRecognizer(CApaRecognizerDll* aDll)
+	{
+	__ASSERT_DEBUG(iRecognizerLib.Count()>0,User::Invariant());
+	// try to remove the recognizer from the list
+	TInt ret=RemoveDataRecognizerType(aDll->iRec);
+	if (ret!=KErrNone && ret!=KErrNotFound)
+		return ret;
+	//
+	// get a handle to the previous entry in the list
+	TInt count=iRecognizerLib.Count();
+	TInt i;
+	for (i=0; i<count; i++)
+		{
+		if (iRecognizerLib[i]==aDll)
+			break;
+		}
+	__ASSERT_ALWAYS(i<count,Panic(EPanicLibraryNotInList));
+	
+	// remove the dll
+	delete iRecognizerLib[i];
+	iRecognizerLib.Remove(i);
+	iRecognizerLib.Compress();
+	if(iExtra->iObserver)
+		iExtra->iObserver->SetUpdateCounter(iExtra->iObserver->UpdateCounter() +1);
+	return KErrNone;
+	}
+
+#ifdef USING_ECOM_RECOGS
+
+//load the ecom style data recognizer
+void CApaScanningDataRecognizer::LoadEcomRecognizerL(TDriveUnit& aDrive,TUid aUid)
+	{
+	//Get implementation information of the recognizer with UID aUid
+	RImplInfoPtrArray implementationInfoArray;
+	TCleanupItem cleanup(CleanUpEComInfoArray, &implementationInfoArray);
+	CleanupStack::PushL(cleanup);
+	REComSession::ListImplementationsL(KUidDataRecogInterFaceUid,implementationInfoArray);
+	const TInt availCount = implementationInfoArray.Count();
+	CImplementationInformation* info=NULL;
+	TInt ii;
+	for (ii=0;ii<availCount;++ii)
+		{
+		info = implementationInfoArray[ii];
+		TUid uid = info->ImplementationUid();
+		
+		if(uid.iUid == aUid.iUid )
+			{
+			break;
+			}
+		}
+
+	//If the implementation not found just return
+	if(ii==availCount)
+		{
+		CleanupStack::PopAndDestroy(&implementationInfoArray);		
+		return;
+		}
+	
+	//Get the version of implementation
+	TInt version=info->Version();
+	
+	// check we haven't loaded this one already
+	TInt count=iRecognizerLib.Count();
+	TInt i;
+	CApaRecognizerDll* lib=NULL; // the previous one in the list
+	for (i=0; i<count; i++)
+		{
+		lib=iRecognizerLib[i];
+		if (lib->iId.iUid==aUid)
+			{// we may have to override one
+			if (lib->iPresent!=CApaRecognizerDll::ENotPresent)
+				{
+				CleanupStack::PopAndDestroy(&implementationInfoArray);				
+				return; // already found
+				}
+			else
+				{
+				if (lib->iVersion < version)
+					{
+					//Upgrade a plugin if a plugin with higher version than loaded plugin is installed.  
+					lib->iPresent = CApaRecognizerDll::ESuperseded;
+					break;
+					}
+				else
+					{
+					CleanupStack::PopAndDestroy(&implementationInfoArray);					
+					lib->iPresent = CApaRecognizerDll::EIsPresent;
+					return;
+					}
+				}
+			}			
+		}
+	//Remove the old version and let it continue to load new version
+	if ((i<count)&&(lib->iPresent==CApaRecognizerDll::ESuperseded))
+		{
+		RemoveRecognizer(lib);
+		}
+
+	// load the library
+	HBufC* recogName=info->DisplayName().AllocL();
+	CleanupStack::PushL(recogName);
+	lib=NULL;
+	lib = new(ELeave) CApaRecognizerDll(recogName);
+	CleanupStack::Pop(recogName);
+	CleanupStack::PushL(lib);
+	TRAPD(error,lib->iRec = CApaDataRecognizerType::CreateDataRecognizerL(aUid));
+	if(!error && lib->iRec)
+		{
+		lib->iPresent = CApaRecognizerDll::EIsPresent;
+		AddDataRecognizerTypeL(lib->iRec);
+		lib->iId.iUid = aUid;
+		lib->iId.iDrive = aDrive;
+		lib->iVersion=version;
+		iExtra->iObserver->SetUpdateCounter(iExtra->iObserver->UpdateCounter() + 1);
+		//
+		// add lib to the library list
+		iRecognizerLib.AppendL(lib);
+		CleanupStack::Pop(lib); // lib
+		}
+	else
+		{
+		CleanupStack::PopAndDestroy(lib); // lib
+		}
+	CleanupStack::PopAndDestroy(&implementationInfoArray);	
+	}
+#else
+void CApaScanningDataRecognizer::LoadEcomRecognizerL(TDriveUnit&,TUid)
+	{
+	}
+#endif
+
+void CApaScanningDataRecognizer::ScanForEcomRecognizersL()
+	{
+#ifdef USING_ECOM_RECOGS
+	//scan ecom plugin
+	RImplInfoPtrArray implementationArray;
+	TCleanupItem cleanup(CleanUpEComInfoArray, &implementationArray);
+	CleanupStack::PushL(cleanup);
+	REComSession::ListImplementationsL(KUidDataRecogInterFaceUid,implementationArray);
+	const TInt availCount = implementationArray.Count();
+	for (TInt count=0;count<availCount;++count)
+		{
+		const CImplementationInformation* info = implementationArray[count];
+		TUid uid = info->ImplementationUid();
+		TDriveUnit drive=info-> Drive();
+		TRAP_IGNORE(LoadEcomRecognizerL(drive,uid));
+		}
+	CleanupStack::PopAndDestroy(&implementationArray);
+#endif
+	}
+
+/**
+@internalTechnology
+*/
+EXPORT_C void CApaScanningDataRecognizer::LoadRecognizersL()
+	{
+	iExtra->iRecognizersLoaded = ETrue;
+	ScanForRecognizersL();
+	UpdateDataTypesL();
+	}
+
+/**
+@internalTechnology
+*/
+EXPORT_C void CApaScanningDataRecognizer::UnloadRecognizers()
+	{	
+	iExtra->iRecognizersLoaded = EFalse;
+	DestroyRecognizerList();
+	iRecognizerLib.ResetAndDestroy();
+	}
+