fep/frontendprocessor/test/src/FepSwitch.cpp
changeset 0 eb1f2e154e89
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32std.h>
       
    17 #include <e32keys.h>
       
    18 #include <centralrepository.h>
       
    19 #include <w32std.h>
       
    20 #include <coedef.h>
       
    21 #include <fepbase.h>
       
    22 #include <apgwgnam.h>
       
    23 #include <graphics/cone/coedefkeys.h>
       
    24 
       
    25 class CFepKeyDataListener;
       
    26 
       
    27 const TUid KFepSwitchAppUid = {0xfabbabba}; // fake uid
       
    28 
       
    29 // class definitions
       
    30 
       
    31 class CFepSwitcher : public CActive
       
    32 	{
       
    33 public:
       
    34 	static CFepSwitcher* NewLC();
       
    35 	virtual ~CFepSwitcher();
       
    36 	void SetOnOrOffKeyDataL(TInt aError, const TFepOnOrOffKeyData& aNewKeyData, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo);
       
    37 	void RetryFailedKeyCaptures(TBool& aNeedFurtherRetry);
       
    38 private:
       
    39 	class CRetryOnError : public CTimer
       
    40 		{
       
    41 	public:
       
    42 		static CRetryOnError* NewL(CFepSwitcher& aFepSwitcher);
       
    43 		virtual ~CRetryOnError();
       
    44 		void Activate();
       
    45 	private:
       
    46 		CRetryOnError(CFepSwitcher& aFepSwitcher);
       
    47 		void DoActivate();
       
    48 		// from CActive (via CTimer)
       
    49 		virtual void RunL();
       
    50 	private:
       
    51 		CFepSwitcher& iFepSwitcher;
       
    52 		TInt iRetryCount;
       
    53 		};
       
    54 private:
       
    55 	CFepSwitcher();
       
    56 	void ConstructL();
       
    57 	void Queue();
       
    58 	static TBool MatchesKeyData(const TKeyEvent& aKeyEvent, const TFepOnOrOffKeyData& aKeyData);
       
    59 	// from CActive
       
    60 	virtual void DoCancel();
       
    61 	virtual void RunL();
       
    62 private:
       
    63 	TUint iFlags;
       
    64 	TInt32 iOnKey_CaptureKeyHandleOrError;
       
    65 	TInt32 iOffKey_CaptureKeyHandleOrError; // a capture-key handle
       
    66 	RWsSession iWsSession;
       
    67 	RWindowGroup iWindowGroup;
       
    68 	CFepGenericGlobalSettings* iFepGenericGlobalSettings;
       
    69 	CRetryOnError* iRetryOnError;
       
    70 	TFepOnOrOffKeyData iOnKeyData;
       
    71 	TFepOnOrOffKeyData iOffKeyData;
       
    72 	CFepKeyDataListener* iFepKeyDataListener_OnKey;
       
    73 	CFepKeyDataListener* iFepKeyDataListener_OffKey;
       
    74 	};
       
    75 
       
    76 class CFepKeyDataListener : public CActive
       
    77 	{
       
    78 public:
       
    79 	static CFepKeyDataListener* NewLC(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo);
       
    80 	virtual ~CFepKeyDataListener();
       
    81 private:
       
    82 	CFepKeyDataListener(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo);
       
    83 	void ConstructL();
       
    84 	void SetFepSwitcherL();
       
    85 	void Queue();
       
    86 	// from CActive
       
    87 	virtual void DoCancel();
       
    88 	virtual void RunL();
       
    89 private:
       
    90 	CFepSwitcher& iFepSwitcher;
       
    91 	const TUint32 iRepositoryKeyMask_OnOrOff;
       
    92 	CRepository* iRepository;
       
    93 	TInt32 CFepSwitcher::* const iCaptureKeyHandleOrError;
       
    94 	TFepOnOrOffKeyData CFepSwitcher::* const iKeyDataToAssignTo;
       
    95 	};
       
    96 
       
    97 // CFepSwitcher
       
    98 
       
    99 CFepSwitcher* CFepSwitcher::NewLC()
       
   100 	{
       
   101 	CFepSwitcher* const self=new(ELeave) CFepSwitcher;
       
   102 	CleanupStack::PushL(self);
       
   103 	self->ConstructL();
       
   104 	return self;
       
   105 	}
       
   106 
       
   107 CFepSwitcher::~CFepSwitcher()
       
   108 	{
       
   109 	Cancel();
       
   110 	if (iWindowGroup.WsHandle()!=0)
       
   111 		{
       
   112 		if (iOnKey_CaptureKeyHandleOrError>0)
       
   113 			{
       
   114 			iWindowGroup.CancelCaptureKey(iOnKey_CaptureKeyHandleOrError);
       
   115 			}
       
   116 		if (iOffKey_CaptureKeyHandleOrError>0)
       
   117 			{
       
   118 			iWindowGroup.CancelCaptureKey(iOffKey_CaptureKeyHandleOrError);
       
   119 			}
       
   120 		iWindowGroup.Close();
       
   121 		}
       
   122 	iWsSession.Close();
       
   123 	delete iFepGenericGlobalSettings;
       
   124 	delete iRetryOnError;
       
   125 	delete iFepKeyDataListener_OnKey;
       
   126 	delete iFepKeyDataListener_OffKey;
       
   127 	}
       
   128 
       
   129 void CFepSwitcher::SetOnOrOffKeyDataL(TInt aError, const TFepOnOrOffKeyData& aNewKeyData, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo)
       
   130 	{
       
   131 	// change the state of this object
       
   132 	TInt32& captureKeyHandleOrError=this->*aCaptureKeyHandleOrError;
       
   133 	TInt32 captureKeyToCancel=0;
       
   134 	if (aError!=KErrNone)
       
   135 		{
       
   136 		captureKeyToCancel=captureKeyHandleOrError;
       
   137 		captureKeyHandleOrError=0;
       
   138 		}
       
   139 	else if (this->*aKeyDataToAssignTo!=aNewKeyData)
       
   140 		{
       
   141 		this->*aKeyDataToAssignTo=aNewKeyData;
       
   142 		captureKeyToCancel=captureKeyHandleOrError;
       
   143 		captureKeyHandleOrError=iWindowGroup.CaptureKey(aNewKeyData.CharacterCodeForFoldedMatch(), aNewKeyData.ModifierMask(), aNewKeyData.ModifierValues());
       
   144 		}
       
   145 	if (captureKeyToCancel>0)
       
   146 		{
       
   147 		iWindowGroup.CancelCaptureKey(captureKeyToCancel);
       
   148 		}
       
   149 
       
   150 	// kick-off or stop iRetryOnError, if need be
       
   151 	if ((iOnKey_CaptureKeyHandleOrError>=0) && (iOffKey_CaptureKeyHandleOrError>=0))
       
   152 		{
       
   153 		iRetryOnError->Cancel();
       
   154 		}
       
   155 	else if (!iRetryOnError->IsActive())
       
   156 		{
       
   157 		iRetryOnError->Activate();
       
   158 		}
       
   159 	}
       
   160 
       
   161 void CFepSwitcher::RetryFailedKeyCaptures(TBool& aNeedFurtherRetry)
       
   162 	{
       
   163 	__ASSERT_DEBUG((iOnKey_CaptureKeyHandleOrError<0) || (iOffKey_CaptureKeyHandleOrError<0), User::Invariant());
       
   164 	if (iOnKey_CaptureKeyHandleOrError<0)
       
   165 		{
       
   166 		iOnKey_CaptureKeyHandleOrError=iWindowGroup.CaptureKey(iOnKeyData.CharacterCodeForFoldedMatch(), iOnKeyData.ModifierMask(), iOnKeyData.ModifierValues());
       
   167 		}
       
   168 	if (iOffKey_CaptureKeyHandleOrError<0)
       
   169 		{
       
   170 		iOffKey_CaptureKeyHandleOrError=iWindowGroup.CaptureKey(iOffKeyData.CharacterCodeForFoldedMatch(), iOffKeyData.ModifierMask(), iOffKeyData.ModifierValues());
       
   171 		}
       
   172 	aNeedFurtherRetry=((iOnKey_CaptureKeyHandleOrError<0) || (iOffKey_CaptureKeyHandleOrError<0));
       
   173 	}
       
   174 
       
   175 CFepSwitcher::CFepSwitcher()
       
   176 	:CActive(EPriorityStandard),
       
   177 	 iFlags(0),
       
   178 	 iOnKey_CaptureKeyHandleOrError(0),
       
   179 	 iOffKey_CaptureKeyHandleOrError(0),
       
   180 	 iFepGenericGlobalSettings(NULL),
       
   181 	 iRetryOnError(NULL),
       
   182 	 iOnKeyData(0, 0, 0),
       
   183 	 iOffKeyData(0, 0, 0),
       
   184 	 iFepKeyDataListener_OnKey(NULL),
       
   185 	 iFepKeyDataListener_OffKey(NULL)
       
   186 	{
       
   187 	CActiveScheduler::Add(this);
       
   188 	}
       
   189 
       
   190 void CFepSwitcher::ConstructL()
       
   191 	{
       
   192 	User::LeaveIfError(iWsSession.Connect());
       
   193 	iWindowGroup=RWindowGroup(iWsSession);
       
   194 	User::LeaveIfError(iWindowGroup.Construct(REINTERPRET_CAST(TUint32, this), EFalse));
       
   195 	CApaWindowGroupName* wgName=CApaWindowGroupName::NewLC(iWsSession,iWindowGroup.Identifier());
       
   196  	wgName->SetHidden(ETrue);
       
   197  	wgName->SetAppUid(KFepSwitchAppUid);
       
   198 	wgName->SetWindowGroupName(iWindowGroup);
       
   199  	CleanupStack::PopAndDestroy(wgName);
       
   200 	iFepGenericGlobalSettings=CFepGenericGlobalSettings::NewL();
       
   201 	iRetryOnError=CRetryOnError::NewL(*this);
       
   202 	iFepKeyDataListener_OnKey=CFepKeyDataListener::NewLC(*this, ERepositoryKeyMask_OnKeyData, &CFepSwitcher::iOnKey_CaptureKeyHandleOrError, &CFepSwitcher::iOnKeyData);
       
   203 	iFepKeyDataListener_OffKey=CFepKeyDataListener::NewLC(*this, ERepositoryKeyMask_OffKeyData, &CFepSwitcher::iOffKey_CaptureKeyHandleOrError, &CFepSwitcher::iOffKeyData);
       
   204 	Queue();
       
   205 	}
       
   206 
       
   207 void CFepSwitcher::Queue()
       
   208 	{
       
   209 	iWsSession.EventReady(&iStatus);
       
   210 	SetActive();
       
   211 	}
       
   212 
       
   213 TBool CFepSwitcher::MatchesKeyData(const TKeyEvent& aKeyEvent, const TFepOnOrOffKeyData& aKeyData)
       
   214 	{ // static
       
   215 	return ((User::Fold(aKeyEvent.iCode)==User::Fold(aKeyData.CharacterCodeForFoldedMatch())) &&
       
   216 			((aKeyEvent.iModifiers&aKeyData.ModifierMask())==aKeyData.ModifierValues()));
       
   217 	}
       
   218 
       
   219 void CFepSwitcher::DoCancel()
       
   220 	{
       
   221 	iWsSession.EventReadyCancel();
       
   222 	}
       
   223 
       
   224 void CFepSwitcher::RunL()
       
   225 	{
       
   226 	const TInt error=iStatus.Int();
       
   227 	if (error<KErrNone)
       
   228 		{
       
   229 		Queue();
       
   230 		User::Leave(error);
       
   231 		}
       
   232 	TWsEvent event;
       
   233 	iWsSession.GetEvent(event); // need to call this *before* Queue (which calls iWsSession.EventReady), otherwise Wserv panics us
       
   234 	Queue();
       
   235 	if (event.Type()==EEventKey)
       
   236 		{
       
   237 		const TBool isOn=iFepGenericGlobalSettings->IsOn();
       
   238 		const TKeyEvent& keyEvent=*event.Key();
       
   239 		if ((!isOn) && MatchesKeyData(keyEvent, iOnKeyData))
       
   240 			{
       
   241 			iFepGenericGlobalSettings->SetIsOn(ETrue);
       
   242 			iFepGenericGlobalSettings->StoreChangesAndBroadcastL();
       
   243 			}
       
   244 		else if (isOn && MatchesKeyData(keyEvent, iOffKeyData))
       
   245 			{
       
   246 			iFepGenericGlobalSettings->SetIsOn(EFalse);
       
   247 			iFepGenericGlobalSettings->StoreChangesAndBroadcastL();
       
   248 			}
       
   249 		}
       
   250 	}
       
   251 
       
   252 // CFepSwitcher::CRetryOnError
       
   253 
       
   254 CFepSwitcher::CRetryOnError* CFepSwitcher::CRetryOnError::NewL(CFepSwitcher& aFepSwitcher)
       
   255 	{ // static
       
   256 	CRetryOnError* const self=new(ELeave) CRetryOnError(aFepSwitcher);
       
   257 	CleanupStack::PushL(self);
       
   258 	self->ConstructL();
       
   259 	CleanupStack::Pop(self);
       
   260 	return self;
       
   261 	}
       
   262 
       
   263 CFepSwitcher::CRetryOnError::~CRetryOnError()
       
   264 	{
       
   265 	Cancel();
       
   266 	}
       
   267 
       
   268 void CFepSwitcher::CRetryOnError::Activate()
       
   269 	{
       
   270 	iRetryCount=0;
       
   271 	DoActivate();
       
   272 	}
       
   273 
       
   274 CFepSwitcher::CRetryOnError::CRetryOnError(CFepSwitcher& aFepSwitcher)
       
   275 	:CTimer(EPriorityStandard+1),
       
   276 	 iFepSwitcher(aFepSwitcher)
       
   277 	{
       
   278 	CActiveScheduler::Add(this);
       
   279 	}
       
   280 
       
   281 void CFepSwitcher::CRetryOnError::DoActivate()
       
   282 	{
       
   283 	// retry every second for a minute, followed by every minute for an hour, followed by every hour
       
   284 	TInt timeInterval=1000000;
       
   285 	if (iRetryCount>=120)
       
   286 		{
       
   287 		timeInterval*=(60*60); // up it to every hour
       
   288 		}
       
   289 	else if (iRetryCount>=60)
       
   290 		{
       
   291 		timeInterval*=60; // up it to every minute
       
   292 		}
       
   293 	After(TTimeIntervalMicroSeconds32(timeInterval));
       
   294 	}
       
   295 
       
   296 void CFepSwitcher::CRetryOnError::RunL()
       
   297 	{
       
   298 	const TInt error=iStatus.Int();
       
   299 	TBool needFurtherRetry=ETrue;
       
   300 	iFepSwitcher.RetryFailedKeyCaptures(needFurtherRetry);
       
   301 	if (needFurtherRetry)
       
   302 		{
       
   303 		++iRetryCount;
       
   304 		DoActivate();
       
   305 		}
       
   306 	User::LeaveIfError(error);
       
   307 	}
       
   308 
       
   309 // CFepKeyDataListener
       
   310 
       
   311 CFepKeyDataListener* CFepKeyDataListener::NewLC(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo)
       
   312 	{
       
   313 	CFepKeyDataListener* const self=new(ELeave) CFepKeyDataListener(aFepSwitcher, aRepositoryKeyMask_OnOrOff, aCaptureKeyHandleOrError, aKeyDataToAssignTo);
       
   314 	CleanupStack::PushL(self);
       
   315 	self->ConstructL();
       
   316 	return self;
       
   317 	}
       
   318 
       
   319 CFepKeyDataListener::~CFepKeyDataListener()
       
   320 	{
       
   321 	Cancel();
       
   322 	delete iRepository;
       
   323 	}
       
   324 
       
   325 CFepKeyDataListener::CFepKeyDataListener(CFepSwitcher& aFepSwitcher, TUint32 aRepositoryKeyMask_OnOrOff, TInt32 CFepSwitcher::* aCaptureKeyHandleOrError, TFepOnOrOffKeyData CFepSwitcher::* aKeyDataToAssignTo)
       
   326 	:CActive(EPriorityStandard-1),
       
   327 	 iFepSwitcher(aFepSwitcher),
       
   328 	 iRepositoryKeyMask_OnOrOff(aRepositoryKeyMask_OnOrOff),
       
   329 	 iRepository(NULL),
       
   330 	 iCaptureKeyHandleOrError(aCaptureKeyHandleOrError),
       
   331 	 iKeyDataToAssignTo(aKeyDataToAssignTo)
       
   332 	{
       
   333 	CActiveScheduler::Add(this);
       
   334 	}
       
   335 
       
   336 void CFepKeyDataListener::ConstructL()
       
   337 	{
       
   338 	iRepository=CRepository::NewL(TUid::Uid(KUidFepFrameworkRepository));
       
   339 	SetFepSwitcherL();
       
   340 	Queue();
       
   341 	}
       
   342 
       
   343 void CFepKeyDataListener::SetFepSwitcherL()
       
   344 	{
       
   345 	TFepOnOrOffKeyData onOrOffKeyData(0, 0, 0);
       
   346 	TInt error=KErrNone;
       
   347 	CFepGenericGlobalSettings::ReadOnOrOffKeyData(*iRepository, onOrOffKeyData, iRepositoryKeyMask_OnOrOff, &error);
       
   348 	iFepSwitcher.SetOnOrOffKeyDataL(error, onOrOffKeyData, iCaptureKeyHandleOrError, iKeyDataToAssignTo);
       
   349 	}
       
   350 
       
   351 void CFepKeyDataListener::Queue()
       
   352 	{
       
   353 #if defined(_DEBUG)
       
   354 	const TInt error=
       
   355 #endif
       
   356 	iRepository->NotifyRequest(iRepositoryKeyMask_OnOrOff, ERepositoryKeyMask_OnKeyData|ERepositoryKeyMask_OffKeyData, iStatus);
       
   357 	__ASSERT_DEBUG(error==KErrNone, User::Invariant());
       
   358 	SetActive();
       
   359 	}
       
   360 
       
   361 void CFepKeyDataListener::DoCancel()
       
   362 	{
       
   363 	iRepository->NotifyCancel(iRepositoryKeyMask_OnOrOff, ERepositoryKeyMask_OnKeyData|ERepositoryKeyMask_OffKeyData);
       
   364 	}
       
   365 
       
   366 void CFepKeyDataListener::RunL()
       
   367 	{
       
   368 	const TInt error=iStatus.Int();
       
   369 	Queue();
       
   370 	User::LeaveIfError(error);
       
   371 	SetFepSwitcherL();
       
   372 	}
       
   373 
       
   374 // CNonPanickingScheduler
       
   375 
       
   376 class CNonPanickingScheduler : public CActiveScheduler
       
   377 	{
       
   378 public:
       
   379 	static CNonPanickingScheduler* NewLC();
       
   380 private:
       
   381 	// from CActiveScheduler
       
   382 	virtual void Error(TInt aError) const;
       
   383 	};
       
   384 
       
   385 CNonPanickingScheduler* CNonPanickingScheduler::NewLC()
       
   386 	{ // static
       
   387 	CNonPanickingScheduler* const scheduler=new(ELeave) CNonPanickingScheduler;
       
   388 	CleanupStack::PushL(scheduler);
       
   389 	return scheduler;
       
   390 	}
       
   391 
       
   392 void CNonPanickingScheduler::Error(TInt) const
       
   393 	{
       
   394 	// don't panic here, like CActiveScheduler::Error does
       
   395 	}
       
   396 
       
   397 // top-level functions
       
   398 
       
   399 LOCAL_C void MainL()
       
   400 	{
       
   401 	CActiveScheduler* const activeScheduler=CNonPanickingScheduler::NewLC();
       
   402 	CActiveScheduler::Install(activeScheduler);
       
   403 	CFepSwitcher* const fepSwitcher=CFepSwitcher::NewLC();
       
   404 	RProcess::Rendezvous(KErrNone);
       
   405 	CActiveScheduler::Start();
       
   406 	CleanupStack::PopAndDestroy(2, activeScheduler);
       
   407 	}
       
   408 
       
   409 GLDEF_C TInt E32Main()
       
   410 	{
       
   411 	CTrapCleanup* const cleanup=CTrapCleanup::New();
       
   412 	if(cleanup == NULL)
       
   413 		{
       
   414 		return KErrNoMemory;
       
   415 		}
       
   416 	TRAPD(error, MainL());
       
   417 	delete cleanup;
       
   418 	return error;
       
   419 	}
       
   420