iaupdate/IAD/engine/controller/src/iaupdateloader.cpp
changeset 0 ba25891c3a9e
child 1 c42dffbd5b4f
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 
       
    15 *                CIAUpdateLoader class member functions.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include <ncdprovider.h>
       
    23 #include <ncdnode.h>
       
    24 #include <ncdnodecontainer.h>
       
    25 #include <ncdloadnodeoperation.h>
       
    26 #include <ncdquery.h>
       
    27 #include <ncdnodechildoftransparent.h>
       
    28 
       
    29 #include "iaupdateloader.h"
       
    30 #include "iaupdateloaderobserver.h"
       
    31 #include "iaupdatectrlconsts.h"
       
    32 #include "iaupdateversion.h"
       
    33 #include "iaupdateutils.h"
       
    34 #include "iaupdatedebug.h"
       
    35 
       
    36 
       
    37 // Use KMaxTInt value for the child count.
       
    38 // Then, all the children will be downloaded 
       
    39 // even if the parent does not have the correct
       
    40 // information about its child count.
       
    41 const TInt KChildCountLoadAll( KMaxTInt );
       
    42 
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CIAUpdateLoader::NewLC
       
    46 // Two-phased constructor.
       
    47 // -----------------------------------------------------------------------------
       
    48 //
       
    49 CIAUpdateLoader* CIAUpdateLoader::NewLC( 
       
    50     MNcdProvider& aProvider, 
       
    51     MIAUpdateLoaderObserver& aObserver )
       
    52     {
       
    53     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::NewLC() begin");
       
    54     
       
    55     CIAUpdateLoader* self = 
       
    56         new( ELeave ) CIAUpdateLoader( aProvider, aObserver );
       
    57     CleanupStack::PushL( self );
       
    58     self->ConstructL();
       
    59 
       
    60     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::NewLC() end");
       
    61 
       
    62     return self;
       
    63     }
       
    64 
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CIAUpdateLoader::NewL
       
    68 // Two-phased constructor.
       
    69 // -----------------------------------------------------------------------------
       
    70 //    
       
    71 CIAUpdateLoader* CIAUpdateLoader::NewL(
       
    72     MNcdProvider& aProvider, 
       
    73     MIAUpdateLoaderObserver& aObserver )
       
    74     {
       
    75     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::NewL() begin");
       
    76 
       
    77     CIAUpdateLoader* self = 
       
    78         CIAUpdateLoader::NewLC( aProvider, aObserver );
       
    79     CleanupStack::Pop( self );
       
    80 
       
    81     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::NewL() end");
       
    82 
       
    83     return self;
       
    84     }
       
    85 
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CIAUpdateLoader::CIAUpdateLoader
       
    89 // C++ default constructor can NOT contain any code, that
       
    90 // might leave.
       
    91 // -----------------------------------------------------------------------------
       
    92 //        
       
    93 CIAUpdateLoader::CIAUpdateLoader(
       
    94     MNcdProvider& aProvider, 
       
    95     MIAUpdateLoaderObserver& aObserver ) 
       
    96 : CBase(),
       
    97   iProvider( aProvider ), 
       
    98   iObserver( aObserver )
       
    99     {
       
   100     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::CIAUpdateLoader()");
       
   101     }
       
   102 
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // CIAUpdateLoader::ConstructL
       
   106 // Symbian 2nd phase constructor can leave.
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 void CIAUpdateLoader::ConstructL()
       
   110     {
       
   111     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::ConstructL() begin");
       
   112     
       
   113     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::ConstructL() end");
       
   114     }
       
   115     
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CIAUpdateLoader::~CIAUpdateLoader
       
   119 // Destructor
       
   120 // -----------------------------------------------------------------------------
       
   121 //     
       
   122 CIAUpdateLoader::~CIAUpdateLoader()
       
   123     {
       
   124     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::~CIAUpdateLoader() begin");
       
   125 
       
   126     // Call just to be sure.
       
   127     Cancel();
       
   128 
       
   129     iOperations.Close();
       
   130 
       
   131     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::~CIAUpdateLoader() end");
       
   132     }
       
   133 
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // CIAUpdateLoader::RootExpiredL
       
   137 // 
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 TBool CIAUpdateLoader::RootExpiredL() const
       
   141     {
       
   142     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::RootExpiredL() begin");
       
   143     
       
   144     TBool rootExpired( EFalse );
       
   145 
       
   146     // Remember to release this node when it is not needed.
       
   147     MNcdNode* rootNode( iProvider.RootNodeL() );
       
   148 
       
   149     // Get the state of the root.
       
   150     MNcdNode::TState rootState( rootNode->State() );
       
   151 
       
   152     IAUPDATE_TRACE_1("[IAUPDATE] Root state: %d",
       
   153                      rootState);
       
   154 
       
   155     // Check if the root is expired or not.
       
   156     if ( rootState == MNcdNode::EStateExpired )
       
   157         {
       
   158         IAUPDATE_TRACE("[IAUPDATE] Root is expired");
       
   159         rootExpired = ETrue;
       
   160         }
       
   161 
       
   162     MNcdNodeContainer* container( rootNode->QueryInterfaceLC< MNcdNodeContainer >() );               
       
   163     TInt childCount( container->ChildCount() );
       
   164     CleanupStack::PopAndDestroy( container );
       
   165     
       
   166     IAUPDATE_TRACE_1("[IAUPDATE] count of children: %d", childCount ); 
       
   167     
       
   168     //2 here means arrow CGW and firmware CGW. If one of them failed last time, 
       
   169     //refresh from CDB again
       
   170     if ( childCount != 2 && rootState == MNcdNode::EStateInitialized )
       
   171         {
       
   172         IAUPDATE_TRACE("[IAUPDATE] Root is expired. update from phase 1 to phase 2 or previous CGW load failed");
       
   173         rootExpired = ETrue;
       
   174         }
       
   175     // Release root because it is not needed any more.
       
   176     rootNode->Release();
       
   177     
       
   178     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::RootExpiredL() end");
       
   179 
       
   180     return rootExpired;
       
   181     }
       
   182 
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // CIAUpdateLoader::LoadNodesL
       
   186 // 
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 void CIAUpdateLoader::LoadNodesL()
       
   190     {
       
   191     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadNodesL() begin");
       
   192     
       
   193     if ( iOperations.Count() > 0 )
       
   194         {
       
   195         // 
       
   196         IAUPDATE_TRACE("[IAUPDATE] ERROR: Refresh already going on.");
       
   197         User::Leave( KErrInUse );
       
   198         }
       
   199 
       
   200     // Reset this value for new round.
       
   201     iErrorCode = KErrNone;
       
   202         
       
   203     // Root refresh will handle everything.
       
   204     LoadRootL();
       
   205 
       
   206     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadNodesL() end");
       
   207     }
       
   208 
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CIAUpdateLoader::Cancel
       
   212 // 
       
   213 // -----------------------------------------------------------------------------
       
   214 // 
       
   215 void CIAUpdateLoader::Cancel()
       
   216     {
       
   217     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::Cancel() begin");
       
   218 
       
   219     // Cancel asynchronous operations.
       
   220     
       
   221     // Use this flag to inform that operation complete callback function
       
   222     // that cancellation is going on. Cancel related things are handled
       
   223     // here.
       
   224     iCancelling = ETrue;
       
   225 
       
   226     // Operations will use callback functions to inform 
       
   227     // when the operation is completed.
       
   228     TInt count( iOperations.Count() );
       
   229     IAUPDATE_TRACE_1("[IAUPDATE] Cancel array count: %d", count);
       
   230 
       
   231     for ( TInt i = count - 1; i >= 0; --i )    
       
   232         {
       
   233         TIAUpdateOperationInfo info( iOperations[ i ] );
       
   234         MNcdOperation* operation( info.iOperation );
       
   235 
       
   236         // Notice, that OperationCompleteL callback is called when
       
   237         // cancellation finishes
       
   238         operation->CancelOperation();
       
   239       
       
   240         }
       
   241         
       
   242     // Now, that the array elements were released, reset the array.
       
   243     iOperations.Reset();
       
   244 
       
   245     // Release the flag now, that all the cancellations have been handled.
       
   246     iCancelling = EFalse;
       
   247 
       
   248     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::CancelOperation() end");
       
   249     }
       
   250 
       
   251 
       
   252 // -----------------------------------------------------------------------------
       
   253 // CIAUpdateLoader::SetSkipChildCountRefresh
       
   254 // 
       
   255 // -----------------------------------------------------------------------------
       
   256 // 
       
   257 void CIAUpdateLoader::SetSkipChildCountRefresh( TBool aSkip )
       
   258     {
       
   259     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateLoader::SetSkipChildCountRefresh(): %d",
       
   260                      aSkip);
       
   261     iSkipChildCountRefresh = aSkip;
       
   262     }
       
   263 
       
   264 
       
   265 // -----------------------------------------------------------------------------
       
   266 // CIAUpdateLoader::NodesUpdated
       
   267 // 
       
   268 // -----------------------------------------------------------------------------
       
   269 // 
       
   270 void CIAUpdateLoader::NodesUpdated( 
       
   271     MNcdLoadNodeOperation& /*aOperation*/,
       
   272     RCatalogsArray< MNcdNode >& /*aNodes*/ )
       
   273     {
       
   274     // No need to inform the observer about single updates.
       
   275     }
       
   276 
       
   277 
       
   278 // -----------------------------------------------------------------------------
       
   279 // CIAUpdateLoader::QueryReceived
       
   280 // 
       
   281 // -----------------------------------------------------------------------------
       
   282 // 
       
   283 void CIAUpdateLoader::QueryReceived( 
       
   284     MNcdLoadNodeOperation& aOperation,
       
   285     MNcdQuery* aQuery )  
       
   286     {
       
   287     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::QueryReceived() begin");
       
   288 
       
   289     // Operation query received. Always accept queries.
       
   290     // Queries should not be requested from this client.
       
   291     TInt trapError( KErrNone );
       
   292     if ( aQuery )
       
   293         {
       
   294         TRAP ( trapError, 
       
   295                aQuery->SetResponseL( MNcdQuery::EAccepted );
       
   296                aOperation.CompleteQueryL( *aQuery ); );
       
   297         // Release needs to be called to the query after it is not used.
       
   298         aQuery->Release();        
       
   299         }
       
   300 
       
   301     if ( ( trapError != KErrNone ) || ( !aQuery ) )
       
   302         {
       
   303         // Error occurred when query was handled.
       
   304         // So, operation can not continue.
       
   305         // Cancel operation. Notice, that OperationComplete will be called
       
   306         // by the operation when cancel is called.
       
   307         aOperation.CancelOperation();
       
   308         }
       
   309 
       
   310     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::QueryReceived() end");
       
   311     }
       
   312 
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // CIAUpdateLoader::OperationComplete
       
   316 // 
       
   317 // -----------------------------------------------------------------------------
       
   318 // 
       
   319 void CIAUpdateLoader::OperationComplete( 
       
   320     MNcdLoadNodeOperation& aOperation,
       
   321     TInt aError )
       
   322     {
       
   323     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateLoader::OperationComplete() begin: %d",
       
   324                      aError);
       
   325 
       
   326     MNcdNode* operationNode( NULL );
       
   327     TIAUpdateOperationInfo::TOperationType operationType( 
       
   328                     TIAUpdateOperationInfo::EIdle );
       
   329 
       
   330     // Remember to release the operation, 
       
   331     // because its reference count was increased
       
   332     // when the operation was inserted into the array.
       
   333     for ( TInt i = 0; i < iOperations.Count(); ++i )
       
   334         {
       
   335         TIAUpdateOperationInfo tmpInfo( iOperations[ i ] );
       
   336         MNcdOperation* operation( tmpInfo.iOperation );
       
   337         MNcdOperation* paramOperation( &aOperation );
       
   338         if ( paramOperation == operation )
       
   339             {
       
   340             IAUPDATE_TRACE_1("[IAUPDATE] Completed operation was found from the list %d",
       
   341                                  i);
       
   342 
       
   343             // Get the operation type info. 
       
   344             // Then, we can later decide how to continue.
       
   345             operationType = tmpInfo.iOperationType;
       
   346 
       
   347             // Get the node of the operation.
       
   348             // Notice, this needs to be released.
       
   349             operationNode = operation->Node();
       
   350 
       
   351             // Release the operation here because its reference count
       
   352             // was increased before it was added into the array.
       
   353             operation->Release();
       
   354                 
       
   355             // Remove completed operation from the array.
       
   356             iOperations.Remove( i );
       
   357 
       
   358             // No need to continue the for loop anymore.
       
   359             break;
       
   360             }
       
   361         }
       
   362 
       
   363     if ( operationNode )
       
   364         {
       
   365         if ( aError != KErrNone )
       
   366             {
       
   367             // Get the latest error code, if error has occurred.
       
   368             // We handle here only error codes that have been
       
   369             // directed to the operations that we recognized from the
       
   370             // operation array.
       
   371             
       
   372             //Continue next round to load the children.
       
   373             //This is to make sure when one CGW loading failed, the updates from the other CGW will
       
   374             //still be shown in mainview.
       
   375             TRAP_IGNORE( NextLoadLoopL( *operationNode, operationType ) );
       
   376             IAUPDATE_TRACE_1("[IAUPDATE] New iErrorCode value: %d", aError);
       
   377             
       
   378             if ( iErrorCode == KErrNone )
       
   379                 {
       
   380                 iErrorCode = aError;
       
   381                 }
       
   382             }
       
   383         else
       
   384             {
       
   385             // Continue to the next loop only if an error did not occur 
       
   386             // during this round.
       
   387             TRAPD( trapError,
       
   388                    NextLoadLoopL( *operationNode, operationType ) );
       
   389             if ( trapError != KErrNone )
       
   390                 {
       
   391                 IAUPDATE_TRACE_1("[IAUPDATE] ERROR: Next round error: %d", trapError);
       
   392                 // Something went wrong when children load was started.
       
   393                 // Update error code.
       
   394                 iErrorCode = trapError;
       
   395                 }
       
   396             }
       
   397 
       
   398         // No need for the node anymore.
       
   399         operationNode->Release();
       
   400         operationNode = NULL;
       
   401         }
       
   402 
       
   403     if ( iOperations.Count() == 0 )
       
   404         {
       
   405         IAUPDATE_TRACE("[IAUPDATE] The operation as whole completed");
       
   406         // No more operations left. So, inform observer.
       
   407         if ( iErrorCode == KErrNone )
       
   408             {
       
   409             // Because of workaround needed for handling firmware updates.
       
   410             // Refresh from network was completed succesfully.
       
   411             // Current firmware version is stored to private folder. 
       
   412             TRAP_IGNORE( IAUpdateUtils::SaveCurrentFwVersionIfNeededL() );
       
   413             }
       
   414         iObserver.LoadComplete( iErrorCode );
       
   415         }
       
   416         
       
   417     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::OperationComplete() end");
       
   418     }
       
   419 
       
   420 
       
   421 // -----------------------------------------------------------------------------
       
   422 // CIAUpdateLoader::LoadRootL
       
   423 // 
       
   424 // -----------------------------------------------------------------------------
       
   425 //
       
   426 void CIAUpdateLoader::LoadRootL()
       
   427     {
       
   428     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadRootL() begin");
       
   429     
       
   430     MNcdNode* rootNode( iProvider.RootNodeL() );
       
   431     CleanupReleasePushL( *rootNode );
       
   432 
       
   433     MNcdNodeContainer* rootContainer(
       
   434         rootNode->QueryInterfaceLC< MNcdNodeContainer >() );
       
   435 
       
   436     if ( !rootContainer )
       
   437         {
       
   438         User::Leave( KErrNotFound );            
       
   439         }
       
   440 
       
   441     MNcdNode::TState rootState( rootNode->State() );
       
   442     if ( rootState == MNcdNode::EStateInitialized )
       
   443         {
       
   444         IAUPDATE_TRACE("[IAUPDATE] Root already initialized.");
       
   445 
       
   446         // CDB connections should be avoided if possible. So, if the
       
   447         // root node is initialized and not expired, then do not update it
       
   448         // from the net. Just continue directly to its children.
       
   449 
       
   450         if ( iSkipChildCountRefresh )
       
   451             {
       
   452             IAUPDATE_TRACE("[IAUPDATE] Root, load all children and skip child count refresh.");
       
   453             // Because child count refresh should be skipped. Try to load children
       
   454             // of the children directly without requesting the child count first.
       
   455             LoadChildrenOfChildrenL( 
       
   456                 *rootContainer, TIAUpdateOperationInfo::ELoadAllChildren );
       
   457             }
       
   458         else
       
   459             {
       
   460             IAUPDATE_TRACE("[IAUPDATE] Root, load child containers.");
       
   461             // At the moment, NCD Engine does not load root children nodes 
       
   462             // when MNcdContainer::LoadChildrenL is called. So, we have to
       
   463             // load the children one by one here.
       
   464             LoadChildContainersL( *rootContainer );            
       
   465             }
       
   466         }
       
   467     else
       
   468         {
       
   469         IAUPDATE_TRACE_1("[IAUPDATE] Refresh root. State: %d", rootState);
       
   470 
       
   471         // Start loading root.
       
   472         StartLoadOperationL( *rootContainer, TIAUpdateOperationInfo::ELoadRoot );
       
   473         }
       
   474 
       
   475     // No use for the node objects any more. Release them.
       
   476     CleanupStack::PopAndDestroy( rootContainer );
       
   477     CleanupStack::PopAndDestroy( rootNode );
       
   478 
       
   479     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadRootL() end");
       
   480     }
       
   481 
       
   482 
       
   483 // -----------------------------------------------------------------------------
       
   484 // CIAUpdateLoader::LoadChildContainersL
       
   485 // 
       
   486 // -----------------------------------------------------------------------------
       
   487 //    
       
   488 void CIAUpdateLoader::LoadChildContainersL( MNcdNodeContainer& aParentContainer )
       
   489     {
       
   490     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadChildContainersL() begin");
       
   491     
       
   492     // LoadL is used to update the children of the parent container here
       
   493     // instead of updating them by calling LoadChildrenL function.
       
   494 
       
   495     TInt childCount( aParentContainer.ChildCount() );
       
   496     IAUPDATE_TRACE_1("[IAUPDATE] Parent container child count: %d", childCount);
       
   497  
       
   498     for ( TInt i = 0; i < childCount; ++i )
       
   499         {
       
   500         IAUPDATE_TRACE_1("[IAUPDATE] Container child: %d", i);
       
   501 
       
   502         MNcdNode* node( aParentContainer.ChildL( i ) );
       
   503         CleanupReleasePushL( *node );
       
   504 
       
   505         MNcdNodeContainer* container(
       
   506             node->QueryInterfaceLC< MNcdNodeContainer >() );
       
   507         if ( container )
       
   508             {
       
   509             IAUPDATE_TRACE("[IAUPDATE] Container child had container interface");
       
   510             LoadContainerL( *container );
       
   511             CleanupStack::PopAndDestroy( container );                
       
   512             }
       
   513 
       
   514         CleanupStack::PopAndDestroy( node );
       
   515         }
       
   516 
       
   517     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadChildContainersL() end");
       
   518     }
       
   519 
       
   520 
       
   521 // -----------------------------------------------------------------------------
       
   522 // CIAUpdateLoader::LoadContainerL
       
   523 // 
       
   524 // -----------------------------------------------------------------------------
       
   525 //
       
   526 void CIAUpdateLoader::LoadContainerL( MNcdNodeContainer& aContainer )
       
   527     {
       
   528     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadContainerL() begin");
       
   529 
       
   530     StartLoadOperationL( 
       
   531         aContainer, TIAUpdateOperationInfo::ELoadContainer );
       
   532 
       
   533     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadContainerL() end");
       
   534     }
       
   535 
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // CIAUpdateLoader::LoadChildrenL
       
   539 // 
       
   540 // -----------------------------------------------------------------------------
       
   541 //    
       
   542 void CIAUpdateLoader::LoadChildrenL( MNcdNodeContainer& aContainer )
       
   543     {
       
   544     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadChildrenL() begin");
       
   545 
       
   546     if ( aContainer.ChildCount() > 0 )
       
   547         {
       
   548         StartLoadOperationL( 
       
   549             aContainer, TIAUpdateOperationInfo::ELoadChildren );        
       
   550         }
       
   551 
       
   552     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadChildrenL() end");
       
   553     }
       
   554 
       
   555 
       
   556 // -----------------------------------------------------------------------------
       
   557 // CIAUpdateLoader::LoadAllChildrenL
       
   558 // 
       
   559 // -----------------------------------------------------------------------------
       
   560 //    
       
   561 void CIAUpdateLoader::LoadAllChildrenL( MNcdNodeContainer& aContainer )
       
   562     {
       
   563     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadAllChildrenL() begin");
       
   564 
       
   565     if ( !iSkipChildCountRefresh )
       
   566         {
       
   567         // Child count skip flag has been set to EFalse in previous round.
       
   568         // Most likely NCD Engine does not support load all children functionality. 
       
   569         // So, just load children using normal flow from now on.
       
   570         // Notice, that now we need to first load the child count
       
   571         // for the child containers. So, even if children were 
       
   572         // already updated by LoadChildrenL, a new request for
       
   573         // containers needs . Otherwise, the child count 
       
   574         // will not be up-to-date. When the child containers are 
       
   575         // loaded, the flow will continue to load the children.
       
   576         IAUPDATE_TRACE("[IAUPDATE] Child count should not be skipped");
       
   577         LoadContainerL( aContainer );
       
   578         IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadAllChildrenL() end");
       
   579         return;
       
   580         }
       
   581 
       
   582     TRAPD ( trapError, 
       
   583             StartLoadOperationL( 
       
   584                 aContainer, TIAUpdateOperationInfo::ELoadAllChildren ); );
       
   585 
       
   586     IAUPDATE_TRACE_1("[IAUPDATE] trapError: %d", trapError);
       
   587 
       
   588     // Only acceptable error is KErrArgument.
       
   589     // Then it is possible that an old NCD Engine is used
       
   590     // and it does not allow too big page size. So, in that
       
   591     // case try one more time below by not skipping child count
       
   592     // refresh. Else, leave if error occurred.
       
   593 
       
   594     if ( trapError == KErrArgument )
       
   595         {
       
   596         IAUPDATE_TRACE("[IAUPDATE] Try to change child load method");
       
   597         // Notice, that now we need to first load the child count
       
   598         // for the child containers. So, even if children were 
       
   599         // already updated by LoadChildrenL, a new request for
       
   600         // containers needs . Otherwise, the child count 
       
   601         // will not be up-to-date. When the child containers are 
       
   602         // loaded, the flow will continue to load the children.
       
   603         LoadContainerL( aContainer );
       
   604         IAUPDATE_TRACE("[IAUPDATE] Child load method changed and container load started");
       
   605         // If we come here, it means that support for all children is
       
   606         // not available in NCD Engine. So, do not try it after this.
       
   607         SetSkipChildCountRefresh( EFalse );
       
   608         }
       
   609     else if ( trapError != KErrNone )
       
   610         {
       
   611         IAUPDATE_TRACE_1("[IAUPDATE] Error: %d", trapError);
       
   612         User::Leave( trapError );
       
   613         }
       
   614 
       
   615     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadAllChildrenL() end");
       
   616     }
       
   617 
       
   618 // -----------------------------------------------------------------------------
       
   619 // CIAUpdateLoader::LoadChildrenOfChildrenL
       
   620 // 
       
   621 // -----------------------------------------------------------------------------
       
   622 //
       
   623 void CIAUpdateLoader::LoadChildrenOfChildrenL( 
       
   624     MNcdNodeContainer& aContainer,
       
   625     TIAUpdateOperationInfo::TOperationType aPreviousOperationType )
       
   626     {
       
   627     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadChildrenOfChildrenL() begin");
       
   628     
       
   629     TInt childCount( aContainer.ChildCount() );
       
   630     IAUPDATE_TRACE_1("[IAUPDATE] Container child count: %d", childCount);
       
   631  
       
   632     for ( TInt i = 0; i < childCount; ++i )
       
   633         {
       
   634         MNcdNode* node( aContainer.ChildL( i ) );
       
   635         CleanupReleasePushL( *node );
       
   636 
       
   637         MNcdNodeContainer* container( 
       
   638             node->QueryInterfaceLC< MNcdNodeContainer >() );
       
   639         if ( container )
       
   640             {
       
   641             IAUPDATE_TRACE_1("[IAUPDATE] Container child: %d had container interface", i);
       
   642 
       
   643             switch ( aPreviousOperationType )
       
   644                 {
       
   645                 case TIAUpdateOperationInfo::ELoadRoot:
       
   646                     IAUPDATE_TRACE("[IAUPDATE] Load children of the root child");
       
   647                     // When root is loaded, also its children are loaded
       
   648                     // and they have now their child count. So, no need to
       
   649                     // reload children of the root. Load their children
       
   650                     // directly now.
       
   651                     LoadChildrenL( *container );
       
   652                     break;
       
   653                     
       
   654                 case TIAUpdateOperationInfo::ELoadChildren:
       
   655                     IAUPDATE_TRACE("[IAUPDATE] Load children of a container");
       
   656                     // Notice, that now we need to first load the child count
       
   657                     // for the child containers. So, even if children were 
       
   658                     // already updated by LoadChildrenL, a new request for
       
   659                     // containers needs . Otherwise, the child count 
       
   660                     // will not be up-to-date. When the child containers are 
       
   661                     // loaded, the flow will continue to load the children.
       
   662                     LoadContainerL( *container );
       
   663                     break;
       
   664 
       
   665                 case TIAUpdateOperationInfo::ELoadAllChildren:
       
   666                     IAUPDATE_TRACE("[IAUPDATE] Load all children of a container");
       
   667                     // Notice, here we will try to skip the loading of the child
       
   668                     // count of the container. So, all the children are tried to
       
   669                     // be loaded directly even if the child count may not be
       
   670                     // up-to-date.
       
   671                     LoadAllChildrenL( *container );
       
   672                     break;
       
   673                     
       
   674                 default:
       
   675                     IAUPDATE_TRACE("[IAUPDATE] ERROR: Wrong operation type");
       
   676                     User::Leave( KErrArgument );
       
   677                     break;
       
   678                 }
       
   679 
       
   680             CleanupStack::PopAndDestroy( container );                
       
   681             }
       
   682 
       
   683         CleanupStack::PopAndDestroy( node );
       
   684         }
       
   685 
       
   686     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::LoadChildrenOfChildrenL() end");
       
   687     }
       
   688 
       
   689 
       
   690 // -----------------------------------------------------------------------------
       
   691 // CIAUpdateLoader::StartLoadOperationL
       
   692 // 
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 void CIAUpdateLoader::StartLoadOperationL( 
       
   696     MNcdNodeContainer& aContainer,
       
   697     TIAUpdateOperationInfo::TOperationType aOperationType )
       
   698     {
       
   699     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::StartLoadOperation() begin");
       
   700 
       
   701     MNcdOperation* operation( NULL );
       
   702 
       
   703     // Create a new operation based on the operation type information.
       
   704     switch ( aOperationType )
       
   705         {
       
   706         case TIAUpdateOperationInfo::ELoadRoot:
       
   707         case TIAUpdateOperationInfo::ELoadContainer:
       
   708             {
       
   709             // Container itself should be loaded.
       
   710             IAUPDATE_TRACE("[IAUPDATE] LoadL requested as operation");
       
   711             MNcdNode* node( aContainer.QueryInterfaceLC< MNcdNode >() );
       
   712             if ( !node )
       
   713                 {
       
   714                 IAUPDATE_TRACE("[IAUPDATE] Container did not have node interface.");
       
   715                 User::Leave( KErrNotFound );
       
   716                 }
       
   717             operation = node->LoadL( *this );
       
   718             // No need for the node anymore
       
   719             CleanupStack::PopAndDestroy( node );
       
   720             }
       
   721             break;
       
   722  
       
   723         case TIAUpdateOperationInfo::ELoadChildren:
       
   724             {
       
   725             // Children of the container should be loaded.
       
   726             IAUPDATE_TRACE("[IAUPDATE] LoadChildrenL requested as operation");
       
   727             TInt childCount( aContainer.ChildCount() );
       
   728             IAUPDATE_TRACE_1("[IAUPDATE] Child count: %d", childCount);
       
   729             operation = 
       
   730                 aContainer.LoadChildrenL( 
       
   731                     0, childCount, ELoadMetadata, *this );
       
   732             }
       
   733             break;
       
   734 
       
   735         case TIAUpdateOperationInfo::ELoadAllChildren:
       
   736             {
       
   737             // All children of the container should be loaded.
       
   738             IAUPDATE_TRACE("[IAUPDATE] LoadAllChildren requested as operation");
       
   739             // Because we can not be sure about the container child count,
       
   740             // use the really big value. Then we will surely get all the
       
   741             // children.            
       
   742             operation = 
       
   743                 aContainer.LoadChildrenL( 
       
   744                     0, KChildCountLoadAll, ELoadMetadata, *this );
       
   745             }
       
   746             break;
       
   747         
       
   748         default:
       
   749             IAUPDATE_TRACE_1("[IAUPDATE] ERROR: Operation type: %d", aOperationType);
       
   750             User::Leave( KErrArgument );
       
   751             break;
       
   752         }
       
   753 
       
   754     // Insert the operation to the cleanupstack. So, it will be released
       
   755     // if leave occurs.
       
   756     CleanupReleasePushL( *operation );
       
   757 
       
   758     // Insert the operation into the array first. By doing this before starting
       
   759     // the operation, we do not need to Cancel just started operation if leave
       
   760     // occurs.
       
   761     TIAUpdateOperationInfo info( aOperationType, operation );
       
   762     iOperations.AppendL( info );
       
   763 
       
   764     TRAPD( trapError, operation->StartOperationL() );
       
   765     if ( trapError != KErrNone )
       
   766         {
       
   767         IAUPDATE_TRACE_1("[IAUPDATE] ERROR: Operation Start failed: %d", trapError);
       
   768         // Operation start failed.
       
   769         // Remove operation from the array because it was appended
       
   770         // above.
       
   771         iOperations.Remove( iOperations.Count() - 1 );
       
   772 
       
   773         // Now, we can leave.
       
   774         // Notice, this leave will pop and destroy the operation. So,
       
   775         // it will be released then.
       
   776         User::Leave( trapError );
       
   777         }
       
   778 
       
   779     // Operation was started.
       
   780     // Do not release it now but remove only from the stack.
       
   781     // Operation will be released when it completes.
       
   782     CleanupStack::Pop( operation );           
       
   783     
       
   784     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::StartLoadOperation() end");
       
   785     }
       
   786 
       
   787 
       
   788 // -----------------------------------------------------------------------------
       
   789 // CIAUpdateLoader::NextLoadLoopL
       
   790 // 
       
   791 // -----------------------------------------------------------------------------
       
   792 //
       
   793 void CIAUpdateLoader::NextLoadLoopL( 
       
   794     MNcdNode& aNode,
       
   795     TIAUpdateOperationInfo::TOperationType aPreviousOperationType )
       
   796     {
       
   797     IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateLoader::NextLoadLoopL() begin: %d",
       
   798                      aPreviousOperationType);
       
   799     
       
   800     MNcdNodeContainer* container( 
       
   801         aNode.QueryInterfaceLC< MNcdNodeContainer >() );
       
   802     if ( !container )
       
   803         {
       
   804         IAUPDATE_TRACE("[IAUPDATE] Container interface was not found");
       
   805         // Container interface should always exist in these cases.
       
   806         User::Leave( KErrNotFound );
       
   807         }
       
   808 
       
   809     // Check if the operation should be continued to its children.
       
   810     switch ( aPreviousOperationType )
       
   811         {
       
   812         case TIAUpdateOperationInfo::ELoadRoot:
       
   813             IAUPDATE_TRACE("[IAUPDATE] Previously loaded root");
       
   814             // When root is loaded, also its children are loaded
       
   815             // and they have now their child count. So, no need to
       
   816             // reload children of the root. Load their children
       
   817             // directly now.
       
   818             LoadChildrenOfChildrenL( 
       
   819                 *container,
       
   820                 TIAUpdateOperationInfo::ELoadRoot );
       
   821             break;
       
   822 
       
   823         case TIAUpdateOperationInfo::ELoadContainer:
       
   824             IAUPDATE_TRACE("[IAUPDATE] Previously loaded container");
       
   825             // After normal container has been loaded, 
       
   826             // its children can be loaded.
       
   827             LoadChildrenL( *container );
       
   828             break;
       
   829 
       
   830         case TIAUpdateOperationInfo::ELoadChildren:
       
   831             IAUPDATE_TRACE("[IAUPDATE] Previously loaded children");
       
   832             // Because children of the container have been loaded here,
       
   833             // maybe we need to start a new loop for their children.
       
   834             // If this container does not contain any new containers,
       
   835             // then there is nothing to do anymore.
       
   836             if ( iSkipChildCountRefresh )
       
   837                 {
       
   838                 // We should come here only after root has been loaded
       
   839                 // and its children of children have been loaded after that.
       
   840                 // After that, skip child count refreshes in the
       
   841                 // next levels.
       
   842                 IAUPDATE_TRACE("[IAUPDATE] Start to load all children");
       
   843                 LoadChildrenOfChildrenL( 
       
   844                     *container,
       
   845                     TIAUpdateOperationInfo::ELoadAllChildren );                
       
   846                 }
       
   847             else
       
   848                 {
       
   849                 IAUPDATE_TRACE("[IAUPDATE] Continue load children of children");
       
   850                 LoadChildrenOfChildrenL( 
       
   851                     *container,
       
   852                     TIAUpdateOperationInfo::ELoadChildren );
       
   853                 }                
       
   854             break;
       
   855 
       
   856         case TIAUpdateOperationInfo::ELoadAllChildren:
       
   857             IAUPDATE_TRACE("[IAUPDATE] Previously loaded all children");
       
   858             // Notice, here we will try to skip the loading of the child
       
   859             // count of the container. So, all the children are tried to
       
   860             // be loaded directly even if the child count may not be
       
   861             // up-to-date.
       
   862             LoadChildrenOfChildrenL( 
       
   863                 *container,
       
   864                 TIAUpdateOperationInfo::ELoadAllChildren );
       
   865             break;
       
   866                          
       
   867         default:
       
   868             IAUPDATE_TRACE("[IAUPDATE] No need for next loop");
       
   869             // No need to load anything else anymore.
       
   870             break;
       
   871         }    
       
   872 
       
   873     // No need for the interface anymore. Release it.
       
   874     CleanupStack::PopAndDestroy( container );
       
   875 
       
   876     IAUPDATE_TRACE("[IAUPDATE] CIAUpdateLoader::NextLoadLoopL() end");
       
   877     }
       
   878