layouts/cdl/CdlEngine/src/CCdlEngine.cpp
changeset 0 05e9090e2422
child 10 08459e712984
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layouts/cdl/CdlEngine/src/CCdlEngine.cpp	Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,506 @@
+/*
+* Copyright (c) 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 "CCdlEngine.h"
+#include <CdlEngDef.h>
+#include "CdlRefs.h"
+#include "CdlServEng.h"
+
+
+
+//
+// CCdlEngineBase
+//
+
+CCdlEngineBase* CCdlEngineBase::Static()
+	{
+	return static_cast<CCdlEngineBase*>(Dll::Tls());
+	}
+
+CCdlEngineBase* CCdlEngineBase::NewLC()
+	{
+	CCdlEngineBase* self = new(ELeave) CCdlEngineBase;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+CCdlEngineBase* CCdlEngineBase::InstanceLC(TBool& aPushed)
+	{
+	aPushed = EFalse;
+	CCdlEngineBase* eng = CCdlEngineBase::Static();
+	if (!eng)
+		{
+		eng = CCdlEngineBase::NewLC();
+		aPushed = ETrue;
+		}
+	return eng;
+	}
+
+CCdlEngineBase::~CCdlEngineBase()
+	{
+	delete iLibMan;
+	Dll::SetTls(0);
+	}
+
+void CCdlEngineBase::IncRefCount()
+	{
+	iRefCount++;
+	}
+
+void CCdlEngineBase::DecRefCount()
+	{
+	iRefCount--;
+	if (iRefCount == 0)
+		delete this;
+	}
+
+CCdlEngineBase::CCdlEngineBase()
+	{
+	Dll::SetTls(this);
+	}
+
+void CCdlEngineBase::ConstructL()
+	{
+	iLibMan = new(ELeave) CCdlLibManager;
+	iLibMan->ConstructL();
+	}
+
+CCdlRefCollection* CCdlEngineBase::FileContentsLC(const TDesC& aLibName)
+	{
+	return CCdlLibraryContentsImp::NewLC(aLibName, this);
+	}
+
+CCdlLibManager* CCdlEngineBase::LibMan() const
+	{
+	return iLibMan;
+	}
+
+TInt CCdlEngineBase::IsPluginInRom(const TDesC& /*aFileName*/, TBool& /*aIsInRom*/) const
+	{
+	return KErrNotSupported;
+	}
+
+TInt CCdlEngineBase::PluginDrive(const TDesC& /*aFileName*/, TDriveUnit& /*aDrive*/) const
+    {
+	return KErrNotSupported;
+    }
+
+
+//
+// CCdlEngine
+//
+
+CCdlEngine* CCdlEngine::Static()
+	{
+	return static_cast<CCdlEngine*>(Dll::Tls());
+	}
+
+CCdlEngine* CCdlEngine::NewLC()
+	{
+	CCdlEngine* self = new(ELeave) CCdlEngine;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+CCdlEngine* CCdlEngine::InstanceLC(TBool& aPushed)
+	{
+	aPushed = EFalse;
+	CCdlEngine* eng = CCdlEngine::Static();
+	if (!eng)
+		{
+		eng = CCdlEngine::NewLC();
+		aPushed = ETrue;
+		}
+	return eng;
+	}
+
+CCdlEngine& CCdlEngine::Instance()
+	{
+	CCdlEngine* eng = CCdlEngine::Static();
+	__ASSERT_ALWAYS(eng, Panic(ECdlEngPanic_NoEngine));
+	return *eng;
+	}
+
+
+CCdlEngine::~CCdlEngine()
+	{
+	delete iChangeMonitor;
+	// Release the hash table
+	CCdlCustomisations::TIter iterator(iCustomisations);
+	while(iterator.NextKey())
+	{
+		CCdlCustomisationStack* stack = *(iterator.CurrentValue());
+		delete stack;
+	}
+	
+	iCustomisations.Close();
+	iServer.Close();
+	}
+
+TAny* CCdlEngine::GetData(TUid aCdlUid, TInt aApiId) const
+	{
+	return LookupP(aCdlUid).GetData(aApiId);
+	}
+
+TCdlEngineFunc* CCdlEngine::GetFunction(TUid aCdlUid, TInt aApiId) const
+	{
+	return LookupP(aCdlUid).GetFunction(aApiId);
+	}
+
+CCdlEngine::CCdlEngine()
+	{
+	}
+
+void CCdlEngine::ConstructL()
+	{
+	CCdlEngineBase::ConstructL();
+	User::LeaveIfError(iServer.Connect());
+	iChangeMonitor = new(ELeave) CCdlChangeMonitor(iServer, this);
+	}
+
+CCdlCustomisationStack* CCdlEngine::LookupOrCreateL(TUid aCdlUid)
+	{
+	CCdlCustomisationStack* stack = Lookup(aCdlUid);
+	if (!stack)
+		{
+		stack = CCdlCustomisationStack::NewLC(aCdlUid, this);
+		iCustomisations.InsertL(aCdlUid.iUid, stack);
+		CleanupStack::Pop(stack);
+		}
+	return stack;
+	}
+
+void CCdlEngine::RequireCustomisationL(const SCdlInterface* aInterfaceParams)
+	{
+	LookupOrCreateL(aInterfaceParams->iUid)->RequireCustomisationL(aInterfaceParams);
+	}
+
+void CCdlEngine::LoadCustomisationL(const TCdlRef& aRef)
+	{
+	LookupOrCreateL(aRef.iUid)->LoadCustomisationL(aRef);
+	}
+
+TBool CCdlEngine::IsCustomisationStarted(const SCdlInterface* aInterfaceParams) const
+	{
+	CCdlCustomisationStack* stack = Lookup(aInterfaceParams->iUid);
+	if (!stack)
+		return EFalse;
+	return stack->IsCustomisationStarted(aInterfaceParams);
+	}
+
+const CCdlInstance& CCdlEngine::CustomisationInstance(TUid aCdlUid) const
+	{
+	return LookupP(aCdlUid).Top();
+	}
+
+CCdlCustomisationStack* CCdlEngine::Lookup(TUid aCdlUid) const
+	{
+	CCdlCustomisationStack * const * stack = iCustomisations.Find(aCdlUid.iUid);
+	if(stack)
+		{
+		// Found from the hash map
+		return *stack;
+		}
+		
+	return NULL;
+	}
+
+CCdlCustomisationStack& CCdlEngine::LookupP(TUid aCdlUid) const
+	{
+	CCdlCustomisationStack* stack = Lookup(aCdlUid);
+	__ASSERT_ALWAYS(stack, Panic(ECdlEngPanic_CustomisationNotPresent));
+	return *stack;
+	}
+
+const CCdlInstance* CCdlEngine::LastAccessedInstance(TUid aCdlUid) const
+	{
+	return LookupP(aCdlUid).LastAccessedInstance();
+	}
+
+const TCdlRef& CCdlEngine::LastAccessedRef(TUid aCdlUid) const
+	{
+	return LastAccessedInstance(aCdlUid)->Ref();
+	}
+
+void CCdlEngine::FileNameRelativeToLastAccessedInstance(TUid aCdlUid, TFileName& aFileName) const
+	{
+	LastAccessedInstance(aCdlUid)->FileNameRelativeToLastAccessedInstance(aFileName);
+	}
+
+TInt CCdlEngine::LastApiId() const
+	{
+	return iLastApiId;
+	}
+
+CCdlRefs* CCdlEngine::FindInstancesLC(TUid aCdlUid) const
+	{
+	return iServer.FindInstancesLC(aCdlUid);
+	}
+
+CCdlRefCollection* CCdlEngine::FileContentsLC(const TDesC& aLibName)
+	{
+	return iServer.FileContentsLC(aLibName);
+	}
+
+CCdlNames* CCdlEngine::FindCustomisationFilesLC() const
+	{
+	return iServer.FindCustomisationFilesLC();
+	}
+
+CCdlRefs* CCdlEngine::AllAvailableRefsLC() const
+	{
+	return iServer.AllAvailableRefsLC();
+	}
+
+TInt CCdlEngine::IsPluginInRom(const TDesC& aFileName, TBool& aIsInRom) const
+	{
+	return iServer.IsPluginInRom(aFileName, aIsInRom);
+	}
+
+TInt CCdlEngine::PluginDrive(const TDesC& aFileName, TDriveUnit& aDrive) const
+    {
+	return iServer.PluginDrive(aFileName, aDrive);
+    }
+
+TInt* CCdlEngine::LastApiRefL(TUid aCdlUid)
+	{
+	CCdlCustomisationStack* stack = LookupOrCreateL(aCdlUid);
+	return stack->LastApiRef();
+	}
+
+void CCdlEngine::SetLocalStateL(const CCdlRefs& aState)
+	{
+	CCdlUids* uids = CCdlUids::NewLC();
+	TRAPD(err, DoSetLocalStateL(aState, *uids));
+	iObservers.HandleCustomisationChangeL(*uids);
+	CleanupStack::PopAndDestroy();
+	User::LeaveIfError(err);
+	}
+
+void CCdlEngine::DoSetLocalStateL(const CCdlRefs& aState, CCdlUids& aChangedUids)
+	{
+	CCdlUids* uids = aState.UidsLC();
+	TInt uidCount = uids->Count();
+	aChangedUids.ResizeL(uidCount, TUid::Uid(0));
+	for (TInt ii=0; ii<uidCount; ++ii)
+		{
+		TUid uid = uids->At(ii);
+		CCdlCustomisationStack* stack = LookupOrCreateL(uid);
+		stack->ClearOverrides();
+		aChangedUids[ii] = uid;
+		for (CCdlRefs::TIterator pRef = aState.Begin(uid); pRef != aState.End(); ++pRef)
+			{
+			stack->LoadCustomisationL(*pRef);
+			}
+		}
+	CleanupStack::PopAndDestroy(uids);
+	}
+
+void CCdlEngine::SetGlobalStateL(const CCdlRefs& aState)
+	{
+	HBufC8* buf = aState.ExportLC();
+	iServer.SetCustL(*buf);
+	CleanupStack::PopAndDestroy(buf);
+	}
+
+CCdlRefs* CCdlEngine::LocalStateLC(const CCdlUids& aCdlUids) const
+	{
+	CCdlRefs* state = CCdlRefs::NewLC();
+	TInt count = aCdlUids.Count();
+	for (TInt ii=0; ii<count; ii++)
+		{
+		TUid uid = aCdlUids[ii];
+		AddLocalStateToRefs(uid, state);
+		}
+	return state;
+	}
+
+void CCdlEngine::AddLocalStateToRefs(TUid aUid, CCdlRefs* aState) const
+	{
+	CCdlCustomisationStack* stack = Lookup(aUid);
+	if (stack)
+		{
+		const CCdlCustomisationStack::CStack& insts = stack->Stack();
+		TInt iCount = insts.Count();
+		for (TInt jj=0; jj<iCount; jj++)
+			{
+			aState->AppendL(insts[jj]->Ref());
+			}
+		}
+	}
+
+CCdlRefs* CCdlEngine::GlobalStateLC(const CCdlUids& aCdlUids) const
+	{
+	TInt size;
+	iServer.RequestGetCustL(aCdlUids, size);
+	return GlobalStateLC(size);
+	}
+
+CCdlRefs* CCdlEngine::GlobalStateLC(TInt aSize) const
+	{
+	const TInt KMaxRetries = 10;
+	CCdlRefs* state = CCdlRefs::NewLC();
+	HBufC8* buf = HBufC8::NewMaxLC(aSize);
+	TInt ii;
+	for (ii=0; ii<KMaxRetries; ii++)
+		{
+		TPtr8 ptr = buf->Des();
+		TInt err = iServer.GetCust(ptr, aSize);
+		if (err == KErrNone)
+			{
+			state->ImportL(ptr);
+			CleanupStack::PopAndDestroy(buf);
+			break;
+			}
+		else if (err == KCdlRefsSizeChanged)
+			{
+			CleanupStack::PopAndDestroy(buf);	// makes ptr invalid
+			buf = HBufC8::NewMaxLC(aSize);
+			}
+		else
+			{
+			User::Leave(err);
+			}
+		}
+
+	if (ii == KMaxRetries)
+		User::Leave(KErrNotReady);
+
+	return state;
+	}
+
+void CCdlEngine::EnableGlobalCustomisationL(const CCdlUids& aCdlUids, TBool aEnabled)
+	{
+	TInt count = aCdlUids.Count();
+	for (TInt ii=0; ii<count; ii++)
+		{
+		TUid uid = aCdlUids[ii];
+		CCdlCustomisationStack* stack = Lookup(uid);
+		if (stack)
+			{
+			stack->EnableGlobalCustomisation(aEnabled);
+			}
+		}
+	StartGlobalCustomisationL();
+	}
+
+void CCdlEngine::StartGlobalCustomisationL()
+	{
+	CCdlUids* add = CCdlUids::NewLC();
+	
+	CCdlCustomisations::TIter iterator(iCustomisations);
+	while(iterator.NextKey())
+		{
+		CCdlCustomisationStack* stack = *(iterator.CurrentValue());
+		TUid uid = stack->Uid();
+		TBool isEnabled = (iGloballyCustomised.FindIndex(uid) != KErrNotFound);
+		TBool reqEnabled = stack->GlobalCustomisationEnabled();
+		if (isEnabled && !reqEnabled)			// enabled, but not required -> remove
+			iGloballyCustomised.Remove(uid);
+		if (!isEnabled && reqEnabled)			// not enabled, but required -> add
+			add->AppendL(uid);
+		// other combinations of enabled & required need no action.
+		}
+
+	if (add->Count())
+		{
+		CCdlRefs* state = GlobalStateLC(*add);
+		SetLocalStateL(*state);
+		CleanupStack::PopAndDestroy(state);
+		iGloballyCustomised.AddL(*add);
+		}
+
+	iServer.SetUidsToNotifyL(iGloballyCustomised);
+
+	CleanupStack::PopAndDestroy(add);
+	}
+
+void CCdlEngine::HandleGlobalCustomisationChangeL(TInt aSize)
+	{
+	CCdlRefs* state = GlobalStateLC(aSize);
+	SetLocalStateL(*state);
+	CleanupStack::PopAndDestroy(state);
+	}
+
+void CCdlEngine::HandleAvailableRefsChangeL()
+	{
+	iObservers.HandleAvailableRefsChangeL();
+	}
+
+void CCdlEngine::AddCustomisationChangeObserverL(MCdlChangeObserver* aObserver, TUid aUid)
+	{
+	iObservers.AddCustomisationChangeObserverL(aObserver, aUid);
+	}
+
+void CCdlEngine::AddGeneralChangeObserverL(MCdlChangeObserver* aObserver)
+	{
+	iObservers.AddGeneralChangeObserverL(aObserver);
+	}
+
+void CCdlEngine::RemoveChangeObserver(MCdlChangeObserver* aObserver)
+	{
+	iObservers.RemoveChangeObserver(aObserver);
+	}
+
+
+//
+// CCdlLibraryContentsImp
+//
+
+CCdlLibraryContentsImp* CCdlLibraryContentsImp::NewLC(const TDesC& aLibName, CCdlEngineBase* aEngine)
+	{
+	CCdlLibraryContentsImp* self = new(ELeave) CCdlLibraryContentsImp();
+	CleanupStack::PushL(self);
+	self->ConstructL(aEngine, aLibName);
+	return self;
+	}
+
+CCdlLibraryContentsImp::~CCdlLibraryContentsImp()
+	{
+	iLib.Close();
+	}
+
+TInt CCdlLibraryContentsImp::CountRefs() const
+	{
+	return iContent.Count();
+	}
+
+TCdlRef CCdlLibraryContentsImp::Ref(TInt aIndex) const
+	{
+	const SCdlCustomisation& cust = iContent[aIndex];
+	TCdlRef ref = 
+		{
+		cust.iId, 
+		{ cust.iInterface->iUid.iUid }, 
+		iLib.Lib()->FullName()
+		};
+	return ref;
+	}
+
+void CCdlLibraryContentsImp::ConstructL(CCdlEngineBase* aEngine, const TDesC& aLibName)
+	{
+	CCdlLibManager* libMan = aEngine->LibMan();
+    RCdlLibrary* lib = libMan->FindLib(aLibName);
+	iLib = libMan->LoadL(aLibName, lib, EFalse);
+	iContent = iLib.Lib()->ContentsL();
+	}
+
+
+
+
+