iaupdate/IAD/engine/controller/src/iaupdatebasenodeimpl.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 21 Jun 2010 15:48:28 +0300
branchRCL_3
changeset 21 5bddc28da627
parent 11 3ba40be8e484
permissions -rw-r--r--
Revision: 201023 Kit: 2010125

/*
* 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 CIAUpdateBaseNode class 
*                member functions.
*
*/



#include <ncdprovider.h>
#include <ncdnode.h>
#include <ncdnodemetadata.h>
#include <ncdnodepurchase.h>
#include <ncdnodecontentinfo.h>
#include <ncdpurchasehistory.h>
#include <ncdutils.h>
#include <catalogsutils.h>

#include "iaupdatebasenodeimpl.h"
#include "iaupdatenodedetails.h"
#include "iaupdatecontrollerimpl.h"
#include "iaupdatecontentoperationmanager.h"
#include "iaupdateutils.h"
#include "iaupdatectrlnodeconsts.h"
#include "iaupdateprotocolconsts.h"
#include "iaupdatedebug.h"





// -----------------------------------------------------------------------------
// CIAUpdateBaseNode::CIAUpdateBaseNode
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CIAUpdateBaseNode::CIAUpdateBaseNode( CIAUpdateController& aController ) 
: CBase(),
  iController( aController )
    {
    }


// -----------------------------------------------------------------------------
// CIAUpdateBaseNode::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CIAUpdateBaseNode::ConstructL( MNcdNode* aNode )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::ConstructL() begin");

    if ( !aNode )
        {
        // Do not accept NULL node.
        User::Leave( KErrArgument );
        }

    // Here we initialize metadata, details and contentinfo.
    // The metadata, its details and content info should remain same even if
    // update related operations are done. So, they can be created here and there
    // is no need to update that information during the lifetime of this node.
    // If the node is updated from the net server, then this whole node should be 
    // recreated. Or, these object should be updated in correct places.

    MNcdNodeMetadata* metaData = aNode->QueryInterfaceLC< MNcdNodeMetadata >();
    if ( metaData )
        {
        // Also update details information from the metadata.
        iMetaNamespace = metaData->Namespace().AllocL();
        iMetaId = metaData->Id().AllocL();
        SetNameL( *metaData );
        iDescription = metaData->Description().AllocL();
        IAUPDATE_TRACE_1("[IAUPDATE] description: %S", iDescription );
        // Notice, that ownership of metadata is not transferred here.
        iDetails = CIAUpdateNodeDetails::NewL( metaData );
        CleanupStack::PopAndDestroy( metaData );
        metaData = NULL;        
        }
    else
        {
        // Just leave, because important information is missing.
        // We should always have metadata when this node is created.
        User::Leave( KErrNotFound );        
        }

    // Get information from content info.
    // These we have to set here because we can not just pass this information
    // as it is given from the engine and we also take the ownership of the final
    // result.    
    MNcdNodeContentInfo* contentInfo = aNode->QueryInterfaceLC< MNcdNodeContentInfo >();
    if ( contentInfo )
        {
        iMime = contentInfo->MimeType().AllocL();
        iVersion.InternalizeL( contentInfo->Version() );

        //Initialize iUid or iIdentifier according to the mime-type
        iUid = KNullUid;

        if ( iMime->Compare( IAUpdateProtocolConsts::KMimeWidget ) == 0 )
            {
            iIdentifier = contentInfo->Identifier().AllocL();
            }
        else
           {
           iUid = contentInfo->Uid();
           iIdentifier = KNullDesC().AllocL();
           }

        // Release content info.
        // So, we can later check if it still exists and then get 
        // new one if it exists.
        CleanupStack::PopAndDestroy( contentInfo );
        contentInfo = NULL;
        }
    else
        {
        // Just leave, because important information is missing like
        // content UID.
        User::Leave( KErrNotFound );
        }

    // Not, that this function can not leave any more it is safe to take the
    // ownership of the node. Now, the user that called this function can safely
    // pop the node from the cleanup stack.
    iNode = aNode;

    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::ConstructL() end");
    }


