iaupdate/IAD/engine/controller/src/iaupdateservicepacknode.cpp
changeset 0 ba25891c3a9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/iaupdate/IAD/engine/controller/src/iaupdateservicepacknode.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,385 @@
+/*
+* 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:   ?Description
+*
+*/
+
+
+
+#include <ncdnode.h>
+#include <ncdnodeinstall.h>
+
+#include "iaupdateservicepacknode.h"
+#include "iaupdatecontrollerimpl.h"
+#include "iaupdatecontentoperationmanager.h"
+#include "iaupdatenodedetails.h"
+#include "iaupdatenodedependencyimpl.h"
+#include "iaupdatectrlnodeconsts.h"
+#include "iaupdateutils.h"
+
+#include "iaupdatedebug.h"
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::NewLC
+// 
+// ---------------------------------------------------------------------------
+//
+CIAUpdateServicePackNode* CIAUpdateServicePackNode::NewLC( 
+    MNcdNode* aNode,
+    CIAUpdateController& aController )
+    {
+    CIAUpdateServicePackNode* self( 
+        new( ELeave ) CIAUpdateServicePackNode( aController ) );
+    CleanupStack::PushL( self );    
+    self->ConstructL( aNode );
+    return self;
+    }
+  
+    
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::NewL
+// 
+// ---------------------------------------------------------------------------
+//    
+CIAUpdateServicePackNode* CIAUpdateServicePackNode::NewL( 
+    MNcdNode* aNode,
+    CIAUpdateController& aController )
+    {
+    CIAUpdateServicePackNode* self(
+        CIAUpdateServicePackNode::NewLC( aNode, aController ) );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::CIAUpdateServicePackNode
+// 
+// ---------------------------------------------------------------------------
+//
+CIAUpdateServicePackNode::CIAUpdateServicePackNode( 
+    CIAUpdateController& aController ) 
+: CIAUpdateNode( aController )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::ConstructL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateServicePackNode::ConstructL( MNcdNode* aNode )
+    {
+    CIAUpdateNode::ConstructL( aNode );
+    }
+
+    
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::~CIAUpdateServicePackNode
+// 
+// ---------------------------------------------------------------------------
+//
+CIAUpdateServicePackNode::~CIAUpdateServicePackNode()
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::SetInstallStatusToPurchaseHistoryL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateServicePackNode::SetInstallStatusToPurchaseHistoryL( 
+    TInt aErrorCode, TBool aForceVisibleInHistory )
+    {
+    IAUPDATE_TRACE_2("[IAUPDATE] CIAUpdateServicePackNode::SetInstallStatusToPurchaseHistoryL() begin: %d, %d",
+                     aErrorCode, aForceVisibleInHistory);
+
+    // Make sure that error code does not contain any base error value.
+    TInt errorCode( 
+        CIAUpdateContentOperationManager::CheckErrorCode( 
+            aErrorCode ) );
+
+    // Now update the error code with the correct base error value.
+    // This base value will be used later to know that the last operation has been
+    // install operation. This is service pack specific .
+    errorCode += IAUpdateCtrlNodeConsts::KErrBaseServicePackInstall;
+
+    IAUPDATE_TRACE_1("[IAUPDATE] Error code: %d", errorCode);
+
+    SetIdleErrorToPurchaseHistoryL( 
+        errorCode, aForceVisibleInHistory );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateServicePackNode::SetInstallStatusToPurchaseHistoryL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::SetIdleErrorToPurchaseHistoryL
+// 
+// ---------------------------------------------------------------------------
+//
+void CIAUpdateServicePackNode::SetIdleErrorToPurchaseHistoryL( 
+        TInt aError, TBool aForceVisibleInHistory )
+    {
+    IAUPDATE_TRACE_2("[IAUPDATE] CIAUpdateServicePackNode::SetIdleErrorToPurchaseHistoryL() begin: %d, %d",
+                     aError, aForceVisibleInHistory);
+
+    TInt newError( aError );
+
+    TInt decodedError( 
+        CIAUpdateContentOperationManager::CheckErrorCode( aError ) );
+
+    // If aError already contains the base value, then the given value
+    // can be directly saved into the purchase history.
+    if ( newError == decodedError )
+        {
+        // Because error values were same, it means that aError did not contain
+        // any base value. So, check if the base value should be included.
+        
+        // Get the last operation error code from the purchase history.
+        TInt lastErrorCode( 
+            LastUpdateErrorCodeFromPurchaseHistoryL() );
+
+        // Get the decoded value of the error code.
+        // So, it will not contain any base value.
+        TInt decodedHistoryError(
+            CIAUpdateContentOperationManager::CheckErrorCode( 
+                lastErrorCode ) );
+
+        // By subtracting the decoded error from the last purchase history error,
+        // we get the error base value. Then, we can add the newly given error value
+        // to the base value. Also, newly given error value is decoded before using it.
+        newError =
+            lastErrorCode - decodedHistoryError 
+            + decodedError;
+        }
+
+    CIAUpdateNode::SetIdleErrorToPurchaseHistoryL(
+        newError, aForceVisibleInHistory );
+
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateServicePackNode::SetIdleErrorToPurchaseHistoryL() end");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::Type
+// 
+// ---------------------------------------------------------------------------
+//
+MIAUpdateNode::TPackageType CIAUpdateServicePackNode::Type() const
+    {
+    return MIAUpdateNode::EPackageTypeServicePack;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::IsPurchasedL
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateServicePackNode::IsPurchasedL() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateServicePackNode::IsPurchasedL()");
+
+    // Notice, this function should not be called before dependency chains
+    // are created.
+    
+    // Notice, that service pack itself is never purchased but its dependency
+    // items are. Here we trust that the node dependency chains have already
+    // been created. So, we use the dependency nodes to check if this
+    // service pack can be thought as purchased. Also, this function trusts
+    // that while dependency chains were created also loops were removed.
+
+    TBool purchased( ETrue );
+
+    RPointerArray< CIAUpdateNode > dependencies;
+    CleanupClosePushL( dependencies );
+
+    // Accept hidden and visible nodes here.
+    // So, if IAD is shown in the UI but it depends on the hidden
+    // self updater, the self updater is still included inside the
+    // service pack.
+    CIAUpdateContentOperationManager::GetOperationNodesL(
+        *this, dependencies, ETrue, ETrue );
+
+    for ( TInt i = 0; i < dependencies.Count(); ++i )
+        {
+        CIAUpdateNode& node( *dependencies[ i ] );
+        // Notice, that if the dependency node is a service pack itself
+        // then its dependencies are checked like its done in here.
+        // Notice! Here we skip self update nodes because at the moment
+        // IAD Engine does not support self updates inside service packs.
+        // Self update nodes are always shown outside of service pack in 
+        // the UI.
+        // Because we have the whole hierarchy already in dependencies array,
+        // do not call IsPurchased function for other sub service packs.
+        if ( MIAUpdateNode::EPackageTypeServicePack != node.Type() 
+             && !node.IsSelfUpdate()
+             && !node.IsPurchased() )
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Item not downloaded."); 
+            // At least one dependency node was not purchased.
+            // So, think service pack as not purchased also.
+            purchased = EFalse;
+            break;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &dependencies );    
+
+    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateServicePackNode::IsPurchasedL() end: %d",
+                     purchased);
+
+    return purchased;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::IsDownloadedL
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateServicePackNode::IsDownloadedL() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateServicePackNode::IsDownloadedL() begin");
+
+    // Notice, this function should not be called before dependency chains
+    // are created.
+
+    // Notice, that service pack itself is never downloaded but its dependency
+    // items are. Here we trust that the node dependency chains have already
+    // been created. So, we use the dependency nodes to check if this
+    // service pack can be thought as downloaded. Also, this function trusts
+    // that while dependency chains were created also loops were removed.
+
+    TBool downloaded( ETrue );
+
+    RPointerArray< CIAUpdateNode > dependencies;
+    CleanupClosePushL( dependencies );
+
+    // Accept hidden and visible nodes here.
+    // So, if IAD is shown in the UI but it depends on the hidden
+    // self updater, the self updater is still included inside the
+    // service pack.
+    CIAUpdateContentOperationManager::GetOperationNodesL(
+        *this, dependencies, ETrue, ETrue );
+
+    for ( TInt i = 0; i < dependencies.Count(); ++i )
+        {
+        CIAUpdateNode& node( *dependencies[ i ] );
+        // Notice! Here we skip self update nodes because at the moment
+        // IAD Engine does not support self updates inside service packs.
+        // Self update nodes are always shown outside of service pack in 
+        // the UI.
+        // Because we have the whole hierarchy already in dependencies array,
+        // do not call IsDownloaded function for other sub service packs.
+        if ( MIAUpdateNode::EPackageTypeServicePack != node.Type() 
+             && !node.IsSelfUpdate()
+             && !node.IsDownloaded() )
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Item not downloaded."); 
+            // At least one dependency node was not downloaded.
+            // So, think service pack as not downloaded also.
+            downloaded = EFalse;
+            break;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &dependencies );    
+
+    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateServicePackNode::IsDownloadedL() end: %d",
+                     downloaded);
+
+    return downloaded;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CIAUpdateServicePackNode::IsInstalledL
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CIAUpdateServicePackNode::IsInstalledL() const
+    {
+    IAUPDATE_TRACE("[IAUPDATE] CIAUpdateServicePackNode::IsInstalledL() begin");
+
+    // Notice, this function should not be called before dependency chains
+    // are created.
+
+    // Notice, that service pack itself is never installed but its dependency
+    // items are. While operations are done, the state and the error code
+    // will be updated for the service pack in purchase history.
+    // With this implementation if the service pack is successfully installed
+    // and after that some of its items are uninstalled, the service pack will
+    // still be shown in the UI instead of the items.
+    // Notice, that here we suppose that if some dependency node is uninstalled,
+    // then all its dependants are also been uninstalled by the installer. Therefore,
+    // this information will be known also in head service pack, when installation
+    // status is checked. 
+    // Notice, here we trust that while dependency chains were created also loops 
+    // were removed.
+
+    TBool installed( ETrue );
+
+    RPointerArray< CIAUpdateNode > dependencies;
+    CleanupClosePushL( dependencies );
+
+    // Accept hidden and visible nodes here.
+    // So, if IAD is shown in the UI but it depends on the hidden
+    // self updater, the self updater is still included inside the
+    // service pack.
+    CIAUpdateContentOperationManager::GetOperationNodesL(
+        *this, dependencies, ETrue, ETrue );
+
+    for ( TInt i = 0; i < dependencies.Count(); ++i )
+        {
+        CIAUpdateNode& node( *dependencies[ i ] );
+        // Because we have the whole hierarchy already in dependencies array,
+        // do not call IsInstalled function for other sub service packs.
+        if ( MIAUpdateNode::EPackageTypeServicePack != node.Type()
+             && !node.IsSelfUpdate()
+             && !node.IsInstalled() )
+            {
+            IAUPDATE_TRACE("[IAUPDATE] Item not installed."); 
+
+            // If we come here at least one dependency node was not thougth as
+            // installed. So, think service pack as not installed also.
+
+            // Notice! Here we skip self update nodes because at the moment
+            // IAD Engine does not support self updates inside service packs.
+            // Self update nodes are always shown outside of service pack in 
+            // the UI. So, if all the nodes inside service pack are self
+            // updates, think service pack as installed. Then, seemingly empty
+            // service pack itself will be left out of the UI but the
+            // self update items would be anyways shown in the UI and they
+            // are still available.
+            // When service pack has an item that does not require self update,
+            // it is not thought as empty any more.
+            installed = EFalse;
+            break;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &dependencies );
+    
+    IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateServicePackNode::IsInstalledL() end: %d",
+                     installed);
+
+    return installed;
+    }
+
+