diff -r 000000000000 -r ba25891c3a9e iaupdate/IAD/engine/controller/src/iaupdateservicepacknode.cpp --- /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 +#include + +#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; + } + +