uifw/AknGlobalUI/AknCapServer/src/ecompluginnotifier.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AknGlobalUI/AknCapServer/src/ecompluginnotifier.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,216 @@
+/*
+* 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:
+*
+*/
+/*
+* ============================================================================
+* TODO: Appropriate header needs to go here
+* ============================================================================
+*/
+
+#include <ecompluginnotifier.h>
+#include <coemain.h>
+
+
+EXPORT_C TEComPluginInfo::TEComPluginInfo(const TUid& aUid, const TInt aVersion, const TDriveUnit& aDrive)
+: iUid(aUid), iVersion(aVersion), iDrive(aDrive)
+	{
+	}
+
+
+
+CEComPluginNotifier::CEComPluginNotifier(const TUid& aInterfaceId, TCallBack& aCallBack)
+:CActive(EActivePriorityDefault), iInterfaceId(aInterfaceId), iCallBack(aCallBack)
+	{
+	// TODO: What happens if this fails?
+	CActiveScheduler::Add(this);
+	}
+
+
+void CEComPluginNotifier::ConstructL()
+	{
+	iEComSession = &REComSession::OpenL();
+	}
+
+
+CEComPluginNotifier::~CEComPluginNotifier()
+	{
+	Cancel();
+	if (iEComSession)
+		{
+		iEComSession->Close();
+		iEComSession = NULL;
+		}
+	iPreviousPlugins.Reset();
+	}
+
+
+EXPORT_C CEComPluginNotifier* CEComPluginNotifier::NewL(const TUid& iInterfaceId, TCallBack& aCallBack)
+	{
+	CEComPluginNotifier* self = CEComPluginNotifier::NewLC(iInterfaceId, aCallBack);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+EXPORT_C CEComPluginNotifier* CEComPluginNotifier::NewLC(const TUid& iInterfaceId, TCallBack& aCallBack)
+	{
+	CEComPluginNotifier* self = new (ELeave) CEComPluginNotifier(iInterfaceId, aCallBack);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+
+EXPORT_C void CEComPluginNotifier::Start()
+	{
+	// Load initial list of plugins for the UID
+	if(iInterfaceId.iUid != 0)
+		EComPluginUtils::GetInfoArrayL(iInterfaceId, iPreviousPlugins);
+	
+	if (!IsActive())
+		{
+		iEComSession->NotifyOnChange(iStatus);
+		SetActive();
+		}
+	}
+
+	
+void CEComPluginNotifier::RunL()
+	{
+	// TODO: Should the client be notified if there was an error?
+	if (iStatus.Int() == KErrNone )
+		{
+		if(iInterfaceId.iUid == 0)
+			{
+			RunCallBack();
+			}
+		else
+			{
+			TRAP_IGNORE(CheckForEComPluginChangeL())
+			}
+		// TODO: Should this be outside the if? What if there was a connection error?
+		Start();
+		}
+	}
+
+	
+void CEComPluginNotifier::DoCancel()
+	{
+	iEComSession->CancelNotifyOnChange(iStatus);
+	}
+	
+	
+void CEComPluginNotifier::CheckForEComPluginChangeL()
+	{
+	// TODO: Deal with errors here
+	REComPluginInfoArray newPlugins;
+	EComPluginUtils::GetInfoArrayL(iInterfaceId, newPlugins);
+	
+	TBool pluginsChanged = EFalse;
+	
+	TInt prevCount = iPreviousPlugins.Count();
+	TInt newCount = newPlugins.Count();
+	
+	if(newCount != prevCount)
+		{
+		pluginsChanged = ETrue;
+		}
+	else
+		{
+		while(prevCount>0)
+			{
+			prevCount--;
+			
+			TUid prevUid = (iPreviousPlugins[prevCount]).iUid;
+			TInt prevVer = (iPreviousPlugins[prevCount]).iVersion;
+			TBool found = EFalse;
+			
+			newCount = newPlugins.Count();
+			while(newCount>0)
+				{
+				newCount--;
+				TUid newUid = (newPlugins[newCount]).iUid;
+				TInt newVer = (newPlugins[newCount]).iVersion;
+				if(prevUid == newUid && prevVer == newVer)
+					{
+					found = ETrue;
+					}
+				}
+			
+			if(!found)
+				{
+				pluginsChanged = ETrue;
+				break;
+				}
+			}
+		}
+	
+	if(pluginsChanged)
+		{
+		RunCallBack();
+		}
+	
+	iPreviousPlugins.Reset();
+	iPreviousPlugins = newPlugins;
+	}
+
+
+void CEComPluginNotifier::RunCallBack()
+	{
+	(iCallBack.iFunction)(iCallBack.iPtr);
+	}
+
+
+
+// a kind of cleanup item for ecom info array
+NONSHARABLE_CLASS(CCleanupEComArray) : public CBase
+    {
+public:
+    ~CCleanupEComArray()
+        {
+        iArray.ResetAndDestroy();
+        iArray.Close();
+        }
+    RImplInfoPtrArray iArray;
+    };
+
+/**
+ * Reusable utility functions from here, exported as static functions
+ * of CEComPluginUtils
+ **/ 
+EXPORT_C TInt EComPluginUtils::GetInfoArrayL(const TUid aInterfaceId, REComPluginInfoArray& aReturnArray)
+	{
+	CCleanupEComArray* plugins = new (ELeave) CCleanupEComArray;
+	CleanupStack::PushL(plugins);
+	REComSession::ListImplementationsL(aInterfaceId, plugins->iArray);
+	CreateInfoArray(plugins->iArray, aReturnArray);
+	CleanupStack::PopAndDestroy(plugins);
+	return KErrNone;
+	}
+
+
+EXPORT_C TInt EComPluginUtils::CreateInfoArray(const RImplInfoPtrArray aEComArray, REComPluginInfoArray& aReturnArray)
+	{
+	for(TInt i=0; i<aEComArray.Count(); i++)
+		{
+		TUid uid = (aEComArray[i])->ImplementationUid();
+		TInt ver = (aEComArray[i])->Version();
+		TDriveUnit drive = (aEComArray[i])->Drive();
+		TEComPluginInfo info(uid, ver, drive);
+		aReturnArray.Append(info);
+		}
+	return KErrNone;
+	}