--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videofeeds/mrssplugin/src/CIptvRssDownload.cpp Mon Jan 18 20:21:12 2010 +0200
@@ -0,0 +1,1335 @@
+/*
+* Copyright (c) 2004-2008 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:
+*
+*/
+
+
+
+
+#include <e32std.h>
+#include <sysutil.h>
+#include "IptvDebug.h"
+#include <bautils.h>
+#include "CIptvTimer.h"
+#include "CIptvRssDownload.h"
+#include "CIptvRssPlugin.h"
+#include "CIptvEpgService.h"
+#include "CIptv3XmlContentHandler.h"
+#include "ciptvxmldatetime.h"
+
+// 0x10281F1E is the uid of the IptvUtil dll. This is taken
+// into use by reason following:
+// There can be two simultaneous RSS downloads ongoing at the
+// same time; one for search and one for vod. Download manager
+// prevents simultaneous downloads if uid given during Connect
+// is already active. That's why we take another uid into use
+// to allow search operations to run simultaneously with the
+// normal vod update.
+const TUid KIptvSearchUid = { 0x10281F1E };
+
+const TInt KIptvMaxTimeoutInSeconds( 60 );
+const TInt KIptvMaxPauseInSeconds( 10 );
+
+const TInt KIptvTime_1_second( 1000000 );
+const TInt KIptvTime_200_microsecond( 200 );
+
+// ======== MEMBER FUNCTIONS ========
+
+// --------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::ConstructL()
+ {
+ iTimer = CIptvTimer::NewL( CActive::EPriorityUserInput, *this );
+ }
+
+// --------------------------------------------------------------------------
+// Two-phased constructor.
+// Create instance of concrete interface implementation
+// --------------------------------------------------------------------------
+//
+CIptvRssDownload* CIptvRssDownload::NewL(
+ CIptvRssPlugin& aPlugin,
+ RFs& aFs,
+ CIptvXmlContentHandler& aXmlContentHandler )
+ {
+ CIptvRssDownload* self = new( ELeave ) CIptvRssDownload(
+ aPlugin,
+ aFs,
+ aXmlContentHandler );
+ CleanupStack::PushL( self );
+
+ self->ConstructL();
+
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// Destructor
+// --------------------------------------------------------------------------
+//
+CIptvRssDownload::~CIptvRssDownload()
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::~CIptvRssDownload" );
+
+ if ( iTimer )
+ {
+ if ( iTimer->IsActive() )
+ {
+ iTimer->Cancel();
+ }
+ delete iTimer;
+ iTimer = NULL;
+ }
+
+ Disconnect();
+
+ iService = NULL;
+
+ delete iDlDeleteTimer;
+ delete iFileName;
+ delete iUri;
+ delete iETag;
+
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::~CIptvRssDownload exit" );
+ }
+
+// --------------------------------------------------------------------------
+// C++ default constructor
+// --------------------------------------------------------------------------
+//
+CIptvRssDownload::CIptvRssDownload(
+ CIptvRssPlugin& aPlugin,
+ RFs& aFs,
+ CIptvXmlContentHandler& aXmlContentHandler ) :
+ iService( NULL ),
+ iPlugin( aPlugin ),
+ iThumbnail( EFalse ),
+ iDownloadId( 0 ),
+ iTimer( NULL ),
+ iConnected( EFalse ),
+ iState( ENormal ),
+ iPauseCounter( 0 ),
+ iFs( aFs ),
+ iXmlContentHandler( aXmlContentHandler )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// Start download.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::DownloadL(
+ const TDesC8& aUri,
+ const TDesC& aFileName,
+ TBool aThumbnail,
+ const TDesC& aETag,
+ const TTime& aLastUpdated )
+ {
+ if ( iState != ENormal && iState != EFinished )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL Busy Leave" );
+ User::Leave( KErrAlreadyExists );
+ }
+ if ( ( 0 == aFileName.Length() ) || ( 0 == aUri.Length() ) )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL Argument Leave" );
+ User::Leave( KErrArgument );
+ }
+ ChangeState( ENormal );
+
+#ifdef _DEBUG
+
+ // Debug print filename.
+ TBuf<KIptvMaxPath> debugFileName;
+ debugFileName.Copy( aFileName );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL aFileName : %S",
+ &debugFileName );
+
+ // Debug print Uri.
+ TBuf<KIptvUrlMaxLength> debugUri;
+ debugUri.Copy( aUri );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL aUri : %S",
+ &debugUri );
+
+#endif
+
+ // When header information is given, fist dowload will fetch these values
+ // for check. Thumbnail file must also exist to enable check.
+ iWaitingContentTypeCheck =
+ ( ( 0 != aETag.CompareC( KIptvEmptyDes ) ) ||
+ ( TTime( 0LL ) != aLastUpdated ) ) &&
+ !iDisableLastModifiedCheck &&
+ ( !aThumbnail || BaflUtils::FileExists( iFs, aFileName ) );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL Content type check: %d",
+ iWaitingContentTypeCheck );
+
+ // Store argument data for further use.
+ if ( iUri )
+ {
+ delete iUri;
+ iUri = NULL;
+ }
+ iUri = HBufC8::NewL( aUri.Length() );
+ iUri->Des().Copy( aUri );
+
+ if ( iFileName )
+ {
+ delete iFileName;
+ iFileName = NULL;
+ }
+ iFileName = HBufC::NewL( aFileName.Length() );
+ iFileName->Des().Copy( aFileName );
+
+ if ( iETag )
+ {
+ delete iETag;
+ iETag = NULL;
+ }
+ if ( 0 < aETag.Length() )
+ {
+ iETag = HBufC::NewL( aETag.Length() );
+ iETag->Des().Copy( aETag );
+ }
+
+ iLastUpdated = aLastUpdated;
+ iThumbnail = aThumbnail;
+
+ // When no check, old thumbnail can be removed at once.
+ if ( iThumbnail && iFileName && !iWaitingContentTypeCheck )
+ {
+ iPlugin.RemoveIconFromList( iFileName, ETrue );
+ }
+
+ // Create new download.
+ RHttpDownload& download =
+ iDownloadManager.CreateDownloadL( aUri );
+
+ // Set download attributes.
+ download.SetBoolAttribute( EDlAttrNoContentTypeCheck, !iWaitingContentTypeCheck );
+ SetAuthenticationInformationL( download );
+ if ( !iWaitingContentTypeCheck )
+ {
+ // Content check will not require filename and DownloadManager would anyway
+ // delete it.
+ download.SetStringAttribute( EDlAttrDestFilename, aFileName );
+ }
+
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL Using IAP: %d",
+ iService->iIap );
+ User::LeaveIfError(
+ iDownloadManager.SetIntAttribute( EDlMgrIap, iService->iIap ) );
+
+ // Start download.
+ User::LeaveIfError( download.Start() );
+ download.GetIntAttribute( EDlAttrId, iDownloadId );
+ iDownloadIdValid = ETrue;
+ }
+
+// --------------------------------------------------------------------------
+// Restart download.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::DownloadL()
+ {
+ if ( iState != ENormal && iState != EFinished )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL Busy Leave" );
+ User::Leave( KErrAlreadyExists );
+ }
+ if ( !iFileName || !iUri )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL Argument Leave" );
+ User::Leave( KErrArgument );
+ }
+ ChangeState( ENormal );
+
+#ifdef _DEBUG
+
+ // Debug print filename.
+ TBuf<KIptvMaxPath> debugFileName;
+ debugFileName.Copy( iFileName->Des() );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL aFileName : %S",
+ &debugFileName );
+
+#endif
+
+ iWaitingContentTypeCheck = EFalse;
+
+ // Create new download.
+ RHttpDownload& download =
+ iDownloadManager.CreateDownloadL( iUri->Des() );
+
+ // Set download attributes.
+ download.SetBoolAttribute( EDlAttrNoContentTypeCheck, ETrue );
+ SetAuthenticationInformationL( download );
+ download.SetStringAttribute( EDlAttrDestFilename, iFileName->Des() );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DownloadL Using IAP: %d",
+ iService->iIap );
+ User::LeaveIfError(
+ iDownloadManager.SetIntAttribute( EDlMgrIap, iService->iIap ) );
+
+ // Start download.
+ User::LeaveIfError( download.Start() );
+ download.GetIntAttribute( EDlAttrId, iDownloadId );
+ iDownloadIdValid = ETrue;
+ }
+
+// --------------------------------------------------------------------------
+// From MHttpDownloadMgrObserver.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::HandleDMgrEventL(
+ RHttpDownload& aDownload,
+ THttpDownloadEvent aEvent )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL" );
+
+ // In EThumbnail and ENoDiskSpace states we do not need to do anything
+ // for new events. We are just waiting for our timer to step in.
+ // When iTimer is NULL, we are shutting down.
+ if ( ( iState == EThumbnail ) || ( iState == ENoDiskSpace ) || !iTimer || iDlDeleteTimer )
+ {
+ return;
+ }
+
+ //lint -e{961} Else block not needed, default is no operation.
+ if ( iState == EPause )
+ {
+ iTimer->Cancel();
+ ChangeState( ENormal );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL PAUSED %d SECONDS, NOW CONTINUING!",
+ iPauseCounter );
+ iPauseCounter = 0;
+ }
+ else if ( iState == EWaiting )
+ {
+ iTimer->Cancel();
+ ChangeState( ENormal );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL WAITED EVENTS FROM DL-MANAGER %d SECONDS",
+ iPauseCounter );
+ iPauseCounter = 0;
+ }
+ else if ( iState == ETimeout )
+ {
+ if ( aEvent.iDownloadState == EHttpDlCreated )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL download state was EHttpDlCreated." );
+ ChangeState( ENormal );
+ iPauseCounter = 0;
+ }
+ else
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL iState == ETimeout -> return" );
+ return;
+ }
+ }
+
+ TInt32 fileSizeReported = 0;
+ aDownload.GetIntAttribute( EDlAttrUserData, fileSizeReported );
+
+ // We keep checking file size until it is available in EDlAttrLength.
+ if ( fileSizeReported == 0 )
+ {
+ TInt32 fullSize = 0;
+
+ aDownload.GetIntAttribute( EDlAttrLength, fullSize );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL Full size: %d", fullSize );
+
+ if ( fullSize > 0 )
+ {
+ aDownload.SetIntAttribute( EDlAttrUserData, ETrue );
+
+ // For thumbnails, we check if size of file exceeds the maximum
+ // allowed. If it does, the file is not downloaded at all.
+ if ( iThumbnail && fullSize > KIptvRssMaxThumbnailSize )
+ {
+ IPTVLOGSTRING3_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL Thumbnail too big %d, max size %d, download cancelled!!!",
+ fullSize,
+ KIptvRssMaxThumbnailSize );
+
+#ifdef _DEBUG
+
+ switch ( iState )
+ {
+ case ENormal:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL iState changed from ENormal -> EThumbnail" );
+ break;
+
+ case EThumbnail:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL iState changed from EThumbnail -> EThumbnail" );
+ break;
+
+ case EFinished:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL iState changed from EFinished -> EThumbnail" );
+ break;
+
+ default:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL iState changed from ? -> EThumbnail" );
+ break;
+ }
+
+#endif // _DEBUG
+
+ iState = EThumbnail;
+
+ if ( iTimer )
+ {
+ iTimer->Cancel();
+ iTimer->After( KIptvTime_200_microsecond );
+ return;
+ }
+ }
+ // For all other files, those that will be actually downloaded,
+ // we check that we don't exceed critical disk space levels.
+ else
+ {
+ TBool checkResult = EFalse;
+ TRAPD( checkError, checkResult =
+ SysUtil::DiskSpaceBelowCriticalLevelL(
+ &iFs, static_cast<TInt64>(fullSize), EDriveC ) );
+ if ( checkError != KErrNone || checkResult )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL Disk space under critical level!!!" );
+
+ ChangeState( ENoDiskSpace );
+
+ if ( iTimer )
+ {
+ iTimer->Cancel();
+ iTimer->After( KIptvTime_200_microsecond );
+ return;
+ }
+ }
+
+#ifdef _DEBUG
+
+ else
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL Disk space ok." );
+ }
+
+#endif // _DEBUG
+
+ }
+ }
+ }
+
+ switch ( aEvent.iProgressState )
+ {
+ case EHttpContentTypeReceived:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpContentTypeReceived" );
+
+ // Fetch header info to find out whether item has bee updated.
+ TBuf<KMaxGeneralHeaderFieldLength> responseETag;
+ TBuf<KMaxGeneralHeaderFieldLength> responseModifiedSince;
+ aDownload.GetStringAttribute( EDlAttrResponseETag, responseETag );
+ aDownload.GetStringAttribute( EDlAttrEntityLastModified, responseModifiedSince );
+ iWaitingContentTypeCheck = EFalse;
+
+ // Compare header info.
+ TBool eTagMatch( EFalse );
+ if ( iETag )
+ {
+ if ( responseETag.Length() > 0 )
+ {
+ eTagMatch = ( responseETag.Compare( iETag->Des() ) == 0 );
+
+ IPTVLOGSTRING2_LOW_LEVEL( "EDlAttrResponseETag : %S",
+ &responseETag );
+ IPTVLOGSTRING2_LOW_LEVEL( "Local eTag valid : %d",
+ eTagMatch );
+ }
+
+ delete iETag;
+ iETag = NULL;
+ iETag = HBufC::NewL( responseETag.Length() );
+ iETag->Des().Copy( responseETag );
+ }
+
+ TBool modifiedSinceMatch( EFalse );
+ if ( responseModifiedSince.Length() > 0 )
+ {
+ TTime lastUpdated( static_cast<TUint64>( 0 ) );
+
+ // Parse time string to TTime
+ HBufC* lastUpdatedStr = HBufC::NewLC( responseModifiedSince.Length() );
+ lastUpdatedStr->Des().Copy( responseModifiedSince );
+ CIptvXmlDateTime::ParseGmtL( lastUpdatedStr, lastUpdated );
+ CleanupStack::PopAndDestroy( lastUpdatedStr );
+
+ modifiedSinceMatch = lastUpdated <= iLastUpdated;
+
+#ifdef _DEBUG
+
+ // Debug print last updated info.
+ TBuf<KIptvEpgDbLastModifiedMaxLength> ecgDatePrint;
+ TBuf<KIptvEpgDbLastModifiedMaxLength> itemDatePrint;
+ _LIT( KIptvDatePrint, "%D%M%Y%/0%1%/1%2%/2%3%/3" );
+ iLastUpdated.FormatL( ecgDatePrint, KIptvDatePrint );
+ lastUpdated.FormatL( itemDatePrint, KIptvDatePrint );
+
+ TBuf<KIptvEpgDbLastModifiedMaxLength> ecgTimePrint;
+ TBuf<KIptvEpgDbLastModifiedMaxLength> itemTimePrint;
+ _LIT( KIptvTimePrint, "%-B%:0%J%:1%T%:2%S%.%*C4%:3%+B" );
+ iLastUpdated.FormatL( ecgTimePrint, KIptvTimePrint );
+ lastUpdated.FormatL( itemTimePrint, KIptvTimePrint );
+
+ IPTVLOGSTRING2_LOW_LEVEL( "EDlAttrEntityLastModified : %S",
+ &responseModifiedSince );
+ IPTVLOGSTRING3_LOW_LEVEL( "Local entity was last updated : %S %S",
+ &ecgDatePrint,
+ &ecgTimePrint );
+ IPTVLOGSTRING3_LOW_LEVEL( "Server entity was last updated : %S %S",
+ &itemDatePrint,
+ &itemTimePrint );
+ IPTVLOGSTRING2_LOW_LEVEL( "Local entity valid : %d",
+ modifiedSinceMatch );
+
+#endif
+
+ iLastUpdated = lastUpdated;
+
+ }
+ else
+ {
+ iLastUpdated = TTime( static_cast<TUint64>( 0 ) );
+ }
+
+
+ if ( eTagMatch || modifiedSinceMatch )
+ {
+ // Download headers match, no download required.
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL: Headers match to previous." );
+ iDlStatus = EDownloadNoNeed;
+ iDlError = EIptvDlNoError;
+
+ DeleteDownloadAsyncL();
+
+ // Retain old Thumbnail and remove it from list.
+ if ( iThumbnail && iFileName )
+ {
+ iPlugin.RemoveIconFromList( iFileName, EFalse );
+ }
+ }
+ else
+ {
+ // Download headers do not match.
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL: Headers do not match." );
+ iDlStatus = EDownloadNeeded;
+ iDlError = EIptvDlNoError;
+ ChangeState( ENormal );
+ iRestartDownload = ETrue;
+
+ // When service will not support header info, do not request it further.
+ if ( ( 0 == responseETag.Length() ) &&
+ ( 0 == responseModifiedSince.Length() ) )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL: Further header check disabled." );
+ iDisableLastModifiedCheck = ETrue; // Suppress further check
+ }
+
+ DeleteDownloadAsyncL();
+
+ if ( iFileName )
+ {
+ // Delete old Thumbnail if exists and remove it from list.
+ if ( iThumbnail )
+ {
+ iPlugin.RemoveIconFromList( iFileName, ETrue );
+ }
+ else
+ {
+ // Delete old file if exist.
+ if ( BaflUtils::FileExists( iFs, iFileName->Des() ) )
+ {
+ iFs.Delete( iFileName->Des() );
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case EHttpProgNone:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgNone" );
+ }
+ break;
+
+ case EHttpStarted:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpStarted" );
+ }
+ break;
+
+ case EHttpProgCreatingConnection:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgCreatingConnection" );
+ }
+ break;
+
+ case EHttpProgConnectionNeeded:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgConnectionNeeded" );
+ }
+ break;
+
+ case EHttpProgConnected:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgConnected" );
+ }
+ break;
+
+ case EHttpProgConnectionSuspended:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgConnectionSuspended" );
+ }
+ break;
+
+ case EHttpProgDisconnected:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgDisconnected" );
+ }
+ break;
+
+ case EHttpProgDownloadStarted:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgDownloadStarted" );
+ }
+ break;
+
+ case EHttpContentTypeRequested:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpContentTypeRequested" );
+ }
+ break;
+
+ case EHttpProgSubmitIssued:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgSubmitIssued" );
+ }
+ break;
+
+ case EHttpProgResponseHeaderReceived:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgResponseHeaderReceived" );
+ }
+ break;
+
+ case EHttpProgResponseBodyReceived:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgResponseBodyReceived" );
+ }
+ break;
+
+ case EHttpProgRedirectedPermanently:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgRedirectedPermanently" );
+ }
+ break;
+
+ case EHttpProgRedirectedTemporarily:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgRedirectedTemporarily" );
+ }
+ break;
+
+ case EHttpProgDlNameChanged:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgDlNameChanged" );
+ }
+ break;
+
+ case EHttpProgContentTypeChanged:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgContentTypeChanged" );
+ }
+ break;
+
+ case EHttpProgCodDescriptorDownloaded:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgCodDescriptorDownloaded" );
+ }
+ break;
+
+ case EHttpProgCodDownloadStarted:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgCodDownloadStarted" );
+ }
+ break;
+
+ case EHttpProgCodDescriptorAccepted:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgCodDescriptorAccepted" );
+ }
+ break;
+
+ case EHttpProgCodLoadEnd:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgCodLoadEnd" );
+ }
+ break;
+
+ case EHttpProgSupportedMultiPart:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL HttpProgSupportedMultiPart" );
+ }
+ break;
+
+ case EHttpProgMovingContentFile:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgMovingContentFilep" );
+ }
+ break;
+
+ case EHttpProgContentFileMoved:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpProgContentFileMoved" );
+ }
+ break;
+
+ default:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL Unknown state" );
+ break;
+ }
+ }
+
+ switch ( aEvent.iDownloadState )
+ {
+ case EHttpDlCompleted:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlCompleted" );
+ iDlStatus = EDownloadSucceeded;
+ iDlError = EIptvDlNoError;
+ DeleteDownloadAsyncL();
+ }
+ break;
+
+ case EHttpDlFailed:
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlFailed" );
+ // When header download failed, we can still retry actual download.
+ if ( iWaitingContentTypeCheck )
+ {
+ iDlStatus = EDownloadNeeded;
+ iDlError = EIptvDlNoError;
+ ChangeState( ENormal );
+
+ // Delete old Thumbnail and remove it from list.
+ if ( iThumbnail && iFileName )
+ {
+ iPlugin.RemoveIconFromList( iFileName, ETrue );
+ }
+
+ iRestartDownload = ETrue;
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL Further header check disabled." );
+ iDisableLastModifiedCheck = ETrue; // Suppress further check
+ iWaitingContentTypeCheck = EFalse;
+ DeleteDownloadAsyncL();
+ }
+ else
+ {
+ GetDownloadErrorCode( aDownload, iDlError );
+ // No state change, when only progress information.
+ if ( EIptvDlNoError != iDlError )
+ {
+ iDlStatus = EDownloadFailed;
+ DeleteDownloadAsyncL();
+ }
+ }
+ }
+ break;
+
+ case EHttpDlCreated:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlCreated" );
+ break;
+
+ case EHttpDlInprogress:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlInprogress" );
+ break;
+
+ case EHttpDlPaused:
+ {
+ // Ignore paused state when content type is received because download is finished earlier.
+ if ( aEvent.iProgressState != EHttpContentTypeReceived )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlPaused" );
+
+ ChangeState( EPause );
+
+ if ( iTimer )
+ {
+ if ( !iTimer->IsActive() )
+ {
+ iTimer->After( KIptvTime_1_second );
+ }
+ }
+ }
+ }
+ break;
+
+ case EHttpDlMoved:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlMoved" );
+ break;
+
+ case EHttpDlMediaRemoved:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlMediaRemoved" );
+ break;
+
+ case EHttpDlMediaInserted:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlMediaInserted" );
+ break;
+
+ case EHttpDlPausable:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlPausable" );
+ break;
+
+ case EHttpDlNonPausable:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlNonPausable" );
+ break;
+
+ case EHttpDlDeleted:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlDeleted" );
+ break;
+
+ case EHttpDlAlreadyRunning:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlAlreadyRunning" );
+ break;
+
+ case EHttpDlDeleting:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlDeleting" );
+ break;
+
+ case EHttpDlCancelTransaction:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL EHttpDlCancelTransaction" );
+ break;
+
+ default:
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL Unknown state" );
+ break;
+ }
+
+ if ( iState == ENormal )
+ {
+ ChangeState( EWaiting );
+ if ( iTimer )
+ {
+ if ( !iTimer->IsActive() )
+ {
+ iTimer->After( KIptvTime_1_second );
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// Set authentication information.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::SetAuthenticationInformationL(
+ RHttpDownload& aDownload ) const
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::SetAuthenticationInformation" );
+
+ User::LeaveIfError(
+ aDownload.SetStringAttribute( EDlAttrUsername, iUserName ) );
+ User::LeaveIfError(
+ aDownload.SetStringAttribute( EDlAttrPassword, iPassword ) );
+ }
+
+// --------------------------------------------------------------------------
+// Set service information.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::SetServiceInformation( CIptvEpgService* aService )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::SetServiceInformation" );
+
+ iService = aService;
+
+ if ( aService )
+ {
+ iUserName.Copy( aService->iUserName );
+ iPassword.Copy( aService->iPassword );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// Initialize plugin.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::InitializeL()
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::InitializeL" );
+
+ if ( !iConnected )
+ {
+ if ( iPlugin.IsSearchOperation() )
+ {
+ iDownloadManager.ConnectL( KIptvSearchUid, *this, ETrue );
+ }
+ else
+ {
+ iDownloadManager.ConnectL( iService->iUid, *this, ETrue );
+ }
+ iConnected = ETrue;
+ }
+
+ iDownloadManager.DeleteAll();
+ }
+
+// --------------------------------------------------------------------------
+// Disconnect download manager session.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::Disconnect()
+ {
+ IPTVLOGSTRING_LOW_LEVEL( "RSS Plugin --- CIptvRssDownload::Disconnect" );
+
+ if ( iConnected )
+ {
+ iDownloadManager.DeleteAll();
+ iDownloadManager.RemoveObserver( *this );
+ iDownloadManager.Close();
+
+ iConnected = EFalse;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// Get download error code.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::GetDownloadErrorCode(
+ RHttpDownload& aDownload, TIptvDlError& aError ) const
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::GetDownloadErrorCode" );
+
+ TInt32 errorId;
+ TInt32 globalErrorId;
+ aDownload.GetIntAttribute( EDlAttrErrorId, errorId );
+ aDownload.GetIntAttribute( EDlAttrGlobalErrorId, globalErrorId );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::GetDownloadErrorCode:: DL error ID: %d",
+ errorId );
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::GetDownloadErrorCode:: DL global error ID: %d",
+ globalErrorId );
+
+ 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:
+ case ETransactionFailed:
+ {
+ aError = EIptvDlContentNotFound;
+ }
+ break;
+
+ default:
+ {
+ aError = EIptvDlGeneral;
+ }
+ break;
+ }
+
+ switch ( globalErrorId )
+ {
+ case EHttpResponsePaymentRequired:
+ {
+ aError = EIptvDlContentNotFound;
+ }
+ break;
+
+ case EHttpResponseContinue:
+ case EHttpResponseSwitchingProtocols:
+ {
+ aError = EIptvDlNoError;
+ }
+ break;
+
+ default:
+ // Default should not affect aError, due only special cases
+ // are handled here.
+ break;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// Timer expired.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::TimerExpired( CIptvTimer* aTimer )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::TimerExpired" );
+
+ if ( aTimer == iDlDeleteTimer )
+ {
+ delete iDlDeleteTimer;
+ iDlDeleteTimer = NULL;
+ if ( iDownloadIdValid )
+ {
+ DeleteCurrentDownload();
+ }
+
+ if ( iRestartDownload )
+ {
+ // Create new download.
+ iRestartDownload = EFalse;
+ if ( iFileName )
+ {
+ TRAP_IGNORE( DownloadL() )
+ }
+ }
+ else if ( iState == EThumbnail )
+ {
+ TRAP_IGNORE( iPlugin.DownloadThumbnailsL() )
+ }
+ else
+ {
+ TRAP_IGNORE( iPlugin.DownloadFinishedL( iDlStatus, iDlError ) )
+ }
+
+ return;
+ }
+
+ //lint -e{961} Else block not needed, default is no operation.
+ if ( iState == EPause )
+ {
+ iPauseCounter++;
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::TimerExpired PAUSED %d SECONDS",
+ iPauseCounter );
+
+ if ( iPauseCounter > KIptvMaxPauseInSeconds )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::TimerExpired PAUSED TOO LONG, PLUGIN FAILED, PROBABLY WLAN CONNECTION LOST" );
+ iDlStatus = EDownloadFailed;
+ iDlError = EIptvDlConnectionFailed;
+ TRAP_IGNORE( DeleteDownloadAsyncL() )
+ }
+ else
+ {
+ if ( iTimer && !iTimer->IsActive() )
+ {
+ iTimer->After( KIptvTime_1_second );
+ }
+ }
+ }
+ else if ( iState == EWaiting )
+ {
+ iPauseCounter++;
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::TimerExpired WAITING EVENTS FROM DL-MANAGER %d SECONDS",
+ iPauseCounter );
+
+ if ( iPauseCounter > KIptvMaxTimeoutInSeconds )
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::TimerExpired TIMEOUT %d REACHED!",
+ KIptvMaxTimeoutInSeconds );
+ iDlStatus = EDownloadFailed;
+ iDlError = EIptvDlNoError;
+ TRAP_IGNORE( DeleteDownloadAsyncL() )
+ }
+ else
+ {
+ if ( iTimer && !iTimer->IsActive() )
+ {
+ iTimer->After( KIptvTime_1_second );
+ }
+ }
+ }
+ else if ( iState == EThumbnail )
+ {
+ TRAP_IGNORE( DeleteDownloadAsyncL() )
+ }
+ else if ( iState == ENoDiskSpace )
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::TimerExpired No disk space, deleting download." );
+ iDlStatus = EDownloadFailed;
+ iDlError = EIptvDlDiskFull;
+ TRAP_IGNORE( DeleteDownloadAsyncL() )
+ }
+ }
+
+// --------------------------------------------------------------------------
+// Finish and delete current download.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::DeleteCurrentDownload()
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::DeleteCurrentDownload" );
+
+ ChangeState( EFinished );
+
+ 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();
+ iDownloadIdValid = EFalse;
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// Change the state of the download.
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::ChangeState( TInt aState )
+ {
+ switch ( iState )
+ {
+ case ENormal:
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload:: iState changed -> ENormal, was: %d", iState );
+ break;
+ }
+
+ case EPause:
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload:: iState changed -> EPause, was: %d", iState );
+ break;
+ }
+
+ case EThumbnail:
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload:: iState changed -> EThumbnail, was: %d", iState );
+ break;
+ }
+
+ case EWaiting:
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload:: iState changed -> EWaiting, was: %d", iState );
+ break;
+ }
+
+ case EFinished:
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload:: iState changed -> EFinished, was: %d", iState );
+ break;
+ }
+
+ case ETimeout:
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload:: iState changed -> ETimeout, was: %d", iState );
+ break;
+ }
+
+ case ENoDiskSpace:
+ {
+ IPTVLOGSTRING2_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::HandleDMgrEventL iState changed -> ENoDiskSpace, was: %d", iState );
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ iState = aState;
+ }
+
+// --------------------------------------------------------------------------
+// CIptvRssDownload::SkipCurrentDownloadAsyncL
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::SkipCurrentDownloadAsyncL()
+ {
+ IPTVLOGSTRING_LOW_LEVEL(
+ "RSS Plugin --- CIptvRssDownload::SkipCurrentDownloadAsyncL" );
+
+ iDlStatus = EDownloadAlreadyDownloaded;
+ iDlError = EIptvDlNoError;
+
+ DeleteDownloadAsyncL();
+ }
+
+// --------------------------------------------------------------------------
+// CIptvRssDownload::DeleteDownloadAsyncL
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::DeleteDownloadAsyncL()
+ {
+ delete iDlDeleteTimer;
+ iDlDeleteTimer = NULL;
+ iDlDeleteTimer = CIptvTimer::NewL( 0, *this );
+ iDlDeleteTimer->After( 1 ); //just to make it async
+ }
+
+// --------------------------------------------------------------------------
+// Getter for ETag
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::GetETag( TDes& aETag ) const
+ {
+ if ( iETag )
+ {
+ aETag.Copy( iETag->Des() );
+ }
+ else
+ {
+ aETag.Copy( KIptvEmptyDes );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// Getter for LastModifiedSince
+// --------------------------------------------------------------------------
+//
+void CIptvRssDownload::GetLastModifiedSince( TTime& aLastUpdated ) const
+ {
+ aLastUpdated = iLastUpdated;
+ }