--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iaupdate/IAD/engine/controller/src/iaupdatenodeimpl.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,974 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This module contains the implementation of CIAUpdateNode class
+* member functions.
+*
+*/
+
+#include <ncdnode.h>
+#include <ncdnodepurchase.h>
+#include <ncdnodedownload.h>
+#include <ncdnodeinstall.h>
+
+#include "iaupdatenodeimpl.h"
+#include "iaupdatenodeobserver.h"
+#include "iaupdatenodedependencyimpl.h"
+#include "iaupdatenodedetails.h"
+#include "iaupdatecontrollerimpl.h"
+#include "iaupdateutils.h"
+#include "iaupdatecontentoperationmanager.h"
+#include "iaupdatedebug.h"
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateNode::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CIAUpdateNode* CIAUpdateNode::NewLC( MNcdNode* aNode,
+ CIAUpdateController& aController )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewLC() begin");
+
+ CIAUpdateNode* self =
+ new( ELeave ) CIAUpdateNode( aController );
+ CleanupStack::PushL( self );
+ self->ConstructL( aNode );
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewLC() end");
+
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateNode::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CIAUpdateNode* CIAUpdateNode::NewL( MNcdNode* aNode,
+ CIAUpdateController& aController )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewL() begin");
+ CIAUpdateNode* self =
+ CIAUpdateNode::NewLC( aNode, aController );
+ CleanupStack::Pop( self );
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::NewL() end");
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateNode::CIAUpdateNode
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CIAUpdateNode::CIAUpdateNode( CIAUpdateController& aController )
+: CIAUpdateBaseNode( aController )
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateNode::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CIAUpdateNode::ConstructL( MNcdNode* aNode )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ConstructL() begin");
+
+ // Let the parent handle it all.
+ CIAUpdateBaseNode::ConstructL( aNode );
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ConstructL() end");
+ }
+
+
+// -----------------------------------------------------------------------------
+// CIAUpdateNode::~CIAUpdateNode
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CIAUpdateNode::~CIAUpdateNode()
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::~CIAUpdateNode() begin");
+
+ iDependants.Reset();
+ iExcessDependencyNodes.Reset();
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::~CIAUpdateNode() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateBaseNode overloaded functions
+//
+// ---------------------------------------------------------------------------
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::ContentSizeL
+//
+// ---------------------------------------------------------------------------
+//
+TInt CIAUpdateNode::ContentSizeL() const
+ {
+ // Notice, here we give the total content size through the interface.
+ // Here we want only the dependency nodes that are hidden.
+ // Skip visible dependencies because those nodes are visible in UI
+ // and their content size is separately shown and calculated in UI.
+ return
+ Controller().
+ ContentOperationManager().
+ TotalContentSizeL( *this, ETrue, EFalse, ETrue, EFalse );
+ }
+
+
+// ---------------------------------------------------------------------------
+// MIAUpdateNode functions
+//
+// ---------------------------------------------------------------------------
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::Type
+//
+// ---------------------------------------------------------------------------
+//
+MIAUpdateNode::TPackageType CIAUpdateNode::Type() const
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::Type() = %d",
+ Details().ContentType());
+ return Details().ContentType();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::IsSelfUpdate
+//
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateNode::IsSelfUpdate() const
+ {
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::GetDependenciesL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::GetDependenciesL(
+ RPointerArray< MIAUpdateNode >& aDependencies,
+ TBool aIncludeHidden ) const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependenciesL() begin");
+
+ RPointerArray< CIAUpdateNode > dependencies;
+ CleanupClosePushL( dependencies );
+
+ GetDependencyNodesL( dependencies, aIncludeHidden );
+
+ aDependencies.ReserveL( dependencies.Count() );
+ for ( TInt i = 0; i < dependencies.Count(); ++i )
+ {
+ aDependencies.AppendL( dependencies[ i ] );
+ }
+
+ CleanupStack::PopAndDestroy( &dependencies );
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependenciesL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::GetDependantsL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::GetDependantsL(
+ RPointerArray< MIAUpdateNode >& aDependants,
+ TBool aIncludeHidden ) const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependantsL() begin");
+
+ aDependants.Reserve( iDependants.Count() );
+ for( TInt i = 0; i < iDependants.Count(); ++i )
+ {
+ CIAUpdateNode* dependant( iDependants[ i ] );
+ if ( aIncludeHidden
+ || !dependant->Hidden() )
+ {
+ aDependants.AppendL( iDependants[ i ] );
+ }
+ }
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependantsL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::IsDownloaded
+//
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateNode::IsDownloaded() const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsDownloaded() begin");
+
+ TBool downloaded( EFalse );
+ TRAP_IGNORE ( downloaded = IsDownloadedL() );
+
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsDownloaded() end: %d",
+ downloaded);
+
+ return downloaded;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::IsInstalled
+//
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateNode::IsInstalled() const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalled() begin");
+
+ TBool installed( EFalse );
+ TRAP_IGNORE ( installed = IsInstalledL() );
+
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsInstalled() end: %d",
+ installed);
+
+ return installed;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::DownloadL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::DownloadL( MIAUpdateNodeObserver& aObserver )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::DownloadL() begin");
+
+ if( iOperationObserver )
+ {
+ User::Leave( KErrInUse );
+ }
+
+ // Instead of starting download operation here, we start purchase operation.
+ // Purchase needs to be done before download. When purchase compeletes,
+ // the call back function is called and that will start download operation.
+ // Notice, that we can try to create the purchase even if it has already been
+ // done. Then, the operation just finishes without repurchasing.
+
+ // Use content operation manager.
+ // It can handle the possible hidden node chain that requires operations
+ // for multiple nodes.
+ Controller().
+ ContentOperationManager().
+ StartL( *this,
+ CIAUpdateContentOperationManager::EPurchaseOperation,
+ *this );
+
+ iOperationObserver = &aObserver;
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::DownloadL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::InstallL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::InstallL( MIAUpdateNodeObserver& aObserver )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::InstallL() begin");
+
+ if( iOperationObserver )
+ {
+ User::Leave( KErrInUse );
+ }
+
+ // Use content operation manager.
+ // It can handle the possible hidden node chain that requires operations
+ // for multiple nodes.
+ Controller().
+ ContentOperationManager().
+ StartL( *this,
+ CIAUpdateContentOperationManager::EInstallOperation,
+ *this );
+
+ iOperationObserver = &aObserver;
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::InstallL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::CancelOperation()
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::CancelOperation()
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::CancelOperation() begin");
+
+ // This will cancel the possible ongoing operation
+ Controller().ContentOperationManager().Cancel();
+
+ // Also, set the observer to NULL.
+ // Because this value is used to check if operations are going on.
+ iOperationObserver = NULL;
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::CancelOperation() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::Depth()
+//
+// ---------------------------------------------------------------------------
+//
+TInt CIAUpdateNode::Depth() const
+ {
+ return iDepth;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::NodeType
+//
+// ---------------------------------------------------------------------------
+//
+MIAUpdateAnyNode::TNodeType CIAUpdateNode::NodeType() const
+ {
+ return MIAUpdateAnyNode::ENodeTypeNormal;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::Base
+//
+// ---------------------------------------------------------------------------
+//
+MIAUpdateBaseNode& CIAUpdateNode::Base()
+ {
+ return *this;
+ }
+
+
+// ---------------------------------------------------------------------------
+// MIAUpdateContentOperationObserver functions
+//
+// ---------------------------------------------------------------------------
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::ContentOperationCompleteL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::ContentOperationComplete( CIAUpdateBaseNode& /*aNode*/,
+ TInt aError )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationComplete() begin");
+
+ // Get the observer to a temporary pointer. So, we can use it
+ // when informing observers. The member variable needs to be set to NULL
+ // before callbacks are called.
+ MIAUpdateNodeObserver* tmpObserver( iOperationObserver );
+
+ const CIAUpdateContentOperationManager::TContentOperationType& operationType(
+ Controller().ContentOperationManager().OperationType() );
+
+ if ( operationType == CIAUpdateContentOperationManager::EPurchaseOperation )
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] Purchase operation complete: %d", aError);
+ if ( aError == KErrNone )
+ {
+ // Purchase operation was successfull.
+ // So, now try to download the actual content.
+ TRAPD ( trapError,
+ Controller().
+ ContentOperationManager().
+ StartL( *this,
+ CIAUpdateContentOperationManager::EDownloadOperation,
+ *this ); );
+ IAUPDATE_TRACE_1("[IAUPDATE] download trap error code: %d", trapError );
+ if ( trapError != KErrNone )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Could not create download operation.");
+ // Something went wrong when initializing download operation.
+ iOperationObserver = NULL;
+ // Inform observer about the completion of operation.
+ tmpObserver->DownloadComplete( *this, trapError );
+ }
+ }
+ else
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Purchase was not success. Complete download.");
+ // Operation was not successfull.
+ // There is no reason to continue.
+ // Inform observer about the completion of operation.
+ iOperationObserver = NULL;
+ tmpObserver->DownloadComplete( *this, aError );
+ }
+ }
+ else if ( operationType == CIAUpdateContentOperationManager::EDownloadOperation )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Download operation complete");
+ iOperationObserver = NULL;
+ // Inform observer about the completion of operation.
+ tmpObserver->DownloadComplete( *this, aError );
+ }
+ else if ( operationType == CIAUpdateContentOperationManager::EInstallOperation )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Install operation complete");
+ iOperationObserver = NULL;
+ // Inform observers about the completion of operation.
+ tmpObserver->InstallComplete( *this, aError );
+ }
+ else
+ {
+ // We should never come here.
+ IAUPDATE_TRACE("[IAUPDATE] ERROR No operation was going on even if callback called");
+ iOperationObserver = NULL;
+ }
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationComplete() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::ContentOperationProgress
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::ContentOperationProgress( CIAUpdateBaseNode& /*aNode*/,
+ TInt aProgress,
+ TInt aMaxProgress )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationProgress() begin");
+
+ // Inform the observer about the progress of download and install.
+ // There is no need to inform about the purchase progress.
+ switch( Controller().ContentOperationManager().OperationType() )
+ {
+ case CIAUpdateContentOperationManager::EDownloadOperation:
+ IAUPDATE_TRACE("[IAUPDATE] Download operation progress");
+ iOperationObserver->
+ DownloadProgress( *this, aProgress, aMaxProgress );
+ break;
+
+ case CIAUpdateContentOperationManager::EInstallOperation:
+ IAUPDATE_TRACE("[IAUPDATE] Install operation progress");
+ iOperationObserver->
+ InstallProgress( *this, aProgress, aMaxProgress );
+ break;
+
+ default:
+ IAUPDATE_TRACE_1("[IAUPDATE] Do not inform observer: %d",
+ Controller().
+ ContentOperationManager().
+ OperationType());
+ break;
+ }
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::ContentOperationProgress() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// Public functions
+//
+// ---------------------------------------------------------------------------
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::Reset
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::Reset()
+ {
+ SetDependencyCheckStatus(
+ CIAUpdateNode::EDependencyCheckNotSet );
+ SetDepth( 0 );
+ SetLeafDistance( 0 );
+ iDependants.Reset();
+ iExcessDependencyNodes.Reset();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::IsPurchased
+//
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateNode::IsPurchased() const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsPurchased() begin");
+
+ TBool purchased( EFalse );
+ TRAP_IGNORE( purchased = IsPurchasedL() );
+
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsPurchased() end: %d", purchased);
+
+ return purchased;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::SetExcessDependencyL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::SetExcessDependencyL(
+ CIAUpdateNode& aDependencyNode,
+ TBool aAddDependency )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::SetExcessDependencyL() begin");
+
+ // First check if the dependency has already been set in details.
+ RPointerArray< CIAUpdateNodeDependency > dependencies;
+ CleanupClosePushL( dependencies );
+ Details().GetDependenciesL( dependencies );
+ for ( TInt i = 0; i < dependencies.Count(); ++i )
+ {
+ CIAUpdateNodeDependency* dependency( dependencies[ i ] );
+ if ( dependency->Uid() == aDependencyNode.Uid() )
+ {
+ // Dependency has already been set.
+ CleanupStack::PopAndDestroy( &dependencies );
+ return;
+ }
+ }
+ CleanupStack::PopAndDestroy( &dependencies );
+
+ // Check if the node already exists in excess array.
+ for ( TInt i = 0; i < iExcessDependencyNodes.Count(); ++i )
+ {
+ CIAUpdateNode* node( iExcessDependencyNodes[ i ] );
+ if ( node->Uid() == aDependencyNode.Uid() )
+ {
+ // Dependency has already been set.
+ return;
+ }
+ }
+
+ // Depth update and loop check.
+ RPointerArray< CIAUpdateNode > dependencyNodes;
+ CleanupClosePushL( dependencyNodes );
+ // Get dependency hierarchy.
+ // Accept all kind of nodes.
+ Controller().
+ ContentOperationManager().
+ GetOperationNodesL( aDependencyNode,
+ dependencyNodes,
+ ETrue, ETrue );
+ TInt findError(
+ dependencyNodes.Find( this ) );
+ CleanupStack::PopAndDestroy( &dependencyNodes );
+
+ // If the given dependency node depends on this node,
+ // then new dependency would create a loop. So, only
+ // accept node if loop will not occur.
+ if ( findError == KErrNotFound )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Check passed");
+
+ // Update the leaf distances of the this dependant node
+ // and its dependant hierarchy if necessary. Dependant leaf
+ // distance is always at least one greater than its dependency
+ // leaf distance.
+ UpdateDependantLeafDistancesL(
+ aDependencyNode.LeafDistance() + 1 );
+
+ // Update the depth of the dependency hierarchy
+ // if necessary. Dependency depth is always at least one
+ // greater than depth of its dependant.
+ aDependencyNode.
+ UpdateDependencyDepthsL( Depth() + 1 );
+
+ if ( aAddDependency )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Add dependency");
+ // Insert the given dependant node into the array.
+ // The given node is thought as the best match for the dependency.
+ // Also, this function supposes that the dependency chain below the dependency
+ // node is intact.
+ iExcessDependencyNodes.AppendL( &aDependencyNode );
+ // Also, because new dependency is inserted, make sure that
+ // the dependency node dependant info is set correctly.
+ aDependencyNode.AddDependantL( *this );
+ }
+ }
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::SetExcessDependencyL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::GetDependencyNodesL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::GetDependencyNodesL(
+ RPointerArray< CIAUpdateNode >& aDependencies,
+ TBool aIncludeHidden ) const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependencyNodesL() begin");
+
+ RPointerArray< CIAUpdateNodeDependency > dependencies;
+ CleanupClosePushL( dependencies );
+
+ // First get the dependencies from the details object.
+ // These are dependencies given by the server itself.
+ Details().GetDependenciesL( dependencies );
+
+ aDependencies.ReserveL(
+ dependencies.Count() + iExcessDependencyNodes.Count() );
+
+ // Insert node that corresponds the details to the array.
+ for ( TInt i = 0; i < dependencies.Count(); ++i )
+ {
+ CIAUpdateNodeDependency* dependency( dependencies[ i ] );
+ CIAUpdateNode* node( dependency->BestMatch() );
+ if ( node && ( aIncludeHidden || !node->Hidden() ) )
+ {
+ aDependencies.AppendL( node );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &dependencies );
+
+ // Insert excess dependencies to the array.
+ for ( TInt i = 0; i < iExcessDependencyNodes.Count(); ++i )
+ {
+ CIAUpdateNode* node( iExcessDependencyNodes[ i ] );
+ if ( aIncludeHidden || !node->Hidden() )
+ {
+ aDependencies.AppendL( node );
+ }
+ }
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::GetDependencyNodesL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::SetDependencyCheckStatus
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::SetDependencyCheckStatus(
+ CIAUpdateNode::TDependencyCheckStatus aStatus )
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::SetDependencyCheckStatus() = %d",
+ aStatus );
+ iDependencyCheckStatus = aStatus;
+ }
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::DependencyCheckStatus()
+//
+// ---------------------------------------------------------------------------
+//
+CIAUpdateNode::TDependencyCheckStatus CIAUpdateNode::DependencyCheckStatus() const
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::DependencyCheckStatus() = %d",
+ iDependencyCheckStatus );
+ return iDependencyCheckStatus;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::LeafDistance
+//
+// ---------------------------------------------------------------------------
+//
+TInt CIAUpdateNode::LeafDistance() const
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::LeafDistance() = %d",
+ iLeafDistance );
+ return iLeafDistance;
+ }
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::SetLeafDistance
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::SetLeafDistance( TInt aDistance )
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::SetLeafDistance() = %d",
+ aDistance );
+ iLeafDistance = aDistance;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::SetDepth
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::SetDepth( TInt aDepth )
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::SetDepth() = %d",
+ aDepth );
+ iDepth = aDepth;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::DependantNodes
+//
+// ---------------------------------------------------------------------------
+//
+const RPointerArray< CIAUpdateNode >& CIAUpdateNode::DependantNodes() const
+ {
+ return iDependants;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::AddDependantL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::AddDependantL( CIAUpdateNode& aDependantNode )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::AddDependantL() begin");
+
+ for ( TInt i = 0; i < iDependants.Count(); ++i )
+ {
+ CIAUpdateNode* node( iDependants[ i ] );
+ if ( node->Uid() == aDependantNode.Uid() )
+ {
+ // Corresponding node is already in the array.
+ return;
+ }
+ }
+
+ iDependants.AppendL( &aDependantNode );
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::AddDependantL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::UpdateDependencyDepthsL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::UpdateDependencyDepthsL( TInt aDepth )
+ {
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::UpdateDependencyDepthsL() begin: %d",
+ aDepth);
+
+ // Notice, that by comparing depths here, we also make sure
+ // that the depth is increased correctly if we come to same
+ // dependency node via multiple branches. Multiple dependants
+ // can depend on the same node.
+
+ // If dependant depth had increased, then depenencies should
+ // also increase their depth. Also, update if negative value is given.
+ // Then, think this node as root.
+ if ( aDepth > Depth() )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Update dependency depth");
+
+ SetDepth( aDepth );
+
+ RPointerArray< CIAUpdateNode > dependencies;
+ CleanupClosePushL( dependencies );
+
+ // Also, accept hidden nodes here.
+ GetDependencyNodesL( dependencies, ETrue );
+
+ // Recursively loop all the dependencies of the node
+ for ( TInt i = 0; i < dependencies.Count(); ++i )
+ {
+ dependencies[ i ]
+ ->UpdateDependencyDepthsL(
+ Depth() + 1 );
+ }
+
+ CleanupStack::PopAndDestroy( &dependencies );
+ }
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::UpdateDependencyDepthsL() end");
+ }
+
+
+// ---------------------------------------------------------------------------
+// Protected functions
+//
+// ---------------------------------------------------------------------------
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::IsPurchasedL
+//
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateNode::IsPurchasedL() const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsPurchasedL() begin");
+
+ TBool purchased( EFalse );
+
+ MNcdNodePurchase* purchase(
+ Node().QueryInterfaceLC< MNcdNodePurchase >() );
+
+ if ( purchase )
+ {
+ if( purchase->IsPurchased() )
+ {
+ purchased = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy( purchase );
+ }
+
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsPurchasedL() end: %d",
+ purchased);
+
+ return purchased;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::IsDownloadedL
+//
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateNode::IsDownloadedL() const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsDownloadedL() begin");
+
+ TBool downloaded( EFalse );
+
+ MNcdNodeDownload* download(
+ Node().QueryInterfaceLC< MNcdNodeDownload >() );
+
+ if ( download )
+ {
+ if( download->IsDownloadedL() )
+ {
+ downloaded = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy( download );
+ }
+
+ IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateNode::IsDownloadedL() end: %d",
+ downloaded);
+
+ return downloaded;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::IsInstalledL
+//
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateNode::IsInstalledL() const
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalledL() begin");
+
+ TIAUpdateVersion installedVersion;
+ TBool installed( IAUpdateUtils::IsAppInstalledL( Uid(), installedVersion ) );
+ IAUPDATE_TRACE_3("CIAUpdateNode::IsInstalledL() Installed version %d.%d.%d",
+ installedVersion.iMajor,
+ installedVersion.iMinor,
+ installedVersion.iBuild );
+ IAUPDATE_TRACE_3("CIAUpdateNode::IsInstalledL() Metadata version %d.%d.%d",
+ Version().iMajor,
+ Version().iMinor,
+ Version().iBuild );
+ if ( installed && installedVersion >= Version() )
+ {
+ // If the installed version is same or newer, then think the node as
+ // installed.
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalledL() end ETrue");
+ return ETrue;
+ }
+ else
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::IsInstalledL() end EFalse");
+ return EFalse;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::OperationObserverL
+//
+// ---------------------------------------------------------------------------
+//
+MIAUpdateNodeObserver* CIAUpdateNode::OperationObserver() const
+ {
+ return iOperationObserver;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Private functions
+//
+// ---------------------------------------------------------------------------
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateNode::UpdateDependantLeafDistancesL
+//
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateNode::UpdateDependantLeafDistancesL( TInt aLeafDistance )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::UpdateDependantLeafDistancesL() begin");
+
+ // Notice, that by comparing depths here, we also make sure
+ // that the leaf distance is increased correctly if we come to same
+ // dependant node via multiple branches. Multiple dependants
+ // can depend on the same node.
+
+ // Dependant leaf distance should be at least one greater than
+ // dependency depth.
+ if ( aLeafDistance > LeafDistance() )
+ {
+ IAUPDATE_TRACE("[IAUPDATE] Update dependant distance");
+
+ SetLeafDistance( aLeafDistance );
+
+ // Recursively loop all the dependants of the node
+ for ( TInt i = 0; i < DependantNodes().Count(); ++i )
+ {
+ DependantNodes()[ i ]
+ ->UpdateDependantLeafDistancesL(
+ LeafDistance() + 1 );
+ }
+ }
+
+ IAUPDATE_TRACE("[IAUPDATE] CIAUpdateNode::UpdateDependantLeafDistancesL() end");
+ }