applaunchservices/applaunchplugins/apstartsrc/apstart.cpp
author William Roberts <williamr@symbian.org>
Fri, 23 Apr 2010 14:37:17 +0100
branchRCL_3
changeset 22 c82a39b81a38
parent 0 2e3d3ce01487
permissions -rw-r--r--
Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414) Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can arrange to use the same source file name in sfimage, without having to export over the original Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.

// Copyright (c) 2008-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 <apacmdln.h>
#include "apstart.h"
#include "apststd.h"

const TInt KAppArcAppListInitialCompletionTimeout = 10000000; //10s

CApaAppStart::CApaAppStart()
	{
	}

CApaAppStart::~CApaAppStart()
	{
	iApaLsSession.Close();
	}

/**
Used to create an instance of @c CApaAppStart class

@return An instance of @c CApaAppStart
*/
EXPORT_C CApaAppStart* CApaAppStart::NewL()
	{
 	CApaAppStart* self = new(ELeave) CApaAppStart();
	return self;
	}

/**
Wait for apparc server to complete initial population of its app list. If list 
population doesn't complete within @c KAppArcAppListInitialCompletionTimeout, 
this function will leave with KErrTimedOut.

@panic If Apsexe.exe isn't started.
@leave KErrTimedOut if apparc doesn't complete the initial list population within KAppArcAppListInitialCompletionTimeout.
@leave With system-wide error-codes for generic errors.
*/
void CApaAppStart::WaitForApparcToInitialiseL()
	{
	// Make sure we have a usable session...
	if (iApaLsSession.Handle()==KNullHandle)
		{
		const TInt err = iApaLsSession.Connect(); 
		if(err != KErrNone)
			{
			Panic(EApsexeNotRunning);
			}
		}
	
	//...and a timer
	RTimer timer;
	User::LeaveIfError(timer.CreateLocal());
	CleanupClosePushL(timer); 
	
	// Request apparc to notify us when the initial list population is complete
	TRequestStatus apparcStatus;
	iApaLsSession.RegisterListPopulationCompleteObserver(apparcStatus);

	// Request a timeout.
	TRequestStatus timerStatus;
	timer.After(timerStatus, TTimeIntervalMicroSeconds32(KAppArcAppListInitialCompletionTimeout));
	
	// As soon as either request completes, cancel the other
	User::WaitForRequest(timerStatus, apparcStatus);
	if (timerStatus == KRequestPending)
		{
		timer.Cancel();
		User::WaitForRequest(timerStatus);
		}
	else
		{
		// Timeout
		User::LeaveIfError(iApaLsSession.CancelListPopulationCompleteObserver());
		User::WaitForRequest(apparcStatus);
		User::Leave(KErrTimedOut);
		}
		
	CleanupStack::PopAndDestroy(&timer);
	}

/**
Wait for apparc server to complete initial population of its app list. (Asynchronous). 

@param aStatus 
*/
void CApaAppStart::InitApparcServer(TRequestStatus& aStatus)
	{
	// Make sure we have a usable session...
	if (iApaLsSession.Handle()==KNullHandle)
		{
		const TInt err = iApaLsSession.Connect(); 
		if(err != KErrNone)
			{
			TRequestStatus* status = &aStatus;
			User::RequestComplete(status, KErrCouldNotConnect);
			return;
			}
		}
	iApaLsSession.RegisterListPopulationCompleteObserver(aStatus);
	}

/**
Cancel population of app list.
*/
void CApaAppStart::InitApparcServerCancel()
	{
	if (iApaLsSession.Handle()!=KNullHandle)
		{
		// cancel population of app list
		iApaLsSession.CancelListPopulationCompleteObserver();
		}
	}

/** 
Set up the CApaCommandLine object which will be used to start the app.
*/
void CApaAppStart::SetupCommandLineL(CApaCommandLine& aCmdLine,
					const TDesC& aFileName,
					const TDesC8& aArgs,
					TBool aViewLess,
					TBool aStartInBackground)
	{
	
	aCmdLine.SetExecutableNameL(aFileName);
	aCmdLine.SetTailEndL(aArgs) ;
	
	// Define how the app will be launched 		
	if (!aStartInBackground && !aViewLess)
		{
		aCmdLine.SetCommandL(EApaCommandRun);
		}
	else if (aStartInBackground && !aViewLess)
		{
		aCmdLine.SetCommandL(EApaCommandBackground);
		}
	else if (!aStartInBackground && aViewLess)
		{
		aCmdLine.SetCommandL(EApaCommandRunWithoutViews);
		}
	else 
		{
		aCmdLine.SetCommandL(EApaCommandBackgroundAndWithoutViews);
		}
	}

/**
Start an application as defined by the specified command line information. Feedback about 
when the application is actually up and running is given via @c aRequestStatusForRendezvous.

Rule-based launching and non-native applications are supported only after 
@c WaitForApparcToInitialiseL (in case of sysstart) or InitApparcServer (in case of ssma) has been called. 
@see struct INIT_APPARC.
@see struct STRUCT SSM_WAIT_FOR_APPARC_INIT

@param aFileName The full filename of the application.
@param aArgs The arguments passed to the application.
@param aViewLess Indicates whether the application has a view.
@param aStartInBackground Indicates whether the application should start in background.
@param aThreadId The id of the main thread for the application.
@param aRequestStatusForRendezvous To be used for deferred return of the application startup status.

@leave With a system-wide error-code e.g. if @c aFileName doesn't exists or if memory couldn't be allcoated.
*/
void CApaAppStart::StartAppL(const TDesC& aFileName, 
					const TDesC& aArgs, 
					TBool aViewLess, 
					TBool aStartInBackground, 
					TThreadId& aThreadId, 
					TRequestStatus& aRequestStatusForRendezvous)
	{
	DoStartAppL(aFileName, aArgs, aViewLess, aStartInBackground, aThreadId, &aRequestStatusForRendezvous);
	}


/**
Start an application as defined by the specified command line information. No feedback is provided 
about when the application is actually up and running.

Rule-based launching and non-native applications are supported only after 
@c WaitForApparcToInitialiseL (in case of sysstart) or InitApparcServer (in case of ssma) has been called. 
@see struct INIT_APPARC.
@see struct STRUCT SSM_WAIT_FOR_APPARC_INIT

@param aFileName The full filename of the application.
@param aArgs The arguments passed to the application.
@param aViewLess Indicates whether the application has a view.
@param aStartInBackground Indicates whether the application should start in background.
@param aThreadId The id of the main thread for the application.

@leave With a system-wide error-code e.g. if @c aFileName doesn't exists or if memory couldn't be allcoated.
*/
void CApaAppStart::StartAppL(const TDesC& aFileName, 
					const TDesC& aArgs, 
					TBool aViewLess, 
					TBool aStartInBackground, 
					TThreadId& aThreadId)
	{
	DoStartAppL(aFileName, aArgs, aViewLess, aStartInBackground, aThreadId, NULL);
	}


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);
	}