diff -r 000000000000 -r eb1f2e154e89 fep/frontendprocessor/test/src/FepSwitch.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fep/frontendprocessor/test/src/FepSwitch.cpp Tue Feb 02 01:02:04 2010 +0200 @@ -0,0 +1,420 @@ +// Copyright (c) 2005-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 +#include +#include +#include +#include +#include +#include +#include + +class CFepKeyDataListener; + +const TUid KFepSwitchAppUid = {0xfabbabba}; // fake uid + +// class definitions + +class CFepSwitcher : public CActive + { +public: + static CFepSwitcher* NewLC(); + virtual ~CFepSwitcher(); + void SetOnOrOffKeyDataL(TInt aError, const TFepOnOrOffKeyData& aNewKeyData, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo); + void RetryFailedKeyCaptures(TBool& aNeedFurtherRetry); +private: + class CRetryOnError : public CTimer + { + public: + static CRetryOnError* NewL(CFepSwitcher& aFepSwitcher); + virtual ~CRetryOnError(); + void Activate(); + private: + CRetryOnError(CFepSwitcher& aFepSwitcher); + void DoActivate(); + // from CActive (via CTimer) + virtual void RunL(); + private: + CFepSwitcher& iFepSwitcher; + TInt iRetryCount; + }; +private: + CFepSwitcher(); + void ConstructL(); + void Queue(); + static TBool MatchesKeyData(const TKeyEvent& aKeyEvent, const TFepOnOrOffKeyData& aKeyData); + // from CActive + virtual void DoCancel(); + virtual void RunL(); +private: + TUint iFlags; + TInt32 iOnKey_CaptureKeyHandleOrError; + TInt32 iOffKey_CaptureKeyHandleOrError; // a capture-key handle + RWsSession iWsSession; + RWindowGroup iWindowGroup; + CFepGenericGlobalSettings* iFepGenericGlobalSettings; + CRetryOnError* iRetryOnError; + TFepOnOrOffKeyData iOnKeyData; + TFepOnOrOffKeyData iOffKeyData; + CFepKeyDataListener* iFepKeyDataListener_OnKey; + CFepKeyDataListener* iFepKeyDataListener_OffKey; + }; + +class CFepKeyDataListener : public CActive + { +public: + static CFepKeyDataListener* NewLC(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo); + virtual ~CFepKeyDataListener(); +private: + CFepKeyDataListener(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo); + void ConstructL(); + void SetFepSwitcherL(); + void Queue(); + // from CActive + virtual void DoCancel(); + virtual void RunL(); +private: + CFepSwitcher& iFepSwitcher; + const TUint32 iRepositoryKeyMask_OnOrOff; + CRepository* iRepository; + TInt32 CFepSwitcher::* const iCaptureKeyHandleOrError; + TFepOnOrOffKeyData CFepSwitcher::* const iKeyDataToAssignTo; + }; + +// CFepSwitcher + +CFepSwitcher* CFepSwitcher::NewLC() + { + CFepSwitcher* const self=new(ELeave) CFepSwitcher; + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CFepSwitcher::~CFepSwitcher() + { + Cancel(); + if (iWindowGroup.WsHandle()!=0) + { + if (iOnKey_CaptureKeyHandleOrError>0) + { + iWindowGroup.CancelCaptureKey(iOnKey_CaptureKeyHandleOrError); + } + if (iOffKey_CaptureKeyHandleOrError>0) + { + iWindowGroup.CancelCaptureKey(iOffKey_CaptureKeyHandleOrError); + } + iWindowGroup.Close(); + } + iWsSession.Close(); + delete iFepGenericGlobalSettings; + delete iRetryOnError; + delete iFepKeyDataListener_OnKey; + delete iFepKeyDataListener_OffKey; + } + +void CFepSwitcher::SetOnOrOffKeyDataL(TInt aError, const TFepOnOrOffKeyData& aNewKeyData, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo) + { + // change the state of this object + TInt32& captureKeyHandleOrError=this->*aCaptureKeyHandleOrError; + TInt32 captureKeyToCancel=0; + if (aError!=KErrNone) + { + captureKeyToCancel=captureKeyHandleOrError; + captureKeyHandleOrError=0; + } + else if (this->*aKeyDataToAssignTo!=aNewKeyData) + { + this->*aKeyDataToAssignTo=aNewKeyData; + captureKeyToCancel=captureKeyHandleOrError; + captureKeyHandleOrError=iWindowGroup.CaptureKey(aNewKeyData.CharacterCodeForFoldedMatch(), aNewKeyData.ModifierMask(), aNewKeyData.ModifierValues()); + } + if (captureKeyToCancel>0) + { + iWindowGroup.CancelCaptureKey(captureKeyToCancel); + } + + // kick-off or stop iRetryOnError, if need be + if ((iOnKey_CaptureKeyHandleOrError>=0) && (iOffKey_CaptureKeyHandleOrError>=0)) + { + iRetryOnError->Cancel(); + } + else if (!iRetryOnError->IsActive()) + { + iRetryOnError->Activate(); + } + } + +void CFepSwitcher::RetryFailedKeyCaptures(TBool& aNeedFurtherRetry) + { + __ASSERT_DEBUG((iOnKey_CaptureKeyHandleOrError<0) || (iOffKey_CaptureKeyHandleOrError<0), User::Invariant()); + if (iOnKey_CaptureKeyHandleOrError<0) + { + iOnKey_CaptureKeyHandleOrError=iWindowGroup.CaptureKey(iOnKeyData.CharacterCodeForFoldedMatch(), iOnKeyData.ModifierMask(), iOnKeyData.ModifierValues()); + } + if (iOffKey_CaptureKeyHandleOrError<0) + { + iOffKey_CaptureKeyHandleOrError=iWindowGroup.CaptureKey(iOffKeyData.CharacterCodeForFoldedMatch(), iOffKeyData.ModifierMask(), iOffKeyData.ModifierValues()); + } + aNeedFurtherRetry=((iOnKey_CaptureKeyHandleOrError<0) || (iOffKey_CaptureKeyHandleOrError<0)); + } + +CFepSwitcher::CFepSwitcher() + :CActive(EPriorityStandard), + iFlags(0), + iOnKey_CaptureKeyHandleOrError(0), + iOffKey_CaptureKeyHandleOrError(0), + iFepGenericGlobalSettings(NULL), + iRetryOnError(NULL), + iOnKeyData(0, 0, 0), + iOffKeyData(0, 0, 0), + iFepKeyDataListener_OnKey(NULL), + iFepKeyDataListener_OffKey(NULL) + { + CActiveScheduler::Add(this); + } + +void CFepSwitcher::ConstructL() + { + User::LeaveIfError(iWsSession.Connect()); + iWindowGroup=RWindowGroup(iWsSession); + User::LeaveIfError(iWindowGroup.Construct(REINTERPRET_CAST(TUint32, this), EFalse)); + CApaWindowGroupName* wgName=CApaWindowGroupName::NewLC(iWsSession,iWindowGroup.Identifier()); + wgName->SetHidden(ETrue); + wgName->SetAppUid(KFepSwitchAppUid); + wgName->SetWindowGroupName(iWindowGroup); + CleanupStack::PopAndDestroy(wgName); + iFepGenericGlobalSettings=CFepGenericGlobalSettings::NewL(); + iRetryOnError=CRetryOnError::NewL(*this); + iFepKeyDataListener_OnKey=CFepKeyDataListener::NewLC(*this, ERepositoryKeyMask_OnKeyData, &CFepSwitcher::iOnKey_CaptureKeyHandleOrError, &CFepSwitcher::iOnKeyData); + iFepKeyDataListener_OffKey=CFepKeyDataListener::NewLC(*this, ERepositoryKeyMask_OffKeyData, &CFepSwitcher::iOffKey_CaptureKeyHandleOrError, &CFepSwitcher::iOffKeyData); + Queue(); + } + +void CFepSwitcher::Queue() + { + iWsSession.EventReady(&iStatus); + SetActive(); + } + +TBool CFepSwitcher::MatchesKeyData(const TKeyEvent& aKeyEvent, const TFepOnOrOffKeyData& aKeyData) + { // static + return ((User::Fold(aKeyEvent.iCode)==User::Fold(aKeyData.CharacterCodeForFoldedMatch())) && + ((aKeyEvent.iModifiers&aKeyData.ModifierMask())==aKeyData.ModifierValues())); + } + +void CFepSwitcher::DoCancel() + { + iWsSession.EventReadyCancel(); + } + +void CFepSwitcher::RunL() + { + const TInt error=iStatus.Int(); + if (errorIsOn(); + const TKeyEvent& keyEvent=*event.Key(); + if ((!isOn) && MatchesKeyData(keyEvent, iOnKeyData)) + { + iFepGenericGlobalSettings->SetIsOn(ETrue); + iFepGenericGlobalSettings->StoreChangesAndBroadcastL(); + } + else if (isOn && MatchesKeyData(keyEvent, iOffKeyData)) + { + iFepGenericGlobalSettings->SetIsOn(EFalse); + iFepGenericGlobalSettings->StoreChangesAndBroadcastL(); + } + } + } + +// CFepSwitcher::CRetryOnError + +CFepSwitcher::CRetryOnError* CFepSwitcher::CRetryOnError::NewL(CFepSwitcher& aFepSwitcher) + { // static + CRetryOnError* const self=new(ELeave) CRetryOnError(aFepSwitcher); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CFepSwitcher::CRetryOnError::~CRetryOnError() + { + Cancel(); + } + +void CFepSwitcher::CRetryOnError::Activate() + { + iRetryCount=0; + DoActivate(); + } + +CFepSwitcher::CRetryOnError::CRetryOnError(CFepSwitcher& aFepSwitcher) + :CTimer(EPriorityStandard+1), + iFepSwitcher(aFepSwitcher) + { + CActiveScheduler::Add(this); + } + +void CFepSwitcher::CRetryOnError::DoActivate() + { + // retry every second for a minute, followed by every minute for an hour, followed by every hour + TInt timeInterval=1000000; + if (iRetryCount>=120) + { + timeInterval*=(60*60); // up it to every hour + } + else if (iRetryCount>=60) + { + timeInterval*=60; // up it to every minute + } + After(TTimeIntervalMicroSeconds32(timeInterval)); + } + +void CFepSwitcher::CRetryOnError::RunL() + { + const TInt error=iStatus.Int(); + TBool needFurtherRetry=ETrue; + iFepSwitcher.RetryFailedKeyCaptures(needFurtherRetry); + if (needFurtherRetry) + { + ++iRetryCount; + DoActivate(); + } + User::LeaveIfError(error); + } + +// CFepKeyDataListener + +CFepKeyDataListener* CFepKeyDataListener::NewLC(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo) + { + CFepKeyDataListener* const self=new(ELeave) CFepKeyDataListener(aFepSwitcher, aRepositoryKeyMask_OnOrOff, aCaptureKeyHandleOrError, aKeyDataToAssignTo); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CFepKeyDataListener::~CFepKeyDataListener() + { + Cancel(); + delete iRepository; + } + +CFepKeyDataListener::CFepKeyDataListener(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo) + :CActive(EPriorityStandard-1), + iFepSwitcher(aFepSwitcher), + iRepositoryKeyMask_OnOrOff(aRepositoryKeyMask_OnOrOff), + iRepository(NULL), + iCaptureKeyHandleOrError(aCaptureKeyHandleOrError), + iKeyDataToAssignTo(aKeyDataToAssignTo) + { + CActiveScheduler::Add(this); + } + +void CFepKeyDataListener::ConstructL() + { + iRepository=CRepository::NewL(TUid::Uid(KUidFepFrameworkRepository)); + SetFepSwitcherL(); + Queue(); + } + +void CFepKeyDataListener::SetFepSwitcherL() + { + TFepOnOrOffKeyData onOrOffKeyData(0, 0, 0); + TInt error=KErrNone; + CFepGenericGlobalSettings::ReadOnOrOffKeyData(*iRepository, onOrOffKeyData, iRepositoryKeyMask_OnOrOff, &error); + iFepSwitcher.SetOnOrOffKeyDataL(error, onOrOffKeyData, iCaptureKeyHandleOrError, iKeyDataToAssignTo); + } + +void CFepKeyDataListener::Queue() + { +#if defined(_DEBUG) + const TInt error= +#endif + iRepository->NotifyRequest(iRepositoryKeyMask_OnOrOff, ERepositoryKeyMask_OnKeyData|ERepositoryKeyMask_OffKeyData, iStatus); + __ASSERT_DEBUG(error==KErrNone, User::Invariant()); + SetActive(); + } + +void CFepKeyDataListener::DoCancel() + { + iRepository->NotifyCancel(iRepositoryKeyMask_OnOrOff, ERepositoryKeyMask_OnKeyData|ERepositoryKeyMask_OffKeyData); + } + +void CFepKeyDataListener::RunL() + { + const TInt error=iStatus.Int(); + Queue(); + User::LeaveIfError(error); + SetFepSwitcherL(); + } + +// CNonPanickingScheduler + +class CNonPanickingScheduler : public CActiveScheduler + { +public: + static CNonPanickingScheduler* NewLC(); +private: + // from CActiveScheduler + virtual void Error(TInt aError) const; + }; + +CNonPanickingScheduler* CNonPanickingScheduler::NewLC() + { // static + CNonPanickingScheduler* const scheduler=new(ELeave) CNonPanickingScheduler; + CleanupStack::PushL(scheduler); + return scheduler; + } + +void CNonPanickingScheduler::Error(TInt) const + { + // don't panic here, like CActiveScheduler::Error does + } + +// top-level functions + +LOCAL_C void MainL() + { + CActiveScheduler* const activeScheduler=CNonPanickingScheduler::NewLC(); + CActiveScheduler::Install(activeScheduler); + CFepSwitcher* const fepSwitcher=CFepSwitcher::NewLC(); + RProcess::Rendezvous(KErrNone); + CActiveScheduler::Start(); + CleanupStack::PopAndDestroy(2, activeScheduler); + } + +GLDEF_C TInt E32Main() + { + CTrapCleanup* const cleanup=CTrapCleanup::New(); + if(cleanup == NULL) + { + return KErrNoMemory; + } + TRAPD(error, MainL()); + delete cleanup; + return error; + } +