diff -r 000000000000 -r 2f259fa3e83a uifw/AknGlobalUI/AknCapServer/src/ecompluginnotifier.cpp --- /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 +#include + + +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; iImplementationUid(); + TInt ver = (aEComArray[i])->Version(); + TDriveUnit drive = (aEComArray[i])->Drive(); + TEComPluginInfo info(uid, ver, drive); + aReturnArray.Append(info); + } + return KErrNone; + }