--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/sislauncher/server/sislauncherserver.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,558 @@
+/*
+* 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 - server implementation
+*
+*/
+
+
+/**
+ @file
+ @released
+ @internalComponent
+*/
+
+#include "sislauncherserver.h"
+#include "sislaunchersession.h"
+#include "sislauncherclientserver.h"
+#include "log.h"
+#include "securitypolicy.h"
+#include <w32std.h>
+
+#include "threadmonitor.h"
+#include "queueprocessor.h"
+
+#ifndef SWI_TEXTSHELL_ROM
+ #include <apmstd.h>
+ #include <apgcli.h>
+ #include <apgwgnam.h>
+ #include <apgtask.h>
+#endif
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+const TUint KInstallServerUid = 0x101F7295;
+const TUint KSisRegistryServerUid = 0x10202DCA;
+#endif
+
+using namespace Swi;
+
+CServer2* CSisLauncherServer::NewLC()
+ {
+ CSisLauncherServer* self=new(ELeave) CSisLauncherServer;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+CSisLauncherServer::~CSisLauncherServer()
+ {
+#ifndef SWI_TEXTSHELL_ROM
+ if (iBootMode != KTextShell)
+ {
+ iWsSession.Close();
+ }
+#endif
+ delete iShutdown;
+ delete iQueueProcessor;
+ CSecurityPolicy::ReleaseResource();
+ }
+
+void CSisLauncherServer::ConstructL()
+ {
+ StartL(KSisLauncherServerName);
+ iShutdown = new (ELeave) CSisLauncherServerShutdown;
+ iShutdown->ConstructL();
+ TInt connectErr = KErrNotFound;
+#ifndef SWI_TEXTSHELL_ROM
+ // Connect to Window Session
+ connectErr = iWsSession.Connect();
+ if (connectErr != KErrNotFound)
+ {
+ User::LeaveIfError(connectErr);
+ }
+#endif
+ if (connectErr == KErrNotFound)
+ {
+ // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
+ iBootMode = KTextShell;
+ }
+ iQueueProcessor = CQueueProcessor::NewL(*this);
+ }
+
+CSession2* CSisLauncherServer::NewSessionL(const TVersion&,const RMessage2&) const
+ {
+ return new(ELeave) CSisLauncherSession();
+ }
+
+void CSisLauncherServer::AddSession()
+ {
+ ++iSessionCount;
+
+ DEBUG_PRINTF2(_L8("Sis Launcher Server - Adding Session (%d sessions total.)"), iSessionCount);
+
+ CancelShutdown();
+ }
+
+void CSisLauncherServer::DropSession()
+ {
+ --iSessionCount;
+
+ DEBUG_PRINTF2(_L8("Sis Launcher Server - Dropping Session (%d sessions total.)"), iSessionCount);
+
+ if (0==iSessionCount && iShutdown)
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Starting shutdown timer."));
+ // ignored if a long timer is active
+ iShutdown->StartShort(EFalse);
+ }
+ }
+/**
+ * Cancels an existing shutdown timer before renabling with the long timeout. This is used to catch
+ * the case where we need to allow ECOM to work before killing the server. ECOM should finish scanning
+ * files within a couple of seconds of SWI finishing but just in case we allow ECOM a little longer.
+ * The other reason we have the timer is to handle the case where SWI mistakenly identified a plugin
+ * resource file, we don't want to hang around forever waiting for an event that never comes.
+ * */
+void CSisLauncherServer::LongServerShutdown()
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Switching to long shutdown timer"));
+ if (iShutdown)
+ {
+ iShutdown->StartLong();
+ }
+ }
+
+void CSisLauncherServer::CancelShutdown()
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Cancelling shutdown timer"));
+
+ if (iShutdown)
+ {
+ iShutdown->Cancel();
+ }
+ }
+
+void CSisLauncherServer::ShortServerShutdown()
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Re-enabling short shutdown timer"));
+ if (0==iSessionCount && iShutdown)
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Starting shutdown timer"));
+ iShutdown->StartShort(ETrue);
+ }
+ }
+
+ // All functions require TCB capability
+const TInt CSisLauncherServer::iRanges[iRangeCount] =
+ {
+ 0, // All connect attempts
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ // Range of utility services for Post manufacture management of Layered Execution Environemnts
+ EParseSwTypeRegFile,
+ EUnregisterSifLauncherMimeTypes,
+#endif
+ ESeparatorEndAll,
+ };
+
+const TUint8 CSisLauncherServer::iElementsIndex[iRangeCount] =
+ {
+ 0, // Used by Client which is only swis and TCB is needed.
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ 1, // Utility services used by InstallServer
+ 2, // Utility services used by SisRegistryServer
+#endif
+ CPolicyServer::ENotSupported,
+ };
+
+const CPolicyServer::TPolicyElement CSisLauncherServer::iPolicyElements[] =
+ {
+ {_INIT_SECURITY_POLICY_C1(ECapabilityTCB), CPolicyServer::EFailClient},
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ {_INIT_SECURITY_POLICY_S0(KInstallServerUid), CPolicyServer::EFailClient},
+ {_INIT_SECURITY_POLICY_S0(KSisRegistryServerUid), CPolicyServer::EFailClient},
+#endif
+ };
+
+const CPolicyServer::TPolicy CSisLauncherServer::iPolicy =
+ {
+ 0, //specifies all connect attempts need TCB
+ iRangeCount,
+ iRanges,
+ iElementsIndex,
+ iPolicyElements,
+ };
+
+
+// shutdown timer
+
+CSisLauncherServerShutdown::~CSisLauncherServerShutdown()
+ {
+ Cancel();
+ }
+
+void CSisLauncherServerShutdown::RunL()
+ {
+ CActiveScheduler::Stop();
+ }
+
+void CSisLauncherServerShutdown::StartShort(TBool aCancelLongTimer)
+ {
+ if (iLongTimerActive & !aCancelLongTimer)
+ {
+ return;
+ }
+ else
+ {
+ Cancel();
+ iLongTimerActive=EFalse;
+ After(KSisLauncherShutdownDelay);
+ }
+ }
+
+inline void CSisLauncherServerShutdown::StartLong()
+ {
+ Cancel();
+ iLongTimerActive=ETrue;
+ After(KSisLauncherLongShutdownDelay);
+ }
+
+
+void CSisLauncherServer::RunExecutableL(const TDesC& aFileName, TBool aWait)
+ {
+ DEBUG_CODE_SECTION(
+ if (aWait)
+ {
+ DEBUG_PRINTF2(_L("Sis Launcher Server - Attempting to run executable by filename ('%S'), waiting for termination."),
+ &aFileName);
+ }
+ else
+ {
+ DEBUG_PRINTF2(_L("Sis Launcher Server - Attempting to run executable by filename ('%S'), not waiting for termination."),
+ &aFileName);
+ }
+ ); // DEBUG_CODE_SECTION
+
+ RProcess process;
+ _LIT(KNullArgs, "");
+ User::LeaveIfError(process.Create(aFileName, KNullArgs));
+ CleanupClosePushL(process);
+
+ // Get the thread id of the main thread in the process
+ // From CApaExeRecognizer::RunL
+ TFullName fullName(process.Name());
+ _LIT(KCCMain,"::Main");
+ fullName.Append(KCCMain);
+ TFindThread fT(fullName);
+ User::LeaveIfError(fT.Next(fullName));
+ RThread thread;
+ User::LeaveIfError(thread.Open(fT));
+ TThreadId threadId = thread.Id();
+ thread.Close();
+ process.Resume();
+
+ CleanupStack::PopAndDestroy(&process);
+ if (aWait)
+ HandleShutdownL(threadId, ETrue);
+ }
+
+
+
+void CSisLauncherServer::ForceShutdownL(TUid aUid)
+ {
+ TBool needToScanFullList;
+ TFullName fullName;
+ do
+ {
+ needToScanFullList = EFalse;
+ TFindProcess findProcess;
+
+ while(findProcess.Next(fullName) == KErrNone)
+ {
+ RProcess process;
+ User::LeaveIfError(process.Open(findProcess));
+ TUid sid(process.SecureId());
+ if (sid == aUid && process.ExitType() == EExitPending)
+ {
+ process.Kill(KErrNone);
+ needToScanFullList = ETrue;
+ }
+ process.Close();
+ }
+ } while (needToScanFullList);
+ }
+
+
+void CSisLauncherServer::HandleShutdownL(TThreadId aThread, TBool aKillOnTimeout)
+ {
+ RWsSession* wsSession = NULL;
+ if (iBootMode == 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
+ {
+ #ifndef SWI_TEXTSHELL_ROM
+ DEBUG_CODE_SECTION(
+ if (aKillOnTimeout)
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Awaiting thread shutdown, will forcibly kill process on timeout."));
+ }
+ else
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Awaiting thread shutdown, will not forcibly kill process on timeout."));
+ }
+ );
+ wsSession = &iWsSession;
+ #endif
+ }
+ // Read timeout value from software install security
+ // policy.
+ CSecurityPolicy* secPolicy = CSecurityPolicy::GetSecurityPolicyL();
+ TInt runWaitTimeout = secPolicy->RunWaitTimeout();
+ TInt shutdownTimeout = secPolicy->ApplicationShutdownTimeout();
+ // Wait until the thread finishes or a timeout occurs
+ CThreadMonitor* threadMonitor = CThreadMonitor::NewLC(aThread, wsSession);
+ threadMonitor->SyncShutdownL(runWaitTimeout, aKillOnTimeout, shutdownTimeout);
+ CleanupStack::PopAndDestroy(threadMonitor);
+ }
+
+
+#ifndef SWI_TEXTSHELL_ROM
+void CSisLauncherServer::StartDocumentL(RFile& aFile, TBool aWait)
+ {
+ DEBUG_CODE_SECTION(
+ if (aWait)
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Attempting to start document by filehandle, waiting for termination."));
+ }
+ else
+ {
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Attempting to start document by filehandle, not waiting for termination."));
+ }
+ );
+
+ RApaLsSession apaSession;
+ User::LeaveIfError(apaSession.Connect());
+ CleanupClosePushL(apaSession);
+
+ TThreadId threadId;
+ User::LeaveIfError(apaSession.StartDocument(aFile, threadId));
+
+ CleanupStack::PopAndDestroy(&apaSession);
+ if (aWait)
+ HandleShutdownL(threadId);
+ }
+
+void CSisLauncherServer::StartByMimeL(RFile& aFile, TDesC8& aMimeType, TBool aWait)
+ {
+ DEBUG_CODE_SECTION(
+ if (aWait)
+ {
+ DEBUG_PRINTF2(_L8("Sis Launcher Server - Attempting to start document by mimetype '%S' (filehandle supplied), waiting for termination."),
+ &aMimeType);
+ }
+ else
+ {
+ DEBUG_PRINTF2(_L8("Sis Launcher Server - Attempting to start document by mimetype '%S' (filehandle supplied), not waiting for termination."),
+ &aMimeType);
+ }
+ );
+
+ RApaLsSession apaSession;
+ User::LeaveIfError(apaSession.Connect());
+ CleanupClosePushL(apaSession);
+
+ TThreadId threadId;
+ TDataType dataType = TDataType(aMimeType);
+ User::LeaveIfError(apaSession.StartDocument(aFile, dataType, threadId));
+
+ CleanupStack::PopAndDestroy(&apaSession);
+ if (aWait)
+ HandleShutdownL(threadId);
+ }
+
+void CSisLauncherServer::StartDocumentL(const TDesC& aFileName, TBool aWait)
+ {
+ DEBUG_CODE_SECTION(
+ if (aWait)
+ {
+ DEBUG_PRINTF2(_L("Sis Launcher Server - Attempting to start document by filename '%S', waiting for termination."),
+ &aFileName);
+ }
+ else
+ {
+ DEBUG_PRINTF2(_L("Sis Launcher Server - Attempting to start document by filename '%S', not waiting for termination."),
+ &aFileName);
+ }
+ );
+
+ RApaLsSession apaSession;
+ User::LeaveIfError(apaSession.Connect());
+ CleanupClosePushL(apaSession);
+
+ TThreadId threadId;
+ User::LeaveIfError(apaSession.StartDocument(aFileName, threadId));
+
+ CleanupStack::PopAndDestroy(&apaSession);
+ if (aWait)
+ HandleShutdownL(threadId);
+ }
+
+void CSisLauncherServer::StartByMimeL(const TDesC& aFileName, TDesC8& aMimeType, TBool aWait)
+ {
+ DEBUG_CODE_SECTION(
+ if (aWait)
+ {
+ DEBUG_PRINTF2(_L("Sis Launcher Server - Attempting to start document by filename '%S', waiting for termination."),
+ &aFileName);
+ }
+ else
+ {
+ DEBUG_PRINTF2(_L("Sis Launcher Server - Attempting to start document by filename '%S', not waiting for termination."),
+ &aFileName);
+ }
+ );
+ DEBUG_PRINTF2(_L8("Sis Launcher Server - Supplied MIME type is '%S'."), &aMimeType);
+
+ RApaLsSession apaSession;
+ User::LeaveIfError(apaSession.Connect());
+ CleanupClosePushL(apaSession);
+
+ TThreadId threadId;
+ TDataType dataType = TDataType(aMimeType);
+ User::LeaveIfError(apaSession.StartDocument(aFileName, dataType, threadId));
+
+ CleanupStack::PopAndDestroy(&apaSession);
+ if (aWait)
+ HandleShutdownL(threadId);
+ }
+
+void CSisLauncherServer::ShutdownL(TUid aUid, TInt aTimeout)
+ {
+ // This method shuts down running exes matching the SID provided in aUid.
+ // It first attempts a graceful shutdown, killing processes if a graceful
+ // shutdown is not supported or fails to work within aTimeout microseconds.
+
+ DEBUG_PRINTF2(_L8("Sis Launcher Server - Attempting to kill process with SID: 0x%08x."),
+ aUid.iUid);
+
+ TInt wgId=0;
+
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewL(iWsSession);
+ CleanupStack::PushL(wgName);
+ CApaWindowGroupName::FindByAppUid(aUid, iWsSession, wgId);
+
+ while (wgId != KErrNotFound)
+ {
+ wgName->ConstructFromWgIdL(wgId);
+ if(wgName->RespondsToShutdownEvent())
+ {
+ TApaTask task(iWsSession);
+ task.SetWgId(wgId);
+
+ RThread thread;
+ User::LeaveIfError(thread.Open(task.ThreadId()));
+ CleanupClosePushL(thread);
+
+ RProcess process;
+ User::LeaveIfError(thread.Process(process));
+ CleanupClosePushL(process);
+
+ TRequestStatus processStatus;
+ process.Logon(processStatus);
+
+ task.SendSystemEvent(EApaSystemEventShutdown);
+
+ RTimer timer;
+ CleanupClosePushL(timer);
+ TRequestStatus timerStatus;
+ timer.CreateLocal();
+ timer.After(timerStatus, aTimeout);
+
+ User::WaitForRequest(processStatus,timerStatus);
+
+ if (processStatus==KRequestPending)
+ {
+ // Failed to terminate gracefully, so kill the task.
+ DEBUG_PRINTF(_L8("Sis Launcher Server - Process did not die before timeout. Forcibly killing it."));
+ process.Kill(KErrNone);
+ }
+ else if (timerStatus==KRequestPending)
+ {
+ // Rendezvous completed so cancel timer
+ timer.Cancel();
+ }
+ // Handle second request
+ User::WaitForRequest(processStatus,timerStatus);
+ CleanupStack::PopAndDestroy(3, &thread);
+ }
+
+ // See if there's another instance of this App running.
+ CApaWindowGroupName::FindByAppUid(aUid, iWsSession, wgId);
+ }
+ CleanupStack::PopAndDestroy(wgName);
+ }
+
+void CSisLauncherServer::ShutdownL()
+ {
+ TInt wgId=0;
+
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewL(iWsSession);
+ CleanupStack::PushL(wgName);
+ TBuf<1> matchAny;
+ matchAny.Append(KMatchAny);
+ CApaWindowGroupName::FindByCaption(matchAny, iWsSession, wgId);
+ while (wgId != KErrNotFound)
+ {
+ wgName->ConstructFromWgIdL(wgId);
+ //DEF057706 - shut down hidden apps during uninstallation if
+ // SH flag is specified
+ if (!wgName->IsSystem() /* && !wgName->Hidden() */)
+ {
+ // leave if we cannot shutdown the app because its busy
+ if(!wgName->IsBusy())
+ {
+ TApaTask task(iWsSession);
+ task.SetWgId(wgId);
+ // show shutdown dialog for this app?
+ task.SendSystemEvent(EApaSystemEventShutdown);
+ }
+ else
+ {
+ // could not shutdown an app
+ User::Leave(KErrInUse);
+ }
+ }
+
+ // get next app to shutdown
+ CApaWindowGroupName::FindByCaption(matchAny, iWsSession, wgId);
+ }
+ CleanupStack::PopAndDestroy(wgName);
+ }
+
+void CSisLauncherServer::NotifyNewAppsL(const RPointerArray<TDesC>& aFiles)
+ {
+ RApaLsSession apaSession;
+ User::LeaveIfError(apaSession.Connect());
+ CleanupClosePushL(apaSession);
+
+ // UI frameworks advise ignoring the return code
+ apaSession.ForceRegistration(aFiles);
+
+ CleanupStack::PopAndDestroy();
+ }
+#endif
+
+