--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/server/src/ncdnodedownloadimpl.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,388 @@
+/*
+* Copyright (c) 2006 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: Implements CNcdNodeDownload class
+*
+*/
+
+
+#include <bautils.h>
+
+
+#include "ncdnodedownloadimpl.h"
+#include "catalogssession.h"
+#include "catalogsbasemessage.h"
+#include "ncdnodefunctionids.h"
+#include "ncdnodeclassids.h"
+#include "ncdpurchasedetails.h"
+#include "ncdutils.h"
+#include "catalogsconstants.h"
+#include "ncd_pp_dataentity.h"
+#include "ncd_cp_query.h"
+#include "catalogsutils.h"
+#include "catalogsdebug.h"
+#include "ncdproviderutils.h"
+
+
+CNcdNodeDownload::CNcdNodeDownload( NcdNodeClassIds::TNcdNodeClassId aClassId )
+: CCatalogsCommunicable(),
+ iClassId( aClassId )
+ {
+ }
+
+void CNcdNodeDownload::ConstructL()
+ {
+ }
+
+
+CNcdNodeDownload* CNcdNodeDownload::NewL()
+ {
+ CNcdNodeDownload* self =
+ CNcdNodeDownload::NewLC();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CNcdNodeDownload* CNcdNodeDownload::NewLC()
+ {
+ CNcdNodeDownload* self =
+ new( ELeave ) CNcdNodeDownload(
+ NcdNodeClassIds::ENcdNodeDownloadClassId );
+ CleanupClosePushL( *self );
+ self->ConstructL();
+ return self;
+ }
+
+
+CNcdNodeDownload::~CNcdNodeDownload()
+ {
+ DLTRACEIN((""));
+
+ // Delete member variables here.
+
+ TInt count = iDownloadInfo.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CNcdPurchaseDownloadInfo* info =
+ static_cast<CNcdPurchaseDownloadInfo*>(iDownloadInfo[i]);
+ delete info;
+ info = NULL;
+ }
+ iDownloadInfo.Reset();
+
+ delete iFiles;
+
+ DLTRACEOUT((""));
+ }
+
+NcdNodeClassIds::TNcdNodeClassId CNcdNodeDownload::ClassId() const
+ {
+ return iClassId;
+ }
+
+
+// Internalization from the purchase history.
+
+TBool CNcdNodeDownload::InternalizeL( const MNcdPurchaseDetails& aDetails )
+ {
+ DLTRACEIN(("this-ptr: %X", this));
+
+ TArray<MNcdPurchaseDownloadInfo*> dlInfos( aDetails.DownloadInfoL() );
+
+ TInt count = dlInfos.Count();
+
+ // Quit if no download data exists or it's consumable
+ if ( count == 0 || ( count == 1 &&
+ dlInfos[0]->ContentUsage() ==
+ MNcdPurchaseDownloadInfo::EConsumable ))
+ {
+ // No download data found from purchase details.
+ DLTRACEOUT((""));
+ return EFalse;
+ }
+
+ // Check for any downloadable URIs
+ TBool uriExists = EFalse;
+ for ( TInt i = 0; i < count; ++i )
+ {
+ if ( dlInfos[i]->ContentUri().Length() ||
+ dlInfos[i]->DescriptorUri().Length() ||
+ dlInfos[i]->DescriptorData().Length() ||
+ dlInfos[i]->RightsUri().Length() )
+ {
+ uriExists = ETrue;
+ break;
+ }
+ }
+
+ if ( !uriExists )
+ {
+ DLTRACEOUT(("No URI, no download API"));
+ return EFalse;
+ }
+
+ iIsDownloaded = EFalse;
+
+ delete iFiles;
+ iFiles = NULL;
+ iFiles = new (ELeave) CDesCArrayFlat( KListGranularity );
+
+ RPointerArray<MNcdPurchaseDownloadInfo> tempInfos;
+
+ // Can't use CleanupResetAndDestroyPushL because the array can't
+ // be deleted with ResetAndDestroy
+ TRAPD( err,
+ {
+ tempInfos.ReserveL( count );
+ DLTRACE(("Copying purchase download infos"));
+ // Download data found from purchase details.
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CNcdPurchaseDownloadInfo* info =
+ CNcdPurchaseDownloadInfo::NewLC( *dlInfos[i] );
+ tempInfos.AppendL( info );
+ CleanupStack::Pop( info );
+ }
+
+ // Check purchase details status.
+ if ( aDetails.State() == MNcdPurchaseDetails::EStateDownloaded ||
+ aDetails.State() == MNcdPurchaseDetails::EStateInstalled )
+ {
+ iIsDownloaded = ETrue;
+ DLTRACE(("Copy file paths, iIsDownloaded = ETrue"));
+ const MDesCArray& files( aDetails.DownloadedFiles() );
+
+ for ( TInt i = 0; i < files.MdcaCount(); ++i )
+ {
+ iFiles->AppendL( files.MdcaPoint( i ) );
+ }
+ }
+
+ ResetAndDestroyWithCast<CNcdPurchaseDownloadInfo>( iDownloadInfo );
+ iDownloadInfo = tempInfos;
+
+ });
+
+ if ( err != KErrNone )
+ {
+ ResetAndDestroyWithCast<CNcdPurchaseDownloadInfo>( tempInfos );
+ }
+
+ DLTRACEOUT(("iIsDownloaded: %d", iIsDownloaded));
+ return ETrue;
+ }
+
+const RPointerArray< MNcdPurchaseDownloadInfo >&
+ CNcdNodeDownload::DownloadInfo() const
+ {
+ return iDownloadInfo;
+ }
+
+
+void CNcdNodeDownload::ReceiveMessage( MCatalogsBaseMessage* aMessage,
+ TInt aFunctionNumber )
+ {
+ DLTRACEIN(("this-ptr: %X", this));
+
+ DASSERT( aMessage );
+
+ // Now, we can be sure that rest of the time iMessage exists.
+ // This member variable is set for the CounterPartLost function.
+ iMessage = aMessage;
+
+ TInt trapError( KErrNone );
+
+ // Check which function is called by the proxy side object.
+ // Function number are located in ncdnodefunctinoids.h file.
+ switch( aFunctionNumber )
+ {
+ case NcdNodeFunctionIds::ENcdInternalize:
+ // Internalize the proxy side according to the data
+ // of this object.
+ TRAP( trapError, InternalizeRequestL( *aMessage ) );
+ break;
+
+ case NcdNodeFunctionIds::ENcdRelease:
+ // The proxy does not want to use this object anymore.
+ // So, release the handle from the session.
+ ReleaseRequest( *aMessage );
+ break;
+
+ case NcdNodeFunctionIds::ENcdFilesExist:
+ TRAP( trapError, FilesExistRequestL( *aMessage ) );
+ break;
+ default:
+ break;
+ }
+
+ if ( trapError != KErrNone )
+ {
+ // Because something went wrong, the complete has not been
+ // yet called for the message.
+ // So, inform the client about the error if the
+ // message is still available.
+ aMessage->CompleteAndRelease( trapError );
+ }
+
+ // Because the message should not be used after this, set it NULL.
+ // So, CounterPartLost function will know that no messages are
+ // waiting the response at the moment.
+ iMessage = NULL;
+
+ DLTRACEOUT((""));
+ }
+
+void CNcdNodeDownload::CounterPartLost( const MCatalogsSession& aSession )
+ {
+ // This function may be called whenever -- when the message is waiting
+ // response or when the message does not exist.
+ // iMessage may be NULL here, because in the end of the
+ // ReceiveMessage it is set to NULL. The life time of the message
+ // ends shortly after CompleteAndRelease is called.
+ if ( iMessage != NULL )
+ {
+ iMessage->CounterPartLost( aSession );
+ }
+ }
+
+
+void CNcdNodeDownload::InternalizeRequestL( MCatalogsBaseMessage& aMessage )
+ {
+ DLTRACEIN((""));
+
+ CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
+ CleanupStack::PushL( buf );
+
+ RBufWriteStream stream( *buf );
+ CleanupClosePushL( stream );
+
+
+ // Include all the necessary node data to the stream
+ ExternalizeDataForRequestL( stream );
+
+
+ // Commits data to the stream when closing.
+ CleanupStack::PopAndDestroy( &stream );
+
+
+ // If this leaves, ReceiveMessage will complete the message.
+ // NOTE: that here we expect that the buffer contains at least
+ // some data. So, make sure that ExternalizeDataForRequestL inserts
+ // something to the buffer.
+ aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
+
+
+ DLTRACE(("Deleting the buf"));
+ CleanupStack::PopAndDestroy( buf );
+
+ DLTRACEOUT((""));
+ }
+
+
+void CNcdNodeDownload::ExternalizeDataForRequestL( RWriteStream& aStream )
+ {
+ DLTRACEIN((""));
+
+ // Download existed. So, insert info that meta data was found.
+ aStream.WriteInt32L( ClassId() );
+
+ // Add additional content to the stream.
+ // Make sure that this matches to the order that is used in the proxy
+ // side when this stream is internalized.
+ // NOTE: Be careful with the 8- and 16-bit descriptors. Remember to check
+ // if the proxy wants the data in 16 or 8 bits?
+
+ aStream.WriteInt32L( iIsDownloaded );
+
+ DLTRACEOUT(("iIsDownloaded: %d", iIsDownloaded ));
+ }
+
+void CNcdNodeDownload::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
+ {
+ DLTRACEIN((""));
+
+ // Decrease the reference count for this object.
+ // When the reference count reaches zero, this object will be destroyed
+ // and removed from the session.
+ MCatalogsSession& requestSession( aMessage.Session() );
+ TInt handle( aMessage.Handle() );
+
+ // Send complete information back to proxy.
+ aMessage.CompleteAndRelease( KErrNone );
+
+ // Remove this object from the session.
+ requestSession.RemoveObject( handle );
+
+ DLTRACEOUT((""));
+ }
+
+
+void CNcdNodeDownload::FilesExistRequestL( MCatalogsBaseMessage& aMessage )
+ {
+ DLTRACEIN((""));
+
+ TBool filesExist = EFalse;
+ if ( iIsDownloaded )
+ {
+ filesExist = FilesExist();
+ }
+
+ // If this leaves, ReceiveMessage will complete the message.
+ // NOTE: that here we expect that the buffer contains at least
+ // some data. So, make sure that ExternalizeDataForRequestL inserts
+ // something to the buffer.
+ aMessage.CompleteAndReleaseL( filesExist, KErrNone );
+
+
+ DLTRACEOUT(("filesExist: %d", filesExist));
+ }
+
+
+
+TBool CNcdNodeDownload::FilesExist()
+ {
+ DLTRACEIN((""));
+ DASSERT( iFiles->MdcaCount() == iDownloadInfo.Count() );
+
+ for ( TInt i = 0; i < iFiles->MdcaCount(); ++i )
+ {
+ TInt shouldExist = 1;
+
+ // AttributeInt32L leaves only with KErrNone and that happens
+ // if the attribute is not set which means that that download
+ // is required
+ TRAP_IGNORE( shouldExist = iDownloadInfo[i]->AttributeInt32L(
+ MNcdPurchaseDownloadInfo::EDownloadAttributeRequiredDownload ) );
+
+ if ( !iDownloadInfo[i]->ContentUri().Length() )
+ {
+ DLTRACE(("No URI, no file"));
+ shouldExist = EFalse;
+ }
+
+ DLTRACE(("Downloaded file should exist: %d", shouldExist));
+
+ // Dependencies and in Get-cases content file don't have to be
+ // downloaded because they can already be installed. In those cases
+ // shouldExist == 0 and this check is skipped
+ if ( shouldExist && (
+ iFiles->MdcaPoint( i ).Length() == 0 ||
+ !BaflUtils::FileExists(
+ CNcdProviderUtils::FileSession(),
+ iFiles->MdcaPoint( i ) ) ) )
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }