testexecfw/useremul/src/GlobalCapturer.cpp
changeset 0 3e07fef1e154
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecfw/useremul/src/GlobalCapturer.cpp	Mon Mar 08 15:03:44 2010 +0800
@@ -0,0 +1,517 @@
+/*------------------------------------------------------------------
+ -
+ * Software Name : UserEmulator
+ * Version       : v4.2.1309
+ * 
+ * Copyright (c) 2009 France Telecom. All rights reserved.
+ * This software is distributed under the License 
+ * "Eclipse Public License - v 1.0" the text of which is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * France Telecom 
+ *
+ * Contributors:
+ *------------------------------------------------------------------
+ -
+ * File Name: GlobalCapturer.cpp
+ * 
+ * Created: 13/08/2009
+ * Author(s): Marcell Kiss, Reshma Sandeep Das
+ *   
+ * Description:
+ * Key capturing class
+ *------------------------------------------------------------------
+ -
+ *
+ */
+ 
+// System Includes
+#include <e32base.h>
+#include <e32std.h>
+#include <e32cons.h>
+#include <aknnotewrappers.h>
+#include <apgwgnam.h>
+#include <eikenv.h>
+#include <apgtask.h>
+#include <APGCLI.H>
+#include <W32STD.H>
+#include <bautils.h>
+// User Includes
+#include <UserEmulator_0x2001C3AF.rsg>
+#include "GlobalCapturer.h"
+#include "UserEmulatorApplication.h"
+
+// Constants
+const TUid KUidStandBy = { 0x102750f0 };
+
+const TUint KKeyCodePowerKey  	= EKeyDevice2;
+const TUint KCameraKey 			= 0xF887;
+const TUint KEndKeyScanCode 	= 197;
+
+const TInt KCaptureMaxPriority = 11;
+const TInt KAppInfoLength = 10;
+const TInt KZeroAscii = 48;
+const TInt KZedAscii = 122;
+const TInt KDotAscii = 46;
+
+// ============================ MEMBER FUNCTIONS ===============================
+// -------------------------------------------
+// CGlobalCapturer::CGlobalCapturer
+// -------------------------------------------
+//
+CGlobalCapturer::CGlobalCapturer(MKeyObserver& aObserver, CSettings& aSettings, TBool& aScriptRun, 
+		TBool& aRandomTestStarted, RClientCommander& aClientCommander, CEikonEnv* aEikonEnv, RApaLsSession& aSession) :
+		CActive( EPriorityNormal ),iObserver(aObserver),iSettings(aSettings), iScriptRun(aScriptRun),
+		iRandomTestStarted(aRandomTestStarted),iClientCommander(aClientCommander), iEEnv(aEikonEnv), iSession(aSession)
+{
+}
+// -------------------------------------------
+// CGlobalCapturer::NewL
+// -------------------------------------------
+//
+CGlobalCapturer* CGlobalCapturer::NewL(MKeyObserver& aObserver, CSettings& aSettings, TBool& aScriptRun, 
+		TBool& aRandomTestStarted, RClientCommander& aClientCommander, CEikonEnv* aEikonEnv,RApaLsSession& aSession)
+	{
+	CGlobalCapturer* me = new (ELeave) CGlobalCapturer(aObserver,aSettings,aScriptRun, 
+			aRandomTestStarted,aClientCommander,aEikonEnv,aSession);
+	CleanupStack::PushL(me);
+	me->ConstructL();
+	CleanupStack::Pop(me);
+	return me;
+	}
+
+// -------------------------------------------
+// Symbian 2nd phase constructor
+// -------------------------------------------
+//
+void CGlobalCapturer::ConstructL(void)
+	{
+	iRecord = EFalse;
+	iKeyCaptureStart = EFalse;
+	
+	iCameraAppTimer = CCameraAppTimer::NewL(*this);
+	}
+
+// -------------------------------------------
+// Destructor
+// -------------------------------------------
+//
+CGlobalCapturer::~CGlobalCapturer()
+{
+	Cancel();			
+	delete iWindowGroup;
+	iWsSession.Close();
+	iFs.Close();
+	
+	if(iCameraAppTimer)
+		{
+	    delete iCameraAppTimer;
+	    iCameraAppTimer = NULL;
+	    }
+}
+
+// -------------------------------------------
+// CActive cancel function
+// -------------------------------------------
+//
+void CGlobalCapturer::DoCancel()
+{	
+	if ( IsActive() )
+	{
+		iWsSession.EventReadyCancel();
+	}
+}
+
+// -------------------------------------------
+// Initialise key capturing
+// -------------------------------------------
+//
+void CGlobalCapturer::StartCapturingL() 
+{
+	// Connect to the window server
+	User::LeaveIfError( iWsSession.Connect() );
+	// Create an invisible window group. Well, we'll make it invisible later
+	iWindowGroup = new (ELeave) RWindowGroup ( iWsSession );
+	iWindowGroup->Construct( (TUint32)iWindowGroup, EFalse );
+	
+	CApaWindowGroupName* wn;
+	wn=CApaWindowGroupName::NewLC(iWsSession);
+	wn->SetHidden(ETrue);
+	wn->SetWindowGroupName(*iWindowGroup);	
+	CleanupStack::PopAndDestroy(wn);
+	
+	CActiveScheduler::Add( this );
+}
+
+// -------------------------------------------
+// Starts capturing Power button key presses
+// -------------------------------------------
+//
+void CGlobalCapturer::StartL()
+{ 
+    User::LeaveIfError( iCaptureHandle1 = iWindowGroup->CaptureKey( EKeyDevice2, 0, 0, KCaptureMaxPriority ) );	
+  
+	// Tell window server we are ready to receive events
+	if ( !IsActive() )
+	{
+		iWsSession.EventReady( &iStatus );
+		SetActive();
+	}		
+}
+
+// -------------------------------------------
+// Stops capturing Power button key presses
+// -------------------------------------------
+//
+void CGlobalCapturer::Stop()
+{
+		Cancel();
+		iWindowGroup->CancelCaptureKey( iCaptureHandle1 );
+}
+
+// --------------------------------------------------------------
+// CActive RunL function. Called when a key press happened
+// --------------------------------------------------------------
+//
+void CGlobalCapturer::RunL()
+{
+	if( iStatus == KErrNone ) 	
+	{
+		TWsEvent we;
+		iWsSession.GetEvent( we );
+		iKeyEvent=we.Key();
+		CApaWindowGroupName* gn = CApaWindowGroupName::NewLC(iEEnv->WsSession(), iEEnv->WsSession().GetFocusWindowGroup());
+		TUid foreTaskUid = gn->AppUid();
+		CleanupStack::PopAndDestroy(gn);
+		
+		// Stops key recording
+		if(iKeyEvent->iCode == EKeyDevice2 && iRecord)
+			{
+			StopRecordKeysL();
+			return;
+			}
+		// Stops random tests
+		else if(iKeyEvent->iCode == EKeyDevice2 && iRandomTestStarted)
+			{
+			iObserver.RandomTestEndsL();
+			return;
+			}
+		// Stops running scripts
+		else if(iKeyEvent->iCode == EKeyDevice2)
+			{
+			Stop();
+			iObserver.TerminationKeyReceived();
+			return;
+			}
+		
+		// Send event to the application which is in foreground			
+		TInt appId = iEEnv->WsSession().GetFocusWindowGroup();
+		iEEnv->WsSession().SendEventToWindowGroup(appId, we);											
+		
+		if ( !IsActive() )
+		{
+			iWsSession.EventReady( &iStatus );
+			SetActive();
+		}		
+	}
+	
+}
+
+// --------------------------------------------------------------
+// Checks if camera app is in memory or not
+// --------------------------------------------------------------
+//
+void CGlobalCapturer::CheckCameraAppL()
+{
+    _LIT8(KDecimal,"%d");
+    _LIT8(KAsterisk,"*");
+	// Get foreground app's name
+	CApaWindowGroupName* gn = CApaWindowGroupName::NewLC(iEEnv->WsSession(),iEEnv->WsSession().GetFocusWindowGroup());
+	TApaAppInfo appInfo;
+	RApaLsSession ApaLs;
+	User::LeaveIfError(ApaLs.Connect());
+	ApaLs.GetAppInfo(appInfo, gn->AppUid());
+	// Store length!
+	iAppName.Format(KDecimal,appInfo.iCaption.Length());
+	if(appInfo.iCaption.Length()<KAppInfoLength)
+		iAppName.Append(KAsterisk);
+	
+	iAppName.Append(appInfo.iCaption);
+	CleanupStack::PopAndDestroy(gn);
+	ApaLs.Close();
+	
+	iAppName.ZeroTerminate();
+	TPtrC8 ptr;
+	ptr.Set(iAppName);
+	// Poll. (And send foreground app's name) 
+	if( iClientCommander.AnimCommand( RClientCommander::EPoll, &ptr) == 1 )
+	{
+		TUid CamId;
+		CamId = KUidCamera;
+		TApaTaskList taskList(iEEnv->WsSession());
+		TApaTask task = taskList.FindApp(CamId);
+		if (task.Exists())
+			task.EndTask();
+		else
+		  iClientCommander.AnimCommand( RClientCommander::ETaskExisted, NULL);
+	}
+	// Restart camera app timer
+	iCameraAppTimer->After(KWait08); // 0.8 sec
+}
+
+// ---------------------------------------------
+// Filters not appropriate characters
+// Allows only chars. from 0 to z and '.'
+// ---------------------------------------------
+//
+TBool CGlobalCapturer::StrictFileNameCheck(const TDesC& aFileName)
+{
+	TBool res=ETrue;
+	for(TInt t=0;t<aFileName.Length();t++)
+	{
+		const TUint16* a=aFileName.Mid(t,1).Ptr();
+		if((*a<KZeroAscii || *a>KZedAscii) && *a!=KDotAscii) // 46 -> '.'
+			res=EFalse;
+	}
+	return res;
+}
+// ---------------------------------------------
+// Starts key record with Windows server dll
+// ---------------------------------------------
+//
+TInt CGlobalCapturer::StartRecordKeysL()
+	{
+	// Checks if there's another process started
+	if(!iRecord && !iScriptRun && !iKeyCaptureStart)
+		{
+		_LIT16(Ktitle,"Output file name?");
+		TBuf16<KBuffer256> aBuffer;
+		
+		TBool exit = EFalse;
+		while(!exit)
+        {
+          // Asks for output file name
+		  CAknTextQueryDialog* Dialog = CAknTextQueryDialog::NewL(aBuffer,CAknQueryDialog::ENoTone); 
+		  Dialog->PrepareLC(R_FILE_DIALOG); 
+		  Dialog->SetPromptL(Ktitle); 
+		
+		  if(Dialog->RunLD())
+			{
+				iBuf8.Copy(iSettings.iScriptsPath);
+				TInt a = iBuf8.LocateReverse('\\');
+				if(a!=KErrNotFound)
+				{
+				iBuf8 = iBuf8.Left(a+1);
+				}
+								
+				iBuf8.Append(aBuffer);
+				
+				if(iBuf8.LocateReverse('.')==KErrNotFound)
+				{
+			    _LIT(Kxml,".xml");
+			    iBuf8.Append(Kxml);
+			    }
+							
+				TBuf<KBuffer512> TempPath;
+				TempPath.Copy(iBuf8);
+				// Validate file name
+				if(iEEnv->FsSession().IsValidName(TempPath) && StrictFileNameCheck(aBuffer))
+				{
+					exit = ETrue;
+				}
+				else
+				{
+				    _LIT(KInvalid,"Invalid file name! Please try again.");
+					CAknErrorNote* errorNote = new (ELeave) CAknErrorNote(ETrue);
+					errorNote->ExecuteLD(KInvalid);
+					continue;
+				}
+				
+				User::LeaveIfError(iFs.Connect());
+				
+				// If file exists then overwrite it or not?
+				TBool overwrite=ETrue;
+				TBuf16<KBuffer512> TempiBuf8;
+				TBuf16<KBuffer8> empty;
+				TempiBuf8.Copy(iBuf8);
+				if(BaflUtils::FileExists(iFs, TempiBuf8))
+				{
+					_LIT8(Kk,"Overwrite existing file?");
+					_LIT8(Kk1,"");
+					TempiBuf8.Copy(Kk);
+					empty.Copy(Kk1);
+					if(iEEnv->QueryWinL(TempiBuf8,empty))
+						overwrite = ETrue;
+					else
+						overwrite = EFalse;
+				}
+				
+				iFs.Close();
+			
+				if(overwrite)
+				{
+					TPtrC8 ptr;
+					ptr.Set(iBuf8);
+					// Starts all event capture with the Window server object!
+					TInt res=iClientCommander.AnimCommand( RClientCommander::EStart, &ptr);
+					
+					if(res==1)
+					{
+					    _LIT(KWritingError,"Script file writing error. Drive might be locked");
+						CAknErrorNote* errorNote = new (ELeave) CAknErrorNote(ETrue);
+						errorNote->ExecuteLD(KWritingError);
+						return 1;
+					}
+					else
+					{
+                       TBuf<KBuffer64> buff;
+                       _LIT(KWait,"Wait. Script recording will start from the Idle screen..");
+                       
+                       CAknConfirmationNote* note = new (ELeave) CAknConfirmationNote(ETrue);
+                       buff.Copy(KWait);
+                       note->ExecuteLD(buff);
+                       User::After(KWait02);
+					   // Closes apps (there are exceptions) as a reset
+					   KillUnwantedAppsResetL();
+					
+					   // Starts wait timer
+                       iClientCommander.AnimCommand( RClientCommander::EStartTiming, NULL);
+					
+					   // Resets menu screen
+					   if(ScreenReset()!=KErrNone)
+						  return 1;
+					   iKeyCaptureStart = ETrue;				
+					   iRecord = ETrue;
+	
+	                   // Starts Power button capturing
+					   StartL();
+					   // Starts camera app timer
+					   iCameraAppTimer->After(KWait05); // 0.5 sec
+					  
+					}	
+					
+				}
+			}
+			else
+				return 1;
+		  }// while end
+		}
+	else
+		{
+		_LIT(KRunning,"A script or recording is already running!");
+		CAknErrorNote* errorNote = new (ELeave) CAknErrorNote(ETrue);
+		errorNote->ExecuteLD(KRunning);
+		return 1;
+		}
+	
+	return 0;
+	}
+
+// --------------------------------------------------------------------
+// Closes Menu screen and resets idle screen by two No key presses
+// --------------------------------------------------------------------
+//
+TInt CGlobalCapturer::ScreenReset()
+	{
+	// Reset Menu app.
+	TApaTaskList taskList(iEEnv->WsSession());
+	TApaTask task = taskList.FindApp(KUidMenu);
+        
+	task.EndTask();
+	
+	//Brings 'Menu' to foreground and resets screen selecting 'Exit'
+	TApaTaskList taskList2(iEEnv->WsSession());
+    TApaTask task2 = taskList2.FindApp(KUidHomeScreen); //? old phones
+    task2.BringToForeground();
+    User::After(KWait1);
+    
+    TRawEvent lEventDown;
+    TRawEvent lEventUp;
+    
+    // No key press (Idle screen reset!) //? old phones (No key opens a menu on old phones)
+    lEventDown.Set(TRawEvent::EKeyDown, KEndKeyScanCode); // No key
+    UserSvr::AddEvent(lEventDown);
+    User::After(KWait01);               
+    lEventUp.Set(TRawEvent::EKeyUp, KEndKeyScanCode);                       
+    UserSvr::AddEvent(lEventUp);
+    User::After(KWait1);
+    
+	return KErrNone;
+	}
+
+// --------------------------------------------------------------------
+// Kills applications in the background except apps which has to run
+// --------------------------------------------------------------------
+//
+void CGlobalCapturer::KillUnwantedAppsResetL()
+	{	
+	
+    TInt numWindowGroups = iEEnv->WsSession().NumWindowGroups();
+    CArrayFixFlat<TInt>* windowGroupList = new(ELeave) CArrayFixFlat<TInt>(numWindowGroups);
+    CleanupStack::PushL(windowGroupList);
+
+    // Populate array with current group list ids
+    User::LeaveIfError(iEEnv->WsSession().WindowGroupList(windowGroupList));
+    CApaWindowGroupName* windowGroupName = CApaWindowGroupName::NewLC(iEEnv->WsSession());
+
+    for (TInt i = 0; i < numWindowGroups; ++i)
+    	{
+        TInt wgId = windowGroupList->At(i);
+        windowGroupName->ConstructFromWgIdL(wgId);
+        TUid Uid = windowGroupName->AppUid();
+        TInt32 appUid = Uid.iUid;
+        
+                       
+        // Exceptions
+        if(appUid != KUidMenu.iUid && appUid != KUidPanicCapturer.iUid && appUid != KUidUserEmulatorApp.iUid &&
+        		appUid != KUidHomeScreen.iUid && appUid != KUidAknCapServer.iUid &&
+                   		appUid != KUidAknnfySrv.iUid && appUid != KUidTelephony.iUid && 
+appUid != KUidPenInputSrv.iUid )
+        	{
+			// Only list 'visible' applications
+			if (!windowGroupName->Hidden() && !windowGroupName->IsBusy() && !windowGroupName->IsSystem())
+				{
+				TApaTaskList taskList(iEEnv->WsSession());
+				TApaTask task = taskList.FindApp(Uid);
+				if (task.Exists())
+					{
+        
+					task.EndTask();
+					User::After(KWait005);
+					}
+				}
+        	}
+           
+    	}
+    CleanupStack::PopAndDestroy(2);
+   
+	}
+
+// ----------------------------------------------------
+// Notifies Window server object to stop capturing
+// ----------------------------------------------------
+//
+void CGlobalCapturer::StopRecordKeysL()
+{
+	iKeyCaptureStart = EFalse;
+	
+	// Call client commander which calls server side object
+	iClientCommander.AnimCommand( RClientCommander::EStop, NULL);
+	// Cancels camera app timer
+	iCameraAppTimer->Cancel();
+	// Stop Power button capturing
+	Stop();
+	
+	if(iRecord)
+		iRecord = EFalse;
+	// Bring this app to foreground
+	iObserver.BringUserEmulatorToFront();
+	// Display acknowledgement
+	CAknInformationNote* note = new (ELeave) CAknInformationNote(ETrue);
+	TBuf<KBuffer64> buff;
+	_LIT(KCapturingEnded, "Capturing ended");
+	buff.Format(KCapturingEnded);
+	note->ExecuteLD(buff);
+}
+// End of file