ncdengine/provider/server/src/ncdnodedependencyimpl.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:   Implements CNcdNodeDependency class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodedependencyimpl.h"
       
    20 
       
    21 #include "ncdnodemetadataimpl.h"
       
    22 #include "ncddownloadinfo.h"
       
    23 #include "catalogssession.h"
       
    24 #include "catalogsbasemessage.h"
       
    25 #include "ncdnodefunctionids.h"
       
    26 #include "ncdnodeclassids.h"
       
    27 #include "catalogsconstants.h"
       
    28 #include "ncd_pp_dataentity.h"
       
    29 #include "ncd_pp_dataentitycontent.h"
       
    30 #include "ncd_pp_entitydependency.h"
       
    31 #include "ncd_cp_query.h"
       
    32 #include "ncdnodeidentifier.h"
       
    33 #include "ncddependencyinfo.h"
       
    34 #include "catalogsutils.h"
       
    35 #include "ncderrors.h"
       
    36 #include "ncdprotocolwords.h"
       
    37 #include "ncdpurchasehistoryutils.h"
       
    38 
       
    39 #include "catalogsdebug.h"
       
    40 
       
    41 CNcdNodeDependency::CNcdNodeDependency( CNcdNodeMetaData& aParentMetaData, 
       
    42                                         NcdNodeClassIds::TNcdNodeClassId aClassId )
       
    43 : CNcdCommunicable(),
       
    44   iParentMetaData( aParentMetaData ),
       
    45   iClassId( aClassId )
       
    46     {
       
    47     }
       
    48 
       
    49 void CNcdNodeDependency::ConstructL()
       
    50     {
       
    51     // These values have to be set.
       
    52     }
       
    53 
       
    54 
       
    55 CNcdNodeDependency* CNcdNodeDependency::NewL( CNcdNodeMetaData& aParentMetaData )
       
    56     {
       
    57     CNcdNodeDependency* self =   
       
    58         CNcdNodeDependency::NewLC( aParentMetaData );
       
    59     CleanupStack::Pop( self );
       
    60     return self;        
       
    61     }
       
    62 
       
    63 CNcdNodeDependency* CNcdNodeDependency::NewLC( CNcdNodeMetaData& aParentMetaData )
       
    64     {
       
    65     CNcdNodeDependency* self = 
       
    66         new( ELeave ) CNcdNodeDependency( 
       
    67             aParentMetaData,
       
    68             NcdNodeClassIds::ENcdNodeDependencyClassId );
       
    69     CleanupClosePushL( *self );
       
    70     self->ConstructL();
       
    71     return self;        
       
    72     }
       
    73 
       
    74 
       
    75 CNcdNodeDependency::~CNcdNodeDependency()
       
    76     {
       
    77     DLTRACEIN((""));
       
    78 
       
    79     // Delete member variables here
       
    80     iDependencyNodeTargets.ResetAndDestroy();
       
    81     iDependencyContentTargets.ResetAndDestroy();
       
    82 
       
    83     iOldDependencyContentTargets.ResetAndDestroy();
       
    84     // Do not delete parent metadata because it is not owned here.
       
    85 
       
    86     DLTRACEOUT((""));
       
    87     }        
       
    88 
       
    89 
       
    90 NcdNodeClassIds::TNcdNodeClassId CNcdNodeDependency::ClassId() const
       
    91     {
       
    92     return iClassId;
       
    93     }
       
    94 
       
    95 
       
    96 const RPointerArray<CNcdDownloadInfo>& CNcdNodeDependency::ContentTargets() const
       
    97     {
       
    98     return iDependencyContentTargets;
       
    99     }
       
   100 
       
   101 
       
   102 const RPointerArray<CNcdDependencyInfo>& CNcdNodeDependency::NodeTargets() const
       
   103     {
       
   104     return iDependencyNodeTargets;
       
   105     }
       
   106 
       
   107 
       
   108 // Internalization from the protocol
       
   109 
       
   110 void CNcdNodeDependency::InternalizeL( MNcdPreminetProtocolDataEntity& aData )
       
   111     {
       
   112     DLTRACEIN((""));
       
   113 
       
   114     // First create the new values
       
   115 
       
   116     // Notice that ownerships are not transferred from the parser objects.
       
   117     const MNcdPreminetProtocolDataEntityContent* downloadableContent = 
       
   118         aData.DownloadableContent();
       
   119     if ( downloadableContent == NULL )
       
   120         {
       
   121         DLINFO(("No data present"));
       
   122         // Content data not present.
       
   123         User::Leave( KErrNotFound );
       
   124         }
       
   125 
       
   126     // Reset the array here.
       
   127     // If something here fails after this. Then, the owner of this class object 
       
   128     // should remove this class object from the metadata anyway.
       
   129     iDependencyNodeTargets.ResetAndDestroy();
       
   130     iDependencyContentTargets.ResetAndDestroy();
       
   131 
       
   132     const MNcdPreminetProtocolEntityDependency* dependency( NULL );
       
   133     CNcdNodeIdentifier* identifier( NULL );
       
   134     CNcdDependencyInfo* dependencyInfo(NULL ); 
       
   135   
       
   136     DLTRACE(("Going through %d entity dependencies", 
       
   137         downloadableContent->EntityDependencyCount() ));
       
   138         
       
   139     for ( TInt i = 0; i < downloadableContent->EntityDependencyCount(); ++i )
       
   140         {
       
   141         // Check what nodes depend on this node.
       
   142         dependency = &downloadableContent->EntityDependencyL( i );
       
   143         if ( dependency->Type() == EDependency )
       
   144             {
       
   145             MNcdPurchaseDownloadInfo::TContentUsage usage = 
       
   146                 DetermineContentUsage( dependency->Name() );
       
   147                 
       
   148             // Check if the dependency should be loaded as a node when
       
   149             // the download responsibility is transferred to the proxy side
       
   150             // or should we just download the content directly in server side.
       
   151             if ( dependency->EntityId() != KNullDesC &&
       
   152                  // If the name of the dependency contains any of the launcher keywords,
       
   153                  // we handle it like a SIS-dependency even if it is really a entity
       
   154                  // dependency.
       
   155                  usage == MNcdPurchaseDownloadInfo::EDependency )
       
   156                 {
       
   157                 DLINFO((_L("Dependency entity id: %S"), &dependency->EntityId()));
       
   158                 // The dependency information contains  the
       
   159                 // entity id of the target node.
       
   160                 identifier = 
       
   161                     CNcdNodeIdentifier::NewL( iParentMetaData.Identifier().NodeNameSpace(),
       
   162                                               dependency->EntityId(),                                           
       
   163                                               iParentMetaData.Identifier().ServerUri(),
       
   164                                               iParentMetaData.Identifier().ClientUid() );
       
   165                 // Note, that identifier ownership is transferred here.
       
   166                 dependencyInfo = 
       
   167                     CNcdDependencyInfo::NewLC( dependency->Name(),
       
   168                                                dependency->ContentVersion(),
       
   169                                                dependency->ContentId(),
       
   170                                                identifier );
       
   171                 iDependencyNodeTargets.AppendL( dependencyInfo );
       
   172                 CleanupStack::Pop( dependencyInfo );                
       
   173                 }
       
   174             else
       
   175                 {
       
   176                 // Ownership is not transferred here.
       
   177                 const MNcdPreminetProtocolDownload* downloadDetails( 
       
   178                     dependency->DownloadDetails() );
       
   179                 if ( downloadDetails != NULL || 
       
   180                      // Launchers don't need to have download details
       
   181                      usage != MNcdPurchaseDownloadInfo::EDependency )
       
   182                     {
       
   183                     DLINFO(("Download the content directly. New node will not be created."));
       
   184                     // Copy the content object and insert it into the content array.
       
   185                     // The purchase operation may use the array content when checking
       
   186                     // if dependencies should be downloaded and installed.
       
   187                     CNcdDownloadInfo* content( 
       
   188                         CNcdDownloadInfo::NewLC( *dependency ) );
       
   189                     
       
   190                     TBool isLauncher = SetContentUsage( *dependency, *content );
       
   191                     // Dependencies are not launchable but launchers are
       
   192                     content->SetLaunchable( isLauncher );                    
       
   193 
       
   194                     iDependencyContentTargets.AppendL( content );
       
   195                         
       
   196                     // Array took ownership. So, do not delete.
       
   197                     CleanupStack::Pop( content );                    
       
   198                     DLTRACE(("Download info added"));
       
   199                     }
       
   200                 }
       
   201             }
       
   202         }
       
   203 
       
   204 
       
   205     if ( iDependencyContentTargets.Count() == 0 ) 
       
   206         {
       
   207         // No dependency content targets so the current item on the server
       
   208         // doesn't have any dependencies so we don't show any 
       
   209         // through the API
       
   210         iOldDependencyContentTargets.ResetAndDestroy();
       
   211         }
       
   212         
       
   213     if ( iDependencyNodeTargets.Count() == 0
       
   214          && iDependencyContentTargets.Count() == 0 )
       
   215         {
       
   216         // No Dependency data was found. 
       
   217         // So, inform about that to the owner of this class object.
       
   218         DLINFO(("No content"));
       
   219         User::Leave( KErrNotFound );
       
   220         }
       
   221     
       
   222     DLTRACEOUT((""));
       
   223     }
       
   224 
       
   225 
       
   226 TBool CNcdNodeDependency::InternalizeFromPurchaseDetailsL( 
       
   227     const MNcdPurchaseDetails& aDetails )
       
   228     {
       
   229     DLTRACEIN((""));
       
   230     
       
   231     iOldDependencyContentTargets.ResetAndDestroy();
       
   232     
       
   233     TArray<MNcdPurchaseDownloadInfo*> dlInfo ( aDetails.DownloadInfoL() );
       
   234     
       
   235     if ( !dlInfo.Count() ) 
       
   236         {
       
   237         DLTRACEOUT(("No download infos so no dependencies"));
       
   238         return EFalse;
       
   239         }
       
   240     
       
   241     TArray<MNcdPurchaseInstallInfo*> installInfo ( aDetails.InstallInfoL() );
       
   242             
       
   243     
       
   244     for ( TInt i = 0; i < dlInfo.Count(); ++i )
       
   245         {
       
   246         // Launchers are dependencies        
       
   247         if ( NcdPurchaseHistoryUtils::IsDependency( *dlInfo[i] ) )
       
   248             {
       
   249             DLTRACE(("Internalizing dependency from purchase history"));
       
   250             DASSERT( installInfo.Count() > i );
       
   251             CNcdDownloadInfo* info = CNcdDownloadInfo::NewLC( 
       
   252                 *dlInfo[i],
       
   253                 installInfo[i]->ApplicationUid(),
       
   254                 installInfo[i]->ApplicationVersion() );
       
   255             iOldDependencyContentTargets.AppendL( info );
       
   256             CleanupStack::Pop( info );  
       
   257             }            
       
   258         else 
       
   259             {            
       
   260             // Dependencies are before other content so we
       
   261             // can stop here
       
   262             break;
       
   263             }
       
   264         }
       
   265     
       
   266     if ( iOldDependencyContentTargets.Count() ) 
       
   267         {
       
   268         DLTRACEOUT(("Internalization successful"));
       
   269         return ETrue;
       
   270         }
       
   271     
       
   272     DLTRACEOUT(("Nothing to internalize"));
       
   273     return EFalse;
       
   274     }
       
   275 
       
   276 
       
   277 TBool CNcdNodeDependency::UpdateDependencyStatesL()
       
   278     {
       
   279     DLTRACEIN((""));
       
   280     MoveOldContentTargetsToNew();
       
   281     
       
   282     TBool allInstalled = ETrue;
       
   283     
       
   284     // Check if the dependencies have already been installed
       
   285     for ( TInt i = 0; i < iDependencyContentTargets.Count(); ++i ) 
       
   286         {        
       
   287         // allInstalled becomes false if any of the dependencies is
       
   288         // not installed
       
   289         allInstalled = allInstalled && 
       
   290             UpdateDependencyStateL( *iDependencyContentTargets[i] );
       
   291         }
       
   292         
       
   293         
       
   294     // Check if the dependencies have already been installed
       
   295     for ( TInt i = 0; i < iDependencyNodeTargets.Count(); ++i ) 
       
   296         {
       
   297         // EApplicationOlderVersionInstalled & EApplicationNotInstalled
       
   298         // are considered as missing
       
   299         if ( CNcdProviderUtils::IsApplicationInstalledL( 
       
   300             iDependencyNodeTargets[i]->Uid(), 
       
   301             iDependencyNodeTargets[i]->Version() ) <= 
       
   302                 ENcdApplicationNotInstalled  )
       
   303             {
       
   304             DLTRACE(("Dependency not installed, updating state"));
       
   305             iDependencyNodeTargets[i]->SetDependencyState( 
       
   306                 ENcdDependencyMissing );
       
   307             allInstalled = EFalse;
       
   308             }
       
   309         else
       
   310             {
       
   311             iDependencyNodeTargets[i]->SetDependencyState( 
       
   312                 ENcdDependencyInstalled );
       
   313             
       
   314             }
       
   315         }
       
   316         
       
   317     DLTRACEOUT(("allInstalled: %d", allInstalled));
       
   318     return allInstalled;
       
   319     }
       
   320 
       
   321 
       
   322 void CNcdNodeDependency::UpdateDependenciesL( 
       
   323     CNcdPurchaseDetails& aDetails ) const
       
   324     {
       
   325     DLTRACEIN((""));
       
   326     NcdPurchaseHistoryUtils::UpdateDependenciesL( 
       
   327         aDetails, 
       
   328         iDependencyContentTargets );
       
   329     }
       
   330 
       
   331 
       
   332 // Internalization from and externalization to the database
       
   333     
       
   334 void CNcdNodeDependency::ExternalizeL( RWriteStream& aStream )
       
   335     {
       
   336     DLTRACEIN((""));
       
   337 
       
   338     if ( iDependencyNodeTargets.Count() == 0
       
   339          && iDependencyContentTargets.Count() == 0 )
       
   340         {
       
   341         DLERROR(("No content"));
       
   342         DASSERT( EFalse );
       
   343         User::Leave( KErrNotFound );
       
   344         }
       
   345 
       
   346     // First insert data that the creator of this class object will use to
       
   347     // create this class object. Class id informs what class object
       
   348     // will be created.
       
   349     
       
   350     aStream.WriteInt32L( iClassId );
       
   351     
       
   352     ExternalizeNodeDependencyArrayL( aStream );
       
   353     ExternalizeContentDependencyArrayL( aStream );
       
   354     
       
   355     DLTRACEOUT((""));
       
   356     }
       
   357     
       
   358 void CNcdNodeDependency::InternalizeL( RReadStream& aStream )
       
   359     {
       
   360     DLTRACEIN((""));
       
   361 
       
   362     // Read the class id first because it is set to the stream in internalize
       
   363     // function and it is not read from the stream anywhere else.
       
   364     TInt classId( aStream.ReadInt32L() );
       
   365     if ( classId != ClassId() )
       
   366         {
       
   367         DLTRACE(("Wrong class id"));
       
   368         DASSERT( EFalse );
       
   369         // Leave because the stream does not match this class object
       
   370         User::Leave( KErrCorrupt );
       
   371         }
       
   372 
       
   373     InternalizeNodeDependencyArrayL( aStream ); 
       
   374     InternalizeContentDependencyArrayL( aStream );
       
   375         
       
   376     DLTRACEOUT((""));
       
   377     }
       
   378 
       
   379 
       
   380 void CNcdNodeDependency::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
   381                                       TInt aFunctionNumber )
       
   382     {
       
   383     DLTRACEIN((""));    
       
   384 
       
   385     DASSERT( aMessage );
       
   386 
       
   387     // Now, we can be sure that rest of the time iMessage exists.
       
   388     // This member variable is set for the CounterPartLost function.
       
   389     iMessage = aMessage;
       
   390     
       
   391     TInt trapError( KErrNone );
       
   392     
       
   393     // Check which function is called by the proxy side object.
       
   394     // Function number are located in ncdnodefunctinoids.h file.
       
   395     switch( aFunctionNumber )
       
   396         {
       
   397         case NcdNodeFunctionIds::ENcdInternalize:
       
   398             // Internalize the proxy side according to the data
       
   399             // of this object.
       
   400             TRAP( trapError, InternalizeRequestL( *aMessage ) );
       
   401             break;
       
   402 
       
   403         case NcdNodeFunctionIds::ENcdRelease:
       
   404             // The proxy does not want to use this object anymore.
       
   405             // So, release the handle from the session.
       
   406             ReleaseRequest( *aMessage );
       
   407             break;
       
   408                     
       
   409         default:
       
   410             DLERROR(("Unidentified function request"));
       
   411             DASSERT( EFalse );
       
   412             break;
       
   413         }
       
   414 
       
   415     if ( trapError != KErrNone )
       
   416         {
       
   417         // Because something went wrong, the complete has not been
       
   418         // yet called for the message.
       
   419         // So, inform the client about the error if the
       
   420         // message is still available.
       
   421         aMessage->CompleteAndRelease( trapError );
       
   422         }
       
   423 
       
   424     // Because the message should not be used after this, set it NULL.
       
   425     // So, CounterPartLost function will know that no messages are
       
   426     // waiting the response at the moment.
       
   427     iMessage = NULL;        
       
   428     
       
   429     DLTRACEOUT((""));
       
   430     }
       
   431 
       
   432 void CNcdNodeDependency::CounterPartLost( const MCatalogsSession& aSession )
       
   433     {
       
   434     // This function may be called whenever -- when the message is waiting
       
   435     // response or when the message does not exist.
       
   436     // iMessage may be NULL here, because in the end of the
       
   437     // ReceiveMessage it is set to NULL. The life time of the message
       
   438     // ends shortly after CompleteAndRelease is called.
       
   439     if ( iMessage != NULL )
       
   440         {
       
   441         iMessage->CounterPartLost( aSession );
       
   442         }
       
   443     }
       
   444                 
       
   445 
       
   446 void CNcdNodeDependency::InternalizeRequestL( MCatalogsBaseMessage& aMessage )
       
   447     {
       
   448     DLTRACEIN((""));
       
   449     
       
   450     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   451     CleanupStack::PushL( buf );
       
   452     
       
   453     RBufWriteStream stream( *buf );
       
   454     CleanupClosePushL( stream );
       
   455 
       
   456 
       
   457     // Include all the necessary node data to the stream
       
   458     ExternalizeDataForRequestL( stream );     
       
   459     
       
   460     
       
   461     // Commits data to the stream when closing.
       
   462     CleanupStack::PopAndDestroy( &stream );
       
   463 
       
   464 
       
   465     // If this leaves, ReceiveMessage will complete the message.
       
   466     // NOTE: that here we expect that the buffer contains at least
       
   467     // some data. So, make sure that ExternalizeDataForRequestL inserts
       
   468     // something to the buffer.
       
   469     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );        
       
   470         
       
   471     
       
   472     DLTRACE(("Deleting the buf"));
       
   473     CleanupStack::PopAndDestroy( buf );
       
   474         
       
   475     DLTRACEOUT((""));
       
   476     }
       
   477     
       
   478 
       
   479 void CNcdNodeDependency::ExternalizeDataForRequestL( RWriteStream& aStream )
       
   480     {
       
   481     DLTRACEIN((""));
       
   482     
       
   483     if ( IsObsolete() )
       
   484         {
       
   485         DLINFO(("Set as obsolete. This means that server has removed the object."));
       
   486         User::Leave( KNcdErrorObsolete );
       
   487         }
       
   488     
       
   489     UpdateDependencyStatesL();
       
   490     
       
   491     // First insert data that the creator of this class object will use to
       
   492     // create this class object. Class id informs what class object
       
   493     // will be created.
       
   494     
       
   495     aStream.WriteInt32L( iClassId );
       
   496     
       
   497     ExternalizeNodeDependencyArrayL( aStream );
       
   498 
       
   499     // Also externalize some information about the possible content dependencies for the
       
   500     // proxy
       
   501     ExternalizeContentDependencyArrayForRequestL( aStream );
       
   502                 
       
   503     DLTRACEOUT((""));
       
   504     }
       
   505 
       
   506 void CNcdNodeDependency::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
       
   507     {
       
   508     DLTRACEIN((""));
       
   509 
       
   510     // Decrease the reference count for this object.
       
   511     // When the reference count reaches zero, this object will be destroyed
       
   512     // and removed from the session.
       
   513     MCatalogsSession& requestSession( aMessage.Session() );
       
   514     TInt handle( aMessage.Handle() );
       
   515 
       
   516     // Send complete information back to proxy.
       
   517     aMessage.CompleteAndRelease( KErrNone );
       
   518         
       
   519     // Remove this object from the session.
       
   520     requestSession.RemoveObject( handle );
       
   521         
       
   522     DLTRACEOUT((""));
       
   523     }
       
   524 
       
   525 
       
   526 void CNcdNodeDependency::ExternalizeNodeDependencyArrayL( RWriteStream& aStream )
       
   527     {
       
   528     DLTRACEIN((""));
       
   529 
       
   530     aStream.WriteInt32L( iDependencyNodeTargets.Count() );
       
   531     for ( TInt i = 0; i < iDependencyNodeTargets.Count(); ++i )
       
   532         {
       
   533         iDependencyNodeTargets[ i ]->ExternalizeL( aStream );
       
   534         }
       
   535 
       
   536     DLTRACEOUT((""));
       
   537     }
       
   538 
       
   539 void CNcdNodeDependency::InternalizeNodeDependencyArrayL( RReadStream& aStream )
       
   540     {
       
   541     DLTRACEIN((""));
       
   542 
       
   543     CNcdDependencyInfo* dependencyInfo( NULL );
       
   544     TInt count( aStream.ReadInt32L() );
       
   545 
       
   546     iDependencyNodeTargets.ResetAndDestroy();
       
   547     for( TInt i = 0; i < count; ++i )
       
   548         {
       
   549         dependencyInfo = CNcdDependencyInfo::NewLC( aStream );
       
   550         iDependencyNodeTargets.AppendL( dependencyInfo );
       
   551         CleanupStack::Pop( dependencyInfo );
       
   552         }
       
   553 
       
   554     DLTRACEOUT((""));
       
   555     }
       
   556 
       
   557 
       
   558 void CNcdNodeDependency::ExternalizeContentDependencyArrayForRequestL( RWriteStream& aStream )
       
   559     {
       
   560     DLTRACEIN((""));
       
   561 
       
   562     aStream.WriteInt32L( iDependencyContentTargets.Count() );
       
   563     CNcdDownloadInfo* downloadInfo( NULL );
       
   564     CNcdDependencyInfo* dependencyInfo( NULL );
       
   565     // Notice that here we will give dependency info objects to the proxy side.
       
   566     for ( TInt i = 0; i < iDependencyContentTargets.Count(); ++i )
       
   567         {
       
   568         downloadInfo = iDependencyContentTargets[ i ];
       
   569         dependencyInfo = CNcdDependencyInfo::NewLC( downloadInfo->ContentName(), 
       
   570                                                     downloadInfo->ContentVersion(), 
       
   571                                                     downloadInfo->ContentId(),
       
   572                                                     NULL );
       
   573         dependencyInfo->SetDependencyState( downloadInfo->DependencyState() );                                                   
       
   574         dependencyInfo->ExternalizeL( aStream );
       
   575         CleanupStack::PopAndDestroy( dependencyInfo );
       
   576         dependencyInfo = NULL;
       
   577         }
       
   578 
       
   579     DLTRACEOUT((""));
       
   580     }
       
   581 
       
   582 
       
   583 void CNcdNodeDependency::ExternalizeContentDependencyArrayL( RWriteStream& aStream )
       
   584     {
       
   585     DLTRACEIN((""));
       
   586 
       
   587     aStream.WriteInt32L( iDependencyContentTargets.Count() );
       
   588     for ( TInt i = 0; i < iDependencyContentTargets.Count(); ++i )
       
   589         {
       
   590         iDependencyContentTargets[ i ]->ExternalizeL( aStream );
       
   591         }
       
   592 
       
   593     DLTRACEOUT((""));
       
   594     }
       
   595 
       
   596 void CNcdNodeDependency::InternalizeContentDependencyArrayL( RReadStream& aStream )
       
   597     {
       
   598     DLTRACEIN((""));
       
   599 
       
   600     CNcdDownloadInfo* content( NULL );
       
   601     TInt count( aStream.ReadInt32L() );
       
   602 
       
   603     iDependencyContentTargets.ResetAndDestroy();
       
   604     for( TInt i = 0; i < count; ++i )
       
   605         {
       
   606         content = CNcdDownloadInfo::NewLC();
       
   607         content->InternalizeL( aStream );
       
   608         iDependencyContentTargets.AppendL( content );
       
   609         CleanupStack::Pop( content );
       
   610         }
       
   611     
       
   612     DLTRACEOUT((""));
       
   613     }
       
   614 
       
   615 
       
   616 // This moves dependencies read from the purchase history as the 
       
   617 // current dependencies if there are no current dependencies.
       
   618 // This is used to ensure that MNcdNodeDependency show dependencies
       
   619 // correctly even if the node cache has been cleared but the
       
   620 // item has been bought
       
   621 void CNcdNodeDependency::MoveOldContentTargetsToNew()
       
   622     {
       
   623     DLTRACEIN((""));
       
   624     
       
   625     if ( iDependencyContentTargets.Count() == 0 )
       
   626         {
       
   627         DLTRACE(("Moving dependencies"));
       
   628         iDependencyContentTargets.Close();
       
   629         iDependencyContentTargets = iOldDependencyContentTargets;
       
   630         iOldDependencyContentTargets = RPointerArray<CNcdDownloadInfo>();
       
   631         }
       
   632     }
       
   633 
       
   634 
       
   635 TBool CNcdNodeDependency::UpdateDependencyStateL( 
       
   636     CNcdDownloadInfo& aContentTarget )
       
   637     {
       
   638     DLTRACEIN((""));
       
   639     // Compare current dependencies to those read from purchase history
       
   640     // If old dependencies exist:
       
   641     // - they determine whether dependency is installed or not
       
   642     // - their version is compared to the one received in the protocol
       
   643     //   if protocol contains newer, then that is used
       
   644     TInt oldCount = iOldDependencyContentTargets.Count();
       
   645     for ( TInt i = 0; i < oldCount; ++i ) 
       
   646         {
       
   647         if ( aContentTarget.ContentId() 
       
   648              == iOldDependencyContentTargets[i]->ContentId() ) 
       
   649             {
       
   650             TInt comp = 0;
       
   651             TRAPD( err, comp = CNcdProviderUtils::CompareVersionsL(                     
       
   652                 iOldDependencyContentTargets[i]->ContentVersion(),
       
   653                 aContentTarget.ContentVersion() ) );
       
   654             LeaveIfNotErrorL( err, KErrArgument, KErrGeneral );
       
   655             
       
   656             TNcdApplicationStatus status = 
       
   657                 CNcdProviderUtils::IsApplicationInstalledL( 
       
   658                     iOldDependencyContentTargets[i]->ContentId(),
       
   659                     iOldDependencyContentTargets[i]->ContentVersion() );
       
   660             
       
   661             
       
   662             TBool installed = SetDependencyState( 
       
   663                 aContentTarget, status, comp, EFalse );
       
   664         
       
   665             DLTRACEOUT(("Installed: %d", installed));
       
   666             return installed;
       
   667             }
       
   668         }
       
   669     
       
   670         
       
   671     // This is executed only if the dependency is not found from the
       
   672     // old dependencies which means that either there were no old dependencies
       
   673     // old dependencies have been updated on the server
       
   674     TNcdApplicationStatus status = 
       
   675         CNcdProviderUtils::IsApplicationInstalledL( 
       
   676         aContentTarget.ContentId(),
       
   677         aContentTarget.ContentVersion() );
       
   678  
       
   679     // Give 0 as version comp status so that state is set either
       
   680     // installed or missing, but if oldCount != 0 then the state will be
       
   681     // either installed or upgrade available
       
   682     TBool installed = SetDependencyState( 
       
   683         aContentTarget, status, 0, oldCount );
       
   684         
       
   685     DLTRACEOUT(("Installed: %d", installed));
       
   686     return installed;
       
   687     }
       
   688 
       
   689 
       
   690 
       
   691 TBool CNcdNodeDependency::SetDependencyState( 
       
   692     CNcdDownloadInfo& aContentTarget,
       
   693     TNcdApplicationStatus aStatus,
       
   694     TInt aVersionCompResult,
       
   695     TBool aIsUpgrade )
       
   696     {
       
   697     DLTRACEIN((""));
       
   698     // Dependency is installed if the correct or newer version is installed
       
   699     TBool installed = 
       
   700         ( aStatus == ENcdApplicationInstalled ) || 
       
   701         ( aStatus == ENcdApplicationNewerVersionInstalled );
       
   702     
       
   703     // Update dependency state according to installation status and
       
   704     // version numbers
       
   705     if ( installed ) 
       
   706         {                    
       
   707         if ( aVersionCompResult >= 0 )
       
   708             {
       
   709             DLTRACE(("Same or newer installed"));
       
   710             aContentTarget.SetDependencyState( 
       
   711                 ENcdDependencyInstalled );
       
   712             }
       
   713         else 
       
   714             {
       
   715             DLTRACE(("Older version installed"));
       
   716             aContentTarget.SetDependencyState( 
       
   717                 ENcdDependencyUpgradeAvailable );                        
       
   718             }
       
   719         }
       
   720     // if old dependencies are installed, new uninstalled are considered to
       
   721     // be upgrades
       
   722     else if ( aIsUpgrade ) 
       
   723         {
       
   724         DLTRACE(("Dependency not installed but it's considered as an upgrade"));
       
   725         aContentTarget.SetDependencyState( 
       
   726             ENcdDependencyUpgradeAvailable );  
       
   727         }
       
   728     else
       
   729         {
       
   730         DLTRACE(("Dependency not installed"));
       
   731         aContentTarget.SetDependencyState( 
       
   732             ENcdDependencyMissing );  
       
   733         
       
   734         }
       
   735     return installed;
       
   736     }
       
   737 
       
   738 
       
   739 TBool CNcdNodeDependency::SetContentUsage( 
       
   740     const MNcdPreminetProtocolEntityDependency& aDependency, 
       
   741     CNcdDownloadInfo& aTarget ) const
       
   742     {
       
   743     DLTRACEIN((""));
       
   744     MNcdPurchaseDownloadInfo::TContentUsage usage = 
       
   745         DetermineContentUsage( aDependency.Name() );
       
   746             
       
   747     aTarget.SetContentUsage( usage );
       
   748     
       
   749     // Must return ETrue if the dependency is a launcher application
       
   750     return usage != MNcdPurchaseDownloadInfo::EDependency;
       
   751     }
       
   752 
       
   753 
       
   754 MNcdPurchaseDownloadInfo::TContentUsage CNcdNodeDependency::DetermineContentUsage(
       
   755     const TDesC& aDependencyName ) const
       
   756     {
       
   757     MNcdPurchaseDownloadInfo::TContentUsage usage = 
       
   758         MNcdPurchaseDownloadInfo::EDependency;
       
   759         
       
   760     if ( aDependencyName.MatchF( KNcdLauncher ) != KErrNotFound ) 
       
   761         {
       
   762         DLTRACE(("Launcher"));
       
   763         usage = MNcdPurchaseDownloadInfo::ELauncher;
       
   764         }
       
   765     else if ( aDependencyName.MatchF( KNcdLauncherOpen ) != KErrNotFound )
       
   766         {
       
   767         DLTRACE(("Launcher/open"));
       
   768         usage = MNcdPurchaseDownloadInfo::ELauncherOpen;
       
   769         }
       
   770     return usage;    
       
   771     }