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