diff -r 7333d7932ef7 -r 8b7f4e561641 installationservices/swi/source/sishelper/uissclienthandler.cpp --- a/installationservices/swi/source/sishelper/uissclienthandler.cpp Tue Aug 31 15:21:33 2010 +0300 +++ b/installationservices/swi/source/sishelper/uissclienthandler.cpp Wed Sep 01 12:22:02 2010 +0100 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2004-2010 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" @@ -51,130 +51,140 @@ #include "commands/textdialog.h" #include "log.h" +#include "cleanuputils.h" #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK -#include "cleanuputils.h" #include const TInt KCompInfoBufferSize=4*1024; #endif + + namespace Swi { + +//Temporary error logging solution. +void LogSwiErrorsToFileL(TInt aErrorCode, const TDesC& aAppName); + // // A cancel handler // class InternalCancelHandler : public MCancelHandler - { + { public: - InternalCancelHandler(CUissClientHandler& aUissClientHandler); - void HandleCancel(); + InternalCancelHandler(CUissClientHandler& aUissClientHandler); + void HandleCancel(); private: - CUissClientHandler& iUissClientHandler; - }; + CUissClientHandler& iUissClientHandler; + }; InternalCancelHandler::InternalCancelHandler( - CUissClientHandler& aUissClientHandler) -: iUissClientHandler(aUissClientHandler) - { - } + CUissClientHandler& aUissClientHandler) +: iUissClientHandler(aUissClientHandler) + { + } void InternalCancelHandler::HandleCancel() - { - iUissClientHandler.CancelOperation(); - } + { + iUissClientHandler.CancelOperation(); + } CUissClientHandler* CUissClientHandler::NewLC(MUiHandler& aUiHandler, TBool aActiveObjectMode) - { - CUissClientHandler* self=new(ELeave) CUissClientHandler(aUiHandler, aActiveObjectMode); - CleanupStack::PushL(self); - self->ConstructL(); - return self; - } + { + CUissClientHandler* self=new(ELeave) CUissClientHandler(aUiHandler, aActiveObjectMode); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } CUissClientHandler* CUissClientHandler::NewL(MUiHandler& aUiHandler, TBool aActiveObjectMode) - { - CUissClientHandler* self=NewLC(aUiHandler, aActiveObjectMode); - CleanupStack::Pop(self); - return self; - } + { + CUissClientHandler* self=NewLC(aUiHandler, aActiveObjectMode); + CleanupStack::Pop(self); + return self; + } CUissClientHandler::CUissClientHandler(MUiHandler& aUiHandler, TBool aActiveObjectMode) : CActive(EPriorityStandard), iUiHandler(aUiHandler), - iPtrIntoBuf(0,0), + iPtrIntoBuf(0,0), iActiveObjectMode(aActiveObjectMode), - iPtrIntoArgsStream(0,0) - #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK - ,iCompInfoBufPtr(0,0) - #endif - { + iPtrIntoArgsStream(0,0) + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + ,iCompInfoBufPtr(0,0) + #endif + { if (iActiveObjectMode) - { - CActiveScheduler::Add(this); - } - } + { + CActiveScheduler::Add(this); + } + } void CUissClientHandler::WaitForSisHelperShutdown() - { - if(iSisHelper.Handle() > 0) - { - TRequestStatus reqStatus; - iSisHelper.Logon(reqStatus); - User::WaitForRequest(reqStatus); - iSisHelper.Close(); - } - } - + { + if(iSisHelper.Handle() > 0) + { + TRequestStatus reqStatus; + iSisHelper.Logon(reqStatus); + User::WaitForRequest(reqStatus); + iSisHelper.Close(); + } + } + CUissClientHandler::~CUissClientHandler() - { - //Cancel any outstanding request - CancelOperation(); + { + //Cancel any outstanding request + CancelOperation(); - WaitForSisHelperShutdown(); + WaitForSisHelperShutdown(); if (iActiveObjectMode) - { - CActive::Cancel(); // Make sure we are cancelled before deletion - } + { + CActive::Cancel(); // Make sure we are cancelled before deletion + } - delete iCancelHandler; + delete iCancelHandler; delete iArgsStream; - iUissSession.Close(); - delete iBuf; - #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + iUissSession.Close(); + delete iBuf; + delete iBufLogger; + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK delete iCompInfoBuffer; - #endif - } + #endif + } /** * Allocates a buffer for reverse-completion commands. The buffer is going to * be resized in case it is not sufficient for a dialog command. */ void CUissClientHandler::ConstructL() - { - iCancelHandler=new(ELeave) InternalCancelHandler(*this); - AllocBufL(KBufSize);// Allocate the initial r/c buffer - User::LeaveIfError(StartUiss()); // Start UISS - User::LeaveIfError(iUissSession.Connect()); // Connect to UISS - } + { + iCancelHandler=new(ELeave) InternalCancelHandler(*this); + AllocBufL(KBufSize);// Allocate the initial r/c buffer + + //Logger buffer. + iBufLogger = KNullDesC8().AllocL(); + User::LeaveIfError(StartUiss()); // Start UISS + User::LeaveIfError(iUissSession.Connect()); // Connect to UISS + } void CUissClientHandler::AllocBufL(TInt aSize) - { + { HBufC8* buf=HBufC8::NewL(aSize); delete iBuf; iBuf=buf; } void CUissClientHandler::HandleOverflowL() - { - // Reallocate the buffer to the size received in parameter 1 - TInt size=0; - TPckg theSize(size); - theSize.Copy(iBuf->Left(sizeof(TInt))); - AllocBufL(size); - } - + { + // Reallocate the buffer to the size received in parameter 1 + TInt size=0; + TPckg theSize(size); + theSize.Copy(iBuf->Left(sizeof(TInt))); + AllocBufL(size); + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK void CUissClientHandler::AllocCompInfoBufL(TInt aSize) - { + { HBufC8* buf = HBufC8::NewL(aSize); delete iCompInfoBuffer; iCompInfoBuffer = buf; @@ -183,132 +193,132 @@ ///\short Creates a command handler object for the specified dialog request CUissCmdHandler* CUissClientHandler::UissCmdHandlerFactoryL(TInt aCommand) const - { - switch (aCommand) - { - case CUissSession::KMessageApplicationsInUseDialog: - return new(ELeave) CApplicationsInUseDialogCmdHandler(iUiHandler); - case CUissSession::KMessageCannotOverwriteFileDialog: - return new(ELeave) CCannotOverwriteFileDialogCmdHandler(iUiHandler); - - case CUissSession::KMessageDependencyBreakDialog: - return new(ELeave) CDependencyBreakDialogCmdHandler(iUiHandler); - case CUissSession::KMessageDeviceIncompatibility: - return new(ELeave) CDeviceIncompatibilityDialogCmdHandler(iUiHandler); - case CUissSession::KMessageMissingDependency: - return new(ELeave) CMissingDependencyDialogCmdHandler(iUiHandler); - case CUissSession::KMessageDriveDialog: - return new(ELeave) CDriveDialogCmdHandler(iUiHandler); - case CUissSession::KMessageErrorDialog: - return new(ELeave) CErrorDialogCmdHandler(iUiHandler); - case CUissSession::KMessageGrantCapabilitiesDialog: - return new(ELeave) CGrantCapabilitiesDialogCmdHandler(iUiHandler); - case CUissSession::KMessageHandleCancellableInstallEvent: - return new(ELeave) CHandleCancellableInstallEventCmdHandler(iUiHandler, - *iCancelHandler); - case CUissSession::KMessageHandleInstallEvent: - return new(ELeave) CHandleInstallEventCmdHandler(iUiHandler); - case CUissSession::KMessageInstallDialog: - return new(ELeave) CInstallDialogCmdHandler(iUiHandler); - case CUissSession::KMessageLanguageDialog: - return new(ELeave) CLanguageDialogCmdHandler(iUiHandler); - case CUissSession::KMessageOcspResultDialog: - return new(ELeave) COcspResultDialogCmdHandler(iUiHandler); - case CUissSession::KMessageOptionsDialog: - return new(ELeave) COptionsDialogCmdHandler(iUiHandler); - case CUissSession::KMessageQuestionDialog: - return new(ELeave) CQuestionDialogCmdHandler(iUiHandler); - case CUissSession::KMessageSecurityWarningDialog: - return new(ELeave) CSecurityWarningDialogCmdHandler(iUiHandler); - case CUissSession::KMessageUninstallDialog: - return new(ELeave) CUninstallDialogCmdHandler(iUiHandler); - - case CUissSession::KMessageUpgradeDialog: - return new(ELeave) CUpgradeDialogCmdHandler(iUiHandler); - - case CUissSession::KMessageTextDialog: - return new(ELeave) CTextDialogCmdHandler(iUiHandler); - - default: - return NULL; - } - } + { + switch (aCommand) + { + case CUissSession::KMessageApplicationsInUseDialog: + return new(ELeave) CApplicationsInUseDialogCmdHandler(iUiHandler); + case CUissSession::KMessageCannotOverwriteFileDialog: + return new(ELeave) CCannotOverwriteFileDialogCmdHandler(iUiHandler); + + case CUissSession::KMessageDependencyBreakDialog: + return new(ELeave) CDependencyBreakDialogCmdHandler(iUiHandler); + case CUissSession::KMessageDeviceIncompatibility: + return new(ELeave) CDeviceIncompatibilityDialogCmdHandler(iUiHandler); + case CUissSession::KMessageMissingDependency: + return new(ELeave) CMissingDependencyDialogCmdHandler(iUiHandler); + case CUissSession::KMessageDriveDialog: + return new(ELeave) CDriveDialogCmdHandler(iUiHandler); + case CUissSession::KMessageErrorDialog: + return new(ELeave) CErrorDialogCmdHandler(iUiHandler); + case CUissSession::KMessageGrantCapabilitiesDialog: + return new(ELeave) CGrantCapabilitiesDialogCmdHandler(iUiHandler); + case CUissSession::KMessageHandleCancellableInstallEvent: + return new(ELeave) CHandleCancellableInstallEventCmdHandler(iUiHandler, + *iCancelHandler); + case CUissSession::KMessageHandleInstallEvent: + return new(ELeave) CHandleInstallEventCmdHandler(iUiHandler); + case CUissSession::KMessageInstallDialog: + return new(ELeave) CInstallDialogCmdHandler(iUiHandler); + case CUissSession::KMessageLanguageDialog: + return new(ELeave) CLanguageDialogCmdHandler(iUiHandler); + case CUissSession::KMessageOcspResultDialog: + return new(ELeave) COcspResultDialogCmdHandler(iUiHandler); + case CUissSession::KMessageOptionsDialog: + return new(ELeave) COptionsDialogCmdHandler(iUiHandler); + case CUissSession::KMessageQuestionDialog: + return new(ELeave) CQuestionDialogCmdHandler(iUiHandler); + case CUissSession::KMessageSecurityWarningDialog: + return new(ELeave) CSecurityWarningDialogCmdHandler(iUiHandler); + case CUissSession::KMessageUninstallDialog: + return new(ELeave) CUninstallDialogCmdHandler(iUiHandler); + + case CUissSession::KMessageUpgradeDialog: + return new(ELeave) CUpgradeDialogCmdHandler(iUiHandler); + + case CUissSession::KMessageTextDialog: + return new(ELeave) CTextDialogCmdHandler(iUiHandler); + + default: + return NULL; + } + } void CUissClientHandler::InitializeArgStreamL(const CInstallPrefs& aInstallPrefs) - { - // Stream out install parameters. Cannot do this in UISSCLIENT because - // the code is in LAUNCHER which depends on UISSCLIENT. + { + // Stream out install parameters. Cannot do this in UISSCLIENT because + // the code is in LAUNCHER which depends on UISSCLIENT. delete iArgsStream; iArgsStream = 0; - iArgsStream = CWriteStream::NewL(); - *iArgsStream << aInstallPrefs; + iArgsStream = CWriteStream::NewL(); + *iArgsStream << aInstallPrefs; // Save ptr for args (must persist whilst server is processing) - iPtrIntoArgsStream.Set(iArgsStream->Ptr()); - } - + iPtrIntoArgsStream.Set(iArgsStream->Ptr()); + } + void CUissClientHandler::InstallL(const CInstallPrefs& aInstallPrefs, const RArray& aDeviceSupportedLanguages, TRequestStatus& aRequestStatus, RThread& aServer) - { + { iState = KUissClientInstalling; iClientStatus = &aRequestStatus; // Save ptr for data returned by request (must persist whilst server is processing) - iPtrIntoBuf.Set(iBuf->Des()); + iPtrIntoBuf.Set(iBuf->Des()); - InitializeArgStreamL(aInstallPrefs); - iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages.Count()); - //Streaming set of languages that device supports - TInt noOfDeviceSupportedLanguages = aDeviceSupportedLanguages.Count(); - for(TInt i=0;iStream().WriteInt32L(aDeviceSupportedLanguages[i]); - } - // Save ptr for args (must persist whilst server is processing) - iPtrIntoArgsStream.Set(iArgsStream->Ptr()); - + InitializeArgStreamL(aInstallPrefs); + iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages.Count()); + //Streaming set of languages that device supports + TInt noOfDeviceSupportedLanguages = aDeviceSupportedLanguages.Count(); + for(TInt i=0;iStream().WriteInt32L(aDeviceSupportedLanguages[i]); + } + // Save ptr for args (must persist whilst server is processing) + iPtrIntoArgsStream.Set(iArgsStream->Ptr()); + // Issue initial request iUissSession.Install(iPtrIntoArgsStream, iPtrIntoBuf, iStatus); if (iActiveObjectMode) - { - SetActive(); - } + { + SetActive(); + } // Update client's TRequestStatus object *iClientStatus = KRequestPending; iSisHelper = aServer; - } + } #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK void CUissClientHandler::GetComponentInfoL(const CInstallPrefs& aInstallPrefs, Usif::CComponentInfo& aComponentInfo, TRequestStatus& aRequestStatus, RThread& aServer) - { + { iState = KUissClientGettingCompInfo; iClientStatus = &aRequestStatus; - + // Store the component info reference to the class reference. So that, the same will be // populated after getting the asynchronous method completed. iComponentInfo = &aComponentInfo; - InitializeArgStreamL(aInstallPrefs); - - AllocCompInfoBufL(KCompInfoBufferSize); - - // Save the pointer for component info collection buffer - iCompInfoBufPtr.Set(iCompInfoBuffer->Des()); + InitializeArgStreamL(aInstallPrefs); + + AllocCompInfoBufL(KCompInfoBufferSize); + + // Save the pointer for component info collection buffer + iCompInfoBufPtr.Set(iCompInfoBuffer->Des()); // Issue get component info request iUissSession.GetComponentInfo(iPtrIntoArgsStream, iCompInfoBufPtr, iStatus); - // There is no synchronous API for GetComponentInfo - __ASSERT_ALWAYS(iActiveObjectMode, User::Invariant()); - SetActive(); + // There is no synchronous API for GetComponentInfo + __ASSERT_ALWAYS(iActiveObjectMode, User::Invariant()); + SetActive(); // Update client's TRequestStatus object *iClientStatus = KRequestPending; - iSisHelper = aServer; - } + iSisHelper = aServer; + } #endif void CUissClientHandler::UninstallL(const CSisRegistryPackage& aPackage, TRequestStatus& aRequestStatus) - { + { iState = KUissClientUninstalling; iClientStatus = &aRequestStatus; @@ -317,241 +327,264 @@ delete iArgsStream; iArgsStream = 0; - iArgsStream = CWriteStream::NewL(); + iArgsStream = CWriteStream::NewL(); *iArgsStream << aPackage; // Save ptr for args (must persist whilst server is processing) - iPtrIntoArgsStream.Set(iArgsStream->Ptr()); + iPtrIntoArgsStream.Set(iArgsStream->Ptr()); - // Issue initial request + // Issue initial request iUissSession.Uninstall(iPtrIntoArgsStream, iPtrIntoBuf, iStatus); if (iActiveObjectMode) - { - SetActive(); - } + { + SetActive(); + } // Update client's TRequestStatus object *iClientStatus = KRequestPending; - } + } void CUissClientHandler::CancelOperation() - { - if (iState == KUissClientIdle) - { - return; - } - - // User called this so must have an outstanding request with us. + { + if (iState == KUissClientIdle) + { + return; + } + + // User called this so must have an outstanding request with us. - // First tell the Uiss that we want to cancel the current - // operation. - // - // If we have an outstanding Uiss request, this will complete (with - // KErrCancel) when the operation has terminated. - // - // If we are called inside a dialog callback, then there is no - // outstanding Uiss request at the moment. When the dialog - // returns, we will issue a request, which will complete (with - // KErrCancel) when the operation has terminated. - (void)iUissSession.Cancel(); - } + // First tell the Uiss that we want to cancel the current + // operation. + // + // If we have an outstanding Uiss request, this will complete (with + // KErrCancel) when the operation has terminated. + // + // If we are called inside a dialog callback, then there is no + // outstanding Uiss request at the moment. When the dialog + // returns, we will issue a request, which will complete (with + // KErrCancel) when the operation has terminated. + (void)iUissSession.Cancel(); + } void CUissClientHandler::WorkUntilCompleteL() - { - // Keep processing UISS responses and issuing new requests - // until we update the client status to non-pending. - while(iClientStatus && *iClientStatus == KRequestPending) - { - User::WaitForRequest(iStatus); - TRAPD(err,RunL()); - if(err != KErrNone) - { - RunError(err); - } - } - } + { + // Keep processing UISS responses and issuing new requests + // until we update the client status to non-pending. + while(iClientStatus && *iClientStatus == KRequestPending) + { + User::WaitForRequest(iStatus); + TRAPD(err,RunL()); + if(err != KErrNone) + { + RunError(err); + } + } + } TBool CUissClientHandler::IsBusy() - { - return iState != KUissClientIdle; - } + { + return iState != KUissClientIdle; + } // // Code necessary to run UISS in the same process but in a different thread // TInt CUissClientHandler::StartUiss() - { - const TInt KUissServerStackSize=0x2000; - const TInt KUissServerInitHeapSize=0x1000; - const TInt KUissServerMaxHeapSize=0x1000000; - - - TThreadFunction entryPoint=UissThreadFunction; - //TUiSupportStartParams uiSupportParams(aUiHandler); - // The owner of the new thread will be the process, otherwise if the - // current thread dies, the server thread will die, too. - RThread server; - TInt err = KErrNone; - - for (TInt retry=0; retry < 2; ++retry) - { - err = server.Create(KUissServerName, entryPoint, - KUissServerStackSize, KUissServerInitHeapSize, KUissServerMaxHeapSize, - NULL, EOwnerThread); - - if (err == KErrAlreadyExists) - { - User::After(30000); - } - else - { - break; - } - } - - if (err==KErrAlreadyExists) - { - return KErrServerBusy; - } - if (err != KErrNone) - { - return err; - } - - // Synchronise with the process to make sure it hasn't died straight away - TRequestStatus stat; - server.Rendezvous(stat); - if (stat != KRequestPending) - { - // logon failed - server is not yet running, so cannot have terminated - server.Kill(0); // Abort startup - } - else - { - // logon OK - start the server - server.Resume(); - } - // Wait to synchronise with server - if it dies in the meantime, it - // also gets completed - User::WaitForRequest(stat); - // We can't use the 'exit reason' if the server panicked as this - // is the panic 'reason' and may be '0' which cannot be distinguished - // from KErrNone - TInt r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); - server.Close(); - return r; - } + { + const TInt KUissServerStackSize=0x2000; + const TInt KUissServerInitHeapSize=0x1000; + const TInt KUissServerMaxHeapSize=0x1000000; + + + TThreadFunction entryPoint=UissThreadFunction; + //TUiSupportStartParams uiSupportParams(aUiHandler); + // The owner of the new thread will be the process, otherwise if the + // current thread dies, the server thread will die, too. + RThread server; + TInt err = KErrNone; + + for (TInt retry=0; retry < 2; ++retry) + { + err = server.Create(KUissServerName, entryPoint, + KUissServerStackSize, KUissServerInitHeapSize, KUissServerMaxHeapSize, + NULL, EOwnerThread); + + if (err == KErrAlreadyExists) + { + User::After(30000); + } + else + { + break; + } + } + + if (err==KErrAlreadyExists) + { + return KErrServerBusy; + } + if (err != KErrNone) + { + return err; + } + + // Synchronise with the process to make sure it hasn't died straight away + TRequestStatus stat; + server.Rendezvous(stat); + if (stat != KRequestPending) + { + // logon failed - server is not yet running, so cannot have terminated + server.Kill(0); // Abort startup + } + else + { + // logon OK - start the server + server.Resume(); + } + // Wait to synchronise with server - if it dies in the meantime, it + // also gets completed + User::WaitForRequest(stat); + // We can't use the 'exit reason' if the server panicked as this + // is the panic 'reason' and may be '0' which cannot be distinguished + // from KErrNone + TInt r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); + server.Close(); + return r; + } // Entry point for the thread the UISS runs in TInt CUissClientHandler::UissThreadFunction(TAny *) - { - __UHEAP_MARK; - CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack - - CActiveScheduler* scheduler=new(ELeave) CActiveScheduler; - CActiveScheduler::Install(scheduler); - CUissServer* server=NULL; - - TRAPD(err, server=CUissServer::NewL()); - if (err==KErrNone) - { - RThread::Rendezvous(KErrNone); - scheduler->Start(); - } - - delete server; - - CActiveScheduler::Install(NULL); - delete scheduler; - delete cleanup; // destroy clean-up stack - __UHEAP_MARKEND; - return KErrNone; - } + { + __UHEAP_MARK; + CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack + + CActiveScheduler* scheduler=new(ELeave) CActiveScheduler; + CActiveScheduler::Install(scheduler); + CUissServer* server=NULL; + + TRAPD(err, server=CUissServer::NewL()); + if (err==KErrNone) + { + RThread::Rendezvous(KErrNone); + scheduler->Start(); + } + + delete server; + + CActiveScheduler::Install(NULL); + delete scheduler; + delete cleanup; // destroy clean-up stack + __UHEAP_MARKEND; + return KErrNone; + } void CUissClientHandler::RunL() { TInt err = iStatus.Int(); - iPtrIntoBuf.Set(iBuf->Des()); // Get ptr to our return buffer - + iPtrIntoBuf.Set(iBuf->Des()); // Get ptr to our return buffer + DEBUG_PRINTF2(_L8("Sis Helper - UISS Client Handler, RunL(). Status: %d."), err); - - + if(err > 0) + { + // For Logging purpose, store the buffer to retrieve + // application info later. + delete iBufLogger; + iBufLogger = 0; + iBufLogger = iBuf->AllocL(); + } + if (err==KErrOverflow -#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK - && iState != KUissClientGettingCompInfo // We don't support overflow management for component info +#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + && iState != KUissClientGettingCompInfo // We don't support overflow management for component info #endif - ) + ) { // Grow the respective buffer buffer and re-issue "request". // There should now be space for the UISS server to copy in its dialogue message. HandleOverflowL(); iPtrIntoBuf.Set(iBuf->Des()); - iUissSession.BufferReallocated(iPtrIntoBuf, iStatus); + iUissSession.BufferReallocated(iPtrIntoBuf, iStatus); - if (iActiveObjectMode) - { - SetActive(); - } - return; - } - else - { - if (err>CUissSession::KMsgSeparatorMinimumSwisMessage && - errCUissSession::KMsgSeparatorMinimumSwisMessage && + errHandleMessageL(iPtrIntoBuf, iPtrIntoBuf); + CleanupStack::PopAndDestroy(cmdHandler); + } + else + { + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + // Request has been completed successfully. So, now construct the + // component info from the buffer which is populated from the SWI server. + if (err == KErrNone && iState == KUissClientGettingCompInfo) + { + ConstructCompInfoFromBufferL(); + } + #endif + // Either KErrNone or some sort of error status - in any case the processing has finished + iState = KUissClientIdle; + } + } + + // Re-issue request, if we are still installing/uninstalling + switch(iState) + { + case KUissClientInstalling: + case KUissClientUninstalling: + iUissSession.CompleteDialog(KErrNone, iPtrIntoBuf, iStatus); + if (iActiveObjectMode) + { + SetActive(); + } + return; + + case KUissClientIdle: + // All done, or failed... + delete iArgsStream; + iArgsStream = 0; + //Wait for the death of SisHelper + WaitForSisHelperShutdown(); + // Complete user request (also sets iClientStatus to 0) + ASSERT(iClientStatus); + User::RequestComplete(iClientStatus, err); + + // Logging the error to a file + // Temporary solution, should be removed once instrumentation is fully operational. + if(err != KErrNone) + { + TRAP_IGNORE( + RDesReadStream readStream(iBufLogger->Des()); + CleanupClosePushL(readStream); - CleanupStack::PushL(cmdHandler); - // Note that the callback might call CancelOperation which - // would update iState... - cmdHandler->HandleMessageL(iPtrIntoBuf, iPtrIntoBuf); - CleanupStack::PopAndDestroy(cmdHandler); - } - else - { - #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK - // Request has been completed successfully. So, now construct the - // component info from the buffer which is populated from the SWI server. - if (err == KErrNone && iState == KUissClientGettingCompInfo) - { - ConstructCompInfoFromBufferL(); - } - #endif - // Either KErrNone or some sort of error status - in any case the processing has finished - iState = KUissClientIdle; - } - } - - // Re-issue request, if we are still installing/uninstalling - switch(iState) - { - case KUissClientInstalling: - case KUissClientUninstalling: - iUissSession.CompleteDialog(KErrNone, iPtrIntoBuf, iStatus); - if (iActiveObjectMode) - { - SetActive(); - } - return; - - case KUissClientIdle: - // All done, or failed... - delete iArgsStream; - iArgsStream = 0; - //Wait for the death of SisHelper - WaitForSisHelperShutdown(); - // Complete user request (also sets iClientStatus to 0) - ASSERT(iClientStatus); - User::RequestComplete(iClientStatus, err); - return; - } - ASSERT(false); + //Retrieve package name. + CAppInfo* appInfo=CAppInfo::NewLC(readStream); + LogSwiErrorsToFileL(err, appInfo->AppName()); + + CleanupStack::PopAndDestroy(2, &readStream); + ); + } + return; + } + ASSERT(false); } @@ -562,11 +595,11 @@ iPtrIntoBuf.Zero(); iUissSession.CompleteDialog(aError, iPtrIntoBuf, iStatus); if (iActiveObjectMode) - { - SetActive(); - } - return KErrNone; // Do not crash the CActiveScheduler. - } + { + SetActive(); + } + return KErrNone; // Do not crash the CActiveScheduler. + } void CUissClientHandler::DoCancel() { @@ -580,114 +613,164 @@ // iStatus, which would stop the active scheduler and hence stop // the CancelOperation from being actioned. - // Do an emergency abort..... + // Do an emergency abort..... - // First kill our helper threads - - // SIS helper thread/server - CSisHelperServer::Abort(); - - // UI helper thread/server - TFullName fullName = RProcess().FullName(); - fullName.Append(':'); - fullName.Append(':'); - fullName.Append(KUissServerName); + // First kill our helper threads + + // SIS helper thread/server + CSisHelperServer::Abort(); + + // UI helper thread/server + TFullName fullName = RProcess().FullName(); + fullName.Append(':'); + fullName.Append(':'); + fullName.Append(KUissServerName); - RThread server; - TInt err = server.Open(fullName); - if (err == KErrNone) - { - server.Terminate(KErrAbort); - server.Close(); - } - - // Now complete any client request - if (iClientStatus) - { - User::RequestComplete(iClientStatus, err); - } + RThread server; + TInt err = server.Open(fullName); + if (err == KErrNone) + { + server.Terminate(KErrAbort); + server.Close(); + } + + // Now complete any client request + if (iClientStatus) + { + User::RequestComplete(iClientStatus, err); + } } #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK void CUissClientHandler::ConstructCompInfoFromBufferL() { // create a stream based on the buffer - RDesReadStream stream(*iCompInfoBuffer); - CleanupClosePushL(stream); - - CNativeComponentInfo* nativeCompInfo = CNativeComponentInfo::NewLC(); - nativeCompInfo->InternalizeL(stream); - - // UISS and SWI cannot use Usif::CComponentInfo directly, as it is implemented in a non-TCB DLL. For this reason, a private structure maintained (CNativeComponentInfo), - // which is returned by SWI and is converted here to the CComponentInfo according to the USIF interface - Usif::CComponentInfo::CNode* rootNode = MapToComponentInfoL(*nativeCompInfo); - iComponentInfo->SetRootNodeL(rootNode); - - CleanupStack::PopAndDestroy(nativeCompInfo); - CleanupStack::PopAndDestroy(&stream); - } + RDesReadStream stream(*iCompInfoBuffer); + CleanupClosePushL(stream); + + CNativeComponentInfo* nativeCompInfo = CNativeComponentInfo::NewLC(); + nativeCompInfo->InternalizeL(stream); + + // UISS and SWI cannot use Usif::CComponentInfo directly, as it is implemented in a non-TCB DLL. For this reason, a private structure maintained (CNativeComponentInfo), + // which is returned by SWI and is converted here to the CComponentInfo according to the USIF interface + Usif::CComponentInfo::CNode* rootNode = MapToComponentInfoL(*nativeCompInfo); + iComponentInfo->SetRootNodeL(rootNode); - void CUissClientHandler::MapToApplicationInfoL(RCPointerArray& aNativeApplicationsInfo, RPointerArray& aApplicationsInfo) - { - TInt count = aNativeApplicationsInfo.Count(); - for (TInt i = 0; i < count; ++i) - { - Usif::CComponentInfo::CApplicationInfo* app ; - app = Usif::CComponentInfo::CApplicationInfo::NewLC(aNativeApplicationsInfo[i]->AppUid(), aNativeApplicationsInfo[i]->Name(), aNativeApplicationsInfo[i]->GroupName(), aNativeApplicationsInfo[i]->IconFileName()); - DEBUG_PRINTF2(_L("App Uid 0x%08x"),app->AppUid()); - DEBUG_PRINTF2(_L("File Name %S"),&app->Name()); - DEBUG_PRINTF2(_L("Group Name %S"),&app->GroupName()); - DEBUG_PRINTF2(_L("Icon File Name %S"),&app->IconFileName()); - aApplicationsInfo.AppendL(app); - CleanupStack::Pop(app); - } + CleanupStack::PopAndDestroy(nativeCompInfo); + CleanupStack::PopAndDestroy(&stream); } Usif::CComponentInfo::CNode* CUissClientHandler::MapToComponentInfoL(CNativeComponentInfo& aNativeComponentInfo) - { - // Create the array to store the children nodes. - RPointerArray children; - CleanupResetAndDestroyPushL(children); - - // If there is any child for the current node, call this method with that child object. - // Continue this (recursively) until we get the leaf node in the embedded tree (with no children) - // and add the resultant node as one of the children and pass it to create the parent node further. - TInt count = aNativeComponentInfo.iChildren.Count(); - for (TInt i = 0; i < count; ++i) - { - Usif::CComponentInfo::CNode* node = MapToComponentInfoL(*aNativeComponentInfo.iChildren[i]); - CleanupStack::PushL(node); - children.AppendL(node); - CleanupStack::Pop(node); - } - - RPointerArray applicationInfo; - CleanupResetAndDestroyPushL(applicationInfo); - MapToApplicationInfoL(aNativeComponentInfo.iApplications, applicationInfo); - // Create the CNode object using the appropriate parameters. - // children for leaf nodes (bottom most nodes in the embedded tree) will be null. - Usif::CComponentInfo::CNode* node = Usif::CComponentInfo::CNode::NewLC( - Usif::KSoftwareTypeNative(), - *(aNativeComponentInfo.iComponentName), - *(aNativeComponentInfo.iVersion), - *(aNativeComponentInfo.iVendor), - static_cast(aNativeComponentInfo.iScomoState), - static_cast(aNativeComponentInfo.iInstallStatus), - aNativeComponentInfo.iComponentId, - *(aNativeComponentInfo.iGlobalComponentId), - static_cast(aNativeComponentInfo.iAuthenticity), - aNativeComponentInfo.iUserGrantableCaps, - aNativeComponentInfo.iMaxInstalledSize, - aNativeComponentInfo.iHasExe, - aNativeComponentInfo.iIsDriveSelectionRequired, - &applicationInfo, - &children); - CleanupStack::Pop(node); - CleanupStack::Pop(&applicationInfo); - applicationInfo.Close(); - CleanupStack::Pop(&children); - children.Close(); - return (node); - } + { + // Create the array to store the children nodes. + RPointerArray children; + CleanupResetAndDestroyPushL(children); + + // If there is any child for the current node, call this method with that child object. + // Continue this (recursively) until we get the leaf node in the embedded tree (with no children) + // and add the resultant node as one of the children and pass it to create the parent node further. + TInt count = aNativeComponentInfo.iChildren.Count(); + for (TInt i = 0; i < count; ++i) + { + Usif::CComponentInfo::CNode* node = MapToComponentInfoL(*aNativeComponentInfo.iChildren[i]); + CleanupStack::PushL(node); + children.AppendL(node); + CleanupStack::Pop(node); + } + + // Create the CNode object using the appropriate parameters. + // children for leaf nodes (bottom most nodes in the embedded tree) will be null. + Usif::CComponentInfo::CNode* node = Usif::CComponentInfo::CNode::NewLC( + Usif::KSoftwareTypeNative(), + *(aNativeComponentInfo.iComponentName), + *(aNativeComponentInfo.iVersion), + *(aNativeComponentInfo.iVendor), + static_cast(aNativeComponentInfo.iScomoState), + static_cast(aNativeComponentInfo.iInstallStatus), + aNativeComponentInfo.iComponentId, + *(aNativeComponentInfo.iGlobalComponentId), + static_cast(aNativeComponentInfo.iAuthenticity), + aNativeComponentInfo.iUserGrantableCaps, + aNativeComponentInfo.iMaxInstalledSize, + aNativeComponentInfo.iHasExe, + &children); + CleanupStack::Pop(node); + CleanupStack::Pop(&children); + children.Close(); + return (node); + } #endif + + +void LogSwiErrorsToFileL(TInt aErrorCode, const TDesC& aAppName) + { + _LIT(KErrorString, "%S : Failed with %d"); + _LIT(KLogFile, "c:\\data\\swilog.log"); + + //Format Output string + HBufC* outputString = HBufC::NewLC(aAppName.Length()+ 30); + outputString->Des().Format(KErrorString, &aAppName, aErrorCode); + + //Maximum number of log file entries. + const TUint KLogFileSize = 10; + + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + RFile logFile; + TInt err = logFile.Open(fs, KLogFile, EFileWrite); + if(err != KErrNone) + { + //Attempt to create the file. + err = logFile.Create(fs, KLogFile, EFileWrite); + User::LeaveIfError(err); + } + CleanupClosePushL(logFile); + + + //Read the entire log file. + RPointerArray linesArray; + CleanupResetAndDestroyPushL(linesArray); + + TFileText logFileManipulator; + logFileManipulator.Set(logFile); + + TBuf<200>buffer; + err = logFileManipulator.Read(buffer); + TInt count(0); + while(err == KErrNone && ++count <= KLogFileSize) + { + HBufC* line = buffer.AllocLC(); + linesArray.AppendL(line); + CleanupStack::Pop(line); + err = logFileManipulator.Read(buffer); + } + + // If the log file contains less than KLogFileSize entries, + // write the new log entry. + if(count < KLogFileSize) + { + logFileManipulator.Seek(ESeekEnd); + logFileManipulator.Write(*outputString); + } + else + { + // Contains KLogFileSize entries. + // Replicate the last KLogFileSize - 1 entries and add the + // new log at the end. + logFile.Close(); + logFile.Replace(fs, KLogFile, EFileWrite); + logFileManipulator.Set(logFile); + for(TInt i = linesArray.Count()- KLogFileSize +1; i