iaupdate/IAD/engine/controller/src/iaupdatenodeimpl.cpp
changeset 0 ba25891c3a9e
child 18 3ba40be8e484
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2007-2009 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:   This module contains the implementation of CIAUpdateNode class 
       
    15 *                member functions.
       
    16 *
       
    17 */
       
    18 
       
    19 #include <ncdnode.h>
       
    20 #include <ncdnodepurchase.h>
       
    21 #include <ncdnodedownload.h>
       
    22 #include <ncdnodeinstall.h>
       
    23 
       
    24 #include "iaupdatenodeimpl.h"
       
    25 #include "iaupdatenodeobserver.h"
       
    26 #include "iaupdatenodedependencyimpl.h"
       
    27 #include "iaupdatenodedetails.h"
       
    28 #include "iaupdatecontrollerimpl.h"
       
    29 #include "iaupdateutils.h"
       
    30 #include "iaupdatecontentoperationmanager.h"
       
    31 #include "iaupdatedebug.h"
       
    32 
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // CIAUpdateNode::NewLC
       
    36 // Two-phased constructor.
       
    37 // -----------------------------------------------------------------------------
       
    38 // 
       
    39 CIAUpdateNode* CIAUpdateNode::NewLC( MNcdNode* aNode,
       
    40                                      CIAUpdateController& aController )
       
    41     {
       
    42     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewLC() begin");
       
    43 
       
    44     CIAUpdateNode* self = 
       
    45         new( ELeave ) CIAUpdateNode( aController );
       
    46     CleanupStack::PushL( self );    
       
    47     self->ConstructL( aNode );
       
    48 
       
    49     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewLC() end");
       
    50 
       
    51     return self;
       
    52     }
       
    53 
       
    54     
       
    55 // -----------------------------------------------------------------------------
       
    56 // CIAUpdateNode::NewL
       
    57 // Two-phased constructor.
       
    58 // -----------------------------------------------------------------------------
       
    59 //     
       
    60 CIAUpdateNode* CIAUpdateNode::NewL( MNcdNode* aNode,
       
    61                                     CIAUpdateController& aController )
       
    62     {
       
    63     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewL() begin");
       
    64     CIAUpdateNode* self = 
       
    65         CIAUpdateNode::NewLC( aNode, aController );
       
    66     CleanupStack::Pop( self );
       
    67     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewL() end");
       
    68     return self;
       
    69     }
       
    70 
       
    71 
       
    72 // -----------------------------------------------------------------------------
       
    73 // CIAUpdateNode::CIAUpdateNode
       
    74 // C++ default constructor can NOT contain any code, that
       
    75 // might leave.
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CIAUpdateNode::CIAUpdateNode( CIAUpdateController& aController ) 
       
    79 : CIAUpdateBaseNode( aController )
       
    80     {
       
    81     }
       
    82 
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CIAUpdateNode::ConstructL
       
    86 // Symbian 2nd phase constructor can leave.
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 void CIAUpdateNode::ConstructL( MNcdNode* aNode )
       
    90     {
       
    91     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ConstructL() begin");
       
    92 
       
    93     // Let the parent handle it all.
       
    94     CIAUpdateBaseNode::ConstructL( aNode );
       
    95 
       
    96     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ConstructL() end");
       
    97     }
       
    98 
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // CIAUpdateNode::~CIAUpdateNode
       
   102 // Destructor
       
   103 // -----------------------------------------------------------------------------
       
   104 //    
       
   105 CIAUpdateNode::~CIAUpdateNode()
       
   106     {
       
   107     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::~CIAUpdateNode() begin");
       
   108 
       
   109     iDependants.Reset();
       
   110     iExcessDependencyNodes.Reset();
       
   111     
       
   112     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::~CIAUpdateNode() end");
       
   113     }
       
   114 
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 // CIAUpdateBaseNode overloaded functions
       
   118 // 
       
   119 // ---------------------------------------------------------------------------
       
   120 
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // CIAUpdateNode::ContentSizeL
       
   124 // 
       
   125 // ---------------------------------------------------------------------------
       
   126 //
       
   127 TInt CIAUpdateNode::ContentSizeL() const
       
   128     {
       
   129     // Notice, here we give the total content size through the interface.
       
   130     // Here we want only the dependency nodes that are hidden.
       
   131     // Skip visible dependencies because those nodes are visible in UI
       
   132     // and their content size is separately shown and calculated in UI.
       
   133     return 
       
   134         Controller().
       
   135             ContentOperationManager().
       
   136                 TotalContentSizeL( *this, ETrue, EFalse, ETrue, EFalse );        
       
   137     }
       
   138 
       
   139 
       
   140 // ---------------------------------------------------------------------------
       
   141 // MIAUpdateNode functions
       
   142 // 
       
   143 // ---------------------------------------------------------------------------
       
   144 
       
   145 
       
   146 // ---------------------------------------------------------------------------
       
   147 // CIAUpdateNode::Type
       
   148 // 
       
   149 // ---------------------------------------------------------------------------
       
   150 //    
       
   151 MIAUpdateNode::TPackageType CIAUpdateNode::Type() const
       
   152     {
       
   153     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::Type() = %d", 
       
   154                      Details().ContentType());
       
   155     return Details().ContentType();
       
   156     }
       
   157 
       
   158 
       
   159 // ---------------------------------------------------------------------------
       
   160 // CIAUpdateNode::IsSelfUpdate
       
   161 // 
       
   162 // ---------------------------------------------------------------------------
       
   163 //
       
   164 TBool CIAUpdateNode::IsSelfUpdate() const    
       
   165     {
       
   166     return EFalse;
       
   167     }        
       
   168 
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // CIAUpdateNode::GetDependenciesL
       
   172 // 
       
   173 // ---------------------------------------------------------------------------
       
   174 //       
       
   175 void CIAUpdateNode::GetDependenciesL( 
       
   176     RPointerArray< MIAUpdateNode >& aDependencies,
       
   177     TBool aIncludeHidden ) const
       
   178     {
       
   179     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependenciesL() begin");
       
   180 
       
   181     RPointerArray< CIAUpdateNode > dependencies;
       
   182     CleanupClosePushL( dependencies );
       
   183 
       
   184     GetDependencyNodesL( dependencies, aIncludeHidden );
       
   185 
       
   186     aDependencies.ReserveL( dependencies.Count() );    
       
   187     for ( TInt i = 0; i < dependencies.Count(); ++i )
       
   188         {
       
   189         aDependencies.AppendL( dependencies[ i ] );
       
   190         }
       
   191 
       
   192     CleanupStack::PopAndDestroy( &dependencies );
       
   193 
       
   194     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependenciesL() end");
       
   195     }
       
   196 
       
   197 
       
   198 // ---------------------------------------------------------------------------
       
   199 // CIAUpdateNode::GetDependantsL
       
   200 // 
       
   201 // ---------------------------------------------------------------------------
       
   202 //    
       
   203 void CIAUpdateNode::GetDependantsL( 
       
   204     RPointerArray< MIAUpdateNode >& aDependants,
       
   205     TBool aIncludeHidden ) const
       
   206     {
       
   207     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependantsL() begin");
       
   208 
       
   209     aDependants.Reserve( iDependants.Count() );
       
   210     for( TInt i = 0; i < iDependants.Count(); ++i )
       
   211         {
       
   212         CIAUpdateNode* dependant( iDependants[ i ] );
       
   213         if ( aIncludeHidden 
       
   214              || !dependant->Hidden() )
       
   215             {
       
   216             aDependants.AppendL( iDependants[ i ] );
       
   217             }
       
   218         } 
       
   219 
       
   220     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependantsL() end"); 	
       
   221     }
       
   222     
       
   223 
       
   224 // ---------------------------------------------------------------------------
       
   225 // CIAUpdateNode::IsDownloaded
       
   226 // 
       
   227 // ---------------------------------------------------------------------------
       
   228 //
       
   229 TBool CIAUpdateNode::IsDownloaded() const
       
   230     {
       
   231     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsDownloaded() begin");
       
   232 
       
   233     TBool downloaded( EFalse );
       
   234     TRAP_IGNORE ( downloaded = IsDownloadedL() );
       
   235 
       
   236     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsDownloaded() end: %d",
       
   237                      downloaded);
       
   238 
       
   239     return downloaded;
       
   240     }
       
   241 
       
   242 
       
   243 // ---------------------------------------------------------------------------
       
   244 // CIAUpdateNode::IsInstalled
       
   245 // 
       
   246 // ---------------------------------------------------------------------------
       
   247 //
       
   248 TBool CIAUpdateNode::IsInstalled() const
       
   249     {
       
   250     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalled() begin");
       
   251 
       
   252     TBool installed( EFalse );
       
   253     TRAP_IGNORE ( installed = IsInstalledL() );
       
   254 
       
   255     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsInstalled() end: %d",
       
   256                      installed);
       
   257 
       
   258     return installed;
       
   259     }
       
   260 
       
   261 
       
   262 // ---------------------------------------------------------------------------
       
   263 // CIAUpdateNode::DownloadL
       
   264 // 
       
   265 // ---------------------------------------------------------------------------
       
   266 //
       
   267 void CIAUpdateNode::DownloadL( MIAUpdateNodeObserver& aObserver )
       
   268     {
       
   269     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::DownloadL() begin");
       
   270 
       
   271     if( iOperationObserver )
       
   272         {
       
   273         User::Leave( KErrInUse );
       
   274         }
       
   275 
       
   276     // Instead of starting download operation here, we start purchase operation.
       
   277     // Purchase needs to be done before download. When purchase compeletes,
       
   278     // the call back function is called and that will start download operation.
       
   279     // Notice, that we can try to create the purchase even if it has already been
       
   280     // done. Then, the operation just finishes without repurchasing.
       
   281 
       
   282     // Use content operation manager.
       
   283     // It can handle the possible hidden node chain that requires operations 
       
   284     // for multiple nodes.
       
   285     Controller().
       
   286         ContentOperationManager().
       
   287             StartL( *this, 
       
   288                     CIAUpdateContentOperationManager::EPurchaseOperation, 
       
   289                     *this );
       
   290 
       
   291     iOperationObserver = &aObserver;
       
   292 
       
   293     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::DownloadL() end");
       
   294     }
       
   295 
       
   296 
       
   297 // ---------------------------------------------------------------------------
       
   298 // CIAUpdateNode::InstallL
       
   299 // 
       
   300 // ---------------------------------------------------------------------------
       
   301 //
       
   302 void CIAUpdateNode::InstallL( MIAUpdateNodeObserver& aObserver )
       
   303     {
       
   304     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::InstallL() begin");
       
   305     
       
   306     if( iOperationObserver )
       
   307         {
       
   308         User::Leave( KErrInUse );
       
   309         }
       
   310 
       
   311     // Use content operation manager.
       
   312     // It can handle the possible hidden node chain that requires operations 
       
   313     // for multiple nodes.
       
   314     Controller().
       
   315         ContentOperationManager().
       
   316             StartL( *this, 
       
   317                     CIAUpdateContentOperationManager::EInstallOperation, 
       
   318                     *this );
       
   319 
       
   320     iOperationObserver = &aObserver;
       
   321 
       
   322     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::InstallL() end");
       
   323     }
       
   324 
       
   325 
       
   326 // ---------------------------------------------------------------------------
       
   327 // CIAUpdateNode::CancelOperation()
       
   328 // 
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331 void CIAUpdateNode::CancelOperation()
       
   332     {
       
   333     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::CancelOperation() begin");
       
   334 
       
   335     // This will cancel the possible ongoing operation
       
   336     Controller().ContentOperationManager().Cancel();
       
   337     
       
   338     // Also, set the observer to NULL.
       
   339     // Because this value is used to check if operations are going on.
       
   340     iOperationObserver = NULL;
       
   341 
       
   342     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::CancelOperation() end");
       
   343     }
       
   344 
       
   345 
       
   346 // ---------------------------------------------------------------------------
       
   347 // CIAUpdateNode::Depth()
       
   348 // 
       
   349 // ---------------------------------------------------------------------------
       
   350 //
       
   351 TInt CIAUpdateNode::Depth() const
       
   352     {
       
   353     return iDepth;
       
   354     }
       
   355 
       
   356 
       
   357 // ---------------------------------------------------------------------------
       
   358 // CIAUpdateNode::NodeType
       
   359 // 
       
   360 // ---------------------------------------------------------------------------
       
   361 //
       
   362 MIAUpdateAnyNode::TNodeType CIAUpdateNode::NodeType() const
       
   363     {
       
   364     return MIAUpdateAnyNode::ENodeTypeNormal;
       
   365     }
       
   366 
       
   367 
       
   368 // ---------------------------------------------------------------------------
       
   369 // CIAUpdateNode::Base
       
   370 // 
       
   371 // ---------------------------------------------------------------------------
       
   372 //
       
   373 MIAUpdateBaseNode& CIAUpdateNode::Base()
       
   374     {
       
   375     return *this;   
       
   376     }
       
   377 
       
   378 
       
   379 // ---------------------------------------------------------------------------
       
   380 // MIAUpdateContentOperationObserver functions
       
   381 // 
       
   382 // ---------------------------------------------------------------------------
       
   383 
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 // CIAUpdateNode::ContentOperationCompleteL
       
   387 // 
       
   388 // ---------------------------------------------------------------------------
       
   389 //
       
   390 void CIAUpdateNode::ContentOperationComplete( CIAUpdateBaseNode& /*aNode*/, 
       
   391                                               TInt aError )
       
   392     {
       
   393     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationComplete() begin");
       
   394 
       
   395     // Get the observer to a temporary pointer. So, we can use it 
       
   396     // when informing observers. The member variable needs to be set to NULL
       
   397     // before callbacks are called.
       
   398     MIAUpdateNodeObserver* tmpObserver( iOperationObserver );
       
   399     
       
   400     const CIAUpdateContentOperationManager::TContentOperationType& operationType(
       
   401         Controller().ContentOperationManager().OperationType() );
       
   402 
       
   403     if ( operationType == CIAUpdateContentOperationManager::EPurchaseOperation )
       
   404         {
       
   405         IAUPDATE_TRACE_1("[IAUPDATE] Purchase operation complete: %d", aError);
       
   406         if ( aError == KErrNone )
       
   407             {
       
   408             // Purchase operation was successfull.
       
   409             // So, now try to download the actual content.
       
   410             TRAPD ( trapError, 
       
   411                     Controller().
       
   412                         ContentOperationManager().
       
   413                             StartL( *this, 
       
   414                                     CIAUpdateContentOperationManager::EDownloadOperation, 
       
   415                                     *this ); );
       
   416             IAUPDATE_TRACE_1("[IAUPDATE] download trap error code: %d", trapError );
       
   417             if ( trapError != KErrNone )
       
   418                 {
       
   419                 IAUPDATE_TRACE("[IAUPDATE] Could not create download operation.");
       
   420                 // Something went wrong when initializing download operation.
       
   421                 iOperationObserver = NULL;
       
   422                 // Inform observer about the completion of operation.
       
   423                 tmpObserver->DownloadComplete( *this, trapError );
       
   424                 }            
       
   425             }
       
   426         else
       
   427             {
       
   428             IAUPDATE_TRACE("[IAUPDATE] Purchase was not success. Complete download.");
       
   429             // Operation was not successfull.
       
   430             // There is no reason to continue.
       
   431             // Inform observer about the completion of operation.
       
   432             iOperationObserver = NULL;
       
   433             tmpObserver->DownloadComplete( *this, aError );
       
   434             }
       
   435         }
       
   436     else if ( operationType == CIAUpdateContentOperationManager::EDownloadOperation )
       
   437         {
       
   438         IAUPDATE_TRACE("[IAUPDATE] Download operation complete");
       
   439         iOperationObserver = NULL;
       
   440         // Inform observer about the completion of operation.
       
   441         tmpObserver->DownloadComplete( *this, aError );
       
   442         }
       
   443     else if ( operationType == CIAUpdateContentOperationManager::EInstallOperation )
       
   444         {
       
   445         IAUPDATE_TRACE("[IAUPDATE] Install operation complete");
       
   446         iOperationObserver = NULL;
       
   447         // Inform observers about the completion of operation.
       
   448         tmpObserver->InstallComplete( *this, aError );        
       
   449         }
       
   450     else
       
   451         {
       
   452         // We should never come here.
       
   453         IAUPDATE_TRACE("[IAUPDATE] ERROR No operation was going on even if callback called");        
       
   454         iOperationObserver = NULL;
       
   455         }
       
   456         
       
   457     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationComplete() end");
       
   458     }
       
   459 
       
   460 
       
   461 // ---------------------------------------------------------------------------
       
   462 // CIAUpdateNode::ContentOperationProgress
       
   463 // 
       
   464 // ---------------------------------------------------------------------------
       
   465 // 
       
   466 void CIAUpdateNode::ContentOperationProgress( CIAUpdateBaseNode& /*aNode*/, 
       
   467                                               TInt aProgress, 
       
   468                                               TInt aMaxProgress )
       
   469     {
       
   470     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationProgress() begin");
       
   471 
       
   472     // Inform the observer about the progress of download and install.
       
   473     // There is no need to inform about the purchase progress.
       
   474     switch( Controller().ContentOperationManager().OperationType() )
       
   475         {
       
   476         case CIAUpdateContentOperationManager::EDownloadOperation:
       
   477             IAUPDATE_TRACE("[IAUPDATE] Download operation progress");
       
   478             iOperationObserver->
       
   479                 DownloadProgress( *this, aProgress, aMaxProgress );
       
   480             break;
       
   481 
       
   482         case CIAUpdateContentOperationManager::EInstallOperation:
       
   483             IAUPDATE_TRACE("[IAUPDATE] Install operation progress");
       
   484             iOperationObserver->
       
   485                 InstallProgress( *this, aProgress, aMaxProgress );
       
   486             break;
       
   487 
       
   488         default:
       
   489             IAUPDATE_TRACE_1("[IAUPDATE] Do not inform observer: %d",
       
   490                              Controller().
       
   491                                 ContentOperationManager().
       
   492                                     OperationType());
       
   493             break;
       
   494         }
       
   495         
       
   496     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationProgress() end");
       
   497     }
       
   498 
       
   499 
       
   500 // ---------------------------------------------------------------------------
       
   501 // Public functions
       
   502 // 
       
   503 // ---------------------------------------------------------------------------
       
   504 
       
   505 
       
   506 // ---------------------------------------------------------------------------
       
   507 // CIAUpdateNode::Reset
       
   508 // 
       
   509 // ---------------------------------------------------------------------------
       
   510 //
       
   511 void CIAUpdateNode::Reset()
       
   512     {
       
   513     SetDependencyCheckStatus( 
       
   514         CIAUpdateNode::EDependencyCheckNotSet );
       
   515     SetDepth( 0 );
       
   516     SetLeafDistance( 0 );
       
   517     iDependants.Reset();
       
   518     iExcessDependencyNodes.Reset();
       
   519     }
       
   520 
       
   521 
       
   522 // ---------------------------------------------------------------------------
       
   523 // CIAUpdateNode::IsPurchased
       
   524 // 
       
   525 // ---------------------------------------------------------------------------
       
   526 //
       
   527 TBool CIAUpdateNode::IsPurchased() const
       
   528     {
       
   529     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsPurchased() begin");
       
   530 
       
   531     TBool purchased( EFalse );
       
   532     TRAP_IGNORE( purchased = IsPurchasedL() );
       
   533 
       
   534     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsPurchased() end: %d", purchased);
       
   535 
       
   536     return purchased;
       
   537     }
       
   538 
       
   539 
       
   540 // ---------------------------------------------------------------------------
       
   541 // CIAUpdateNode::SetExcessDependencyL
       
   542 // 
       
   543 // ---------------------------------------------------------------------------
       
   544 //
       
   545 void CIAUpdateNode::SetExcessDependencyL( 
       
   546     CIAUpdateNode& aDependencyNode,
       
   547     TBool aAddDependency )
       
   548     {
       
   549     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::SetExcessDependencyL() begin");
       
   550     
       
   551     // First check if the dependency has already been set in details.
       
   552     RPointerArray< CIAUpdateNodeDependency > dependencies;
       
   553     CleanupClosePushL( dependencies );
       
   554     Details().GetDependenciesL( dependencies );
       
   555     for ( TInt i = 0; i < dependencies.Count(); ++i )
       
   556         {
       
   557         CIAUpdateNodeDependency* dependency( dependencies[ i ] );
       
   558         if ( dependency->Uid() == aDependencyNode.Uid() )
       
   559             {
       
   560             // Dependency has already been set.
       
   561             CleanupStack::PopAndDestroy( &dependencies );
       
   562             return;
       
   563             }
       
   564         }
       
   565     CleanupStack::PopAndDestroy( &dependencies );
       
   566 
       
   567     // Check if the node already exists in excess array.
       
   568     for ( TInt i = 0; i < iExcessDependencyNodes.Count(); ++i )
       
   569         {
       
   570         CIAUpdateNode* node( iExcessDependencyNodes[ i ] );
       
   571         if ( node->Uid() == aDependencyNode.Uid() )
       
   572             {
       
   573             // Dependency has already been set.            
       
   574             return;
       
   575             }
       
   576         }
       
   577 
       
   578     // Depth update and loop check.
       
   579     RPointerArray< CIAUpdateNode > dependencyNodes;
       
   580     CleanupClosePushL( dependencyNodes );
       
   581     // Get dependency hierarchy.
       
   582     // Accept all kind of nodes.
       
   583     Controller().
       
   584         ContentOperationManager().
       
   585             GetOperationNodesL( aDependencyNode, 
       
   586                                 dependencyNodes,
       
   587                                 ETrue, ETrue );
       
   588     TInt findError( 
       
   589         dependencyNodes.Find( this ) );
       
   590     CleanupStack::PopAndDestroy( &dependencyNodes );
       
   591 
       
   592     // If the given dependency node depends on this node,
       
   593     // then new dependency would create a loop. So, only
       
   594     // accept node if loop will not occur.
       
   595     if ( findError == KErrNotFound )
       
   596         {
       
   597         IAUPDATE_TRACE("[IAUPDATE] Check passed");
       
   598 
       
   599         // Update the leaf distances of the this dependant node
       
   600         // and its dependant hierarchy if necessary. Dependant leaf
       
   601         // distance is always at least one greater than its dependency
       
   602         // leaf distance.
       
   603         UpdateDependantLeafDistancesL(
       
   604             aDependencyNode.LeafDistance() + 1 );
       
   605 
       
   606         // Update the depth of the dependency hierarchy
       
   607         // if necessary. Dependency depth is always at least one
       
   608         // greater than depth of its dependant.
       
   609         aDependencyNode.
       
   610             UpdateDependencyDepthsL( Depth() + 1 );
       
   611 
       
   612         if ( aAddDependency )
       
   613             {
       
   614             IAUPDATE_TRACE("[IAUPDATE] Add dependency"); 
       
   615             // Insert the given dependant node into the array.
       
   616             // The given node is thought as the best match for the dependency.
       
   617             // Also, this function supposes that the dependency chain below the dependency
       
   618             // node is intact.
       
   619             iExcessDependencyNodes.AppendL( &aDependencyNode );
       
   620             // Also, because new dependency is inserted, make sure that
       
   621             // the dependency node dependant info is set correctly.
       
   622             aDependencyNode.AddDependantL( *this );            
       
   623             }
       
   624         }
       
   625 
       
   626     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::SetExcessDependencyL() end");
       
   627     }
       
   628 
       
   629 
       
   630 // ---------------------------------------------------------------------------
       
   631 // CIAUpdateNode::GetDependencyNodesL
       
   632 // 
       
   633 // ---------------------------------------------------------------------------
       
   634 //
       
   635 void CIAUpdateNode::GetDependencyNodesL( 
       
   636     RPointerArray< CIAUpdateNode >& aDependencies,
       
   637     TBool aIncludeHidden ) const
       
   638     {
       
   639     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependencyNodesL() begin");
       
   640     
       
   641     RPointerArray< CIAUpdateNodeDependency > dependencies;
       
   642     CleanupClosePushL( dependencies );
       
   643 
       
   644     // First get the dependencies from the details object.
       
   645     // These are dependencies given by the server itself.
       
   646     Details().GetDependenciesL( dependencies );
       
   647     
       
   648     aDependencies.ReserveL( 
       
   649         dependencies.Count() + iExcessDependencyNodes.Count() );
       
   650     
       
   651     // Insert node that corresponds the details to the array.
       
   652     for ( TInt i = 0; i < dependencies.Count(); ++i )
       
   653         {
       
   654         CIAUpdateNodeDependency* dependency( dependencies[ i ] );
       
   655         CIAUpdateNode* node( dependency->BestMatch() );
       
   656         if ( node && ( aIncludeHidden || !node->Hidden() ) )
       
   657             {
       
   658             aDependencies.AppendL( node );        
       
   659             }
       
   660         }
       
   661     
       
   662     CleanupStack::PopAndDestroy( &dependencies );
       
   663 
       
   664     // Insert excess dependencies to the array.
       
   665     for ( TInt i = 0; i < iExcessDependencyNodes.Count(); ++i )
       
   666         {
       
   667         CIAUpdateNode* node( iExcessDependencyNodes[ i ] );
       
   668         if ( aIncludeHidden || !node->Hidden() )
       
   669             {
       
   670             aDependencies.AppendL( node );
       
   671             }
       
   672         }
       
   673 
       
   674     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependencyNodesL() end");
       
   675     }
       
   676 
       
   677 
       
   678 // ---------------------------------------------------------------------------
       
   679 // CIAUpdateNode::SetDependencyCheckStatus
       
   680 // 
       
   681 // ---------------------------------------------------------------------------
       
   682 //
       
   683 void CIAUpdateNode::SetDependencyCheckStatus( 
       
   684     CIAUpdateNode::TDependencyCheckStatus aStatus )
       
   685     {
       
   686     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::SetDependencyCheckStatus() = %d", 
       
   687                      aStatus );
       
   688     iDependencyCheckStatus = aStatus;
       
   689     }
       
   690 
       
   691 // ---------------------------------------------------------------------------
       
   692 // CIAUpdateNode::DependencyCheckStatus()
       
   693 // 
       
   694 // ---------------------------------------------------------------------------
       
   695 //    
       
   696 CIAUpdateNode::TDependencyCheckStatus CIAUpdateNode::DependencyCheckStatus() const
       
   697     {
       
   698     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::DependencyCheckStatus() = %d", 
       
   699                      iDependencyCheckStatus );
       
   700     return iDependencyCheckStatus;
       
   701     }   
       
   702     
       
   703 
       
   704 // ---------------------------------------------------------------------------
       
   705 // CIAUpdateNode::LeafDistance
       
   706 // 
       
   707 // ---------------------------------------------------------------------------
       
   708 //
       
   709 TInt CIAUpdateNode::LeafDistance() const
       
   710     {
       
   711     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::LeafDistance() = %d", 
       
   712                      iLeafDistance );
       
   713     return iLeafDistance;
       
   714     }
       
   715 
       
   716 // ---------------------------------------------------------------------------
       
   717 // CIAUpdateNode::SetLeafDistance
       
   718 // 
       
   719 // ---------------------------------------------------------------------------
       
   720 //
       
   721 void CIAUpdateNode::SetLeafDistance( TInt aDistance )
       
   722     {
       
   723     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::SetLeafDistance() = %d", 
       
   724                      aDistance );
       
   725     iLeafDistance = aDistance;
       
   726     }
       
   727 
       
   728 
       
   729 // ---------------------------------------------------------------------------
       
   730 // CIAUpdateNode::SetDepth
       
   731 // 
       
   732 // ---------------------------------------------------------------------------
       
   733 //
       
   734 void CIAUpdateNode::SetDepth( TInt aDepth )
       
   735     {
       
   736     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::SetDepth() = %d", 
       
   737                      aDepth );
       
   738     iDepth = aDepth;
       
   739     }
       
   740 
       
   741 
       
   742 // ---------------------------------------------------------------------------
       
   743 // CIAUpdateNode::DependantNodes
       
   744 // 
       
   745 // ---------------------------------------------------------------------------
       
   746 //
       
   747 const RPointerArray< CIAUpdateNode >& CIAUpdateNode::DependantNodes() const
       
   748     {
       
   749     return iDependants;
       
   750     }
       
   751 
       
   752 
       
   753 // ---------------------------------------------------------------------------
       
   754 // CIAUpdateNode::AddDependantL
       
   755 // 
       
   756 // ---------------------------------------------------------------------------
       
   757 //
       
   758 void CIAUpdateNode::AddDependantL( CIAUpdateNode& aDependantNode ) 
       
   759     {
       
   760 	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::AddDependantL() begin");
       
   761 
       
   762 	for ( TInt i = 0; i < iDependants.Count(); ++i )
       
   763 	    {
       
   764 	    CIAUpdateNode* node( iDependants[ i ] );
       
   765 	    if ( node->Uid() == aDependantNode.Uid() )
       
   766 	        {
       
   767 	        // Corresponding node is already in the array.
       
   768 	        return;
       
   769 	        }
       
   770 	    }
       
   771 
       
   772 	iDependants.AppendL( &aDependantNode );
       
   773 
       
   774 	IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::AddDependantL() end");
       
   775     }
       
   776 
       
   777 
       
   778 // ---------------------------------------------------------------------------
       
   779 // CIAUpdateNode::UpdateDependencyDepthsL
       
   780 // 
       
   781 // ---------------------------------------------------------------------------
       
   782 //
       
   783 void CIAUpdateNode::UpdateDependencyDepthsL( TInt aDepth )
       
   784     {
       
   785     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::UpdateDependencyDepthsL() begin: %d",
       
   786                      aDepth);
       
   787     
       
   788     // Notice, that by comparing depths here, we also make sure
       
   789     // that the depth is increased correctly if we come to same
       
   790     // dependency node via multiple branches. Multiple dependants 
       
   791     // can depend on the same node.
       
   792 
       
   793     // If dependant depth had increased, then depenencies should
       
   794     // also increase their depth. Also, update if negative value is given.
       
   795     // Then, think this node as root.
       
   796     if ( aDepth > Depth() )
       
   797         {
       
   798         IAUPDATE_TRACE("[IAUPDATE] Update dependency depth");
       
   799 
       
   800         SetDepth( aDepth );
       
   801 
       
   802         RPointerArray< CIAUpdateNode > dependencies;
       
   803         CleanupClosePushL( dependencies );
       
   804         
       
   805         // Also, accept hidden nodes here.
       
   806         GetDependencyNodesL( dependencies, ETrue );
       
   807         
       
   808         // Recursively loop all the dependencies of the node
       
   809         for ( TInt i = 0; i < dependencies.Count(); ++i )
       
   810             {
       
   811             dependencies[ i ]
       
   812                 ->UpdateDependencyDepthsL( 
       
   813                     Depth() + 1 );
       
   814             }
       
   815 
       
   816         CleanupStack::PopAndDestroy( &dependencies );
       
   817         }
       
   818 
       
   819     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::UpdateDependencyDepthsL() end");
       
   820     }
       
   821 
       
   822 
       
   823 // ---------------------------------------------------------------------------
       
   824 // Protected functions
       
   825 // 
       
   826 // ---------------------------------------------------------------------------
       
   827 
       
   828 
       
   829 // ---------------------------------------------------------------------------
       
   830 // CIAUpdateNode::IsPurchasedL
       
   831 // 
       
   832 // ---------------------------------------------------------------------------
       
   833 //
       
   834 TBool CIAUpdateNode::IsPurchasedL() const
       
   835     {
       
   836     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsPurchasedL() begin");
       
   837     
       
   838     TBool purchased( EFalse );
       
   839     
       
   840     MNcdNodePurchase* purchase( 
       
   841         Node().QueryInterfaceLC< MNcdNodePurchase >() );
       
   842     
       
   843     if ( purchase )
       
   844         {
       
   845         if( purchase->IsPurchased() )
       
   846             {
       
   847             purchased = ETrue;
       
   848             }
       
   849 
       
   850         CleanupStack::PopAndDestroy( purchase );
       
   851         }
       
   852 
       
   853     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsPurchasedL() end: %d", 
       
   854                      purchased);
       
   855 
       
   856     return purchased;
       
   857     }
       
   858 
       
   859 
       
   860 // ---------------------------------------------------------------------------
       
   861 // CIAUpdateNode::IsDownloadedL
       
   862 // 
       
   863 // ---------------------------------------------------------------------------
       
   864 //
       
   865 TBool CIAUpdateNode::IsDownloadedL() const
       
   866     {
       
   867     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsDownloadedL() begin");
       
   868     
       
   869     TBool downloaded( EFalse );
       
   870     
       
   871     MNcdNodeDownload* download( 
       
   872         Node().QueryInterfaceLC< MNcdNodeDownload >() );
       
   873     
       
   874     if ( download )
       
   875         {
       
   876         if( download->IsDownloadedL() )
       
   877             {
       
   878             downloaded = ETrue;            
       
   879             }
       
   880 
       
   881         CleanupStack::PopAndDestroy( download );
       
   882         }
       
   883 
       
   884     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsDownloadedL() end: %d", 
       
   885                      downloaded);
       
   886 
       
   887     return downloaded;
       
   888     }    
       
   889 
       
   890 
       
   891 // ---------------------------------------------------------------------------
       
   892 // CIAUpdateNode::IsInstalledL
       
   893 // 
       
   894 // ---------------------------------------------------------------------------
       
   895 //
       
   896 TBool CIAUpdateNode::IsInstalledL() const
       
   897     {
       
   898     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalledL() begin");
       
   899 
       
   900     TIAUpdateVersion installedVersion;
       
   901     TBool installed( IAUpdateUtils::IsAppInstalledL( Uid(), installedVersion ) );
       
   902     IAUPDATE_TRACE_3("CIAUpdateNode::IsInstalledL() Installed version  %d.%d.%d", 
       
   903             installedVersion.iMajor, 
       
   904             installedVersion.iMinor, 
       
   905             installedVersion.iBuild );
       
   906     IAUPDATE_TRACE_3("CIAUpdateNode::IsInstalledL() Metadata version  %d.%d.%d", 
       
   907             Version().iMajor, 
       
   908             Version().iMinor, 
       
   909             Version().iBuild );
       
   910     if ( installed && installedVersion >= Version() )
       
   911         {
       
   912         // If the installed version is same or newer, then think the node as
       
   913         // installed.
       
   914         IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalledL() end ETrue");
       
   915         return ETrue;
       
   916         }
       
   917     else
       
   918         {
       
   919         IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalledL() end EFalse");
       
   920         return EFalse;
       
   921         }
       
   922     }    
       
   923 
       
   924 
       
   925 // ---------------------------------------------------------------------------
       
   926 // CIAUpdateNode::OperationObserverL
       
   927 // 
       
   928 // ---------------------------------------------------------------------------
       
   929 //
       
   930 MIAUpdateNodeObserver* CIAUpdateNode::OperationObserver() const
       
   931     {
       
   932     return iOperationObserver;
       
   933     }
       
   934 
       
   935 
       
   936 // ---------------------------------------------------------------------------
       
   937 // Private functions
       
   938 // 
       
   939 // ---------------------------------------------------------------------------
       
   940 
       
   941 
       
   942 // ---------------------------------------------------------------------------
       
   943 // CIAUpdateNode::UpdateDependantLeafDistancesL
       
   944 // 
       
   945 // ---------------------------------------------------------------------------
       
   946 //
       
   947 void CIAUpdateNode::UpdateDependantLeafDistancesL( TInt aLeafDistance )
       
   948     {
       
   949     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::UpdateDependantLeafDistancesL() begin");
       
   950     
       
   951     // Notice, that by comparing depths here, we also make sure
       
   952     // that the leaf distance is increased correctly if we come to same
       
   953     // dependant node via multiple branches. Multiple dependants 
       
   954     // can depend on the same node.
       
   955 
       
   956     // Dependant leaf distance should be at least one greater than
       
   957     // dependency depth. 
       
   958     if ( aLeafDistance > LeafDistance() )
       
   959         {
       
   960         IAUPDATE_TRACE("[IAUPDATE] Update dependant distance");
       
   961 
       
   962         SetLeafDistance( aLeafDistance );
       
   963 
       
   964         // Recursively loop all the dependants of the node
       
   965         for ( TInt i = 0; i < DependantNodes().Count(); ++i )
       
   966             {
       
   967             DependantNodes()[ i ]
       
   968                 ->UpdateDependantLeafDistancesL( 
       
   969                     LeafDistance() + 1 );
       
   970             }
       
   971         }
       
   972 
       
   973     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::UpdateDependantLeafDistancesL() end");
       
   974     }