loadgen/src/loadgen_applications.cpp
changeset 0 d6fe6244b863
child 11 454d022d514b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loadgen/src/loadgen_applications.cpp	Tue Feb 02 00:17:27 2010 +0200
@@ -0,0 +1,686 @@
+/*
+* 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:  
+*
+*/
+
+
+// INCLUDE FILES
+#include "loadgen_applications.h"
+#include "loadgen_model.h"
+#include "loadgen.hrh"
+#include <loadgen.rsg>
+
+#include <e32math.h>
+#include "loadgen_traces.h"
+
+_LIT(KThreadName, "Applications %d");
+
+const TInt KDefaultStartDelay = 500;
+const TInt KThreadNameLength = 64;
+const TInt KDescriptorBufSize = 256;
+const TInt KPriorityBufSize = 16;
+const TInt KScanCodeStart = 32;
+    
+// ===================================== MEMBER FUNCTIONS =====================================
+
+CAppLauncher* CAppLauncher::NewL( TApplicationsAttributes& aAttributes, TInt aReferenceNumber )
+    {
+    CAppLauncher* self = new(ELeave) CAppLauncher( aAttributes, aReferenceNumber );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;    
+    }
+
+// --------------------------------------------------------------------------------------------
+
+CAppLauncher::~CAppLauncher()
+    {
+    Close();
+    }
+
+// --------------------------------------------------------------------------------------------
+
+CAppLauncher::CAppLauncher(  
+           TApplicationsAttributes& aAttributes, TInt aReferenceNumber ) : 
+           iAttributes( aAttributes )
+    {
+    iAttributes.iId = aReferenceNumber;
+    }
+
+// --------------------------------------------------------------------------------------------
+
+void CAppLauncher::ConstructL()
+    {
+    CLoadBase::ConstructL();
+    
+    iType = ELoadGenCmdNewLoadApplications;
+    
+    TBuf<KThreadNameLength> threadName;
+    threadName.Format( KThreadName, iAttributes.iId );
+    
+    // create a thread
+    User::LeaveIfError( iThread.Create( threadName, ThreadFunction, 
+                                        KDefaultStackSize*2, KMinHeapSize, 
+                                        KKilo * KMinHeapSize, (TAny*) &iAttributes ) );
+    
+    // set priority of the thread
+    SetPriority();
+    }
+
+// --------------------------------------------------------------------------------------------
+
+TInt CAppLauncher::ThreadFunction( TAny* aThreadArg )
+    {
+    CTrapCleanup* pC = CTrapCleanup::New();
+    CActiveScheduler* pS = new CActiveScheduler;
+    CActiveScheduler::Install( pS );
+
+    // start generating load, pass pointer to arguments
+    GenerateLoad( *( ( TApplicationsAttributes* ) aThreadArg ) );
+
+    delete pS;
+    delete pC;
+    
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+
+void CAppLauncher::GenerateLoad( TApplicationsAttributes& aAttributes )
+    {
+    CAppLauncherManager* appLauncherManager = NULL;
+    TRAPD( err, appLauncherManager = CAppLauncherManager::NewL( aAttributes ) );
+    if ( err == KErrNone ) 
+        {
+        CActiveScheduler::Start();
+        }
+    delete appLauncherManager;
+    }
+
+// --------------------------------------------------------------------------------------------
+
+void CAppLauncher::Resume()
+    {
+    CLoadBase::Resume();
+    
+    iThread.Resume();
+    }
+
+// --------------------------------------------------------------------------------------------
+
+void CAppLauncher::Suspend()
+    {
+    CLoadBase::Suspend();
+    
+    iThread.Suspend();
+    }
+
+// --------------------------------------------------------------------------------------------
+
+void CAppLauncher::SetPriority()
+    {
+    CLoadBase::SetPriority();
+    
+    iThread.SetPriority( CLoadGenModel::SettingItemToThreadPriority( iAttributes.iPriority ) );
+    }
+    
+// --------------------------------------------------------------------------------------------
+
+void CAppLauncher::Close()
+    {
+    CLoadBase::Close();
+    
+    if ( iThread.ExitReason() == 0 ) // check if the thread is still alive
+        {
+        // signal the thread that it needs to close
+        iThread.RequestComplete( iAttributes.iDeathStatus, KErrCancel );
+
+        // wait the thread to die
+        TRequestStatus waiter;
+        iThread.Logon( waiter );
+        User::WaitForRequest( waiter );
+        iThread.Close();
+        }
+    }
+    
+// --------------------------------------------------------------------------------------------
+
+TPtrC CAppLauncher::Description()
+    {
+    TBuf<KDescriptorBufSize> buf;
+    TBuf<KPriorityBufSize> prioBuf;
+    CLoadGenModel::SettingItemToThreadDescription( iAttributes.iPriority, prioBuf );
+    
+    _LIT(KAppLauncherEntry, "[%d] Appls prio=%S max apps=%d heartbeat=%dms random=%d%%");
+    buf.Format( KAppLauncherEntry, iAttributes.iId, &prioBuf, iAttributes.iMaxOpen, 
+                iAttributes.iHeartBeat, iAttributes.iRandomVariance );
+   
+    return TPtrC( buf );
+    }               
+
+// --------------------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------
+
+CAppLauncherManager* CAppLauncherManager::NewL( TApplicationsAttributes& aAttributes )
+    {
+    CAppLauncherManager* self = new(ELeave) CAppLauncherManager(aAttributes);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+
+CAppLauncherManager::CAppLauncherManager( TApplicationsAttributes& aAttributes ) :
+            CActive( EPriorityStandard ), iAttributes( aAttributes )
+    {
+    iAppEventType = EApplicationsLaunchApplication;
+    }
+
+// --------------------------------------------------------------------------------------------
+    
+CAppLauncherManager::~CAppLauncherManager()
+    {
+    if ( iPeriodicTimer )
+        {
+        iPeriodicTimer->Cancel();
+        delete iPeriodicTimer;
+        }
+    delete iLauncherEngine;
+    Cancel();
+    
+    iWsSession.Close();
+    }
+
+// --------------------------------------------------------------------------------------------
+ 
+void CAppLauncherManager::ConstructL()
+    {
+    CActiveScheduler::Add( this );
+    
+    // create instance to application launcher
+    iLauncherEngine = CLauncherEngine::NewL( iAttributes );
+    
+    // set the status as pending
+    iStatus = KRequestPending;
+    SetActive();
+    
+    // set the death status pointer point to the request status of this ao
+    iAttributes.iDeathStatus = &iStatus;
+    
+    // init
+    User::LeaveIfError( iWsSession.Connect() );
+    
+    // start timer    
+    iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+    iPeriodicTimer->Start( KDefaultStartDelay, 
+                           CLoadGenModel::MilliSecondsToMicroSeconds( 
+                               iAttributes.iLaunchingInterval, iAttributes.iRandomVariance ),
+                           TCallBack( PeriodicTimerCallBack, this ) );
+    }
+    
+// --------------------------------------------------------------------------------------------
+ 
+void CAppLauncherManager::RunL()
+    {
+    // request status has completed by the main thread meaning that we need to stop now
+    CActiveScheduler::Stop();
+    }
+
+// --------------------------------------------------------------------------------------------
+ 
+void CAppLauncherManager::DoCancel()
+    {
+    }
+
+// --------------------------------------------------------------------------------------------
+
+TInt CAppLauncherManager::PeriodicTimerCallBack( TAny* aAny )
+    {
+    CAppLauncherManager* self = static_cast<CAppLauncherManager*>( aAny );
+
+    TRAPD( err, self->SimulateEventL() );
+    if ( KErrNone != err )
+        {
+        return err;
+        }
+    return KErrNone;
+    }
+    
+// --------------------------------------------------------------------------------------------
+ 
+void CAppLauncherManager::SimulateEventL()
+    {    
+    // Randomly start new applications.
+    // After maximum applications launched stop one application.
+    // And after that start launching again.
+    if ( iAppEventType == EApplicationsLaunchApplication && 
+         iAttributes.iMaxOpen == iLauncherEngine->AppLaunchCounter() )
+        {
+        iAppEventType = EApplicationsCloseApplication;
+        }
+    if ( iAppEventType == EApplicationsCloseApplication && 
+         iAttributes.iMaxOpen -1 == iLauncherEngine->AppLaunchCounter() )
+        {
+        iAppEventType = EApplicationsLaunchApplication;
+        }
+    
+    // Launch or stop
+    if ( iAppEventType == EApplicationsLaunchApplication )
+        {
+        iLauncherEngine->StartAppLaunchingL();
+        }  
+    else
+        {
+        iLauncherEngine->StopApplication( ETrue );
+        }
+    }
+    
+// --------------------------------------------------------------------------------------------
+
+#include <avkon.hrh>
+#include <e32std.h>
+#include <w32std.h>
+#include <apgtask.h>
+#include <bautils.h>
+#include <s32file.h>
+#include <APGWGNAM.H> 
+
+// ---------------------------------------------------------------------------
+
+CLauncherEngine* CLauncherEngine::NewL( TApplicationsAttributes& aAttributes )
+    {
+    CLauncherEngine* self = new(ELeave) CLauncherEngine( aAttributes );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+
+CLauncherEngine::CLauncherEngine( TApplicationsAttributes& aAttributes ) : 
+                        iAttributes( aAttributes )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+
+void CLauncherEngine::ConstructL()
+    {
+    LOGSTRING("LoadGen: CLauncherEngine::ConstructL");
+    iAppKeyPressManager = CAppKeyPressManager::NewL( iAttributes );
+    iAppLaunchCounter = 0;
+    User::LeaveIfError( iTimer.CreateLocal() );
+
+    User::LeaveIfError( iLs.Connect() );
+    User::LeaveIfError( iWs.Connect() );
+
+    }
+
+// ---------------------------------------------------------------------------
+
+CLauncherEngine::~CLauncherEngine()
+    {
+    LOGSTRING("LoadGen: CLauncherEngine::~CLauncherEngine");
+    StopApplication( EFalse );
+    iWs.Close();
+    iLs.Close();
+    iTimer.Close();
+    delete iAppKeyPressManager;
+    }
+
+// ---------------------------------------------------------------------------
+
+void CLauncherEngine::StartAppLaunchingL()
+    {
+    LOGSTRING("LoadGen: CLauncherEngine::StartAppLaunchingL");
+    if ( iAppLaunchCounter == iAttributes.iMaxOpen )
+        {
+        return;
+        }
+
+    // start launching
+    TBool launched( EFalse );
+    while ( !launched )
+        {
+        launched = LaunchApplicationL();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+
+TBool CLauncherEngine::LaunchApplicationL()
+    {
+    LOGSTRING("LoadGen: CLauncherEngine::LaunchApplicationL");
+    TBool result( EFalse );
+    // get the uid of the current app
+    iCurrentAppUid = KNullUid;
+    TApaAppInfo appInfo;
+    
+    // get application list size
+    TInt appsListSize = iAttributes.iAppsArray->MdcaCount();
+    // get random application number in the list
+    TInt appTolaunch = CLoadGenModel::RandomNumber( 0,  appsListSize - 1 );
+    // get file name of the application to be launched
+    TFileName launchFileName = iAttributes.iAppsArray->MdcaPoint( appTolaunch );
+    iLs.GetAllApps();
+    while ( iLs.GetNextApp( appInfo ) == KErrNone )
+        {
+        // get file name in  current appInfo
+        TFileName appFileName = appInfo.iFullName;
+        // get AppUid
+        if ( appFileName.CompareF( launchFileName ) == 0 )
+            {
+            iCurrentAppUid = appInfo.iUid;
+            break;
+            }
+        }
+
+    if ( iCurrentAppUid != KNullUid )
+        {        
+        // parse the filename
+        TParse nameParser;
+        nameParser.SetNoWild( iAttributes.iAppsArray->MdcaPoint( appTolaunch ), NULL, NULL );
+        iCurrentAppNameAndExt.Copy( nameParser.Drive() );
+        iCurrentAppNameAndExt.Append( nameParser.NameAndExt() );
+           
+        // do not try to launch these apps
+        if ( iCurrentAppUid != KNullUid &&
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch).FindF(_L("\\loadgen.")) == KErrNotFound &&
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\Phone." ) ) == KErrNotFound &&
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch).FindF( _L("\\Startup.") ) == KErrNotFound &&  
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\SplashScreen.") ) == KErrNotFound &&  
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\cameraapp.") ) == KErrNotFound &&
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\eshell.") ) == KErrNotFound &&
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\ConnTest.") ) == KErrNotFound &&
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\Launcher.") ) == KErrNotFound &&
+              
+#ifdef __WINS__
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\DebugAgent.") ) == KErrNotFound &&
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\redirect.") ) == KErrNotFound &&              
+#endif              
+              iAttributes.iAppsArray->MdcaPoint( appTolaunch ).FindF( _L("\\VoiceRecorder.") ) == KErrNotFound )            
+            {
+        
+            // check if the app is already running
+            TApaTaskList taskList( iWs );
+            TApaTask thisTask = taskList.FindApp( iCurrentAppUid );
+            if ( !thisTask.Exists( ))
+                {
+                // check the program's capabilities
+                TApaAppCapabilityBuf buf;
+                iLs.GetAppCapability( buf, iCurrentAppUid );
+                TApaAppCapability cap = buf();
+        
+                // if it's embeddable only, don't launch if setting is enabled
+                // if it's hidden, don't launch if setting is enabled
+                if ( cap.iEmbeddability != TApaAppCapability::EEmbeddableOnly &&
+                     !cap.iAppIsHidden )
+                    {
+                    LOGSTRING2("launchFileName = %S", &launchFileName);
+                    
+                    DoLaunchApplicationL();
+                    result = ETrue;
+                    }            
+                } 
+            }
+        }
+    return result;
+    }
+
+
+// ---------------------------------------------------------------------------
+
+void CLauncherEngine::DoLaunchApplicationL()
+    {
+    LOGSTRING("LoadGen: CLauncherEngine::DoLaunchApplicationL");
+
+    // Find the task with uid3
+    TApaTaskList tasklist( iWs );
+    TApaTask task=tasklist.FindApp( iCurrentAppUid );
+
+    if ( !task.Exists() )
+        // Task doesn't exist, launch a new instance of an application
+        {
+        TApaAppInfo appInfo;
+        User::LeaveIfError( iLs.GetAppInfo( appInfo, iCurrentAppUid ) );
+        TApaAppCapabilityBuf capBuf;
+        User::LeaveIfError( iLs.GetAppCapability( capBuf, iCurrentAppUid ) );
+        TApaAppCapability& caps = capBuf();
+
+        CApaCommandLine* cmdLine=CApaCommandLine::NewLC();
+        cmdLine->SetExecutableNameL( appInfo.iFullName );
+
+        // app is launched in background
+        cmdLine->SetCommandL( EApaCommandBackground );       
+
+        // start the app
+        User::LeaveIfError( iLs.StartApp( *cmdLine ) );
+        iAppKeyPressManager->AddNewApplicationUidToKeyEventsL( iCurrentAppUid );
+        iAppLaunchCounter++;
+
+        CleanupStack::PopAndDestroy( cmdLine );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+
+void CLauncherEngine::StopApplication( TBool aRandomApplication )
+    {
+    LOGSTRING("LoadGen: CLauncherEngine::StopApplication");
+
+    // remove key pressing instance
+    TUid appToDelete = iAppKeyPressManager->KillApplication( aRandomApplication );
+    if ( appToDelete != KNullUid )
+        {
+        TApaTaskList taskList( iWs );
+        TApaTask thisTask = taskList.FindApp( appToDelete );
+    
+        if ( thisTask.Exists() )
+            {
+            // since the application is still open, let's close it
+            thisTask.EndTask();
+            }
+        iAppLaunchCounter--;
+        }
+    
+    // return if only one application requested
+    if ( aRandomApplication )
+        {
+        return;
+        }
+    
+    // remove all launched applications because load is requested to be closed
+    while ( appToDelete != KNullUid )
+        {
+        appToDelete = iAppKeyPressManager->KillApplication( aRandomApplication );
+            
+        if ( appToDelete != KNullUid )
+            {
+            TApaTaskList taskList( iWs );
+            TApaTask thisTask = taskList.FindApp( appToDelete );
+        
+            if ( thisTask.Exists() )
+                {
+                // since the application is still open, let's close it
+                thisTask.EndTask();
+                }
+            iAppLaunchCounter--;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------
+
+CAppKeyPressManager* CAppKeyPressManager::NewL( TApplicationsAttributes& aAttributes )
+    {
+    LOGSTRING("LoadGen: CAppKeyPressManager::NewL");
+    CAppKeyPressManager* self = new(ELeave) CAppKeyPressManager( aAttributes );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+
+CAppKeyPressManager::CAppKeyPressManager( TApplicationsAttributes& aAttributes ) :
+                                            iAttributes( aAttributes )
+    {
+    LOGSTRING("LoadGen: CAppKeyPressManager::CAppKeyPressManager");
+    }
+
+// --------------------------------------------------------------------------------------------
+    
+CAppKeyPressManager::~CAppKeyPressManager()
+    {
+    LOGSTRING("LoadGen: CAppKeyPressManager::~CAppKeyPressManager");
+    if ( iKeyPresses.Count() != 0 )
+        {
+        iKeyPresses.ResetAndDestroy();
+        }
+
+    iKeyPresses.Close();
+    }
+
+// --------------------------------------------------------------------------------------------
+ 
+void CAppKeyPressManager::ConstructL()
+    {
+    LOGSTRING("LoadGen: CAppKeyPressManager::ConstructL");
+    }
+    
+   
+// --------------------------------------------------------------------------------------------
+void CAppKeyPressManager::AddNewApplicationUidToKeyEventsL( TUid aUid )
+    {
+    LOGSTRING("LoadGen: CAppKeyPressManager::AddNewApplicationUidToKeyEventsL");
+    CApplicationKeyPresses* applicationKP = CApplicationKeyPresses::NewL( aUid,
+                                                                    iAttributes );
+    CleanupStack::PushL( applicationKP );
+    User::LeaveIfError( iKeyPresses.Append( applicationKP ) );
+    CleanupStack::Pop( applicationKP );
+    }
+
+// --------------------------------------------------------------------------------------------
+TUid CAppKeyPressManager::KillApplication( TBool aRandomApplication )
+    {
+    TUid applicationUid = KNullUid;
+    TInt appToDelete = iKeyPresses.Count() - 1 ;
+    // remove the newest application if not random 
+    if ( aRandomApplication )
+        {
+         appToDelete = CLoadGenModel::RandomNumber( 0, iKeyPresses.Count() - 1 );
+        }
+    if ( iKeyPresses.Count() )
+        {
+        // get random application and delete it
+        
+        applicationUid = iKeyPresses[appToDelete]->ApplicationUid();
+        delete iKeyPresses[appToDelete];
+        iKeyPresses.Remove( appToDelete );
+        }
+    return applicationUid;
+    }
+// --------------------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------
+
+CApplicationKeyPresses* CApplicationKeyPresses::NewL( TUid aUid, TApplicationsAttributes&  
+        aAttributes )
+    {
+    LOGSTRING("LoadGen: CApplicationKeyPresses::NewL");
+    CApplicationKeyPresses* self = new(ELeave) CApplicationKeyPresses( aUid, aAttributes );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+
+CApplicationKeyPresses::CApplicationKeyPresses( TUid aUid, 
+                                                        TApplicationsAttributes& aAttributes ) :
+                                                iUid( aUid ), iAttributes( aAttributes ) 
+    {
+    LOGSTRING("LoadGen: CApplicationKeyPresses::CApplicationKeyPresses");
+    }
+
+// --------------------------------------------------------------------------------------------
+    
+CApplicationKeyPresses::~CApplicationKeyPresses()
+    {
+    LOGSTRING("LoadGen: CApplicationKeyPresses::~CApplicationKeyPresses");
+    if ( iPeriodicTimer )
+        {
+        iPeriodicTimer->Cancel();
+        delete iPeriodicTimer;
+        }
+    
+    iWsSession.Close();
+    }
+
+// --------------------------------------------------------------------------------------------
+ 
+void CApplicationKeyPresses::ConstructL()
+    {
+    LOGSTRING("LoadGen: CApplicationKeyPresses::ConstructL");
+    // init
+    User::LeaveIfError( iWsSession.Connect() );
+    
+    // start timer    
+    iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+    if ( iAttributes.iKeyPressType )
+        {
+        iPeriodicTimer->Start( KDefaultStartDelay,
+                               CLoadGenModel::MilliSecondsToMicroSeconds( 
+                                       iAttributes.iHeartBeat,
+                                       iAttributes.iRandomVariance ),
+                                TCallBack( PeriodicTimerCallBack, this ) );
+        }
+    }
+    
+// --------------------------------------------------------------------------------------------
+
+TInt CApplicationKeyPresses::PeriodicTimerCallBack( TAny* aAny )
+    {
+    CApplicationKeyPresses* self = static_cast<CApplicationKeyPresses*>( aAny );
+    self->SimulateKeyEvent();
+    return KErrNone;
+    }
+    
+// --------------------------------------------------------------------------------------------
+ 
+void CApplicationKeyPresses::SimulateKeyEvent()
+    {
+    LOGSTRING("LoadGen: CApplicationKeyPresses::SimulateKeyEvent");
+    // for arrow key events
+    
+    TInt wgId(0);
+    CApaWindowGroupName::FindByAppUid( iUid, iWsSession, wgId );
+    // generate a random arrow key event
+    TWsEvent event;
+    event.SetType( EEventKey );
+    event.Key()->iCode = CLoadGenModel::RandomNumber( EKeyLeftArrow, EKeyDownArrow );
+    event.Key()->iScanCode = event.Key()->iCode - KScanCodeStart;
+    event.Key()->iModifiers = 0;
+    event.Key()->iRepeats = 0;
+    iWsSession.SendEventToWindowGroup( wgId, event );
+    }
+
+// End of File