iaupdate/IAD/engine/controller/src/iaupdatefwnodeimpl.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 0 ba25891c3a9e
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 CIAUpdateFwNode class 
*                member functions.
*
*/



#include <e32cmn.h>
#include <etelmm.h>
#include <ncdnode.h>
#include <ncdnodecontentinfo.h>
#include <ncdpurchasedownloadinfo.h>
#include <ncdutils.h>

#include "iaupdatefwnodeimpl.h"
#include "iaupdatecontrollerimpl.h"
#include "iaupdatefwpurchaseoperation.h"
#include "iaupdatefwnodeobserver.h"
#include "iaupdatenodedetails.h"
#include "iaupdatedebug.h"


// -----------------------------------------------------------------------------
// CIAUpdateFwNode::NewLC
// Two-phased constructor.
// -----------------------------------------------------------------------------
// 
CIAUpdateFwNode* CIAUpdateFwNode::NewLC( 
    MNcdNode* aNode,
    CIAUpdateController& aController,
    MIAUpdateFwNode::TFwUpdateType aFwType )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::NewLC() begin");

    CIAUpdateFwNode* self = 
        new( ELeave ) CIAUpdateFwNode( aController, aFwType );
    CleanupStack::PushL( self );    
    self->ConstructL( aNode );

    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::NewLC() end");

    return self;
    }

    
// -----------------------------------------------------------------------------
// CIAUpdateFwNode::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//     
CIAUpdateFwNode* CIAUpdateFwNode::NewL( 
    MNcdNode* aNode,
    CIAUpdateController& aController,
    MIAUpdateFwNode::TFwUpdateType aFwType )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::NewL() begin");

    CIAUpdateFwNode* self = 
        CIAUpdateFwNode::NewLC( aNode, aController, aFwType );
    CleanupStack::Pop( self );

    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::NewL() end");

    return self;
    }


// -----------------------------------------------------------------------------
// CIAUpdateFwNode::CIAUpdateFwNode
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CIAUpdateFwNode::CIAUpdateFwNode( CIAUpdateController& aController,
                                  MIAUpdateFwNode::TFwUpdateType aFwType ) 
: CIAUpdateBaseNode( aController ),
  iType( aFwType )
    {
    }


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

    // Let the parent handle it all.
    CIAUpdateBaseNode::ConstructL( aNode );

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


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

    if ( iPurchaseOperation )
        {
        // Because purchase operation exists, set the cancelling flag on. 
        // Then, observer callbacks are not called when the deletion of 
        // the object cancels the operation. 
        // Also, notice that instead of directly using the error code given 
        // to callbacks, we use the local cancel flag. So, we can handle cases 
        // when operation was able to finish and cancellation did not occur even
        // if it was requested. That would most likely never occur, but better to
        // be safe than sorry,.
        iCancelling = ETrue;
        // Notice, that callback function will delete the iPurchaseOperation.
        // So, do not call delete instead of cancel operation here because then
        // delete would be called twice for the same pointer. Instead, just use 
        // the CancelOperation function call.
        iPurchaseOperation->CancelOperation();
        // There should not be any need to call delete after cancel above. 
        // But, insert it here just in case the operation functionality changes. 
        // It does not hurt to call it here now
        // because pointer should always be NULL already.
        delete iPurchaseOperation;    
        }

    delete iContentUrl;
    
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::~CIAUpdateFwNode() end");
    }


