installationservices/swi/source/sislauncher/server/sislaunchersession.cpp
changeset 0 ba25891c3a9e
child 25 98b66e4fb0be
child 65 7333d7932ef7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/sislauncher/server/sislaunchersession.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,527 @@
+/*
+* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+* SisLauncher - session implementation
+*
+*/
+
+
+/**
+ @file 
+ @released
+ @internalComponent
+*/
+
+#include <s32mem.h>
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include <ct/rcpointerarray.h>
+#include "swtypereginfoparser.h"
+#ifndef SWI_TEXTSHELL_ROM
+#include <apgcli.h>
+#endif
+#endif
+
+#include "sislauncherserver.h"
+#include "sislaunchersession.h"
+#include "sislauncherclientserver.h"
+#include "threadmonitor.h"
+#include "securitypolicy.h"
+#include "sisregistryfiledescription.h"
+#include "sislauncherdefs.h"
+#include "arrayutils.h"  // from source/sisregistry/common/ 
+#include "log.h"
+#include "queueprocessor.h"
+
+namespace Swi 
+{
+
+template <class T>
+void DestroyRPointerArray(TAny* aPtr)
+    {
+    RPointerArray<T>* self = static_cast<RPointerArray<T>*> (aPtr);
+    self->ResetAndDestroy();
+    delete self;
+    }
+
+template <>
+class TTraits<TDesC>
+	{
+public:
+	static TDesC* CopyLC(const TDesC& aOther) { return aOther.AllocLC(); }
+	static TDesC* ReadFromStreamLC(RReadStream& aStream) { return HBufC::NewLC(aStream, KMaxTInt); }
+	static void WriteToStreamL(const TDesC& aItem, RWriteStream& aStream) { aStream << aItem; }
+	};
+
+CSisLauncherSession::CSisLauncherSession()
+	{
+	}
+
+void CSisLauncherSession::CreateL()
+	{
+	Server().AddSession();
+	}
+
+CSisLauncherSession::~CSisLauncherSession()
+	{
+	Server().DropSession();
+	}
+void CSisLauncherSession::DoRunExecutableL(const RMessage2& aMessage) 
+	{
+	TFileName filename;
+	aMessage.ReadL(0, filename);
+
+	TBool wait;
+	TPckg <TBool> waitPckg(wait);
+
+	aMessage.ReadL(1, waitPckg);
+	Server().RunExecutableL(filename, wait);
+
+	aMessage.Complete(KErrNone);
+	}
+
+void CSisLauncherSession::DoStartDocumentL(const RMessage2& aMessage)
+	{
+	TFileName filename;
+	aMessage.ReadL(0, filename);
+	
+	TBool wait;
+	TPckg <TBool> waitPckg(wait);
+	
+	aMessage.ReadL(1, waitPckg);
+	if (Server().BootUpMode() == KTextShell) 
+		{
+		// emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+		DEBUG_PRINTF2(_L8("Sis Launcher Server - textshell - skipping start document by file handle. wait = %d"), wait);	
+		}
+	else
+		{ 
+		// emulatore running with GUI
+		#ifndef SWI_TEXTSHELL_ROM
+			Server().StartDocumentL(filename, wait);
+		#endif
+		}
+
+	aMessage.Complete(KErrNone);	
+	}
+
+
+void CSisLauncherSession::DoStartDocumentByHandleL(const RMessage2& aMessage)
+	{
+	RFile file;
+	file.AdoptFromClient(aMessage, 0, 1);
+	CleanupClosePushL(file);
+
+	TBool wait;
+	TPckg <TBool> waitPckg(wait);
+
+	aMessage.ReadL(2, waitPckg);
+	if (Server().BootUpMode() == KTextShell)
+		{
+		// emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+		DEBUG_PRINTF3(_L8("Sis Launcher Server - textshell - skipping start document %S, wait = %d"),
+				&file, wait);
+		}
+	else
+		{
+		// emulatore running with GUI
+#ifndef SWI_TEXTSHELL_ROM
+		Server().StartDocumentL(file, wait);
+#endif
+		}
+	CleanupStack::PopAndDestroy(&file);
+	aMessage.Complete(KErrNone);
+}
+void CSisLauncherSession::DoStartByMimeL(const RMessage2& aMessage)
+	{
+	TFileName filename;
+	aMessage.ReadL(0, filename);
+
+	TInt srcLen = aMessage.GetDesLengthL(1);
+
+	HBufC8* mimeType = HBufC8::NewLC(srcLen);
+	TPtr8 ptr(mimeType->Des());
+	aMessage.ReadL(1, ptr);
+
+	TBool wait;
+	TPckg <TBool> waitPckg(wait);
+	aMessage.ReadL(2, waitPckg);
+	if (Server().BootUpMode() == KTextShell) 
+		{
+		// emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+		DEBUG_PRINTF3(_L8("Sis Launcher Server - textshell - skipping start document by file handle mimetype %S, wait = %d"),
+				mimeType, wait);	
+		}
+	else
+		{
+		// emulatore running with GUI
+#ifndef SWI_TEXTSHELL_ROM
+		Server().StartByMimeL(filename, *mimeType, wait);
+#endif
+		}		
+	CleanupStack::PopAndDestroy(mimeType);
+
+	aMessage.Complete(KErrNone);
+	}
+void CSisLauncherSession::DoStartByMimeByHandleL(const RMessage2& aMessage)
+	{
+	RFile file;
+	file.AdoptFromClient(aMessage, 0, 1);			
+	CleanupClosePushL(file);
+
+	TInt srcLen = aMessage.GetDesLengthL(2);
+
+	HBufC8* mimeType = HBufC8::NewLC(srcLen);
+	TPtr8 ptr(mimeType->Des());
+	aMessage.ReadL(2, ptr);
+
+	TBool wait;
+	TPckg <TBool> waitPckg(wait);
+
+	aMessage.ReadL(3, waitPckg);
+	if (Server().BootUpMode() == KTextShell) 
+		{
+		// emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+		DEBUG_PRINTF4(_L("Sis Launcher Server - textshell - skipping launch of document %S, mimetype %s, wait %d"),
+				&file, mimeType, wait);
+		}
+	else
+		{
+		// emulatore running with GUI
+#ifndef SWI_TEXTSHELL_ROM
+		Server().StartByMimeL(file, *mimeType, wait);
+#endif
+		}		
+	CleanupStack::PopAndDestroy(mimeType);
+	CleanupStack::PopAndDestroy(&file);
+
+	aMessage.Complete(KErrNone);
+
+	}
+void CSisLauncherSession::ServiceL(const RMessage2& aMessage)
+	{
+	DEBUG_PRINTF2(_L8("Sis Launcher Server - Servicing Message %d"), aMessage.Function());
+	
+	switch (aMessage.Function())
+		{
+		case ERunExecutable:
+			DoRunExecutableL(aMessage);
+			break;
+		case EStartDocument:
+			DoStartDocumentL(aMessage);			
+			break;
+		case EStartDocumentByHandle:
+			DoStartDocumentByHandleL(aMessage);
+			break;	
+		case EStartByMime:
+			DoStartByMimeL(aMessage);
+			break;
+		case EStartByMimeByHandle:
+			DoStartByMimeByHandleL(aMessage);
+			break;
+		case EShutdown:
+			{
+			TInt srcLen=aMessage.GetDesLengthL(0);
+			
+			HBufC8* uidBuffer = HBufC8::NewLC(srcLen);
+			TPtr8 uidPtr = uidBuffer->Des();
+			aMessage.ReadL(0, uidPtr, 0);
+			
+			TUint8* dataPtr=const_cast<TUint8*>(uidPtr.Ptr());
+			TUid* tUidPtr=reinterpret_cast<TUid*>(dataPtr);
+			TInt8 uidCount=srcLen/sizeof(TUid);
+			TInt shutdownTimeout = aMessage.Int1();
+			if (Server().BootUpMode() == KTextShell) 
+				{
+				// emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+				DEBUG_PRINTF(_L8("Sis Launcher Server - textshell - skipping graceful shutdown of GUI applications"));
+				}
+			else
+				{
+				// emulatore running with GUI
+				#ifndef SWI_TEXTSHELL_ROM
+					for (TInt i = 0; i < uidCount; i++)
+						{
+						// graceful shutdown
+						Server().ShutdownL(tUidPtr[i], shutdownTimeout);	
+						}
+				#endif
+				}
+			// Having tried graceful shutdown, we need to kill any remaining processes
+			// matching the SID.  Note that killing a process may re-order the list of
+			// remaining processes, so the search must start from the top again.
+			for (TInt i = 0; i < uidCount; i++)
+				{
+				Server().ForceShutdownL(tUidPtr[i]);
+				}			
+			CleanupStack::PopAndDestroy(uidBuffer);
+			aMessage.Complete(KErrNone);
+			
+			break;
+			}
+		case EShutdownAll:
+			{
+			if (Server().BootUpMode() == KTextShell) 
+				{
+				// emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+				DEBUG_PRINTF(_L8("Sis Launcher Server - textshell - skipping shutdown of user applications"));	
+				}
+			else
+				{
+				// emulatore running with GUI
+				#ifndef SWI_TEXTSHELL_ROM
+				Server().ShutdownL();
+				#endif
+				}
+			aMessage.Complete(KErrNone);
+			break;	
+			}
+		case ECheckApplicationInUse:
+			{
+			TInt srcLen=aMessage.GetDesLengthL(0);
+				
+			HBufC8* appInUseBuffer = HBufC8::NewLC(srcLen);
+			TPtr8 appInUseBufferPtr = appInUseBuffer->Des();	
+			aMessage.ReadL(0, appInUseBufferPtr, 0);
+	 
+			TAppInUse* appInUsePtr = (TAppInUse*) User::AllocL(srcLen);
+			CleanupStack::PushL(appInUsePtr);	
+			Mem::Copy(appInUsePtr, appInUseBufferPtr.Ptr(), srcLen);
+ 
+			TUint appInUseCount=srcLen/sizeof(TAppInUse);
+			for (TInt i=0;i<appInUseCount;i++)
+				{
+				TRAPD(err, CheckApplicationInUseL(appInUsePtr[i].iAppUid));
+				if (err==KErrInUse)  
+					{
+ 					appInUsePtr[i].iInUse=ETrue;
+					}			 
+				}	
+	 
+			TUint8* dataPtr=reinterpret_cast<TUint8*>(appInUsePtr);
+ 			const TPtrC8 data(dataPtr, srcLen);	
+ 		
+ 			//Indicate the client apps in use
+ 			aMessage.WriteL(0, data);							
+			aMessage.Complete(KErrNone);
+			CleanupStack::PopAndDestroy(appInUsePtr);
+			CleanupStack::PopAndDestroy(appInUseBuffer); 	
+			break;
+			}
+	    case ENotifyNewApps:
+			{
+			TInt size = aMessage.GetDesLengthL(0);
+
+			HBufC8* buf = HBufC8::NewLC(size);
+			TPtr8 bufPtr = buf->Des();
+			aMessage.ReadL(0, bufPtr);
+
+			RDesReadStream stream(*buf);
+			RPointerArray<TDesC> files;
+			InternalizePointerArrayL(files, stream);
+			if (Server().BootUpMode() == KTextShell) 
+				{
+				// emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+				DEBUG_PRINTF(_L8("Sis Launcher Server - textshell - skipping notification of new applications."));
+				}
+			else
+				{
+				// emulatore running with GUI
+				#ifndef SWI_TEXTSHELL_ROM
+				Server().NotifyNewAppsL(files);
+				#endif
+				}
+			files.ResetAndDestroy();
+
+			CleanupStack::PopAndDestroy(buf);
+
+			aMessage.Complete(KErrNone);
+			break;
+			}
+		case EParseSwTypeRegFile:
+			#ifndef SWI_TEXTSHELL_ROM
+			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			ParseSwTypeRegFileL(aMessage);
+			#endif
+			#endif
+			aMessage.Complete(KErrNone);
+			break;
+		case ERegisterSifLauncherMimeTypes:
+			#ifndef SWI_TEXTSHELL_ROM
+			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			RegisterSifLauncherMimeTypesL(aMessage);
+			#endif
+			#endif
+			aMessage.Complete(KErrNone);
+			break;
+		case EUnregisterSifLauncherMimeTypes:
+			#ifndef SWI_TEXTSHELL_ROM
+			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			UnregisterSifLauncherMimeTypesL(aMessage);
+			#endif
+			#endif
+			aMessage.Complete(KErrNone);
+			break;
+	    case EQueueRunExecutable:
+	    	//fall through
+	    case EQueueStartDocumentByHandle:
+	    	//fall through
+	    case EQueueStartByMimeByHandle:
+	    	Server().RunQueue().AddToQueueL(aMessage);
+	    	aMessage.Complete(KErrNone);
+	    	break;
+	    case EExecuteQueue:
+	    	aMessage.Complete(Server().RunQueue().ExecuteQueue());
+	    	break;
+	    case EKillQueue:
+	    	Server().RunQueue().ResetQueue();
+	    	aMessage.Complete(KErrNone);
+	    	break;
+	    default:
+			{
+			PanicClient(aMessage,EPanicIllegalFunction);
+			break;
+			}
+		}
+	}
+
+
+void CSisLauncherSession::ServiceError(const RMessage2& aMessage,TInt aError)
+	{
+	DEBUG_PRINTF2(_L8("Sis Launcher Server - ServiceL failed with error code %d."), aError);
+	
+	if (aError==KErrBadDescriptor)
+		{
+		PanicClient(aMessage,EPanicBadDescriptor);
+		}
+	CSession2::ServiceError(aMessage,aError);
+	}
+
+
+void CSisLauncherSession::CheckApplicationInUseL(TUid aUid)
+	{
+	
+	TFindProcess findProcess;
+	TFullName fullName;
+ 
+	while(findProcess.Next(fullName) == KErrNone)
+		{
+		RProcess process;
+		User::LeaveIfError(process.Open(findProcess));
+		TUid sid(process.SecureId());
+		TExitType exitType = process.ExitType();
+		process.Close();
+		if (sid == aUid && exitType == EExitPending)
+					User::Leave(KErrInUse);
+		}
+	}
+
+
+
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+void CSisLauncherSession::ParseSwTypeRegFileL(const RMessage2& aMessage)
+	{
+	// Unpack the file handle
+	RFile file;
+	User::LeaveIfError(file.AdoptFromClient(aMessage, 0, 1));
+	CleanupClosePushL(file);
+	
+	// Read the registration file
+	TInt fileSize = 0;
+	User::LeaveIfError(file.Size(fileSize));
+	HBufC8* buf = HBufC8::NewLC(fileSize);
+	TPtr8 bufPtr = buf->Des();
+	User::LeaveIfError(file.Read(bufPtr));
+
+	// Parse the registration file
+	RCPointerArray<CSoftwareTypeRegInfo> regInfoArray;
+	CleanupClosePushL(regInfoArray);
+	
+	CSoftwareTypeRegInfoParser* parser = CSoftwareTypeRegInfoParser::NewL();
+	CleanupStack::PushL(parser);
+	parser->ParseL(*buf, regInfoArray);
+
+	// Pack the registration data
+	RBuf8 serializedRegInfo;
+	serializedRegInfo.CleanupClosePushL();
+	SoftwareTypeRegInfoUtils::SerializeArrayL(regInfoArray, serializedRegInfo);
+	aMessage.Write(2, serializedRegInfo);
+
+	CleanupStack::PopAndDestroy(5, &file); // buf, regInfoArray, parser, serializedRegInfo
+	}
+
+#ifndef SWI_TEXTSHELL_ROM
+void CSisLauncherSession::RegisterSifLauncherMimeTypesL(const RMessage2& aMessage)
+	{
+	RegisterSifLauncherMimeTypesImplL(aMessage, ETrue);
+	}
+
+void CSisLauncherSession::UnregisterSifLauncherMimeTypesL(const RMessage2& aMessage)
+	{
+	RegisterSifLauncherMimeTypesImplL(aMessage, EFalse);
+	}
+
+void CSisLauncherSession::RegisterSifLauncherMimeTypesImplL(const RMessage2& aMessage, TBool aRegister)
+	{
+	// Read serialized MIME types from aMessage
+	HBufC8* buf = HBufC8::NewLC(aMessage.GetDesLengthL(0));
+	TPtr8 bufPtr(buf->Des());
+	aMessage.ReadL(0, bufPtr);
+	
+	// Unserialize MIME types
+	RDesReadStream rs(*buf);
+	CleanupClosePushL(rs);
+	
+	RCPointerArray<HBufC8> mimeTypes;
+	CleanupClosePushL(mimeTypes);
+	
+	InternalizePointerArrayL(mimeTypes, rs);
+	
+	// Connect to AppArc
+	RApaLsSession apa;
+	TInt err = apa.Connect();
+	if (err != KErrNone)
+		{
+		DEBUG_PRINTF2(_L8("Failed to connect to the AppArc server, err = %d\n"),err);
+		User::Leave(err);
+		}
+	CleanupClosePushL(apa);
+
+	// Iterate over the MIME types and (un)register them
+	for (TInt i=0; i<mimeTypes.Count(); ++i)
+		{
+		TDataType dataType(*mimeTypes[i]);
+		if (aRegister)
+			{
+			const TUid KSifLauncherUid = {0x10285BD0};
+			err = apa.InsertDataMapping(dataType, KDataTypePriorityTrustedHigh, KSifLauncherUid);
+			}
+		else
+			{
+			err = apa.DeleteDataMapping(dataType);
+			}
+		if (err != KErrNone)
+			{
+			DEBUG_PRINTF2(_L8("Failed to (un)register MIME types to AppArc, err = %d\n"),err);
+			}
+		}
+	
+	CleanupStack::PopAndDestroy(4, buf); //rs, mimeTypes, apa
+	}
+
+#endif // SWI_TEXTSHELL_ROM
+#endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+
+} // namespace Swi