ncdengine/provider/server/src/ncddownloadsuboperation.cpp
changeset 0 ba25891c3a9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/server/src/ncddownloadsuboperation.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,520 @@
+/*
+* 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 "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 <s32mem.h>
+#include <f32file.h>
+
+#include "ncddownloadsuboperation.h"
+#include "catalogsbasemessage.h"
+#include "catalogshttpsession.h"
+#include "catalogshttpconfig.h"
+#include "catalogshttpoperation.h"
+#include "ncdhttpheaders.h"
+#include "catalogsutils.h"
+#include "catalogshttpheaders.h"
+#include "catalogscontext.h"
+#include "ncdproviderdefines.h"
+#include "ncdgeneralmanager.h"
+
+#include "catalogsdebug.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CNcdDownloadSubOperation* CNcdDownloadSubOperation::NewL( 
+    CNcdGeneralManager& aGeneralManager,
+    MCatalogsHttpSession& aHttpSession,
+    const TDesC& aUri,
+    const TDesC& aDestination,
+    MNcdOperationObserver& aObserver,
+    MCatalogsSession& aSession )
+    {
+    CNcdDownloadSubOperation* self = new( ELeave ) CNcdDownloadSubOperation( 
+        aGeneralManager, 
+        aHttpSession, 
+        aSession );
+    CleanupClosePushL( *self );
+    self->ConstructL( aUri, aDestination, aObserver );
+
+    CleanupStack::Pop();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CNcdDownloadSubOperation* CNcdDownloadSubOperation::NewL( 
+    CNcdGeneralManager& aGeneralManager,
+    MCatalogsHttpSession& aHttpSession,
+    MNcdOperationObserver& aObserver,
+    RReadStream& aStream,
+    MCatalogsSession& aSession )
+    {
+    CNcdDownloadSubOperation* self = new( ELeave ) CNcdDownloadSubOperation( 
+        aGeneralManager,
+        aHttpSession, 
+        aSession );
+    CleanupClosePushL( *self );
+    self->ConstructL( aObserver );
+    self->InternalizeL( aStream );
+
+    CleanupStack::Pop();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CNcdDownloadSubOperation::~CNcdDownloadSubOperation()
+    {
+    DLTRACEIN( ( "" ) );
+    if ( iDownload ) 
+        {
+        iDownload->Release();
+        iDownload = NULL;
+        }
+        
+    DLTRACEOUT((""));
+    }
+
+
+// ---------------------------------------------------------------------------
+// Download config getter
+// ---------------------------------------------------------------------------
+//
+MCatalogsHttpConfig& CNcdDownloadSubOperation::Config()
+    {
+    DASSERT( iDownload );
+    return iDownload->Config();
+    }
+
+
+// ---------------------------------------------------------------------------
+// Download request header getter
+// ---------------------------------------------------------------------------
+//
+MCatalogsHttpHeaders& CNcdDownloadSubOperation::RequestHeaders()
+    {
+    DASSERT( iDownload );
+    return iDownload->Config().RequestHeaders();    
+    }
+
+// ---------------------------------------------------------------------------
+// Download response header getter
+// ---------------------------------------------------------------------------
+//
+const MCatalogsHttpHeaders& CNcdDownloadSubOperation::ResponseHeadersL()
+    {
+    DASSERT( iDownload );
+    return iDownload->ResponseHeadersL();
+    }
+
+
+// ---------------------------------------------------------------------------
+// HttpOperation
+// ---------------------------------------------------------------------------
+//
+MCatalogsHttpOperation& CNcdDownloadSubOperation::HttpOperation()
+    {
+    DASSERT( iDownload );
+    return *iDownload;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Start
+// ---------------------------------------------------------------------------
+//
+TInt CNcdDownloadSubOperation::Start()
+    {
+    DLTRACEIN((""));
+    TInt ret = iDownload->Start();
+        
+    if ( ret >= KErrNone ) 
+        {
+        DLTRACEOUT((""));
+        return KErrNone;
+        }
+    DLTRACEOUT((""));
+    return ret;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Pause
+// ---------------------------------------------------------------------------
+//
+TInt CNcdDownloadSubOperation::Pause()
+    {
+    DLTRACEIN((""));
+    TInt err = iDownload->Pause();              
+    if ( err == KErrNone ) 
+        {
+        iDownloadState = ENcdDownloadPaused;
+        }
+    
+    DLTRACEOUT((""));
+    return err;
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// Resume
+// ---------------------------------------------------------------------------
+//
+TInt CNcdDownloadSubOperation::Resume()
+    {
+    DLTRACEIN((""));
+    TInt err = KErrNone; 
+    
+    if ( iDownload->State() == ECatalogsHttpOpPaused ) 
+        {
+        err = iDownload->Start();                
+        if ( err == KErrNone ) 
+            {
+            iDownloadState = ENcdDownloadInProgress;
+            }
+    
+        }    
+    DLTRACEOUT((""));
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Cancel
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::Cancel() 
+    {    
+    DLTRACEIN(( "" ));
+    if ( iDownload ) 
+        {
+        // Cancel also releases the dl
+        iDownload->Cancel();
+        iDownload = NULL;
+        }
+    DLTRACEOUT(( "" ));
+    }
+
+
+// ---------------------------------------------------------------------------
+// HandleHttpEventL
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::HandleHttpEventL( 
+    MCatalogsHttpOperation& aOperation, 
+    TCatalogsHttpEvent aEvent )
+    {
+    DLTRACEIN((( "Event op state: %d, progress state: %d" ), aEvent.iOperationState, aEvent.iProgressState ));
+    (void) aOperation; // suppresses compiler warning
+    DASSERT( &aOperation == iDownload );
+    DASSERT( aOperation.OperationType() == ECatalogsHttpDownload );
+
+    TCatalogsTransportProgress progress( iDownload->Progress() );
+    
+    iProgress = TNcdSendableProgress( iDownloadState,
+        iDownload->OperationId().Id(), progress.iProgress,
+        progress.iMaxProgress );
+
+    switch( aEvent.iOperationState ) 
+        {
+        // Handle completed operation
+        case ECatalogsHttpOpCompleted:
+            {
+            DLTRACE(("ECatalogsHttpOpCompleted"));
+            iDownloadState = ENcdDownloadComplete;
+            NotifyObserversComplete( KErrNone );            
+            break;
+            }
+        
+        // Handle operation in progress
+        case ECatalogsHttpOpInProgress:
+            {
+            iDownloadState = ENcdDownloadInProgress;
+            switch( aEvent.iProgressState ) 
+                {
+                case ECatalogsHttpResponseBodyReceived:
+                    {            
+                    iOperationState = EStateRunning;
+                    DLTRACE(("Inform observer about progress"));
+                    NotifyObserversProgress();
+                    break;
+                    }
+                case ECatalogsHttpDisconnected: 
+                    {
+                    DLTRACE(("ECatalogsHttpDisconnected"));
+                    
+                    iError = KErrDisconnected;
+                    iDownloadState = ENcdDownloadFailed;
+                    iOperationState = EStateComplete;   
+                    NotifyObserversComplete( iError );
+                    break;
+                    }
+                
+                case ECatalogsHttpStarted:
+                    {
+                    DLTRACE(("ECatatalogsHttpStarted"));
+                    iOperationState = EStateRunning;
+                    iProgress.iState = ENcdDownloadStarted;
+                    NotifyObserversProgress();
+                    break;
+                    }
+                    
+                default:
+                    {
+                    break;
+                    }
+                }
+            break;
+            }
+                
+        default:
+            {
+            break;
+            }
+        }
+    DLTRACEOUT((""));
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// HandleHttpError
+// ---------------------------------------------------------------------------
+//
+TBool CNcdDownloadSubOperation::HandleHttpError(
+    MCatalogsHttpOperation& aOperation,
+    TCatalogsHttpError aError )
+    {    
+    DLTRACEIN( ( "Error type: %i, id: %i", aError.iType, aError.iError ) );
+    DASSERT( &aOperation == iDownload );
+    
+    if ( aError.iError == KErrCancel ) 
+        {
+        aOperation.Cancel();
+        }
+    else
+        {        
+        aOperation.Release();
+        }
+    iDownload = NULL;
+    iError = aError.iError;
+    iDownloadState = ENcdDownloadFailed;
+    iOperationState = EStateComplete;   
+
+    // notify observer
+    NotifyObserversComplete( iError );
+    return ETrue;
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// Externalize
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::ExternalizeL( RWriteStream& aStream ) const
+    {
+    DLTRACEIN((""));
+
+    aStream.WriteInt32L( iDownloadState );
+    if ( iDownload && 
+         // don't save the download if there's no platform download 
+         // because we can't restore it from download manager anyway
+         iDownload->OperationId().SecondaryId() != KErrNotFound )
+        {
+        // Download exists
+        aStream.WriteInt8L( 1 );
+
+        // Write operation id so that it can be retrieved from Transport
+        iDownload->OperationId().ExternalizeL( aStream );
+        
+        iDownload->ExternalizeL( aStream );
+        }
+    else
+        {
+        aStream.WriteInt8L( 0 );
+        }
+            
+    }
+
+
+// ---------------------------------------------------------------------------
+// Internalize
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::InternalizeL( RReadStream& aStream )
+    {
+    DLTRACEIN((""));
+    
+    iDownloadState = static_cast<TNcdDownloadState>( aStream.ReadInt32L() );
+    if ( iDownloadState == ENcdDownloadInProgress ) 
+        {
+        DLTRACE(("State was set to in progress, setting as paused"));
+        iDownloadState = ENcdDownloadPaused;
+        }
+        
+    TInt8 downloadExists = aStream.ReadInt8L();
+    if ( downloadExists )
+        {        
+        TCatalogsTransportOperationId opId;
+        opId.InternalizeL( aStream );
+        
+        // Search through restored downloads
+        const RCatalogsHttpOperationArray& downloads = 
+            iHttpSession.RestoredDownloads();
+            
+        for ( TInt i = 0; i < downloads.Count(); ++i )
+            {
+            TCatalogsTransportOperationId compId( downloads[i]->OperationId() );
+            if ( compId.SecondaryId() == opId.SecondaryId() && 
+                 compId.SessionId() == opId.SessionId() ) 
+                {
+                DLINFO(("Found a matching download"));
+                iDownload = downloads[i];
+                iDownload->InternalizeL( aStream );
+                iDownload->Config().SetObserver( this );                
+                                
+                // Move dl from restored to current dls so that the restored
+                // dl list can be purged from unnecessary dls afterwards
+                User::LeaveIfError( iHttpSession.MoveRestoredDlToCurrentDls( 
+                    *iDownload ) );
+                return;
+                }
+            }                
+        }        
+    DLERROR(("Download was not found!"));
+    // Download was not found though it should have existed
+    User::Leave( KErrNotFound );
+    
+    }
+
+
+// ---------------------------------------------------------------------------
+// RunOperation
+// ---------------------------------------------------------------------------
+//
+TInt CNcdDownloadSubOperation::RunOperation()
+    {
+    DLTRACEIN(( "Pending message: %X", iPendingMessage ));
+    return KErrNone;
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CNcdDownloadSubOperation::CNcdDownloadSubOperation(
+    CNcdGeneralManager& aGeneralManager,
+    MCatalogsHttpSession& aHttpSession,
+    MCatalogsSession& aSession ) :
+        CNcdBaseOperation( aGeneralManager, NULL, EDownloadSubOperation, aSession ),
+        iHttpSession( aHttpSession )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::ConstructL( const TDesC& aUri, 
+    const TDesC& aDestination, MNcdOperationObserver& aObserver )
+    {
+    DLTRACEIN(( _L("URI: %S, Destination: %S"), &aUri, &aDestination ));
+    
+    AddObserverL( &aObserver );
+    
+    // Call ConstructL for the base class
+    CNcdBaseOperation::ConstructL();    
+    
+    // Create the download
+    iDownload = iHttpSession.CreateDownloadL( aUri, EFalse, this );
+    
+    TParsePtrC parse( aDestination );
+        
+    iDownload->Config().SetDirectoryL( parse.DriveAndPath() );
+    
+    TPtrC filename( parse.NameAndExt() );
+    if ( filename.Length() ) 
+        {
+        DLTRACE(( _L("Destination filename: %S"), &filename ));
+        iDownload->Config().SetFilenameL( filename );
+        }
+ 
+    iProgress.iProgress = -1;
+    iProgress.iMaxProgress = -1;
+    DLTRACEOUT(( "" ));
+    }
+
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::ConstructL( MNcdOperationObserver& aObserver )
+    {
+    DLTRACEIN(( "" ));
+    
+    AddObserverL( &aObserver );
+    
+    // Call ConstructL for the base class
+    CNcdBaseOperation::ConstructL();    
+     
+    iProgress.iProgress = -1;
+    iProgress.iMaxProgress = -1;
+    DLTRACEOUT(( "" ));
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// NotifyObserversComplete
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::NotifyObserversComplete( TInt aError )
+    {
+    Open(); // increase ref count in CCatalogsCommunicable
+    for( TInt i = 0; i < iObservers.Count(); ++i ) 
+        {
+        iObservers[i]->OperationComplete( this, aError );
+        }
+    Close();
+    }
+
+
+// ---------------------------------------------------------------------------
+// NotifyObserversProgress
+// ---------------------------------------------------------------------------
+//
+void CNcdDownloadSubOperation::NotifyObserversProgress()
+    {
+    Open(); // increase ref count in CCatalogsCommunicable
+    for( TInt i = 0; i < iObservers.Count(); ++i ) 
+        {
+        iObservers[i]->Progress( *this );
+        }
+    Close();
+    }