示例#1
0
void CApaAppStart::DoStartAppL(const TDesC &aFileName, 
					const TDesC& aArgs, 
					TBool aViewLess, 
					TBool aStartInBackground, 
					TThreadId& aThreadId, 
					TRequestStatus* aRequestStatusForRendezvous)
	{
	// Create an 8-bit variant of aArgs
	RBuf writableArgs;
	writableArgs.CreateL(aArgs);
	CleanupClosePushL(writableArgs);
	TPtr8 args8 = writableArgs.Collapse();
	
	CApaCommandLine* const cmdLine = CApaCommandLine::NewLC();
	SetupCommandLineL(*cmdLine, aFileName, args8, aViewLess, aStartInBackground) ;

	User::LeaveIfError(iApaLsSession.StartApp(*cmdLine, aThreadId, aRequestStatusForRendezvous));
	
	CleanupStack::PopAndDestroy(cmdLine);
	CleanupStack::PopAndDestroy(&writableArgs);
	}
/**
 * Read command line parameters and control the launching of targets. 
 * Create global launch semaphore KLaunchSemaphoreName
 */
void MainL()
    {

    TInt numApps = KNumApps;
    TInt numLaunches = KNumLaunches;
    TInt launchControl = 0;

    TInt argc = User::CommandLineLength();
    HBufC* commandLine = NULL;
    RDebug::Printf( ">Launcher Process() argc=%d", argc );

    if( argc )
        {
        commandLine = HBufC::NewLC(argc);
        TPtr commandLineBuffer = commandLine->Des();
        User::CommandLine(commandLineBuffer);

        RBuf printCommandLine;
        CleanupClosePushL( printCommandLine );
        printCommandLine.CreateL( commandLine->Des().Length() );
        printCommandLine.Copy( commandLine->Des() );
        printCommandLine.Collapse();
        RDebug::Printf( ">command line = %S", &printCommandLine );
        CleanupStack::PopAndDestroy( &printCommandLine );

        // create a lexer and read through the command line
        TLex lex(*commandLine);
        while (!lex.Eos())
            {
            // only look for options with first character '+', other switches are for the targets
            if (lex.Get() == '+')
                {
                TChar arg = lex.Get();
                switch (arg)
                    {
                    case 'n':
                        lex.Val( numApps );
                        RDebug::Printf("parsed numApps as %d", numApps);
                        break;
                    case 'm':
                        lex.Val( numLaunches );
                        RDebug::Printf("parsed numLaunches as %d", numLaunches );
                        break;
                    case 'o':
                        lex.Val( launchControl );
                        RDebug::Printf("parsed launchControl as %d", launchControl);
                        break;
                    default:
                        // unknown argument ignore it
                        break;             
                    }//switch
                }// if +
            }//while
        }//if argc

   RSemaphore launchSemaphore;
   TInt ret = KErrNone;
   CleanupClosePushL( launchSemaphore );
   ret = launchSemaphore.CreateGlobal( KLaunchSemaphoreName, 0 );
   RDebug::Printf( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret);
   User::LeaveIfError( ret );

   ret = launchSemaphore.OpenGlobal( KLaunchSemaphoreName );
   RDebug::Printf( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret);
   User::LeaveIfError( ret );
   
   //Only now indicate to the launcher that we have fully started, so they can find and open the semaphore
   RProcess::Rendezvous(KErrNone);

   //Now launch the requested number of apps for the requested number of launches
   for( ; numLaunches > 0; numLaunches-- )
       { 
       for( TInt launchIndex = numApps; launchIndex > 0; launchIndex-- )  
           {
           RDebug::Printf( ">Target Launcher:  Semaphore wait app %d, launch %d", launchIndex, numLaunches );
           launchSemaphore.Wait();

           RBuf targetName;
           CleanupClosePushL( targetName );
           RDebug::Printf( ">Target Launcher:  targetName.Create %d, launch %d", launchIndex, numLaunches );
           targetName.Create( KTargetExe().Length() + 2 );

           if( launchControl == 1 )
               {
               // Reverse the order of the apps launched by reversing the index in the name
               RDebug::Printf( ">Target Launcher:  targetName.Format %d, launch %d", numApps - launchIndex + 1, numLaunches );
               targetName.Format( KTargetExe(), numApps - launchIndex + 1 );
               }
           else
               {
               RDebug::Printf( ">Target Launcher:  targetName.Format %d, launch %d", launchIndex, numLaunches );
               targetName.Format( KTargetExe(), launchIndex );
               }

           RProcess aProc;
           CleanupClosePushL( aProc ); 
    
           RDebug::Printf( ">Target Launcher: LaunchProcess %d, launch %d", launchIndex, numLaunches );
           RDebug::Printf( ">LaunchProcess %lS", &targetName );
           TPtr cmdLinePtr( commandLine->Des() );
           ret = LaunchProcess( aProc, targetName, cmdLinePtr );
           CleanupStack::PopAndDestroy( &aProc );

           RDebug::Printf( "<Target Launcher: LaunchProcess returned %d", ret );
           CleanupStack::PopAndDestroy( &targetName );

           User::LeaveIfError( ret );

           //By now the add proc event should have been delivered to the
           //test app agent.
           }
       }

    launchSemaphore.Wait( 500000 );

    CleanupStack::PopAndDestroy( &launchSemaphore );

    if( commandLine )
       CleanupStack::PopAndDestroy( commandLine );
 
    }
