installationservices/swi/source/sishelper/uissclienthandler.cpp
branchRCL_3
changeset 17 741e5bba2bd1
parent 0 ba25891c3a9e
child 25 7333d7932ef7
equal deleted inserted replaced
15:98a43fae6e2b 17:741e5bba2bd1
     1 /*
     1 /*
     2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    49 #include "commands/uninstalldialog.h"
    49 #include "commands/uninstalldialog.h"
    50 #include "commands/securitywarningdialog.h"
    50 #include "commands/securitywarningdialog.h"
    51 #include "commands/textdialog.h"
    51 #include "commands/textdialog.h"
    52 #include "log.h"
    52 #include "log.h"
    53 
    53 
       
    54 #include "cleanuputils.h"
    54 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
    55 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
    55 #include "cleanuputils.h"
       
    56 #include <usif/sif/sifcommon.h>
    56 #include <usif/sif/sifcommon.h>
    57 const TInt KCompInfoBufferSize=4*1024;
    57 const TInt KCompInfoBufferSize=4*1024;
    58 #endif
    58 #endif
    59 
    59 
       
    60 
       
    61 
    60 namespace Swi
    62 namespace Swi
    61 {
    63 {
       
    64 
       
    65 //Temporary error logging solution.
       
    66 void LogSwiErrorsToFileL(TInt aErrorCode, const TDesC& aAppName);
       
    67 
    62 //
    68 //
    63 // A cancel handler
    69 // A cancel handler
    64 //
    70 //
    65 class InternalCancelHandler : public MCancelHandler
    71 class InternalCancelHandler : public MCancelHandler
    66 	{
    72     {
    67 public:
    73 public:
    68 	InternalCancelHandler(CUissClientHandler& aUissClientHandler);
    74     InternalCancelHandler(CUissClientHandler& aUissClientHandler);
    69 	void HandleCancel();
    75     void HandleCancel();
    70 private:
    76 private:
    71 	CUissClientHandler& iUissClientHandler;
    77     CUissClientHandler& iUissClientHandler;
    72 	};
    78     };
    73 
    79 
    74 InternalCancelHandler::InternalCancelHandler(
    80 InternalCancelHandler::InternalCancelHandler(
    75 	CUissClientHandler& aUissClientHandler)
    81     CUissClientHandler& aUissClientHandler)
    76 :	iUissClientHandler(aUissClientHandler)
    82 :   iUissClientHandler(aUissClientHandler)
    77 	{
    83     {
    78 	}
    84     }
    79 
    85 
    80 void InternalCancelHandler::HandleCancel()
    86 void InternalCancelHandler::HandleCancel()
    81 	{
    87     {
    82 	iUissClientHandler.CancelOperation();
    88     iUissClientHandler.CancelOperation();
    83 	}
    89     }
    84 
    90 
    85 CUissClientHandler* CUissClientHandler::NewLC(MUiHandler& aUiHandler, TBool aActiveObjectMode)
    91 CUissClientHandler* CUissClientHandler::NewLC(MUiHandler& aUiHandler, TBool aActiveObjectMode)
    86 	{
    92     {
    87 	CUissClientHandler* self=new(ELeave) CUissClientHandler(aUiHandler, aActiveObjectMode);
    93     CUissClientHandler* self=new(ELeave) CUissClientHandler(aUiHandler, aActiveObjectMode);
    88 	CleanupStack::PushL(self);
    94     CleanupStack::PushL(self);
    89 	self->ConstructL();
    95     self->ConstructL();
    90 	return self;
    96     return self;
    91 	}
    97     }
    92 
    98 
    93 CUissClientHandler* CUissClientHandler::NewL(MUiHandler& aUiHandler, TBool aActiveObjectMode)
    99 CUissClientHandler* CUissClientHandler::NewL(MUiHandler& aUiHandler, TBool aActiveObjectMode)
    94 	{
   100     {
    95 	CUissClientHandler* self=NewLC(aUiHandler, aActiveObjectMode);
   101     CUissClientHandler* self=NewLC(aUiHandler, aActiveObjectMode);
    96 	CleanupStack::Pop(self);
   102     CleanupStack::Pop(self);
    97 	return self;
   103     return self;
    98 	}
   104     }
    99 
   105 
   100 CUissClientHandler::CUissClientHandler(MUiHandler& aUiHandler, TBool aActiveObjectMode)
   106 CUissClientHandler::CUissClientHandler(MUiHandler& aUiHandler, TBool aActiveObjectMode)
   101         : CActive(EPriorityStandard),
   107         : CActive(EPriorityStandard),
   102           iUiHandler(aUiHandler),
   108           iUiHandler(aUiHandler),
   103 		  iPtrIntoBuf(0,0),
   109           iPtrIntoBuf(0,0),
   104           iActiveObjectMode(aActiveObjectMode),
   110           iActiveObjectMode(aActiveObjectMode),
   105 		  iPtrIntoArgsStream(0,0)
   111           iPtrIntoArgsStream(0,0)
   106 		  #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   112           #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   107 		  ,iCompInfoBufPtr(0,0)
   113           ,iCompInfoBufPtr(0,0)
   108 		  #endif
   114           #endif
   109 	{
   115     {
   110     if (iActiveObjectMode)
   116     if (iActiveObjectMode)
   111 		{
   117         {
   112 		CActiveScheduler::Add(this);
   118         CActiveScheduler::Add(this);
   113 		}
   119         }
   114 	}
   120     }
   115 
   121 
   116 void CUissClientHandler::WaitForSisHelperShutdown()
   122 void CUissClientHandler::WaitForSisHelperShutdown()
   117 	{	
   123     {   
   118 	if(iSisHelper.Handle() > 0)
   124     if(iSisHelper.Handle() > 0)
   119 		{
   125         {
   120 		TRequestStatus reqStatus;
   126         TRequestStatus reqStatus;
   121 		iSisHelper.Logon(reqStatus);
   127         iSisHelper.Logon(reqStatus);
   122 		User::WaitForRequest(reqStatus);
   128         User::WaitForRequest(reqStatus);
   123 		iSisHelper.Close();
   129         iSisHelper.Close();
   124 		}		
   130         }       
   125 	}
   131     }
   126 	
   132     
   127 CUissClientHandler::~CUissClientHandler()
   133 CUissClientHandler::~CUissClientHandler()
   128 	{
   134     {
   129 	//Cancel any outstanding request
   135     //Cancel any outstanding request
   130 	CancelOperation();
   136     CancelOperation();
   131 
   137 
   132 	WaitForSisHelperShutdown();
   138     WaitForSisHelperShutdown();
   133     if (iActiveObjectMode)
   139     if (iActiveObjectMode)
   134 		{
   140         {
   135 		CActive::Cancel(); // Make sure we are cancelled before deletion
   141         CActive::Cancel(); // Make sure we are cancelled before deletion
   136 		}
   142         }
   137 
   143 
   138 	delete iCancelHandler;
   144     delete iCancelHandler;
   139     delete iArgsStream;
   145     delete iArgsStream;
   140 	iUissSession.Close();
   146     iUissSession.Close();
   141 	delete iBuf;
   147     delete iBuf;
   142 	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   148     delete iBufLogger;
       
   149     #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   143     delete iCompInfoBuffer;
   150     delete iCompInfoBuffer;
   144 	#endif
   151     #endif
   145 	}
   152     }
   146 
   153 
   147 /**
   154 /**
   148  * Allocates a buffer for reverse-completion commands. The buffer is going to 
   155  * Allocates a buffer for reverse-completion commands. The buffer is going to 
   149  * be resized in case it is not sufficient for a dialog command.
   156  * be resized in case it is not sufficient for a dialog command.
   150  */
   157  */
   151 void CUissClientHandler::ConstructL()
   158 void CUissClientHandler::ConstructL()
   152 	{
   159     {
   153 	iCancelHandler=new(ELeave) InternalCancelHandler(*this);
   160     iCancelHandler=new(ELeave) InternalCancelHandler(*this);
   154 	AllocBufL(KBufSize);// Allocate the initial r/c buffer
   161     AllocBufL(KBufSize);// Allocate the initial r/c buffer
   155 	User::LeaveIfError(StartUiss()); // Start UISS
   162 
   156 	User::LeaveIfError(iUissSession.Connect()); // Connect to UISS
   163 	//Logger buffer.
   157 	}
   164 	iBufLogger = KNullDesC8().AllocL();
       
   165     User::LeaveIfError(StartUiss()); // Start UISS
       
   166     User::LeaveIfError(iUissSession.Connect()); // Connect to UISS
       
   167     }
   158 
   168 
   159 void CUissClientHandler::AllocBufL(TInt aSize)
   169 void CUissClientHandler::AllocBufL(TInt aSize)
   160 	{
   170     {
   161     HBufC8* buf=HBufC8::NewL(aSize);
   171     HBufC8* buf=HBufC8::NewL(aSize);
   162     delete iBuf;
   172     delete iBuf;
   163     iBuf=buf;
   173     iBuf=buf;
   164     }
   174     }
   165 
   175 
   166 void CUissClientHandler::HandleOverflowL()
   176 void CUissClientHandler::HandleOverflowL()
   167 	{
   177     {
   168 	// Reallocate the buffer to the size received in parameter 1
   178     // Reallocate the buffer to the size received in parameter 1
   169 	TInt size=0;
   179     TInt size=0;
   170 	TPckg<TInt> theSize(size);
   180     TPckg<TInt> theSize(size);
   171 	theSize.Copy(iBuf->Left(sizeof(TInt)));
   181     theSize.Copy(iBuf->Left(sizeof(TInt)));
   172 	AllocBufL(size);
   182     AllocBufL(size);
   173 	}
   183     }
   174 	
   184     
   175 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   185 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   176 void CUissClientHandler::AllocCompInfoBufL(TInt aSize)
   186 void CUissClientHandler::AllocCompInfoBufL(TInt aSize)
   177 	{
   187     {
   178     HBufC8* buf = HBufC8::NewL(aSize);
   188     HBufC8* buf = HBufC8::NewL(aSize);
   179     delete iCompInfoBuffer;
   189     delete iCompInfoBuffer;
   180     iCompInfoBuffer = buf;
   190     iCompInfoBuffer = buf;
   181     }
   191     }
   182 #endif
   192 #endif
   183 
   193 
   184 ///\short Creates a command handler object for the specified dialog request
   194 ///\short Creates a command handler object for the specified dialog request
   185 CUissCmdHandler* CUissClientHandler::UissCmdHandlerFactoryL(TInt aCommand) const
   195 CUissCmdHandler* CUissClientHandler::UissCmdHandlerFactoryL(TInt aCommand) const
   186 	{
   196     {
   187 	switch (aCommand)
   197     switch (aCommand)
   188 		{
   198         {
   189 		case CUissSession::KMessageApplicationsInUseDialog:
   199         case CUissSession::KMessageApplicationsInUseDialog:
   190 			return new(ELeave) CApplicationsInUseDialogCmdHandler(iUiHandler);
   200             return new(ELeave) CApplicationsInUseDialogCmdHandler(iUiHandler);
   191 		case CUissSession::KMessageCannotOverwriteFileDialog:
   201         case CUissSession::KMessageCannotOverwriteFileDialog:
   192 			return new(ELeave) CCannotOverwriteFileDialogCmdHandler(iUiHandler);
   202             return new(ELeave) CCannotOverwriteFileDialogCmdHandler(iUiHandler);
   193 		
   203         
   194 		case CUissSession::KMessageDependencyBreakDialog:
   204         case CUissSession::KMessageDependencyBreakDialog:
   195 			return new(ELeave) CDependencyBreakDialogCmdHandler(iUiHandler);
   205             return new(ELeave) CDependencyBreakDialogCmdHandler(iUiHandler);
   196 		case CUissSession::KMessageDeviceIncompatibility:
   206         case CUissSession::KMessageDeviceIncompatibility:
   197 			return new(ELeave) CDeviceIncompatibilityDialogCmdHandler(iUiHandler);
   207             return new(ELeave) CDeviceIncompatibilityDialogCmdHandler(iUiHandler);
   198 		case CUissSession::KMessageMissingDependency:
   208         case CUissSession::KMessageMissingDependency:
   199 			return new(ELeave) CMissingDependencyDialogCmdHandler(iUiHandler);
   209             return new(ELeave) CMissingDependencyDialogCmdHandler(iUiHandler);
   200 		case CUissSession::KMessageDriveDialog:
   210         case CUissSession::KMessageDriveDialog:
   201 			return new(ELeave) CDriveDialogCmdHandler(iUiHandler);
   211             return new(ELeave) CDriveDialogCmdHandler(iUiHandler);
   202 		case CUissSession::KMessageErrorDialog:
   212         case CUissSession::KMessageErrorDialog:
   203 			return new(ELeave) CErrorDialogCmdHandler(iUiHandler);
   213             return new(ELeave) CErrorDialogCmdHandler(iUiHandler);
   204 		case CUissSession::KMessageGrantCapabilitiesDialog:
   214         case CUissSession::KMessageGrantCapabilitiesDialog:
   205 			return new(ELeave) CGrantCapabilitiesDialogCmdHandler(iUiHandler);	
   215             return new(ELeave) CGrantCapabilitiesDialogCmdHandler(iUiHandler);  
   206 		case CUissSession::KMessageHandleCancellableInstallEvent:
   216         case CUissSession::KMessageHandleCancellableInstallEvent:
   207 			return new(ELeave) CHandleCancellableInstallEventCmdHandler(iUiHandler, 
   217             return new(ELeave) CHandleCancellableInstallEventCmdHandler(iUiHandler, 
   208 				*iCancelHandler);
   218                 *iCancelHandler);
   209 		case CUissSession::KMessageHandleInstallEvent:
   219         case CUissSession::KMessageHandleInstallEvent:
   210 			return new(ELeave) CHandleInstallEventCmdHandler(iUiHandler);
   220             return new(ELeave) CHandleInstallEventCmdHandler(iUiHandler);
   211 		case CUissSession::KMessageInstallDialog:
   221         case CUissSession::KMessageInstallDialog:
   212 			return new(ELeave) CInstallDialogCmdHandler(iUiHandler);
   222             return new(ELeave) CInstallDialogCmdHandler(iUiHandler);
   213 		case CUissSession::KMessageLanguageDialog:
   223         case CUissSession::KMessageLanguageDialog:
   214 			return new(ELeave) CLanguageDialogCmdHandler(iUiHandler);
   224             return new(ELeave) CLanguageDialogCmdHandler(iUiHandler);
   215 		case CUissSession::KMessageOcspResultDialog:
   225         case CUissSession::KMessageOcspResultDialog:
   216 			return new(ELeave) COcspResultDialogCmdHandler(iUiHandler);
   226             return new(ELeave) COcspResultDialogCmdHandler(iUiHandler);
   217 		case CUissSession::KMessageOptionsDialog:
   227         case CUissSession::KMessageOptionsDialog:
   218 			return new(ELeave) COptionsDialogCmdHandler(iUiHandler);
   228             return new(ELeave) COptionsDialogCmdHandler(iUiHandler);
   219 		case CUissSession::KMessageQuestionDialog:
   229         case CUissSession::KMessageQuestionDialog:
   220 			return new(ELeave) CQuestionDialogCmdHandler(iUiHandler);
   230             return new(ELeave) CQuestionDialogCmdHandler(iUiHandler);
   221 		case CUissSession::KMessageSecurityWarningDialog:
   231         case CUissSession::KMessageSecurityWarningDialog:
   222 			return new(ELeave) CSecurityWarningDialogCmdHandler(iUiHandler);
   232             return new(ELeave) CSecurityWarningDialogCmdHandler(iUiHandler);
   223 		case CUissSession::KMessageUninstallDialog:
   233         case CUissSession::KMessageUninstallDialog:
   224 			return new(ELeave) CUninstallDialogCmdHandler(iUiHandler);
   234             return new(ELeave) CUninstallDialogCmdHandler(iUiHandler);
   225 		
   235         
   226 		case CUissSession::KMessageUpgradeDialog:
   236         case CUissSession::KMessageUpgradeDialog:
   227 			return new(ELeave) CUpgradeDialogCmdHandler(iUiHandler);
   237             return new(ELeave) CUpgradeDialogCmdHandler(iUiHandler);
   228 		
   238         
   229 		case CUissSession::KMessageTextDialog:
   239         case CUissSession::KMessageTextDialog:
   230 			return new(ELeave) CTextDialogCmdHandler(iUiHandler);
   240             return new(ELeave) CTextDialogCmdHandler(iUiHandler);
   231 					
   241                     
   232 		default:
   242         default:
   233 			return NULL;
   243             return NULL;
   234 		}
   244         }
   235 	}
   245     }
   236 
   246 
   237 void CUissClientHandler::InitializeArgStreamL(const CInstallPrefs& aInstallPrefs)
   247 void CUissClientHandler::InitializeArgStreamL(const CInstallPrefs& aInstallPrefs)
   238 	{
   248     {
   239 	// Stream out install parameters. Cannot do this in UISSCLIENT because 
   249     // Stream out install parameters. Cannot do this in UISSCLIENT because 
   240 	// the code is in LAUNCHER which depends on UISSCLIENT.
   250     // the code is in LAUNCHER which depends on UISSCLIENT.
   241     delete iArgsStream;
   251     delete iArgsStream;
   242     iArgsStream = 0;
   252     iArgsStream = 0;
   243 	iArgsStream = CWriteStream::NewL();
   253     iArgsStream = CWriteStream::NewL();
   244 	*iArgsStream << aInstallPrefs;
   254     *iArgsStream << aInstallPrefs;
   245     // Save ptr for args (must persist whilst server is processing)
   255     // Save ptr for args (must persist whilst server is processing)
   246 	iPtrIntoArgsStream.Set(iArgsStream->Ptr());	
   256     iPtrIntoArgsStream.Set(iArgsStream->Ptr()); 
   247 	}
   257     }
   248 	
   258     
   249 void CUissClientHandler::InstallL(const CInstallPrefs& aInstallPrefs, const RArray<TInt>& aDeviceSupportedLanguages, TRequestStatus& aRequestStatus, RThread& aServer)
   259 void CUissClientHandler::InstallL(const CInstallPrefs& aInstallPrefs, const RArray<TInt>& aDeviceSupportedLanguages, TRequestStatus& aRequestStatus, RThread& aServer)
   250 	{
   260     {
   251     iState = KUissClientInstalling;
   261     iState = KUissClientInstalling;
   252     iClientStatus = &aRequestStatus;
   262     iClientStatus = &aRequestStatus;
   253     
   263     
   254     // Save ptr for data returned by request (must persist whilst server is processing)
   264     // Save ptr for data returned by request (must persist whilst server is processing)
   255 	iPtrIntoBuf.Set(iBuf->Des());
   265     iPtrIntoBuf.Set(iBuf->Des());
   256 
   266 
   257 	InitializeArgStreamL(aInstallPrefs);
   267     InitializeArgStreamL(aInstallPrefs);
   258 	iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages.Count());
   268     iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages.Count());
   259 	//Streaming set of languages that device supports
   269     //Streaming set of languages that device supports
   260 	TInt noOfDeviceSupportedLanguages = aDeviceSupportedLanguages.Count();
   270     TInt noOfDeviceSupportedLanguages = aDeviceSupportedLanguages.Count();
   261 	for(TInt i=0;i<noOfDeviceSupportedLanguages;i++)
   271     for(TInt i=0;i<noOfDeviceSupportedLanguages;i++)
   262 		{
   272         {
   263 		iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages[i]);
   273         iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages[i]);
   264 		}
   274         }
   265 	// Save ptr for args (must persist whilst server is processing)
   275     // Save ptr for args (must persist whilst server is processing)
   266 	iPtrIntoArgsStream.Set(iArgsStream->Ptr());	
   276     iPtrIntoArgsStream.Set(iArgsStream->Ptr()); 
   267 		
   277         
   268     // Issue initial request
   278     // Issue initial request
   269     iUissSession.Install(iPtrIntoArgsStream, iPtrIntoBuf, iStatus);
   279     iUissSession.Install(iPtrIntoArgsStream, iPtrIntoBuf, iStatus);
   270     if (iActiveObjectMode)
   280     if (iActiveObjectMode)
   271 		{
   281         {
   272 		SetActive();
   282         SetActive();
   273 		}
   283         }
   274 
   284 
   275     // Update client's TRequestStatus object
   285     // Update client's TRequestStatus object
   276     *iClientStatus = KRequestPending;
   286     *iClientStatus = KRequestPending;
   277     iSisHelper = aServer;
   287     iSisHelper = aServer;
   278 	}
   288     }
   279 
   289 
   280 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   290 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   281 void CUissClientHandler::GetComponentInfoL(const CInstallPrefs& aInstallPrefs, Usif::CComponentInfo& aComponentInfo, TRequestStatus& aRequestStatus, RThread& aServer)
   291 void CUissClientHandler::GetComponentInfoL(const CInstallPrefs& aInstallPrefs, Usif::CComponentInfo& aComponentInfo, TRequestStatus& aRequestStatus, RThread& aServer)
   282 	{	
   292     {    
   283     iState = KUissClientGettingCompInfo;
   293     iState = KUissClientGettingCompInfo;
   284     iClientStatus = &aRequestStatus;
   294     iClientStatus = &aRequestStatus;
   285     	
   295         
   286     // Store the component info reference to the class reference. So that, the same will be 
   296     // Store the component info reference to the class reference. So that, the same will be 
   287     // populated after getting the asynchronous method completed.
   297     // populated after getting the asynchronous method completed.
   288     iComponentInfo = &aComponentInfo;
   298     iComponentInfo = &aComponentInfo;
   289     
   299     
   290 	InitializeArgStreamL(aInstallPrefs);
   300     InitializeArgStreamL(aInstallPrefs);
   291 	
   301     
   292 	AllocCompInfoBufL(KCompInfoBufferSize);	
   302     AllocCompInfoBufL(KCompInfoBufferSize); 
   293 	
   303     
   294 	// Save the pointer for component info collection buffer
   304     // Save the pointer for component info collection buffer
   295 	iCompInfoBufPtr.Set(iCompInfoBuffer->Des());
   305     iCompInfoBufPtr.Set(iCompInfoBuffer->Des());
   296 
   306 
   297     // Issue get component info request
   307     // Issue get component info request
   298     iUissSession.GetComponentInfo(iPtrIntoArgsStream, iCompInfoBufPtr, iStatus);
   308     iUissSession.GetComponentInfo(iPtrIntoArgsStream, iCompInfoBufPtr, iStatus);
   299 
   309 
   300 	// There is no synchronous API for GetComponentInfo
   310     // There is no synchronous API for GetComponentInfo
   301 	__ASSERT_ALWAYS(iActiveObjectMode, User::Invariant());
   311     __ASSERT_ALWAYS(iActiveObjectMode, User::Invariant());
   302 	SetActive();
   312     SetActive();
   303 
   313 
   304     // Update client's TRequestStatus object
   314     // Update client's TRequestStatus object
   305     *iClientStatus = KRequestPending;
   315     *iClientStatus = KRequestPending;
   306     iSisHelper = aServer;	
   316     iSisHelper = aServer;   
   307 	}
   317     }
   308 #endif
   318 #endif
   309 
   319 
   310 void CUissClientHandler::UninstallL(const CSisRegistryPackage& aPackage, TRequestStatus& aRequestStatus)
   320 void CUissClientHandler::UninstallL(const CSisRegistryPackage& aPackage, TRequestStatus& aRequestStatus)
   311 	{
   321     {
   312     iState = KUissClientUninstalling;
   322     iState = KUissClientUninstalling;
   313     iClientStatus = &aRequestStatus;
   323     iClientStatus = &aRequestStatus;
   314 
   324 
   315     // Save ptr for data returned by request (must persist whilst server is processing)
   325     // Save ptr for data returned by request (must persist whilst server is processing)
   316     iPtrIntoBuf.Set(iBuf->Des());
   326     iPtrIntoBuf.Set(iBuf->Des());
   317 
   327 
   318     delete iArgsStream;
   328     delete iArgsStream;
   319     iArgsStream = 0;
   329     iArgsStream = 0;
   320 	iArgsStream = CWriteStream::NewL();
   330     iArgsStream = CWriteStream::NewL();
   321     *iArgsStream << aPackage;
   331     *iArgsStream << aPackage;
   322     // Save ptr for args (must persist whilst server is processing)
   332     // Save ptr for args (must persist whilst server is processing)
   323 	iPtrIntoArgsStream.Set(iArgsStream->Ptr());
   333     iPtrIntoArgsStream.Set(iArgsStream->Ptr());
   324 
   334 
   325 	// Issue initial request
   335     // Issue initial request
   326     iUissSession.Uninstall(iPtrIntoArgsStream, iPtrIntoBuf, iStatus);
   336     iUissSession.Uninstall(iPtrIntoArgsStream, iPtrIntoBuf, iStatus);
   327     if (iActiveObjectMode)
   337     if (iActiveObjectMode)
   328 		{
   338         {
   329 		SetActive();
   339         SetActive();
   330 		}
   340         }
   331 
   341 
   332     // Update client's TRequestStatus object
   342     // Update client's TRequestStatus object
   333     *iClientStatus = KRequestPending;
   343     *iClientStatus = KRequestPending;
   334 	}
   344     }
   335 
   345 
   336 void CUissClientHandler::CancelOperation()
   346 void CUissClientHandler::CancelOperation()
   337 	{
   347     {
   338 	if (iState == KUissClientIdle)
   348     if (iState == KUissClientIdle)
   339 		{
   349         {
   340 		return;
   350         return;
   341 		}
   351         }
   342 	
   352     
   343 	// User called this so must have an outstanding request with us.
   353     // User called this so must have an outstanding request with us.
   344 
   354 
   345 	// First tell the Uiss that we want to cancel the current
   355     // First tell the Uiss that we want to cancel the current
   346 	// operation.
   356     // operation.
   347 	//
   357     //
   348 	// If we have an outstanding Uiss request, this will complete (with
   358     // If we have an outstanding Uiss request, this will complete (with
   349 	// KErrCancel) when the operation has terminated.
   359     // KErrCancel) when the operation has terminated.
   350 	//
   360     //
   351 	// If we are called inside a dialog callback, then there is no
   361     // If we are called inside a dialog callback, then there is no
   352 	// outstanding Uiss request at the moment. When the dialog
   362     // outstanding Uiss request at the moment. When the dialog
   353 	// returns, we will issue a request, which will complete (with
   363     // returns, we will issue a request, which will complete (with
   354 	// KErrCancel) when the operation has terminated.
   364     // KErrCancel) when the operation has terminated.
   355 	(void)iUissSession.Cancel();
   365     (void)iUissSession.Cancel();
   356 	}
   366     }
   357 
   367 
   358 void CUissClientHandler::WorkUntilCompleteL()
   368 void CUissClientHandler::WorkUntilCompleteL()
   359 	{
   369     {
   360 	// Keep processing UISS responses and issuing new requests
   370     // Keep processing UISS responses and issuing new requests
   361 	// until we update the client status to non-pending.
   371     // until we update the client status to non-pending.
   362 	while(iClientStatus && *iClientStatus == KRequestPending) 
   372     while(iClientStatus && *iClientStatus == KRequestPending) 
   363 		{
   373         {
   364 		User::WaitForRequest(iStatus);
   374         User::WaitForRequest(iStatus);
   365 		TRAPD(err,RunL());
   375         TRAPD(err,RunL());
   366 		if(err != KErrNone)
   376         if(err != KErrNone)
   367 			{	
   377             {   
   368 			RunError(err);
   378             RunError(err);
   369 			}
   379             }
   370 		}
   380         }
   371 	}
   381     }
   372 
   382 
   373 TBool CUissClientHandler::IsBusy()
   383 TBool CUissClientHandler::IsBusy()
   374 	{
   384     {
   375 	return iState != KUissClientIdle;
   385     return iState != KUissClientIdle;
   376 	}
   386     }
   377 
   387 
   378 
   388 
   379 //
   389 //
   380 // Code necessary to run UISS in the same process but in a different thread
   390 // Code necessary to run UISS in the same process but in a different thread
   381 //
   391 //
   382 TInt CUissClientHandler::StartUiss()
   392 TInt CUissClientHandler::StartUiss()
   383 	{
   393     {
   384 	const TInt KUissServerStackSize=0x2000;
   394     const TInt KUissServerStackSize=0x2000;
   385 	const TInt KUissServerInitHeapSize=0x1000;
   395     const TInt KUissServerInitHeapSize=0x1000;
   386 	const TInt KUissServerMaxHeapSize=0x1000000;
   396     const TInt KUissServerMaxHeapSize=0x1000000;
   387 	
   397     
   388 	
   398     
   389 	TThreadFunction entryPoint=UissThreadFunction;
   399     TThreadFunction entryPoint=UissThreadFunction;
   390 	//TUiSupportStartParams uiSupportParams(aUiHandler);
   400     //TUiSupportStartParams uiSupportParams(aUiHandler);
   391 	// The owner of the new thread will be the process, otherwise if the 
   401     // The owner of the new thread will be the process, otherwise if the 
   392 	// current thread dies, the server thread will die, too.
   402     // current thread dies, the server thread will die, too.
   393 	RThread server;
   403     RThread server;
   394 	TInt err = KErrNone;
   404     TInt err = KErrNone;
   395 		
   405         
   396 	for (TInt retry=0; retry < 2; ++retry)
   406     for (TInt retry=0; retry < 2; ++retry)
   397 		{
   407         {
   398 		err = server.Create(KUissServerName, entryPoint, 
   408         err = server.Create(KUissServerName, entryPoint, 
   399 		KUissServerStackSize, KUissServerInitHeapSize, KUissServerMaxHeapSize,
   409         KUissServerStackSize, KUissServerInitHeapSize, KUissServerMaxHeapSize,
   400 		NULL, EOwnerThread);
   410         NULL, EOwnerThread);
   401 		
   411         
   402 		if (err == KErrAlreadyExists)
   412         if (err == KErrAlreadyExists)
   403 			{
   413             {
   404 			User::After(30000);	
   414             User::After(30000); 
   405 			}
   415             }
   406 		else
   416         else
   407 			{
   417             {
   408 			break;
   418             break;
   409 			}
   419             }
   410 		}
   420         }
   411 		
   421         
   412 	if (err==KErrAlreadyExists)
   422     if (err==KErrAlreadyExists)
   413 		{
   423         {
   414 		return KErrServerBusy;
   424         return KErrServerBusy;
   415 		}
   425         }
   416 	if (err != KErrNone)
   426     if (err != KErrNone)
   417 		{
   427         {
   418 		return err;
   428         return err;
   419 		}
   429         }
   420 	
   430     
   421 	// Synchronise with the process to make sure it hasn't died straight away
   431     // Synchronise with the process to make sure it hasn't died straight away
   422 	TRequestStatus stat;
   432     TRequestStatus stat;
   423 	server.Rendezvous(stat);
   433     server.Rendezvous(stat);
   424 	if (stat != KRequestPending)
   434     if (stat != KRequestPending)
   425 		{
   435         {
   426 		// logon failed - server is not yet running, so cannot have terminated
   436         // logon failed - server is not yet running, so cannot have terminated
   427 		server.Kill(0); // Abort startup
   437         server.Kill(0); // Abort startup
   428 		}
   438         }
   429 	else
   439     else
   430 		{
   440         {
   431 		// logon OK - start the server
   441         // logon OK - start the server
   432 		server.Resume();
   442         server.Resume();
   433 		}
   443         }
   434 	// Wait to synchronise with server - if it dies in the meantime, it
   444     // Wait to synchronise with server - if it dies in the meantime, it
   435 	// also gets completed
   445     // also gets completed
   436 	User::WaitForRequest(stat);	
   446     User::WaitForRequest(stat); 
   437 	// We can't use the 'exit reason' if the server panicked as this
   447     // We can't use the 'exit reason' if the server panicked as this
   438 	// is the panic 'reason' and may be '0' which cannot be distinguished
   448     // is the panic 'reason' and may be '0' which cannot be distinguished
   439 	// from KErrNone
   449     // from KErrNone
   440 	TInt r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
   450     TInt r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
   441 	server.Close();
   451     server.Close();
   442 	return r;
   452     return r;
   443 	}
   453     }
   444 
   454 
   445 // Entry point for the thread the UISS runs in
   455 // Entry point for the thread the UISS runs in
   446 TInt CUissClientHandler::UissThreadFunction(TAny *)
   456 TInt CUissClientHandler::UissThreadFunction(TAny *)
   447 	{
   457     {
   448 	__UHEAP_MARK;
   458     __UHEAP_MARK;
   449 	CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
   459     CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
   450 	
   460     
   451 	CActiveScheduler* scheduler=new(ELeave) CActiveScheduler;
   461     CActiveScheduler* scheduler=new(ELeave) CActiveScheduler;
   452 	CActiveScheduler::Install(scheduler);
   462     CActiveScheduler::Install(scheduler);
   453 	CUissServer* server=NULL;
   463     CUissServer* server=NULL;
   454 	
   464     
   455 	TRAPD(err, server=CUissServer::NewL());
   465     TRAPD(err, server=CUissServer::NewL());
   456 	if (err==KErrNone)
   466     if (err==KErrNone)
   457 		{
   467         {
   458 		RThread::Rendezvous(KErrNone);
   468         RThread::Rendezvous(KErrNone);
   459 		scheduler->Start();
   469         scheduler->Start();
   460 		}
   470         }
   461 	
   471     
   462 	delete server;
   472     delete server;
   463 	
   473     
   464 	CActiveScheduler::Install(NULL);
   474     CActiveScheduler::Install(NULL);
   465 	delete scheduler;
   475     delete scheduler;
   466 	delete cleanup; // destroy clean-up stack
   476     delete cleanup; // destroy clean-up stack
   467 	__UHEAP_MARKEND;
   477     __UHEAP_MARKEND;
   468 	return KErrNone;
   478     return KErrNone;
   469 	}
   479     }
   470 
   480 
   471 void CUissClientHandler::RunL()
   481 void CUissClientHandler::RunL()
   472     {
   482     {
   473     TInt err = iStatus.Int();
   483     TInt err = iStatus.Int();
   474 	iPtrIntoBuf.Set(iBuf->Des()); // Get ptr to our return buffer
   484     iPtrIntoBuf.Set(iBuf->Des()); // Get ptr to our return buffer
   475 
   485     
   476 	DEBUG_PRINTF2(_L8("Sis Helper - UISS Client Handler, RunL(). Status: %d."), err);
   486 	DEBUG_PRINTF2(_L8("Sis Helper - UISS Client Handler, RunL(). Status: %d."), err);
   477 
   487     if(err > 0)
   478 	
   488         {
       
   489 		// For Logging purpose, store the buffer to retrieve 
       
   490 		// application info later.
       
   491         delete iBufLogger;
       
   492         iBufLogger = 0;
       
   493         iBufLogger = iBuf->AllocL();
       
   494         }
       
   495     
   479     if (err==KErrOverflow 
   496     if (err==KErrOverflow 
   480 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK	
   497 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK  
   481 		&& iState != KUissClientGettingCompInfo // We don't support overflow management for component info
   498         && iState != KUissClientGettingCompInfo // We don't support overflow management for component info
   482 #endif
   499 #endif
   483 		)
   500         )
   484         {
   501         {
   485         // Grow the respective buffer buffer and re-issue "request".
   502         // Grow the respective buffer buffer and re-issue "request".
   486         // There should now be space for the UISS server to copy in its dialogue message.
   503         // There should now be space for the UISS server to copy in its dialogue message.
   487         HandleOverflowL();
   504         HandleOverflowL();
   488         iPtrIntoBuf.Set(iBuf->Des());
   505         iPtrIntoBuf.Set(iBuf->Des());
   489 		iUissSession.BufferReallocated(iPtrIntoBuf, iStatus);
   506         iUissSession.BufferReallocated(iPtrIntoBuf, iStatus);
   490 
   507 
   491 		if (iActiveObjectMode)
   508         if (iActiveObjectMode)
   492 			{
   509             {
   493 			SetActive();
   510             SetActive();
   494 			}
   511             }
   495 		return;
   512         return;
   496 		}
   513         }
   497 	else
   514     else
   498 		{
   515         {
   499 		if (err>CUissSession::KMsgSeparatorMinimumSwisMessage && 
   516         if (err>CUissSession::KMsgSeparatorMinimumSwisMessage && 
   500 			err<CUissSession::KMsgSeparatorMaximumSwisMessage)
   517             err<CUissSession::KMsgSeparatorMaximumSwisMessage)
   501 			{
   518             {
   502 			// this is a dialog request, unmarshal parameters and display 
   519             // this is a dialog request, unmarshal parameters and display 
   503 			// the dialog
   520             // the dialog
   504 			CUissCmdHandler* cmdHandler=UissCmdHandlerFactoryL(err);
   521             CUissCmdHandler* cmdHandler=UissCmdHandlerFactoryL(err);
   505 			if (!cmdHandler)
   522             if (!cmdHandler)
   506 				{
   523                 {               
   507 				User::Leave(KErrNotSupported);
   524                 User::Leave(KErrNotSupported);
   508 				}
   525                 }
       
   526             
       
   527             CleanupStack::PushL(cmdHandler);
       
   528             // Note that the callback might call CancelOperation which
       
   529             // would update iState...
       
   530             cmdHandler->HandleMessageL(iPtrIntoBuf, iPtrIntoBuf);
       
   531             CleanupStack::PopAndDestroy(cmdHandler);
       
   532             }
       
   533         else
       
   534             {
       
   535             #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   536             // Request has been completed successfully. So, now construct the 
       
   537             // component info from the buffer which is populated from the SWI server.
       
   538             if (err == KErrNone  && iState == KUissClientGettingCompInfo)
       
   539                 {
       
   540                 ConstructCompInfoFromBufferL();
       
   541                 }           
       
   542             #endif
       
   543             // Either KErrNone or some sort of error status - in any case the processing has finished
       
   544             iState = KUissClientIdle;           
       
   545             }
       
   546         }
       
   547     
       
   548     // Re-issue request, if we are still installing/uninstalling
       
   549     switch(iState)
       
   550         {
       
   551     case KUissClientInstalling:
       
   552     case KUissClientUninstalling:
       
   553         iUissSession.CompleteDialog(KErrNone, iPtrIntoBuf, iStatus);
       
   554         if (iActiveObjectMode)
       
   555             {
       
   556             SetActive();
       
   557             }
       
   558         return;
       
   559             
       
   560     case KUissClientIdle:
       
   561         // All done, or failed...
       
   562         delete iArgsStream;
       
   563         iArgsStream = 0;
       
   564         //Wait for the death of SisHelper
       
   565         WaitForSisHelperShutdown(); 
       
   566         // Complete user request (also sets iClientStatus to 0)
       
   567         ASSERT(iClientStatus);
       
   568         User::RequestComplete(iClientStatus, err);
       
   569         
       
   570         // Logging the error to a file 
       
   571         // Temporary solution, should be removed once instrumentation is fully operational.
       
   572         if(err != KErrNone)
       
   573             {
       
   574 			TRAP_IGNORE(
       
   575             RDesReadStream readStream(iBufLogger->Des());
       
   576             CleanupClosePushL(readStream);
   509 			
   577 			
   510 			CleanupStack::PushL(cmdHandler);
   578 			//Retrieve package name.
   511 			// Note that the callback might call CancelOperation which
   579             CAppInfo* appInfo=CAppInfo::NewLC(readStream);
   512 			// would update iState...
   580             LogSwiErrorsToFileL(err, appInfo->AppName());
   513 			cmdHandler->HandleMessageL(iPtrIntoBuf, iPtrIntoBuf);
   581             
   514 			CleanupStack::PopAndDestroy(cmdHandler);
   582             CleanupStack::PopAndDestroy(2, &readStream);
   515 			}
   583 			);
   516 		else
   584             }
   517 			{
   585         return;
   518 			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   586         }
   519 			// Request has been completed successfully. So, now construct the 
   587     ASSERT(false);
   520 			// component info from the buffer which is populated from the SWI server.
       
   521 			if (err == KErrNone  && iState == KUissClientGettingCompInfo)
       
   522 				{
       
   523 				ConstructCompInfoFromBufferL();
       
   524 				}			
       
   525 			#endif
       
   526 			// Either KErrNone or some sort of error status - in any case the processing has finished
       
   527 			iState = KUissClientIdle;			
       
   528 			}
       
   529 		}
       
   530 	
       
   531 	// Re-issue request, if we are still installing/uninstalling
       
   532 	switch(iState)
       
   533 		{
       
   534 	case KUissClientInstalling:
       
   535 	case KUissClientUninstalling:
       
   536 		iUissSession.CompleteDialog(KErrNone, iPtrIntoBuf, iStatus);
       
   537 		if (iActiveObjectMode)
       
   538 			{
       
   539 			SetActive();
       
   540 			}
       
   541 		return;
       
   542 			
       
   543 	case KUissClientIdle:
       
   544 		// All done, or failed...
       
   545 		delete iArgsStream;
       
   546 		iArgsStream = 0;
       
   547 		//Wait for the death of SisHelper
       
   548 		WaitForSisHelperShutdown();	
       
   549 		// Complete user request (also sets iClientStatus to 0)
       
   550 		ASSERT(iClientStatus);
       
   551 		User::RequestComplete(iClientStatus, err);
       
   552 		return;
       
   553 		}
       
   554 	ASSERT(false);
       
   555     }
   588     }
   556 
   589 
   557 
   590 
   558 TInt CUissClientHandler::RunError(TInt aError)
   591 TInt CUissClientHandler::RunError(TInt aError)
   559 	{
   592 	{
   560 	DEBUG_PRINTF2(_L8("Sis Helper - UISS Client Handler, RunError. Error: %d."), aError);
   593 	DEBUG_PRINTF2(_L8("Sis Helper - UISS Client Handler, RunError. Error: %d."), aError);
   561 	// Pass failure code on to our client.
   594 	// Pass failure code on to our client.
   562 	iPtrIntoBuf.Zero();
   595 	iPtrIntoBuf.Zero();
   563 	iUissSession.CompleteDialog(aError, iPtrIntoBuf, iStatus);
   596 	iUissSession.CompleteDialog(aError, iPtrIntoBuf, iStatus);
   564     if (iActiveObjectMode)
   597     if (iActiveObjectMode)
   565 		{
   598         {
   566 		SetActive();
   599         SetActive();
   567 		}
   600         }
   568 	return KErrNone; // Do not crash the CActiveScheduler.
   601     return KErrNone; // Do not crash the CActiveScheduler.
   569 	}
   602     }
   570 
   603 
   571 void CUissClientHandler::DoCancel()
   604 void CUissClientHandler::DoCancel()
   572     {
   605     {
   573     DEBUG_PRINTF(_L8("Sis Helper - UISS Client Handler, Cancelling."));
   606     DEBUG_PRINTF(_L8("Sis Helper - UISS Client Handler, Cancelling."));
   574     
   607     
   578 	// We can NOT simply call CancelOperation, because when we return
   611 	// We can NOT simply call CancelOperation, because when we return
   579 	// into the framework Cancel function it will block on our
   612 	// into the framework Cancel function it will block on our
   580 	// iStatus, which would stop the active scheduler and hence stop
   613 	// iStatus, which would stop the active scheduler and hence stop
   581 	// the CancelOperation from being actioned.
   614 	// the CancelOperation from being actioned.
   582 
   615 
   583 	// Do an emergency abort.....
   616     // Do an emergency abort.....
   584 
   617 
   585 	// First kill our helper threads
   618     // First kill our helper threads
   586 	
   619     
   587 	// SIS helper thread/server
   620     // SIS helper thread/server
   588 	CSisHelperServer::Abort();
   621     CSisHelperServer::Abort();
   589 	
   622     
   590 	// UI helper thread/server
   623     // UI helper thread/server
   591 	TFullName fullName = RProcess().FullName();
   624     TFullName fullName = RProcess().FullName();
   592 	fullName.Append(':');
   625     fullName.Append(':');
   593 	fullName.Append(':');
   626     fullName.Append(':');
   594 	fullName.Append(KUissServerName);
   627     fullName.Append(KUissServerName);
   595 
   628 
   596 	RThread server;
   629     RThread server;
   597 	TInt err = server.Open(fullName);
   630     TInt err = server.Open(fullName);
   598 	if (err == KErrNone)
   631     if (err == KErrNone)
   599 		{
   632         {
   600 		server.Terminate(KErrAbort);
   633         server.Terminate(KErrAbort);
   601 		server.Close();
   634         server.Close();
   602 		}
   635         }
   603 	
   636     
   604 	// Now complete any client request
   637     // Now complete any client request
   605 	if (iClientStatus)
   638     if (iClientStatus)
   606 		{
   639         {
   607 		User::RequestComplete(iClientStatus, err);
   640         User::RequestComplete(iClientStatus, err);
   608 		}
   641         }
   609     }
   642     }
   610     
   643     
   611 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   644 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
   612 void CUissClientHandler::ConstructCompInfoFromBufferL()
   645 void CUissClientHandler::ConstructCompInfoFromBufferL()
   613     {    
   646     {    
   614     // create a stream based on the buffer
   647     // create a stream based on the buffer
   615 	RDesReadStream stream(*iCompInfoBuffer);
   648     RDesReadStream stream(*iCompInfoBuffer);
   616 	CleanupClosePushL(stream);
   649     CleanupClosePushL(stream);
   617 	
   650     
   618 	CNativeComponentInfo* nativeCompInfo = CNativeComponentInfo::NewLC();
   651     CNativeComponentInfo* nativeCompInfo = CNativeComponentInfo::NewLC();
   619 	nativeCompInfo->InternalizeL(stream);
   652     nativeCompInfo->InternalizeL(stream);
   620 		
   653         
   621 	// 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),
   654     // 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),
   622 	// which is returned by SWI and is converted here to the CComponentInfo according to the USIF interface
   655     // which is returned by SWI and is converted here to the CComponentInfo according to the USIF interface
   623 	Usif::CComponentInfo::CNode* rootNode = MapToComponentInfoL(*nativeCompInfo);
   656     Usif::CComponentInfo::CNode* rootNode = MapToComponentInfoL(*nativeCompInfo);
   624 	iComponentInfo->SetRootNodeL(rootNode);
   657     iComponentInfo->SetRootNodeL(rootNode);
   625 
   658 
   626 	CleanupStack::PopAndDestroy(nativeCompInfo);
   659     CleanupStack::PopAndDestroy(nativeCompInfo);
   627 	CleanupStack::PopAndDestroy(&stream);
   660     CleanupStack::PopAndDestroy(&stream);
   628     }
   661     }
   629 
   662 
   630 Usif::CComponentInfo::CNode* CUissClientHandler::MapToComponentInfoL(CNativeComponentInfo& aNativeComponentInfo)
   663 Usif::CComponentInfo::CNode* CUissClientHandler::MapToComponentInfoL(CNativeComponentInfo& aNativeComponentInfo)
   631 	{
   664     {
   632 	// Create the array to store the children nodes.
   665     // Create the array to store the children nodes.
   633 	RPointerArray<Usif::CComponentInfo::CNode> children;
   666     RPointerArray<Usif::CComponentInfo::CNode> children;
   634 	CleanupResetAndDestroyPushL(children);
   667     CleanupResetAndDestroyPushL(children);
   635 	
   668     
   636 	// If there is any child for the current node, call this method with that child object.
   669     // If there is any child for the current node, call this method with that child object.
   637 	// Continue this (recursively) until we get the leaf node in the embedded tree (with no children)
   670     // Continue this (recursively) until we get the leaf node in the embedded tree (with no children)
   638 	// and add the resultant node as one of the children and pass it to create the parent node further.
   671     // and add the resultant node as one of the children and pass it to create the parent node further.
   639 	TInt count = aNativeComponentInfo.iChildren.Count();
   672     TInt count = aNativeComponentInfo.iChildren.Count();
   640 	for (TInt i = 0; i < count; ++i)
   673     for (TInt i = 0; i < count; ++i)
   641 		{
   674         {
   642 		Usif::CComponentInfo::CNode* node = MapToComponentInfoL(*aNativeComponentInfo.iChildren[i]);
   675         Usif::CComponentInfo::CNode* node = MapToComponentInfoL(*aNativeComponentInfo.iChildren[i]);
   643 		CleanupStack::PushL(node);
   676         CleanupStack::PushL(node);
   644 		children.AppendL(node);
   677         children.AppendL(node);
   645 		CleanupStack::Pop(node);
   678         CleanupStack::Pop(node);
   646 		}
   679         }
   647 		
   680         
   648 	// Create the CNode object using the appropriate parameters.
   681     // Create the CNode object using the appropriate parameters.
   649 	// children for leaf nodes (bottom most nodes in the embedded tree) will be null.
   682     // children for leaf nodes (bottom most nodes in the embedded tree) will be null.
   650 	Usif::CComponentInfo::CNode* node = Usif::CComponentInfo::CNode::NewLC(
   683     Usif::CComponentInfo::CNode* node = Usif::CComponentInfo::CNode::NewLC(
   651 										Usif::KSoftwareTypeNative(),
   684                                         Usif::KSoftwareTypeNative(),
   652 										*(aNativeComponentInfo.iComponentName), 
   685                                         *(aNativeComponentInfo.iComponentName), 
   653 										*(aNativeComponentInfo.iVersion),
   686                                         *(aNativeComponentInfo.iVersion),
   654 										*(aNativeComponentInfo.iVendor),
   687                                         *(aNativeComponentInfo.iVendor),
   655 										static_cast<Usif::TScomoState>(aNativeComponentInfo.iScomoState),
   688                                         static_cast<Usif::TScomoState>(aNativeComponentInfo.iScomoState),
   656 										static_cast<Usif::TInstallStatus>(aNativeComponentInfo.iInstallStatus),
   689                                         static_cast<Usif::TInstallStatus>(aNativeComponentInfo.iInstallStatus),
   657 										aNativeComponentInfo.iComponentId,
   690                                         aNativeComponentInfo.iComponentId,
   658 										*(aNativeComponentInfo.iGlobalComponentId),
   691                                         *(aNativeComponentInfo.iGlobalComponentId),
   659 										static_cast<Usif::TAuthenticity>(aNativeComponentInfo.iAuthenticity),
   692                                         static_cast<Usif::TAuthenticity>(aNativeComponentInfo.iAuthenticity),
   660 										aNativeComponentInfo.iUserGrantableCaps,
   693                                         aNativeComponentInfo.iUserGrantableCaps,
   661 										aNativeComponentInfo.iMaxInstalledSize,
   694                                         aNativeComponentInfo.iMaxInstalledSize,
   662 										aNativeComponentInfo.iHasExe,
   695                                         aNativeComponentInfo.iHasExe,
   663 										&children);
   696                                         &children);
   664 	CleanupStack::Pop(node);
   697     CleanupStack::Pop(node);
   665 	CleanupStack::Pop(&children);
   698     CleanupStack::Pop(&children);
   666 	children.Close();
   699     children.Close();
   667 	return (node);
   700     return (node);
   668 	}
   701     }
   669 #endif
   702 #endif
       
   703 
       
   704 
       
   705 void LogSwiErrorsToFileL(TInt aErrorCode, const TDesC& aAppName)
       
   706     {
       
   707     _LIT(KErrorString, "%S : Failed with %d");
       
   708     _LIT(KLogFile, "c:\\data\\swilog.log");
       
   709     
       
   710     //Format Output string
       
   711     HBufC* outputString = HBufC::NewLC(aAppName.Length()+ 30);
       
   712     outputString->Des().Format(KErrorString, &aAppName, aErrorCode);
       
   713     
       
   714 	//Maximum number of log file entries.
       
   715     const TUint KLogFileSize = 10;
       
   716     
       
   717     RFs fs;
       
   718     User::LeaveIfError(fs.Connect());
       
   719     CleanupClosePushL(fs);
       
   720     
       
   721     RFile logFile;
       
   722     TInt err = logFile.Open(fs, KLogFile, EFileWrite);
       
   723     if(err != KErrNone)
       
   724         {
       
   725 		//Attempt to create the file.
       
   726         err = logFile.Create(fs, KLogFile, EFileWrite);
       
   727         User::LeaveIfError(err);
       
   728         }
       
   729     CleanupClosePushL(logFile);   
       
   730     
       
   731 
       
   732 	//Read the entire log file.
       
   733     RPointerArray<HBufC> linesArray;
       
   734     CleanupResetAndDestroyPushL(linesArray);
       
   735     
       
   736     TFileText logFileManipulator;
       
   737     logFileManipulator.Set(logFile);
       
   738 
       
   739     TBuf<200>buffer;
       
   740     err = logFileManipulator.Read(buffer);
       
   741     TInt count(0);
       
   742     while(err == KErrNone && ++count <= KLogFileSize)
       
   743         {
       
   744 		HBufC* line = buffer.AllocLC();
       
   745         linesArray.AppendL(line);
       
   746 		CleanupStack::Pop(line);
       
   747         err = logFileManipulator.Read(buffer);   
       
   748         }
       
   749     
       
   750 	// If the log file contains less than KLogFileSize entries,
       
   751 	// write the new log entry.
       
   752     if(count < KLogFileSize)
       
   753         {
       
   754         logFileManipulator.Seek(ESeekEnd);
       
   755         logFileManipulator.Write(*outputString);
       
   756         }
       
   757     else
       
   758         {
       
   759 		// Contains KLogFileSize entries. 
       
   760 		// Replicate the last KLogFileSize - 1 entries and add the
       
   761 		// new log at the end.
       
   762         logFile.Close();
       
   763         logFile.Replace(fs, KLogFile, EFileWrite);
       
   764         logFileManipulator.Set(logFile);
       
   765         for(TInt i = linesArray.Count()- KLogFileSize +1; i<linesArray.Count(); ++i )
       
   766             {
       
   767             logFileManipulator.Write(*linesArray[i]);
       
   768             }
       
   769 
       
   770 		// New Entry.
       
   771         logFileManipulator.Write(*outputString);   
       
   772         }
       
   773     logFile.Close();
       
   774     CleanupStack::PopAndDestroy(4, outputString);    
       
   775     }
   670 } // namespace Swi
   776 } // namespace Swi