// -----------------------------------------------------------------------------
// CIAUpdateBaseNode::~CIAUpdateBaseNode
// Destructor
// -----------------------------------------------------------------------------
//    
CIAUpdateBaseNode::~CIAUpdateBaseNode()
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::~CIAUpdateBaseNode() begin");

    if ( iNode )
        {
    	iNode->Release();
        }

    delete iMetaNamespace;    
    delete iMetaId;
    delete iName;    
    delete iDescription;
    delete iMime;
	delete iIdentifier;
    delete iDetails;
    
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::~CIAUpdateBaseNode() end");
    }



// ---------------------------------------------------------------------------
// MIAUpdateNode functions
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::MetaNamespace
// 
// ---------------------------------------------------------------------------
//
const TDesC& CIAUpdateBaseNode::MetaNamespace() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::MetaNamespace() = %S", 
                     iMetaNamespace);
    return *iMetaNamespace;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::MetaId
// 
// ---------------------------------------------------------------------------
//
const TDesC& CIAUpdateBaseNode::MetaId() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::MetaId() = %S", iMetaId);
    return *iMetaId;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Uid
// 
// ---------------------------------------------------------------------------
//
const TUid& CIAUpdateBaseNode::Uid() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::Uid() = %x", iUid);
    return iUid;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Identifier
// 
// ---------------------------------------------------------------------------
//
const TDesC& CIAUpdateBaseNode::Identifier() const
    {
    return *iIdentifier;
    }
    
// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Name
// 
// ---------------------------------------------------------------------------
//
const TDesC &CIAUpdateBaseNode::Name() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::Name() = %S", iName);
    return *iName;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Description
// 
// ---------------------------------------------------------------------------
//
const TDesC& CIAUpdateBaseNode::Description() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::Description() = %S", 
                     iDescription);
    return *iDescription;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::ContentSize
// 
// ---------------------------------------------------------------------------
//
TInt CIAUpdateBaseNode::ContentSizeL() const
    {
    // Notice, here we give the content size through the interface.
    // See OwnContentSizeL for the size that has been gotten from the server.
    // It will be given as a default, if child classes do not implement this.
    return OwnContentSizeL();
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Version
// 
// ---------------------------------------------------------------------------
//
const TIAUpdateVersion& CIAUpdateBaseNode::Version() const
    {
    return iVersion;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Importance
// 
// ---------------------------------------------------------------------------
//    
MIAUpdateBaseNode::TImportance CIAUpdateBaseNode::Importance() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::Importance() = %d", 
                     Details().Importance());
    return Details().Importance();
    }

void CIAUpdateBaseNode::SetImportance( MIAUpdateBaseNode::TImportance aImportance )
    {
    Details().SetImportance( aImportance );
    }
// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::SearchCriteria
// 
// ---------------------------------------------------------------------------
//
const TDesC& CIAUpdateBaseNode::SearchCriteria() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::SearchCriteria() = %S", 
                     &Details().SearchCriteria());
    return Details().SearchCriteria();
    }

// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::RebootAfterInstall
// 
// ---------------------------------------------------------------------------
//
TBool CIAUpdateBaseNode::RebootAfterInstall() const
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::RebootAfterInstall() = %d", 
                         Details().RebootAfterInstall());
    return Details().RebootAfterInstall();
    }

// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Hidden
// 
// ---------------------------------------------------------------------------
//
TBool CIAUpdateBaseNode::Hidden() const
    {
    TBool hidden( EFalse );
    if ( iForcedHidden
         || Details().Importance() == MIAUpdateBaseNode::EHidden )
        {
        hidden = ETrue;
        }
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::Hidden() = %d", hidden);
    return hidden;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::SetSelected
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateBaseNode::SetSelected( TBool aSelected )
    {
    iSelected = aSelected;
    }

    
// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::IsSelected
// 
// ---------------------------------------------------------------------------
//
    
TBool CIAUpdateBaseNode::IsSelected() const
    {
    return iSelected;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::LastUpdateErrorCodeL()
// 
// ---------------------------------------------------------------------------
// 
TInt CIAUpdateBaseNode::LastUpdateErrorCodeL() const
    {
    return CIAUpdateContentOperationManager::CheckErrorCode( 
            LastUpdateErrorCodeFromPurchaseHistoryL() );
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::SetIdleCancelToPurchaseHistoryL
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateBaseNode::SetIdleCancelToPurchaseHistoryL( 
    TBool aForceVisibleInHistory )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::SetIdleCancelToPurchaseHistoryL() begin");

    SetIdleErrorToPurchaseHistoryL( KErrCancel, aForceVisibleInHistory );

    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::SetIdleCancelToPurchaseHistoryL() end");  
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::SetInstallStatusToPurchaseHistoryL
// 
// ---------------------------------------------------------------------------
//    
void CIAUpdateBaseNode::SetInstallStatusToPurchaseHistoryL( 
    TInt aErrorCode, TBool aForceVisibleInHistory )
    {
    IAUPDATE_TRACE_2("[IAUPDATE] CIAUpdateBaseNode::SetInstallStatusToPurchaseHistoryL(): %d, %d",
                     aErrorCode, aForceVisibleInHistory);
    (void)aErrorCode;
    (void)aForceVisibleInHistory;
    // Nothing to do here because install status is automatically set into the
    // purchase history when normal nodes are used. 
    // Child classes may have their own implementation here.
    return;
    }

// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Mime
// 
// ---------------------------------------------------------------------------
// 
const TDesC& CIAUpdateBaseNode::Mime() const
    {
    return *iMime;
    }



// ---------------------------------------------------------------------------
// Public functions
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::SetIdleErrorToPurchaseHistoryL
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateBaseNode::SetIdleErrorToPurchaseHistoryL( 
    TInt aError, TBool aForceVisibleInHistory )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::SetIdleErrorToPurchaseHistoryL() begin");

    // Update the current node information to the purchase history.

    // Create a new purchase detail.
    CNcdPurchaseDetails* details( PurchaseDetailsLC() );

    // Set the current universal time. 
    // So, that item is the newest in the purhcase history list.
    details->SetLastUniversalOperationTime();

    // The operation was cancelled.
    details->SetLastOperationErrorCode( aError );

    // Because item should be forced as visible in history,
    // remove the hidden postfix if necessary.
    if ( aForceVisibleInHistory )
        {
        IAUPDATE_TRACE("[IAUPDATE] Change purchase history MIME to visible");
        TInt postfixIndex(
            iMime->Match( IAUpdateCtrlNodeConsts::KMimeHiddenPostfixPattern() ) );
        if ( postfixIndex != KErrNotFound )
            {
            IAUPDATE_TRACE("[IAUPDATE] Hidden postfix found. Omit it.");
            details->SetAttributeL( 
                MNcdPurchaseDetails::EPurchaseAttributeContentMimeType, 
                    iMime->Left( postfixIndex ) );            
            }
        }

    // Get the purchase history and save the purchase detail information there.
    MNcdPurchaseHistory* history( iController.ProviderL().PurchaseHistoryL() );
    CleanupReleasePushL( *history );
    
    history->SavePurchaseL( *details );
    
    CleanupStack::PopAndDestroy( history );
    
    CleanupStack::PopAndDestroy( details );    

    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::SetIdleErrorToPurchaseHistoryL() end");      
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Equals
// 
// ---------------------------------------------------------------------------
// 
TBool CIAUpdateBaseNode::Equals( const CIAUpdateBaseNode& aNode ) const
    {
    TBool equals = EFalse;
    if ( iMime->Compare( IAUpdateProtocolConsts::KMimeWidget ) == 0 )
        {
        if ( aNode.MetaNamespace() == MetaNamespace()
                && aNode.MetaId() == MetaId()
             || ( aNode.Identifier() == Identifier() 
                && aNode.Version() == Version() ) )
            {
            equals = ETrue;
            }
        }
    else
        {
        if ( aNode.MetaNamespace() == MetaNamespace()
                && aNode.MetaId() == MetaId()
             || ( aNode.Uid() == Uid()
                && aNode.Version() == Version() 
                && aNode.iMime->Match( IAUpdateProtocolConsts::KMimeServicePackPattern()) == KErrNotFound ) ) 
            {
            equals = ETrue;
            }
        }
    return equals;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::ForceHidden
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateBaseNode::ForceHidden( TBool aHidden )
    {
    iForcedHidden = aHidden;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::OwnContentSizeL()
// 
// ---------------------------------------------------------------------------
//     
TInt CIAUpdateBaseNode::OwnContentSizeL() const
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::OwnContentSizeL() begin");

    // Set the default size to zero.
    // We should always have content info and get the correct value 
    // from there. But, if content info is not available, then
    // zero is only thing we can give here.
    TInt retSize( 0 );

    // Get information from content info.
    MNcdNodeContentInfo* contentInfo( 
        iNode->QueryInterfaceL< MNcdNodeContentInfo >() );
    if ( contentInfo )
        {
        IAUPDATE_TRACE("[IAUPDATE] Content info interface found");
        // Content info existed. So, get the size info.
        retSize = contentInfo->Size();
        // Release content info.
        // So, we can later check if it still exists and then get 
        // new one if it exists.
        contentInfo->Release();
        contentInfo = NULL;
        }

    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::OwnContentSizeL() end: %d",
                     retSize);

    return retSize;
    }

 
// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Details
// 
// ---------------------------------------------------------------------------
//
CIAUpdateNodeDetails& CIAUpdateBaseNode::Details() const
    {
    return *iDetails;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Controller
// 
// ---------------------------------------------------------------------------
//
CIAUpdateController& CIAUpdateBaseNode::Controller() const
    {
    return iController;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::Node
// 
// ---------------------------------------------------------------------------
//
MNcdNode& CIAUpdateBaseNode::Node() const
    {
    return *iNode;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::LastUpdateErrorCodeFromPurchaseHistoryL
// 
// ---------------------------------------------------------------------------
//
TInt CIAUpdateBaseNode::LastUpdateErrorCodeFromPurchaseHistoryL() const
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::LastUpdateErrorCodeFromPurchaseHistoryL() begin");
    
    TInt errorCode( KErrNone );
    
    // Get the error code of the last operation.
    // Purchase history provides a good place to get this.

    // Create filter. So, we will get
    // all the purchase history items.
    CNcdPurchaseHistoryFilter* filter =
        CNcdPurchaseHistoryFilter::NewLC();
    filter->SetNamespaceL( MetaNamespace() );
    filter->SetEntityIdL( MetaId() );

    // Add family uid to the filter
    RArray< TUid > uids;
    CleanupClosePushL( uids );
    uids.AppendL( iController.FamilyUid() );
    filter->SetClientUids( uids.Array() );
    CleanupStack::PopAndDestroy( &uids );

    MNcdPurchaseHistory* history( iController.ProviderL().PurchaseHistoryL() );
    CleanupReleasePushL( *history );
    
    // Get the ids. So, we can next get all the corresponding
    // details.
    RArray< TUint > ids = history->PurchaseIdsL( *filter );
    // Temporarily remove history from cleanup stack
    CleanupStack::Pop( history );
    CleanupStack::PopAndDestroy( filter );
    CleanupReleasePushL( *history );
    CleanupClosePushL( ids );
    
    if ( ids.Count() > 0 )
        {
        CNcdPurchaseDetails* details( 
            history->PurchaseDetailsL( ids[ 0 ] , EFalse ) );
        if ( details )
            {
            errorCode = details->LastOperationErrorCode();    
            delete details;
            details = NULL;
            }
        }
    
    CleanupStack::PopAndDestroy( &ids );
    CleanupStack::PopAndDestroy( history );
    
    IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", errorCode );
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::LastUpdateErrorCodeFromPurchaseHistoryL() end");

    return errorCode;    
    }


// ---------------------------------------------------------------------------
// Protected functions
// 
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::PurchaseDetailsLC
// 
// ---------------------------------------------------------------------------
//
CNcdPurchaseDetails* CIAUpdateBaseNode::PurchaseDetailsLC()
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::IdleCancelPurchaseDetailsLC begin");

    // This will contain the correct details object.
    CNcdPurchaseDetails* details( NULL );

    // Create filter. So, we will get
    // all the purchase history items.
    CNcdPurchaseHistoryFilter* filter =
        CNcdPurchaseHistoryFilter::NewLC();
    filter->SetNamespaceL( MetaNamespace() );
    filter->SetEntityIdL( MetaId() );
    
    // Add family uid to the filter
    RArray< TUid > uids;
    CleanupClosePushL( uids );
    uids.AppendL( iController.FamilyUid() );
    filter->SetClientUids( uids.Array() );
    CleanupStack::PopAndDestroy( &uids );

    MNcdPurchaseHistory* history( iController.ProviderL().PurchaseHistoryL() );
    CleanupReleasePushL( *history );
    
    // Get the ids. So, we can next get all the corresponding
    // details.
    RArray< TUint > ids = history->PurchaseIdsL( *filter );
    // Temporarily remove history from cleanup stack
    CleanupStack::Pop( history );
    CleanupStack::PopAndDestroy( filter );
    CleanupReleasePushL( *history );
    CleanupClosePushL( ids );
    
    if ( ids.Count() > 0 )
        {
        // If purchase details exist, then use the most up-to-date one.
        // This may be a previous idle cancel or if the update flow has
        // proceeded for this node, then this is a real purchase detail.
        // In either case, this details will be updated with the cancel
        // error code and new time information.
        details = 
            history->PurchaseDetailsL( ids[ 0 ], EFalse );
        }
    
    CleanupStack::PopAndDestroy( &ids );
    CleanupStack::PopAndDestroy( history );
    
    if ( !details )
        {
        // There was not corresponding purchase details in the history.
        // So, create new.
        details = CNcdPurchaseDetails::NewLC();

        // Set the known details into the newly created object.
        
        // Set identifier information here.
        details->SetNamespaceL( MetaNamespace() );
        details->SetEntityIdL( MetaId() );
        // The client uid means here the family uid.
        details->SetClientUid( iController.FamilyUid() );
            
        // This information we already have available in this class.
        details->SetItemNameL( Name() );
        details->SetDescriptionL( Description() );
        details->SetVersionL( Version().Name() );

        // Notice, let the purchase time be zero because the purchase operation
        // has not been done to the node content yet.
        const TInt KDefaultPurchaseTime( 0 );
        details->SetPurchaseTime( KDefaultPurchaseTime );
        }
    else
        {
        // The details was created but not inserted into
        // the cleanup stack above. Insert it into the cleanupstack now.
        CleanupStack::PushL( details );
        }

    // MIME type checking.
    // Make sure that the purchase history also contains the correct MIME.
    // In certain cases the MIME type depends on the node state or settings
    // and the purchase history may contain old value that has been gotten
    // from the server.
    // By setting it here, we can be sure that if the purchase details is
    // later saved into the history, the correct value will then be used.
    details->SetAttributeL( 
        MNcdPurchaseDetails::EPurchaseAttributeContentMimeType, MimeL() );


    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::IdleCancelPurchaseDetailsLC end");

    return details;
    }


// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::MimeL
// 
// ---------------------------------------------------------------------------
//
const TDesC& CIAUpdateBaseNode::MimeL()
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::MimeL begin");

    TInt postfixIndex(
        iMime->Match( IAUpdateCtrlNodeConsts::KMimeHiddenPostfixPattern() ) );

	IAUPDATE_TRACE_1("[IAUPDATE] postfixIndex: %d", postfixIndex);

    if ( Hidden() )
        {
    	IAUPDATE_TRACE("Set as hidden");

        // Node should be set as hidden.
        if ( postfixIndex == KErrNotFound )
            {
        	IAUPDATE_TRACE("[IAUPDATE] Was not hidden");
            // The node is not already set as hidden.
            // So, set it now.
            // Expand the buffer size, so hidden postfix can be added.
            iMime = 
                iMime->ReAllocL(
                    iMime->Length()
                    + IAUpdateCtrlNodeConsts::KMimeHiddenPostfix().Length() );

            // Append the postfix into the mime variable.
            TPtr ptrMime( iMime->Des() );
            ptrMime.Append( IAUpdateCtrlNodeConsts::KMimeHiddenPostfix() );
            }        
        }
    else
        {
    	IAUPDATE_TRACE("Unset hidden");

        // Node should be set as not a hidden.
        if ( postfixIndex != KErrNotFound )
            {
            IAUPDATE_TRACE("[IAUPDATE] Was hidden");
            // The node was actually hidden.
            // So, set the correct new value now.
            // Notice, that this sets the value into the purchase history and into
            // the member variable.
            HBufC* mime( iMime->Left( postfixIndex ).AllocL() );
            delete iMime;
            iMime = mime;
            }
        }

    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateBaseNode::MimeL end: %S", 
                     iMime);

    return *iMime;
    }

// ---------------------------------------------------------------------------
// CIAUpdateBaseNode::SetNameL
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateBaseNode::SetNameL( const MNcdNodeMetadata& aMetaData )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::SetNameL begin");
    delete iName;
    iName = NULL;
    iName = aMetaData.Name().AllocL();
    IAUPDATE_TRACE_1("[IAUPDATE] name: %S", iName );
    
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateBaseNode::SetNameL end");
    }