iaupdate/IAD/engine/controller/src/iaupdatehistoryitemimpl.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:51:10 +0200
changeset 0 ba25891c3a9e
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 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:    CIAUpdateHistoryItem
*
*/




#include <ncdpurchasedetails.h>
#include <ncdprovider.h>
#include <ncdnode.h>
#include <ncdnodeinstall.h>
#include <ncdnodedownload.h>

#include "iaupdatehistoryitemimpl.h"
#include "iaupdatecontentoperationmanager.h"


CIAUpdateHistoryItem* CIAUpdateHistoryItem::NewL( MNcdPurchaseDetails* aDetails,
                                                  MNcdProvider& aProvider )
    {
    CIAUpdateHistoryItem* self = 
        CIAUpdateHistoryItem::NewLC( aDetails, aProvider );
    CleanupStack::Pop( self );
    return self;
    }


CIAUpdateHistoryItem* CIAUpdateHistoryItem::NewLC( MNcdPurchaseDetails* aDetails,
                                                   MNcdProvider& aProvider )
    {    
    CIAUpdateHistoryItem* self = 
        new( ELeave ) CIAUpdateHistoryItem( aProvider );
    CleanupStack::PushL( self );
    self->ConstructL( aDetails );
    return self;
    }


CIAUpdateHistoryItem::CIAUpdateHistoryItem( MNcdProvider& aProvider )
: CBase(),
  iProvider( aProvider )
    {
    
    }
 
    
void CIAUpdateHistoryItem::ConstructL( MNcdPurchaseDetails* aDetails )
    {
    if ( !aDetails )
        {
        User::Leave( KErrArgument );
        }

    // The details is set here instead of in the constructor, because now
    // the details object ownership can be safely taken. If the ownership would be
    // transferred in constructor, a memory leak could happen if new( ELeave )
    // function leaves.
    iDetails = aDetails;    
    }
 
    
CIAUpdateHistoryItem::~CIAUpdateHistoryItem()
    {
    delete iDetails;
    }


MNcdPurchaseDetails& CIAUpdateHistoryItem::Details() const
    {
    return *iDetails;
    }


MNcdProvider& CIAUpdateHistoryItem::Provider() const
    {
    return iProvider;
    }


const TDesC& CIAUpdateHistoryItem::Name() const
    {
    return Details().ItemName();
    }
    
const TDesC& CIAUpdateHistoryItem::Version() const
    {
    return Details().Version();
    }

TTime CIAUpdateHistoryItem::LastOperationTime() const
    {
    return Details().LastOperationTime();
    }


TInt CIAUpdateHistoryItem::LastOperationErrorCode() const
    {
    // Make sure that error code does not contain possible
    // base error code value.
    return 
        CIAUpdateContentOperationManager::CheckErrorCode( 
            Details().LastOperationErrorCode() );
    }


CIAUpdateHistoryItem::TIAHistoryItemState CIAUpdateHistoryItem::StateL() const
    {
    // Set the preliminary state for the node.
    // Purchase state is the initial state of the purchase details.
    TIAHistoryItemState state( EPurchased );

    // Notice, when node content has been installed, its purchase details state
    // will remain as EStateInstalled even if the content is uninstalled.
    // Also notice, that an error may occur during an operation or an error code 
    // may be set by NCD API user because operations have been cancelled. 
    // Thus, purchase details can not be used here for all the cases because 
    // in some situations the update item content may have been uninstalled 
    // and after that the operation can be cancelled. After that, purhcase details 
    // still give EStateInstalled, but the error code may be set by NCD API user. So, 
    // use purchase details for error code but use the node interfaces to get the 
    // correct state information.
    

    // First check if the node is a service pack because then we need to 
    // handle it differently.
    CIAUpdateContentOperationManager::TContentOperationType operationType(
        CIAUpdateContentOperationManager::ServicePackOperationType( Details() ) );
    if ( operationType != CIAUpdateContentOperationManager::ENoContentOperation )
        {
        // Because we come here, it means that the node is a service pack.
        // Now check what was the latest operation.
        switch ( operationType )
            {
            case CIAUpdateContentOperationManager::EPurchaseOperation:
                state = EPurchased;
                break;

            case CIAUpdateContentOperationManager::EDownloadOperation:
                if ( LastOperationErrorCode() == KErrNone )
                    {
                    // Because error code describe success in operation.
                    state = EDownloaded;                    
                    }
                else
                    {
                    // Error code says that download has not been success.
                    // So, only purchase operation has been fully done.
                    state = EPurchased;
                    }
                break;

            case CIAUpdateContentOperationManager::EInstallOperation:
                if ( LastOperationErrorCode() == KErrNone )
                    {
                    // Because error code describe success in operation.
                    state = EInstalled;                    
                    }
                else
                    {
                    // Error code says that install has not been success.
                    // So, only download operation has been fully done.
                    state = EDownloaded;
                    }
                break;
            
            default:
                User::Leave( KErrNotSupported );
                break;
            }

        return state;
        }


    // Get the node from the provider. The node can be gotten by using the
    // purchase details.
    MNcdNode* node( Provider().NodeL( Details() ) );
    if ( !node )
        {
        // Node should always be found if its purchase details can be found
        // from the purchase history.
        User::Leave( KErrNotFound );
        }
    CleanupReleasePushL( *node );
    
    // First check if the node has already been installed and it is still installed.
    MNcdNodeInstall* install( node->QueryInterfaceLC<MNcdNodeInstall>() );
    if ( install )
        {
        if ( install->IsInstalledL() )
            {
            // Content has already been installed.
            // So, the whole process has been completed.
            // Notice, downloaded files are removed or
            // moved after installation.
            state = EInstalled;                
            }
        CleanupStack::PopAndDestroy( install );
        install = NULL;
        }

    if ( state != EInstalled )
        {
        if ( LastOperationErrorCode() == KErrNone
             && Details().State() == MNcdPurchaseDetails::EStateInstalled )
            {
            // This check is required for the cases where the node has been installed,
            // but it has been uninstalled after that.
            // If error code is KErrNone and purchase details value is EStateInstalled,
            // then the last operation has been an install-operation that was success.
            // Because the content is not in the phone anymore, it must have been 
            // uninstalled. Anyways, the last history information should show
            // installed state.
            state = EInstalled;
            }
        else
            {
            // Node was not installed. So, check if it has been downloaded and it is
            // ready for installing.
            MNcdNodeDownload* download( node->QueryInterfaceLC<MNcdNodeDownload>() );
            if ( download )
                {
                if ( download->IsDownloadedL() )
                    {
                    // Content has not been installed yet, but it has been
                    // downloaded and it is available.
                    state = EDownloaded;
                    }
                CleanupStack::PopAndDestroy( download );
                download = NULL; 
                }            
            }
        }
        
    CleanupStack::PopAndDestroy( node );
    node = NULL;
        
    return state;
    }