//Query the aItem from Table DscItem void CDscDatabase::QueryItemL(RDbView& aView, const CDscItem& aItem) const { RBuf sqlCmd; CleanupClosePushL(sqlCmd); if (aItem.ItemId()) { sqlCmd.CreateL(KSqlSelectDscItemOnIdLength); sqlCmd.Format( KSqlSelectDscItemOnId, &KDscIdCol, &KItemIdCol, &KFileNameCol, &KArgListCol,&KStartMethodCol, &KTimeoutCol, &KNoOfRetriesCol, &KMonitorCol, &KStartupTypeCol, &KViewlessCol, &KStartInBackgroundCol, &KItemTable, &KDscIdCol, aItem.DscId(), &KItemIdCol, aItem.ItemId()); } else { const TPtrC filename = aItem.FileName(); const TPtrC argList = aItem.Args(); //whitespace already trimmed LeaveIfFileParamsNotValidL(aItem); const TInt length = KSqlSelectDscItemOnNameLength + filename.Length() + argList.Length(); sqlCmd.CreateL(length); sqlCmd.Format(KSqlSelectDscItemOnName, &KDscIdCol, &KItemIdCol, &KFileNameCol,&KArgListCol, &KStartMethodCol, &KTimeoutCol, &KNoOfRetriesCol, &KMonitorCol, &KStartupTypeCol, &KViewlessCol, &KStartInBackgroundCol, &KItemTable, &KDscIdCol, aItem.DscId(), &KFileNameCol, &filename, &KArgListCol, &argList); } DebugPrint(sqlCmd); User::LeaveIfError(aView.Prepare(iDatabase, sqlCmd)); User::LeaveIfError(aView.EvaluateAll()); //no error for non existing item CleanupStack::PopAndDestroy(&sqlCmd); }
void CDscDatabase::CreateTablesL() { RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KMaxDdlLength); //Start a new transaction DatabaseBeginLC(); //Create Table DSC sqlCmd.Format(KSqlCreateDscTable, &KDscTable, &KDscIdCol, &KDescriptionCol, KDbUndefinedLength); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); //Create unique index for Table DSC sqlCmd.Format(KSqlCreateDscIndex, &KIdIndex, &KDscTable, &KDscIdCol); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); //Create Table DscItem sqlCmd.Format(KSqlCreateItemTable, &KItemTable, &KDscIdCol, &KItemIdCol, &KFileNameCol, KDbUndefinedLength, &KArgListCol, KDbUndefinedLength, &KStartMethodCol, &KTimeoutCol, &KNoOfRetriesCol, &KMonitorCol, &KStartupTypeCol, &KViewlessCol, &KStartInBackgroundCol); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); //Create unique index for Table DscItem sqlCmd.Format(KSqlCreateItemIndex, &KIndex, &KItemTable, &KDscIdCol, &KItemIdCol); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); DatabaseCommitL(); //CommitL + CleanupStack::Pop() CleanupStack::PopAndDestroy(&sqlCmd); }
//Delete the DSC with aDscId, all items related to aDscId are deleted too. void CDscDatabase::DeleteDscL(const TUid& aDscId) { //If the DSC is opened for enumeration, leave with KErrLocked if (iIsEnumOpened) { User::Leave(KErrLocked); } //Start a new transaction DatabaseBeginLC(); if (!DscExistsL(aDscId)) { // aDscId doesn't exist, leave with KErrNotFound User::Leave(KErrNotFound); } RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KSqlDeleteUsingIdLength); //Delete all items related with aDscId first sqlCmd.Format(KSqlDeleteUsingId, &KItemTable, &KDscIdCol, aDscId); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); //Then delete the row in Table DSC sqlCmd.Format(KSqlDeleteUsingId, &KDscTable, &KDscIdCol, aDscId); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); CleanupStack::PopAndDestroy(&sqlCmd); DatabaseCommitL(); //CommitL + CleanupStack::Pop() }
//Update aItem. void CDscDatabase::UpdateItemL(const CDscItem& aItem) { //Leave if DB is opened for enumeration if (iIsEnumOpened) { User::Leave(KErrLocked); } if(aItem.ItemId() == 0) { LeaveIfFileParamsNotValidL(aItem); } DatabaseBeginLC(); //Leave if aItem does not exist if (!ItemExistsL( aItem)) { User::Leave(KErrNotFound); } RBuf sqlCmd; CleanupClosePushL(sqlCmd); if (aItem.ItemId()) { sqlCmd.CreateL(KSqlUpdateUsingIdLength); sqlCmd.Format(KSqlUpdateUsingId, &KItemTable, &KStartMethodCol, aItem.StartMethod(), &KTimeoutCol, aItem.Timeout(), &KNoOfRetriesCol, aItem.NoOfRetries(), &KMonitorCol, aItem.Monitored(), &KStartupTypeCol, aItem.StartupType(), &KViewlessCol, aItem.Viewless(), &KStartInBackgroundCol, aItem.StartInBackground(), &KDscIdCol, aItem.DscId(), &KItemIdCol, aItem.ItemId()); } else { const TPtrC filename = aItem.FileName(); const TPtrC argList = aItem.Args(); //whitespace already trimmed const TInt length = KSqlUpdateUsingNameLength + filename.Length() + argList.Length(); sqlCmd.CreateL(length); sqlCmd.Format(KSqlUpdateUsingName, &KItemTable, &KStartMethodCol, aItem.StartMethod(), &KTimeoutCol, aItem.Timeout(), &KNoOfRetriesCol, aItem.NoOfRetries(), &KMonitorCol, aItem.Monitored(), &KStartupTypeCol, aItem.StartupType(), &KViewlessCol, aItem.Viewless(), &KStartInBackgroundCol, aItem.StartInBackground(), &KDscIdCol, aItem.DscId(), &KFileNameCol, &filename, &KArgListCol, &argList); } DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); CleanupStack::PopAndDestroy(&sqlCmd); DatabaseCommitL(); //CommitL + CleanupStack::Pop() }
//Open a view of items with aDscID for enumeration, need to //call EnumClose() to close the view after enumeration. void CDscDatabase::EnumOpenLC(const TUid& aDscId) { //If the DSC is opened for enumeration, leave with KErrLocked if (iIsEnumOpened) { User::Leave(KErrLocked); } //Start a new transaction to add read-lock on DSC EnumBeginLC(); //Leave with KErrNotFound if aDscId doesn't exist if (!DscExistsL(aDscId)) { User::Leave(KErrNotFound); } iIsEnumOpened = ETrue; //Open a view contains all items in aDscId RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KSqlSelectAllItemsInDscLength); sqlCmd.Format(KSqlSelectAllItemsInDsc, &KDscIdCol, &KItemIdCol, &KFileNameCol, &KArgListCol, &KStartMethodCol, &KTimeoutCol, &KNoOfRetriesCol, &KMonitorCol, &KStartupTypeCol, &KViewlessCol, &KStartInBackgroundCol, &KItemTable, &KDscIdCol, aDscId, &KItemIdCol); DebugPrint(sqlCmd); User::LeaveIfError(iView.Prepare(iDatabase, sqlCmd)); User::LeaveIfError(iView.EvaluateAll()); //no error for non existing item CleanupStack::PopAndDestroy(&sqlCmd); }
void CDscDatabase::GetDscDescriptionL(const TUid &aDscId, TDes& aDescription) const { RDbView view; CleanupClosePushL(view); RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KSqlSelectDscDescriptionLength); sqlCmd.Format(KSqlSelectDscDescription, &KDescriptionCol, &KDscTable, &KDscIdCol, aDscId); DebugPrint(sqlCmd); User::LeaveIfError(view.Prepare(iDatabase, sqlCmd)); User::LeaveIfError(view.EvaluateAll()); CleanupStack::PopAndDestroy(&sqlCmd); if(view.IsEmptyL()) { User::Leave(KErrNotFound); } view.FirstL(); view.GetL(); //Check the length of aDescription TPtrC description(view.ColDes(1)); if (description.Length() > aDescription.MaxLength()) { User::Leave(KErrOverflow); } aDescription.Zero(); aDescription=description; CleanupStack::PopAndDestroy(&view); }
//Add a DSC with aDscId to DSC DB. if the aDscId exists, leave with KErrAlreadyExists void CDscDatabase::CreateDscL(const TUid& aDscId, const TDesC& aDescription) { //The maximum length of aDescription is KDbMaxStrLen if(aDescription.Length() > KDbMaxStrLen) { User::Leave(KErrArgument); } //If the DSC is opened for enumeration, leave with KErrLocked if (iIsEnumOpened) { User::Leave(KErrLocked); } //Start a new transaction DatabaseBeginLC(); //Insert aDscId in Table DSC. If aDscId exists, will leave with KErrAlreadyExists RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KSqlInsertDscLength + aDescription.Length()); sqlCmd.Format(KSqlInsertDsc, &KDscTable, &KDscIdCol, &KDescriptionCol, aDscId, &aDescription); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); CleanupStack::PopAndDestroy(&sqlCmd); DatabaseCommitL(); //CommitL + CleanupStack::Pop() }
/** Launch a process @param aExeName the executable used to create the process @param aCommandLine the commandline parameters passed to the new process file name of the executable used to create the process @return KErrNone on success, or one of the other system wide error codes */ TInt CRunModeAgent::LaunchProcessL( RProcess& aProcess, const TDesC& aExeName, const TDesC& aCommandLine ) { LOG_ENTRY(); RBuf launcherOptions; launcherOptions.CleanupClosePushL(); const TInt additionalWords = 1; launcherOptions.CreateL( aCommandLine.Length() + additionalWords ); launcherOptions.Format( aCommandLine, iParams.iTestTargetPriority); LOG_DES(_L("launcherOptions %S"), &launcherOptions); TInt err = aProcess.Create( aExeName, launcherOptions ); CleanupStack::PopAndDestroy(); // check that there was no error raised if (err != KErrNone) return err; // rendezvous with process TRequestStatus status = KRequestPending; aProcess.Rendezvous(status); // start the test target aProcess.Resume(); User::WaitForRequest(status); if(KErrNone != status.Int()) { aProcess.Kill(KErrNone); } LOG_EXIT(); return status.Int(); }
//Add aItem to DSC at aPos void CDscDatabase::AddItemL(CDscItem& aItem, TDscPosition aPos) { //Leave if DB is opened for enumeration if (iIsEnumOpened) { User::Leave(KErrLocked); } //verify data integrity, LeaveIfFileParamsNotValidL(aItem); if(aItem.ItemId() != 0) { User::Leave(KErrArgument); } //Start transaction DatabaseBeginLC(); //Leave if aDscId doesn't exist if (!DscExistsL(aItem.DscId())) { User::Leave(KErrNotFound); } //Leave if aItem exists if (ItemExistsL(aItem)) { User::Leave(KErrAlreadyExists); } const TPtrC filename = aItem.FileName(); const TPtrC argList = aItem.Args(); //whitespace already trimmed const TInt itemId = GetNextItemIdL(aPos, aItem.DscId()); RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KSqlInsertDscItemLength + filename.Length() + argList.Length()); //insert the item sqlCmd.Format(KSqlInsertDscItem, &KItemTable, &KDscIdCol, &KItemIdCol, &KFileNameCol, &KArgListCol, &KStartMethodCol, &KTimeoutCol, &KNoOfRetriesCol, &KMonitorCol, &KStartupTypeCol, &KViewlessCol, &KStartInBackgroundCol, aItem.DscId(), itemId, &filename, &argList, aItem.StartMethod(), aItem.Timeout(), aItem.NoOfRetries(), aItem.Monitored(), aItem.StartupType(), aItem.Viewless(), aItem.StartInBackground()); DebugPrint(sqlCmd); User::LeaveIfError(iDatabase.Execute(sqlCmd)); CleanupStack::PopAndDestroy(&sqlCmd); DatabaseCommitL(); //CommitL + CleanupStack::Pop() //Now aItem is persistent, set the ItemId so it can be read by the client aItem.SetItemId(itemId); }
void CWindowGroupListBoxData::DoFormatL(TObjectKernelInfo* aInfo, RBuf& name, RBuf& more, TInt& /*itemId*/) { SWgInfo& info = *reinterpret_cast<SWgInfo*>(aInfo); CApaWindowGroupName* wgName = info.iName; name.Copy(wgName->Caption()); _LIT(KUnnamed, "<Untitled window group>"); if (name.Length() == 0) name.Copy(KUnnamed); TThreadId tid; TInt res = info.iSession->GetWindowGroupClientThreadId(info.iHandle, tid); if (res == KErrNone) { res = tid; } more.Format(_L("Busy=%i System=%i Tid=%i"), wgName->IsBusy(), wgName->IsSystem(), res); }
/** Helper function. Get the next available itemId for the item. Reads all existing ItemIds for the specified DscId, then calculates last+1 or first-1 depending on aPos. Will never return 0 as its reserved to mean not yet persistent. */ TInt CDscDatabase::GetNextItemIdL(TDscPosition aPos, const TUid& aDscId) const { RDbView view; CleanupClosePushL(view); RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KSqlQueryAllItemIdsLength); sqlCmd.Format(KSqlQueryAllItemIds, &KItemIdCol, &KItemTable,&KDscIdCol, aDscId, &KItemIdCol ); DebugPrint(sqlCmd); User::LeaveIfError(view.Prepare(iDatabase, sqlCmd)); User::LeaveIfError(view.EvaluateAll()); CleanupStack::PopAndDestroy(&sqlCmd); TInt nextId = 1; //add first item with id=1 and reserve 0 to mean "not yet persistent" if (aPos==ELast && view.LastL()) { //add at ELast: pos =max of itemId+1 view.GetL(); nextId = view.ColInt(1); if(KMaxTInt == nextId) { User::Leave(KErrOverflow); } //increase, make sure to not use 0 as itemid in the database nextId = (-1==nextId) ? (nextId+2) : (nextId+1); } else if (aPos==EFirst && view.FirstL()) { //add at EFirst: pos=min of itemId-1 view.GetL(); nextId = view.ColInt(1); if(KMinTInt == nextId) { User::Leave(KErrUnderflow); } //decrease, but reserve 0 to mean "not yet persistent" nextId = (1==nextId) ? (nextId-2) : (nextId-1); } CleanupStack::PopAndDestroy(&view); return nextId; }
//Check the existance of a DSC TBool CDscDatabase::DscExistsL(const TUid& aDscId) const { RDbView view; CleanupClosePushL(view); RBuf sqlCmd; CleanupClosePushL(sqlCmd); sqlCmd.CreateL(KSqlSelectDscLength); sqlCmd.Format(KSqlSelectDsc, &KDscIdCol, &KDscTable, &KDscIdCol, aDscId); DebugPrint(sqlCmd); User::LeaveIfError(view.Prepare(iDatabase, sqlCmd)); User::LeaveIfError(view.EvaluateAll()); const TBool dscExists = !view.IsEmptyL(); CleanupStack::PopAndDestroy(&sqlCmd); CleanupStack::PopAndDestroy(&view); return (dscExists); }
/** * 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()"); }
void CFeatRegListBoxData::DoFormatL(TObjectKernelInfo* aInfo, RBuf& name, RBuf& more, TInt& /*itemId*/) { SFeature& info = *reinterpret_cast<SFeature*>(aInfo); more.Format(_L("Value: %i Info: %i"), info.iErr, info.iInfo); gPlugin->FormatValue(name, MProductPlugin::EFeature, info.iFeature, 0); }
/** * 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 ); }
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; }