/**
 * Read command line parameters and control the launching of the agents. 
 */
void MainL()
	{	
	LOG_MSG( "ENTER: t_multi_agent_launcher MainL()");

	TInt ret = KErrNone;
	TInt numAgents = KNumAgents;
	TInt numTargets = KNumTargets;
	TInt numTestRuns = KNumTestRuns;

	TInt argc = User::CommandLineLength();
	HBufC* commandLine = NULL;
	LOG_MSG2("t_multi_agent_launcher: MainL(): argc=%d", argc);
    
	if(argc)
		{
		commandLine = HBufC::NewLC(argc);
		TPtr commandLineBuffer = commandLine->Des();
		User::CommandLine(commandLineBuffer);

		RBuf printCommandLine;
		CleanupClosePushL( printCommandLine );
		printCommandLine.CreateL( commandLine->Des().Length() );
		printCommandLine.Copy( commandLine->Des() );
		printCommandLine.Collapse();
		LOG_MSG2("t_multi_agent_launcher: command line = %S", &printCommandLine);
		CleanupStack::PopAndDestroy( &printCommandLine );
 
		// create a lexer and read through the command line
		TLex lex(*commandLine);
		while (!lex.Eos())
			{
			// only look for options with first character '-'
			if (lex.Get() == '-')
				{
					TChar arg = lex.Get();
					switch ( arg )
						{
						case 'n':
							lex.Val( numAgents );
							LOG_MSG2("t_multi_agent_launcher: parsed numAgents as %d", numAgents);
							break;
						case 'm':
							lex.Val( numTargets );
							LOG_MSG2("t_multi_agent_launcher: parsed numTargets as %d", numTargets);                        
							break;  
						case 't':
							lex.Val( numTestRuns );
							LOG_MSG2("t_multi_agent_launcher: parsed numTestRuns as %d", numTestRuns);                        
							break;                    
						default:
							LOG_MSG("t_multi_agent_launcher: unknown argument ignoring it");
							break;                 
						}
				}
			}
		}

	// Note: below is a workaround to overcome an issue with RTest server crashing 
	// when writing to the windows console from different agents (on different CPUs 
	// at the same time). To overcome this we get signaled by the agents when they have 
	// completed their tests so that we can do a RTest complete
	RSemaphore launchSemaphore;
	CleanupClosePushL(launchSemaphore);
	ret = launchSemaphore.CreateGlobal(KLaunchSemaphoreName, 0);
	LOG_MSG2( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret);
	User::LeaveIfError( ret );

	ret = launchSemaphore.OpenGlobal(KLaunchSemaphoreName);
	LOG_MSG2( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret);
	User::LeaveIfError( ret );

	//Now launch the requested number of apps for the requested number of test runs
	for( TInt j = 0; j < numTestRuns; j++ )
		{ 
			for( TInt i = 0; i < numAgents; i++ )  
				{
					RBuf targetName;
					targetName.CleanupClosePushL();
					targetName.CreateL(KAgentExe());

					RProcess aProc;
					CleanupClosePushL(aProc); 
					RBuf launcherOptions;
					CleanupClosePushL(launcherOptions);
				    const TInt additionalWords = 2;	
					launcherOptions.CreateL( KAgentOptions().Length() + additionalWords );
		
					// Apply offset: launcherOptions.Format( .., .., i * numTargets, ..)
					// workaround to ensure we have the same binary for multiple agents. 
					// e.g. So if offset = 0, agent attaches to app1, app2, app3, app4, app5
					// if offset = 5, agent attached to app6, app7, app8, app9, app10 etc.
					// Note: apps need to be in rom otherwise the agent will fail on an assert 
					// (with KErrNotFound)
					launcherOptions.Format( KAgentOptions(), (TUint)numTargets, i * numTargets, 0);
			
					ret = LaunchProcess( aProc, targetName, launcherOptions );	
					CleanupStack::PopAndDestroy(3,&targetName);
					User::LeaveIfError(ret);
				}
		}

	// Wait for all agents to do their testing before checking the semaphore
	User::After(12000000);

	LOG_MSG( ">Target Launcher:  Semaphore wait");

	for (TInt i = 0; i < numAgents; i ++)
		{
		//We need this delay just in case an agent crashes and never signals the sem
		ret = launchSemaphore.Wait(100000);
		if( ret != KErrNone )
			{
			LOG_MSG3("launchSemaphore.Wait ret %d for agent %d", ret, i);
			break;
			}
		}

	LOG_MSG2( "testing for Semaphore ret %d", ret);

	// We only want to have one RTest instance at any one time since otherwise RTest can panic
	RTest test(_L("T_MULTI_AGENT_LAUNCHER"));
	test.Start(_L("t_multi_agent_launcher Check for agents finishing correctly"));
	test(ret == KErrNone);
	test.End();
	test.Close();

	CleanupStack::PopAndDestroy(&launchSemaphore); // launchSemaphore

	if( commandLine )
	CleanupStack::PopAndDestroy(commandLine);
	
	LOG_MSG("EXIT: t_multi_agent_launcher MainL()");
	}
