diff -r 000000000000 -r 8e480a14352b messagingfw/msgtest/targetautomation/TechviewStart/Starter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/msgtest/targetautomation/TechviewStart/Starter.cpp Mon Jan 18 20:36:02 2010 +0200 @@ -0,0 +1,445 @@ +// Copyright (c) 1997-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 "Starter.h" +#include "AppStarter.h" +#include "ThreadWatch.h" +#include +#include "MsvTestUtils.h" +#include +#include "Start.hrh" + +typedef TInt (*ShellEntryPoint)(TAny *); +#if defined(__WINS__) +LOCAL_D const TUint KHeapSize=0x10000; +LOCAL_D const TUint KMaxHeapSize=0x400000; +#endif + + +_LIT(KStubRunResourceFileName, "Z:\\SYSTEM\\PROGRAMS\\Start.RSC"); +_LIT(KGlobalSemaphore, "SPLASH"); +_LIT(KStartChunkName,"Start"); + +const TInt KRetryTime = 100000; + +/** +@internalComponent +*/ +TBool definedPhonePwrValue = EFalse; + + +/** +* Contructor +*/ +CStarter::CStarter() : CActive(EPriorityStandard), iNrSemaphore(0) + {} + +/** +* Destructor. +*/ +CStarter::~CStarter() + { + if (iQueHeader) + { + while (!(iQueHeader->IsEmpty())) + { + CThreadWatcher* threadWatcher = iQueHeader->First(); + iQueHeader->Remove(*threadWatcher); + delete threadWatcher; + } + delete iQueHeader; + } + + iLsSess.Close(); +#if defined (__WINS__) + iAppUiSession.Close(); +#endif + delete iStartupList; + delete iExtrasList; + delete iSplashExe; + iCmdLineArgs.Close(); + iResourceFile.Close(); + iFsSession.Close(); + } + +/** +* Creates an instance of a CStarter object. +* @return a pointer to this object +*/ +CStarter* CStarter::NewL() + { + CStarter* self = new (ELeave) CStarter; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +/** +* Handles the actual initialization of this object. +*/ +void CStarter::ConstructL() + { + // Connect to the File Server + while (iFsSession.Connect() != KErrNone) + { + User::After(KRetryTime); + } + + //Connected to File Server + iResourceFile.OpenL(iFsSession, KStubRunResourceFileName); + + // read the first one + HBufC8* res = iResourceFile.AllocReadLC(R_APP_START_PARAMS); + TResourceReader theReader; + theReader.SetBuffer(res); + //Main configuration resource read + + // get data from it + iSplashExe = theReader.ReadHBufCL(); + + TUint32 applicationsListId = theReader.ReadInt32(); + TUint32 exeListId = theReader.ReadInt32(); + + // free up memory + CleanupStack::PopAndDestroy(); // res + + // prepare the data for the active object + iStartupList = iResourceFile.AllocReadL(applicationsListId); + iStartupListReader.SetBuffer(iStartupList); + iStartupCount = iStartupListReader.ReadUint16(); //The size of the resource array + + iExtrasList= iResourceFile.AllocReadL(exeListId); + iExtrasListReader.SetBuffer(iExtrasList); + iExtrasCount = iExtrasListReader.ReadUint16(); //The size of the resource array + + iQueHeader = new (ELeave) TSglQue(_FOFF(CThreadWatcher,iLink)); + + // Tell system agent the phone is on. + // This is only appropriate for 2-box solutions, and is needed for SMS sending and receiving. + // Also, at some point, this should probably be moved to a separate component that startup launches. + TInt testState; + if(KErrNone != RProperty::Get(KUidSystemCategory, KMsvTestUidPhonePwrValue, testState)) + { + User::LeaveIfError(RProperty::Define(KUidSystemCategory, KMsvTestUidPhonePwrValue, RProperty::EInt)); + definedPhonePwrValue = ETrue; + } + User::LeaveIfError(RProperty::Set(KUidSystemCategory, KMsvTestUidPhonePwrValue, EMsvTestPhoneOn)); + + if(definedPhonePwrValue) + { + User::LeaveIfError(RProperty::Delete(KUidSystemCategory, KMsvTestUidPhonePwrValue)); + } + + RChunk chunk; + TUint8 finish=0; + if( chunk.CreateGlobal(KStartChunkName,1,1)== KErrNone) + { + if( chunk.OpenGlobal(KStartChunkName,EFalse)== KErrNone) + { + TUint8* base=chunk.Base(); + *base=finish; + chunk.Close(); + } + } + } + +/** +* Actually launch the splash screen exe +*/ +void CStarter::StartSplashScreenL() + { + if (iSplashExe == NULL || iSplashExe->Length() == 0) + { + return; + } + + // launch the splash screen + TPtrC splashCmd; + splashCmd.Set(*iSplashExe); + +#if defined(__WINS__) + TParse fileName; + User::LeaveIfError(fileName.Set(_L(".DLL"),&splashCmd,NULL)); + User::LeaveIfError(iLib.Load(fileName.FullName())); + ShellEntryPoint libFunc=(ShellEntryPoint)iLib.Lookup(1); + if (!libFunc) + { + User::Leave(KErrGeneral); + } + TBuf<256> name; + TInt num=0; + TInt ret=KErrNone; + do + { + name.Format(TRefByValue(_L("Splash%d")),num++); + ret=iSplash.Create(name,libFunc,KDefaultStackSize,&splashCmd,&iLib,NULL,/*NULL,*/KHeapSize,KMaxHeapSize,EOwnerProcess); + } while(ret==KErrAlreadyExists); + User::LeaveIfError(ret); +#else + TFindFile findShell(iFsSession); + User::LeaveIfError(findShell.FindByDir(splashCmd,_L("\\System\\Programs\\.EXE"))); + //User::LeaveIfError(iSplash.Create(findShell.File(),splashCmd)); + TInt err1 = 0; + TRAPD(err,(err1 = iSplash.Create(findShell.File(),splashCmd))); //Change back to commented out line when E32 bug is fixed ### + if (err!=KErrNone && err1 != KErrNone) + { + iSplash.SetHandle(KNullHandle); + User::Leave(err); + } +#endif + iSplash.Resume(); + + } + +/** +* Method to be called to procced the startup +*/ +void CStarter::Start() + { + iStage = ESplashScreen; + RequestNotify(); + } + +/** +* Start then connect the Eikon server +*/ +void CStarter::Connect() + { + // Connect to the AppUi session, effective starting it. + while(iAppUiSession.Connect() != KErrNone) + { + User::After(KRetryTime); + } + + // Connect to the AppLsServer + while(iLsSess.Connect() != KErrNone) + { + User::After(KRetryTime); + } + + TInt count=0; + while(iLsSess.GetAllApps() != KErrNone) //collect data + { + } + while(iLsSess.AppCount(count) != KErrNone) //collect data + { + } + RequestNotify(); + } + +/** +* Proceed the next application to be launched +*/ +void CStarter::LaunchNextStartupAppL() + { + TUint32 applicationUid = iStartupListReader.ReadUint32(); + TFullName exeFilePath = iStartupListReader.ReadTPtrC(); + TFullName dllFilePath = iStartupListReader.ReadTPtrC(); + iCmdLineArgs.Append( iStartupListReader.ReadTPtrC()); + TDesC *commandLineArgs = &iCmdLineArgs[ iCmdLineArgs.Count()-1]; + + TUint32 stackSize = iStartupListReader.ReadUint32(); + stackSize = stackSize ? stackSize : KDefaultStackSize; + TUint32 minHeapSize = iStartupListReader.ReadUint32(); + minHeapSize = minHeapSize ? minHeapSize : KMinHeapSize; + TUint32 maxHeapSize = iStartupListReader.ReadUint32(); + + TBool monitored = (TUint16)iStartupListReader.ReadUint16(); + TBool semaphore = (TUint16)iStartupListReader.ReadUint16(); + TBool viewless = (TUint16)iStartupListReader.ReadUint16(); + TInt bootType = (TUint16)iStartupListReader.ReadUint16(); + + if(semaphore) + { + iNrSemaphore++; //increase with one. + iWaiting++; + } + + iStartupCount--; // next app + CAppStarter::NewLD(bootType, applicationUid, exeFilePath, dllFilePath, commandLineArgs, + stackSize, minHeapSize, maxHeapSize, monitored, viewless, + semaphore, iQueHeader, iLsSess, this); + } + +/** +* Proceed the next extra app to be launched +*/ +void CStarter::LaunchNextExtrasL() + { + TUint32 applicationUid = iExtrasListReader.ReadUint32(); + TFullName exeFilePath = iExtrasListReader.ReadTPtrC(); + TFullName dllFilePath = iExtrasListReader.ReadTPtrC(); + iCmdLineArgs.Append( iExtrasListReader.ReadTPtrC()); + TDesC *commandLineArgs = &iCmdLineArgs[ iCmdLineArgs.Count()-1]; + + TUint32 stackSize = iExtrasListReader.ReadUint32(); + stackSize = stackSize ? stackSize : KDefaultStackSize; + TUint32 minHeapSize = iExtrasListReader.ReadUint32(); + minHeapSize = minHeapSize ? minHeapSize : KMinHeapSize; + TUint32 maxHeapSize = iExtrasListReader.ReadUint32(); + + TBool monitored = (TUint16)iExtrasListReader.ReadUint16(); + TBool viewless = (TUint16)iExtrasListReader.ReadUint16(); + TInt bootType = (TUint16)iExtrasListReader.ReadUint16(); + + iExtrasCount--; // next app + CAppStarter::NewLD(bootType, applicationUid, exeFilePath, dllFilePath, commandLineArgs, + stackSize, minHeapSize, maxHeapSize, monitored, viewless, + EFalse, iQueHeader, iLsSess, this); + } + +void CStarter::RestartMonitoredThreadL(TInt appType, TThreadId& aThreadId, TDesC& aExeFileName, TUint32 aAppUid, TBool aViewless) + { + if(appType == EExecutableType) + { + User::LeaveIfError(iLsSess.StartDocument(aExeFileName, TUid::Uid(0), aThreadId)); + } + else if(aViewless) + { + TApaAppInfo info; + User::LeaveIfError(iLsSess.GetAppInfo(info,TUid::Uid(aAppUid))); + CApaCommandLine* cmdLine=CApaCommandLine::NewLC(); + cmdLine->SetLibraryNameL(info.iFullName); + cmdLine->SetCommandL(EApaCommandRunWithoutViews); + User::LeaveIfError(iLsSess.StartApp(*cmdLine, aThreadId)); + CleanupStack::PopAndDestroy(); // cmdLine + } + else + { + TApaAppInfo info; + User::LeaveIfError(iLsSess.GetAppInfo(info,TUid::Uid(aAppUid))); + TFileName fName; + if (info.iUid!=KNullUid) + { + User::LeaveIfError(iLsSess.StartDocument(fName, TUid::Uid(aAppUid), aThreadId)); + } + } + } + +/** +* Method called when the requested step have been procced +*/ +void CStarter::RunL() + { + switch (iStage) + { + case ESplashScreen: + { + iStage = EStarting; + // don't care about the error - for now + TRAPD(err, StartSplashScreenL()); + iSplashStarted = (err == KErrNone); + RequestNotify(); + } + break; + case EStarting: + iStage = EConnected; + Connect(); + break; + case EConnected: + { + iStage = EStart; + iSema.CreateGlobal(KGlobalSemaphore, EOwnerProcess); //For Shell + RequestNotify(); + } + break; + case EStart: + { + iStage = EStart; + if (iStartupCount) + { + LaunchNextStartupAppL(); + RequestNotify(); + } + break; + case EWait: + iStage = EStartExtras; + if(iSema.OpenGlobal(KGlobalSemaphore, EOwnerProcess) == KErrNone) + { + while(iNrSemaphore > 0) //Defined in the resourcefile for apps that has to be started before the splash screen is removed + { + iSema.Wait(); + iNrSemaphore--; + } + iSema.Close(); + } + + if(iSplashStarted) + { + //use chunk to tell splash screen to stop by setting to 1 + RChunk chunk; + TUint8 finish=1; + if( chunk.OpenGlobal(KStartChunkName,EFalse)== KErrNone) + { + TUint8* base=chunk.Base(); + *base=finish; + chunk.Close(); + } + } + + RequestNotify(); + } + break; + case EStartExtras: + if(iExtrasCount) + { + LaunchNextExtrasL(); + RequestNotify(); + } + break; + default: + iStage = ESplashScreen; + break; + } + } + +TInt CStarter::RunError(TInt /*aError*/) + { + return KErrNone; + } + +void CStarter::Done(TBool aSuccess) + { + if(aSuccess) + { + iWaiting--; + } + else + { + iWaiting--; + iNrSemaphore--; + } + if(iWaiting <= 0) + { + iStage = EWait; + RequestNotify(); + } + } +/** +* Cancel the execution +*/ +void CStarter::DoCancel() + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrCancel); + } + +void CStarter::RequestNotify() + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + SetActive(); + }