// ---------------------------------------------------------------------------
// MIAUpdateFwNode functions
// 
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::FwType
// 
// ---------------------------------------------------------------------------
//    
MIAUpdateFwNode::TFwUpdateType CIAUpdateFwNode::FwType() const
    {
    return iType;
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::FwVersion1
// 
// ---------------------------------------------------------------------------
//    
const TDesC& CIAUpdateFwNode::FwVersion1() const
    {
    return Details().FwVersion1();
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::FwVersion2
// 
// ---------------------------------------------------------------------------
//    
const TDesC& CIAUpdateFwNode::FwVersion2() const
    {
    return Details().FwVersion2();
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::FwVersion3
// 
// ---------------------------------------------------------------------------
//    
const TDesC& CIAUpdateFwNode::FwVersion3() const
    {
    return Details().FwVersion3();
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::InitDownloadDataL
// 
// ---------------------------------------------------------------------------
//    
TBool CIAUpdateFwNode::InitDownloadDataL( MIAUpdateFwNodeObserver& aObserver )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::InitDownloadDataL() begin");
    
    if ( iPurchaseOperation )
        {
        IAUPDATE_TRACE("[IAUPDATE] ERROR: KErrInUse, operation already going on.");
        User::Leave( KErrInUse );
        }

    // Create new purchase operation and start it if purchase is necessary.
    IAUPDATE_TRACE("[IAUPDATE] Create new purchase operation");
    CIAUpdateContentOperation* tmpPurchaseOperation(
        CIAUpdateFwPurchaseOperation::NewLC( *this, *this ) );
    TBool operationStarted(
        tmpPurchaseOperation->StartOperationL() );

    if ( operationStarted )
        {
        IAUPDATE_TRACE("[IAUPDATE] Operation started");

        // Ownership will be transferred below to the member variable.
        // So, do not leve the operation into the stack.
        CleanupStack::Pop( tmpPurchaseOperation );

        // Now, that function can not leave, set the member variable values.
        // These values are required when the asynchronous purcahse operation
        // completes and callback functions are called.
        iPurchaseOperation = tmpPurchaseOperation;
        iObserver = &aObserver;        
        }
    else
        {
        // Because operation was not started,
        // delete the operation object.
        CleanupStack::PopAndDestroy( tmpPurchaseOperation );        
        tmpPurchaseOperation = NULL;
        }

    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateFwNode::InitDownloadDataL() end: %d",
                     operationStarted);

    return operationStarted;
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::ContentUrl
// 
// ---------------------------------------------------------------------------
//    
const TDesC& CIAUpdateFwNode::ContentUrl() const
    {
    if ( !iContentUrl )
        {
        return KNullDesC();
        }

    return *iContentUrl;
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::NodeType
// 
// ---------------------------------------------------------------------------
//
MIAUpdateAnyNode::TNodeType CIAUpdateFwNode::NodeType() const
    {
    return MIAUpdateAnyNode::ENodeTypeFw;
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::Base
// 
// ---------------------------------------------------------------------------
//
MIAUpdateBaseNode& CIAUpdateFwNode::Base()
    {
    return *this;   
    }


// ---------------------------------------------------------------------------
// MIAUpdateContentOperationObserver functions
// 
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::ContentOperationComplete
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateFwNode::ContentOperationComplete( CIAUpdateBaseNode& /*aNode*/, 
                                                TInt aError )
    {
    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateFwNode::ContentOperationComplete() begin: %d",
                     aError);
    
    delete iPurchaseOperation;
    iPurchaseOperation = NULL;

    // Use the temporary variable here for the observer because, in some cases,
    // the observer may delete this object when callback is called and no
    // member variables should be used after that.
    MIAUpdateFwNodeObserver* tmpObserver( iObserver );
    // Do not delete observer because it is not owned here.
    // Just set it to NULL.
    iObserver = NULL;

    if ( !iCancelling )
        {
        IAUPDATE_TRACE("[IAUPDATE] Operation not cancelled.");

        // Because operation was not cancelled, 
        // set the URL if everything went OK.        
        if ( aError == KErrNone )
            {
            // If URL can not be set, then replace KErrNone value of aError
            // with the leave error. So, that value will be given for the observer.
            TRAP( aError, SetContentUrlL() );
            }

        IAUPDATE_TRACE_1("[IAUPDATE] Inform observer: %d", aError);
        tmpObserver->InitDownloadDataComplete( *this, aError );        
        }
        
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::ContentOperationComplete() end");
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::ContentOperationProgress
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateFwNode::ContentOperationProgress( CIAUpdateBaseNode& /*aNode*/, 
                                                TInt /*aProgress*/, 
                                                TInt /*aMaxProgress*/ )
    {
    
    }


// ---------------------------------------------------------------------------
// CIAUpdateFwNode functions
// 
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
// CIAUpdateFwNode::SetContentUrlL
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateFwNode::SetContentUrlL()
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::SetContentUrlL() begin");

    // Before trying to set the new values for content URL,
    // delete old values.
    delete iContentUrl;
    iContentUrl = NULL;

    CNcdPurchaseDetails* details( PurchaseDetailsLC() );

    TArray< MNcdPurchaseDownloadInfo* > downloadInfos( 
        details->DownloadInfoL() );
    if ( downloadInfos.Count() == 0 )
        {
        IAUPDATE_TRACE("[IAUPDATE] ERROR: KErrNotFound, no download info");
        User::Leave( KErrNotFound );
        }
    else
        {
        IAUPDATE_TRACE_1("[IAUPDATE] Download info count: %d", 
                         downloadInfos.Count());
        // Always use the first download info even if there exists
        // multiple of them.
        MNcdPurchaseDownloadInfo* info( downloadInfos[ 0 ] );
        // Get the content uri and insert it to the member variable.
        iContentUrl = info->ContentUri().AllocL();
        IAUPDATE_TRACE_1("[IAUPDATE] Content uri set: %S",
                         iContentUrl); 
        }    

    CleanupStack::PopAndDestroy( details );

    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::SetContentUrlL() end");
    }

// ---------------------------------------------------------------------------
// CIAUpdateFwNode::SetNameL
// 
// ---------------------------------------------------------------------------
//
void CIAUpdateFwNode::SetNameL( const MNcdNodeMetadata& /*aMetaData*/ )
    {
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::SetNameL() begin");
    RTelServer telServer;
    CleanupClosePushL( telServer );
    User::LeaveIfError( telServer.Connect() );
    RTelServer::TPhoneInfo teleinfo;
    User::LeaveIfError( telServer.GetPhoneInfo( 0, teleinfo ) );
    RMobilePhone phone;
    CleanupClosePushL( phone );
    User::LeaveIfError( phone.Open( telServer, teleinfo.iName ) );
    User::LeaveIfError(phone.Initialise()); 
    TUint32 teleidentityCaps;
    phone.GetIdentityCaps( teleidentityCaps );
    RMobilePhone::TMobilePhoneIdentityV1 telid;
    TRequestStatus status;
    phone.GetPhoneId( status, telid );
    User::WaitForRequest( status );
    delete iName;
    iName = NULL;
    if ( status==KErrNone )
        {
        iName = telid.iModel.AllocL(); 
        }
    else
        {
        iName = KNullDesC().AllocL();
        }
    CleanupStack::PopAndDestroy( &phone );
    CleanupStack::PopAndDestroy( &telServer );
     
    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateFwNode::SetNameL() end");
    }