ncdengine/provider/server/src/ncdcontentdownloadoperation.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdcontentdownloadoperation.h"
       
    20 
       
    21 #include <s32mem.h>
       
    22 #include <f32file.h>
       
    23 #include <apmstd.h>
       
    24 #include <e32math.h>
       
    25 
       
    26 #include "catalogsbasemessage.h"
       
    27 #include "catalogshttpsession.h"
       
    28 #include "catalogshttpconfig.h"
       
    29 #include "catalogshttpoperation.h"
       
    30 #include "catalogsconstants.h"
       
    31 #include "ncdnodemanager.h"
       
    32 #include "ncdnodeimpl.h"
       
    33 #include "ncdnodemetadataimpl.h"
       
    34 #include "ncdnodeidentifier.h"
       
    35 #include "ncdsessionhandler.h"
       
    36 #include "ncdhttpheaders.h"
       
    37 #include "catalogsutils.h"
       
    38 #include "catalogshttpheaders.h"
       
    39 #include "ncdconfigurationmanager.h"
       
    40 #include "catalogscontext.h"
       
    41 #include "ncdproviderdefines.h"
       
    42 #include "ncdnodeclassids.h"
       
    43 #include "ncdnodelink.h"
       
    44 #include "ncdoperationremovehandler.h"
       
    45 #include "ncddownloadsuboperation.h"
       
    46 #include "ncddescriptordownloadsuboperation.h"
       
    47 #include "ncdnodedownloadimpl.h"
       
    48 #include "ncdpurchasedetails.h"
       
    49 #include "ncdpurchasedownloadinfo.h"
       
    50 #include "ncdpurchasehistorydbimpl.h"
       
    51 #include "ncdutils.h"
       
    52 #include "ncderrors.h"
       
    53 #include "ncdpanics.h"
       
    54 #include "ncdstorageitem.h"
       
    55 #include "ncddatabasestorage.h"
       
    56 #include "ncdcontentdescriptor.h"
       
    57 #include "ncdproviderutils.h"
       
    58 #include "ncdengineconfiguration.h"
       
    59 #include "ncdnodecontentinfoimpl.h"
       
    60 #include "ncdnodeinstallimpl.h"
       
    61 #include "catalogshttpconnectionmanager.h"
       
    62 #include "ncdpurchasehistoryutils.h"
       
    63 #include "ncdnodedependencyimpl.h"
       
    64 #include "catalogsaccesspointmanager.h"
       
    65 #include "ncdgeneralmanager.h"
       
    66 
       
    67 #include "catalogsdebug.h"
       
    68 
       
    69 // ======== MEMBER FUNCTIONS ========
       
    70 
       
    71 
       
    72 const TInt KNoDownloads = 25000;
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // NewL
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CNcdContentDownloadOperation* CNcdContentDownloadOperation::NewL( 
       
    79     MNcdOperationRemoveHandler& aRemoveHandler, 
       
    80     const CNcdNodeIdentifier& aNodeId,
       
    81     CNcdGeneralManager& aGeneralManager,
       
    82     MCatalogsHttpSession& aHttpSession,
       
    83     MNcdDownloadReportObserver& aReportObserver,
       
    84     MNcdSessionHandler* aSessionHandler,    
       
    85     MNcdDatabaseStorage& aDownloadStorage,
       
    86     MCatalogsSession& aSession,
       
    87     TInt aDownloadIndex )
       
    88     {
       
    89     CNcdContentDownloadOperation* self = new( ELeave ) 
       
    90         CNcdContentDownloadOperation( 
       
    91         aRemoveHandler,
       
    92         aGeneralManager, 
       
    93         aHttpSession, 
       
    94         aReportObserver,
       
    95         aSessionHandler, 
       
    96         aSession,
       
    97         aDownloadStorage );
       
    98         
       
    99     CleanupClosePushL( *self );
       
   100     self->ConstructL( aNodeId, aDownloadIndex );
       
   101 
       
   102     CleanupStack::Pop();
       
   103     return self;
       
   104     }
       
   105 
       
   106 
       
   107 
       
   108 // ---------------------------------------------------------------------------
       
   109 // NewL
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 CNcdContentDownloadOperation* CNcdContentDownloadOperation::NewLC( 
       
   113     MNcdOperationRemoveHandler& aRemoveHandler, 
       
   114     CNcdGeneralManager& aGeneralManager,
       
   115     MCatalogsHttpSession& aHttpSession,
       
   116     MNcdDownloadReportObserver& aReportObserver,
       
   117     MNcdDatabaseStorage& aDownloadStorage,
       
   118     MCatalogsSession& aSession )
       
   119     {
       
   120     CNcdContentDownloadOperation* self = new( ELeave ) 
       
   121         CNcdContentDownloadOperation( 
       
   122         aRemoveHandler,
       
   123         aGeneralManager, 
       
   124         aHttpSession, 
       
   125         aReportObserver,
       
   126         NULL, 
       
   127         aSession,
       
   128         aDownloadStorage );
       
   129         
       
   130     CleanupClosePushL( *self );
       
   131     
       
   132     self->ConstructL();
       
   133     return self;
       
   134     }
       
   135 
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // Destructor
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 CNcdContentDownloadOperation::~CNcdContentDownloadOperation()
       
   142     {
       
   143     DLTRACEIN( ( "" ) );
       
   144     
       
   145     if ( iDownloadState == ENcdDownloadInProgress )
       
   146         {        
       
   147         if ( iDownload )
       
   148             {
       
   149             DLTRACE(("Pausing download"));
       
   150             iDownload->Pause();
       
   151             }
       
   152         iDownloadState = ENcdDownloadPaused;
       
   153         }
       
   154     
       
   155     if ( iDownloadState == ENcdDownloadPaused && 
       
   156          iOperationState != EStateCancelled )
       
   157         {
       
   158         DLINFO(("Externalizing the download since it's paused"));
       
   159 
       
   160         TRAP_IGNORE( SaveStateL() );            
       
   161         }
       
   162     else
       
   163         {
       
   164         TRAP_IGNORE( RemoveTempInfoL() );
       
   165         }
       
   166         
       
   167     if ( iDownload ) 
       
   168         {
       
   169         iDownload->Close();
       
   170         iDownload = NULL;
       
   171         }
       
   172 
       
   173     if ( iDescriptorDownload )
       
   174         {
       
   175         iDescriptorDownload->Close();
       
   176         iDescriptorDownload = NULL;
       
   177         }
       
   178     
       
   179     delete iDescriptor;
       
   180     delete iMimeType;
       
   181     
       
   182     delete iSessionId;
       
   183     delete iContentDescriptor;
       
   184     
       
   185     delete iContentFilename;
       
   186     delete iStorageUid;
       
   187     DLTRACEOUT((""));
       
   188     }
       
   189 
       
   190 
       
   191 
       
   192 // ---------------------------------------------------------------------------
       
   193 // Cancel
       
   194 // ---------------------------------------------------------------------------
       
   195 //
       
   196 void CNcdContentDownloadOperation::Cancel() 
       
   197     {    
       
   198     DLTRACEIN(( "" ));
       
   199     
       
   200     // Can't handle leaves in cancel
       
   201     TNcdReportStatusInfo info( ENcdReportCancel, KErrCancel );
       
   202     TRAP_IGNORE( ReportStatusL( info ) );
       
   203     TRAP_IGNORE( SendOmaNotificationL( info ) );
       
   204     
       
   205     if ( iDownload ) 
       
   206         {
       
   207         // Content downloads should be cancelled only when the client says so
       
   208         if ( iDeleting )
       
   209             {
       
   210             iDownload->Pause();            
       
   211             }
       
   212         else
       
   213             {                        
       
   214             iDownload->Cancel();
       
   215             ClosePtr( iDownload );            
       
   216             }        
       
   217         }
       
   218         
       
   219     if ( iDescriptorDownload )
       
   220         {
       
   221         iDescriptorDownload->Cancel();
       
   222         iDescriptorDownload = NULL;
       
   223         }
       
   224 
       
   225     DLTRACEOUT(( "" ));
       
   226     }
       
   227 
       
   228 
       
   229 // ---------------------------------------------------------------------------
       
   230 // ReceiveMessage
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 void CNcdContentDownloadOperation::ReceiveMessage( 
       
   234     MCatalogsBaseMessage* aMessage,
       
   235     TInt aFunctionNumber )
       
   236     {
       
   237     DLTRACEIN(( "Function: %d", aFunctionNumber ));
       
   238     TNcdOperationMessageCompletionId completionId;
       
   239     TInt err = KErrNone;
       
   240     
       
   241     TBool requireStart = EFalse;
       
   242     // Response to pause and resume messages, other messages are handled
       
   243     // by the base class
       
   244     switch ( aFunctionNumber )
       
   245         {
       
   246         // GetData which in fact is pausable check
       
   247         case ENCDOperationFunctionGetData: 
       
   248             {
       
   249             DLTRACE(( "ENCDOperationFunctionGetData "));
       
   250             // Only error will come from CompleteMessageL
       
   251             TRAP_IGNORE( GetPausableStateL( *aMessage ) );
       
   252             return;
       
   253             }
       
   254         
       
   255         case ENCDOperationFunctionStart:
       
   256             {
       
   257             // Resume if paused, otherwise start
       
   258             if ( iDownload && iDownload->Progress().iState 
       
   259                  == ECatalogsHttpOpPaused )
       
   260                 {
       
   261                 DLTRACE(("Resuming download"));
       
   262                 err = iDownload->Start();
       
   263                 if ( err == KErrNone ) 
       
   264                     {
       
   265                     iDownloadState = ENcdDownloadInProgress;
       
   266                     }
       
   267     
       
   268                 completionId = ENCDOperationMessageCompletionResume;
       
   269                 }
       
   270             else 
       
   271                 {
       
   272                 CNcdBaseOperation::ReceiveMessage( aMessage, aFunctionNumber );
       
   273                 return;
       
   274                 }
       
   275             break;
       
   276             }
       
   277         
       
   278         // Pause download if it's pausable
       
   279         case ENCDOperationFunctionPause:
       
   280             {
       
   281             DLTRACE( ( "ENCDOperationFunctionPause" ) );
       
   282             if ( iOperationState != EStateComplete && 
       
   283                  iOperationState != EStateCancelled ) 
       
   284                 {
       
   285                 err = KErrNone;
       
   286                 if ( iDownload ) 
       
   287                     {
       
   288                     // Don't care about pausable status since the user wants to pause
       
   289                     // we must pause the operation. If the download is not pausable,
       
   290                     // it will be started from the beginning                   
       
   291                     err = iDownload->Pause();              
       
   292                     }
       
   293                                     
       
   294                 if ( iDescriptorDownload )
       
   295                     {
       
   296                     iDescriptorDownload->Cancel();
       
   297                     iDescriptorDownload = NULL;
       
   298                     }
       
   299                     
       
   300                 if ( err == KErrNone ) 
       
   301                     {
       
   302                     iDownloadState = ENcdDownloadPaused;
       
   303                     TNcdReportStatusInfo info( ENcdReportPause, KErrNone );
       
   304                     TRAP( err, ReportStatusL( info, EFalse ) );
       
   305                     }
       
   306                 }
       
   307             completionId = ENCDOperationMessageCompletionPause;
       
   308             break;
       
   309             }
       
   310             
       
   311             
       
   312         // Resume download
       
   313         case ENCDOperationFunctionResume:
       
   314             {
       
   315             DLTRACE( ( "ENCDOperationFunctionResume" ) );
       
   316             
       
   317             if ( iOperationState != EStateComplete &&
       
   318                  iOperationState != EStateCancelled )             
       
   319                 {
       
   320                 if ( iDownload ) 
       
   321                     {                    
       
   322                     err = iDownload->Start();                
       
   323                     if ( err == KErrNone ) 
       
   324                         {
       
   325                         iDownloadState = ENcdDownloadInProgress;
       
   326                         iOperationState = EStateRunning;
       
   327                         }                
       
   328                     }
       
   329                 else 
       
   330                     {
       
   331                     DLTRACE(("No download, should Start"));
       
   332                     iDownloadState = ENcdDownloadStopped;
       
   333                     iOperationState = EStateStopped;
       
   334                     requireStart = ETrue;
       
   335                     }
       
   336                 }
       
   337             completionId = ENCDOperationMessageCompletionResume;
       
   338             
       
   339             break;
       
   340             }
       
   341             
       
   342         default:
       
   343             {
       
   344             DLTRACE(("Calling baseclass"));
       
   345             // Call implementation in the base class
       
   346             CNcdBaseOperation::ReceiveMessage( aMessage, aFunctionNumber );
       
   347             DLTRACEOUT(( "Called baseclass" ));
       
   348             return;
       
   349             }
       
   350         }
       
   351         
       
   352     
       
   353     if ( iDownload ) 
       
   354         {        
       
   355         iProgress = iDownload->Progress();        
       
   356         }
       
   357         
       
   358     iProgress.iState = iDownloadState;
       
   359     if ( !iPendingMessage && 
       
   360           iDownloadState != ENcdDownloadPaused )
       
   361         {
       
   362         DLTRACE(("No pending message, ask for one"));        
       
   363         if ( requireStart ) 
       
   364             {
       
   365             iProgress.iState = KNcdDownloadStartMessageRequired;    
       
   366             }
       
   367         else
       
   368             {
       
   369             iProgress.iState = KNcdDownloadContinueMessageRequired;    
       
   370             }
       
   371         }
       
   372     
       
   373     if ( err == KErrNone ) 
       
   374         {        
       
   375         TRAP( err, SaveStateL() );
       
   376         }
       
   377     
       
   378     // Complete pause/resume message
       
   379     // If this fails then it fails
       
   380     CompleteMessage( aMessage, completionId, iProgress, err );
       
   381 
       
   382     // Ensure that iState stays valid
       
   383     iProgress.iState = iCurrentFile;
       
   384     iProgress.iOperationId = iTotalFileCount;
       
   385 
       
   386     // The operation will halt if we don't do this because it has been paused
       
   387     // when there was a pending event so the proxy side won't send a new
       
   388     // message until we complete the pending message
       
   389     if ( iPendingMessage && 
       
   390          requireStart ) 
       
   391         {
       
   392         DLTRACE(("There was a pending message when resume was called -> Run"));
       
   393         RunOperation();
       
   394         }
       
   395 
       
   396     DLTRACEOUT(( "" ));
       
   397     }
       
   398 
       
   399 
       
   400 // ---------------------------------------------------------------------------
       
   401 // 
       
   402 // ---------------------------------------------------------------------------
       
   403 //
       
   404 void CNcdContentDownloadOperation::CounterPartLost( 
       
   405     const MCatalogsSession& aSession )
       
   406     {
       
   407     DLTRACEIN((""));
       
   408     iDeleting = ETrue;
       
   409     CNcdBaseOperation::CounterPartLost( aSession ); 
       
   410     }
       
   411 
       
   412 
       
   413 // ---------------------------------------------------------------------------
       
   414 // Externalize the download
       
   415 // ---------------------------------------------------------------------------
       
   416 //
       
   417 void CNcdContentDownloadOperation::ExternalizeL( RWriteStream& aStream )
       
   418     {
       
   419     DLTRACEIN((""));
       
   420     
       
   421     // Externalize node id
       
   422     iNode->Identifier().ExternalizeL( aStream );
       
   423     
       
   424     // Externalize metadata id
       
   425     iNode->NodeMetaDataL().Identifier().ExternalizeL( aStream );
       
   426     
       
   427     ExternalizeDesL( *iStorageUid, aStream );
       
   428     
       
   429     // Externalize node type so that we can create a correct kind of
       
   430     // a temp node when we restore the download
       
   431     ExternalizeEnumL( CNcdNodeFactory::NodeTypeL( *iNode ), aStream );
       
   432     
       
   433     if ( iSessionId )
       
   434         {        
       
   435         ExternalizeDesL( *iSessionId, aStream );
       
   436         }
       
   437     else
       
   438         {
       
   439         ExternalizeDesL( KNullDesC, aStream );
       
   440         }
       
   441     
       
   442     aStream.WriteInt32L( iDownloadIndex );
       
   443     
       
   444     aStream.WriteInt32L( iContentDownloadState );
       
   445     
       
   446     aStream.WriteInt32L( iDownloadState );
       
   447     
       
   448     aStream.WriteInt32L( iDependenciesUpdated );
       
   449     
       
   450     if ( iDownload )
       
   451         {
       
   452         DLTRACE(("Download exists"));
       
   453         aStream.WriteInt8L( 1 );
       
   454         iDownload->ExternalizeL( aStream );
       
   455         }
       
   456     else
       
   457         {
       
   458         DLTRACE(("No download"));
       
   459         // no download 
       
   460         aStream.WriteInt8L( 0 );
       
   461         }
       
   462     }
       
   463 
       
   464 
       
   465 // ---------------------------------------------------------------------------
       
   466 // Internalize the download
       
   467 // ---------------------------------------------------------------------------
       
   468 //
       
   469 void CNcdContentDownloadOperation::InternalizeL( RReadStream& aStream )
       
   470     {
       
   471     DLTRACEIN((""));
       
   472     iIsOk = EFalse;
       
   473     CNcdNodeIdentifier* nodeId = CNcdNodeIdentifier::NewLC( aStream );
       
   474     DLINFO(( _L("Internalized nodeid: %S::%S"), &nodeId->NodeNameSpace(),
       
   475         &nodeId->NodeId() ));
       
   476     
       
   477     CNcdNodeIdentifier* metadataId = CNcdNodeIdentifier::NewLC( aStream );
       
   478     DLINFO(( _L("Internalized nodeid: %S::%S"), &metadataId->NodeNameSpace(),
       
   479         &metadataId->NodeId() ));
       
   480     
       
   481     InternalizeDesL( iStorageUid, aStream );
       
   482     
       
   483     CNcdNodeFactory::TNcdNodeType nodeType( CNcdNodeFactory::ENcdNodeItem );
       
   484     InternalizeEnumL( nodeType, aStream );
       
   485 
       
   486     CNcdNodeManager::TNcdTemporaryNodeType tempNodeType( 
       
   487         CNcdNodeManager::ENcdTemporaryNodeItem );
       
   488 
       
   489     switch( nodeType ) 
       
   490         {
       
   491         case CNcdNodeFactory::ENcdNodeItem:
       
   492             {
       
   493             tempNodeType = CNcdNodeManager::ENcdTemporaryNodeItem;
       
   494             break;
       
   495             }
       
   496         
       
   497         case CNcdNodeFactory::ENcdNodeFolder:
       
   498             {
       
   499             tempNodeType = CNcdNodeManager::ENcdTemporaryNodeFolder;
       
   500             break;
       
   501             }
       
   502                 
       
   503         default:
       
   504             {
       
   505             DLERROR(("Corrupt data, leave"));
       
   506             User::Leave( KErrCorrupt );
       
   507             }
       
   508         };
       
   509     
       
   510     // Get node pointer and NodeDownload-pointer
       
   511 
       
   512     DLINFO(( "Node was not found. Must create a temp node" ));
       
   513     // Create temp node and update temp node usage status
       
   514     // nodeId is a temp node id because content downloads always use
       
   515     // temp nodes so we don't have to create a new temp node id from metadata id
       
   516     iNode = &iNodeManager->CreateTemporaryNodeL( 
       
   517             *nodeId, tempNodeType, ETrue );
       
   518    
       
   519     DLTRACE(("Updating access point"));
       
   520     UpdateAccessPointsL( *nodeId );
       
   521         
       
   522     CleanupStack::PopAndDestroy( 2, nodeId ); // metadataId, nodeId
       
   523     
       
   524     DLTRACE(("Getting metadata reference"));
       
   525     // Notice that the node has always some kind of metadata
       
   526     // when content is available
       
   527     CNcdNodeMetaData& metaData( iNode->NodeMetaDataL() );
       
   528     iNodeDownload = &metaData.DownloadL();    
       
   529     
       
   530 
       
   531     // Sets iSessionId only if the original session ID != NULL
       
   532     HBufC* sessionId = NULL;
       
   533     InternalizeDesL( sessionId, aStream );
       
   534     if ( *sessionId == KNullDesC )
       
   535         {
       
   536         delete sessionId;
       
   537         sessionId = NULL;
       
   538         }
       
   539     iSessionId = sessionId;
       
   540     
       
   541     iDownloadIndex = aStream.ReadInt32L();
       
   542     
       
   543     iContentDownloadState = static_cast<TContentDownloadState>( 
       
   544         aStream.ReadInt32L() );
       
   545     
       
   546     iDownloadState = static_cast<TNcdDownloadState>( 
       
   547         aStream.ReadInt32L() );
       
   548     
       
   549     if ( iDownloadState != ENcdDownloadComplete &&
       
   550          iDownloadState != ENcdDownloadFailed ) 
       
   551         {
       
   552         DLTRACE(("Setting iDownloadState to ENcdDownloadPaused"));
       
   553         iDownloadState = ENcdDownloadPaused;
       
   554         }
       
   555     
       
   556     iDependenciesUpdated = aStream.ReadInt32L();
       
   557         
       
   558     TInt8 downloadExists = aStream.ReadInt8L();
       
   559     if ( downloadExists )
       
   560         {
       
   561         DLTRACE(("Internalizing download suboperation"));
       
   562         TRAPD( err, 
       
   563             iDownload = CNcdDownloadSubOperation::NewL(
       
   564                 iGeneralManager,
       
   565                 iHttpSession, 
       
   566                 *this, 
       
   567                 aStream,
       
   568                 iSession ) );
       
   569         
       
   570         if ( err == KErrNone ) 
       
   571             {
       
   572             // Register download to report manager, iReportId will be the old one
       
   573             // if the manager still has the old report
       
   574             HBufC* uri = ConvertUtf8ToUnicodeL( iDownload->HttpOperation().Uri() );
       
   575             CleanupStack::PushL( uri );
       
   576 
       
   577             // This also update the accesspoint though that's unnecessary
       
   578             // since it has been saved by the report itself
       
   579             RegisterDownloadL( *uri, metaData.Identifier() );
       
   580             CleanupStack::PopAndDestroy( uri );    
       
   581             }
       
   582         // CNcdDownloadSubOperation::NewL leaves with KErrNotFound if the
       
   583         // platform download is not found but we don't want to let it
       
   584         // go any further than this
       
   585         else if ( err != KErrNotFound ) 
       
   586             {
       
   587             DLERROR(("Leaving with err: %d", err ));
       
   588             User::Leave( err );
       
   589             }
       
   590         }
       
   591     iIsOk = ETrue;    
       
   592     }
       
   593 
       
   594 
       
   595 // ---------------------------------------------------------------------------
       
   596 // Checks if the download matches the given criteria
       
   597 // ---------------------------------------------------------------------------
       
   598 //
       
   599 TBool CNcdContentDownloadOperation::MatchDownload( 
       
   600     const CNcdNodeIdentifier& aId, 
       
   601     TNcdDownloadDataType& aType, 
       
   602     TInt /* aIndex */ ) const
       
   603     {
       
   604     return aType == ENcdContentDownload && 
       
   605         aId.Equals( MetadataId() );
       
   606          //&& aIndex == iDownloadIndex;
       
   607     }
       
   608 
       
   609 
       
   610 // ---------------------------------------------------------------------------
       
   611 // Node ID getter
       
   612 // ---------------------------------------------------------------------------
       
   613 //
       
   614 const CNcdNodeIdentifier& CNcdContentDownloadOperation::NodeId() const
       
   615     {
       
   616     return iNode->Identifier();
       
   617     }
       
   618     
       
   619 
       
   620 // ---------------------------------------------------------------------------
       
   621 // Metadata id getter
       
   622 // ---------------------------------------------------------------------------
       
   623 //
       
   624 const CNcdNodeIdentifier& CNcdContentDownloadOperation::MetadataId() const
       
   625     {
       
   626     
       
   627     return iNode->NodeMetaData()->Identifier();
       
   628     }
       
   629 
       
   630 
       
   631 // ---------------------------------------------------------------------------
       
   632 // Ok status getter
       
   633 // ---------------------------------------------------------------------------
       
   634 //
       
   635 TBool CNcdContentDownloadOperation::IsOk() const
       
   636     {
       
   637     return iIsOk;
       
   638     }
       
   639 
       
   640 
       
   641 // ---------------------------------------------------------------------------
       
   642 // Current download index
       
   643 // ---------------------------------------------------------------------------
       
   644 //
       
   645 TInt CNcdContentDownloadOperation::CurrentDownload() const
       
   646     {
       
   647     return iDownloadIndex;
       
   648     }
       
   649 
       
   650    
       
   651 // ---------------------------------------------------------------------------
       
   652 // Progress
       
   653 // ---------------------------------------------------------------------------
       
   654 //
       
   655 void CNcdContentDownloadOperation::Progress( CNcdBaseOperation& aOperation )
       
   656     {
       
   657     DLTRACEIN((""));
       
   658     
       
   659     // Report operation start to report manager
       
   660     if ( aOperation.Progress().iState == ENcdDownloadStarted )
       
   661         {
       
   662         TNcdReportStatusInfo info( ENcdReportStart, KErrNone );
       
   663         TRAPD( err, ReportStatusL( info, EFalse ) );
       
   664         if ( err != KErrNone ) 
       
   665             {
       
   666             DLERROR(("Error: %d", err));
       
   667             iError = err;
       
   668             RunOperation();
       
   669             }
       
   670         }
       
   671     
       
   672     if ( !iDescriptorDownload && iContentDownloadState == EContentDownload )
       
   673         {        
       
   674         iProgress = aOperation.Progress();   
       
   675         iProgress.iState = iCurrentFile;
       
   676         iProgress.iOperationId = iTotalFileCount;
       
   677         iUnhandledEvent = ETrue; 
       
   678         RunOperation();    
       
   679         }
       
   680     }
       
   681 
       
   682 // ---------------------------------------------------------------------------
       
   683 // QueryReceived
       
   684 // ---------------------------------------------------------------------------
       
   685 //
       
   686 void CNcdContentDownloadOperation::QueryReceived( 
       
   687     CNcdBaseOperation& /* aOperation */,
       
   688     CNcdQuery* /* aQuery */ )
       
   689     {
       
   690     DLTRACEIN((""));
       
   691     }
       
   692 
       
   693 // ---------------------------------------------------------------------------
       
   694 // OperationComplete
       
   695 // ---------------------------------------------------------------------------
       
   696 //
       
   697 void CNcdContentDownloadOperation::OperationComplete( 
       
   698     CNcdBaseOperation* aOperation, 
       
   699     TInt aError )
       
   700     {
       
   701     DLTRACEIN(( "aError: %d", aError ));
       
   702     iProgress = aOperation->Progress();
       
   703     iProgress.iState = iCurrentFile;
       
   704     iProgress.iOperationId = iTotalFileCount;
       
   705     
       
   706     // Ignore errors in notification sending
       
   707     if ( aError == KErrNone  ) 
       
   708         {             
       
   709         TRAPD( err,
       
   710             {
       
   711 
       
   712             if ( iDescriptorDownload )
       
   713                 {
       
   714                 DLTRACE(("Descriptor download finished"));
       
   715                 DASSERT( aOperation == static_cast<CNcdBaseOperation*>( 
       
   716                     iDescriptorDownload ) );
       
   717                 FinishDescriptorDownloadL();
       
   718                 ReleaseDownload( aOperation );                
       
   719                 
       
   720                 // Initialize & start next descriptor/content download
       
   721                 InitializeDownloadL( iDownloadIndex );
       
   722                     
       
   723                 StartDownloadL();
       
   724                 }
       
   725             else
       
   726                 {                
       
   727                 TBool contentDownloaded = FinishDownloadL();
       
   728                  
       
   729                 ReleaseDownload( aOperation );
       
   730                 
       
   731                 if ( contentDownloaded && iContentDownloadState == EDownloadDone ) 
       
   732                     {                    
       
   733                     iContentDownloadState = ENoDownload;
       
   734                     DLTRACE(("Content file downloaded"));
       
   735                     ++iDownloadIndex;
       
   736                     if ( iDownloadIndex == iNodeDownload->DownloadInfo().Count() )
       
   737                         {
       
   738                         DLTRACE(("Download is complete"));
       
   739                         iDownloadState = ENcdDownloadComplete;       
       
   740                         
       
   741                         // Remove state information from the download db
       
   742                         RemoveTempInfoL();                 
       
   743                         }
       
   744                     else
       
   745                         {
       
   746                         DLTRACE(("Starting the next file from index: %d", 
       
   747                             iDownloadIndex ));
       
   748                         iCurrentFile++;
       
   749                         iDownloadState = ENcdDownloadInProgress;
       
   750                         iUnhandledEvent = ETrue;
       
   751                         iStartNextFile = ETrue;
       
   752                         }
       
   753                     }
       
   754                 else 
       
   755                     {
       
   756                     DLTRACE(("Start downloading the actual content file/send notification"));
       
   757                     iDownloadState = ENcdDownloadInProgress;
       
   758                     iStartNextFile = ETrue;
       
   759                     }
       
   760                 }
       
   761             });
       
   762         
       
   763         if ( err != KErrNone ) 
       
   764             {
       
   765             if ( err == KNoDownloads ) 
       
   766                 {
       
   767                 DLTRACE(("Everything has already been downloaded & installed"));
       
   768                 iError = KErrNone;
       
   769                 iDownloadState = ENcdDownloadComplete;
       
   770                 iContentDownloadState = ENoDownload;
       
   771                 }
       
   772             else 
       
   773                 {
       
   774                 DLERROR(("Error %d when handling a completed download", err ));
       
   775                 iError = err;
       
   776                 iDownloadState = ENcdDownloadFailed;
       
   777                 }
       
   778             }
       
   779         RunOperation();
       
   780         }
       
   781     else
       
   782         {
       
   783         DLERROR(( "Handling error: %d", aError ));
       
   784         
       
   785         // Already handling an error so we can forget about this one
       
   786         TNcdReportStatusInfo info( ENcdReportFail, aError );
       
   787         TRAP_IGNORE( ReportStatusL( info ) );
       
   788         ReleaseDownload( aOperation );
       
   789         
       
   790         iError = aError;
       
   791         iDownloadState = ENcdDownloadFailed;
       
   792         RunOperation();
       
   793         }            
       
   794     }
       
   795 
       
   796     
       
   797 // ---------------------------------------------------------------------------
       
   798 // RunOperation
       
   799 // ---------------------------------------------------------------------------
       
   800 //
       
   801 TInt CNcdContentDownloadOperation::RunOperation()
       
   802     {
       
   803     DLTRACEIN(( "Pending message: %X", iPendingMessage ));
       
   804     
       
   805     if ( !iPendingMessage ) 
       
   806         {      
       
   807         DLTRACE(("No pending message"));  
       
   808         return KErrNotReady;
       
   809         }
       
   810      
       
   811     TInt err = KErrNone;
       
   812     DLTRACE(("DL state: %i", iDownloadState ));
       
   813 
       
   814     switch( iDownloadState ) 
       
   815         {
       
   816         // Start the download
       
   817         case ENcdDownloadStopped: 
       
   818             {            
       
   819             DLTRACE(("ENcdDownloadStopped"));
       
   820             TRAP( err,
       
   821                 {               
       
   822                 InitializeDownloadL( iDownloadIndex );                
       
   823                 DLTRACE(("Starting the download"));                
       
   824                 StartDownloadL();                
       
   825                 });
       
   826             
       
   827             if ( err == KNoDownloads ) 
       
   828                 {
       
   829                 DLTRACE(("No downloads"));
       
   830                 iDownloadState = ENcdDownloadComplete;
       
   831                 RunOperation();
       
   832                 // error handled
       
   833                 err = KErrNone;
       
   834                 }
       
   835             DLTRACE(("ENcdDownloadStopped done, err: %d", err));
       
   836             break;
       
   837             }
       
   838         
       
   839         case ENcdDownloadInProgress: 
       
   840             {
       
   841             DLTRACE(("ENcdDownloadInProgress"));
       
   842             if ( iUnhandledEvent ) 
       
   843                 {   
       
   844                 CompleteMessage( iPendingMessage,
       
   845                     ENCDOperationMessageCompletionProgress, 
       
   846                     iProgress, err );
       
   847                 iUnhandledEvent = EFalse;
       
   848                 }
       
   849                 
       
   850             if ( iStartNextFile ) 
       
   851                 {
       
   852                 DLTRACE(("Starting the next file"));
       
   853                 iStartNextFile = EFalse;
       
   854 
       
   855                 TRAP( err,
       
   856                     {                    
       
   857                     InitializeDownloadL( iDownloadIndex );
       
   858                     DLTRACE(("Starting the download"));
       
   859                     StartDownloadL();
       
   860                     });
       
   861                     
       
   862                 if ( err == KNoDownloads ) 
       
   863                     {
       
   864                     DLTRACE(("No more downloads"));
       
   865                     iDownloadState = ENcdDownloadComplete;
       
   866                     RunOperation();
       
   867                     // error handled
       
   868                     err = KErrNone;
       
   869                     }
       
   870                 }
       
   871                 
       
   872             DLTRACE(("ENcdDownloadInProgress done"));
       
   873             break;
       
   874             }
       
   875             
       
   876         case ENcdDownloadComplete:
       
   877             {
       
   878             DLTRACE(("ENcdDownloadComplete"));            
       
   879             CompleteMessage( 
       
   880                 iPendingMessage,
       
   881                 ENCDOperationMessageCompletionComplete, 
       
   882                 iProgress, err ); 
       
   883 
       
   884             // This prevents download pausing/resuming problems after
       
   885             // the download has been completed
       
   886             iOperationState = EStateComplete;
       
   887             break;
       
   888             }
       
   889             
       
   890         case ENcdDownloadFailed:
       
   891             {
       
   892             DLTRACE(("ENcdDownloadFailed"));
       
   893             // Send error message in case didn't have any pending
       
   894             // messages when the download actually failed
       
   895             
       
   896             CompleteMessage( iPendingMessage,
       
   897                 ENCDOperationMessageCompletionError, iProgress,
       
   898                 iError );
       
   899 
       
   900             // This prevents download pausing/resuming problems after
       
   901             // the download has been completed
       
   902             iOperationState = EStateComplete;
       
   903 
       
   904             DLTRACE(("ENcdDownloadFailed done"));
       
   905             break;            
       
   906             }
       
   907             
       
   908         case ENcdDownloadPaused:
       
   909             {
       
   910             DLTRACE(("Operation paused"));
       
   911             break;
       
   912             }
       
   913             
       
   914         default: 
       
   915             {
       
   916             DLTRACE(("Default"));
       
   917             DASSERT( 0 );
       
   918             }
       
   919         }
       
   920     
       
   921     if ( err != KErrNone )
       
   922         {
       
   923         DLTRACE(("error: %d", err));
       
   924         Cancel();
       
   925         iDownloadState = ENcdDownloadFailed;
       
   926         iError = err;
       
   927         if ( iPendingMessage )
       
   928             {
       
   929             CompleteMessage( iPendingMessage,
       
   930                 ENCDOperationMessageCompletionError, iError );
       
   931             }
       
   932         // call observers
       
   933         CompleteCallback();
       
   934         }
       
   935     DLTRACEOUT(("err: %d", err));
       
   936     return err;
       
   937     }
       
   938 
       
   939 
       
   940 // ---------------------------------------------------------------------------
       
   941 // Initializer
       
   942 // ---------------------------------------------------------------------------
       
   943 //
       
   944 TInt CNcdContentDownloadOperation::Initialize()
       
   945     {
       
   946     DLTRACEIN( ( "" ) );
       
   947     
       
   948     TRAPD( err, DoInitializationL() );
       
   949     
       
   950     if ( err != KErrNone ) 
       
   951         {
       
   952         DLTRACE( ( "Err: %d", err ) );
       
   953         iPendingMessage->CompleteAndRelease( err );
       
   954         iPendingMessage = NULL;
       
   955         }
       
   956     DLTRACEOUT(( "err: %d", err ));
       
   957     return err;    
       
   958     }
       
   959 
       
   960 
       
   961 // ---------------------------------------------------------------------------
       
   962 // Actual initializer
       
   963 // ---------------------------------------------------------------------------
       
   964 //
       
   965 void CNcdContentDownloadOperation::DoInitializationL()
       
   966     {
       
   967     DLTRACEIN(("Writing initialize response"));
       
   968     
       
   969     // Write the response
       
   970     RCatalogsBufferWriter writer;
       
   971     writer.OpenLC();
       
   972     writer().WriteInt32L( ENCDOperationMessageCompletionInit );
       
   973     
       
   974     if ( !iDependenciesUpdated ) 
       
   975         {
       
   976         TRAPD( err, UpdateDependenciesL() );        
       
   977         LeaveIfNotErrorL( err, KErrNotFound );
       
   978         }
       
   979     
       
   980     iCurrentFile = 1;
       
   981     iTotalFileCount = CalculateMissingFilesL();
       
   982      
       
   983     writer().WriteInt32L( iTotalFileCount );
       
   984     // write pause-status
       
   985     writer().WriteInt32L( iDownloadState == ENcdDownloadPaused );
       
   986     
       
   987     iPendingMessage->CompleteAndReleaseL( writer.PtrL(), KErrNone );
       
   988     iPendingMessage = NULL;
       
   989     CleanupStack::PopAndDestroy( &writer );
       
   990 
       
   991     }
       
   992 
       
   993 // ---------------------------------------------------------------------------
       
   994 // Constructor
       
   995 // ---------------------------------------------------------------------------
       
   996 //
       
   997 CNcdContentDownloadOperation::CNcdContentDownloadOperation( 
       
   998     MNcdOperationRemoveHandler& aRemoveHandler,
       
   999     CNcdGeneralManager& aGeneralManager,
       
  1000     MCatalogsHttpSession& aHttpSession, 
       
  1001     MNcdDownloadReportObserver& aReportObserver,
       
  1002     MNcdSessionHandler* aSessionHandler, 
       
  1003     MCatalogsSession& aSession,
       
  1004     MNcdDatabaseStorage& aDownloadStorage ) : 
       
  1005         CNcdBaseOperation( aGeneralManager, &aRemoveHandler, EContentDownloadOperation,
       
  1006             aSession ),
       
  1007         iHttpSession( aHttpSession ),
       
  1008         iReportObserver( aReportObserver ),
       
  1009         iSessionHandler( aSessionHandler ),
       
  1010         iConfigurationManager( aGeneralManager.ConfigurationManager() ),
       
  1011         iAccessPointManager( aGeneralManager.AccessPointManager() ),
       
  1012         iStorage( aDownloadStorage ),
       
  1013         iContext( aSession.Context() ),
       
  1014         iDownloadState( ENcdDownloadStopped )
       
  1015     {
       
  1016     }
       
  1017 
       
  1018 
       
  1019 // ---------------------------------------------------------------------------
       
  1020 // ConstructL
       
  1021 // ---------------------------------------------------------------------------
       
  1022 //
       
  1023 void CNcdContentDownloadOperation::ConstructL( 
       
  1024     const CNcdNodeIdentifier& aNodeId, 
       
  1025     TInt aDownloadIndex )
       
  1026     {
       
  1027     DLTRACEIN(( "DL index: %i", aDownloadIndex ));
       
  1028     (void) aDownloadIndex; // prevents compiler warning of unused parameter
       
  1029 
       
  1030     ConstructL();    
       
  1031     
       
  1032     GenerateStorageUidL();
       
  1033     
       
  1034     // Get pointer to node, using NodeL since it leaves if the node is not found
       
  1035     iNode = &iNodeManager->NodeL( aNodeId );
       
  1036     
       
  1037     if ( iSessionHandler && iNode->NodeLink() ) 
       
  1038         {        
       
  1039         // Get server URI from the node
       
  1040         const TDesC& serverUri = iNode->NodeLink()->ServerUri();
       
  1041         
       
  1042         if ( iSessionHandler->DoesSessionExist( 
       
  1043                 serverUri,
       
  1044                 aNodeId.NodeNameSpace() ) )
       
  1045             {        
       
  1046             // Get session ID for the URI
       
  1047             iSessionId = iSessionHandler->Session( 
       
  1048                 serverUri,
       
  1049                 aNodeId.NodeNameSpace() ).AllocL();
       
  1050             }
       
  1051         }
       
  1052     
       
  1053                         
       
  1054     UpdateAccessPointsL( aNodeId );
       
  1055     
       
  1056     // Get NodeDownload-interface
       
  1057     // Notice that if content is available the node has some kind of
       
  1058     // metadata.
       
  1059     CNcdNodeMetaData& metaData( iNode->NodeMetaDataL() );
       
  1060     iNodeDownload = &metaData.DownloadL();
       
  1061     
       
  1062     SaveStateL();
       
  1063     iIsOk = ETrue;
       
  1064     DLTRACEOUT(( "" ));
       
  1065     }
       
  1066 
       
  1067 
       
  1068 // ---------------------------------------------------------------------------
       
  1069 // ConstructL
       
  1070 // ---------------------------------------------------------------------------
       
  1071 //
       
  1072 void CNcdContentDownloadOperation::ConstructL()
       
  1073     {
       
  1074     // Call ConstructL for the base class    
       
  1075     CNcdBaseOperation::ConstructL(); 
       
  1076     iContentDescriptor = CNcdContentDescriptor::NewL();
       
  1077     iProgress.iMaxProgress = 1;
       
  1078     }
       
  1079     
       
  1080 // ---------------------------------------------------------------------------
       
  1081 // FinishDescriptorDownloadL
       
  1082 // ---------------------------------------------------------------------------
       
  1083 //
       
  1084 void CNcdContentDownloadOperation::FinishDescriptorDownloadL()
       
  1085     {
       
  1086     DLTRACEIN((""));
       
  1087     
       
  1088     DLTRACE(("Reporting successful download"));
       
  1089     TNcdReportStatusInfo info( ENcdReportSuccess, KErrNone );
       
  1090     ReportStatusL( info );
       
  1091     iReportId = KNcdReportNotSupported;
       
  1092     
       
  1093     if ( iContentDownloadState == ERightsDownload )
       
  1094         {                
       
  1095         const TDesC8& contentType( 
       
  1096             iDescriptorDownload->HttpOperation().ContentType() );
       
  1097             
       
  1098         // Get download info for the current DL
       
  1099         const MNcdPurchaseDownloadInfo& info = *iNodeDownload->DownloadInfo()[
       
  1100             iDownloadIndex ];
       
  1101         
       
  1102         
       
  1103         TDataType dataType;        
       
  1104         
       
  1105         // Try to find out the correct mime type for the rights object    
       
  1106         DLTRACE(("Handling rights object"));
       
  1107         if( contentType.MatchF( KMimeTypeMatchDrmRightsXml8 ) != KErrNotFound ||
       
  1108             contentType.MatchF( KMimeTypeMatchDrmRightsWbxml8 ) != KErrNotFound )
       
  1109             {
       
  1110             DLTRACE(("Rights type: %S", &contentType ));
       
  1111             dataType = TDataType( contentType );
       
  1112             }
       
  1113         else if ( info.RightsType().MatchF( KMimeTypeMatchDrmRightsXml ) != KErrNotFound ||
       
  1114             info.RightsType().MatchF( KMimeTypeMatchDrmRightsWbxml ) != KErrNotFound )
       
  1115             {            
       
  1116             HBufC8* tempBuf = Des16ToDes8LC( info.RightsType() );
       
  1117             dataType = TDataType( *tempBuf );
       
  1118             CleanupStack::PopAndDestroy( tempBuf );
       
  1119             DLINFO(("Rights: %S", &dataType.Des8() ));
       
  1120             }
       
  1121                     
       
  1122         CNcdProviderUtils::InstallationServiceL().AppendRightsL( 
       
  1123             iDescriptorDownload->Body(), 
       
  1124             dataType );
       
  1125         
       
  1126         }
       
  1127     else if ( iContentDownloadState == EDescriptorDownload )
       
  1128         {
       
  1129         DLTRACE(("Handling downloaded descriptor"));
       
  1130         delete iDescriptor;
       
  1131         iDescriptor = NULL;
       
  1132         iDescriptor = iDescriptorDownload->Body().AllocL();    
       
  1133 
       
  1134         HBufC* mime = Des8ToDes16L( 
       
  1135             iDescriptorDownload->HttpOperation().ContentType() );
       
  1136             
       
  1137         TDescriptorType descType( MatchDescriptor( *mime ) );
       
  1138         delete mime;
       
  1139             
       
  1140         if ( descType == EDescriptorDd ) 
       
  1141             {
       
  1142             HandleDescriptorL( KDescriptorTypeOdd, *iDescriptor );
       
  1143             }
       
  1144         else 
       
  1145             {
       
  1146             HandleDescriptorL( KDescriptorTypeJad, *iDescriptor );
       
  1147             }
       
  1148             
       
  1149         UpdatePurchaseHistoryL( KNullDesC() ); 
       
  1150         }
       
  1151     else
       
  1152         {
       
  1153         DASSERT( 0 );
       
  1154         }
       
  1155     }
       
  1156 
       
  1157 
       
  1158 // ---------------------------------------------------------------------------
       
  1159 // StartDownloadL
       
  1160 // ---------------------------------------------------------------------------
       
  1161 //
       
  1162 void CNcdContentDownloadOperation::StartDownloadL()
       
  1163     {
       
  1164     DLTRACEIN((""));    
       
  1165     
       
  1166     if ( iDescriptorDownload ) 
       
  1167         {
       
  1168         DLTRACE(("Start descriptor download"));
       
  1169         User::LeaveIfError( iDescriptorDownload->Start() );
       
  1170         iProgress = iDescriptorDownload->Progress();    
       
  1171         }
       
  1172     else        
       
  1173         {
       
  1174         DLTRACE(("Start file download"));
       
  1175         // Set these before start so that if a progress callback is
       
  1176         // called during start the operation functions correctly in
       
  1177         // RunOperation
       
  1178         iDownloadState = ENcdDownloadInProgress;
       
  1179         iOperationState = EStateRunning;
       
  1180         TInt err = iDownload->Start();
       
  1181         if ( err != KErrNone ) 
       
  1182             {
       
  1183             DLERROR(("Failed: %d", err))
       
  1184             iDownloadState = ENcdDownloadFailed;
       
  1185             iOperationState = EStateComplete;
       
  1186             User::Leave( err );
       
  1187             }
       
  1188         iProgress = iDownload->Progress();    
       
  1189         }
       
  1190     
       
  1191     DLTRACE(("Download started successfully"));
       
  1192     iDownloadState = ENcdDownloadInProgress;
       
  1193     iProgress.iState = iCurrentFile;
       
  1194     iProgress.iOperationId = iTotalFileCount;
       
  1195     
       
  1196     iOperationState = EStateRunning;
       
  1197     SaveStateL();
       
  1198     }
       
  1199     
       
  1200 
       
  1201 // ---------------------------------------------------------------------------
       
  1202 // FinishDownloadL
       
  1203 // ---------------------------------------------------------------------------
       
  1204 //
       
  1205 TBool CNcdContentDownloadOperation::FinishDownloadL()
       
  1206     {
       
  1207     DLTRACEIN((""));
       
  1208     
       
  1209     DLTRACE(("Reporting successful download"));
       
  1210     TNcdReportStatusInfo info( ENcdReportSuccess, KErrNone );
       
  1211     ReportStatusL( info );
       
  1212     
       
  1213     // iDownload doesn't exist if we are sending the notification
       
  1214     if ( iDownload && !iContentFilename ) 
       
  1215         {
       
  1216         DLTRACE(("Get target filename"));
       
  1217         iContentFilename = iDownload->Config().FullPathLC();
       
  1218         CleanupStack::Pop( iContentFilename );
       
  1219         }
       
  1220                 
       
  1221     HBufC* mimeType = NULL;
       
  1222     TBool mimeOwned = EFalse;
       
  1223     if ( iDownload ) 
       
  1224         {        
       
  1225         mimeType = Des8ToDes16LC( iDownload->HttpOperation().ContentType() );
       
  1226         }
       
  1227     else if ( iMimeType && iMimeType->Length() ) 
       
  1228         {
       
  1229         mimeType = iMimeType->AllocLC();           
       
  1230         }
       
  1231     else
       
  1232         {
       
  1233         mimeType = KNullDesC().AllocLC();
       
  1234         }        
       
  1235     
       
  1236     
       
  1237     // No MIME type, update from HTTP headers
       
  1238     if ( !iMimeType || !iMimeType->Length() ) 
       
  1239         {
       
  1240         DLTRACE(("Update mime type"));
       
  1241         delete iMimeType;
       
  1242         iMimeType = NULL;
       
  1243         iMimeType = mimeType;
       
  1244         DLTRACE(( _L("MIME type: %S"), iMimeType ));
       
  1245         iMimeUpdated = ETrue;
       
  1246         mimeOwned = ETrue;        
       
  1247         }
       
  1248 
       
  1249     if ( !iContentMime.Length() ) 
       
  1250         {
       
  1251         iContentMime.Set( *iMimeType );
       
  1252         }
       
  1253 
       
  1254     // Using the actual mime from the response
       
  1255     TDescriptorType descType( MatchDescriptor( 
       
  1256         *mimeType ) );
       
  1257     
       
  1258     if ( !mimeOwned ) 
       
  1259         {
       
  1260         CleanupStack::PopAndDestroy( mimeType );
       
  1261         }
       
  1262     else 
       
  1263         {
       
  1264         CleanupStack::Pop( mimeType );
       
  1265         }
       
  1266     
       
  1267     // iDownloadType is checked so that the actual content file is not handled like
       
  1268     // the downloaded descriptor
       
  1269     if ( descType != EDescriptorUnknown && 
       
  1270         iDownloadType == EDescriptorUnknown )
       
  1271         {
       
  1272         DLTRACE(("Downloaded a descriptor in a file"));
       
  1273         DASSERT( iContentFilename );
       
  1274         delete iDescriptor;
       
  1275         iDescriptor = NULL;
       
  1276         iDescriptor = ReadFileL( CNcdProviderUtils::FileSession(), 
       
  1277             *iContentFilename );
       
  1278         
       
  1279         // Beware: this debug print can easily panic if the descriptor is long
       
  1280         // enough
       
  1281         //DLINFO(( "Descriptor: %S", iDescriptor ));
       
  1282         CNcdProviderUtils::FileSession().Delete( *iContentFilename );
       
  1283         delete iContentFilename;
       
  1284         iContentFilename = NULL;
       
  1285         
       
  1286         if ( descType == EDescriptorDd ) 
       
  1287             {
       
  1288             HandleDescriptorL( KDescriptorTypeOdd, *iDescriptor );
       
  1289             }
       
  1290         else 
       
  1291             {
       
  1292             HandleDescriptorL( KDescriptorTypeJad, *iDescriptor );
       
  1293             }
       
  1294         
       
  1295         // Writes the descriptor to purchase history and updates
       
  1296         // content type
       
  1297         UpdatePurchaseHistoryL( KNullDesC() ); 
       
  1298         
       
  1299         return EFalse;
       
  1300         }
       
  1301 
       
  1302     // Notice that purchase history has to be updated before sending any
       
  1303     // notifications to server to prevent situations where purchase history
       
  1304     // could not be updated after notification sending.
       
  1305     // (examples of such situations: out of memory, user cancellation)
       
  1306     // Notice also that the update is not done if download state is
       
  1307     // ESendNotification to prevent double update (before notification
       
  1308     // sending and after).
       
  1309     DASSERT( iContentFilename );
       
  1310     UpdatePurchaseHistoryL( *iContentFilename );
       
  1311 
       
  1312     // Update node's status from the purchase history
       
  1313     DLTRACE(("Updating node from purchase history"));
       
  1314     iNodeManager->DownloadDataHandlerL( iNode->Identifier() );
       
  1315 
       
  1316 
       
  1317     SendOmaNotificationL( info );
       
  1318     
       
  1319     delete iContentFilename;
       
  1320     iContentFilename = NULL;
       
  1321     
       
  1322     // Reset URI and mime
       
  1323     iContentUri.Set( KNullDesC );
       
  1324     iContentMime.Set( KNullDesC );
       
  1325     iNotificationUri.Set( KNullDesC );
       
  1326     iDownloadType = EDescriptorUnknown;
       
  1327     iContentDownloadState = EDownloadDone;
       
  1328     iReportId = KNcdReportNotSupported;
       
  1329     SaveStateL();
       
  1330     return ETrue;
       
  1331     }
       
  1332     
       
  1333     
       
  1334 // ---------------------------------------------------------------------------
       
  1335 // UpdatePurchaseHistoryL
       
  1336 // ---------------------------------------------------------------------------
       
  1337 //
       
  1338 void CNcdContentDownloadOperation::UpdatePurchaseHistoryL( 
       
  1339     const TDesC& aDownloadedFile )
       
  1340     {    
       
  1341     DLTRACEIN(("Updating download in index: %d", iDownloadIndex ));
       
  1342     
       
  1343     CNcdPurchaseDetails* purchase = GetPurchaseDetailsLC();
       
  1344 
       
  1345     if ( !purchase->DownloadInfo( iDownloadIndex ).ContentMimeType().Length() )
       
  1346         {
       
  1347         DLTRACE(( _L("Updating mime type to purchase details, Mime: %S"), 
       
  1348             &iContentMime ));                
       
  1349         purchase->DownloadInfo( iDownloadIndex ).SetContentMimeTypeL( 
       
  1350             iContentMime );        
       
  1351         }
       
  1352         
       
  1353     if ( iDescriptor )
       
  1354         {
       
  1355         DLTRACE(("Setting descriptor data, length: %d", iDescriptor->Length() ));
       
  1356 
       
  1357         if ( iDownloadType == EDescriptorDd ) 
       
  1358             {
       
  1359             purchase->DownloadInfo( iDownloadIndex ).SetDescriptorTypeL( 
       
  1360                 KDescriptorTypeOdd );
       
  1361             }
       
  1362         else if ( iDownloadType == EDescriptorJad )
       
  1363             {
       
  1364             purchase->DownloadInfo( iDownloadIndex ).SetDescriptorTypeL( 
       
  1365                 KDescriptorTypeJad );
       
  1366             }
       
  1367 
       
  1368         // Write the descriptor data only if it's of a known type
       
  1369         if ( iDownloadType != EDescriptorUnknown )
       
  1370             {            
       
  1371             purchase->DownloadInfo( iDownloadIndex ).SetDescriptorDataL(
       
  1372                 *iDescriptor );
       
  1373             }
       
  1374            
       
  1375         delete iDescriptor;
       
  1376         iDescriptor = NULL;
       
  1377         }
       
  1378     
       
  1379     // This download needs to be handled afterwards
       
  1380     purchase->DownloadInfo( iDownloadIndex ).SetAttributeL( 
       
  1381         MNcdPurchaseDownloadInfo::EDownloadAttributeRequiredDownload, 1 );
       
  1382 
       
  1383     
       
  1384     DASSERT( iDownloadIndex < purchase->DownloadedFiles().MdcaCount() );
       
  1385     
       
  1386     // 
       
  1387     purchase->ReplaceDownloadedFileL( iDownloadIndex, aDownloadedFile );
       
  1388 
       
  1389     DLTRACE(("Saving purchase history"));
       
  1390     iNodeManager->PurchaseHistory().SavePurchaseL( *purchase, EFalse );
       
  1391     
       
  1392     CleanupStack::PopAndDestroy( purchase );
       
  1393     DLTRACEOUT(("Purchase history updated"));
       
  1394     }
       
  1395 
       
  1396 
       
  1397 // ---------------------------------------------------------------------------
       
  1398 // Updates a skipped download to purchase history
       
  1399 // ---------------------------------------------------------------------------
       
  1400 //    
       
  1401 void CNcdContentDownloadOperation::UpdateSkippedDownloadToPurchaseHistoryL(
       
  1402     TInt aIndex )
       
  1403     {
       
  1404     DLTRACEIN(("Updating download in index: %d", aIndex ));
       
  1405         
       
  1406     CNcdPurchaseDetails* purchase = GetPurchaseDetailsLC();
       
  1407     
       
  1408     purchase->DownloadInfo( aIndex ).SetAttributeL( 
       
  1409         MNcdPurchaseDownloadInfo::EDownloadAttributeRequiredDownload, 0 );
       
  1410         
       
  1411     purchase->ReplaceDownloadedFileL( aIndex, KNullDesC );
       
  1412     
       
  1413     DLTRACE(("Saving purchase history"));
       
  1414     iNodeManager->PurchaseHistory().SavePurchaseL( *purchase, EFalse );
       
  1415     
       
  1416     CleanupStack::PopAndDestroy( purchase );
       
  1417     DLTRACEOUT(("Purchase history updated"));
       
  1418 
       
  1419     }
       
  1420 
       
  1421 // ---------------------------------------------------------------------------
       
  1422 // Updates the download headers
       
  1423 // ---------------------------------------------------------------------------
       
  1424 //    
       
  1425 void CNcdContentDownloadOperation::UpdateHeadersL( 
       
  1426     MCatalogsHttpHeaders& aHeaders )
       
  1427     {    
       
  1428     DLTRACEIN((""));
       
  1429     
       
  1430     DLTRACE(( _L("Client id: %S"), &iConfigurationManager.ClientIdL( 
       
  1431         iContext) ));    
       
  1432     
       
  1433     // Add ClientId, SSID and sessionId to file downloads    
       
  1434     aHeaders.AddHeaderL( NcdHttpHeaders::KClientIdHeader, 
       
  1435         iConfigurationManager.ClientIdL( iContext) );
       
  1436     aHeaders.AddHeaderL( NcdHttpHeaders::KSsidHeader, 
       
  1437         iConfigurationManager.SsidL( iContext) );
       
  1438         
       
  1439     if ( iSessionId )
       
  1440         {  
       
  1441         DLTRACE(( _L("Adding session id: %S"), iSessionId ));      
       
  1442         aHeaders.AddHeaderL( NcdHttpHeaders::KSessionIdHeader, *iSessionId );
       
  1443         }
       
  1444     DLTRACEOUT(( "" ));
       
  1445     }
       
  1446     
       
  1447 
       
  1448 // ---------------------------------------------------------------------------
       
  1449 // Resets the correct pointer
       
  1450 // ---------------------------------------------------------------------------
       
  1451 //      
       
  1452 void CNcdContentDownloadOperation::ReleaseDownload( 
       
  1453     CNcdBaseOperation* aOperation )
       
  1454     {
       
  1455     if ( aOperation == static_cast<CNcdBaseOperation*>( iDownload ) )
       
  1456         {
       
  1457         iDownload = NULL;
       
  1458         }
       
  1459     else if ( aOperation == static_cast<CNcdBaseOperation*>( 
       
  1460         iDescriptorDownload ) )
       
  1461         {
       
  1462         iDescriptorDownload = NULL;            
       
  1463         }
       
  1464     else
       
  1465         {
       
  1466         NCD_ASSERT_ALWAYS( 0, ENcdPanicInvalidArgument );
       
  1467         }
       
  1468     aOperation->Close();
       
  1469     }
       
  1470         
       
  1471 
       
  1472 // ---------------------------------------------------------------------------
       
  1473 // Handles a download descriptor
       
  1474 // ---------------------------------------------------------------------------
       
  1475 //      
       
  1476 void CNcdContentDownloadOperation::HandleDescriptorL( 
       
  1477     const TDesC& aDescriptorType, const TDesC8& aDescriptor )
       
  1478     {
       
  1479     DLTRACEIN((""));
       
  1480     DLINFO(("Descriptor: %S", &aDescriptor));
       
  1481     // Start descriptor parsing
       
  1482     iContentDescriptor->SetDescriptorL( 
       
  1483         aDescriptorType,
       
  1484         aDescriptor );
       
  1485         
       
  1486     if ( iContentDescriptor->DataUriL().Length() ) 
       
  1487         {
       
  1488         DLINFO(( _L("Data URI from descriptor: %S"), 
       
  1489             &iContentDescriptor->DataUriL() ));
       
  1490         iContentUri.Set( iContentDescriptor->DataUriL() );        
       
  1491         }         
       
  1492         
       
  1493     if ( iContentDescriptor->MimeType().Length() ) 
       
  1494         {
       
  1495         DLINFO(( _L("Setting content mime as: %S"), 
       
  1496             &iContentDescriptor->MimeType() ));
       
  1497             
       
  1498         iContentMime.Set( iContentDescriptor->MimeType() );
       
  1499         }
       
  1500     
       
  1501     // Update type of the download
       
  1502     iDownloadType = MatchDescriptor( aDescriptorType );   
       
  1503     
       
  1504     if ( iContentDescriptor && 
       
  1505          iContentDescriptor->InstallNotificationUri().Length() )
       
  1506         {
       
  1507         // Send notification only for DDs because installer
       
  1508         // handles JADs
       
  1509         if ( iDownloadType == EDescriptorDd ) 
       
  1510             {
       
  1511             DLTRACEOUT(("Setting state as ESendNotification, using URI from descriptor"));
       
  1512             iNotificationUri.Set( 
       
  1513                 iContentDescriptor->InstallNotificationUri() );
       
  1514             }
       
  1515         else 
       
  1516             {
       
  1517             iNotificationUri.Set( KNullDesC );
       
  1518             }
       
  1519         }
       
  1520         
       
  1521     }
       
  1522 
       
  1523 
       
  1524 // ---------------------------------------------------------------------------
       
  1525 // 
       
  1526 // ---------------------------------------------------------------------------
       
  1527 //      
       
  1528 void CNcdContentDownloadOperation::InitializeDownloadL( TInt aIndex )
       
  1529     {
       
  1530     DLTRACEIN(( "Download index: %d", aIndex ));
       
  1531 
       
  1532     DASSERT( aIndex >= 0 );
       
  1533     
       
  1534     // Find the next file that needs to be downloaded
       
  1535     if ( aIndex >= iNodeDownload->DownloadInfo().Count() ||
       
  1536          SkipInstalledFilesL() ) 
       
  1537         {
       
  1538         DLTRACEOUT(("Everything has been installed already"));
       
  1539         User::Leave( KNoDownloads );
       
  1540         }
       
  1541     
       
  1542     aIndex = iDownloadIndex;
       
  1543         
       
  1544     // Get download info for the current DL
       
  1545     const MNcdPurchaseDownloadInfo& info = *iNodeDownload->DownloadInfo()[
       
  1546         aIndex ];
       
  1547 
       
  1548     
       
  1549     HBufC* clientDataPath = CNcdProviderUtils::EngineConfig().ClientDataPathLC( 
       
  1550         iGeneralManager.FamilyName(), EFalse );
       
  1551     
       
  1552     DASSERT( clientDataPath );
       
  1553     DLINFO(( _L("Client data path: %S"), clientDataPath ));  
       
  1554     WouldDiskSpaceGoBelowCriticalLevelL( *clientDataPath,
       
  1555         CNcdProviderUtils::FileSession(), 
       
  1556         info.ContentSize() );
       
  1557     
       
  1558     DLTRACE(("Reset progress to -1"));
       
  1559     iProgress.iState = iCurrentFile;
       
  1560     iProgress.iOperationId = iTotalFileCount;
       
  1561     
       
  1562     iProgress.iProgress = -1;
       
  1563     iProgress.iMaxProgress = -1;
       
  1564     
       
  1565     const CNcdNodeIdentifier& identifier = 
       
  1566         iNode->NodeMetaDataL().Identifier();
       
  1567     
       
  1568     // Handle required descriptors    
       
  1569     if ( iContentDownloadState < ERightsDownload && info.RightsUri().Length() ) 
       
  1570         {
       
  1571         DLTRACE(( _L("Creating descriptor download operation for Rights-URI: %S"),
       
  1572             &info.RightsUri() ));
       
  1573         iContentDownloadState = ERightsDownload;
       
  1574         iDescriptorDownload = CNcdDescriptorDownloadSubOperation::NewL( 
       
  1575             iGeneralManager,
       
  1576             iHttpSession, 
       
  1577             info.RightsUri(), 
       
  1578             *this, 
       
  1579             iSession );
       
  1580         
       
  1581         iDescriptorDownload->Config().SetConnectionMethod( iApId );
       
  1582         UpdateHeadersL( iDescriptorDownload->RequestHeaders() );
       
  1583         CleanupStack::PopAndDestroy( clientDataPath );
       
  1584 
       
  1585         RegisterDownloadL( info.RightsUri(), identifier );
       
  1586         return;
       
  1587         }
       
  1588         
       
  1589     else if ( info.RightsUri().Length() <= 0 && info.RightsType().Length() )
       
  1590         {
       
  1591         DLERROR(( _L("Rights type set but no Rights Uri available -> ERROR!") ));
       
  1592         User::Leave( KErrNotFound );
       
  1593         }
       
  1594     
       
  1595     // Handle descriptor embedded in the protocol response
       
  1596     // Embedded descriptors don't have DescriptorUris
       
  1597     else if ( iContentDownloadState < EEmbeddedDescriptor && 
       
  1598               info.DescriptorData().Length() && 
       
  1599               !info.DescriptorUri().Length() ) 
       
  1600         {
       
  1601         DLTRACE(("Handling embedded descriptor"));
       
  1602         HandleDescriptorL( info.DescriptorType(), info.DescriptorData() );
       
  1603         iContentDownloadState = EEmbeddedDescriptor;                
       
  1604         }
       
  1605     // Handle descriptor URI from the protocol response
       
  1606     else if ( iContentDownloadState < EDescriptorDownload &&
       
  1607               info.DescriptorUri().Length() ) 
       
  1608         {
       
  1609         DLTRACE(( _L("Download descriptor from URI: %S"),
       
  1610             &info.DescriptorUri() ));
       
  1611             
       
  1612         iDescriptorDownload = CNcdDescriptorDownloadSubOperation::NewL( 
       
  1613             iGeneralManager,
       
  1614             iHttpSession, 
       
  1615             info.DescriptorUri(), 
       
  1616             *this, 
       
  1617             iSession );
       
  1618                     
       
  1619         iDescriptorDownload->Config().SetConnectionMethod( iApId );
       
  1620         
       
  1621         UpdateHeadersL( iDescriptorDownload->RequestHeaders() );
       
  1622         iContentDownloadState = EDescriptorDownload;        
       
  1623         CleanupStack::PopAndDestroy( clientDataPath );
       
  1624 
       
  1625         RegisterDownloadL( info.DescriptorUri(), identifier );
       
  1626         // Don't start content download just yet
       
  1627         return;
       
  1628         }
       
  1629     
       
  1630     // Note: embedded descriptor handling continues in here -> no "else if"
       
  1631     if ( iContentDownloadState <= EContentDownload )
       
  1632         {
       
  1633         
       
  1634         // Content download
       
  1635         DLTRACE(("Handling content download"));
       
  1636         if ( !iContentUri.Length() ) 
       
  1637             {            
       
  1638             iContentUri.Set( info.ContentUri() );
       
  1639             
       
  1640             DLTRACE(( _L("Content URI from protocol response: %S"),
       
  1641                 &iContentUri ));
       
  1642             }
       
  1643         
       
  1644         if ( !iContentMime.Length() )
       
  1645             {
       
  1646             iContentMime.Set( info.ContentMimeType() );
       
  1647             DLTRACE(( _L("Content mimetype from protocol response: %S"),
       
  1648                 &iContentMime ));
       
  1649                 
       
  1650             // Dependencies and upgrades don't necessarily share the mime type
       
  1651             // with the actual content so we don't update it from the protocol for
       
  1652             // them        
       
  1653             if ( !iContentMime.Length() && 
       
  1654                  info.ContentUsage() != MNcdPurchaseDownloadInfo::EDependency ) 
       
  1655                 {
       
  1656                 const CNcdNodeContentInfo* contentInfo = NULL;
       
  1657                 
       
  1658                 TRAP_IGNORE( contentInfo = 
       
  1659                     &iNode->NodeMetaDataL().ContentInfoL() );
       
  1660                 if ( contentInfo ) 
       
  1661                     {                    
       
  1662                     DLTRACE(( _L("Content mimetype from content info: %S"),
       
  1663                         &iContentMime ));                            
       
  1664                     iContentMime.Set( contentInfo->MimeType() );
       
  1665                     }
       
  1666                 }
       
  1667             }
       
  1668         iContentDownloadState = EContentDownload;
       
  1669         
       
  1670         if ( info.InstallNotificationUri().Length() ) 
       
  1671             {
       
  1672             iNotificationUri.Set( info.InstallNotificationUri() );
       
  1673             DLINFO(( _L("Set install notification URI: %S"), 
       
  1674                 &iNotificationUri ));
       
  1675             }
       
  1676 
       
  1677         iDownload = CNcdDownloadSubOperation::NewL( 
       
  1678             iGeneralManager,
       
  1679             iHttpSession,
       
  1680             iContentUri,
       
  1681             *clientDataPath,
       
  1682             *this,
       
  1683             iSession );
       
  1684                         
       
  1685         iDownload->HttpOperation().SetContentTypeL( iContentMime );
       
  1686            
       
  1687         // Force HTTP header getting with transactions because DL manager doesn't
       
  1688         // support content-disposition for file names etc.
       
  1689         
       
  1690         iDownload->HttpOperation().SetHeaderMode( 
       
  1691             ECatalogsHttpHeaderModeForceHead );        
       
  1692         iDownload->Config().SetConnectionMethod( iApId );
       
  1693         
       
  1694         // Ensure that we use HEAD when downloading content files from
       
  1695         // URIs that we got from descriptors even if HEAD has been
       
  1696         // disabled
       
  1697         if ( iDownloadType != EDescriptorUnknown ) 
       
  1698             {
       
  1699             iDownload->Config().SetOptions(
       
  1700                 iDownload->Config().Options() & ~ECatalogsHttpDisableHeadRequest );
       
  1701             }
       
  1702         
       
  1703         // Get mime type set in the protocol/descriptor
       
  1704         AssignDesL( iMimeType, info.ContentMimeType() );
       
  1705         iMimeUpdated = EFalse;
       
  1706         
       
  1707         UpdateHeadersL( iDownload->RequestHeaders() );    
       
  1708         
       
  1709         const CNcdNodeIdentifier& identifier = 
       
  1710             iNode->NodeMetaDataL().Identifier();
       
  1711 
       
  1712         RegisterDownloadL( iContentUri, identifier );
       
  1713         }
       
  1714 
       
  1715     CleanupStack::PopAndDestroy( clientDataPath );    
       
  1716     }
       
  1717   
       
  1718   
       
  1719 // ---------------------------------------------------------------------------
       
  1720 // 
       
  1721 // ---------------------------------------------------------------------------
       
  1722 //      
       
  1723 TBool CNcdContentDownloadOperation::IsFileInstalledL( 
       
  1724     TInt aIndex, 
       
  1725     TBool aCheckOnly )
       
  1726     {
       
  1727     DLTRACEIN((""));
       
  1728     const MNcdPurchaseDownloadInfo& info = 
       
  1729         *iNodeDownload->DownloadInfo()[ aIndex ];
       
  1730 
       
  1731     // AttributeInt32L leaves only with KErrNotFound and if that happens,
       
  1732     // it means that this file has not been handled before -> Buy
       
  1733     TRAPD( isFirstDownload, info.AttributeInt32L( 
       
  1734         MNcdPurchaseDownloadInfo::EDownloadAttributeRequiredDownload ) );
       
  1735 
       
  1736     // If handling buy, we can not skip content downloads
       
  1737     if ( isFirstDownload &&
       
  1738          info.ContentUsage() == MNcdPurchaseDownloadInfo::EDownloadable )
       
  1739         {
       
  1740         DLTRACEOUT(("Not a dependency"));
       
  1741         return EFalse;
       
  1742         }
       
  1743 
       
  1744     // If launcher is defined but there's no URI, there's no point
       
  1745     // checking whether it is installed or not because can't download it
       
  1746     // anyway
       
  1747     if ( !info.ContentUri().Length() &&
       
  1748          IsOneOf( info.ContentUsage(), 
       
  1749             MNcdPurchaseDownloadInfo::ELauncher,
       
  1750             MNcdPurchaseDownloadInfo::ELauncherOpen ) ) 
       
  1751         {
       
  1752         DLTRACEOUT(("Launcher without URI, skip"));
       
  1753         // This ensures that for instance MNcdNodeDownload::IsDownloadedL
       
  1754         // ignores these files         
       
  1755         if ( !aCheckOnly ) 
       
  1756             {            
       
  1757             UpdateSkippedDownloadToPurchaseHistoryL( aIndex );
       
  1758             }
       
  1759         return ETrue;
       
  1760         }
       
  1761 
       
  1762     CNcdNodeInstall* install = NULL;
       
  1763     TRAPD( err, install = &iNode->NodeMetaData()->InstallL() );
       
  1764     
       
  1765     if ( err != KErrNone ) 
       
  1766         {
       
  1767         DLERROR(("Error %d when getting CNcdNodeInstall", err));
       
  1768         if ( err == KErrNotFound ) 
       
  1769             {
       
  1770             return EFalse;
       
  1771             }
       
  1772         User::Leave( err );
       
  1773         }
       
  1774             
       
  1775     TBool available = 
       
  1776         ( install->IsContentInstalledL( aIndex, EFalse ) >= ENcdApplicationInstalled );
       
  1777     
       
  1778     if ( available && !aCheckOnly ) 
       
  1779         {
       
  1780         // This ensures that for instance MNcdNodeDownload::IsDownloadedL
       
  1781         // ignores these files 
       
  1782         UpdateSkippedDownloadToPurchaseHistoryL( aIndex );
       
  1783         }
       
  1784     DLTRACEOUT(("Content installed: %d", available));
       
  1785     return available;
       
  1786     }    
       
  1787 
       
  1788 
       
  1789 // ---------------------------------------------------------------------------
       
  1790 // 
       
  1791 // ---------------------------------------------------------------------------
       
  1792 //      
       
  1793 TBool CNcdContentDownloadOperation::SkipInstalledFilesL()
       
  1794     {
       
  1795     DLTRACEIN((""));
       
  1796     TBool installed = ETrue;
       
  1797     TInt count = iNodeDownload->DownloadInfo().Count();
       
  1798     
       
  1799     while ( installed && iDownloadIndex < count )
       
  1800         {        
       
  1801         DLTRACE(("Checking deps for index: %d", iDownloadIndex ));
       
  1802             // Get download info for the current DL
       
  1803 
       
  1804         // Check if dependency/upgrade has already been installed
       
  1805         if ( !IsFileInstalledL( iDownloadIndex, EFalse ) ) 
       
  1806             {
       
  1807             installed = EFalse;            
       
  1808             }
       
  1809         else 
       
  1810             {            
       
  1811             ++iDownloadIndex;
       
  1812             }
       
  1813         }
       
  1814     
       
  1815     if ( installed ) 
       
  1816         {
       
  1817         DLTRACE(("All files have been downloaded or installed"));
       
  1818         //iOperationState = EStateComplete;
       
  1819         iDownloadState = ENcdDownloadComplete;
       
  1820         }
       
  1821     return installed;
       
  1822     }
       
  1823 
       
  1824 
       
  1825 // ---------------------------------------------------------------------------
       
  1826 // 
       
  1827 // ---------------------------------------------------------------------------
       
  1828 //      
       
  1829 TInt CNcdContentDownloadOperation::CalculateMissingFilesL()
       
  1830     {
       
  1831     DLTRACEIN((""));    
       
  1832     TInt count = iNodeDownload->DownloadInfo().Count();    
       
  1833     TInt missing = 0;
       
  1834     
       
  1835     while ( count-- )
       
  1836         {        
       
  1837         // Check if the file is already installed
       
  1838         if ( !IsFileInstalledL( count, ETrue ) ) 
       
  1839             {
       
  1840             missing++;
       
  1841             }
       
  1842         }
       
  1843     
       
  1844     DLTRACEOUT(("Missing: %d files", missing));
       
  1845     return missing;
       
  1846     }
       
  1847         
       
  1848 
       
  1849 // ---------------------------------------------------------------------------
       
  1850 // Saves the current state of the download to db
       
  1851 // ---------------------------------------------------------------------------
       
  1852 //      
       
  1853 void CNcdContentDownloadOperation::SaveStateL()
       
  1854     {
       
  1855     DLTRACEIN((""));
       
  1856     DASSERT( iStorageUid );
       
  1857     // Externalize the download
       
  1858     MNcdStorageItem* item = iStorage.StorageItemL( *iStorageUid, 
       
  1859         NcdProviderDefines::ENcdDownloadData );
       
  1860     item->SetDataItem( this );
       
  1861     item->OpenL();
       
  1862     item->WriteDataL();
       
  1863     
       
  1864     item->SaveL();
       
  1865     iStorage.CommitL();
       
  1866     DLTRACEOUT(("Download state saved"));
       
  1867     }
       
  1868 
       
  1869 
       
  1870 // ---------------------------------------------------------------------------
       
  1871 // 
       
  1872 // ---------------------------------------------------------------------------
       
  1873 //      
       
  1874 void CNcdContentDownloadOperation::GenerateStorageUidL()
       
  1875     {    
       
  1876     DLTRACEIN((""));
       
  1877     
       
  1878     // Enough for timestamp (64bit) + rand (32bit)
       
  1879     HBufC* id = HBufC::NewLC( NcdProviderDefines::KClientIdMaxLength );  
       
  1880 
       
  1881     TTime now;
       
  1882     now.HomeTime();
       
  1883     TInt64 int64 = now.Int64();
       
  1884     
       
  1885     TInt64 ptrInt = reinterpret_cast<TInt64>( this );
       
  1886     // Use both timestamp and free disk space to get a unique seed
       
  1887     TInt rand = Math::Rand( ptrInt );
       
  1888 
       
  1889     TPtr ptr( id->Des() );
       
  1890 
       
  1891 
       
  1892     ptr.NumFixedWidth( int64 >> 32, EHex, 8 );
       
  1893     ptr.AppendNumFixedWidth( int64 & 0xffffffff, EHex, 8 );
       
  1894     ptr.AppendNumFixedWidth( rand, EHex, 8 );
       
  1895     
       
  1896     delete iStorageUid;    
       
  1897     iStorageUid = id;
       
  1898     CleanupStack::Pop( id );
       
  1899     }
       
  1900 
       
  1901 
       
  1902 // ---------------------------------------------------------------------------
       
  1903 // Removes state information from the download db
       
  1904 // ---------------------------------------------------------------------------
       
  1905 //      
       
  1906 void CNcdContentDownloadOperation::RemoveTempInfoL()
       
  1907     {
       
  1908     DLTRACEIN((""));
       
  1909     MNcdStorageItem* item = iStorage.StorageItemL( *iStorageUid, 
       
  1910         NcdProviderDefines::ENcdDownloadData );
       
  1911     
       
  1912     item->RemoveFromStorageL();
       
  1913     iStorage.CommitL();
       
  1914     DLTRACEOUT(("Temp info removed successfully"));
       
  1915     }
       
  1916 
       
  1917 // ---------------------------------------------------------------------------
       
  1918 // 
       
  1919 // ---------------------------------------------------------------------------
       
  1920 //      
       
  1921 CNcdContentDownloadOperation::TDescriptorType 
       
  1922     CNcdContentDownloadOperation::MatchDescriptor( 
       
  1923     const TDesC& aMimeType ) const
       
  1924     {
       
  1925     DLTRACEIN((""));
       
  1926     if ( aMimeType.MatchF( KMimeTypeMatchJad ) != KErrNotFound ||
       
  1927          aMimeType.CompareF( KDescriptorTypeJad ) == 0 )
       
  1928         {
       
  1929         DLTRACEOUT(("Jad"));
       
  1930         return EDescriptorJad;
       
  1931         }
       
  1932     else if ( aMimeType.MatchF( KMimeTypeMatchOdd ) != KErrNotFound ||
       
  1933               aMimeType.CompareF( KDescriptorTypeOdd ) == 0 )
       
  1934         {
       
  1935         DLTRACEOUT(("DD"));
       
  1936         return EDescriptorDd;
       
  1937         }
       
  1938     DLTRACEOUT(("Unknown/not a descriptor"));
       
  1939     return EDescriptorUnknown;
       
  1940     }
       
  1941 
       
  1942 
       
  1943 // ---------------------------------------------------------------------------
       
  1944 // GetPurchaseDetailsLC
       
  1945 // ---------------------------------------------------------------------------
       
  1946 //    
       
  1947 CNcdPurchaseDetails* CNcdContentDownloadOperation::GetPurchaseDetailsLC()
       
  1948     {
       
  1949     DLTRACEIN((""))    
       
  1950         
       
  1951     return NcdPurchaseHistoryUtils::PurchaseDetailsLC( 
       
  1952         iNodeManager->PurchaseHistory(), 
       
  1953         iContext.FamilyId(),
       
  1954         iNode->NodeLinkL().MetaDataIdentifier(),
       
  1955         EFalse );
       
  1956     }
       
  1957     
       
  1958     
       
  1959 // ---------------------------------------------------------------------------
       
  1960 // UpdateAccessPointsL
       
  1961 // ---------------------------------------------------------------------------
       
  1962 //
       
  1963 void CNcdContentDownloadOperation::UpdateAccessPointsL( 
       
  1964     const CNcdNodeIdentifier& aNodeId )
       
  1965     {
       
  1966     DLTRACEIN((""));
       
  1967     // Get origin node id from purchase history
       
  1968     CNcdPurchaseDetails* purchase = GetPurchaseDetailsLC();
       
  1969     
       
  1970     // Create origin identifier
       
  1971     CNcdNodeIdentifier* originIdentifier = CNcdNodeIdentifier::NewL(
       
  1972         aNodeId.NodeNameSpace(), purchase->OriginNodeId(), aNodeId.ClientUid() );
       
  1973     CleanupStack::PopAndDestroy( purchase );
       
  1974     
       
  1975     CleanupStack::PushL( originIdentifier );
       
  1976     
       
  1977     // Get download ap
       
  1978     TUint32 apId = 0;
       
  1979     
       
  1980     TInt error = iAccessPointManager.AccessPointIdL(
       
  1981         *originIdentifier, 
       
  1982         MCatalogsAccessPointManager::EDownload, 
       
  1983         iContext.FamilyId(), 
       
  1984         apId );
       
  1985     
       
  1986     if ( error == KErrNone ) 
       
  1987         {
       
  1988         DLTRACE(( "Setting access point %d for content download", apId ))   
       
  1989         iApId = TCatalogsConnectionMethod( 
       
  1990             apId, 
       
  1991             ECatalogsConnectionMethodTypeAccessPoint );
       
  1992         }
       
  1993     
       
  1994     // Get report ap    
       
  1995     apId = 0;
       
  1996     error = iAccessPointManager.AccessPointIdL(
       
  1997         *originIdentifier, 
       
  1998         MCatalogsAccessPointManager::EBrowse, 
       
  1999         iContext.FamilyId(), 
       
  2000         apId );
       
  2001         
       
  2002     if ( error == KErrNone ) 
       
  2003         {
       
  2004         DLTRACE(( "Setting access point %d for reports", apId ))   
       
  2005         iReportAp = TCatalogsConnectionMethod( 
       
  2006             apId, 
       
  2007             ECatalogsConnectionMethodTypeAccessPoint );
       
  2008         }
       
  2009     
       
  2010     if ( iReportAp.iId == 0 ) 
       
  2011         {
       
  2012         iReportAp = iHttpSession.ConnectionManager().DefaultConnectionMethod();
       
  2013         }
       
  2014     CleanupStack::PopAndDestroy( originIdentifier );
       
  2015 
       
  2016     }
       
  2017 
       
  2018 
       
  2019 // ---------------------------------------------------------------------------
       
  2020 // Report download status
       
  2021 // ---------------------------------------------------------------------------
       
  2022 //
       
  2023 void CNcdContentDownloadOperation::ReportStatusL( 
       
  2024     const TNcdReportStatusInfo& aStatus,
       
  2025     TBool aSendable )
       
  2026     {
       
  2027     DLTRACEIN(("aStatus: %d", aStatus.iStatus));
       
  2028     iReportObserver.ReportDownloadStatusL(
       
  2029         iReportId,
       
  2030         aStatus,
       
  2031         aSendable );
       
  2032     }
       
  2033 
       
  2034 
       
  2035 // ---------------------------------------------------------------------------
       
  2036 // 
       
  2037 // ---------------------------------------------------------------------------
       
  2038 //      
       
  2039 void CNcdContentDownloadOperation::SendOmaNotificationL( 
       
  2040     const TNcdReportStatusInfo& aStatus )
       
  2041     {
       
  2042     DLTRACEIN((""));
       
  2043     if ( ( aStatus.iStatus != ENcdReportCancel && aStatus.iStatus != ENcdReportSuccess ) ||
       
  2044         !iContentUri.Length() ||
       
  2045         !iNotificationUri.Length() )
       
  2046         {
       
  2047         DLTRACEOUT(("Nothing to report"));
       
  2048         return;
       
  2049         }
       
  2050     
       
  2051     const CNcdNodeIdentifier& identifier = 
       
  2052         iNode->NodeMetaDataL().Identifier();
       
  2053     
       
  2054     TNcdReportStatusInfo info( ENcdReportCreate, KErrNone );
       
  2055     TNcdReportId omaReportId = iReportObserver.RegisterOmaDownloadL( 
       
  2056         iContentUri,
       
  2057         identifier,
       
  2058         info,
       
  2059         iNotificationUri );
       
  2060     
       
  2061     iReportObserver.SetDownloadReportAccessPoint(
       
  2062         omaReportId,
       
  2063         iApId );
       
  2064         
       
  2065     DLTRACE(("Report registered, now trigger sending"));
       
  2066     iReportObserver.ReportDownloadStatusL(
       
  2067         omaReportId,
       
  2068         aStatus,
       
  2069         ETrue );            
       
  2070     DLTRACEOUT(("Report sending initiated"));
       
  2071     }
       
  2072 
       
  2073 
       
  2074 // ---------------------------------------------------------------------------
       
  2075 // 
       
  2076 // ---------------------------------------------------------------------------
       
  2077 //      
       
  2078 void CNcdContentDownloadOperation::UpdateDependenciesL()
       
  2079     {
       
  2080     DLTRACEIN((""));
       
  2081     CNcdPurchaseDetails* purchase = GetPurchaseDetailsLC();
       
  2082             
       
  2083     iNode->NodeMetaDataL().DependencyL().UpdateDependenciesL( *purchase );
       
  2084     
       
  2085     DLTRACE(("Saving purchase history"));
       
  2086     iNodeManager->PurchaseHistory().SavePurchaseL( *purchase, EFalse );
       
  2087     
       
  2088     DLTRACE(("Updating node download from purchase details"));
       
  2089     iNodeDownload->InternalizeL( *purchase );
       
  2090     
       
  2091     DLTRACE(("Updating node install from purchase details"));
       
  2092     CNcdNodeInstall& install = iNode->NodeMetaData()->InstallL();
       
  2093     install.InternalizeL( *purchase );
       
  2094     
       
  2095     CleanupStack::PopAndDestroy( purchase );
       
  2096     iDependenciesUpdated = ETrue;
       
  2097     DLTRACEOUT(("Purchase history updated"));
       
  2098     }
       
  2099 
       
  2100 
       
  2101 // ---------------------------------------------------------------------------
       
  2102 // 
       
  2103 // ---------------------------------------------------------------------------
       
  2104 //      
       
  2105 void CNcdContentDownloadOperation::GetPausableStateL( 
       
  2106     MCatalogsBaseMessage& aMessage )
       
  2107     {
       
  2108     DLTRACEIN((""));
       
  2109     TInt pausableState = KNcdDownloadIsNotPausable;
       
  2110     if ( iDownload && iDownload->HttpOperation().IsPausable() ) 
       
  2111         {
       
  2112         DLTRACE(("Download is pausable"));
       
  2113         pausableState = KNcdDownloadIsPausable;
       
  2114         }
       
  2115                 
       
  2116     aMessage.CompleteAndReleaseL(
       
  2117         pausableState, 
       
  2118         KErrNone );    
       
  2119     }
       
  2120 
       
  2121 
       
  2122 // ---------------------------------------------------------------------------
       
  2123 // 
       
  2124 // ---------------------------------------------------------------------------
       
  2125 //      
       
  2126 void CNcdContentDownloadOperation::RegisterDownloadL(
       
  2127     const TDesC& aUri,
       
  2128     const CNcdNodeIdentifier& aIdentifier )
       
  2129     {
       
  2130     DLTRACEIN((""));
       
  2131     TNcdReportStatusInfo statusInfo( ENcdReportCreate, KErrNone );
       
  2132     iReportId = iReportObserver.RegisterDownloadL( 
       
  2133         aUri,
       
  2134         aIdentifier,
       
  2135         statusInfo,
       
  2136         aIdentifier.ServerUri(),
       
  2137         aIdentifier.NodeNameSpace() );
       
  2138     
       
  2139     iReportObserver.SetDownloadReportAccessPoint( 
       
  2140         iReportId,
       
  2141         iReportAp );    
       
  2142     }