TInt CMultiTargetAgent::LaunchTargetsInOrderL()
{
    RDebug::Printf( "CMultiTargetAgent::LaunchTargetsInOrderL" );

    RBuf launcher;
    CleanupClosePushL( launcher );
    launcher.CreateL( KLauncherExe() );

    RBuf launcherOptions;
    CleanupClosePushL( launcherOptions );
    launcherOptions.CreateL( KTargetOptions().Length() + 2 );
    launcherOptions.Format( KTargetOptions(), (TUint)ENormalExit );

    RDebug::Printf( ">LaunchProcess()" );
    RProcess launcherProc;
    CleanupClosePushL( launcherProc );

    TInt ret = LaunchProcess( launcherProc, launcher, launcherOptions );
    RDebug::Printf( "<LaunchProcess() ret %d", ret );

    CleanupStack::PopAndDestroy( &launcherProc ); // launcherProc
    CleanupStack::PopAndDestroy( &launcherOptions ); // launcherOptions
    CleanupStack::PopAndDestroy( &launcher ); //launcher

    test( ret == KErrNone );

    RSemaphore launchSemaphore;
    CleanupClosePushL( launchSemaphore );

    TFindSemaphore launchSemFinder( KLaunchSemaphoreNameSearchString );
    TFullName semaphoreResult;
    ret = launchSemFinder.Next(semaphoreResult);
    RDebug::Printf( ">  Find Launch Semaphote.Next ret=%d, %lS", ret, &semaphoreResult );
    test( ret == KErrNone );

    ret = launchSemaphore.OpenGlobal( semaphoreResult );
    RDebug::Printf( "> OpenGlobal semaphore ret=%d", ret );
    test( ret == KErrNone );

    TBool thisLaunchCompleted;

    test.Next(_L("LaunchTargetsInOrderL\n"));
    for( TInt numLaunches = KNumLaunches; numLaunches > 0; numLaunches-- )
    {
        for( TInt numApps = KNumApps; numApps > 0; numApps-- )
        {
            thisLaunchCompleted = EFalse;
            // This will trigger the launcher app to launch the next target
            RDebug::Printf( " >Semaphore.Signal app=%d, launch=%d", numApps, numLaunches);
            launchSemaphore.Signal();

            RBuf8 tgt8Name;
            CleanupClosePushL( tgt8Name );

            RBuf tgtCollapseName;
            CleanupClosePushL( tgtCollapseName );

            tgtCollapseName.CreateL( iTargets[numApps-1] );
            tgt8Name.CreateL( tgtCollapseName.Collapse() );


            while( ! thisLaunchCompleted )
            {
                RDebug::Printf( ">GetEvent app %d for %S", numApps, &tgt8Name );
                iServSession.GetEvent( iTargets[numApps-1], iStatus, iEventPtr );

                // Wait for the target to get started.
                RDebug::Printf( " >Wait for event from target app=%d, launch=%d\n", numApps, numLaunches);
                User::WaitForRequest( iStatus );
                RDebug::Printf( " <Wait for request returned with status %d", iStatus.Int() );
                test( iStatus==KErrNone );

                RDebug::Printf( " > Got iEventType =%d, app=%d", iEventInfo.iEventType, numApps );
                switch( iEventInfo.iEventType )
                {
                case EEventsAddProcess:
                {
                    RDebug::Printf( "Got EEventsAddProcess" );
                    TPtrC8 exeNamePtr8( iEventInfo.iAddProcessInfo.iFileName, iEventInfo.iAddProcessInfo.iFileNameLength );

                    RBuf8 exeName8;
                    CleanupClosePushL( exeName8 );
                    exeName8.CreateL( exeNamePtr8 );
                    RDebug::Printf( " from event: exeName8=%S", &exeName8 );
                    CleanupStack::PopAndDestroy( &exeName8 );

                    RBuf8 compareName8;
                    CleanupClosePushL( compareName8 );
                    compareName8.CreateL( KTargetExeName().Length() + 10 );
                    compareName8.Format( KTargetExeName(), numApps );
                    RDebug::Printf( " comparing to: compareName8=%S", &compareName8 );

                    test( compareName8.CompareC( exeNamePtr8 ) == 0 );
                    CleanupStack::PopAndDestroy( &compareName8 );

                    RDebug::Printf( "Testing if event process id is valid" );
                    test( iEventInfo.iProcessIdValid );
                    RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) );

                    RProcess targetProc;
                    ret = targetProc.Open( TProcessId( iEventInfo.iProcessId ) );
                    RDebug::Printf( "RProcess open ret=%d",ret );
                    targetProc.Close();
                    test( ret == KErrNone );

                    break;
                }//EEventsAddProcess

                case EEventsStartThread:
                {
                    RDebug::Printf( "Got EEventsStartThread" );

                    TPtrC8 exeNamePtr8( iEventInfo.iStartThreadInfo.iFileName, iEventInfo.iStartThreadInfo.iFileNameLength );
                    RBuf8 exe8Name;
                    CleanupClosePushL( exe8Name );
                    exe8Name.CreateL( exeNamePtr8 );
                    RDebug::Printf( " from event: exeName8=%S", &exe8Name );
                    CleanupStack::PopAndDestroy( &exe8Name );

                    test( tgt8Name.CompareC( exeNamePtr8 ) == 0 );

                    RDebug::Printf( "Testing if event process id is valid" );
                    test( iEventInfo.iProcessIdValid );
                    RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) );

                    RDebug::Printf( "Testing if event thread id is valid" );
                    test( iEventInfo.iThreadIdValid );
                    RDebug::Printf( "Got iEventInfo.iThreadId=%d", I64LOW( iEventInfo.iThreadId ) );

                    RThread targetThread;
                    CleanupClosePushL( targetThread );

                    ret = targetThread.Open( TThreadId( iEventInfo.iThreadId ) );
                    RDebug::Printf( "RThread open ret=%d", ret );
                    test( ret == KErrNone );

                    test( iEventInfo.iThreadId == targetThread.Id() );

                    RDebug::Printf( "Resuming thread for app=%d, id=%d", numApps, I64LOW( targetThread.Id() ));
                    ret = iServSession.ResumeThread( iEventInfo.iThreadId );
                    CleanupStack::PopAndDestroy( &targetThread );

                    test( ret == KErrNone );

                    ret = iServSession.ResumeThread( iEventInfo.iThreadId );
                    break;
                }//case EEventsStartThread

                case ( EEventsRemoveProcess ):
                {
                    RDebug::Printf( "*** Got EEventsRemoveProcess. app%d has exited. Moving on to next app", numApps );
                    thisLaunchCompleted = ETrue;
                    break;
                }

                default :
                    RDebug::Printf( "Got unknown event" );
                    test( EFalse );
                    break;
                }
            }//while

            CleanupStack::PopAndDestroy( &tgtCollapseName ); // tgtCollapseName
            CleanupStack::PopAndDestroy( &tgt8Name ); // tgt8Name
        }
    }

    launchSemaphore.Signal();

    CleanupStack::PopAndDestroy( &launchSemaphore ); // launchSemaphore

    for( TInt i = iTargets.Count()-1; i>=0; i-- )
    {
        RDebug::Printf( "Closing target %d", i );
        iTargets[ i ].Close();
    }

    iTargets.Close();

    return KErrNone;
}