diff -r 000000000000 -r 96612d01cf9f videofeeds/livetvutils/src/CIptvDownload.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videofeeds/livetvutils/src/CIptvDownload.cpp Mon Jan 18 20:21:12 2010 +0200 @@ -0,0 +1,418 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Http download handler for epg plugin* +*/ + + + +#include "IptvLiveLogger.h" +#include "CIptvEpgService.h" +#include "CIptvDownload.h" +#include "MIptvDownloadObserver.h" +#include "CIptvLiveUIObjectTimer.h" + +// --------------------------------------------------------- +// CIptvDownload::NewL +// +// --------------------------------------------------------- +// +EXPORT_C CIptvDownload* CIptvDownload::NewL( MIptvDownloadObserver* aObserver ) + { + CIptvDownload* self = new (ELeave) CIptvDownload( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------- +// CIptvDownload::CIptvDownload +// +// --------------------------------------------------------- +// +CIptvDownload::CIptvDownload( MIptvDownloadObserver* aObserver ) : + iObserver( aObserver ), iConnected( EFalse ) + { + } + +// --------------------------------------------------------- +// CIptvDownload::~CIptvDownload +// +// --------------------------------------------------------- +// +CIptvDownload::~CIptvDownload() + { + if ( iConnected ) + { + iDownloadManager.RemoveObserver( *this ); + } + iDownloadManager.Close(); + iService = NULL; + + delete iTimer; + iTimer = NULL; + } + +// --------------------------------------------------------- +// CIptvDownload::ConstructL +// +// --------------------------------------------------------- +// +void CIptvDownload::ConstructL() + { + iTimer = CIptvLiveUIObjectTimer::NewL( this ); + } + +// --------------------------------------------------------- +// CIptvDownload::SetService +// +// --------------------------------------------------------- +// +EXPORT_C void CIptvDownload::SetService( CIptvEpgService* aService ) + { + iService = aService; + TRAPD( err, InitializeDownloadL() ); + if ( err != KErrNone ) + { + LIVE_TV_TRACE2(_L("CIptvDownload::SetService: InitializeDownloadL FAILED: %d"), err); + } + } + +// --------------------------------------------------------- +// CIptvDownload::DownloadL +// +// --------------------------------------------------------- +// +EXPORT_C void CIptvDownload::DownloadL( + TUid /*aUid*/, + const TDesC8& aUri, + TUint32 /*aIapId*/, + const TDesC& aFileName, + const TDesC& aETag, + const TDesC& aModifiedSince ) + { +#if defined( LIVE_TV_RDEBUG_TRACE ) || defined( LIVE_TV_FILE_TRACE ) + TName url; url.Copy( aUri ); + LIVE_TV_TRACE2( _L("CIptvDownload::DownloadL IN, aUri: %S"), &url ); +#endif // LIVE_TV_RDEBUG_TRACE || LIVE_TV_FILE_TRACE + + iFileName.Copy( aFileName ); + iDownloadETag.Copy( aETag ); + iDownloadLastModified.Copy( aModifiedSince ); + iUrl.Copy( aUri ); + + CreateDownloadL( aUri, EFalse ); + + LIVE_TV_TRACE1( _L("CIptvDownload::DownloadL OUT") ); + } + +// --------------------------------------------------------- +// CIptvDownload::CreateDownloadL +// +// --------------------------------------------------------- +// +void CIptvDownload::CreateDownloadL( + const TDesC8& aUri, + TBool aNoContentTypeCheck ) + { + LIVE_TV_TRACE1( _L("CIptvDownload::CreateDownloadL IN") ); + RHttpDownload &download = iDownloadManager.CreateDownloadL( aUri ); + User::LeaveIfError( download.SetStringAttribute( EDlAttrUsername, iService->iUserName ) ); + User::LeaveIfError( download.SetStringAttribute( EDlAttrPassword, iService->iPassword ) ); + User::LeaveIfError( download.SetStringAttribute( EDlAttrDestFilename, iFileName ) ); + User::LeaveIfError( download.SetBoolAttribute( EDlAttrNoContentTypeCheck, aNoContentTypeCheck ) ); + User::LeaveIfError( download.SetIntAttribute( EDlAttrAction, EMove ) ); + User::LeaveIfError( download.Start() ); + User::LeaveIfError( download.GetIntAttribute( EDlAttrId, iDownloadId ) ); + LIVE_TV_TRACE1( _L("CIptvDownload::CreateDownloadL OUT") ); + } + +// --------------------------------------------------------- +// CIptvDownload::HandleDMgrEventL +// +// --------------------------------------------------------- +// +void CIptvDownload::HandleDMgrEventL( + RHttpDownload& aDownload, + THttpDownloadEvent aEvent ) + { + LIVE_TV_TRACE3( _L("CIptvDownload::HandleDMgrEventL IN, aEvent.iProgress: %d, aEvent.iDownloadState %d"), aEvent.iProgressState, aEvent.iDownloadState ); + TBuf<50> responseETag; + TBuf<50> responseModifiedSince; + aDownload.GetStringAttribute( EDlAttrResponseETag, responseETag ); + aDownload.GetStringAttribute( EDlAttrEntityLastModified, responseModifiedSince ); + + switch (aEvent.iProgressState) + { + // Content type received + case EHttpContentTypeReceived: + LIVE_TV_TRACE1(_L("EHttpContentTypeReceived")); + // Compare old ETag and last modified values. Length check is done + // because if service provides neither ETag nor last modified time + // we need to run update cause there is no data to verify the match. + if( ( responseETag.Length() > 0 && iDownloadETag.Compare( responseETag ) == 0 ) || + ( responseModifiedSince.Length() > 0 && iDownloadLastModified.Compare( responseModifiedSince ) == 0 ) ) + { + // Delete download asynchronously and signalize the observer + // that data is up to date -> no need to download + iDlError = EIptvDlContentUnchanged; + DeleteDownloadAsyncL(); + } + // Neither ETag nor last modified values didn't match -> do download + else + { + // Content has changed. Delete this download and create a new to get + // content. + iRestartDownloadAfterDeletion = ETrue; + DeleteDownloadAsyncL(); + } + break; + + case EHttpProgDisconnected: + { + LIVE_TV_TRACE1(_L("EHttpProgDisconnected")); + TIptvDlError dlError( EIptvDlNoError ); + ResolveDownloadErrorCode( aDownload, dlError ); + // Connection lost, current Download Manager version sends + // this progress state if connection is stopped right after the + // download is initialized and started. In that case it never + // sends the EHttpDlFailed so lets finish our work here: + iDlError = dlError; + DeleteDownloadAsyncL(); + } + break; + + default: + break; + } + + switch (aEvent.iDownloadState) + { + case EHttpDlCompleted: + { + LIVE_TV_TRACE1(_L("EHttpDlCompleted")); + iDlError = KErrNone; + DeleteDownloadAsyncL(); + // Send new modified since and ETag to the caller + iObserver->SetModifiedSinceAndETag( responseModifiedSince, responseETag ); + // Set the values to an empty strings. These strings are re-set at + // DownloadL method with the values given by the caller. + iDownloadLastModified.Zero(); + iDownloadETag.Zero(); + } + break; + + case EHttpDlFailed: + { + LIVE_TV_TRACE1(_L("EHttpDlFailed")); + TIptvDlError dlError( EIptvDlNoError ); + ResolveDownloadErrorCode( aDownload, dlError ); + iDlError = dlError; + DeleteDownloadAsyncL(); + // Set the values to an empty strings. These strings are re-set at + // DownloadL method with the values given by the caller. + iDownloadLastModified.Zero(); + iDownloadETag.Zero(); + } + break; + default: + break; + } + } + +// --------------------------------------------------------- +// CIptvDownload::TimerFires +// +// --------------------------------------------------------- +// +void CIptvDownload::TimerFires() + { + LIVE_TV_TRACE1( _L("CIptvDownload::TimerFires IN") ); + + if( iDeleteDownloadTimerRunning ) + { + iDeleteDownloadTimerRunning = EFalse; + LIVE_TV_TRACE1( _L("CIptvDownload::TimerFires() Deleting the download.") ); + + TInt count = iDownloadManager.CurrentDownloads().Count(); + TInt32 downloadId; + for ( TInt i = 0; i < count; i++ ) + { + iDownloadManager.CurrentDownloads()[i]->GetIntAttribute( + EDlAttrId, downloadId ); + if ( downloadId == iDownloadId ) + { + RHttpDownload* dl = iDownloadManager.CurrentDownloads()[i]; + if ( dl ) + { + dl->Delete(); + } + } + } + + if( iRestartDownloadAfterDeletion ) + { + // Create new download. + iRestartDownloadAfterDeletion = EFalse; + TRAP( iDlError, CreateDownloadL( iUrl, ETrue ) ); // No content type check + if( iDlError != KErrNone ) + { + LIVE_TV_TRACE2( _L("CIptvDownload::TimerFires() Error creating download: %d."), iDlError ); + iObserver->DownloadFinished( iDlError ); + } + } + else + { + // Inform observer that download is finished. + LIVE_TV_TRACE2( _L("CIptvDownload::TimerFires() Sending %d to observer."), iDlError ); + iObserver->DownloadFinished( iDlError ); + } + } + LIVE_TV_TRACE1( _L("CIptvDownload::TimerFires OUT") ); + } + +// --------------------------------------------------------- +// CIptvDownload::TimerError +// +// --------------------------------------------------------- +// +void CIptvDownload::TimerError( const TInt aError ) + { + TRAP_IGNORE( HandleTimerErrorL( aError ) ); + } + +// --------------------------------------------------------- +// CIptvDownload::HandleTimerErrorL +// +// --------------------------------------------------------- +// +void CIptvDownload::HandleTimerErrorL( const TInt aError ) + { + LIVE_TV_TRACE1( _L("CIptvDownload::HandleTimerErrorL IN") ); + + // Start the timer in case of error + if ( aError == KErrOverflow || aError == KErrUnderflow ) + { + delete iTimer; + iTimer = NULL; + iTimer = CIptvLiveUIObjectTimer::NewL( this ); + iDeleteDownloadTimerRunning = ETrue; + iTimer->After(1); + } + + LIVE_TV_TRACE1( _L("CIptvDownload::HandleTimerErrorL OUT") ); + } + +// --------------------------------------------------------- +// CIptvDownload::InitializeDownloadL +// +// --------------------------------------------------------- +// +void CIptvDownload::InitializeDownloadL() + { + iDownloadManager.ConnectL( iService->iUid, *this, EFalse ); + iConnected = ETrue; + User::LeaveIfError( iDownloadManager.SetIntAttribute( + EDlMgrIap, iService->iIap ) ); + User::LeaveIfError( iDownloadManager.SetBoolAttribute( + EDlMgrSilentMode, ETrue ) ); + } + +// --------------------------------------------------------- +// CIptvDownload::ResolveDownloadErrorCode +// +// --------------------------------------------------------- +// +void CIptvDownload::DeleteDownloadAsyncL() + { + delete iTimer; + iTimer = NULL; + iTimer = CIptvLiveUIObjectTimer::NewL( this ); + iDeleteDownloadTimerRunning = ETrue; + iTimer->After(1); + } + +// --------------------------------------------------------- +// CIptvDownload::ResolveDownloadErrorCode +// +// --------------------------------------------------------- +// +void CIptvDownload::ResolveDownloadErrorCode( + RHttpDownload& aDownload, + TIptvDlError& aError ) const + { + TInt32 errorId( 0 ); + TInt32 globalErrorId( 0 ); + // Get errors from aDownload object + aDownload.GetIntAttribute(EDlAttrErrorId, errorId); + aDownload.GetIntAttribute(EDlAttrGlobalErrorId, globalErrorId); + LIVE_TV_TRACE3(_L("CIptvDownload::ResolveDownloadErrorCode: errorId: %d, globalErrorId: %d"), errorId, globalErrorId); + + // Handle error + switch( errorId ) + { + case EConnectionFailed: + aError = EIptvDlConnectionFailed; + break; + + case EHttpAuthenticationFailed: + aError = EIptvDlAuthFailed; + break; + + case EProxyAuthenticationFailed: + aError = EIptvDlProxyAuthFailed; + break; + + case EDestFileInUse: + aError = EIptvDlDestFileInUse; + break; + + case EBadUrl: + aError = EIptvDlBadUrl; + break; + + case EMMCRemoved: + aError = EIptvDlMmcRemoved; + break; + + case EDiskFull: + aError = EIptvDlDiskFull; + break; + + case EObjectNotFound: + aError = EIptvDlContentNotFound; + break; + + case ETransactionFailed: + { + if ( globalErrorId == KErrCancel ) + { + // Connection stopped + aError = EIptvDlDisconnected; + } + else + { + aError = EIptvDlGeneral; + } + } + break; + + default: + aError = EIptvDlGeneral; + break; + } + } + + +// End of file