--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iaupdate/IAD/engine/controller/src/iaupdatehistoryimpl.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,347 @@
+/*
+* 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: CIAUpdateHistory
+*
+*/
+
+
+
+// NCD headers:
+#include <ncdprovider.h>
+#include <ncdnode.h>
+#include <ncdnodecontentinfo.h>
+// Purchase history contains items
+#include <ncdpurchasehistory.h>
+// Contains CBase-class headers of the ncd purchase classes.
+#include <ncdutils.h>
+
+
+#include "iaupdatehistoryimpl.h"
+#include "iaupdatehistoryitemimpl.h"
+#include "iaupdatenodefactory.h"
+
+
+
+CIAUpdateHistory* CIAUpdateHistory::NewL( const TUid& aFamilyUid,
+ MNcdProvider& aProvider )
+ {
+ CIAUpdateHistory* self =
+ CIAUpdateHistory::NewLC( aFamilyUid, aProvider );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+CIAUpdateHistory* CIAUpdateHistory::NewLC( const TUid& aFamilyUid,
+ MNcdProvider& aProvider )
+ {
+ CIAUpdateHistory* self =
+ new( ELeave ) CIAUpdateHistory( aFamilyUid, aProvider );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+CIAUpdateHistory::CIAUpdateHistory( const TUid& aFamilyUid,
+ MNcdProvider& aProvider )
+: CBase(),
+ iFamilyUid( aFamilyUid ),
+ iProvider( aProvider )
+ {
+
+ }
+
+void CIAUpdateHistory::ConstructL()
+ {
+ // Get the purchase history from the provider.
+ // Leave if it can not be gotten.
+ iHistory = Provider().PurchaseHistoryL();
+
+ // The items from the NCD Engine purchase history
+ // are not fetched here.
+ // Instead the user of this class has to call RefreshL to
+ // get and to update the list.
+ }
+
+
+CIAUpdateHistory::~CIAUpdateHistory()
+ {
+ iItems.ResetAndDestroy();
+ History().Release();
+ }
+
+
+const RPointerArray< MIAUpdateHistoryItem >& CIAUpdateHistory::Items() const
+ {
+ return iItems;
+ }
+
+
+void CIAUpdateHistory::RefreshL()
+ {
+ iItems.ResetAndDestroy();
+
+ // Create filter. So, we will get
+ // all the purchase history items.
+ CNcdPurchaseHistoryFilter* filter =
+ CNcdPurchaseHistoryFilter::NewLC();
+
+ // Add family uid to the filter
+ RArray< TUid > uids;
+ CleanupClosePushL( uids );
+ uids.AppendL( FamilyUid() );
+ filter->SetClientUids( uids.Array() );
+ CleanupStack::PopAndDestroy( &uids );
+
+ // Get the ids. So, we can next get all the corresponding
+ // details.
+ RArray< TUint > ids =
+ History().PurchaseIdsL( *filter );
+ CleanupStack::PopAndDestroy( filter );
+ CleanupClosePushL( ids );
+
+ // Get all the details and add corresponding history items
+ // into the array.
+ // Notice, that pruneSelfUpdates is not required anymore for
+ // the current version of IAD but it is here just in case
+ // purchase history contains old information and this kind
+ // of checking is needed for them. pruneSelfUpdates flag
+ // informs if other self update items in the list should
+ // be skipped because IAD has already been inserted in the
+ // list.
+ TBool pruneSelfUpdates( EFalse );
+ for ( TInt i = 0; i < ids.Count(); ++i )
+ {
+ // We do not want to load icons. So, use EFalse.
+ // Ownership is transferred here.
+ CNcdPurchaseDetails* details(
+ History().PurchaseDetailsL( ids[ i ], EFalse ) );
+
+
+ // Purchase history detail contains the UID information.
+ // So, use it here.
+ TUid itemUid(
+ TUid::Uid(
+ details->AttributeInt32(
+ MNcdPurchaseDetails::EPurchaseAttributeContentUid ) ) );
+
+ if ( IAUpdateNodeFactory::IsSelfUpdate( itemUid )
+ || IAUpdateNodeFactory::IsUpdater( itemUid )
+ || AcceptItem( *details ) )
+ {
+ if ( !pruneSelfUpdates )
+ {
+ // If pruning is not on, then all the items are accepted.
+ // This takes the ownership of details.
+ InsertItemL( details );
+
+ if ( IAUpdateNodeFactory::IsIad( itemUid ) )
+ {
+ // IAD was found, but because pruning was not on yet,
+ // set it on.
+ pruneSelfUpdates = ETrue;
+ }
+ }
+ else if ( !IAUpdateNodeFactory::IsSelfUpdate( itemUid )
+ && !IAUpdateNodeFactory::IsUpdater( itemUid ) )
+ {
+ // If pruning is on, then accept only items that are not
+ // self update related. This takes the ownership of details.
+ InsertItemL( details );
+ }
+ else
+ {
+ // Item was not inserted to the array. So, delete it.
+ delete details;
+ details = NULL;
+ }
+ }
+ else
+ {
+ // Item was not accepted into the history.
+ // So, just skip it.
+ delete details;
+ details = NULL;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &ids );
+ }
+
+
+MNcdProvider& CIAUpdateHistory::Provider()
+ {
+ return iProvider;
+ }
+
+
+MNcdPurchaseHistory& CIAUpdateHistory::History()
+ {
+ return *iHistory;
+ }
+
+
+const TUid& CIAUpdateHistory::FamilyUid() const
+ {
+ return iFamilyUid;
+ }
+
+
+void CIAUpdateHistory::InsertItemL( MNcdPurchaseDetails* aDetails )
+ {
+ if ( !aDetails )
+ {
+ // Nothing to do with NULL object.
+ return;
+ }
+
+ CleanupStack::PushL( aDetails );
+ CIAUpdateHistoryItem* item(
+ CIAUpdateHistoryItem::NewL( aDetails, Provider() ) );
+ CleanupStack::Pop( aDetails );
+ CleanupStack::PushL( item );
+
+ if ( iItems.Count() == 0 )
+ {
+ // Array is empty.
+ // So, just append new item.
+ iItems.AppendL( item );
+ CleanupStack::Pop( item );
+ return;
+ }
+
+ // Check if there exists an older version of the item
+ // in the array.
+ for ( TInt i = 0; i < iItems.Count(); ++i )
+ {
+ // Casting here is safe thing to do because this function
+ // is the only one that creates the array items and the items
+ // are created as CIAUpdateHistoryItem objects.
+ CIAUpdateHistoryItem* arrayItem(
+ static_cast< CIAUpdateHistoryItem* >( iItems[ i ] ) );
+
+ // Get the purchase detail object from the arrayItem.
+ // So, we can check the detail identifications.
+ const MNcdPurchaseDetails& arrayItemDetails( arrayItem->Details() );
+
+ if ( aDetails->EntityId() == arrayItemDetails.EntityId()
+ && aDetails->Namespace() == arrayItemDetails.Namespace()
+ && aDetails->ClientUid() == arrayItemDetails.ClientUid() )
+ {
+ // We have two same items. So, compare their operation times.
+ if ( aDetails->LastOperationTime()
+ > arrayItemDetails.LastOperationTime() )
+ {
+ // The array item was older for the same purhcase detail.
+ // So, remove the old version.
+ delete iItems[ i ];
+ iItems[ i ] = NULL;
+ iItems.Remove( i );
+
+ // Continue to the phase were the current item will be
+ // inserted to the correct place in the array.
+ break;
+ }
+ else
+ {
+ // Let the array item be in the array because its newer.
+ // Just delete the unnecessary new one.
+ CleanupStack::PopAndDestroy( item );
+
+ // Nothing to do here anymore.
+ return;
+ }
+ }
+ }
+
+ // Insert the item into a correct place in the array.
+ for ( TInt i = 0; i < iItems.Count(); ++i )
+ {
+ MIAUpdateHistoryItem* arrayItem( iItems[ i ] );
+
+ TTime itemTime( item->LastOperationTime() );
+ TDateTime itemDateTime( itemTime.DateTime() );
+ TTime arrayItemTime( arrayItem->LastOperationTime() );
+ TDateTime arrayItemDateTime( arrayItemTime.DateTime() );
+
+ // The right place to insert the item is
+ // 1.1. Item in the array is from previous day than this item.
+ // 1.2. Items are from the same day.
+ // Item in the array is not error item, but this item is.
+ // (Error items first)
+ // 1.3. Items are from the same day.
+ // If item in array and this are same type, but the time of
+ // this item is later. (Latest ones first)
+
+ TBool arrayItemPreviousDay(
+ itemDateTime.Day() > arrayItemDateTime.Day()
+ && itemDateTime.Month() == arrayItemDateTime.Month()
+ && itemDateTime.Year() == arrayItemDateTime.Year()
+ || itemDateTime.Month() > arrayItemDateTime.Month()
+ && itemDateTime.Year() == arrayItemDateTime.Year()
+ || itemDateTime.Year() > arrayItemDateTime.Year() );
+
+ TBool itemsSameDay(
+ itemDateTime.Day() == arrayItemDateTime.Day()
+ && itemDateTime.Month() == arrayItemDateTime.Month()
+ && itemDateTime.Year() == arrayItemDateTime.Year() );
+
+ TBool itemSuccessfullyInstalled(
+ item->LastOperationErrorCode() == KErrNone
+ && item->StateL() == MIAUpdateHistoryItem::EInstalled );
+
+ TBool arrayItemSuccessfullyInstalled(
+ arrayItem->LastOperationErrorCode() == KErrNone
+ && arrayItem->StateL() == MIAUpdateHistoryItem::EInstalled );
+
+ if ( arrayItemPreviousDay
+ || itemsSameDay
+ && ( arrayItemSuccessfullyInstalled
+ && !itemSuccessfullyInstalled
+ || itemSuccessfullyInstalled == arrayItemSuccessfullyInstalled
+ && itemTime > arrayItemTime ) )
+ {
+ iItems.InsertL( item, i );
+ CleanupStack::Pop( item );
+ return;
+ }
+ }
+
+ // If we came here, then the item should be appended to the end
+ // of the array, because it was not inserted above.
+ iItems.AppendL( item );
+ CleanupStack::Pop( item );
+ }
+
+
+TBool CIAUpdateHistory::AcceptItem( const CNcdPurchaseDetails& aItem ) const
+ {
+ TBool accept( ETrue );
+
+ const TDesC& mime(
+ aItem.AttributeString(
+ MNcdPurchaseDetails::EPurchaseAttributeContentMimeType ) );
+
+ if ( IAUpdateNodeFactory::IsFwUpdate( mime )
+ || IAUpdateNodeFactory::IsHidden( mime ) )
+ {
+ // Do not accept firmwares into the history.
+ // Do not accept hidden items into the history.
+ accept = EFalse;
+ }
+
+ return accept;
+ }
+