ncdengine/provider/server/src/ncdnodedownloadimpl.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006 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:   Implements CNcdNodeDownload class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <bautils.h>
       
    20 
       
    21 
       
    22 #include "ncdnodedownloadimpl.h"
       
    23 #include "catalogssession.h"
       
    24 #include "catalogsbasemessage.h"
       
    25 #include "ncdnodefunctionids.h"
       
    26 #include "ncdnodeclassids.h"
       
    27 #include "ncdpurchasedetails.h"
       
    28 #include "ncdutils.h"
       
    29 #include "catalogsconstants.h"
       
    30 #include "ncd_pp_dataentity.h"
       
    31 #include "ncd_cp_query.h"
       
    32 #include "catalogsutils.h"
       
    33 #include "catalogsdebug.h"
       
    34 #include "ncdproviderutils.h"
       
    35 
       
    36 
       
    37 CNcdNodeDownload::CNcdNodeDownload( NcdNodeClassIds::TNcdNodeClassId aClassId )
       
    38 : CCatalogsCommunicable(),
       
    39   iClassId( aClassId )
       
    40     {
       
    41     }
       
    42 
       
    43 void CNcdNodeDownload::ConstructL()
       
    44     {
       
    45     }
       
    46 
       
    47 
       
    48 CNcdNodeDownload* CNcdNodeDownload::NewL()
       
    49     {
       
    50     CNcdNodeDownload* self =   
       
    51         CNcdNodeDownload::NewLC();
       
    52     CleanupStack::Pop( self );
       
    53     return self;        
       
    54     }
       
    55 
       
    56 CNcdNodeDownload* CNcdNodeDownload::NewLC()
       
    57     {
       
    58     CNcdNodeDownload* self = 
       
    59         new( ELeave ) CNcdNodeDownload( 
       
    60             NcdNodeClassIds::ENcdNodeDownloadClassId );
       
    61     CleanupClosePushL( *self );
       
    62     self->ConstructL();
       
    63     return self;        
       
    64     }
       
    65 
       
    66 
       
    67 CNcdNodeDownload::~CNcdNodeDownload()
       
    68     {
       
    69     DLTRACEIN((""));
       
    70 
       
    71     // Delete member variables here.
       
    72 
       
    73     TInt count = iDownloadInfo.Count();
       
    74     for ( TInt i = 0; i < count; i++ )
       
    75         {
       
    76         CNcdPurchaseDownloadInfo* info =
       
    77             static_cast<CNcdPurchaseDownloadInfo*>(iDownloadInfo[i]);
       
    78         delete info;
       
    79         info = NULL;
       
    80         }
       
    81     iDownloadInfo.Reset();
       
    82     
       
    83     delete iFiles;
       
    84 
       
    85     DLTRACEOUT((""));
       
    86     }        
       
    87 
       
    88 NcdNodeClassIds::TNcdNodeClassId CNcdNodeDownload::ClassId() const
       
    89     {
       
    90     return iClassId;
       
    91     }
       
    92 
       
    93 
       
    94 // Internalization from the purchase history.
       
    95 
       
    96 TBool CNcdNodeDownload::InternalizeL( const MNcdPurchaseDetails& aDetails )
       
    97     {
       
    98     DLTRACEIN(("this-ptr: %X", this));
       
    99     
       
   100     TArray<MNcdPurchaseDownloadInfo*> dlInfos( aDetails.DownloadInfoL() );
       
   101     
       
   102     TInt count = dlInfos.Count();    
       
   103 
       
   104     // Quit if no download data exists or it's consumable
       
   105     if ( count == 0 || ( count == 1 && 
       
   106          dlInfos[0]->ContentUsage() == 
       
   107          MNcdPurchaseDownloadInfo::EConsumable ))
       
   108         {
       
   109         // No download data found from purchase details.
       
   110         DLTRACEOUT((""));
       
   111         return EFalse;
       
   112         }
       
   113 
       
   114     // Check for any downloadable URIs
       
   115     TBool uriExists = EFalse;
       
   116     for ( TInt i = 0; i < count; ++i ) 
       
   117         {
       
   118         if ( dlInfos[i]->ContentUri().Length() ||
       
   119              dlInfos[i]->DescriptorUri().Length() ||
       
   120              dlInfos[i]->DescriptorData().Length() ||
       
   121              dlInfos[i]->RightsUri().Length() )
       
   122             {
       
   123             uriExists = ETrue;
       
   124             break;
       
   125             }
       
   126         }
       
   127     
       
   128     if ( !uriExists ) 
       
   129         {
       
   130         DLTRACEOUT(("No URI, no download API"));
       
   131         return EFalse;
       
   132         }
       
   133         
       
   134     iIsDownloaded = EFalse;
       
   135     
       
   136     delete iFiles;
       
   137     iFiles = NULL;
       
   138     iFiles = new (ELeave) CDesCArrayFlat( KListGranularity );
       
   139     
       
   140     RPointerArray<MNcdPurchaseDownloadInfo> tempInfos;
       
   141 
       
   142     // Can't use CleanupResetAndDestroyPushL because the array can't
       
   143     // be deleted with ResetAndDestroy
       
   144     TRAPD( err, 
       
   145         {
       
   146         tempInfos.ReserveL( count );
       
   147         DLTRACE(("Copying purchase download infos"));
       
   148         // Download data found from purchase details.
       
   149         for ( TInt i = 0; i < count; i++ )
       
   150             {
       
   151             CNcdPurchaseDownloadInfo* info =
       
   152                 CNcdPurchaseDownloadInfo::NewLC( *dlInfos[i] );
       
   153             tempInfos.AppendL( info );
       
   154             CleanupStack::Pop( info );
       
   155             }
       
   156 
       
   157         // Check purchase details status.
       
   158         if ( aDetails.State() == MNcdPurchaseDetails::EStateDownloaded ||
       
   159              aDetails.State() == MNcdPurchaseDetails::EStateInstalled )
       
   160             {
       
   161             iIsDownloaded = ETrue;
       
   162             DLTRACE(("Copy file paths, iIsDownloaded = ETrue"));
       
   163             const MDesCArray& files( aDetails.DownloadedFiles() );
       
   164             
       
   165             for ( TInt i = 0; i < files.MdcaCount(); ++i )
       
   166                 {
       
   167                 iFiles->AppendL( files.MdcaPoint( i ) );
       
   168                 }
       
   169             }
       
   170 
       
   171         ResetAndDestroyWithCast<CNcdPurchaseDownloadInfo>( iDownloadInfo );
       
   172         iDownloadInfo = tempInfos;
       
   173         
       
   174         });
       
   175         
       
   176     if ( err != KErrNone ) 
       
   177         {
       
   178         ResetAndDestroyWithCast<CNcdPurchaseDownloadInfo>( tempInfos );
       
   179         }
       
   180         
       
   181     DLTRACEOUT(("iIsDownloaded: %d", iIsDownloaded));
       
   182     return ETrue;
       
   183     }
       
   184 
       
   185 const RPointerArray< MNcdPurchaseDownloadInfo >&
       
   186     CNcdNodeDownload::DownloadInfo() const
       
   187     {
       
   188     return iDownloadInfo;
       
   189     }
       
   190 
       
   191 
       
   192 void CNcdNodeDownload::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
   193                                        TInt aFunctionNumber )
       
   194     {
       
   195     DLTRACEIN(("this-ptr: %X", this));    
       
   196 
       
   197     DASSERT( aMessage );
       
   198     
       
   199     // Now, we can be sure that rest of the time iMessage exists.
       
   200     // This member variable is set for the CounterPartLost function.
       
   201     iMessage = aMessage;
       
   202     
       
   203     TInt trapError( KErrNone );
       
   204     
       
   205     // Check which function is called by the proxy side object.
       
   206     // Function number are located in ncdnodefunctinoids.h file.
       
   207     switch( aFunctionNumber )
       
   208         {
       
   209         case NcdNodeFunctionIds::ENcdInternalize:
       
   210             // Internalize the proxy side according to the data
       
   211             // of this object.
       
   212             TRAP( trapError, InternalizeRequestL( *aMessage ) );
       
   213             break;
       
   214 
       
   215         case NcdNodeFunctionIds::ENcdRelease:
       
   216             // The proxy does not want to use this object anymore.
       
   217             // So, release the handle from the session.
       
   218             ReleaseRequest( *aMessage );
       
   219             break;
       
   220 
       
   221         case NcdNodeFunctionIds::ENcdFilesExist:
       
   222             TRAP( trapError, FilesExistRequestL( *aMessage ) );
       
   223             break;
       
   224         default:
       
   225             break;
       
   226         }
       
   227 
       
   228     if ( trapError != KErrNone )
       
   229         {
       
   230         // Because something went wrong, the complete has not been
       
   231         // yet called for the message.
       
   232         // So, inform the client about the error if the
       
   233         // message is still available.
       
   234         aMessage->CompleteAndRelease( trapError );
       
   235         }
       
   236 
       
   237     // Because the message should not be used after this, set it NULL.
       
   238     // So, CounterPartLost function will know that no messages are
       
   239     // waiting the response at the moment.
       
   240     iMessage = NULL;        
       
   241     
       
   242     DLTRACEOUT((""));
       
   243     }
       
   244 
       
   245 void CNcdNodeDownload::CounterPartLost( const MCatalogsSession& aSession )
       
   246     {
       
   247     // This function may be called whenever -- when the message is waiting
       
   248     // response or when the message does not exist.
       
   249     // iMessage may be NULL here, because in the end of the
       
   250     // ReceiveMessage it is set to NULL. The life time of the message
       
   251     // ends shortly after CompleteAndRelease is called.
       
   252     if ( iMessage != NULL )
       
   253         {
       
   254         iMessage->CounterPartLost( aSession );
       
   255         }
       
   256     }
       
   257                 
       
   258 
       
   259 void CNcdNodeDownload::InternalizeRequestL( MCatalogsBaseMessage& aMessage )
       
   260     {
       
   261     DLTRACEIN((""));
       
   262     
       
   263     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   264     CleanupStack::PushL( buf );
       
   265     
       
   266     RBufWriteStream stream( *buf );
       
   267     CleanupClosePushL( stream );
       
   268 
       
   269 
       
   270     // Include all the necessary node data to the stream
       
   271     ExternalizeDataForRequestL( stream );     
       
   272     
       
   273     
       
   274     // Commits data to the stream when closing.
       
   275     CleanupStack::PopAndDestroy( &stream );
       
   276 
       
   277 
       
   278     // If this leaves, ReceiveMessage will complete the message.
       
   279     // NOTE: that here we expect that the buffer contains at least
       
   280     // some data. So, make sure that ExternalizeDataForRequestL inserts
       
   281     // something to the buffer.
       
   282     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );        
       
   283         
       
   284     
       
   285     DLTRACE(("Deleting the buf"));
       
   286     CleanupStack::PopAndDestroy( buf );
       
   287         
       
   288     DLTRACEOUT((""));
       
   289     }
       
   290     
       
   291 
       
   292 void CNcdNodeDownload::ExternalizeDataForRequestL( RWriteStream& aStream )
       
   293     {
       
   294     DLTRACEIN((""));
       
   295 
       
   296     // Download existed. So, insert info that meta data was found.
       
   297     aStream.WriteInt32L( ClassId() );
       
   298 
       
   299     // Add additional content to the stream.
       
   300     // Make sure that this matches to the order that is used in the proxy
       
   301     // side when this stream is internalized.
       
   302     // NOTE: Be careful with the 8- and 16-bit descriptors. Remember to check
       
   303     // if the proxy wants the data in 16 or 8 bits?    
       
   304 
       
   305     aStream.WriteInt32L( iIsDownloaded );
       
   306         
       
   307     DLTRACEOUT(("iIsDownloaded: %d", iIsDownloaded ));
       
   308     }
       
   309 
       
   310 void CNcdNodeDownload::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
       
   311     {
       
   312     DLTRACEIN((""));
       
   313 
       
   314     // Decrease the reference count for this object.
       
   315     // When the reference count reaches zero, this object will be destroyed
       
   316     // and removed from the session.
       
   317     MCatalogsSession& requestSession( aMessage.Session() );
       
   318     TInt handle( aMessage.Handle() );
       
   319 
       
   320     // Send complete information back to proxy.
       
   321     aMessage.CompleteAndRelease( KErrNone );
       
   322         
       
   323     // Remove this object from the session.
       
   324     requestSession.RemoveObject( handle );
       
   325         
       
   326     DLTRACEOUT((""));
       
   327     }
       
   328 
       
   329 
       
   330 void CNcdNodeDownload::FilesExistRequestL( MCatalogsBaseMessage& aMessage )
       
   331     {
       
   332     DLTRACEIN((""));
       
   333 
       
   334     TBool filesExist = EFalse;
       
   335     if ( iIsDownloaded )
       
   336         {
       
   337         filesExist = FilesExist();
       
   338         }
       
   339     
       
   340     // If this leaves, ReceiveMessage will complete the message.
       
   341     // NOTE: that here we expect that the buffer contains at least
       
   342     // some data. So, make sure that ExternalizeDataForRequestL inserts
       
   343     // something to the buffer.
       
   344     aMessage.CompleteAndReleaseL( filesExist, KErrNone );        
       
   345         
       
   346             
       
   347     DLTRACEOUT(("filesExist: %d", filesExist));
       
   348     }
       
   349     
       
   350 
       
   351 
       
   352 TBool CNcdNodeDownload::FilesExist()
       
   353     {
       
   354     DLTRACEIN((""));
       
   355     DASSERT( iFiles->MdcaCount() == iDownloadInfo.Count() );
       
   356     
       
   357     for ( TInt i = 0; i < iFiles->MdcaCount(); ++i )
       
   358         {        
       
   359         TInt shouldExist = 1;        
       
   360         
       
   361         // AttributeInt32L leaves only with KErrNone and that happens
       
   362         // if the attribute is not set which means that that download
       
   363         // is required
       
   364         TRAP_IGNORE( shouldExist = iDownloadInfo[i]->AttributeInt32L( 
       
   365             MNcdPurchaseDownloadInfo::EDownloadAttributeRequiredDownload ) );
       
   366         
       
   367         if ( !iDownloadInfo[i]->ContentUri().Length() ) 
       
   368             {
       
   369             DLTRACE(("No URI, no file"));
       
   370             shouldExist = EFalse;
       
   371             }
       
   372             
       
   373         DLTRACE(("Downloaded file should exist: %d", shouldExist));        
       
   374         
       
   375         // Dependencies and in Get-cases content file don't have to be
       
   376         // downloaded because they can already be installed. In those cases
       
   377         // shouldExist == 0 and this check is skipped
       
   378         if ( shouldExist && (
       
   379              iFiles->MdcaPoint( i ).Length() == 0 ||
       
   380              !BaflUtils::FileExists( 
       
   381                 CNcdProviderUtils::FileSession(),
       
   382                 iFiles->MdcaPoint( i ) ) ) )
       
   383             {            
       
   384             return EFalse;
       
   385             }            
       
   386         }
       
   387     return ETrue;
       
   388     }