smartinstaller/bootstrap/src/bootstrapstatemachine.cpp
branchADM
changeset 48 364021cecc90
equal deleted inserted replaced
47:3f419852be07 48:364021cecc90
       
     1 /*
       
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *     CStateMachine class implementation.
       
    16 *
       
    17 *
       
    18 */
       
    19 
       
    20 #include <e32base.h>
       
    21 #include <aknappui.h>
       
    22 #include <swinstdefs.h>
       
    23 #include <swi/sisregistrysession.h>
       
    24 #include <swi/sisregistryentry.h>
       
    25 #include <httpdownloadmgrcommon.h>
       
    26 #include <coeutils.h>
       
    27 #include <SenDomFragment.h>
       
    28 #include <SenXmlReader.h>
       
    29 #include <SenElement.h>
       
    30 #include <centralrepository.h>      // CRepository
       
    31 #include <browseruisdkcrkeys.h>     // KCRUidBrowser
       
    32 
       
    33 #include <wlanerrorcodes.h> 		//For download error handling
       
    34 #include <etelpckt.h>       		//For download error handling
       
    35 #include <exterror.h>       		//For download error handling
       
    36 #include <httpdownloadmgrcommon.h>	//For download error handling (not in S60 5.0 SDK)
       
    37 
       
    38 #include <es_enum.h>
       
    39 #include <rconnmon.h>
       
    40 #include <eikdef.h>
       
    41 
       
    42 #include "bootstrapstatemachine.h"
       
    43 #include "bootstrapappui.h"
       
    44 #include "bootstrapconst.h"
       
    45 #include "bootstrapinstallationobserver.h"
       
    46 #include "smartinstallerdll.h"
       
    47 #include "debug.h"
       
    48 #include "globals.h"
       
    49 #include "macros.h"
       
    50 #include "config.h"
       
    51 #include "utils.h" // HideAppFromMenuL()
       
    52 
       
    53 // ADM binary name
       
    54 _LIT(KAdmExePath, "ADM.exe");
       
    55 _LIT(KDownloadFolder,"?:\\system\\adm\\");
       
    56 // Sis file extension
       
    57 _LIT(KSisExtn,".SIS");
       
    58 _LIT(KSisxExtn,".SISX");
       
    59 // Xml file extension
       
    60 _LIT(KXMLExtn,".XML");
       
    61 // Dep file extension
       
    62 _LIT(KDepExtn,"_DEP");
       
    63 // ADM changes file name
       
    64 _LIT(KAdmChangesFile, "adm_changes.xml");
       
    65 // Private folder of SWI Daemon
       
    66 _LIT(KSWIDaemonPrivateFolder, "\\private\\10202dce\\");
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 // CStateMachine::NewLC
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 CStateMachine* CStateMachine::NewLC(CBootstrapAppUi& aSIUiObj, TUint32 aWrapperUid)
       
    73 	{
       
    74 	CStateMachine* object = new ( ELeave ) CStateMachine(aSIUiObj, aWrapperUid);
       
    75 	CleanupStack::PushL( object );
       
    76 	object->ConstructL();
       
    77 	return object;
       
    78 	}
       
    79 
       
    80 // ---------------------------------------------------------------------------
       
    81 // CStateMachine::NewL
       
    82 // ---------------------------------------------------------------------------
       
    83 //
       
    84 CStateMachine* CStateMachine::NewL(CBootstrapAppUi& aSIUiObj, TUint32 aWrapperUid)
       
    85 	{
       
    86 	CStateMachine* object = CStateMachine::NewLC(aSIUiObj, aWrapperUid);
       
    87 	CleanupStack::Pop();
       
    88 	return object;
       
    89 	}
       
    90 
       
    91 // ---------------------------------------------------------------------------
       
    92 // CStateMachine::CStateMachine
       
    93 // C++ default constructor.
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 CStateMachine::CStateMachine(CBootstrapAppUi& aBsAppUiObj, TUint32 aWrapperUid) :
       
    97 							CActive(CActive::EPriorityStandard),
       
    98 							iAppUi(aBsAppUiObj),
       
    99 							iWrapperPackageUid(aWrapperUid),
       
   100 							iAdmChangesInfo(),
       
   101 							iBootstrapFailed(EFalse)
       
   102 #ifdef USE_LOGFILE
       
   103 							, iLog(aBsAppUiObj.iLog)
       
   104 #endif
       
   105 	{
       
   106 	CActiveScheduler::Add(this);
       
   107 	}
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // CStateMachine::ConstructL
       
   111 // 2nd phase constructor.
       
   112 // ---------------------------------------------------------------------------
       
   113 //
       
   114 void CStateMachine::ConstructL()
       
   115 	{
       
   116 	// Connect to the Download Manager
       
   117 	TBool masterInstance(!(iAppUi.EikonEnv()->StartedAsServerApp()));
       
   118 	iDownloadManager.ConnectL( KUidBootstrapApp, *this, masterInstance );
       
   119 
       
   120 	User::LeaveIfError(iLauncher.Connect());
       
   121 
       
   122 	iIsAdmInstalled = IsPackagePresentL(KUidAdm, iAdmInstalledVersion);
       
   123 
       
   124 	ReadConfigurationL();
       
   125 	}
       
   126 
       
   127 // ---------------------------------------------------------------------------
       
   128 // CStateMachine::~CStateMachine
       
   129 // Virtual Destructor.
       
   130 // ---------------------------------------------------------------------------
       
   131 //
       
   132 CStateMachine::~CStateMachine()
       
   133 	{
       
   134 	LOG( "~StateMachine()" );
       
   135 	Cancel();
       
   136 	DELETE_IF_NONNULL( iDepFilename );
       
   137 	DELETE_IF_NONNULL( iSisFilename );
       
   138 	DELETE_IF_NONNULL( iDownloadUrl );
       
   139 	delete iInstallObsrv;
       
   140 	delete iConfigUrl;
       
   141 	delete iUrl;
       
   142 	delete iDownloadFileName;
       
   143 	iIapArray.Close();
       
   144 	iDownloadManager.DeleteAll();
       
   145 	iDownloadManager.Close();
       
   146 	iLauncher.Close();
       
   147 	}
       
   148 
       
   149 // ---------------------------------------------------------------------------
       
   150 // CStateMachine::RunL
       
   151 // Called for each state transition
       
   152 // ---------------------------------------------------------------------------
       
   153 //
       
   154 void CStateMachine::RunL()
       
   155 	{
       
   156 	switch (iAppState)
       
   157 		{
       
   158 		case EBSStateInit:
       
   159 			{
       
   160 			StateInitL();
       
   161 			RequestState(EBSStateDownloadChanges);
       
   162 			}
       
   163 			break;
       
   164 		case EBSStateDownloadChanges:
       
   165 			{
       
   166 			StateDownloadL();
       
   167 			// No need to request a state change. HandleDMgrEventL() will
       
   168 			// trigger a correct event after the download has completed.
       
   169 			}
       
   170 			break;
       
   171 		case EBSStateParseChanges:
       
   172 			{
       
   173 			StateParseChangesL();
       
   174 			if( IsAdmDownloadRequired() )
       
   175 				{
       
   176 				RequestState(EBSStateDownloadAdm);
       
   177 				}
       
   178 			else
       
   179 				{
       
   180 				RequestState(EBSStateLaunchAdm);
       
   181 				}
       
   182 			}
       
   183 			break;
       
   184 		case EBSStateDownloadAdm:
       
   185 			{
       
   186 			StateDownloadL();
       
   187 			// No need to request a state change. HandleDMgrEventL() will
       
   188 			// trigger a correct event after the download has completed.
       
   189 			}
       
   190 			break;
       
   191 		case EBSStateInstallAdm:
       
   192 			{
       
   193 			StateInstallAdmL();
       
   194 			// No need to request a state change. HandleInstallCompleteL() will
       
   195 			// trigger a correct event after the installation has completed.
       
   196 			}
       
   197 			break;
       
   198 		case EBSStateLaunchAdm:
       
   199 			{
       
   200 			StateLaunchAdmL();
       
   201 			RequestState(EBSStateExit);
       
   202 			}
       
   203 			break;
       
   204 		case EBSStateExit:
       
   205 			{
       
   206 			// Exit the application
       
   207 			Cancel();
       
   208 			iAppUi.ExitApp(iAppState);
       
   209 			}
       
   210 			break;
       
   211 		case EBSStateExitWithError:
       
   212 			{
       
   213 			Cancel();
       
   214 			//Error Id needs to be already set before the state transition.
       
   215 			iAppUi.ExitApp(iAppState);
       
   216 			}
       
   217 			break;
       
   218 		default:
       
   219 			LOG2( "Ignoring state change %d", iAppState );
       
   220 			break;
       
   221 		}
       
   222 	}
       
   223 
       
   224 // ---------------------------------------------------------------------------
       
   225 // CStateMachine::StateComplete
       
   226 // Trigger the state transition.
       
   227 // ---------------------------------------------------------------------------
       
   228 //
       
   229 void CStateMachine::RequestState(const EBSAppState aNextState)
       
   230 	{
       
   231 	LOG3( "+ RequestState(): %d->%d", iAppState, aNextState );
       
   232 	iAppState = aNextState;
       
   233 	iStatus = KRequestPending;
       
   234 
       
   235 	if( !IsActive() )
       
   236 		{
       
   237 		SetActive();
       
   238 		}
       
   239 	TRequestStatus* status = &iStatus;
       
   240 	User::RequestComplete( status, KErrNone );
       
   241 	}
       
   242 
       
   243 // ---------------------------------------------------------------------------
       
   244 // CStateMachine::RunError
       
   245 // Call Handlefailure incase of error.
       
   246 // ---------------------------------------------------------------------------
       
   247 //
       
   248 TInt CStateMachine::RunError(TInt aError)
       
   249 	{
       
   250 	LOG2( "+ CStateMachine::RunError(%d)", aError );
       
   251 	if ( aError != KLeaveExit )
       
   252 		{
       
   253 		HandleFailure();
       
   254 		return KErrNone;
       
   255 		}
       
   256 	else
       
   257 		{
       
   258 		return KLeaveExit;
       
   259 		}
       
   260 	}
       
   261 
       
   262 // ---------------------------------------------------------------------------
       
   263 // CStateMachine::DoCancel
       
   264 // ---------------------------------------------------------------------------
       
   265 //
       
   266 void CStateMachine::DoCancel()
       
   267 	{
       
   268 	LOG( "+ CStateMachine::DoCancel()" );
       
   269 	iLauncher.CancelAsyncRequest(SwiUI::ERequestSilentInstall);
       
   270 	iDownloadManager.DeleteAll();
       
   271 	LOG( "- CStateMachine::DoCancel()" );
       
   272 	}
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // CStateMachine::Start
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 void CStateMachine::Start()
       
   279 	{
       
   280 	SetActive();
       
   281 
       
   282 	// send signal that this request has completed
       
   283 	TRequestStatus* status = &iStatus;
       
   284 	User::RequestComplete(status, KErrNone);
       
   285 	}
       
   286 
       
   287 // ---------------------------------------------------------------------------
       
   288 // CStateMachine::Stop
       
   289 // ---------------------------------------------------------------------------
       
   290 //
       
   291 void CStateMachine::Stop()
       
   292 	{
       
   293 	LOG( "+ CStateMachine::Stop()" );
       
   294 	Cancel();
       
   295 	}
       
   296 
       
   297 // ---------------------------------------------------------------------------
       
   298 // CBootstrapAppUi::ReadConfigurationL
       
   299 // Leaves if runs out of memory
       
   300 // Called from ConstructL in InitState
       
   301 // @return KErrNone if configuration was read correctly, error code otherwise
       
   302 // ---------------------------------------------------------------------------
       
   303 //
       
   304 TInt CStateMachine::ReadConfigurationL()
       
   305 	{
       
   306 	LOG( "+ ReadConfiguration()" );
       
   307 
       
   308 	TFileName configFile;
       
   309 	RArray< TPtrC > lineBuffer;
       
   310 	RFs& rfs = CEikonEnv::Static()->FsSession();
       
   311 
       
   312 	// Find the configuration file from the private directory
       
   313 	TInt ret = rfs.PrivatePath( configFile );
       
   314 	if ( ret == KErrNone )
       
   315 		{
       
   316 		TBuf<2> appDrive;
       
   317 		// Insert the drive of the running application
       
   318 		appDrive.Copy(iAppUi.Application()->AppFullName().Left(2));
       
   319 		configFile.Insert( 0, appDrive );
       
   320 		// Append the configuration file name
       
   321 		configFile.Append( KConfigFile );
       
   322 
       
   323 		LOG2( "configFile = %S", &configFile );
       
   324 
       
   325 		HBufC* buffer = ReadConfigFile( rfs, configFile, lineBuffer, ret );
       
   326 
       
   327 		if ( buffer && ret == KErrNone )
       
   328 			{
       
   329 			// Get Url from the config file
       
   330 			TPtrC urlLine = GetConfigValue( KCfgTagUrl, lineBuffer, ret );
       
   331 			if ( ret == KErrNone )
       
   332 				{
       
   333 				iConfigUrl = HBufC8::NewL( urlLine.Length() );
       
   334 				iConfigUrl->Des().Copy(urlLine );
       
   335 				LOG8_2( "configUrl = %S", iConfigUrl );
       
   336 				}
       
   337 			delete buffer;
       
   338 			}
       
   339 		}
       
   340 	if ( !iConfigUrl )
       
   341 		{
       
   342 		// Error occured while reading the configuration, use default URL
       
   343 		iConfigUrl = HBufC8::NewL( KDefaultDepServerUrl().Length() );
       
   344 		*iConfigUrl = KDefaultDepServerUrl;
       
   345 		LOG8_2( "configUrl = %S (default)", iConfigUrl );
       
   346 		}
       
   347 
       
   348 	lineBuffer.Close();
       
   349 
       
   350 	LOG2("-  ReadConfiguration(): %d", ret );
       
   351 	return ret;
       
   352 	}
       
   353 
       
   354 // ---------------------------------------------------------------------------
       
   355 // CBootstrapAppUi::StateInitL
       
   356 // Enter in EBSStateSetup,
       
   357 //
       
   358 // Read the sis file name and dep file name, based on Bootstrap version
       
   359 // Set the ADM changes file to download and the url to download from.
       
   360 // ---------------------------------------------------------------------------
       
   361 //
       
   362 void CStateMachine::StateInitL()
       
   363 	{
       
   364 	LOG2( "+ SetFileNameInfo(): ver = %d", KBootstrapVersion );
       
   365 
       
   366 	if( ( KBootstrapVersion < 1 ) && ( KBootstrapVersion > 4 ) )
       
   367 		{
       
   368 		// Unsupported Bootstrap version
       
   369 		User::Leave( KErrNotSupported );
       
   370 		}
       
   371 
       
   372 	// Connect to SisRegistry to fetch Package info
       
   373 	Swi::RSisRegistrySession registrySession;
       
   374 	User::LeaveIfError( registrySession.Connect() );
       
   375 	CleanupClosePushL( registrySession );
       
   376 
       
   377 	Swi::RSisRegistryEntry entry;
       
   378 
       
   379 	// Open registry entry
       
   380 	User::LeaveIfError( entry.Open( registrySession, TUid::Uid( iWrapperPackageUid ) ) );
       
   381 	CleanupClosePushL( entry );
       
   382 
       
   383 	RPointerArray<HBufC> packageFiles;
       
   384 	entry.FilesL( packageFiles );
       
   385 	const TInt filesCount( packageFiles.Count() );
       
   386 
       
   387 	// look into the files installed as part of the package,
       
   388 	// to find the dep file name and actuall application file name.
       
   389 	for ( TInt i=0; i<filesCount; i++ )
       
   390 		{
       
   391 		TParsePtrC parse( *packageFiles[i] );
       
   392 		TPtrC orgExtn = parse.Ext();
       
   393 
       
   394 		if ( orgExtn.Length() == 0 )
       
   395 			{
       
   396 			continue;
       
   397 			}
       
   398 
       
   399 		HBufC* extn = orgExtn.AllocLC();
       
   400 		TPtr extnPtr = extn->Des();
       
   401 		extnPtr.UpperCase();
       
   402 
       
   403 		if ( KBootstrapVersion != 3 )
       
   404 			{
       
   405 			if (( extnPtr.Compare(KSisExtn) == 0 ) || ( extnPtr.Compare(KSisxExtn) == 0 ) )
       
   406 				{
       
   407 				TPtrC privatePath( KNullDesC );
       
   408 				const TInt KDriveLength = 2;
       
   409 				if ( ( packageFiles[i]->Length() ) > ( KSWIDaemonPrivateFolder().Length() + KDriveLength ) )
       
   410 					{
       
   411 					privatePath.Set( packageFiles[i]->Des().Mid( KDriveLength ) );
       
   412 					privatePath.Set( privatePath.Left( KSWIDaemonPrivateFolder().Length() ) );
       
   413 					}
       
   414 
       
   415 				// Ignore if its a Stub Sis file
       
   416 				if ( privatePath.CompareF( KSWIDaemonPrivateFolder ) )
       
   417 					{
       
   418 					if ( iSisFilename == NULL )
       
   419 						{
       
   420 						iSisFilename = packageFiles[i]->AllocL();
       
   421 						LOG2( "Application sis '%S'", iSisFilename );
       
   422 						}
       
   423 					else
       
   424 						// More than one sis present in the Wrapper Pkg
       
   425 						{
       
   426 						LOG2( "! More than one sis file present: '%S'. LEAVE.", packageFiles[i] );
       
   427 						//TODO:GM: should there be a new error code for this??
       
   428 						User::Leave( KErrNotSupported );
       
   429 						}
       
   430 					}
       
   431 				} // if sis extension
       
   432 			} // if (KBoostraVersion != 3)
       
   433 
       
   434 		if ( KBootstrapVersion != 4 )
       
   435 			{
       
   436 			if( extnPtr.Compare(KXMLExtn) == 0 )
       
   437 				{
       
   438 				TPtrC orgName = parse.Name();
       
   439 				const TInt namelength = orgName.Length();
       
   440 				const TInt depSuffixlength = KDepExtn().Length();
       
   441 
       
   442 				if ( namelength > depSuffixlength )
       
   443 					{
       
   444 					TPtrC depSuffix = orgName.Mid( ( namelength-depSuffixlength ), depSuffixlength );
       
   445 
       
   446 					HBufC* name = depSuffix.AllocLC();
       
   447 					TPtr namePtr = name->Des();
       
   448 					namePtr.UpperCase();
       
   449 
       
   450 					if ( namePtr.Compare( KDepExtn ) == 0 )
       
   451 						{
       
   452 						if ( iDepFilename == NULL )
       
   453 							{
       
   454 							iDepFilename = packageFiles[i]->AllocL();
       
   455 							LOG2( "Dep file name is '%S'", iDepFilename );
       
   456 							}
       
   457 						else
       
   458 							// More than one dep file present in the Wrapper Pkg
       
   459 							{
       
   460 							LOG2( "! More than one dep file present: '%S'. LEAVE.", packageFiles[i] );
       
   461 							//TODO:GM: should there be a new error code for this??
       
   462 							User::Leave( KErrNotSupported );
       
   463 							}
       
   464 						}
       
   465 					CleanupStack::PopAndDestroy( name );
       
   466 					}
       
   467 				} // if XML extn
       
   468 			} // if (KBoostrapVersion != 4)
       
   469 		CleanupStack::PopAndDestroy( extn );
       
   470 		}
       
   471 
       
   472 	packageFiles.ResetAndDestroy();
       
   473 	packageFiles.Close();
       
   474 
       
   475 	if (KBootstrapVersion != 3)
       
   476 		{
       
   477 		if ( iSisFilename == NULL )
       
   478 			{
       
   479 			User::Leave( KErrNotSupported );
       
   480 			}
       
   481 		}
       
   482 	if (KBootstrapVersion != 4)
       
   483 		{
       
   484 		if ( iDepFilename == NULL )
       
   485 			{
       
   486 			User::Leave( KErrNotSupported );
       
   487 			}
       
   488 		}
       
   489 
       
   490 	CleanupStack::PopAndDestroy(&entry);
       
   491 	CleanupStack::PopAndDestroy(&registrySession);
       
   492 
       
   493 	iFileName.Set(KAdmChangesFile);
       
   494 
       
   495 	// URL is already set
       
   496 	DELETE_IF_NONNULL(iUrl);
       
   497 	iUrl = iConfigUrl->AllocL();
       
   498 
       
   499 	LOG2( "Filename is '%S'",&iFileName );
       
   500 
       
   501 #ifdef FEATURE_BOOTSTRAP_SETIAP
       
   502 	SetAndValidateIAPL();
       
   503 #endif
       
   504 
       
   505 	LOG( "- SetFileNameInfo()" );
       
   506 	}
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // CStateMachine::::IsAdmDownloadRequired
       
   510 // Enter after EBSStateParseChanges
       
   511 //
       
   512 // Verify whether ADM sis download is required. Based on this, the next state will be set.
       
   513 // ---------------------------------------------------------------------------
       
   514 //
       
   515 TBool CStateMachine::IsAdmDownloadRequired()
       
   516 	{
       
   517 	const TBool isAdmDownloadRequired =
       
   518 			CompareVersions(iAdmInstalledVersion, iAdmChangesInfo.iVersion)
       
   519 				== EGreaterSecondVersion;
       
   520 
       
   521 	if ( isAdmDownloadRequired )
       
   522 		{
       
   523 		LOG7( "ADM update required (v%d.%02d.%d -> v%d.%02d.%d)",
       
   524 			iAdmInstalledVersion.iMajor, iAdmInstalledVersion.iMinor, iAdmInstalledVersion.iBuild,
       
   525 			iAdmChangesInfo.iVersion.iMajor, iAdmChangesInfo.iVersion.iMinor, iAdmChangesInfo.iVersion.iBuild
       
   526 			);
       
   527 
       
   528 		iFileName.Set(*iAdmChangesInfo.iSisName);
       
   529 
       
   530 		DELETE_IF_NONNULL(iUrl);
       
   531 
       
   532 		iUrl = iConfigUrl->AllocL();
       
   533 		}
       
   534 	else
       
   535 		{
       
   536 		LOG4( "ADM is up-to-date (v%d.%02d.%d)",
       
   537 			iAdmInstalledVersion.iMajor, iAdmInstalledVersion.iMinor, iAdmInstalledVersion.iBuild
       
   538 			);
       
   539 		}
       
   540 
       
   541 	return isAdmDownloadRequired;
       
   542 	}
       
   543 
       
   544 // ---------------------------------------------------------------------------
       
   545 // CStateMachine::::StateDownloadL
       
   546 // Enter in case EBSStateDownloadChanges, EBSStateDownloadAdm
       
   547 //
       
   548 // Download the specified file from the given url.
       
   549 // ---------------------------------------------------------------------------
       
   550 //
       
   551 void CStateMachine::StateDownloadL()
       
   552 	{
       
   553 	LOG( "+ StateDownloadL()" );
       
   554 
       
   555 	// Create the full URL for download
       
   556 	DELETE_IF_NONNULL( iDownloadUrl );
       
   557 	// +1 for '/'
       
   558 	iDownloadUrl = HBufC8::NewL(iUrl->Length() + iFileName.Length() + 1 );
       
   559 	TPtr8 ptr(iDownloadUrl->Des());
       
   560 	ptr.Copy(*iUrl);
       
   561 
       
   562 	// Append forward slash if that's missing
       
   563 	if (ptr.Right(1)[0] != '/')
       
   564 		{
       
   565 		ptr.Append('/');
       
   566 		}
       
   567 	ptr.Append(iFileName);
       
   568 
       
   569 	iDownloadError = EDlErrNoError;
       
   570 	iConnectionAttempt = 0;
       
   571 
       
   572 	// Set download file name along with path
       
   573 	TChar systemDrive;
       
   574 	RFs::DriveToChar(RFs::GetSystemDrive(), systemDrive);
       
   575 
       
   576 	DELETE_IF_NONNULL( iDownloadFileName );
       
   577 	iDownloadFileName = HBufC::NewL(KDownloadFolder().Length() + iFileName.Length());
       
   578 	TPtr responseFilenamePtr = iDownloadFileName->Des();
       
   579 
       
   580 	responseFilenamePtr.Copy(KDownloadFolder);
       
   581 	responseFilenamePtr[0] = systemDrive;
       
   582 	responseFilenamePtr.Append(iFileName);
       
   583 
       
   584 	// Create new download
       
   585 	LOG2( "Downloading '%S'", iDownloadFileName );
       
   586 	LOG8_2( "  from '%S'", iDownloadUrl );
       
   587 
       
   588 	TBool isNewDl = ETrue, tried = EFalse;
       
   589 retry:
       
   590 	RHttpDownload& dl = iDownloadManager.CreateDownloadL( *iDownloadUrl, isNewDl );
       
   591 
       
   592 	ConeUtils::EnsurePathExistsL(*iDownloadFileName);
       
   593 
       
   594 	if (isNewDl)
       
   595 		{
       
   596 		LOG2( "Receiving '%S'", iDownloadFileName );
       
   597 		dl.SetStringAttribute( EDlAttrDestFilename, *iDownloadFileName );
       
   598 		User::LeaveIfError( dl.Start() );
       
   599 		}
       
   600 	else
       
   601 		{
       
   602 		LOG( "Dl exists." );
       
   603 		dl.Delete();
       
   604 		LOG( "Dl deleted." );
       
   605 		if (tried)
       
   606 			{
       
   607 			LOG( "Tried already, leaving" );
       
   608 			User::Leave(KErrAlreadyExists);
       
   609 			}
       
   610 		else
       
   611 			{
       
   612 			tried = ETrue;
       
   613 			goto retry;
       
   614 			}
       
   615 		}
       
   616 
       
   617 	LOG( "- Download()" );
       
   618 	}
       
   619 
       
   620 // ---------------------------------------------------------------------------
       
   621 // CStateMachine::StateParseChangesL
       
   622 // Enter in case EBSStateParseChanges
       
   623 //
       
   624 // Parse the given changes file.
       
   625 // ---------------------------------------------------------------------------
       
   626 //
       
   627 void CStateMachine::StateParseChangesL()
       
   628 	{
       
   629 	LOG2( "+ ParseFile('%S')", iDownloadFileName );
       
   630 	User::LeaveIfNull(iDownloadFileName);
       
   631 
       
   632 	// Initialize the parser
       
   633 	CSenXmlReader* XmlReader = CSenXmlReader::NewLC(EErrorOnUnrecognisedTags);
       
   634 	CSenDomFragment* DomFragment = CSenDomFragment::NewL();
       
   635 	CleanupStack::PushL(DomFragment);
       
   636 
       
   637 	XmlReader->SetContentHandler(*DomFragment);
       
   638 	DomFragment->SetReader(*XmlReader);
       
   639 
       
   640 	// Parse the provided changes file
       
   641 	XmlReader->ParseL(CEikonEnv::Static()->FsSession(), *iDownloadFileName);
       
   642 
       
   643 	// Get package version
       
   644 	CSenElement* packageElement;
       
   645 	packageElement = DomFragment->AsElement().Element(KFieldVersion);
       
   646 	if (packageElement == NULL)
       
   647 		{
       
   648 		User::Leave(EXmlErrorMissingVersion);
       
   649 		}
       
   650 	else
       
   651 		{
       
   652 		TPtrC8 versionPtr = packageElement->Content();
       
   653 		TVersion ver;
       
   654 		if (SetVersion(versionPtr, iAdmChangesInfo.iVersion) == EFalse)
       
   655 			{
       
   656 			User::Leave(EXmlErrorInvalidVersion);
       
   657 			}
       
   658 		}
       
   659 
       
   660 	// Get the ADM sis file name
       
   661 	packageElement = DomFragment->AsElement().Element(KFieldSisName);
       
   662 	if (packageElement)
       
   663 		{
       
   664 		iAdmChangesInfo.iSisName = packageElement->ContentUnicodeL();
       
   665 		}
       
   666 	else
       
   667 		{
       
   668 		User::Leave(EXmlErrorMissingSisFileName);
       
   669 		}
       
   670 
       
   671 	// URL read from ADM changes file.
       
   672 	// ADM.sis will be fetched from this url, if present. Or else default config url will be used.
       
   673 #if USE_ADMCHANGES_URL
       
   674 	// Get the optional URL
       
   675 	packageElement = DomFragment->AsElement().Element(KFieldUrl);
       
   676 	if (packageElement)
       
   677 		{
       
   678 		TPtrC8 urlPtr = packageElement->Content();
       
   679 		iAdmChangesInfo.iUrl = urlPtr.AllocL();
       
   680 		}
       
   681 #endif
       
   682 
       
   683 	CleanupStack::PopAndDestroy( DomFragment );
       
   684 	CleanupStack::PopAndDestroy( XmlReader );
       
   685 
       
   686 	// Delete no longer required changes file
       
   687 	DeleteFile(*iDownloadFileName);
       
   688 
       
   689 	LOG( "- ParseFile()" );
       
   690 	}
       
   691 
       
   692 // ---------------------------------------------------------------------------
       
   693 // CStateMachine::StateInstallAdmL
       
   694 // Enter in case EBSStateInstallAdm
       
   695 //
       
   696 // Silent Install the given sis file. This is asynchronous and the next state transition happens only in the handle function.
       
   697 // ---------------------------------------------------------------------------
       
   698 //
       
   699 void CStateMachine::StateInstallAdmL()
       
   700 	{
       
   701 	LOG( "+ InstallPackage()" );
       
   702 	SwiUI::TInstallOptions Options;
       
   703 
       
   704 	Options.iUpgrade = SwiUI::EPolicyAllowed;
       
   705 	Options.iOCSP    = SwiUI::EPolicyNotAllowed;
       
   706 	Options.iDrive   = 'c';
       
   707 	Options.iUntrusted = SwiUI::EPolicyNotAllowed;
       
   708 	Options.iCapabilities = SwiUI::EPolicyNotAllowed;
       
   709 	Options.iOverwrite = SwiUI::EPolicyAllowed;
       
   710 
       
   711 	iOptionsPckg = Options;
       
   712 
       
   713 	if (iInstallObsrv == NULL)
       
   714 		{
       
   715 		iInstallObsrv = new (ELeave) CInstallObserver(this);
       
   716 		}
       
   717 	iInstallObsrv->iStatus = KRequestPending;
       
   718 	iInstallObsrv->Start();
       
   719 	// Start asynchronous installation
       
   720 	iLauncher.SilentInstall(iInstallObsrv->iStatus, *iDownloadFileName, iOptionsPckg);
       
   721 
       
   722 	LOG( "- InstallPackage()" );
       
   723 	}
       
   724 
       
   725 // ---------------------------------------------------------------------------
       
   726 // CStateMachine::StateLaunchAdmL
       
   727 // Enter in case EBSStateLaunchAdm
       
   728 //
       
   729 // Launch ADM. A few command line args are passed and this depends on the bootstrap version.
       
   730 // ---------------------------------------------------------------------------
       
   731 //
       
   732 void CStateMachine::StateLaunchAdmL()
       
   733 	{
       
   734 	LOG( "+ LaunchAdm()" );
       
   735 
       
   736 	TUint32 protocolVer = KBootstrapAdmProtocolVersion;
       
   737 	TUint32 launchCtrl = 0;
       
   738 
       
   739 	// Command line arguments, version 15 specification:
       
   740 	//
       
   741 	//31               9  8  7  6  5  4  3  2  1  0
       
   742 	// +-------------+--+--+--+--+--+--+--+--+--+--+
       
   743 	// | reserved    |  |  |  |  |  |  |           |
       
   744 	// +-------------+--+--+--+--+--+--+--+--+--+--+
       
   745 	//
       
   746 	//      value
       
   747 	// bits range description
       
   748 	//  0-3  0-15 Command line parameter protocol version:
       
   749 	//             0 = not supported
       
   750 	//             1 = ADM.exe 1 <wrapper_uid> <iap> <depfile> <sisfile>
       
   751 	//             2 = ADM.exe 2 <wrapper_uid> <iap> <depfile> <sisfile>
       
   752 	//             3 = ADM.exe 3 <wrapper_uid> <iap> <depfile>
       
   753 	//             4 = ADM.exe 4 <wrapper_uid> <iap> <sisfile> (this was used in beta1, beta2)
       
   754 	//            15 = ADM.exe 15 [parameters as specified by other bits]
       
   755 	//
       
   756 	//         since
       
   757 	//  bit  version type command line parameter present
       
   758 	//    4      4     N  Bootstrap version number
       
   759 	//    5      4     N  Wrapper UID
       
   760 	//    6      4     N  IAP
       
   761 	//    7      4     N  ADM launch condition code:
       
   762 	//                    KCmdLineCancelAdm: ADM needs to cancel installation
       
   763 	//                    KCmdLineLaunchAdm: ADM starts normally
       
   764 	//    8      4     S  Full path to dependency XML file
       
   765 	//    9      4     S  Full path to application SIS file
       
   766 	//
       
   767 	// Types:
       
   768 	//  N  Natural decimal number (range 0 - 2^32-1, fits to TUint32)
       
   769 	//  S  UTF-8 string, must NOT contains spaces or other whitespaces
       
   770 	//
       
   771 	// Command line parameters appear in the order of the bits set, i.e.
       
   772 	// if bits 4, 8, 9 are set the command line parameters are:
       
   773 	// ADM.exe 784 <bootstrap_version> <dep_file> <sis_file>
       
   774 	//
       
   775 	// If command line protocol version is less than 15, it is assumed that
       
   776 	// old version command line parameter format is used.
       
   777 	//
       
   778 
       
   779 	// In case of approach 3 , cleanup of only BootStrap
       
   780 	// is required.
       
   781 	if (KBootstrapVersion == 3)
       
   782 		{
       
   783 		iWrapperPackageUid = KUidBootstrapApp.iUid;
       
   784 		}
       
   785 
       
   786 	// Set the launchCtrl based on Bootstrap Failure/Success
       
   787 	if ( iBootstrapFailed )
       
   788 		{
       
   789 		if (iSisFilename)
       
   790 			{
       
   791 			// SisFile exists -> resuming is possible
       
   792 			launchCtrl = KCmdLineCancelAdm;
       
   793 			}
       
   794 		else
       
   795 			{
       
   796 			launchCtrl = KCmdLineCancelAdmNoResume;
       
   797 			}
       
   798 		}
       
   799 	else
       
   800 		{
       
   801 		launchCtrl = KCmdLineLaunchAdm;
       
   802 		}
       
   803 
       
   804 	LOG2( "LaunchCtrl: %d", launchCtrl );
       
   805 
       
   806 	// By default, set the following bits:
       
   807 	// 1. BootstrapVersion,
       
   808 	// 2. WrapperUid
       
   809 	// 3. Launchctrl
       
   810 	// 4. IAP (If not set, the value is 0)
       
   811 	protocolVer |= (KCmdLineBitBootstrapVersion | KCmdLineBitWrapperUid)
       
   812 			| KCmdLineBitADMLaunchControl
       
   813 			| KCmdLineBitIAP;
       
   814 
       
   815 	// Set the mandatory command line parameters
       
   816 	//
       
   817 	// Size of 32-bit Bootstrap Version Value is 10 characters
       
   818 	// Size of 32-bit UID when converted to numeric string is 10 characters (4294967295)
       
   819 	// Size of 32-bit iIAP (TUint32) when converted to numeric string is 10 characters
       
   820 	// Size of 2 spaces is 2 characters
       
   821 	if ( (launchCtrl == KCmdLineCancelAdm) || (launchCtrl == KCmdLineLaunchAdm) )
       
   822 		{
       
   823 		switch (KBootstrapVersion)
       
   824 			{
       
   825 			case 1:
       
   826 			case 2:
       
   827 				{
       
   828 				User::LeaveIfNull(iSisFilename);
       
   829 				User::LeaveIfNull(iDepFilename);
       
   830 
       
   831 				protocolVer |= (KCmdLineBitFileSis | KCmdLineBitFileDep);
       
   832 				break;
       
   833 				}
       
   834 			case 3:
       
   835 				{
       
   836 				User::LeaveIfNull(iDepFilename);
       
   837 				protocolVer |= (KCmdLineBitFileDep);
       
   838 				break;
       
   839 				}
       
   840 			case 4:
       
   841 				{
       
   842 				User::LeaveIfNull(iSisFilename);
       
   843 				protocolVer |= (KCmdLineBitFileSis);
       
   844 				break;
       
   845 				}
       
   846 			default:
       
   847 				// Unsupported Bootstrap Version
       
   848 				User::Leave(KErrNotSupported);
       
   849 				break;
       
   850 			} // switch (KBootstrapVersion)
       
   851 		} // if ( (launchCtrl == KCmdLineCancelAdm) || (launchCtrl == KCmdLineLaunchAdm) )
       
   852 
       
   853 	// Build the command line parameter string
       
   854 	HBufC *processArgs = NULL;
       
   855 	TInt processArgsLen = 11; // obligatory protocol version number and ' '
       
   856 	TUint32 tmp = (protocolVer & ~KCmdLineBitProtocolVerMask) >> KCmdLineProtocolVerBits;
       
   857 	for (TInt i = 0; tmp != 0 || i < sizeof(KCmdLineParamLengths); tmp >>= 1, i++)
       
   858 		{
       
   859 		if (tmp & 1)
       
   860 			{
       
   861 			processArgsLen += KCmdLineParamLengths[i];
       
   862 			}
       
   863 		}
       
   864 	if (iDepFilename)
       
   865 		processArgsLen += iDepFilename->Length()+1; // +1 comes from the appended ' '
       
   866 	if (iSisFilename)
       
   867 		processArgsLen += iSisFilename->Length();
       
   868 	LOG2( "len %d", processArgsLen );
       
   869 	processArgs = HBufC::NewLC(processArgsLen);
       
   870 	TPtr ptr = processArgs->Des();
       
   871 
       
   872 	// append the obligatory protocol version number
       
   873 	ptr.AppendNum(protocolVer);
       
   874 	ptr.Append(' ');
       
   875 
       
   876 	if (protocolVer & KCmdLineBitBootstrapVersion)
       
   877 		{
       
   878 		ptr.AppendNum(KBootstrapVersion);
       
   879 		ptr.Append(' ');
       
   880 		}
       
   881 	if (protocolVer & KCmdLineBitWrapperUid)
       
   882 		{
       
   883 		ptr.AppendNum(iWrapperPackageUid);
       
   884 		ptr.Append(' ');
       
   885 		}
       
   886 	if (protocolVer & KCmdLineBitIAP)
       
   887 		{
       
   888 		ptr.AppendNum(iIAP);
       
   889 		ptr.Append(' ');
       
   890 		}
       
   891 	if (protocolVer & KCmdLineBitADMLaunchControl)
       
   892 		{
       
   893 		ptr.AppendNum(launchCtrl);
       
   894 		ptr.Append(' ');
       
   895 		}
       
   896 	if (protocolVer & KCmdLineBitFileDep)
       
   897 		{
       
   898 		ptr.Append(*iDepFilename);
       
   899 		ptr.Append(' ');
       
   900 		}
       
   901 	if (protocolVer & KCmdLineBitFileSis)
       
   902 		{
       
   903 		ptr.Append(*iSisFilename);
       
   904 		}
       
   905 
       
   906 	// Launch ADM
       
   907 	LOG3( "Launching %S '%S'", &KAdmExePath, processArgs);
       
   908 
       
   909 	RProcess process;
       
   910 	CleanupClosePushL<RProcess>( process );
       
   911 
       
   912 	const TInt err = process.Create( KAdmExePath, processArgs->Des() );
       
   913 	if (err != KErrNone)
       
   914 		{
       
   915 		LOG2( "ADM launch failed with error: %d", err );
       
   916 		CleanupStack::PopAndDestroy( &process );
       
   917 		CleanupStack::PopAndDestroy( processArgs );
       
   918 		User::Leave(err);
       
   919 		}
       
   920 	else
       
   921 		{
       
   922 		// ADM was launched properly, set it visible in the menu grid
       
   923 		LOG( "Revealing ADM menu icon" );
       
   924 		CUtils::HideApplicationFromMenuL( KUidAdm.iUid, EFalse );
       
   925 		}
       
   926 
       
   927 // Do not lower the priority: it will cause the "OK" note to be shown
       
   928 // on faster, more recent S60 devices
       
   929 //	process.SetPriority( EPriorityBackground );
       
   930 	process.Resume();
       
   931 
       
   932 	CleanupStack::PopAndDestroy( &process );
       
   933 	CleanupStack::PopAndDestroy( processArgs );
       
   934 
       
   935 	LOG2( "- LaunchAdmL(): %d", err );
       
   936 	}
       
   937 
       
   938 // ---------------------------------------------------------------------------
       
   939 // CStateMachine::HandleDMgrEventL
       
   940 // Callback to handle the download manager events
       
   941 // Called in EBSStateDownloadChanges, EBSStateDownloadAdm
       
   942 // ---------------------------------------------------------------------------
       
   943 //
       
   944 void CStateMachine::HandleDMgrEventL( RHttpDownload& aDownload, THttpDownloadEvent aEvent )
       
   945 	{
       
   946 	TInt32 glErrId = KErrNone;
       
   947 	TInt32 errId = ENoError;
       
   948 
       
   949 	// Get error IDs
       
   950 	aDownload.GetIntAttribute( EDlAttrGlobalErrorId, glErrId );
       
   951 	aDownload.GetIntAttribute( EDlAttrErrorId, errId );
       
   952 
       
   953 #ifdef DO_LOG
       
   954 	_LIT(KFmt, ", GlErrId=%6d, ErrId=%d");
       
   955 	TBuf<64> buf;
       
   956 
       
   957 	if ( ((glErrId != KErrNone) || (errId != ENoError)) && glErrId != KErrUnknown )
       
   958 		{
       
   959 		buf.AppendFormat(KFmt, glErrId, errId);
       
   960 		}
       
   961 
       
   962 	if ( ( iDownloadState != aEvent.iDownloadState ) ||
       
   963 		 ( iProgressState != aEvent.iProgressState ) )
       
   964 		{
       
   965 		iDownloadState = aEvent.iDownloadState;
       
   966 		iProgressState = aEvent.iProgressState;
       
   967 
       
   968 		LOG4( "DlSt=%5d, PrSt=%5d%S", iDownloadState, iProgressState, &buf );
       
   969 		}
       
   970 #endif
       
   971 
       
   972 	switch ( aEvent.iDownloadState )
       
   973 		{
       
   974 		case EHttpDlCreated:
       
   975 		case EHttpDlInprogress:
       
   976 			{
       
   977 			//Nothing done.
       
   978 			break;
       
   979 			}
       
   980 		case EHttpDlPaused:
       
   981 		case EHttpDlFailed:
       
   982 // These two fill fold to EHttpDlFailed. We don't want to process failure events twice.
       
   983 //		case EHttpDlNonPausableNetworkLoss:
       
   984 //		case EHttpDlMultipleMOFailed:
       
   985 			{
       
   986 			//Continue download if paused in EHttpContentTypeReceived.
       
   987 			//Pause is received even in ProgNone state!
       
   988 			if( ( aEvent.iProgressState == EHttpContentTypeReceived ) ||
       
   989 				( (aEvent.iProgressState == EHttpProgNone ) && ( errId == ENoError ) ) )
       
   990 				{
       
   991 				LOG( "Starting download" );
       
   992 				aDownload.Start();
       
   993 				break;
       
   994 				}
       
   995 			if ( ProcessDlErrors(glErrId, errId, iDownloadError) )
       
   996 				{
       
   997 				if ( (iIapArrayIndex+1) < iIapArray.Count() )
       
   998 					{
       
   999 					// Try the next IAP
       
  1000 					iIapArrayIndex++;
       
  1001 					LOG3( "Starting download with next IAP[%d]=%d.", iIapArrayIndex, iIapArray[iIapArrayIndex] );
       
  1002 					SetIAP( iIapArray[iIapArrayIndex] );
       
  1003 					aDownload.Start();
       
  1004 					break;
       
  1005 					}
       
  1006 				else if ( (iIapArrayIndex+1) == iIapArray.Count() )
       
  1007 					{
       
  1008 					// We've gone through all the IAPs in the SNAP, prompt the user for an access point
       
  1009 					SetIAP( 0 );
       
  1010 					// This ensures that this code path is taken only once
       
  1011 					iIapArrayIndex++;
       
  1012 					}
       
  1013 				if (++iConnectionAttempt < KDownloadConnectionRetries)
       
  1014 					{
       
  1015 					LOG4( "Restarting download due to network failure (%d: %d, %d)", iConnectionAttempt, glErrId, errId );
       
  1016 					// TODO: Do we need to do a Reset() before Start()?
       
  1017 					aDownload.Start();
       
  1018 					// We don't restart the download timer on purpose
       
  1019 					//
       
  1020 					// Clear the error id so it doesn't get caught below
       
  1021 					// as this is not an error situation.
       
  1022 					iDownloadError = EDlErrNoError;
       
  1023 					}
       
  1024 				else
       
  1025 					{
       
  1026 					LOG4( "Too many download retries, cancelling download (%d; %d, %d)", iDownloadError, glErrId, errId );
       
  1027 					// iDownloadError has been set properly by ProcessDlErrors()
       
  1028 					}
       
  1029 				}
       
  1030 			if ( iDownloadError != EDlErrNoError )
       
  1031 				{
       
  1032 				LOG2( "DlErr=%d", iDownloadError );
       
  1033 
       
  1034 				if ( iDownloadError == EDlErrCancelled )
       
  1035 					{
       
  1036 					HandleFailure(ETrue); // If user pressed cancel, then iIsIapCancelled is 1
       
  1037 					}
       
  1038 				else
       
  1039 					{
       
  1040 					HandleFailure(EFalse);
       
  1041 					}
       
  1042 				}
       
  1043 			break;
       
  1044 			}
       
  1045 		case EHttpDlCompleted:
       
  1046 			{
       
  1047 			// TODO: Get the DownloadfileName??
       
  1048 			iDownloadManager.GetIntAttribute( EDlMgrIap, iIAP );
       
  1049 			LOG2( "IAP set to %d", iIAP );
       
  1050 
       
  1051 			switch (iAppState)
       
  1052 				{
       
  1053 				case EBSStateDownloadChanges:
       
  1054 					RequestState(EBSStateParseChanges);
       
  1055 					break;
       
  1056 				case EBSStateDownloadAdm:
       
  1057 					RequestState(EBSStateInstallAdm);
       
  1058 					break;
       
  1059 				default:
       
  1060 					LOG2( "DlEvent from unknown state %d", iAppState );
       
  1061 					// TODO: Fix the panic code
       
  1062 					User::Panic(_L("SmartInst"), 42);
       
  1063 					break;
       
  1064 				}
       
  1065 			break;
       
  1066 			}
       
  1067 		default:
       
  1068 			{
       
  1069 			break;
       
  1070 			}
       
  1071 		}
       
  1072 	}
       
  1073 
       
  1074 // ---------------------------------------------------------------------------
       
  1075 //
       
  1076 // ---------------------------------------------------------------------------
       
  1077 //
       
  1078 TBool CStateMachine::ProcessDlErrors(const TInt32 aGlErrId, const TInt32 aErrId, EDownloadError& aDownloadError)
       
  1079 	{
       
  1080 	LOG4( "+ ProcessDlErrors(%d, %d, %d)", aGlErrId, aErrId, aDownloadError );
       
  1081 	TBool requestRestart = EFalse;
       
  1082 	const TUint count = iIapArray.Count();
       
  1083 	// Process the error codes
       
  1084 	switch (aErrId)
       
  1085 		{
       
  1086 		case KErrNone:
       
  1087 			// everything a-OK!
       
  1088 			break;
       
  1089 		case EConnectionFailed:
       
  1090 			// Request restart, if we haven't exhausted all the IAPs on the list.
       
  1091 			if (count > 0 && iIapArrayIndex < count)
       
  1092 				{
       
  1093 				requestRestart = ETrue;
       
  1094 				goto exit;
       
  1095 				}
       
  1096 			else
       
  1097 				{
       
  1098 				aDownloadError = EDlErrDownloadFailure;
       
  1099 				}
       
  1100 			break;
       
  1101 		case ETransactionFailed:
       
  1102 			// We set the download error to network failure as that's the
       
  1103 			// error propagated to TState::DownloadFailed().
       
  1104 			// The state machine will try to restart the download, if the
       
  1105 			// error code is EDlErrDownloadFailure, but NOT for EDlErrNetworkFailure.
       
  1106 			aDownloadError = EDlErrDownloadFailure;
       
  1107 			requestRestart = ETrue;
       
  1108 			break;
       
  1109 		case EObjectNotFound:
       
  1110 			aDownloadError = EDlErrFileNotFound;
       
  1111 			break;
       
  1112 		default:
       
  1113 			LOG2( "Unhandled ErrId %d", aErrId );
       
  1114 			aDownloadError = EDlErrDownloadFailure;
       
  1115 			break;
       
  1116 		}
       
  1117 	// Process the global error code
       
  1118 	switch (aGlErrId)
       
  1119 		{
       
  1120 		case KErrNone:
       
  1121 			// everything a-OK!
       
  1122 			break;
       
  1123 		case KErrCancel:
       
  1124 		case KErrAbort:
       
  1125 			// The user has cancelled the download / IAP selection box
       
  1126 			aDownloadError = EDlErrCancelled;
       
  1127 			break;
       
  1128 		case KErrDiskFull:
       
  1129 			// Disk full
       
  1130 			aDownloadError = EDlErrNotEnoughSpace;
       
  1131 			break;
       
  1132 		case KErrUnknown:
       
  1133 			{
       
  1134 			if( aErrId == KErrNone )
       
  1135 				{
       
  1136 				aDownloadError = EDlErrDownloadFailure;
       
  1137 				requestRestart = ETrue;
       
  1138 				}
       
  1139 			}
       
  1140 			break;
       
  1141 		case KErrNotFound:
       
  1142 		case KErrBadName:
       
  1143 		case KErrNotSupported:
       
  1144 		case KErrCommsLineFail:
       
  1145 		case KErrTimedOut:
       
  1146 		case KErrCouldNotConnect:
       
  1147 		case KErrDisconnected:
       
  1148 		case KErrGprsServicesNotAllowed:
       
  1149 		case KErrGsmMMNetworkFailure:
       
  1150 		case -8268: // KErrGsmOfflineOpNotAllowed:
       
  1151 		// WLAN network related errors:
       
  1152 		case KErrWlanNetworkNotFound:
       
  1153 		case KErrWlanRoamingFailed:
       
  1154 		case KErrWlanNetworkLost:
       
  1155 #if 0
       
  1156 		case KErrBadName:
       
  1157 		case KErrNotSupported:
       
  1158 		case KErrWlanOpenAuthFailed:
       
  1159 		case KErrWlanSharedKeyAuthRequired:
       
  1160 		case KErrWlanSharedKeyAuthFailed:
       
  1161 		case KErrWlanWpaAuthRequired:
       
  1162 		case KErrWlanIllegalEncryptionKeys:
       
  1163 		case KErrWlanPskModeRequired:
       
  1164 		case KErrWlanEapModeRequired:
       
  1165 		case KErrWlanSimNotInstalled:
       
  1166 		case KErrWlanNotSubscribed:
       
  1167 		case KErrWlanAccessBarred:
       
  1168 		case KErrWlanPasswordExpired:
       
  1169 		case KErrWlanNoDialinPermissions:
       
  1170 		case KErrWlanAccountDisabled:
       
  1171 		case KErrWlanRestrictedLogonHours:
       
  1172 		case KErrWlanServerCertificateExpired:
       
  1173 		case KErrWlanCerficateVerifyFailed:
       
  1174 		case KErrWlanNoUserCertificate:
       
  1175 		case KErrWlanNoCipherSuite:
       
  1176 		case KErrWlanUserRejected:
       
  1177 		case KErrWlanUserCertificateExpired:
       
  1178 		// less fatal, but still needs to fail the download:
       
  1179 		case KErrWlanWpaAuthFailed:
       
  1180 		case KErrWlan802dot1xAuthFailed:
       
  1181 		case KErrWlanIllegalWpaPskKey:
       
  1182 		case KErrWlanEapSimFailed:
       
  1183 		case KErrWlanEapTlsFailed:
       
  1184 		case KErrWlanEapPeapFailed:
       
  1185 		case KErrWlanEapMsChapv2:
       
  1186 		case KErrWlanEapAkaFailed:
       
  1187 		case KErrWlanEapTtlsFailed:
       
  1188 		case KErrWlanLeapFailed:
       
  1189 		case KErrWlanEapGtcFailed:
       
  1190 #endif
       
  1191 			// A fatal network error has occured, don't retry the download
       
  1192 			requestRestart = EFalse;
       
  1193 			aDownloadError = EDlErrNetworkFailure;
       
  1194 			break;
       
  1195 		default:
       
  1196 			if (!requestRestart)
       
  1197 				{
       
  1198 				// We assume all the other error codes to be 'hard' network errors
       
  1199 				LOG2( "Unhandled GlErrId %d", aGlErrId );
       
  1200 				aDownloadError = EDlErrNetworkFailure;
       
  1201 				}
       
  1202 			break;
       
  1203 		}
       
  1204 exit:
       
  1205 	LOG3( "- ProcessDlErrors(): %d, %d", requestRestart, aDownloadError );
       
  1206 	return requestRestart;
       
  1207 	}
       
  1208 
       
  1209 // ---------------------------------------------------------------------------
       
  1210 // CStateMachine::HandleInstallCompleteL
       
  1211 // Callback to handle the Installation events
       
  1212 // Called in EBSStateInstallAdm
       
  1213 //
       
  1214 // If SWI is busy, re attempt installation 6 times
       
  1215 // ---------------------------------------------------------------------------
       
  1216 //
       
  1217 void CStateMachine::HandleInstallCompleteL(const TInt& aStatus)
       
  1218 	{
       
  1219 	LOG2("+ HandleInstallCompleteL(%d)", aStatus);
       
  1220 	TBool retrying = EFalse;
       
  1221 
       
  1222 	User::LeaveIfNull(iDownloadFileName);
       
  1223 
       
  1224 	// If the install server is busy , try connecting multiple times.
       
  1225 	if ( (aStatus == SwiUI::KSWInstErrBusy ||
       
  1226 			aStatus == KErrInUse ||
       
  1227 			aStatus == KErrServerBusy)
       
  1228 			&& ((++iInstallAttempt) <= KMaxInstallerConnectionAttempts))
       
  1229 		{
       
  1230 		LOG3( "Installer busy (%d), requesting retry (%d)", iInstallAttempt, aStatus );
       
  1231 		retrying = ETrue;
       
  1232 		User::After(KIterationTimer * iInstallAttempt);
       
  1233 		RequestState(EBSStateInstallAdm);
       
  1234 		}
       
  1235 
       
  1236 	if (aStatus == KErrNone)
       
  1237 		{
       
  1238 		LOG( "ADM installed OK, deleting SIS." );
       
  1239 		// Delete no longer required sis file.
       
  1240 		DeleteFile(*iDownloadFileName);
       
  1241 		// ADM was installed succesfully, launch it!
       
  1242 		RequestState(EBSStateLaunchAdm);
       
  1243 		}
       
  1244 	else if (!retrying)
       
  1245 		{
       
  1246 		LOG3( "Installation unsuccessful (%d) after %d attempts, leaving.", aStatus, iInstallAttempt );
       
  1247 		// TODO: Better error handling
       
  1248 		User::Leave(aStatus);
       
  1249 		}
       
  1250 
       
  1251 	LOG("- HandleInstallCompleteL()");
       
  1252 	}
       
  1253 
       
  1254 // ---------------------------------------------------------------------------
       
  1255 // CStateMachine::IsPackagePresentL
       
  1256 // Check whether the given Package (uid & version) is already present in the device.
       
  1257 // Called in EBSStateInit to check for ADM Presence
       
  1258 // ---------------------------------------------------------------------------
       
  1259 //
       
  1260 TBool CStateMachine::IsPackagePresentL(const TUid& aUid, TVersion& aVersion)
       
  1261 	{
       
  1262 	LOG( "+ ADMPresent()");
       
  1263 
       
  1264 	// Connect to SisRegistry to find if the package is
       
  1265 	// already installed.
       
  1266 	Swi::RSisRegistrySession registrySession;
       
  1267 
       
  1268 	User::LeaveIfError(registrySession.Connect());
       
  1269 	CleanupClosePushL(registrySession);
       
  1270 
       
  1271 	const TBool isPkgInstalled = registrySession.IsInstalledL(aUid);
       
  1272 
       
  1273 	if (isPkgInstalled)
       
  1274 		{
       
  1275 		Swi::RSisRegistryEntry entry;
       
  1276 
       
  1277 		// Open registry entry
       
  1278 		User::LeaveIfError(entry.Open(registrySession, aUid));
       
  1279 		CleanupClosePushL(entry);
       
  1280 		aVersion = entry.VersionL();
       
  1281 
       
  1282 		CleanupStack::PopAndDestroy(&entry);
       
  1283 		}
       
  1284 
       
  1285 	CleanupStack::PopAndDestroy(&registrySession);
       
  1286 
       
  1287 	LOG3( "- ADMPresent(): 0x%x = %d", aUid.iUid, isPkgInstalled );
       
  1288 
       
  1289 	return isPkgInstalled;
       
  1290 	}
       
  1291 
       
  1292 // ---------------------------------------------------------------------------
       
  1293 // CStateMachine::DeleteFile
       
  1294 // Delete the given file
       
  1295 // ---------------------------------------------------------------------------
       
  1296 //
       
  1297 void CStateMachine::DeleteFile(const TDesC& aFileName)
       
  1298 	{
       
  1299 	CCoeEnv::Static()->FsSession().Delete(aFileName);
       
  1300 	}
       
  1301 
       
  1302 // ---------------------------------------------------------------------------
       
  1303 // CStateMachine::HandleWaitNoteCancel
       
  1304 // Call HandleFailure.
       
  1305 // ---------------------------------------------------------------------------
       
  1306 //
       
  1307 //TODO: Can this be removed and call HandleFailure() directly?
       
  1308 void CStateMachine::HandleWaitNoteCancel()
       
  1309 	{
       
  1310 	HandleFailure(ETrue);
       
  1311 	}
       
  1312 
       
  1313 // ---------------------------------------------------------------------------
       
  1314 // CStateMachine::HandleFailure
       
  1315 // Perform the state specific cleanup incase of failure.
       
  1316 // And then call AppUi Exit.
       
  1317 // ---------------------------------------------------------------------------
       
  1318 //
       
  1319 void CStateMachine::HandleFailure(TInt aError)
       
  1320 	{
       
  1321 	LOG2( "+ HandleFailure(): %d", aError );
       
  1322 
       
  1323 	switch (iAppState)
       
  1324 		{
       
  1325 		case EBSStateInit:
       
  1326 		case EBSStateSetup:
       
  1327 		case EBSStateLaunchAdm:
       
  1328 			// No cleanUp required here
       
  1329 			break;
       
  1330 		case EBSStateDownloadChanges:
       
  1331 		case EBSStateDownloadAdm:
       
  1332 			// Deletion of all downloads is taken care in destructor
       
  1333 			break;
       
  1334 		case EBSStateInstallAdm:
       
  1335 			// Cancel the installation
       
  1336 			iLauncher.CancelAsyncRequest(SwiUI::ERequestSilentInstall);
       
  1337 			// fall-through
       
  1338 		case EBSStateParseChanges:
       
  1339 			{
       
  1340 			// Delete the downloaded dep file
       
  1341 			if (iDownloadFileName)
       
  1342 				{
       
  1343 				DeleteFile(*iDownloadFileName);
       
  1344 				}
       
  1345 			}
       
  1346 			break;
       
  1347 		default:
       
  1348 			break;
       
  1349 		}
       
  1350 
       
  1351 	// Even in case of any failure, launch ADM, if present in device.
       
  1352 	// ADM needs to be launched in Cancel mode.
       
  1353 	if( (iAppState < EBSStateLaunchAdm) && iIsAdmInstalled )
       
  1354 		{
       
  1355 		// If it is user press cancel or Filenames are itself not set, then remove the whole wrapper package.
       
  1356 		// TODO: Should the failure reason be passed to ADM?
       
  1357 		// TODO: or show the error note in bootstrap, but launch ADM to remove the wrapper?
       
  1358 		if ( aError || ( iAppState <= EBSStateSetup) )
       
  1359 			{
       
  1360 			// No need to delete the files here, as the whole package will get removed.
       
  1361 			iBootstrapFailed = ETrue;
       
  1362 			}
       
  1363 		RequestState(EBSStateLaunchAdm);
       
  1364 		}
       
  1365 	else
       
  1366 		{
       
  1367 		// Delete the dep file is present
       
  1368 		if ( (KBootstrapVersion == 3) && iDepFilename )
       
  1369 			{
       
  1370 			DeleteFile(*iDepFilename);
       
  1371 			}
       
  1372 		else if ( (KBootstrapVersion == 4) && iSisFilename )
       
  1373 			{
       
  1374 			DeleteFile(*iSisFilename);
       
  1375 			}
       
  1376 
       
  1377 		// Set the Error ID based on App State and User Cancel.
       
  1378 		if( aError || ((iAppState != EBSStateDownloadChanges) && (iAppState != EBSStateDownloadAdm)) )
       
  1379 			{
       
  1380 			iAppUi.SetErrorId(EInstallationFailed);
       
  1381 			}
       
  1382 		else
       
  1383 			{
       
  1384 			iAppUi.SetErrorId(EDownloadFailed);
       
  1385 			}
       
  1386 
       
  1387 		// Now call App Exit to display the error note and exit bootstrap.
       
  1388 		RequestState(EBSStateExitWithError);
       
  1389 		}
       
  1390 
       
  1391 	LOG( "- HandleFailure()" );
       
  1392 	}
       
  1393 
       
  1394 #ifdef FEATURE_BOOTSTRAP_SETIAP
       
  1395 // ---------------------------------------------------------------------------
       
  1396 // Sets the used internet access point (IAP) to same that the Browser uses
       
  1397 // with additional verification that the selected IAP actually exist.
       
  1398 // ---------------------------------------------------------------------------
       
  1399 //
       
  1400 void CStateMachine::SetIAP(const TUint aIAP)
       
  1401 	{
       
  1402 	LOG2( "+ SetDlMgrIAP(): %d", aIAP );
       
  1403 	iIAP = aIAP;
       
  1404 	// Set the download manager to silent mode, if the IAP is valid
       
  1405 	iDownloadManager.SetBoolAttribute( EDlMgrSilentMode, aIAP != 0 );
       
  1406 	iDownloadManager.SetIntAttribute( EDlMgrIap, iIAP );
       
  1407 	}
       
  1408 
       
  1409 // ---------------------------------------------------------------------------
       
  1410 // Sets the used internet access point (IAP) to same that the Browser uses
       
  1411 // with additional verification that the selected IAP actually exist.
       
  1412 // ---------------------------------------------------------------------------
       
  1413 //
       
  1414 void CStateMachine::SetAndValidateIAPL()
       
  1415 	{
       
  1416 	LOG( "+ CBootstrapAppUi::SetAndValidateIAPL()" );
       
  1417 	// Use the browser default IAP, if available
       
  1418 	TInt ret;
       
  1419 	TInt browserIAP, browserIAPmode, browserSNAP;
       
  1420 	TRequestStatus status;
       
  1421 	RConnectionMonitor connMon;
       
  1422 
       
  1423 	// IsIapActive() requires this
       
  1424 	CleanupClosePushL(connMon);
       
  1425 	connMon.ConnectL();
       
  1426 
       
  1427 	CRepository *repository = CRepository::NewLC( KCRUidBrowser );
       
  1428 	User::LeaveIfError( repository->Get(KBrowserAccessPointSelectionMode, browserIAPmode) );
       
  1429 	User::LeaveIfError( repository->Get(KBrowserDefaultAccessPoint, browserIAP) );
       
  1430 	ret = repository->Get( KBrowserNGDefaultSnapId, browserSNAP );
       
  1431 	CleanupStack::PopAndDestroy( repository );
       
  1432 
       
  1433 	LOG5( "Browser IAP = %d, mode %d, SNAP %d (%d)", browserIAP, browserIAPmode, browserSNAP, ret );
       
  1434 
       
  1435 	if ( OviStoreRunning() && IsIapActive(connMon, browserIAP) )
       
  1436 		{
       
  1437 		LOG2( "Using Ovi Store IAP %d", browserIAP );
       
  1438 		browserIAPmode = EBrowserCenRepApSelModeUserDefined;
       
  1439 		// browserIAP now contains the IAP ID that OviStore is using
       
  1440 		}
       
  1441 
       
  1442 	// Get the IAP IDs for the browser SNAP, if we got the SNAP ID properly
       
  1443 	if (ret == KErrNone && browserSNAP > 0)
       
  1444 		{
       
  1445 		GetSnapIapsL(browserSNAP);
       
  1446 		}
       
  1447 
       
  1448 	switch (browserIAPmode)
       
  1449 		{
       
  1450 		case EBrowserCenRepApSelModeDestination:
       
  1451 			//LOG( "Destination network ");
       
  1452 			break;
       
  1453 		case EBrowserCenRepApSelModeUserDefined:
       
  1454 			//LOG( "User defined IAP" );
       
  1455 			if (browserIAP > 0)
       
  1456 				{
       
  1457 				SetIAP(browserIAP);
       
  1458 				break;
       
  1459 				}
       
  1460 			// else fall-through
       
  1461 		case EBrowserCenRepApSelModeAlwaysAsk:
       
  1462 		default:
       
  1463 			LOG( "'Always ask'" );
       
  1464 			// if browser IAP is already active: then we utilise it directly, no prompting
       
  1465 			if ( IsIapActive(connMon, browserIAP) )
       
  1466 				{
       
  1467 				LOG2( "Connection already up (%d)", browserIAP );
       
  1468 				SetIAP(browserIAP);
       
  1469 				}
       
  1470 			else
       
  1471 				{
       
  1472 				LOG( "Prompting IAP" );
       
  1473 				// Set to always ask, we obey it as well
       
  1474 				}
       
  1475 			// need to set this, if we ended up here with default:
       
  1476 			browserIAPmode = EBrowserCenRepApSelModeAlwaysAsk;
       
  1477 			break;
       
  1478 		}
       
  1479 	// Found a proper IAP?
       
  1480 	if (iIAP != 0 || browserIAPmode == EBrowserCenRepApSelModeAlwaysAsk)
       
  1481 		{
       
  1482 #if 0
       
  1483 		TBuf<64> iapName;
       
  1484 		connMon.GetStringAttribute( iIAP, 0, KIAPName, iapName, status );
       
  1485 		User::WaitForRequest( status );
       
  1486 		if ( status.Int() != KErrNone )
       
  1487 			{
       
  1488 			// Try access point name
       
  1489 			connMon.GetStringAttribute( iIAP, 0, KAccessPointName, iapName, status );
       
  1490 			User::WaitForRequest( status );
       
  1491 			if ( status.Int() != KErrNone )
       
  1492 				{
       
  1493 				LOG2( "ConnMon.GetStrAttr() ret = %d, ignoring.", status.Int() );
       
  1494 				}
       
  1495 			}
       
  1496 		LOG3( "Using IAP %d ('%S')", iIAP, &iapName );
       
  1497 #else
       
  1498 		//LOG2( "Using IAP %d", iIAP );
       
  1499 #endif
       
  1500 		}
       
  1501 	else
       
  1502 		{
       
  1503 		// set the IAP from SNAP, if it's valid
       
  1504 		if (iIapArray.Count() > 0 && iIapArray[0] > 0)
       
  1505 			{
       
  1506 			LOG2( "Starting with IAP %d", iIapArray[0] );
       
  1507 			SetIAP(iIapArray[0]);
       
  1508 			}
       
  1509 		}
       
  1510 
       
  1511 	CleanupStack::PopAndDestroy( &connMon );
       
  1512 	LOG3( "- CBootstrapAppUi::SetAndValidateIAPL(): %d, %d", ret, iIAP );
       
  1513 	}
       
  1514 
       
  1515 // ---------------------------------------------------------------------------
       
  1516 // Get the default IAP for the selected SNAP. SNAP is available since 3.2
       
  1517 // ---------------------------------------------------------------------------
       
  1518 //
       
  1519 void CStateMachine::GetSnapIapsL(const TUint aSNAPId)
       
  1520 	{
       
  1521 	// Load the helper library dynamically
       
  1522 	_LIT(KLibHelper, "smartinstaller.dll");
       
  1523 	LOG( "Loading helper" );
       
  1524 	RLibrary lib;
       
  1525 	const TInt ret = lib.Load( KLibHelper() );
       
  1526 	if (ret == KErrNone)
       
  1527 		{
       
  1528 		CleanupClosePushL(lib);
       
  1529 		const TInt KHelperNewLC = 2;
       
  1530 		CHelper* helper = (CHelper*)lib.Lookup(KHelperNewLC)();
       
  1531 		TRAPD(ret, helper->GetSnapIapsL(aSNAPId, iIapArray) );
       
  1532 		LOG3( "Got %d IAPs (%d)", iIapArray.Count(), ret );
       
  1533 #ifdef DO_LOG
       
  1534 		for (TInt i = 0; i < iIapArray.Count(); i++)
       
  1535 			{
       
  1536 			LOG3( "IAP[%d]=%d", i, iIapArray[i] );
       
  1537 			}
       
  1538 #endif
       
  1539 		CleanupStack::PopAndDestroy(2, &lib); // helper, lib
       
  1540 		}
       
  1541 	else
       
  1542 		{
       
  1543 		LOG2( "Helper load failed %d", ret );
       
  1544 		}
       
  1545 	lib.Close();
       
  1546 	}
       
  1547 
       
  1548 // ---------------------------------------------------------------------------
       
  1549 //
       
  1550 // ---------------------------------------------------------------------------
       
  1551 //
       
  1552 TBool CStateMachine::IsIapActive(RConnectionMonitor &aConnMon, TInt& aIAP)
       
  1553 	{
       
  1554 	LOG2( "+ IsIapActive(): %d", aIAP );
       
  1555 
       
  1556 	TBool ret = EFalse;
       
  1557 	// Get the connection info for each connection
       
  1558 	TUint id, iapId, count, countSubConn;
       
  1559 	TRequestStatus status = KRequestPending;
       
  1560 
       
  1561 	aConnMon.GetConnectionCount( count, status );
       
  1562 	User::WaitForRequest( status );
       
  1563 
       
  1564 	if (status.Int() != KErrNone)
       
  1565 		{
       
  1566 		LOG2( "GetConnCount() failed %d.", status.Int() );
       
  1567 		return ret;
       
  1568 		}
       
  1569 
       
  1570 	LOG2( "Active connections: %d", count );
       
  1571 
       
  1572 	TInt oviStoreIap = KErrNotFound;
       
  1573 	for ( TInt i = 1; i <= count && !ret; i++ )
       
  1574 		{
       
  1575 		const TInt err = aConnMon.GetConnectionInfo( i, id, countSubConn );
       
  1576 		if ( err == KErrNone )
       
  1577 			{
       
  1578 			LOG3( "ConnID[%d] = %d" , i, id );
       
  1579 			// Get the IAP Id of the connection
       
  1580 			aConnMon.GetUintAttribute( id, 0, KIAPId, iapId, status );
       
  1581 			User::WaitForRequest( status );
       
  1582 			if ( status.Int() != KErrNone )
       
  1583 				{
       
  1584 				LOG2( "GetIapId failed (%d), trying next", status.Int() );
       
  1585 				// try next connection
       
  1586 				continue;
       
  1587 				}
       
  1588 			else
       
  1589 				{
       
  1590 				LOG2( "Active IAP = %d", iapId );
       
  1591 				}
       
  1592 
       
  1593 			// Find the UIDs using this connection
       
  1594 			TConnMonClientEnumBuf clientBuf;
       
  1595 			aConnMon.GetPckgAttribute( id, 0, KClientInfo, clientBuf, status );
       
  1596 			User::WaitForRequest( status );
       
  1597 			if ( status.Int() == KErrNone )
       
  1598 				{
       
  1599 				//LOG3( "%d clients sharing IAP %d", clientBuf().iCount, iapId );
       
  1600 				for (TUint client = 0; client < clientBuf().iCount; client++)
       
  1601 					{
       
  1602 					//LOG2( "0x%08X", clientBuf().iUid[client].iUid );
       
  1603 					const TInt KUidSecureWidgetUi = 0x102829A0;
       
  1604 					if ( clientBuf().iUid[client].iUid == KUidSecureWidgetUi
       
  1605 							&& OviStoreRunning() )
       
  1606 						{
       
  1607 						if (oviStoreIap == KErrNotFound)
       
  1608 							{
       
  1609 							//LOG2( "Possible OviStore IAP %d", iapId );
       
  1610 							oviStoreIap = iapId;
       
  1611 							}
       
  1612 						else
       
  1613 							{
       
  1614 							// Another secure widget is running, we cannot determine
       
  1615 							// which one is ovi store, default to browser IAP
       
  1616 							oviStoreIap = 0;
       
  1617 							}
       
  1618 						}
       
  1619 					}
       
  1620 				}
       
  1621 			else
       
  1622 				{
       
  1623 				LOG2( "GetClientInfo failed (%d)", status.Int() );
       
  1624 				}
       
  1625 			// ignore any errors in KClientInfo query
       
  1626 
       
  1627 			// If we found Ovi Store IAP, use that
       
  1628 			if (oviStoreIap > 0)
       
  1629 				{
       
  1630 				LOG2( "Sharing Ovi Store IAP %d", oviStoreIap );
       
  1631 				iapId = oviStoreIap;
       
  1632 				}
       
  1633 
       
  1634 			if ( iIapArray.Count() > 0 )
       
  1635 				{
       
  1636 				// Go through all the SNAP's IAPs
       
  1637 				for (TInt iap = 0; iap < iIapArray.Count(); iap++)
       
  1638 					{
       
  1639 					if ( iapId == iIapArray[iap] )
       
  1640 						{
       
  1641 						LOG3( "Using %d (SNAP idx %d)", iapId, iap );
       
  1642 						// Update the IAP to match the found one
       
  1643 						aIAP = iapId;
       
  1644 						ret = ETrue;
       
  1645 						break;
       
  1646 						}
       
  1647 					}
       
  1648 				}
       
  1649 			else if ( iapId == aIAP )
       
  1650 				{
       
  1651 				LOG2( "Using %d", iapId );
       
  1652 				ret = ETrue;
       
  1653 				// we found matching IAP ID, break out of the loop
       
  1654 				break;
       
  1655 				}
       
  1656 			}
       
  1657 		else
       
  1658 			{
       
  1659 			LOG3( "GetConnInfo[%d] failed (%d), trying next", i, err );
       
  1660 			// try next connection
       
  1661 			}
       
  1662 		} // for
       
  1663 #if 0
       
  1664 	// If we didn't have any connections up, try to find the last used browser
       
  1665 	// IAP from the SNAP and use that:
       
  1666 	if (!ret && count == 0 && iIapArray.Count() > 0 )
       
  1667 		{
       
  1668 		// Go through all the SNAP's IAPs
       
  1669 		for (TInt iap = 0; iap < iIapArray.Count(); iap++)
       
  1670 			{
       
  1671 			if ( iapId == iIapArray[iap] )
       
  1672 				{
       
  1673 				LOG3( "Using %d (SNAP idx %d)", iapId, iap );
       
  1674 				// Update the IAP to match the found one
       
  1675 				aIAP = iapId;
       
  1676 				ret = ETrue;
       
  1677 				break;
       
  1678 				}
       
  1679 			}
       
  1680 		}
       
  1681 #endif
       
  1682 	LOG3( "- IsIapActive(): %d = %d", aIAP, ret );
       
  1683 
       
  1684 	return ret;
       
  1685 	}
       
  1686 #endif // FEATURE_BOOTSTRAP_SETIAP