diff -r b183ec05bd8c -r 19bba8228ff0 fotaapplication/fotaserver/FotaServer/src/fotadownload.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fotaapplication/fotaserver/FotaServer/src/fotadownload.cpp Wed Sep 01 12:27:42 2010 +0100 @@ -0,0 +1,1979 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: downloads upd pkg +* +*/ + + + +// INCLUDES +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#else +#include +#include +#endif +#include +#include //OMA DM UI for reading resource +#include +#include +#include //for reading san feature +#include +#include "fotastorage.h" +#include "FotaSrvApp.h" +#include "fotadownload.h" +#include "fotaserverPrivatePSKeys.h" +#include "FotaNetworkRegStatus.h" +#include //globalrfsstates +#include +#define __LEAVE_IF_ERROR(x) if(KErrNone!=x) {FLOG(_L("LEAVE in %s: %d"), __FILE__, __LINE__); User::Leave(x); } +#define __LEAVE(x) {FLOG(_L("LEAVE in %s: %d"), __FILE__, __LINE__); User::Leave(x); } + + +// -------------------------------------------------------------------------- +// CFotaDownload::NewL +// -------------------------------------------------------------------------- +CFotaDownload* CFotaDownload::NewL (CFotaServer* aServer) + { + __ASSERT_ALWAYS( aServer, User::Panic(KFotaPanic, KErrArgument) ); + CFotaDownload* ao = new (ELeave) CFotaDownload(); + ao->iFotaServer = aServer; + return ao; + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::RunL +// Do operations started in HandleDmgrEvent +// -------------------------------------------------------------------------- +void CFotaDownload::RunL() + { + FLOG(_L( "[FotaServer] CFotaDownload::RunL() >>")); + CancelDownload( ETrue ); + CreateDownloadL(); + FLOG(_L( "[FotaServer] CFotaDownload::RunL() <<" ) ); + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::DoCancel() +// Cancel notifier request +// -------------------------------------------------------------------------- +// +void CFotaDownload::DoCancel() + { + FLOG(_L("CFotaDownload::DoCancel() >>")); + FLOG(_L("CFotaDownload::DoCancel() <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::RunError(TInt aError) +// Handle active object run error. +// -------------------------------------------------------------------------- +// +TInt CFotaDownload::RunError(TInt aError) + { + if(aError) + { + FLOG(_L(" CFotaDownload::RunError err %d"), aError ); + } + return KErrNone; + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::CFotaDownload() +// -------------------------------------------------------------------------- +// +CFotaDownload::CFotaDownload() : CActive(EPriorityNormal) + , iUpdateAfterDownload (EFalse), iUrl( NULL ), + iDownload (NULL), + iDownloadedContentSize(0), + iPreviousContentSize ( 0 ), iShowOMACDUI(EFalse), iShowDLPrgUI(EFalse), + iDownloadResumable (EFalse), + iFMSEnabled (EFalse), + iDownloadActive (EFalse), + iFreshDL(ETrue), + iUserInitiatedResume(EFalse), + iSanValue(KErrNotFound), + iDownloadFinalized(EFalse) + { + CActiveScheduler::Add( this ); + FLOG(_L("CFotaDownload::CFotaDownload()")); + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::~CFotaDownload() +// -------------------------------------------------------------------------- +// +CFotaDownload::~CFotaDownload() + { + FLOG(_L("CFotaDownload::~CFotaDownload() >>")); + Cancel(); + + //Sets download state inactive if accidently closed. This is anyhow taken care in FinalizeDownload in Server. + SetDownloadActive(EFalse); + CancelDownload( ETrue ); + if ( iUrl ) + { + delete iUrl; iUrl=NULL; + } +/* if ( iNotifHandler ) Deleted at server + { + iNotifHandler->Cancel(); + delete iNotifHandler; + }*/ + if ( iDLProgressDlg ) + { + delete iDLProgressDlg; iDLProgressDlg=NULL; + } + + if (iDownloadMgr.Handle()) + iDownloadMgr.Close(); + //don't delete iFotaServer as it doesn't belong here. + + FLOG(_L("CFotaDownload::~CFotaDownload() <<")); +} + + +// -------------------------------------------------------------------------- +// CFotaDownload::CancelDownload +// Cancel download +// -------------------------------------------------------------------------- +// +void CFotaDownload::CancelDownload( const TBool aCancelProgressBar ) + { + FLOG(_L("CFotaDownload::CancelDownload() >>")); + + if( iDownloadMgr.Handle() ) + { + iDownloadMgr.Close(); + } + + if ( aCancelProgressBar && iDLProgressDlg ) + { + TRAPD(err, iDLProgressDlg->ProcessFinishedL() ) ;// deletes + if(err); // remove compiler warning + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + FLOG(_L("CFotaDownload::CancelDownload() <<")); + } + +// -------------------------------------------------------------------------- +// CFotaDownload::CreateDownloadL +// Create download +// -------------------------------------------------------------------------- +// +void CFotaDownload::CreateDownloadL() + { + FLOG(_L("CFotaDownload::CreateDownloadL() >>") ); + __ASSERT_ALWAYS( iDownloadMgr.Handle()==0, User::Leave(KErrAlreadyExists) ); + RHttpDownload* d(NULL); + iDLNeedsReset = EFalse; + TBool created; + iDownloadMgr.ConnectL( TUid::Uid(KFotaServerUid) , *this, EFalse); + FLOG(_L("CFotaDownload::CreateDownloadL, Stage 1") ); + iDownloadMgr.DeleteAll(); + + TRAPD(err, d = &iDownloadMgr.CreateDownloadL( *iUrl, created ) ); + RFs fs; + if(fs.Connect() == KErrNone) + { + RFile file; + CleanupClosePushL( fs ); + CleanupClosePushL( file ); + err=fs.MkDir(KDDDirPath); + FLOG(_L("creating directory err as %d"),err); + err=fs.SetSessionPath(KDDDirPath); + FLOG(_L("setting session path err as %d"),err); + err=fs.ShareProtected(); + FLOG(_L("ShareProtected err as %d"),err); + err = file.Replace(fs,KDDFilename, EFileWrite|EFileShareAny); + FLOG(_L("creating rfile err as %d"),err); + err = d->SetFileHandleAttribute(file); + FLOG(_L("setting dlmgr destfile attrib err as %d"),err); + CleanupStack::PopAndDestroy( &file ); + CleanupStack::PopAndDestroy( &fs ); + } + FLOG(_L("CFotaDownload::CreateDownloadL, Stage 2. err %d"),err); + if ( err == KErrArgument ) User::Leave( KErrNotFound ); + else if( err !=KErrNone) User::Leave( err ); + + if ( iDLState.iIapId > KErrNotFound ) + { + FLOG(_L(" Using internet access point iapid: %d"), iDLState.iIapId); + err = iDownloadMgr.SetIntAttribute( EDlMgrIap, iDLState.iIapId); // IAP id + User::LeaveIfError( err ); + //At this point the iIapId used in the SyncML Session is presumed working. Hence + //the same is stored in database for use during download. + FLOG(_L("Setting IAPID=%d is FotaState"),iDLState.iIapId); + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState,KNullDesC8, EFDBIapId ); + iFotaServer->iDatabase->CloseAndCommitDB(); + } + FLOG(_L("CFotaDownload::CreateDownloadL, Stage 3") ); + User::LeaveIfError( d->SetIntAttribute(EDlAttrFotaPckgId ,iDLState.iPkgId) ); + FLOG(_L("CFotaDownload::CreateDownloadL, Stage 4") ); + User::LeaveIfError( d->SetBoolAttribute(EDlAttrNoContentTypeCheck,ETrue) ); + + // If ui hidden or download restarting, do not show descriptor + if ( !iShowOMACDUI || iRestartCounter > 0 ) + { + FLOG(_L("setting DD to hidden")); + User::LeaveIfError(iDownloadMgr.SetBoolAttribute( EDlMgrSilentMode,ETrue )) ; + } + //It's a fresh download + iFreshDL = ETrue; + + // Start download + User::LeaveIfError(iDownloadMgr.StartAll()); + FLOG(_L("CFotaDownload::CreateDownloadL, Stage 5") ); + iDLProgress = EStarted; + + //This P&S Key is used to notify DM UI on any download event. key=0 for idle and key=1 for download + err = RProperty::Set( TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + ETrue ); + FLOG(_L("RProperty KFotaDMRefresh Set Etrue, err = %d"), err); + + SetDownloadActive(ETrue); + + User::LeaveIfError(err); + FLOG(_L("[FotaServer] CFotaDownload::CreateDownloadL <<")); +} + + // -------------------------------------------------------------------------- + // CFotaDownload::DownloadL + // Start download of swupd package. + // -------------------------------------------------------------------------- + // +void CFotaDownload::DownloadL(TDownloadIPCParams aParams,const TDesC8& aPkgURL + ,TBool aUpdateAfterDownload,const TInt aIapid,const TInt aRestartDownload) + { + FLOG(_L("[FotaServer] CFotaDownload::DownloadL >> restart %d"),aRestartDownload); + + TInt err = RProperty::Define( TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + RProperty::EInt,KReadPolicy,KWritePolicy); + FLOG(_L("RProperty KFotaDMRefresh Define, err = %d"), err); + if (err != KErrAlreadyExists ) + { + User::LeaveIfError(err); + + err = RProperty::Set( TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + KErrNotFound ); + + FLOG(_L("RProperty KFotaDMRefresh Set KErrNotFound, err = %d"), err); + User::LeaveIfError(err); + } + + if ( iUrl ) {delete iUrl; iUrl=NULL;} + iUrl = aPkgURL.Alloc(); + + iRestartCounter = aRestartDownload; + + iDLState = aParams; + FLOG(_L("CFotaDownload::DownloadL, Stage 1") ); + + // Set state ------------------------------------------------------------- + iDLState.iState = RFotaEngineSession::EStartingDownload; + + iDLState.iResult = KErrNotFound; + iDLState.iUpdateLtr = aUpdateAfterDownload; + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL( iDLState, *iUrl,EFDBState|EFDBResult + | EFDBProfileId|EFDBPkgUrl|EFDBPkgName|EFDBVersion|EFDBUpdateLtr); + iFotaServer->iDatabase->CloseAndCommitDB(); + FLOG(_L("CFotaDownload::DownloadL, Stage 2, pkgid:%d"),iDLState.iPkgId); + + // 2. Get Iap Id to use for download. This would be set in iDLState.iIapId. + SetIapToUseL(aParams, aIapid); + + + if ( iDLState.iIapId > KErrNotFound ) + { + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState,KNullDesC8, EFDBIapId ); + iFotaServer->iDatabase->CloseAndCommitDB(); + } + + /* + TBuf8<100> test; + //_LIT8( KNSmlDMFotaNode,"http://2IND02230.noe.nokia.com8080/myspace/ddv1.dd" ); + _LIT8( KNSmlDMFotaNode,"http://fdsqa.nokia.com/fdp/interface?fid=A0A19HMCUHWRU" ); + test.Copy(KNSmlDMFotaNode); + + + TUriParser8 parser; + + if (!parser.Parse(test) && !parser.IsSchemeValid()) */ + + TUriParser8 parser; + + + + if((parser.Parse(aPkgURL) == KErrNone) && !parser.IsSchemeValid() ) + + { + FLOG(_L("URL is malformed.. finalizing download")); + iDLState.iResult = RFotaEngineSession::EResMalformedOrBadURL; + iDLState.iState = RFotaEngineSession::EDownloadFailed; + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState, KNullDesC8, EFDBState | EFDBResult); + iFotaServer->iDatabase->CloseAndCommitDB(); + iFotaServer->FinalizeDownloadL(iDLState); + LaunchNotifierL(ESyncMLFwUpdErrorNote, KErrGeneralNoResume, EFalse ); + return; + } + iUpdateAfterDownload = aUpdateAfterDownload; + + // 3. Determine whether download should be visible or not + // Autoaccepted profile? + + SetDownloadUiBehavior(ETrue); + + CancelDownload( ETrue ); + + FLOG(_L("Setting SessionType=%d in FotaState"),iDLState.iSessionType); + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState,KNullDesC8, EFDBSessionType ); + iFotaServer->iDatabase->CloseAndCommitDB(); + FLOG(_L("CFotaDownload::DownloadL, Stage 3") ); + //Called to read the download variations in Fota (resume support & FMS) + CheckDownloadVariations(); + + //Create the download + CreateDownloadL( ); + FLOG(_L("[FotaServer] CFotaDownload::DownloadL <<")); + } + +// --------------------------------------------------------------------------- +// CFotaDownload::HandleDLProgressDialogExitL +// Handle canceling of download +// --------------------------------------------------------------------------- +TBool CFotaDownload::HandleDLProgressDialogExitL( TInt aButtonId ) + { + FLOG(_L("CFotaDownload::HandleDLProgressDialogExitL %d, note = %d >>"),aButtonId, iDLProgressDlg->iNoteType); + // Cancel clicked during download + if ( aButtonId == KErrNotFound ) + { + iRestartCounter = -1; + FLOG(_L("[FotaServer] CFotaDownload::HandleDLProgressDialogExitL Hiding UI")); + iFotaServer->iParentApp->SetUIVisibleL ( EFalse, ETrue ); + iUpdateAfterDownload = EFalse; + + iDLState.iResult = RFotaEngineSession::EResUserCancelled; + + if (iDLProgressDlg->iNoteType == EConnectingNote) + { + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + + TInt active (KErrNotFound); + RProperty::Get( TUid::Uid(KFotaServerUid), KFotaDownloadActive, active ); + FLOG(_L("active = %d"),active); + + if (active) //Resume operation has just begun and download request is submitted to dlmgr. Hence need to suspend. + { + RunDownloadSuspendL(RFotaEngineSession::EResUserCancelled, ETrue); + } + else //Resume operation has just begun, but download request is not submitted to dlmgr + { + LaunchNotifierL( ESyncMLFwUpdOmaDLPostponed, EFalse, EFalse ); + iFotaServer->FinalizeDownloadL( iDLState ); + } + } + else if (iDLProgressDlg->iNoteType == EDownloadingNote) + { + if (iDownloadResumable) + { + //Resume is supported. Query user whether to postpone or cancel download. + FLOG(_L("User pressed cancel. Resume is supported; hence pause download and query user if download has to be postponed or cancelled permanently.")); + RunDownloadSuspendL(RFotaEngineSession::EResUserCancelled); + } + else + { + //Resume is not supported. Download is cancelled + FLOG(_L("User pressed cancel. Resume is not supported & hence download has to be cancelled")); + RunDownloadCancelL(RFotaEngineSession::EResUserCancelled); + } + } + } + FLOG(_L("CFotaDownload::HandleDLProgressDialogExitL <<")); + return ETrue; + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::DoHandleDMgrEventL +// Handles download events. Updates package state accordingly +// -------------------------------------------------------------------------- +void CFotaDownload::DoHandleDMgrEventL( RHttpDownload* aDownload + , THttpDownloadEvent aEvent ) + { + __ASSERT_ALWAYS( aDownload, User::Panic(KFotaPanic, KErrArgument) ); + TInt32 sysErrorId( KErrNone ); + TInt32 contentsize; + TInt32 downloadedsize; + + TInt32 tmp; + THttpDownloadMgrError dlErrorId; + iDownload = aDownload; + // If DL is in final state (complete/fail), there's an error id available. + User::LeaveIfError( aDownload->GetIntAttribute( EDlAttrGlobalErrorId + ,sysErrorId ) ); + User::LeaveIfError( aDownload->GetIntAttribute( EDlAttrDownloadedSize + ,downloadedsize ) ); + User::LeaveIfError( aDownload->GetIntAttribute( EDlAttrLength + ,contentsize ) ); + User::LeaveIfError( aDownload->GetIntAttribute( EDlAttrErrorId + ,tmp ) ); + dlErrorId = (THttpDownloadMgrError)tmp; + + + // Update progress dlg progress + if ( !iDLProgressDlg && iRestartCounter>0) + { + FLOG(_L("reshowing progress...")); + iDLProgressDlg = new(ELeave) CFotaDLProgressDlg((CEikDialog** ) &iDLProgressDlg , EFalse, this, EDownloadingNote ); + iDLProgressDlg->PrepareLC( R_FOTASERVER_DL_PROGRESS_DIALOG ); + iDLProgressDlg->RunLD(); + } + if (iDLProgressDlg) + { + CEikProgressInfo* progressInfo = iDLProgressDlg->GetProgressInfoL(); + __ASSERT_ALWAYS( progressInfo, User::Panic(KFotaPanic, KErrBadHandle) ); + if ( iPreviousContentSize!=contentsize ) + { + iPreviousContentSize = contentsize; + if ( contentsize > 0 ) + { + progressInfo->SetFinalValue( contentsize ); + } + } + TInt incr = downloadedsize - iDownloadedContentSize; + if (incr<=0) incr=0; //Protection + progressInfo->IncrementAndDraw(incr); + iDownloadedContentSize = downloadedsize; + } + FLOG(_L("CFotaDownload::HandleDMgrEventL() >> DLstate:%d ProgressSt:%d\ + globErr: %d DLError: %d (%d/%d)"),aEvent.iDownloadState + ,aEvent.iProgressState,sysErrorId,dlErrorId,downloadedsize,contentsize ); + + if ( sysErrorId <= -25000) { FLOG(_L(" error %d interpreted as http \ + error %d") , sysErrorId, sysErrorId + 25000 ); } + + switch ( aEvent.iDownloadState ) + { + case EHttpDlCreated: // 1 + { + FLOG(_L("Download State: EHttpDlCreated")); + } + break; + case EHttpDlInprogress: // 2 + { + FLOG(_L("Download State: EHttpDlProgress")); + + + if (aEvent.iProgressState == EHttpProgCodDescriptorDownloaded) + { + if (iShowOMACDUI || iShowDLPrgUI) + { + iFotaServer->iParentApp->SetUIVisibleL ( ETrue, EFalse); + } + } + + // Is ECodLoadEnd optimized out? + if ( aEvent.iProgressState == EHttpProgCodLoadEnd ) // 2503 + { + TInt err; + err = aDownload->Start(); // PPAR-6FRHFY fixed + if(err) + { + FLOG(_L(" ERROR when restarting DL %d"),err); + User::Leave(err); + } + FLOG( _L(" DL restarted") ); + } + + // Should tell user to free disk space. But how do we know that disk space is about be exceeded? + + if ( iDLNeedsReset ) + { + FLOG(_L("aDownload->Reset();")); + iDLNeedsReset = EFalse; + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + User::LeaveIfError( aDownload->Reset() ); + } + + // Body data of descriptor or payload pkg + if ( aEvent.iProgressState == EHttpProgResponseBodyReceived && iDLProgress==EDescriptorDownloaded/*2500*/) + { + // Now pkg size can be retrieved. must check size. + iDLState.iPkgSize = contentsize; + FLOG(_L("Setting PkgSize=%d in FotaState"),contentsize); + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState,KNullDesC8, EFDBPkgSize ); + iFotaServer->iDatabase->CloseAndCommitDB(); + + + TInt contentsize2 = contentsize; + + TInt dlsize (KErrNone); + TInt tlsize (KErrNone); + + TRAPD(err, iFotaServer->GetDownloadUpdatePackageSizeL(iDLState.iPkgId, dlsize,tlsize)); + if(err); // remove compiler warning + contentsize2 -= dlsize; + FLOG(_L("check pkg size = %d"),contentsize2 ); + + CFotaStorage::TFreeSpace avail = iFotaServer->StoragePluginL()->IsPackageStoreSizeAvailableL(contentsize2); + + iDLProgress = ESizeChecked; + + if ( avail==CFotaStorage::EDoesntFitToFileSystem ) + { + FLOG(_L("CFotaStorage::EDoesntFitToFileSystem")); + if (iFreshDL) + { + if ( iShowDLPrgUI ) + { + FLOG(_L("iDLNeedsReset = ETrue;")); + iDLNeedsReset = ETrue; + LaunchNotifierL( ESyncMLFwUpdOmaDLNotEnoughMemory, KErrDiskFull,contentsize2 ); + } + else + { + iDLState.iResult = RFotaEngineSession::EResDLFailDueToDeviceOOM; + iDLState.iState = RFotaEngineSession::EDownloadFailed; + iUpdateAfterDownload = EFalse; + LaunchNotifierL( ESyncMLFwUpdErrorNote, KErrGeneral, contentsize2,ETrue ); + } + } + else //resuming download + { + FLOG(_L("Memory need in order to resume. Notify user...")); + LaunchNotifierL( ESyncMLFwUpdOmaDLNotEnoughMemory, KErrDiskFull,contentsize2 ); + RunDownloadSuspendL(RFotaEngineSession::EResDLFailDueToDeviceOOM); + } + + } + } + + // OMA DD download completed , must hide progress + if ( aEvent.iProgressState == EHttpProgContentTypeChanged ) // 2055 + { + if ( iDLProgressDlg ) + { + iDLProgressDlg->ProcessFinishedL(); // deletes itself + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + } + // OMA DD accepted,show progress + if ( aEvent.iProgressState == EHttpProgCodDescriptorAccepted ) // 2502 + + { + iDLProgress = EDescriptorDownloaded; + if ( iShowDLPrgUI ) + { + FLOG(_L("SHOW PROGRESS")); + if ( iDLProgressDlg ) + { + FLOG(_L("Removing Connecting progress note...")); + iDLProgressDlg->ProcessFinishedL(); + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + if (!iDLProgressDlg) + { + + FLOG(_L("Creating iDLProgressDlg")); + iDLProgressDlg = new(ELeave) CFotaDLProgressDlg((CEikDialog** ) &iDLProgressDlg , EFalse, this, EDownloadingNote ); + iDLProgressDlg->PrepareLC( R_FOTASERVER_DL_PROGRESS_DIALOG ); + iDLProgressDlg->RunLD(); + } + CEikProgressInfo* progressInfo = iDLProgressDlg->GetProgressInfoL(); + progressInfo->SetFinalValue( 500 ); + iPreviousContentSize = -1; + iDownloadedContentSize = 0; + iFotaServer->iParentApp->SetUIVisibleL ( ETrue , EFalse ); + } + if (iDownloadResumable) + { + FLOG(_L("Setting download as resumable")); + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + iFotaServer->SetStartupReason(EFotaDownloadInterrupted); + } + else + { + FLOG(_L("Setting download as non resumable")); + iDLState.iState = RFotaEngineSession::EDownloadProgressing; + iFotaServer->SetStartupReason(EFotaPendingGenAlert); + } + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState,KNullDesC8, EFDBState ); + iFotaServer->iDatabase->CloseAndCommitDB(); + + + if (iDLState.iIapId <= 0) //Read the IAP ID when not known, and set it into db. + { + TInt32 usedapid (KErrNotFound); + TInt er = iDownloadMgr.GetIntAttribute( EDlMgrIap, usedapid); + iDLState.iIapId = usedapid; + FLOG(_L("Setting IAPID=%d is FotaState"),iDLState.iIapId); + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState,KNullDesC8, EFDBIapId ); + iFotaServer->iDatabase->CloseAndCommitDB(); + } + } + } + break; + case EHttpDlCompleted: // 4 + { + FLOG(_L("Download State: EHttpDlCompleted")); + + iRestartCounter = -1; + if ( iDLProgressDlg ) + { + iDLProgressDlg->ProcessFinishedL(); // deletes itself + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + iDLState.iState = RFotaEngineSession::EDownloadComplete; + + if (iUpdateAfterDownload) + iDLState.iResult = KErrNotFound; + else + iDLState.iResult = RFotaEngineSession::EResSuccessful; + iFotaServer->FinalizeDownloadL( iDLState ); + } + break; + case EHttpDlPaused: //Event thrown for any resumable download + case EHttpDlFailed: //Event thrown for any non-resumable download or critical error on resumable download + { + + if (aEvent.iProgressState != EHttpProgNone) //Accepting only events from COD + return; + + if (aEvent.iDownloadState == EHttpDlPaused) + { + FLOG(_L("Download State: EHttpDlPaused")); + if (iDownloadResumable) + { + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + } + else + { + // iDownloadResumable remains 0 even for resumable download. + iDLState.iState = RFotaEngineSession::EDownloadFailed; + } + } + else //aEvent.iDownloadState = EHttpDlFailed + { + FLOG(_L("Download State: EHttpDlFailed")); + iDLState.iState = RFotaEngineSession::EDownloadFailed; + iDownloadResumable = EFalse; + } + //Remove the download progress bar + if ( iDLProgressDlg && (iDLState.iResult != RFotaEngineSession::EResUserCancelled )) + { + FLOG(_L("Shd not come in EResUserCancelled")); + iDLProgressDlg->ProcessFinishedL(); // deletes itself + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + // This is restarted download => decrement counter + if ( iRestartCounter > 0 ) + { + --iRestartCounter; + if ( iRestartCounter <=0 ) iRestartCounter = -1; + FLOG(_L(" iRestartCounter to %d"),iRestartCounter ); + } + /*****************************/ + //Handling all errors now...// + /****************************/ + TInt notifType (KErrNotFound); + TInt notifParam (KErrNotFound); + //Handling User Cancel of Download Descriptor + if ( dlErrorId == EGeneral && (sysErrorId == KErrAbort || sysErrorId == KErrCancel )) + { + FLOG(_L("Reason: User cancelled download descriptor")); + //LaunchNotifierL(ESyncMLFwUpdOmaDLCancelled, EFalse, EFalse); + iRestartCounter = -1; + iDLState.iResult = RFotaEngineSession::EResUserCancelled; + notifType = ESyncMLFwUpdOmaDLCancelled; + notifParam = KErrNone; + } + //Handling User Cancel + else if ( iDLState.iResult == RFotaEngineSession::EResUserCancelled ) //This variable is set in RunDownloadCancelL or RunDownloadSuspendL + { + iRestartCounter = -1; + //If initial pause is successful, query user if he wants to postpone or cancel permanently. + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL(iDLState,KNullDesC8, EFDBState); + iFotaServer->iDatabase->CloseAndCommitDB(); + + if (iDownloadResumable) + { + if (!iSilentOpn) + { + FLOG(_L("Download has been paused successful. Query user if he wants to postpone or cancel permanently")); + LaunchNotifierL(ESyncMLFwUpdOmaDLUserCancel, KErrNone, KErrNone); + break; + } + else + { + notifType = ESyncMLFwUpdOmaDLPostponed; + notifParam = KErrNone; + } + } + else + { + FLOG(_L("Error while initial pausing...%d Hence download has to be cancelled permanently!")); + RunDownloadCancelL(RFotaEngineSession::EResUserCancelled); + notifType = ESyncMLFwUpdOmaDLCancelled; + notifParam = KErrNone; + } + } + else if ( iDLState.iResult == RFotaEngineSession::EResDLFailDueToDeviceOOM ) + { + FLOG(_L("Reason: Not enough memory to perform resume")); + iRestartCounter = -1; + + if (iDownloadResumable) + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + else + iDLState.iState = RFotaEngineSession::EDownloadFailed; + } + //Handling user cancel IAP selection popup + else if ( dlErrorId == EConnectionFailed && sysErrorId == KErrCancel) + { + FLOG(_L("Reason: User canceled IAP selection popup")); + iDLState.iResult = RFotaEngineSession::EResUserCancelled; + iRestartCounter = -1; + + notifType = ESyncMLFwUpdOmaDLPostponed; + notifParam = KErrNone; + } + //Handling temproary network timeout. This may either try resume or restart based on download. +/* else if ( dlErrorId == EGeneral && sysErrorId == KErrTimedOut ) + { + FLOG(_L("Reason: Network timeout")); + // No restart issued yet, this is 1st download attempt + if ( iRestartCounter == 0 ) + { + iRestartCounter = KFotaDownloadTimeoutRestartCount; + iDLState.iState = RFotaEngineSession::EIdle; + FLOG(_L("Trying to restart download (iRestartCounter=%d)"),iRestartCounter ); + } + + }*/ + //Handling all Network interrupts + else if ( (dlErrorId == EConnectionFailed && sysErrorId == KErrCommsLineFail)|| + dlErrorId == ETransactionFailed || + (dlErrorId == KErrCodWapConnectionDropped && sysErrorId == KErrGeneral) || + (dlErrorId == EGeneral && sysErrorId == KErrTimedOut) || + (dlErrorId == EConnectionFailed && sysErrorId == KErrGprsServicesNotAllowed ) || + (dlErrorId == EConnectionFailed && sysErrorId == KErrGsmMMNetworkFailure ) || + (dlErrorId == EConnectionFailed && sysErrorId == KErrWlanNetworkNotFound ) + ) + { + FLOG(_L("Reason: Network breakage")); + iRestartCounter = -1; + notifType = ESyncMLFwUpdErrorNote; + if (iDownloadResumable) + { + notifParam = KErrCommsLineFail2; + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + iDLState.iResult = RFotaEngineSession::EResDLFailDueToNWIssues; + } + else + { + notifParam = KErrCommsLineFail; + iDLState.iState = RFotaEngineSession::EDownloadFailed; + iDLState.iResult = RFotaEngineSession::EResDLFailDueToNWIssues; + } + } + //Handling Out Of Memory interrupt + else if ((dlErrorId == EGeneral && sysErrorId == KErrDiskFull ) || sysErrorId == KErrCodInsufficientSpace) + { + FLOG(_L("Reason: Disk full")); + iRestartCounter = -1; + notifType = KErrNotFound; + notifParam = KErrNotFound; // don't show anything + iDLState.iResult = RFotaEngineSession::EResDLFailDueToDeviceOOM; + } + //Handle unclassified (general) interrupts + else + { + iRestartCounter = -1; + + + RProperty prop; + TInt val = KErrNone; + + TInt err = prop.Get(KPSUidStartup, KPSGlobalSystemState, val); + if (err==KErrNone && val!=ESwStateShuttingDown) + { + notifType = ESyncMLFwUpdErrorNote; + } + else + { + FLOG(_L("Phone is powering down...")); + } + + if (iDownloadResumable) + { + notifParam = KErrGeneralResume; + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + } + else + { + notifParam = KErrGeneralNoResume; + iDLState.iState = RFotaEngineSession::EDownloadFailed; + } + + + SetDLResultdlErrorId(dlErrorId ,sysErrorId ); + + + } + if ( iRestartCounter <= 0) + { + iUpdateAfterDownload = EFalse; + SetDownloadActive(EFalse); + if ( iDLState.iSessionType!= ESanSilent && notifType!=KErrNotFound ) + { + if ( iShowDLPrgUI ) + LaunchNotifierL( (TSyncMLFwUpdNoteTypes)notifType, notifParam,0 ); + else + LaunchNotifierL( (TSyncMLFwUpdNoteTypes)notifType, notifParam,0, ETrue); + } + FLOG(_L("Should come here for nonpausable ")); + iDownloadFinalized = ETrue; + iFotaServer->FinalizeDownloadL( iDLState ); + } + else + { + if (iDownloadResumable) + { + FLOG(_L("Resuming download...")); + iDownload->Start(); + } + else + { + FLOG(_L("Restarting download...")); + iFotaServer->FinalizeDownloadL( iDLState ); + } + } + } + break; + + case EHttpDlPausable: + { + FLOG(_L("Download State: EHttpDlPausable")); + if (iDownloadResumable) //This is initially set by IsDownloadSuspendResumeSupported() + { + FLOG(_L("Download Suspend/Resume is supported!")); + } + else + { + FLOG(_L("Download Server support Suspend/Resume, but Fota doesn't!")); + //retain the state iDownloadResumable = EOmaDLResumeNotSupported; + } + } + break; + + case EHttpDlNonPausable: + { + FLOG(_L("Download State: EHttpDlNonPausable")); + if (iDownloadResumable) //This is initially set by CheckDownloadVariations() + { + FLOG(_L("Download Server doesn't support Suspend/Resume, but Fota does!")); + //Reset the state to not supported. + iDownloadResumable = EFalse; + } + else + { + FLOG(_L("Download Server doesn't support Suspend/Resume, neither does Fota!")); + } + } + break; + case EHttpDlDeleting: //13 + { + FLOG(_L("Download State: EHttpDlDeleting")); + } + break; + case EHttpDlDeleted: //11 + { + FLOG(_L("Download State: EHttpDlDeleted")); + } + break; + default: + { + FLOG(_L("Default. No action performed for this Download State")); + } + break; + } + FLOG(_L("CFotaDownload::HandleDMgrEventL() <<")); + } + + + +// -------------------------------------------------------------------------- +// CFotaDownload::SetDLResultdlErrorId +// Sets the appropriate error +// -------------------------------------------------------------------------- +// + +void CFotaDownload::SetDLResultdlErrorId( THttpDownloadMgrError adlErrorId, TInt32 asysErrorId) +{ + if ( adlErrorId == EInternal) + { + FLOG(_L("Reason: error EInternal")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( adlErrorId == EContentFileIntegrity) + { + FLOG(_L("Reason: error EContentFileIntegrity")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( adlErrorId == EMMCRemoved) + { + FLOG(_L("Reason: error EMMCRemoved,")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( adlErrorId == EBadUrl) + { + FLOG(_L("Reason: error EBadUrl")); + iDLState.iResult = RFotaEngineSession::EResMalformedOrBadURL; + } + else if ( adlErrorId == EHttpUnhandled) + { + FLOG(_L("Reason: error EHttpUnhandled, check global error id!")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( adlErrorId == EHttpAuthenticationFailed) + { + FLOG(_L("Reason: error EHttpAuthenticationFailed")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( adlErrorId == EObjectNotFound) + { + FLOG(_L("Reason: error EObjectNotFound")); + iDLState.iResult = RFotaEngineSession::EResAlternateDLServerUnavailable; + } + else if ( adlErrorId == EPartialContentModified) + { + FLOG(_L("Reason: error EPartialContentModified")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( adlErrorId == EContentExpired) + { + FLOG(_L("Reason: error EContentExpired")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( adlErrorId == EHttpRestartFailed) + { + FLOG(_L("Reason: error EHttpRestartFailed")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + else if ( asysErrorId == KErrCodInvalidDescriptor ) + { + FLOG(_L("Reason: error KErrCodInvalidDescriptor")); + iDLState.iResult = RFotaEngineSession::EResMalformedOrBadURL; + } + else + { + FLOG(_L("Reason: unknown, check dlError!")); + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + } + +} + +// -------------------------------------------------------------------------- +// CFotaDownload::HandleDMgrEventL +// -------------------------------------------------------------------------- +// +void CFotaDownload::HandleDMgrEventL( RHttpDownload& aDownload + , THttpDownloadEvent aEvent ) + { + DoHandleDMgrEventL(&aDownload,aEvent); + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::LaunchNotifierL +// Launches notifier. This method is also used to finalize erronous DL +// -------------------------------------------------------------------------- +// +void CFotaDownload::LaunchNotifierL( const TSyncMLFwUpdNoteTypes aNotetype + ,const TInt aIntParam + ,const TInt aMemoryNeeded + ,TBool aFinishOnly ) + { + if ( iNotifHandler ) iNotifHandler->Cancel(); + else iNotifHandler = CFotaDownloadNotifHandler::NewL(this); + iNotifHandler->LaunchNotifierL( aNotetype,aIntParam,aMemoryNeeded + ,aFinishOnly ); + } + +// -------------------------------------------------------------------------- +// CFotaDownload::CheckDownloadVariations +// Reads download variations - fota suspend & resume bahavior & FMS from cenrep keys +// -------------------------------------------------------------------------- +// +void CFotaDownload::CheckDownloadVariations() + { + FLOG(_L("CFotaDownload::CheckDownloadVariations >>")); + + CRepository* centrep( NULL); + TRAPD(err, centrep = CRepository::NewL( KCRUidFotaServer ) ); + if (err) FLOG(_L("Error reading FotaServer cenrep... %d"),err); + TInt supported(KErrNone); + if (centrep ) + { + err = centrep->Get( KSuspendResumeFeatureSupported, supported ); + if (err) FLOG(_L("Error reading cenrep key... %d"),err); + iDownloadResumable = (supported==1)? ETrue:EFalse; + + supported = KErrNone; + centrep->Get( KFotaMonitoryServiceEnabled, supported ); + if (err) FLOG(_L("Error reading cenrep key... %d"),err); + iFMSEnabled = (supported > 0)? ETrue:EFalse; + + delete centrep; + centrep = NULL; + } + + FLOG(_L("Susp&Resume feature supported = %d, FMS feature supported = %d"),iDownloadResumable,iFMSEnabled); + FLOG(_L("CFotaDownload::CheckDownloadVariations <<")); + } + +// -------------------------------------------------------------------------- +// CFotaDownload::RunDownloadCancelL +// Starts to cancel the download operation +// -------------------------------------------------------------------------- +// +void CFotaDownload::RunDownloadCancelL(const TInt aReason, TBool aSilent) + { + FLOG(_L("CFotaDownload::RunDownloadCancelL, reason = %d, silent = %d >>"), aReason, aSilent); + + iDLState.iState = RFotaEngineSession::EDownloadFailed; + iDLState.iResult = aReason; + iSilentOpn = aSilent; + + iRestartCounter = -1; + iUpdateAfterDownload = EFalse; + + if (!iDownload) + { + //iDownload is null when user cancels the download permanently when prompted to resume. + //hence retrieve the download object first + iDownload = RetrieveDownloadL(); + } + TInt err = iDownload->Delete(); //or Cancel or Reset? + FLOG(_L("Error = %d"),err); + + if(iDownloadFinalized == EFalse) + { + iFotaServer->FinalizeDownloadL( iDLState ); + FLOG(_L("Should not come here fro nopausable ")); + if (aReason == RFotaEngineSession::EResUserCancelled) + LaunchNotifierL(ESyncMLFwUpdOmaDLCancelled, EFalse, EFalse); + else if (aReason == RFotaEngineSession::EResUndefinedError) + LaunchNotifierL(ESyncMLFwUpdErrorNote, KErrGeneralNoResume, EFalse ); + } + FLOG(_L("CFotaDownload::RunDownloadCancelL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaDownload::RunDownloadSuspendL +// Starts to suspend the download operation +// -------------------------------------------------------------------------- +// +void CFotaDownload::RunDownloadSuspendL(const TInt aReason, TBool aSilent) + { + FLOG(_L("CFotaDownload::RunDownloadSuspendL, reason = %d, silent = %d >>"), aReason, aSilent); + + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + iDLState.iResult = aReason; + iSilentOpn = aSilent; + //First pause download, and later ask for user action. + TInt err = iDownload->Pause(); + + if (err) + { + //initial pausing becomes a problem. + FLOG(_L("Error while initial pausing...%d Hence download has to be cancelled permanently!"),err); + RunDownloadCancelL(aReason); + } + + FLOG(_L("CFotaDownload::RunDownloadSuspendL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaDownload::TryResumeDownloadL +// Tries to resume the download operation +// -------------------------------------------------------------------------- +// +void CFotaDownload::TryResumeDownloadL(TBool aUserInitiated) + { + FLOG(_L("CFotaDownload::TryResumeDownloadL >>")); + + iUserInitiatedResume = aUserInitiated; + TInt err = RProperty::Define( TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + RProperty::EInt,KReadPolicy,KWritePolicy); + FLOG(_L("RProperty KFotaDMRefresh Define, err = %d"), err); + if (err != KErrAlreadyExists ) + { + User::LeaveIfError(err); + } + //This P&S Key is used to notify DM UI on any download event. key=0 for idle and key=1 for download + err = RProperty::Set( TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + ETrue ); + FLOG(_L("RProperty KFotaDMRefresh Set ETrue, err = %d"), err); + + //Called to read the download variations in Fota (resume support & FMS) + CheckDownloadVariations(); + if (IsFMSEnabled() && iUserInitiatedResume) + iFotaServer->CancelFmsL(); + + //Query based on the type of DM session used earlier. + if (iUserInitiatedResume || iDLState.iSessionType != ESanSilent) + { + //Query user for resume + FLOG(_L("Quering user for resume...")); + if (iFotaServer->iNotifHandler) + { + iFotaServer->iNotifHandler->Cancel(); + delete iFotaServer->iNotifHandler; + iFotaServer->iNotifHandler = NULL; + } + iNotifHandler = CFotaDownloadNotifHandler::NewL(this); + + iNotifHandler->LaunchNotifierL(ESyncMLFwUpdOmaDLResume, EFalse, EFalse); + } + else //Only FMS initiated Silent Session download + { + //Resume directly + FLOG(_L("Resuming automatically...")); + ResumeDownloadL(); + } + FLOG(_L("CFotaDownload::TryResumeDownloadL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaDownload::ResumeDownloadL +// Resume the download operation +// -------------------------------------------------------------------------- +// +void CFotaDownload::ResumeDownloadL() + { + FLOG(_L("CFotaDownload::ResumeDownloadL >>")); + TBool toresetdl (EFalse); + TBool downloadiapvalid (ETrue); + //Find the download ui behavior from fota cenrep + TInt behavior(KErrNotFound); + CRepository* centrep = NULL; + TRAPD(err, centrep = CRepository::NewL( KCRUidFotaServer ) ); + if (( centrep ) && ( err == KErrNone)) + { + centrep->Get( KSilentOmaDlUIBehavior, behavior ); + delete centrep; + } + centrep = NULL; + + if (iUserInitiatedResume || + (behavior == EOmacdOffdlprgOn || behavior == EOmacdOndlprgOn)) + { + FLOG(_L("Showing Connecting progress note...")); + iFotaServer->iParentApp->SetUIVisibleL ( ETrue , EFalse ); + + if ( !iDLProgressDlg ) + { + iDLProgressDlg = new(ELeave) CFotaDLProgressDlg((CEikDialog** ) &iDLProgressDlg , EFalse, this, EConnectingNote ); + iDLProgressDlg->PrepareLC( R_CONNECTION_NOTE ); + } + // Load the resource files + TInt err = KErrNone; + + // Localize the file name, and load the SCP resources + TFileName resFile; + resFile.Copy( KDriveZ ); + resFile.Append( KSCPResourceFilename ); + + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), resFile ); + + TInt Res1(KErrNone); + TRAP( err, Res1 =CCoeEnv::Static()->AddResourceFileL( resFile ) ); + + HBufC* buf = StringLoader::LoadLC(R_SYNCSTATUS_SYNC_CONN); + + if( Res1 ) + { + iFotaServer->GetEikEnv()->DeleteResourceFile( Res1 ); + } + FLOG(_L("Reading txt as: %S"), &buf->Des()); + iDLProgressDlg->SetTextL(buf->Des()); + CleanupStack::PopAndDestroy(buf); + + iDLProgressDlg->RunLD(); + } + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 1")); + + iDownload = RetrieveDownloadL(); + if (iDownload) + { + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 2: Successfully retrieved download object >>")); + + SetIapToUseL(iDLState, iDLState.iIapId); + + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 3: Using iapid %d for resume..."), iDLState.iIapId); + downloadiapvalid = iFotaServer->CheckIapExistsL(iDLState.iIapId); + if (iDLState.iIapId > 0 && downloadiapvalid) + { + if (!iMonitor) + { + iMonitor = CFotaNetworkRegStatus::NewL (iFotaServer); + } + TBool val = iMonitor->IsConnectionPossibleL(iDLState.iIapId); + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 4")); + delete iMonitor; iMonitor = NULL; + +#if defined(__WINS__) + val =ETrue; +#endif + if (!val) + { + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 5.1: Disallowing resume operation as connection not possible")); + + if ( !iShowDLPrgUI && iDLProgressDlg ) + { + FLOG(_L("Removing Connecting progress note...")); + + iDLProgressDlg->ProcessFinishedL(); + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + if (iUserInitiatedResume || iDLState.iSessionType!=ESanSilent) + LaunchNotifierL(ESyncMLFwUpdErrorNote, KErrCommsLineFail2,0); + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + iDLState.iResult = RFotaEngineSession::EResDLFailDueToNWIssues; + iUpdateAfterDownload = EFalse; + iFotaServer->FinalizeDownloadL(iDLState); + return; + } + } + + if (iDLState.iIapId == KErrNotFound || !downloadiapvalid ) + { + iDLState.iIapId = KErrNotFound; + User::LeaveIfError( iDownloadMgr.SetIntAttribute( EDlMgrIap, 0)); // Download mgr interprets 0 for Always Ask + } + else + User::LeaveIfError( iDownloadMgr.SetIntAttribute( EDlMgrIap, iDLState.iIapId)); // IAP id + + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 5.2")); + SetDownloadUiBehavior(EFalse); + + if ( !iShowDLPrgUI && iDLProgressDlg ) + { + FLOG(_L("Removing Connecting progress note...")); + + iDLProgressDlg->ProcessFinishedL(); + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + TInt dlsize, tlsize; + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 6")); + iFotaServer->GetDownloadUpdatePackageSizeL(iDLState.iPkgId, dlsize,tlsize); + iDownloadedContentSize = dlsize; //for progress bar update only + iUpdateAfterDownload = iDLState.iUpdateLtr; //should update after reboot? + iRestartCounter = 0; + + //Set right states in fota db + iDLState.iState = RFotaEngineSession::EDownloadProgressingWithResume; + iDLState.iResult = KErrNotFound; + + iFotaServer->iDatabase->OpenDBL(); + iFotaServer->iDatabase->SetStateL( iDLState, KNullDesC8, EFDBState|EFDBResult); + iFotaServer->iDatabase->CloseAndCommitDB(); + iFreshDL = EFalse; + FLOG(_L("CFotaDownload::ResumeDownloadL, Stage 6: Starting to resume download now...")); + TInt err = iDownload->Start(); + if (err == KErrNone) + { + //Set the P&S Key to active... + FLOG(_L("Resume operation is success!")); + SetDownloadActive(ETrue); + } + else + { + FLOG(_L("An error occured during resume, err = %d"),err); + toresetdl = ETrue; + } + } + else + { + FLOG(_L("Failed to get the paused download object")); + if ( iDLProgressDlg ) + { + FLOG(_L("Removing Connecting progress note...")); + iDLProgressDlg->ProcessFinishedL(); // deletes itself + delete iDLProgressDlg; + iDLProgressDlg = NULL; + } + toresetdl = ETrue; + } + ReSetDownloadL( toresetdl); + + FLOG(_L("CFotaDownload::ResumeDownloadL <<")); + } +// -------------------------------------------------------------------------- +// CFotaDownload::ReSetDownloadL +// Sets the download state to failed +// -------------------------------------------------------------------------- +// +void CFotaDownload::ReSetDownloadL(TBool atoresetdl) +{ +if (atoresetdl) + { + FLOG(_L("Resetting fota download !!!")); + if (iUserInitiatedResume || iDLState.iSessionType!=ESanSilent) + LaunchNotifierL(ESyncMLFwUpdErrorNote, KErrGeneralNoResume,0); + iDLState.iState = RFotaEngineSession::EDownloadFailed; + iDLState.iResult = RFotaEngineSession::EResUndefinedError; + iUpdateAfterDownload = EFalse; + iFotaServer->FinalizeDownloadL(iDLState); + } +} + + + +// -------------------------------------------------------------------------- +// CFotaDownload::IsFMSEnabled +// Returns FMS enabled state +// -------------------------------------------------------------------------- +// +TBool CFotaDownload::IsFMSEnabled() + { + FLOG(_L("CFotaDownload::IsFMSEnabled, iFMSEnabled = %d <<"), iFMSEnabled); + return iFMSEnabled; + } + +// -------------------------------------------------------------------------- +// CFotaDownload::IsDownloadResumable +// Returns whether the download is resumable or not. +// -------------------------------------------------------------------------- +// +TBool CFotaDownload::IsDownloadResumable() + { + FLOG(_L("CFotaDownload::IsDownloadResumable, iDownloadResumable = %d <<"), iDownloadResumable); + return iDownloadResumable; + } + +// -------------------------------------------------------------------------- +// CFotaDownload::SetIapToUseL +// Sets the IAP ID to use. This menthod is used in fresh and resume download. +// -------------------------------------------------------------------------- +// +void CFotaDownload::SetIapToUseL(TPackageState aParams, const TInt aIapid) + { + FLOG(_L("CFotaDownload::SetIapToUseL >>")); + + RSyncMLSession sml; + TInt profIapid( KErrNotFound ); + TInt sockIapid( KErrNotFound ); + TSmlServerAlertedAction saa(ESmlConfirmSync); + + CleanupClosePushL( sml ); + sml.OpenL(); + iFotaServer->GetProfileDataL(&sml,aParams.iProfileId, profIapid, saa + ,iIsjobStartedFromUI, iSanValue ); + CleanupStack::PopAndDestroy( &sml ); + + // 2/3 GET IAP FROM ESOCK ---------------------------------------------- + // resolve which accespoint is used for current DM session + if ( (profIapid == KErrNotFound || profIapid == KErrGeneral) + && aIapid==KErrNotFound) + { + RSocketServ serv; + CleanupClosePushL( serv ); + User::LeaveIfError( serv.Connect() ); + + RConnection conn; + CleanupClosePushL( conn ); + User::LeaveIfError( conn.Open( serv ) ); + + TUint count( 0 ); + User::LeaveIfError( conn.EnumerateConnections ( count ) ); + // enumerate connections + for( TUint idx=1; idx<=count; ++idx ) + { + TConnectionInfo connectionInfo; + TConnectionInfoBuf connInfo( connectionInfo ); + + TInt err = conn.GetConnectionInfo( idx, connInfo ); // iapid + if( err != KErrNone ) + { + CleanupStack::PopAndDestroy( 2 ); // conn, serv + User::Leave( err ); + } + // enumerate connectionclients + TConnectionEnumArg conArg; + conArg.iIndex = idx; + TConnEnumArgBuf conArgBuf(conArg); + err=conn.Control(KCOLConnection,KCoEnumerateConnectionClients + ,conArgBuf); + if( err != KErrNone ) + { + CleanupStack::PopAndDestroy( 2 ); // conn, serv + User::Leave( err ); + } + TInt cliCount = conArgBuf().iCount; + for ( TUint j=1; j<=cliCount ;++j ) + { + TConnectionGetClientInfoArg conCliInfo; + conCliInfo.iIndex = j; + TConnGetClientInfoArgBuf conCliInfoBuf(conCliInfo); + err=conn.Control(KCOLConnection, KCoGetConnectionClientInfo + , conCliInfoBuf); + + if( err != KErrNone ) + { + CleanupStack::PopAndDestroy( 2 ); // conn, serv + User::Leave( err ); + } + TConnectionClientInfo conCliInf = conCliInfoBuf().iClientInfo; + TUid uid = conCliInf.iUid; + if ( uid == TUid::Uid(KSosServerUid) ) + { + sockIapid = connInfo().iIapId; + FLOG(_L("[FotaServer] IAP found %x"),sockIapid); + } + + FLOG(_L("[FotaServer] CFotaDownload::DownloadL uid %x") + ,uid.iUid); + } + } + CleanupStack::PopAndDestroy( 2 ); // conn, serv + } + TInt newIapid( KErrNotFound ); + if ( sockIapid!=KErrNotFound ) newIapid = sockIapid; + if ( profIapid!=KErrNotFound && profIapid != KErrGeneral ) newIapid = profIapid; + if ( aIapid !=KErrNotFound ) newIapid = aIapid; + + //Do some intelligent work during resume + /* Some rules.. + * 1. If IAP is always ask in DM profile, use the earlier set during FMS trigger + * 2. If IAP is always ask in DM profile, query user for IAP during user trigger + * 3. If IAP has changed in DM profile after suspend, use the newer one during resume + * 4. + */ + TInt active (KErrNotFound); + RProperty::Get(TUid::Uid(KFotaServerUid), KFotaDownloadActive, active ); + FLOG(_L("active = %d"),active); + if (active==EFalse && iDLState.iState == RFotaEngineSession::EDownloadProgressingWithResume) + { + //Actual resume only + if (!iUserInitiatedResume && (profIapid == KErrNotFound || profIapid == KErrGeneral ) ) + { + //FMS triggered resume, apply Rule 1 + newIapid = iDLState.iIapId; + } + else if (profIapid == KErrNotFound || profIapid == KErrGeneral ) + { + //User triggered resume, apply Rule 2 + newIapid = KErrNotFound; + } + else if (profIapid != iDLState.iIapId && profIapid > KErrNone) + { + //IAP has changed in DM profile, apply Rule 3 + newIapid = profIapid; + } + } + iDLState.iIapId = newIapid; + + + FLOG(_L("CFotaDownload::SetIapToUseL, iap = %d <<"), iDLState.iIapId); + } + +// -------------------------------------------------------------------------- +// CFotaDownload::SetDownloadUiBehavior +// Sets Download UI behavior. ex: DD display and Progress note +// -------------------------------------------------------------------------- +// +void CFotaDownload::SetDownloadUiBehavior(TBool aFreshDL) + { + FLOG(_L("CFotaDownload::SetDownloadUiBehavior, aFreshDL = %d >>"),aFreshDL); + + if (aFreshDL) //Fresh download + { + iDLState.iSessionType = iSanValue; + } + else //resuming download + { + iSanValue = iDLState.iSessionType; + } + + if ( !iIsjobStartedFromUI && iRestartCounter==0 ) //iRestartCounter to ensure that the UI behavior is read only once. + { + TInt behavior(KErrNotFound); + TInt sansupported(KErrNone); + + //Find whether SAN is supported or not + CRepository* centrep = NULL; + + TRAPD( err, centrep = CRepository::NewL( KCRUidDeviceManagementInternalKeys) ); + if( centrep ) centrep->Get( KDevManSANUIBitVariation, sansupported ); + delete centrep; centrep = NULL; + FLOG(_L("...1...")); + if (sansupported != 1) sansupported = 0; + + //Find the download ui behavior from fota cenrep + TRAP(err, centrep = CRepository::NewL( KCRUidFotaServer ) ); + if ( centrep ) centrep->Get( KSilentOmaDlUIBehavior, behavior ); + delete centrep; centrep = NULL; + + FLOG(_L("Values are... SAN enabled: %d, session type: %d, downloadbehavior: %d"),sansupported, iDLState.iSessionType,behavior); + + if (sansupported) //SAN is supported + { + + DetermineUISANON(behavior) ; + + } + else //SAN not supported + { + DetermineUISANOFF(behavior); + + } + } + else// if (iRestartCounter==0) //Started from DM UI, but not retry + { + iShowOMACDUI = ETrue; + iShowDLPrgUI = ETrue; + if (aFreshDL) + iDLState.iSessionType = KErrNotFound; + } + +TInt value (EFotaUpdateDM); +TInt err = RProperty::Get( KPSUidNSmlDMSyncApp, KNSmlCurrentFotaUpdateAppName, value ); +if (!err && ((value == EFotaUpdateNSC) || (value == EFotaUpdateNSCBg))) +{ + iShowOMACDUI = EFalse; + iShowDLPrgUI = ETrue; + FLOG(_L("CFotaDownload::DownloadL UI will not be shown!")); +} + FLOG(_L("UI Behavior: OMA DD Display = %d, Download Progress = %d"),iShowOMACDUI,iShowDLPrgUI); + + FLOG(_L("CFotaDownload::SetDownloadUiBehavior <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaDownload::DetermineUISANON +// Determine UI when SAN is ON +// -------------------------------------------------------------------------- +// +void CFotaDownload::DetermineUISANON(TInt aBehavior) +{ + switch (aBehavior) + { + case EOmacdOffdlprgOff: //0 + { + iShowOMACDUI = EFalse; + iShowDLPrgUI = EFalse; + } + break; + case EOmacdOffdlprgOn: //1 + { + iShowOMACDUI = EFalse; + iShowDLPrgUI = ETrue; + } + break; + case EOmacdOndlprgOff: //2 + { + iShowOMACDUI = ETrue; + iShowDLPrgUI = EFalse; + } + break; + case EOmacdOndlprgOn: //3 + { + iShowOMACDUI = ETrue; + iShowDLPrgUI = ETrue; + } + break; + default: //includes EChooseFromSan + { + if(iSanValue == ESanSilent) + { + iShowOMACDUI = EFalse; + iShowDLPrgUI = EFalse; + } + else if (iSanValue == ESanInformative) + { + iShowOMACDUI = EFalse; + iShowDLPrgUI = ETrue; + } + else //includes ESanInteractive, ESanNotSpecified + { + iShowOMACDUI = ETrue; + iShowDLPrgUI = ETrue; + } + } + break; + } + + +} + +// -------------------------------------------------------------------------- +// CFotaDownload::DetermineUISANOFF +// Determine UI when SAN is OFF +// -------------------------------------------------------------------------- +// + +void CFotaDownload::DetermineUISANOFF(TInt aBehavior) +{ + if (iSanValue==EAcceptedYes) //Accepted is Yes in Profile + { + switch (aBehavior) + { + case EOmacdOffdlprgOff: //0 + { + iShowOMACDUI = EFalse; + iShowDLPrgUI = EFalse; + } + break; + case EOmacdOffdlprgOn: //1 + { + iShowOMACDUI = EFalse; + iShowDLPrgUI = ETrue; + } + break; + case EOmacdOndlprgOff: //2 + { + iShowOMACDUI = ETrue; + iShowDLPrgUI = EFalse; + } + break; + default: //includes EOmacdOndlprgOn + { + iShowOMACDUI = ETrue; + iShowDLPrgUI = ETrue; + } + break; + } + } + else // includes iSanValue = EAcceptedNo (Accepted is No in profile) + { + iShowOMACDUI = ETrue; + iShowDLPrgUI = ETrue; + } +} + + + + + + + +// -------------------------------------------------------------------------- +// CFotaDownload::RetrieveDownloadL +// Retrieves the RHttpDownload object from download manager during resume +// -------------------------------------------------------------------------- +// +RHttpDownload* CFotaDownload::RetrieveDownloadL() + { + FLOG(_L("CFotaDownload::RetrieveDownloadL >>")); + //Retrieve RHttpDownload object for the suspended download from Download Mgr. + if (!iDownloadMgr.Handle()) + iDownloadMgr.ConnectL( TUid::Uid(KFotaServerUid) , *this, EFalse); + const CDownloadArray& downloads = iDownloadMgr.CurrentDownloads(); + + TBuf8 url8; + TInt32 val (KErrNone); + + RHttpDownload* aDownload (NULL); + for (TInt i = 0; i < downloads.Count(); i++ ) + { + User::LeaveIfError( downloads[i]->GetStringAttribute( EDlAttrCurrentUrl, url8 )); + User::LeaveIfError( downloads[i]->GetIntAttribute( EDlAttrFotaPckgId, val)); + + FLOG(_L("Current download(s) as per download mgr: %d, url = %S, pkgid = %d"), i+1, &url8, val); + + if (iDLState.iPkgId == val) + { + FLOG(_L("Successfully found the paused download object")); + aDownload = downloads[i]; + if ( iUrl ) {delete iUrl; iUrl=NULL;} + iUrl = url8.Alloc(); + + } + } + FLOG(_L("CFotaDownload::RetrieveDownloadL <<")); + return aDownload; + } + +// -------------------------------------------------------------------------- +// CFotaDownload::SetDownloadActive +// Sets the download activity state P&S key +// -------------------------------------------------------------------------- +// +void CFotaDownload::SetDownloadActive(TBool aValue) + { + FLOG(_L("CFotaDownload::SetDownloadActive, aValue = %d"),aValue); + iDownloadActive = aValue; + TBool val (EFalse); + TInt err = RProperty::Get(TUid::Uid(KFotaServerUid), KFotaDownloadActive, val ); + + if (err == KErrNone && val != aValue) + { + err = RProperty::Set(TUid::Uid(KFotaServerUid), KFotaDownloadActive, aValue ); + FLOG(_L("RProperty KFotaDownloadActive Set %d, err = %d"), aValue, err); + } + + FLOG(_L("CFotaDownload::SetDownloadActive <<")); + } + +// -------------------------------------------------------------------------- +// IsDownloadActive +// Returns the activeness of the download +// -------------------------------------------------------------------------- +// + +TBool CFotaDownload::IsDownloadActive() + { + FLOG(_L("CFotaDownload::IsDownloadActive, value = %d"),iDownloadActive); + return iDownloadActive; + } + + +// -------------------------------------------------------------------------- +// CFotaDownloadNotifHandler::NewL +// -------------------------------------------------------------------------- +// +CFotaDownloadNotifHandler* CFotaDownloadNotifHandler::NewL (CFotaDownload* aDownload) + { + FLOG(_L("CFotaDownloadNotifHandler::NewL")); + __ASSERT_ALWAYS( aDownload, User::Panic(KFotaPanic, KErrArgument) ); + CFotaDownloadNotifHandler* h=new (ELeave)CFotaDownloadNotifHandler; + h->iDownload = aDownload; + h->iDownload->iFotaServer->iNotifHandler = h; + return h; + } + +// -------------------------------------------------------------------------- +CFotaDownloadNotifHandler::CFotaDownloadNotifHandler() : CActive(EPriorityNormal) + { + FLOG(_L("CFotaDownloadNotifHandler::CFotaDownloadNotifHandler()")); + CActiveScheduler::Add( this ); + } + +// -------------------------------------------------------------------------- +CFotaDownloadNotifHandler::~CFotaDownloadNotifHandler() + { + FLOG(_L("CFotaDownloadNotifHandler::~CFotaDownloadNotifHandler >>")); + iNotifier.Close(); + Cancel(); + FLOG(_L("CFotaDownloadNotifHandler::~CFotaDownloadNotifHandler <<")); + } + +// -------------------------------------------------------------------------- +void CFotaDownloadNotifHandler::RunL() + { + FLOG(_L("CFotaDownloadNotifHandler::RunL() note:%d, param:%d" ),iNotifParams.iNoteType, iNotifParams.iIntParam); + + TBool reset (ETrue); + + iNotifier.Close(); + + iDownload->SetDownloadActive(EFalse); + if ( iNotifParams.iNoteType == ESyncMLFwUpdErrorNote ) // 1 + { + //do nothing here + } + if ( iNotifParams.iNoteType == ESyncMLFwUpdOmaDLNotEnoughMemory ) // 7 + { + //To be active as Flexible mem is in action. + if (iDownload->iFreshDL) + iDownload->SetDownloadActive(ETrue); + } + if ( iNotifParams.iNoteType == ESyncMLFwUpdOmaDLUserCancel ) + { + //At this point Download Mgr has already paused the download successfully. + if (iStatus.Int() == KErrCancel) //RSK Press + { + //User wants to cancel download permanently. + FLOG(_L("User choose to cancel download permanently!")); + iDownload->RunDownloadCancelL(RFotaEngineSession::EResUserCancelled); + } + else + { + //Other keys pressed, like LSK or Call termination key + FLOG(_L("User choose to resume download later, key press = %d"),iStatus.Int()); + iDownload->iFotaServer->FinalizeDownloadL( iDownload->iDLState ); + if (iStatus.Int() == KErrNone) //RSK is pressed + { + LaunchNotifierL(ESyncMLFwUpdOmaDLPostponed, EFalse, EFalse); + reset = EFalse; + } + else + iDownload->iFotaServer->ShutApp(); + } + } + + if ( iNotifParams.iNoteType == ESyncMLFwUpdOmaDLPostponed ) + { + //Nothing to do + } + + if ( iNotifParams.iNoteType == ESyncMLFwUpdOmaDLCancelled ) + { + //Nothing to do + } + + if ( iNotifParams.iNoteType == ESyncMLFwUpdOmaDLResume ) + { + if (iStatus.Int() == KErrNone) // LSK Press + { + FLOG(_L("User choose to continue download now.")); + iNotifParams.iNoteType = ESyncMLFwUpdUnknown; + iNotifParams.iIntParam = 0; + iDownload->ResumeDownloadL(); + reset = EFalse; + } + else //RSK or any other key + { + FLOG(_L("User cancelled to continue download now, key press = %d."),iStatus.Int()); + if (iStatus.Int() == KErrCancel) //RSK is pressed + { + iDownload->iDLState.iResult = RFotaEngineSession::EResUserCancelled; + LaunchNotifierL(ESyncMLFwUpdOmaDLUserCancel, EFalse, EFalse); + reset = EFalse; + } + else + iDownload->iFotaServer->ShutApp(); + } + } + + if (reset) + { + iNotifParams.iNoteType = ESyncMLFwUpdUnknown; + iNotifParams.iIntParam = 0; + } + } + +// -------------------------------------------------------------------------- +TInt CFotaDownloadNotifHandler::RunError(TInt aError) + { + FLOG(_L("CFotaDownloadNotifHandler::RunError %d"),aError); + return aError; + } + +// -------------------------------------------------------------------------- +void CFotaDownloadNotifHandler::DoCancel() + { + FLOG(_L("CFotaDownloadNotifHandler::DoCancel >>")); + if (iNotifier.Handle()) + { + iNotifier.CancelNotifier( KSyncMLFwUpdNotifierUid ); + iNotifier.Close(); + } + FLOG(_L("CFotaDownloadNotifHandler::DoCancel <<")); + } + +// -------------------------------------------------------------------------- +void CFotaDownloadNotifHandler::LaunchNotifierL( const TSyncMLFwUpdNoteTypes aNotetype + ,const TInt aIntParam + , const TInt aMemoryNeeded + ,TBool aFinishOnly) + { + FLOG(_L("CFotaDownloadNotifHandler::LaunchNotifierL, aNoteType=%d, aParam=%d, aMemoryNeeded=%d aFinishOnly=%d >> "), aNotetype, aIntParam, aMemoryNeeded, aFinishOnly?1:0); + + __ASSERT_ALWAYS( iNotifier.Handle()==0, User::Leave(KErrAlreadyExists) ); + __ASSERT_ALWAYS( aMemoryNeeded>=0, User::Leave(KErrArgument) ); + + + // Launch notifier + TSyncMLFwUpdNotifParams params; + FLOG(_L(" 1")); + params.iNoteType = aNotetype; + params.iIntParam = aIntParam; + + TInt rem = 0; + rem = aMemoryNeeded % 1024 ; + if (rem) + { + params.iMemoryNeeded = (aMemoryNeeded /1024) + 1; + } + else + { + params.iMemoryNeeded = (aMemoryNeeded /1024) ; + } + + // #endif + TSyncMLFwUpdNotifParamsPckg pckg(params); + iNotifParams.iNoteType = params.iNoteType; + iNotifParams.iIntParam = params.iIntParam; + + iNotifParams.iMemoryNeeded = params.iMemoryNeeded; + + iDummyResponsePckg = TSyncMLFwUpdNotifRetValPckg(); + FLOG(_L(" 2")); + if ( !aFinishOnly ) + { + User::LeaveIfError( iNotifier.Connect() ); + iNotifier.StartNotifierAndGetResponse( iStatus, KSyncMLFwUpdNotifierUid + , pckg, iDummyResponsePckg ); + SetActive(); + } + else + { + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + FLOG(_L(" 3 %d"),iStatus.Int()); + FLOG(_L("CFotaDownloadNotifHandler::LaunchNotifierL() <<")); + } + +TBool CFotaDownloadNotifHandler::IsOpen() + { + FLOG(_L("Handle = %d"), iNotifier.Handle()); + return (iNotifier.Handle())? ETrue:EFalse; + }