videofeeds/scheduleddlplugin/src/vcnsscheduleddownloadpluginengine.cpp
changeset 0 96612d01cf9f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videofeeds/scheduleddlplugin/src/vcnsscheduleddownloadpluginengine.cpp	Mon Jan 18 20:21:12 2010 +0200
@@ -0,0 +1,1172 @@
+/*
+* Copyright (c) 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:    Implementation of the scheduled download plugin engine.*
+*/
+
+
+
+// INCLUDE FILES
+#include <bldvariant.hrh>
+#include <e32cmn.h>
+#include <s32mem.h>
+#include <e32std.h>
+#include <e32base.h>
+#include <e32msgqueue.h>
+#include <ipvideo/CCseScheduledProgram.h>
+#include <ipvideo/MCsePluginObserver.h>
+#include "IptvLiveDataStructures.h"
+#include <hwrmpowerstatesdkpskeys.h>
+#include <commdb.h>
+#include "IptvDebug.h"
+#include <CProfileChangeNotifyHandler.h>
+#include <Profile.hrh>
+#include <MProfileEngine.h>
+#include "CIptvMediaContent.h"
+
+#include "vcnsscheduleddownloadpluginengine.h"
+#include "iptvbatterywatcher.h"
+#include "iptvphoneregistrationwatcher.h"
+#include "vcnsscheduleddownloadmpxclient.h"
+
+// MACROS
+#define RETURNONERROR(e) \
+    { \
+    if ( ( e ) != KErrNone ) \
+        { \
+        IPTVLOGSTRING2_HIGH_LEVEL( \
+            ">>> CIptvScheduledDownloadPluginEngine return with error code: %d", ( e ) ); \
+        return; \
+        } \
+    }
+
+// LOCAL CONSTANTS AND MACROS
+const TInt KIptvTimeoutInMicroseconds = 15 * 60 * 1000 * 1000 ; // 15 minutes
+const TInt KIptvSearchStringmaxLen = 10;
+const TInt KIptvGetAll = 0;
+const TInt KIptvNoFileOrDrive = 0;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::NewL
+//
+// -----------------------------------------------------------------------------
+//
+CIptvScheduledDownloadPluginEngine* CIptvScheduledDownloadPluginEngine::NewL(
+        MCsePluginObserver& aObserver )
+	{	
+	CIptvScheduledDownloadPluginEngine* self =
+	        new ( ELeave ) CIptvScheduledDownloadPluginEngine( aObserver );
+	   
+    CleanupStack::PushL( self );
+    self->ConstructL( );    
+    CleanupStack::Pop( self );    
+    
+    return self;		
+	}
+	
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::ConstructL
+//
+// -----------------------------------------------------------------------------
+//
+void CIptvScheduledDownloadPluginEngine::ConstructL()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::ConstructL");
+        
+	iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait;
+	iVodDownloads = CIptvVodDlDownloadList::NewL();
+    iIptvServiceManagementClient = CIptvServiceManagementClient::NewL( *this );
+    iBatteryWatcher = CIptvBatteryWatcher::NewL();
+    iBatteryWatcher->AddObserverL( this );
+    CTimer::ConstructL();
+    CActiveScheduler::Add( this );
+    iProfChangeHandler = CProfileChangeNotifyHandler::NewL( this );
+    iPhoneRegistrationWatcher = CIptvPhoneRegistrationWatcher::NewL();
+    iPhoneRegistrationWatcher->AddObserverL( this );
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::ConstructL");
+	}
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::CIptvScheduledDownloadPluginEngine
+//
+// -----------------------------------------------------------------------------
+//
+CIptvScheduledDownloadPluginEngine::CIptvScheduledDownloadPluginEngine(
+        MCsePluginObserver& aObserver ) :
+        CTimer( EPriorityNormal ), iObserver( aObserver )
+    {
+	}
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::~CIptvScheduledDownloadPluginEngine
+//
+// -----------------------------------------------------------------------------
+//	
+CIptvScheduledDownloadPluginEngine::~CIptvScheduledDownloadPluginEngine()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::~CIptvScheduledDownloadPluginEngine");
+
+    // Set error value to KErrAbort. This will cause nearly instant return from 
+    // RunTaskL -method in case we're aborting plugin execution. This would mean
+    // that we're actually running dead code. Class is already destroyed, but the
+    // stack is still alive and kicking. This isn't a problems unless we change
+    // internal class variables (class is destroyed, but the stack is still there).
+    if ( iErrorReason )
+        {
+        *iErrorReason = KErrAbort;
+        }
+
+    // Uses iActiveSchedulerWait so pointer must exists.
+    if ( iActiveSchedulerWait )
+        {
+        ActiveWait( EFalse );
+        }
+
+    delete iPhoneRegistrationWatcher;    
+    delete iProfChangeHandler;    
+    delete iBatteryWatcher;	
+	delete iVodDlClient;    
+    delete iIptvVodContentClient;    
+    delete iIptvServiceManagementClient;    
+    delete iService;
+	delete iVodDownloads;	
+    delete iActiveSchedulerWait;
+
+	iEcgList.ResetAndDestroy();
+	iCategoryList.ResetAndDestroy();
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::~CIptvScheduledDownloadPluginEngine");
+	}
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::RunTaskL
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::RunTaskL(
+            CCseScheduledProgram& aProg,
+            TInt& aEngineReturnValue )
+	{
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::RunTaskL");
+
+    TInt errorReason( KErrNone );
+        
+    iErrorReason = &errorReason;
+    
+    iState = EStarted;
+
+    RestartTimeoutTimer();
+
+    //  Check that we are not in offline mode, reschedule if we are
+    CheckOfflineModeL();
+    aEngineReturnValue = errorReason;
+    RETURNONERROR( errorReason )
+
+	// Get used Service ID
+	iServiceID = GetServiceIdL( aProg );
+
+    if (iIptvVodContentClient)
+        {
+        delete iIptvVodContentClient;
+        iIptvVodContentClient = NULL;
+        }
+    iIptvVodContentClient = CIptvVodContentClient::NewL( iServiceID, *this );
+
+	// Check Battery Status
+	GetBatteryStatus();
+	aEngineReturnValue = errorReason;
+    RETURNONERROR( errorReason )
+
+    //  Get and check the used IAP
+    GetUsableIapL();
+    aEngineReturnValue = errorReason;
+	RETURNONERROR( errorReason )
+
+    iState = EUpdatingContentGuide;
+
+    //  Remember the time, this will be used as last successfull download time
+    TTime now;
+    now.HomeTime();
+
+    // Update ECG, blocks until the update either is either finished or fails
+    UpdateEpgL();
+    aEngineReturnValue = errorReason;
+	RETURNONERROR( errorReason);
+	
+	RestartTimeoutTimer();
+
+    //  Update epg and start downloads
+    LoadContentL();
+    aEngineReturnValue = errorReason;
+	RETURNONERROR( errorReason )
+
+    //  Are we downloading
+    if (iState == EDownloadingFiles)
+        {
+        //  This block until the files are downloaded
+        IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::RunTaskL starting to wait the downloads to finish");
+        ActiveWait( ETrue );
+        }
+        
+    aEngineReturnValue = errorReason;        
+	RETURNONERROR( errorReason )
+
+    IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::RunTaskL downloads finished, updating schedules");
+
+    iState = EFinished;
+
+    //  Update all schedules by changing the last successfull download time
+    UpdateLastDownloadTimeL( now );
+
+    iObserver.PluginCompleted( KErrNone );
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::RunTaskL");
+
+	}
+
+// from CTimer, CActive
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::RunL
+//
+// -----------------------------------------------------------------------------
+//
+void CIptvScheduledDownloadPluginEngine::RunL()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::RunL");
+
+    //  No activity in KTimeoutInMilliseconds
+    //  Assuming some kind of error situation and aborting all activities
+    *iErrorReason = KErrTimedOut;
+    CancelDownloads();
+    ActiveWait( EFalse );
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::RunL");
+    }
+
+//  from MIptvServiceManagementClientObserver
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::AddServiceResp
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::AddServiceResp(
+        TRespStatus /*aRespStatus*/)
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>><<< CIptvScheduledDownloadPluginEngine::AddServiceResp");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::UpdateServiceResp
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::UpdateServiceResp(
+        TRespStatus /*aRespStatus*/)
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>><<< CIptvScheduledDownloadPluginEngine::UpdateServiceResp");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::DeleteServiceResp
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::DeleteServiceResp(
+        TRespStatus /*aRespStatus*/)
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>><<< CIptvScheduledDownloadPluginEngine::DeleteServiceResp");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::GetServicesResp
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::GetServicesResp(
+        TRespStatus /*aRespStatus*/, 
+        CDesC8ArraySeg* /*aServicesArray*/)
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>><<< CIptvScheduledDownloadPluginEngine::GetServicesResp");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::GetUsedIapResp
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::GetUsedIapResp(
+        TUint32 /*aIapId*/,
+        const TDesC& /*aIapName*/,
+        CIptvNetworkSelection::TConnectionPermission /*aConnectionPermission*/,
+        TBool /*aWlanWhenGPRS*/,
+        CIptvNetworkSelection::TRespStatus /*aRespStatus*/ )
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>><<< CIptvScheduledDownloadPluginEngine::GetUsedIapResp");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::ServerShutdownResp
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::ServerShutdownResp(
+        TRespStatus /*aRespStatus*/)
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>><<< CIptvScheduledDownloadPluginEngine::ServerShutdownResp");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::HandleSmEvent
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::HandleSmEvent(
+        CIptvSmEvent& /*aEvent*/)
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>><<< CIptvScheduledDownloadPluginEngine::HandleSmEvent");
+    }
+
+
+// from MIptvVodContentClientObserver
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::HandleEpgManagerMsgL
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::HandleEpgManagerMsgL(
+        TInt aMsg,
+        TInt /*aInfo*/,
+        TIptvServiceId /*aServiceId*/)
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::HandleEpgManagerMsgL");
+    IPTVLOGSTRING2_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::HandleEpgManagerMsgL, msg = %d", aMsg);
+
+	switch (aMsg)
+		{
+		case KIptvErrorEpgUpdateFailed:
+		    {
+		    //  EPG update failed for some reason, try again later
+		    *iErrorReason = EReschedule;
+		    ActiveWait( EFalse );
+		    }
+		    break;
+
+		case KIptvVodUpdateNotStarted:
+		case KIptvErrorEpgUpdateSuccessed:
+		    {
+		    if (iState == EUpdatingContentGuide)
+		        {
+		        ActiveWait( EFalse );
+		        }
+		    }
+			break;	
+
+		case KIptvErrorVodNoIap:
+		    {
+		    if (iState == EUpdatingContentGuide)
+		        {
+		        IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::HandleEpgManagerMsgL, setting iap");
+		        iIptvVodContentClient->SetIapL( iIapId );
+		        }
+		    }
+		    break;
+
+		case KIptvVodUpdateStarted:
+		case KIptvErrorEpgUpdateStopped:
+		case KIptvContentUpdateCompleted:
+		case KIptvServiceThumbnailDownloaded:
+		case KIptvContentThumbnailDownloaded:
+		default:
+		    {
+		    // No operation, update still in progress.
+		    }
+			break;
+        }
+
+    RestartTimeoutTimer();
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::HandleEpgManagerMsgL");
+    }
+
+//  from MIptvVodDlClientObserver
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::HandleVodDlDownloadEvent
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::HandleVodDlDownloadEvent(
+                CIptvVodDlDownloadEvent& aEvent) 
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::HandleVodDlDownloadEvent");
+    IPTVLOGSTRING2_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::HandleVodDlDownloadEvent, event = %d", aEvent.iEvent);
+
+    switch (aEvent.iEvent)
+        {
+        case CIptvVodDlDownloadEvent::EDownloadState:
+            {
+            switch ( aEvent.iState )
+                {
+                case KIptvVodDlDownloadInQueue:
+                case KIptvVodDlDownloadStarting:
+                case KIptvVodDlDownloadDeleted:
+                case KIptvVodDlDownloadPermanentlyPausing:
+                case KIptvVodDlDownloadCreated:
+                case KIptvVodDlDownloadIdle:
+                case KIptvVodDlDownloadGlobalFileIdIsValid:
+                case KIptvVodDlDownloadRunning:
+                case KIptvVodDlDownloadPausing:
+                case KIptvVodDlDownloadPaused:
+                    {
+                    }
+                    break;
+
+                case KIptvVodDlDownloadPermanentlyPaused:
+                case KIptvVodDlDownloadFailed:
+                    {
+                    if (DeleteFromList( aEvent.iServiceId, aEvent.iContentId ))
+                        {
+                        TRAP_IGNORE( iVodDlClient->CancelDownloadL( 
+                                aEvent.iServiceId,
+                                aEvent.iContentId ) )
+                        }
+                    }
+                    break;
+
+                case KIptvVodDlDownloadDeletedCompletely:
+                case KIptvVodDlDownloadSucceeded:
+                    {
+                    DeleteFromList( aEvent.iServiceId, aEvent.iContentId );
+                    }
+                    break;
+
+                default:
+                    break;            
+                }
+            }
+            break;
+
+        case CIptvVodDlDownloadEvent::EDownloadReqSucceeded:
+        case CIptvVodDlDownloadEvent::ECancelReqFailed:
+        case CIptvVodDlDownloadEvent::ECancelReqSucceeded:
+        case CIptvVodDlDownloadEvent::EDownloadReqFailed:
+        case CIptvVodDlDownloadEvent::EDownloadItemsModified:
+        break;
+
+        default:
+        break;
+        }
+
+    RestartTimeoutTimer();
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::HandleVodDlDownloadEvent");
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::BatteryLow
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::BatteryLow()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::BatteryLow");
+
+    //  Set error reason, cancel downloads and finish the plugin
+    *iErrorReason = KErrBadPower;
+    CancelDownloads();
+    ActiveWait( EFalse );
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::BatteryLow");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::HandleActiveProfileEventL
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::HandleActiveProfileEventL(
+            TProfileEvent aProfileEvent,
+            TInt aProfileId ) 
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::HandleActiveProfileEventL");
+
+    if (aProfileEvent == EProfileNewActiveProfile)
+        {
+        if (aProfileId == EProfileOffLineId)
+            {
+            IPTVLOGSTRING_LOW_LEVEL("CIptvScheduledDownloadPluginEngine::HandleActiveProfileEventL phone changed to offline mode");
+            *iErrorReason = EReschedule;
+            CancelDownloads();
+            ActiveWait( EFalse );
+            }
+        }
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::HandleActiveProfileEventL");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::OnHomeNetwork
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::OnHomeNetwork( TBool aOnHomeNetwork )
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::OnHomeNetwork");
+
+    if (!aOnHomeNetwork)
+        {
+        IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::OnHomeNetwork, not in home network");
+        //  Set error reason, cancel downloads and finish the plugin
+        *iErrorReason = EReschedule;
+        CancelDownloads();
+        ActiveWait( EFalse );
+        }
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::OnHomeNetwork");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::GetBatteryStatus
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::GetBatteryStatus()
+	{
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::GetBatteryStatus");
+
+    if (iBatteryWatcher->IsLowPower())
+        {
+        *iErrorReason = KErrBadPower;
+        IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::GetBatteryStatus low power, aborting");
+        }
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::GetBatteryStatus");
+	}	
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::CancelDownloads
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::CancelDownloads()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::CancelDownloads");
+
+    if (iState == EDownloadingFiles)
+        {
+        //  Cancel the downloads
+        while (iVodDownloads->iList.Count())
+            {
+            //  Remove in reverse order, otherwise DL manager will start new dl
+            //  after we cancel active one which are in the beginning of the list
+            CIptvVodDlDownloadListItem* download =
+                    iVodDownloads->iList[iVodDownloads->iList.Count() - 1];
+            TUint32 contentId = download->iContentId;
+
+            IPTVLOGSTRING3_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::CancelDownloads Cancelling %d %d", iServiceID, contentId );
+            iVodDownloads->Delete( iServiceID, contentId );
+
+            TRAP_IGNORE(
+                    iVodDlClient->CancelDownloadL( iServiceID, contentId ) )
+            }
+        }
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::CancelDownloads");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::GetUsableIapL
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::GetUsableIapL()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::GetUsableIapL");
+
+	CIptvNetworkSelection::TConnectionPermission connectionPermission =
+	        CIptvNetworkSelection::ENotAllowed;
+    TBuf<KIptvNsIapNameMaxLength> apName;
+    CIptvNetworkSelection::TRespStatus respStatus;
+
+	iIptvServiceManagementClient->GetUsedIapL(
+	            iServiceID,
+	            iIapId,
+	            apName,
+	            connectionPermission,
+	            respStatus);
+
+	// Check if IAP is retrieved successfully
+	if (respStatus == CIptvNetworkSelection::ESucceeded)
+	    {
+	    //  We even skip the CIptvNetworkSelection::EAlreadyActive case
+	    //  because we don't want to download when something else is going on
+
+        //  Set not allowed and test the iap against scheduled download settings
+        connectionPermission = CIptvNetworkSelection::ENotAllowed;
+
+        //  IAP was found, get the schduled download settings
+        FetchServiceL();
+    	if( *iErrorReason != KErrNone ) 
+        	{
+            User::Leave( *iErrorReason );
+        	}
+
+        TIptvVodScheduleConnectionCondition scheduledConnectionType =
+                static_cast<TIptvVodScheduleConnectionCondition>(
+                iService->ScheduleDlNetwork() );
+
+        *iErrorReason = KErrCouldNotConnect;
+
+		// Check connection permission
+        switch (scheduledConnectionType)
+            {
+            case EAlways:
+                {
+                connectionPermission = CIptvNetworkSelection::EAllowed;
+                }
+                break;
+
+            case EWLAN:
+                {
+                if (CIptvUtil::ConnectionTypeL(iIapId) == CIptvUtil::EWlan)
+                    {
+                    connectionPermission = CIptvNetworkSelection::EAllowed;
+                    }
+                else
+                    {
+                    //  Iap does not support wlan, try again later
+                    *iErrorReason = EReschedule;
+                    }
+                }
+                break;
+
+            case EHomeCellular:
+                {
+                CIptvUtil::TConnectionType
+                        connectionType = CIptvUtil::ConnectionTypeL(iIapId);
+                if (connectionType == CIptvUtil::EWlan)
+                    {
+                    //  Allow wlan always
+                    connectionPermission = CIptvNetworkSelection::EAllowed;
+                    }
+                else
+                    {
+                    if (connectionType == CIptvUtil::EGprs)
+                        {
+                        IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::GetUsableIapL, connection allowed only in home network, checking");
+                        //  Allow connection on home network
+                        if (iPhoneRegistrationWatcher->IsOnHomeNetwork())
+                            {
+                            IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::GetUsableIapL, allowed");
+                            connectionPermission = CIptvNetworkSelection::EAllowed;
+                            }
+                        else
+                            {
+                            //  Not on home network, reschedule
+                            *iErrorReason = EReschedule;
+                            }
+                        }
+                    }
+                }
+                break;
+
+            default:
+                {
+                }
+                break;
+            }
+
+		if (connectionPermission == CIptvNetworkSelection::EAllowed)
+		    {
+		    IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::GetUsableIapL, connection allowed");
+        	// Set the connection to be allowed
+        	iIptvServiceManagementClient->SetConnectionAllowedL(
+        	        ETrue, iIapId, respStatus );
+
+            if(respStatus == CIptvNetworkSelection::ESucceeded) 
+                {
+                //  Set IAP
+                iIptvVodContentClient->SetIapL( iIapId );
+
+                //  All is fine
+                *iErrorReason = KErrNone;
+                }
+		    }
+	    }
+	else if ( respStatus == CIptvNetworkSelection::EFailedAlwaysAskSelected )
+	    {
+	    connectionPermission = CIptvNetworkSelection::ENotAllowed;
+        *iErrorReason = EDontReschedule; // No reschedule, when 'Always Ask' is selected.
+	    }
+    else
+        {
+        //  No iap, try again later
+        *iErrorReason = EReschedule;
+        }
+
+    RestartTimeoutTimer();
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::GetUsableIapL");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::GetServiceIdL
+//
+// -----------------------------------------------------------------------------
+//	
+TInt CIptvScheduledDownloadPluginEngine::GetServiceIdL(
+        CCseScheduledProgram& aProg ) const
+    {
+	// Get Service ID
+	RDesReadStream readStream;
+    CleanupClosePushL( readStream );
+    readStream.Open( aProg.ApplicationData() );
+    TUint32 serviceId = readStream.ReadUint32L();
+    CleanupStack::PopAndDestroy( &readStream );
+    
+    return serviceId;
+	}
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::UpdateEpgL
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::UpdateEpgL()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::UpdateEpgL");
+
+    iIptvVodContentClient->UpdateEcgL();
+    
+    ActiveWait( ETrue );
+        
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::UpdateEpgL");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::StartDownloadL
+//
+// -----------------------------------------------------------------------------
+//	
+TInt CIptvScheduledDownloadPluginEngine::StartDownloadL( CIptvVodContentContentBriefDetails*  aContent )
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::StartDownloadL");
+
+    // Create download item so that download events can be matched
+    CIptvVodDlDownloadListItem* download = CIptvVodDlDownloadListItem::NewL();
+    CleanupStack::PushL(download); // 1->
+    download->iIapId     = iIapId;
+    download->iServiceId = iServiceID;
+    download->iContentId = aContent->iContentId;
+    download->iDlType    = EIptvDownloadTypeImmediate;
+    iVodDownloads->iList.AppendL( download );
+    CleanupStack::Pop(download); // <-1
+
+    TIptvDlError err = iVodDlClient->DownloadL(
+                iIapId,
+                iService,
+                aContent->iContentId,
+                aContent->iName );
+
+    if (err != EIptvDlNoError)
+        {
+        //  Download not started
+        iVodDownloads->Delete( iServiceID, aContent->iContentId );
+        iVodDownloads->iList.Remove( iVodDownloads->iList.Count() - 1 );
+        }
+    else
+        {
+        IPTVLOGSTRING3_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::StartDownloadL Download started %d %d", iServiceID, aContent->iContentId );
+        }
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::StartDownloadL");
+
+    RestartTimeoutTimer();
+
+    return err == EIptvDlNoError ? KErrNone : KErrCancel;
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::ActiveWait
+//
+// -----------------------------------------------------------------------------
+//	
+void CIptvScheduledDownloadPluginEngine::ActiveWait( TBool aStart )
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::ActiveWait");
+    if (aStart)
+        {
+	    if(!iActiveSchedulerWait->IsStarted())
+	        {
+	        IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::ActiveWait - On!");
+	        iActiveSchedulerWait->Start( );		
+	        }
+        }
+    else
+        {
+		if(iActiveSchedulerWait->IsStarted())
+			{			
+            iActiveSchedulerWait->AsyncStop( );
+			IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::ActiveWait - Off!");
+			}
+        }
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::ActiveWait");        
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::DeleteFromList
+//
+// -----------------------------------------------------------------------------
+//	
+TBool CIptvScheduledDownloadPluginEngine::DeleteFromList(
+        TUint32 aServiceId,
+        TUint32 aContentId )
+    {
+    TBool isInList = EFalse;
+    if (iState == EDownloadingFiles)
+        {
+        CIptvVodDlDownloadListItem* item =
+                iVodDownloads->GetListItem( aServiceId, aContentId );
+        if (item)
+            {
+            isInList = ETrue;
+            iVodDownloads->Delete( aServiceId, aContentId );
+	        if (iVodDownloads->iList.Count() == 0)
+	            {
+	            ActiveWait( EFalse );
+	            }
+	        }
+        }
+    return isInList;
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::FetchServiceL
+//
+// -----------------------------------------------------------------------------
+//
+void CIptvScheduledDownloadPluginEngine::FetchServiceL()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::FetchServiceL");
+
+    delete iService;
+    iService = NULL;
+
+    CDesC8ArraySeg* serializedServices;
+    MIptvServiceManagementClientObserver::TRespStatus respStatus;
+
+    TInt err = iIptvServiceManagementClient->GetServicesL(
+                iServiceID, iServiceID, serializedServices, respStatus );
+
+    if (err == KErrNone && respStatus == ESucceeded)
+        {
+        CleanupStack::PushL( serializedServices );
+        //  There should be one item, just check that it exists
+        if (serializedServices->Count() > 0)
+            {
+            iService = CIptvService::NewL();
+            iService->SetL( serializedServices->MdcaPoint(0) );
+            }
+        else
+            {
+            err = KErrGeneral;
+            }
+        CleanupStack::PopAndDestroy( serializedServices );
+        }
+    else
+        {
+        //  Didin't get the service, return error code
+        err = (err == KErrNone) ? KErrGeneral : err;
+        }
+
+    if (err)
+        {
+        *iErrorReason = err;
+        }
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::FetchServiceL");
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::LoadContentL
+//
+// -----------------------------------------------------------------------------
+//
+TInt CIptvScheduledDownloadPluginEngine::LoadContentL()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::LoadContentL");
+
+    iState = EGettingContent;
+
+    //  Get the categories
+    iCategoryList.ResetAndDestroy();
+	*iErrorReason = iIptvVodContentClient->GetEcgCategoryListL(
+	        KIptvVodContentCategoryRootId, iCategoryList );
+	
+	if( *iErrorReason != KErrNone )
+	    {
+	    return *iErrorReason;
+	    }
+	
+	if( iVodDlClient )
+	    {
+	    delete iVodDlClient;
+	    iVodDlClient = NULL;
+	    }
+	
+    iVodDlClient = CVcxNsScheduledDownloadMpxClient::NewL( *this, *iIptvVodContentClient, iServiceID );
+
+    iState = ECheckingDownloadedFiles;
+
+    //  Download all episodes which have been added after the last successfull
+    //  scheduled download and which aren't already downloaded
+    TTime lastScheduledDl = iService->GetScheduledLastDownloadTime();
+
+    //  Go through categories and load their content
+	TInt count = iCategoryList.Count();
+	for (TInt i = 0; i < count && *iErrorReason == KErrNone; i++)
+	    {
+	    TUint32 totalAmount = 0;
+        TBuf<KIptvSearchStringmaxLen> searchString( KNullDesC );
+
+        //  If video search is in use and the category is search category,
+        //  the download is skipped
+        if (!iCategoryList[i]->iIsSearchCategory)
+            {
+            // Get the episodes
+    	    iEcgList.ResetAndDestroy();
+            IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::LoadContentL getting categories");
+    		*iErrorReason = iIptvVodContentClient->GetEcgListL(
+    		        iCategoryList[i]->iCategoryId,
+    		        searchString,
+    		        KIptvGetAll,
+    		        KIptvGetAll,
+    		        totalAmount,
+    		        iEcgList );
+    		
+    		if( *iErrorReason != KErrNone )
+		        {
+		        return *iErrorReason;
+		        }
+
+            // Check if the episodes contain publish date
+            TBool hasPublishDate = EFalse;
+
+            for (TInt j = 0; j < iEcgList.Count() && !hasPublishDate; j++)
+                {
+                if (iEcgList[j]->iPubDate.Int64() != 0)
+                    {
+                    hasPublishDate = ETrue;
+                    }
+                }
+
+            if (hasPublishDate)
+                {
+                IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::LoadContentL feed has publish dates.");
+                
+                // Publish date exists, download after last scheduled download
+                for (TInt j = 0;
+                        j < iEcgList.Count() && *iErrorReason == KErrNone;
+                        j++)
+                    {
+                    CIptvVodContentContentBriefDetails* details = iEcgList[j];
+
+                    // Check whether it has been downloaded already.
+                    if ( details && details->iFileId &&
+                         details->iFileId->iDrive == KIptvNoFileOrDrive &&
+                         details->iFileId->iFileId == static_cast<TIptvFileId>(
+                             KIptvNoFileOrDrive ) )
+                        {
+                        // Check whether it has been added after the last scheduled
+                        // download.
+                        if (lastScheduledDl <= details->iPubDate)
+                            {
+                            IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::LoadContentL video is new enough.");
+                            
+                            // Check whether it is a downloadable file.
+                            if ( IsDownloadableL( details->iContentId ) )
+                                {
+                                // Remember the old state.
+                                TState  oldState = iState;
+                                iState = EDownloadingFiles;
+                                if ( KErrNone != StartDownloadL( details ) )
+                                    {
+                                    // Download not going on, restore old state.
+                                    iState = oldState;
+                                    }
+                                }
+                            }
+                        else
+                            {
+                            IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::LoadContentL video is not new enough.");
+                            }
+                        }
+                    }
+                }
+            else
+                {
+                IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::LoadContentL feed does not have publish dates.");
+                
+                // No publish date, download only the first one.
+                if (iEcgList.Count() > 0)
+                    {
+                    CIptvVodContentContentBriefDetails* details = iEcgList[0];
+
+                    // Check whether it has been downloaded already.
+                    if ( details && details->iFileId &&
+                         details->iFileId->iDrive == KIptvNoFileOrDrive &&
+                         details->iFileId->iFileId == static_cast<TIptvFileId>(
+                             KIptvNoFileOrDrive ) )
+                        {
+                        // Check whether it is a downloadable file.
+                        if ( IsDownloadableL( details->iContentId ))
+                            {
+                            // Remember the old state.
+                            TState  oldState = iState;
+                            iState = EDownloadingFiles;
+                            if ( KErrNone != StartDownloadL( details ) )
+                                {
+                                //  Download not going on, restore old state.
+                                iState = oldState;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+	    }
+
+    iEcgList.ResetAndDestroy();
+    iCategoryList.ResetAndDestroy();
+
+    RestartTimeoutTimer();
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::LoadContentL");
+
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::IsDownloadableL
+//
+// -----------------------------------------------------------------------------
+//
+TBool CIptvScheduledDownloadPluginEngine::IsDownloadableL( TIptvContentId aContentId )
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::IsDownloadableL");
+
+    TBool retVal = EFalse;
+    RPointerArray<CIptvMediaContent> caDetails;
+    CleanupClosePushL( caDetails );
+
+    if (iIptvVodContentClient->GetContentAccessListL(
+            aContentId,
+            caDetails ) == KErrNone)
+        {
+        //  Go through the content access list and check it is downloadable
+        for (TInt i = 0; i < caDetails.Count() && !retVal; i++)
+            {
+            retVal = caDetails[i]->iDownloadType == EIptvDownloadTypeImmediate
+                    && caDetails[i]->iExpression == CIptvMediaContent::EFull;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &caDetails );	            
+
+    IPTVLOGSTRING2_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::IsDownloadableL: %d", retVal);
+
+    return retVal;
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::UpdateLastDownloadTimeL
+//
+// -----------------------------------------------------------------------------
+//
+void CIptvScheduledDownloadPluginEngine::UpdateLastDownloadTimeL(
+        const TTime& aTimestamp )
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::UpdateLastDownloadTimeL");
+
+    //  First get the service
+    FetchServiceL();
+    IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::UpdateLastDownloadTimeL service fetched");
+
+    //  Update the last download time
+    iService->SetScheduledLastDownloadTime( aTimestamp );
+
+    //  Update the service.
+    //  No check on the result since nothing can be done if it fails
+    MIptvServiceManagementClientObserver::TRespStatus respStatus;
+    iIptvServiceManagementClient->UpdateServiceL( *iService, respStatus );
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::UpdateLastDownloadTimeL");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::RestartTimeoutTimer
+//
+// -----------------------------------------------------------------------------
+//
+void CIptvScheduledDownloadPluginEngine::RestartTimeoutTimer()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::RestartTimeoutTimer");
+
+    Cancel();
+    After( TTimeIntervalMicroSeconds32( KIptvTimeoutInMicroseconds ) );
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::RestartTimeoutTimer");
+    }
+
+// -----------------------------------------------------------------------------
+// CIptvScheduledDownloadPluginEngine::CheckOfflineModeL
+//
+// -----------------------------------------------------------------------------
+//
+void CIptvScheduledDownloadPluginEngine::CheckOfflineModeL()
+    {
+    IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvScheduledDownloadPluginEngine::CheckOfflineModeL");
+
+	MProfileEngine* profileEngine = CreateProfileEngineL();
+
+    if (profileEngine)
+        {
+        if ( profileEngine->ActiveProfileId() == EProfileOffLineId )
+            {
+            *iErrorReason = EReschedule;
+            IPTVLOGSTRING_HIGH_LEVEL("CIptvScheduledDownloadPluginEngine::CheckOfflineModeL offline mode");
+            }
+
+        profileEngine->Release();
+        }
+
+    IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvScheduledDownloadPluginEngine::CheckOfflineModeL");
+    }