testexecfw/useremul/engine/WSServer/src/serverCtrl.cpp
author Johnson Ma <johnson.ma@nokia.com>
Thu, 13 May 2010 17:42:48 +0800
changeset 3 a5f55a5789f3
parent 0 3e07fef1e154
permissions -rw-r--r--
Defect Fix: TeamTrack DEF145107

/*------------------------------------------------------------------
 -
 * 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: serverCtrl.cpp
 * 
 * Created: 13/08/2009
 * Author(s): Marcell Kiss
 *   
 * Description:
 * Implementation of Anim dll server side class
 *------------------------------------------------------------------
 -
 *
 */

// System Includes
#include <e32std.h>
#include <e32event.h>
#include <e32base.h>
#include <BAUTILS.H>
// User Includes
#include "serverCtrl.h"
#include "clientcommander.h"

// Local constants
_LIT8(KStartXml,"<!--?xml version='1.0' encoding='utf-16' ?>-->\n<UserEmulator>\n<action>\n<type>screenreset</type>\n</action>");
_LIT8(KEndXml, "\n</UserEmulator>");
_LIT8(KStr,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys> %d </keys>\n</action>");
_LIT8(KUp,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>UAK</keys>\n</action>");
_LIT8(KDown,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>DAK</keys>\n</action>");
_LIT8(KLeft,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>LAK</keys>\n</action>");
_LIT8(KRight,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>RAK</keys>\n</action>");
_LIT8(KLSK,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>LSK</keys>\n</action>");
_LIT8(KRSK,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>RSK</keys>\n</action>");
_LIT8(KMSK,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>MSK</keys>\n</action>");
_LIT8(KBS,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>BS</keys>\n</action>");
_LIT8(KAsterisk,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>*</keys>\n</action>");
_LIT8(KYes,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>KYES</keys>\n</action>");
_LIT8(KNo,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>KNO</keys>\n</action>");
_LIT8(KHash,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>#</keys>\n</action>");
_LIT8(KTasks,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>MENU</keys>\n</action>");
_LIT8(KScreenShot1,"\n<action>\n<name> Pause </name>\n<type> wait </type>\n<params> 10 </params>\n<screenshot>");
_LIT8(KScreenShot2,"-%LD</screenshot>\n</action>");

_LIT8(KPortrait,"\n<action>\n<name>Orientation</name>\n<type>orientation</type>\n<params>portrait</params>\n</action>");
_LIT8(KLandscape,"\n<action>\n<name>Orientation</name>\n<type>orientation</type>\n<params>landscape</params>\n</action>");

_LIT8(KStrWait,"\n<action>\n<name> Pause </name>\n<type> wait </type>\n<params> %d </params>\n</action>");
_LIT8(KStrPointerDown,"\n<action>\n<name>Pointer</name>\n<type>pointerevent</type>\n<params>pointerdownAt,%d,%d</params>\n</action>");
_LIT8(KStrDrag,"\n<action>\n<name>Pointer</name>\n<type>pointerevent</type>\n<params>moveTo,%d,%d</params>\n</action>");
_LIT8(KStrPointerUp,"\n<action>\n<name>Pointer</name>\n<type>pointerevent</type>\n<params>pointerupAt,%d,%d</params>\n</action>");

_LIT8(KCamera,"Camera");

const TInt KAsteriskKeyScanCode		= 0x2A;
const TInt KWriteBufferSize			= 20;

// ======== MEMBER FUNCTIONS ========

CServerCtrl::CServerCtrl():iMainBuffer(NULL)
    {// No implementation required
    }

CServerCtrl::~CServerCtrl()
    {
    delete iCaptureKeyTimer;
    iCaptureKeyTimer = NULL;
        
    if(iMainBuffer)
        {
        // If buffer's length is not zero then write that data to file.
        if(iMainBuffer->Length()>0)
            iRFile.Write(*iMainBuffer);
        
        delete iMainBuffer;
        iMainBuffer = NULL;
        }
                            
    iRFile.Close();
    iFs.Close();
    }
// ----------------------------------------------------------
// Second phase constructor
// ----------------------------------------------------------
//
void CServerCtrl::ConstructL( TAny* /* aArgs */, TBool /* aHasFocus */ )
    {
    // Initialisation
    iRecord = EFalse;
    iFirstDelay=EFalse;
    iCameraButtonPressed = EFalse;
    iCaptureKeyTimer = CCaptureKeyTimer::NewL(*this);
    
    
    iIsEventEnabled = EFalse;
    }
// ------------------------------------------------------------
// Communication between client and server. Called by client
// ------------------------------------------------------------
//
TInt CServerCtrl::CommandReplyL( TInt aCode, TAny*  aArgs )
    {
    // Execute client command (aCode)
    switch ( aCode )
            {
        // Start recording
        case RClientCommander::EStart:
        	{
        	 TBuf8<KBuffer512> buf((const TUint8 *)aArgs);
             // Name and path of script file defined on Settings page
        	 iKeyFilePath.Copy(buf);
        	 
        	 // Cut long extension names
        	 TInt pos=iKeyFilePath.LocateReverse('.');
        	 if( pos!=KErrNotFound )
        		 {
        		 iKeyFilePath = iKeyFilePath.Left(pos+4);
        		 }
        		 
        	 // Check if device is in landscape or portrait mode
        	 TSize screen=iFunctions->ScreenDevice()->SizeInPixels();
        	 if(screen.iWidth <= screen.iHeight)
        		iOrientation = ETrue;
        	 else
        		iOrientation = EFalse;
        	   
        	 // Create script file
        	 User::LeaveIfError(iFs.Connect());
        	 TInt val=iRFile.Replace(iFs,iKeyFilePath,EFileShareAny|EFileWrite);
        	 if(val!=KErrNone)
        		 return 1;
        	 
        	 // Write xml header to file
        	 buf.Copy(KStartXml);
        	 
        	 
        	 // Write orientation 'action' to file
        	 if(iOrientation)
        		 buf.Append(KPortrait);
        	 else
        		 buf.Append(KLandscape);
        	 iRecord = ETrue;
        	
        	 iRFile.Write(buf);
        	 iIsEventEnabled = EFalse;
        	 
        	 // Enable raw events
        	 iFunctions->GetRawEvents(ETrue);
        	 
			 iWritePointer = 0;
			 // Initialise main buffer (length of it will be allocated dynamically)
			 iMainBuffer = HBufC8::NewL(1);
        	 
			 iNoCount = 0;
			 
        	}
            break;
            // Start wait timing
        case RClientCommander::EStartTiming:
            {
            // Store home time at start
            TTime time;
            time.HomeTime();
             
            iWaitTimer = time;
            }
            break;
        // Stop recording
        case RClientCommander::EStop:
        	{ 
        	// Disable raw events
            iFunctions->GetRawEvents(EFalse);
            if(iRecord)
            	{
            	TBuf8<KBuffer64> buf;
            	// Write last wait period to buffer
            	CheckTimerInsertWait();
            	
            	iIsEventEnabled = EFalse;
            	
            	// Flush buffer
            	if(iMainBuffer)
            		{
            	    if(iMainBuffer->Length()>0)
            	    	iRFile.Write(*iMainBuffer);
            	    	
            	    delete iMainBuffer;
            	    iMainBuffer = NULL;
            	    }
            	
            	// End tag of xml script
            	buf.Copy(KEndXml);
            	iRFile.Write(buf);            	
            	
            	iRecord = EFalse;
            		
            	iRFile.Flush();
            	iRFile.Close();
            	iFs.Close();
            	}
        	}
            break;
        // Poll the status of camera button (pressed or not)
        case RClientCommander::EPoll:
        	{
        	TBuf8<KBuffer256> buf((const TUint8 *)aArgs);
        	
        	if(buf.Length()>0)
        		{
        		const TUint8* a = buf.Left(0).Ptr();
        		const TUint8* b = buf.Mid(1,1).Ptr();
        		TInt length;
        		if(*b!=42) // 42 = '*'
        			length = (*a-48)*10+(*b-48);
        		else
        			length = *a-48;
        		
        		if(length>0 && 2+length<=buf.Length())
        			buf = buf.Mid(2,length);
        		}
        	// Check if camera application is still in foreground or closed already.
        	if(buf.Compare(KCamera)==0 && !iFirstDelay)
        		iFirstDelay = ETrue;
        	else
        		iFirstDelay = EFalse;
        	
        	if(!iFirstDelay)
        		{
				if(buf.Length()>2)
					iAppName.Copy(buf);
        		}
        				
        	if(iCameraButtonPressed)
        		return 1;
        		
             // Check orientation and write orientation 'action' to buffer if that changed
            TSize screen=iFunctions->ScreenDevice()->SizeInPixels();
		    if(screen.iWidth <= screen.iHeight)
			{
				if(!iOrientation)
					{// log portrait
					TBuf8<KBuffer128> buf;
					buf.Copy(KPortrait);    
					WriteFile(buf);
					}
				iOrientation = ETrue;
			}
			else
			{
				if(iOrientation)
					{// log landscape
					TBuf8<KBuffer128> buf;
					buf.Copy(KLandscape);   
					WriteFile(buf);
					}
				iOrientation = EFalse;
			}
		}
        	break;
        // Reset camera button's state flag
        case RClientCommander::ETaskExisted:
        	{
        	iCameraButtonPressed = EFalse;
        	}
        break;	
        default:
        	{}
            break;
            }
    
    return 0;
    }

TInt CServerCtrl::CommandReplyL( TInt /*aCode*/)
    {
    return 0;
    }

void CServerCtrl::Command( TInt /*aCode*/, TAny* /* aArgs */ )
    {
    }
void CServerCtrl::Redraw()
    {
    }
void CServerCtrl::Animate( TDateTime* /* aDT */ )
    {
    }
void CServerCtrl::FocusChanged( TBool /* aState */ )
    {
    }
    
// ----------------------------------------------------------------------------------
// OfferRawEvent is called by Window Server when an event occurs (key press, pointer event)
// ----------------------------------------------------------------------------------
//
TBool CServerCtrl::OfferRawEvent( const TRawEvent& aRawEvent )
   {
    if (iRecord)
    {
    // Pointer down
    if(aRawEvent.Type() == TRawEvent::EButton1Down)
    	{
    	// Convert coordinates if needed
        // Check elapsed time and write it to buffer 
    	CheckTimerInsertWait();
    	// Write button down event to buffer
    	TBuf8<KBuffer128> buf;
    	buf.Format(KStrPointerDown,aRawEvent.Pos().iX,aRawEvent.Pos().iY);	
    	WriteFile(buf);
    	}
    // Drag event occured
    if(aRawEvent.Type() == TRawEvent::EPointerMove)
    	{
    		CheckTimerInsertWait();
    		TBuf8<KBuffer128> buf;
    		buf.Format(KStrDrag,aRawEvent.Pos().iX,aRawEvent.Pos().iY);
    		WriteFile(buf);
    	}
    // Pointer released
    if(aRawEvent.Type() == TRawEvent::EButton1Up)
    	{   	
    	CheckTimerInsertWait();  	
    	TBuf8<KBuffer128> buf;
    	buf.Format(KStrPointerUp,aRawEvent.Pos().iX,aRawEvent.Pos().iY);	
    	WriteFile(buf);
    	}
    // Button pressed
    if(aRawEvent.Type() == TRawEvent::EKeyDown)
       	{
       	// camera button pressed, write screen shot command to buffer
        if(aRawEvent.ScanCode() == 227 || aRawEvent.ScanCode() == 171 )
            {
            TBuf8<KBuffer256> buf;
            TTime Now;
            Now.HomeTime();
            buf.Copy(KScreenShot1);
            buf.Append(iAppName);
            buf.AppendFormat(KScreenShot2, Now.Int64());
        
            WriteFile(buf);
            
            iCameraButtonPressed = ETrue;
            }
        else
            {
       	// Start to count time while button is pressed
       	iSecCounter = 0;
       	iCaptureKeyTimer->After(KWait08); // 0.8 sec
       	    }
       	}
       	
       	
    // Button released
    if(aRawEvent.Type() == TRawEvent::EKeyUp)
    	{
    	iCaptureKeyTimer->Cancel();
    	
    	TBuf8<KBuffer256> buf;
    	// Write pressed key to buffer
    	if(aRawEvent.ScanCode()>47 && aRawEvent.ScanCode()<=57)
    	    	buf.Format(KStr,iSecCounter,aRawEvent.ScanCode()-48);	
    	if(aRawEvent.ScanCode()==EStdKeyUpArrow)
    			buf.Format(KUp,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyDownArrow)
    			buf.Format(KDown,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyRightArrow)
				buf.Format(KRight,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyLeftArrow)
    			buf.Format(KLeft,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyDevice0)
    			buf.Format(KLSK,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyDevice1)
    			buf.Format(KRSK,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyDevice3)
    			buf.Format(KMSK,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyBackspace)
    			buf.Format(KBS,iSecCounter);
    	if(aRawEvent.ScanCode()==KAsteriskKeyScanCode)
    			buf.Format(KAsterisk,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyYes)
    			buf.Format(KYes,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyNo)
    		{// To filter first two 'No' keys (part of screen reset)
    		    if(iNoCount==0)
    		    	{
    		    	iNoCount++;
                    iIsEventEnabled = ETrue;
                    return EFalse;
    		    	}
    		  
    			buf.Format(KNo,iSecCounter);
    		}
    	if(aRawEvent.ScanCode()==EStdKeyHash)
    			buf.Format(KHash,iSecCounter);
    	if(aRawEvent.ScanCode()==EStdKeyApplication0) //MENU
    			buf.Format(KTasks,iSecCounter);
    	if(buf.Length()>0)
    		{
    		
    		CheckTimerInsertWait();
    		WriteFile(buf);
    		}
    	//
    	    				
    	}
    	
    	
    }
    return EFalse;
   }
// -------------------------------------------
// Count time while button is pressed
// -------------------------------------------
//
void CServerCtrl::KeyTimerExpired()
    {
    iSecCounter++;
    iCaptureKeyTimer->After(KWait08); // 0.8 sec
    }
// --------------------------------------------------------------
// Inserts time interval between two events into the script
// --------------------------------------------------------------
//   
void CServerCtrl::CheckTimerInsertWait()
    {
    TTime time;
    time.HomeTime();
    
    TTimeIntervalMicroSeconds interval = time.MicroSecondsFrom(iWaitTimer);
    
    // If time interval is bigger than 100 micosecs then write it to buffer
    if( interval > 100 )
        {
        TBuf8<KBuffer128> buf;
        buf.Format(KStrWait, interval.Int64() );
        WriteFile(buf);
        }
    // Home time will be the previous time at next event
    iWaitTimer = time;
    }

// --------------------------------------------------------------
// Implements a buffer. Writes to file only if buffer is full.
// --------------------------------------------------------------
//    
void CServerCtrl::WriteFile(TDesC8& aBuf)
	{
	// It doesn't record till screen reset (2 NO key presses) is not over
	if(!iIsEventEnabled)
		return;
	
	TInt r=iMainBuffer->Length();
	TInt t=aBuf.Length();
	iMainBuffer = iMainBuffer->ReAlloc(r+t+1);
	TPtr8 bufferPtr( iMainBuffer->Des() );
	bufferPtr.Append(aBuf);

	if(iWritePointer++ > KWriteBufferSize)
		{
		// Buffer is full. Write to file and reset buffer
		iWritePointer = 0;
		iRFile.Write(*iMainBuffer);
		delete iMainBuffer;
		iMainBuffer = NULL;
		TRAPD(err, iMainBuffer = HBufC8::NewL(1));
		}
	}
// End of File