diff -r 000000000000 -r 32704c33136d ncdengine/provider/client/src/ncdoperationmanagerproxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ncdengine/provider/client/src/ncdoperationmanagerproxy.cpp Tue Jan 26 12:06:03 2010 +0200 @@ -0,0 +1,1234 @@ +/* +* 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 CNcdOperationManagerProxy class +* +*/ + + +#include "ncdoperationmanagerproxy.h" + +#include + +#include "ncdbaseoperationproxy.h" +#include "ncdloadnodeoperationproxy.h" +#include "ncddownloadoperationproxy.h" +#include "ncdnodeproxy.h" +#include "ncdnodeidentifier.h" +#include "ncdloadnodeoperation.h" +#include "catalogsclientserver.h" +#include "ncdnodefunctionids.h" +#include "ncdfiledownloadoperationproxy.h" +#include "ncdpurchaseoperationproxy.h" +#include "catalogsconstants.h" +#include "catalogsutils.h" +#include "ncdpurchaseoptionproxy.h" +#include "ncdinstalloperationproxy.h" +#include "ncdsilentinstalloperationproxy.h" +#include "ncdrightsobjectoperationproxy.h" +#include "ncdsubscriptionoperationproxy.h" +#include "ncdnodemanagerproxy.h" +#include "ncddeviceinteractionfactory.h" +#include "ncdinstallationservice.h" +#include "ncdnodemetadataproxy.h" +#include "ncdcreateaccesspointoperationproxy.h" +#include "ncdsendhttprequestoperationproxy.h" +#include "ncdconnectionmethod.h" +#include "ncdserverreportoperationproxy.h" +#include "ncdproviderdefines.h" + +#include "catalogsdebug.h" + +CNcdOperationManagerProxy* CNcdOperationManagerProxy::NewL( MCatalogsClientServer& aSession, + TInt aHandle ) + { + CNcdOperationManagerProxy* self = CNcdOperationManagerProxy::NewLC( aSession, aHandle ); + CleanupStack::Pop( self ); + return self; + } + +CNcdOperationManagerProxy* CNcdOperationManagerProxy::NewLC( MCatalogsClientServer& aSession, + TInt aHandle ) + { + CNcdOperationManagerProxy* self = + new( ELeave ) CNcdOperationManagerProxy( aSession, aHandle ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +CNcdOperationManagerProxy::~CNcdOperationManagerProxy() + { + DLTRACEIN(("")); + iRemovingAllOperations = ETrue; + + DLTRACE(("All operations should have been released by now")); + DASSERT( iOperationCache.Count() == 0 ); + iOperationCache.Close(); + delete iInstallationService; + DLTRACEOUT(("")); + } + +void CNcdOperationManagerProxy::SetClientLocalizer( + MNcdClientLocalizer& aLocalizer ) + { + iClientLocalizer = &aLocalizer; + } + + +CNcdLoadNodeOperationProxy* CNcdOperationManagerProxy::CreateLoadNodeOperationL( + CNcdNodeProxy& aNode, TBool aLoadChildren, TInt aPageSize, TInt aPageStart, TInt aDepth, + TNcdChildLoadMode aMode, MNcdSearchFilter* aSearchFilter ) + { + DLTRACEIN(("")); + + CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); + CleanupStack::PushL( buf ); + RBufWriteStream stream( *buf ); + CleanupClosePushL( stream ); + aNode.NodeIdentifier().ExternalizeL( stream ); + stream.WriteInt32L( aLoadChildren ); + stream.WriteInt32L( aPageSize ); + stream.WriteInt32L( aPageStart ); + stream.WriteInt32L( aDepth ); + stream.WriteInt32L( aMode ); + stream.WriteInt32L( aSearchFilter != NULL ); + if ( aSearchFilter ) + { + stream.WriteUint32L( aSearchFilter->ContentPurposes() ); + stream.WriteInt32L( aSearchFilter->Keywords().MdcaCount() ); + for ( TInt i = 0 ; i < aSearchFilter->Keywords().MdcaCount() ; i++ ) + { + ExternalizeDesL( aSearchFilter->Keywords().MdcaPoint( i ), stream ); + } + ExternalizeEnumL( aSearchFilter->SearchMode(), stream ); + stream.WriteUint32L( aSearchFilter->RecursionDepth() ); + } + + CleanupStack::PopAndDestroy( &stream ); + TPtrC8 ptr = buf->Ptr( 0 ); + + DLTRACE(("Create server side operation")); + // Send message to server side operation manager to create the server side + // operation and to get a handle to the operation. + TInt operationHandle( 0 ); + User::LeaveIfError( + ClientServerSession(). + SendSync( NcdNodeFunctionIds::ENcdOperationManagerCreateLoadNodeOperation, + ptr, + operationHandle, + Handle() ) ); + + CleanupStack::PopAndDestroy( buf ); + + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + DLINFO(("operation handle: %d", operationHandle )); + + // Create operation proxy + CNcdLoadNodeOperationProxy* operation = + CNcdLoadNodeOperationProxy::NewLC( + ClientServerSession(), operationHandle, removeHandler, &aNode, + iNodeManager, aSearchFilter != NULL, iClientLocalizer ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + +CNcdLoadNodeOperationProxy* CNcdOperationManagerProxy::CreateLoadRootNodeOperationL( + CNcdNodeProxy& aNode ) + { + DLTRACEIN(("")); + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Create operation on the server side + TInt operationHandle = CreateOperationL( aNode, + NcdNodeFunctionIds::ENcdOperationManagerCreateLoadRootNodeOperation, + removeHandler ); + + // Create operation proxy + CNcdLoadNodeOperationProxy* operation = + CNcdLoadNodeOperationProxy::NewLC( + ClientServerSession(), operationHandle, removeHandler, &aNode, + iNodeManager, EFalse, iClientLocalizer ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + +CNcdLoadNodeOperationProxy* CNcdOperationManagerProxy::CreateLoadBundleNodeOperationL( + CNcdNodeProxy& aNode ) + { + DLTRACEIN(("")); + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Create operation on the server side + TInt operationHandle = CreateOperationL( + aNode, NcdNodeFunctionIds::ENcdOperationManagerCreateLoadBundleNodeOperation, + removeHandler ); + + // Create operation proxy + CNcdLoadNodeOperationProxy* operation = + CNcdLoadNodeOperationProxy::NewLC( + ClientServerSession(), operationHandle, removeHandler, &aNode, + iNodeManager, EFalse, iClientLocalizer ); + + iOperationCache.AppendL( operation ); + CleanupStack::Pop( operation ); + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates a new download operation +// --------------------------------------------------------------------------- +// +CNcdDownloadOperationProxy* CNcdOperationManagerProxy::CreateDownloadOperationL( + TNcdDownloadDataType aType, CNcdNodeProxy& aNode, const TDesC& /* aDataId */, + MNcdDownloadOperationObserver* aObserver, + TInt aDownloadIndex ) + { + DLTRACEIN(("")); + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Use temporary node to create a download operation + // http://jira.bothi.fi/jira/browse/PRECLI-1229 + + // Ownership is not transferred + CNcdNodeMetadataProxy* metadataProxy = aNode.Metadata(); + + if ( !metadataProxy ) + { + DLERROR(( "CNcdNodeMetadataProxy was NULL!" )); + User::Leave( KErrNotFound ); + } + + CNcdNodeIdentifier& nodeIdentifier = metadataProxy->Identifier(); + + CNcdNodeProxy* node = NULL; + if( aType == ENcdContentDownload ) + { + // Content download may be started from just purchase history data + // even when chache is completely empty. + // Always use temporary nodes in content downloads to prevent problems. + node = &iNodeManager->CreateTemporaryOrSupplierNodeL( + nodeIdentifier ); + } + else + { + node = &aNode; + } + + // Create the server side download + TInt operationHandle = CreateServerSideDownloadOperationL( aType, + node->NodeIdentifier(), aDownloadIndex ); + + // Check if the download already exists, increases refcount if operation + // is found + CNcdDownloadOperationProxy* operation = FindExistingDownloadOperation( + operationHandle ); + if ( operation ) + { + DLTRACE(("Found existing download")); + if ( aObserver ) + { + operation->AddObserverL( *aObserver ); + } + return operation; + } + + + // Create operation proxy + operation = CNcdDownloadOperationProxy::NewLC( + ClientServerSession(), aType, operationHandle, removeHandler, node, + aObserver, iNodeManager, aDownloadIndex ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates a new file download operation +// --------------------------------------------------------------------------- +// +CNcdFileDownloadOperationProxy* CNcdOperationManagerProxy::CreateFileDownloadOperationL( + TNcdDownloadDataType aType, + CNcdNodeProxy& aNode, + MNcdFileDownloadOperationObserver* aObserver, + const TDesC& aTargetPath ) + { + DLTRACEIN(("")); + if ( !aTargetPath.Length() ) + { + DLERROR(( "No target path, leaving with KErrArgument" )); + User::Leave( KErrArgument ); + } + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Create the server side download + TInt operationHandle = CreateServerSideDownloadOperationL( aType, + aNode.NodeIdentifier(), 0 ); + + // Create operation proxy + CNcdFileDownloadOperationProxy* operation = + CNcdFileDownloadOperationProxy::NewLC( + ClientServerSession(), operationHandle, removeHandler, &aNode, + iNodeManager, aTargetPath, aObserver, aType ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates a new file download operation +// --------------------------------------------------------------------------- +// +CNcdFileDownloadOperationProxy* + CNcdOperationManagerProxy::CreateFileDownloadOperationL( + TNcdDownloadDataType aType, + const TDesC& aUri, + const TDesC& aTargetPath, + MNcdFileDownloadOperationObserver* aObserver ) + { + DLTRACEIN(("")); + + if ( !aUri.Length() || !aTargetPath.Length() ) + { + DLERROR(( "No URI or target path, leaving with KErrArgument" )); + User::Leave( KErrArgument ); + } + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Use node id for transferring URI and targetpath to server-side + CNcdNodeIdentifier* id = CNcdNodeIdentifier::NewLC( + aUri, aTargetPath, TUid::Null() ); + + // Create the server side download + TInt operationHandle = CreateServerSideDownloadOperationL( + ENcdGenericFileDownload, + *id, + 0 ); + + CleanupStack::PopAndDestroy( id ); + + // Create operation proxy + CNcdFileDownloadOperationProxy* operation = + CNcdFileDownloadOperationProxy::NewLC( + ClientServerSession(), operationHandle, removeHandler, NULL, + iNodeManager, aTargetPath, aObserver, aType ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates a new purchase operation +// --------------------------------------------------------------------------- +// +CNcdPurchaseOperationProxy* CNcdOperationManagerProxy::CreatePurchaseOperationL( + CNcdNodeProxy& aNode, + CNcdPurchaseOptionProxy& aSelectedPurchaseOption, + MNcdPurchaseOperationObserver* aObserver ) + { + DLTRACEIN(("")); + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Create operation on the server side + TInt operationHandle = CreateServerSidePurchaseOperationL( + aNode, + aSelectedPurchaseOption, + NcdNodeFunctionIds::ENcdOperationManagerCreatePurchaseOperation, + removeHandler ); + + CNcdSubscriptionManagerProxy* subscriptionManager( NULL ); + if ( iNodeManager != NULL ) + { + subscriptionManager = &iNodeManager->SubscriptionManager(); + } + + // Create operation proxy + CNcdPurchaseOperationProxy* operation = + CNcdPurchaseOperationProxy::NewLC( + ClientServerSession(), + operationHandle, + removeHandler, + &aNode, + &aSelectedPurchaseOption, + aObserver, + subscriptionManager, + iNodeManager, + iClientLocalizer ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + + return operation; + } + + + +// --------------------------------------------------------------------------- +// Creates a new install operation +// --------------------------------------------------------------------------- +// +CNcdInstallOperationProxy* CNcdOperationManagerProxy::CreateInstallOperationL( + CNcdNodeProxy& aNode, + MNcdInstallOperationObserver* aObserver ) + { + DLTRACEIN(("")); + // Should get the actual object for this pointer! + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Create operation on the server side + TInt operationHandle = CreateOperationL( aNode, + NcdNodeFunctionIds::ENcdOperationManagerCreateInstallOperation, + removeHandler ); + + // Create operation proxy + CNcdInstallOperationProxy* operation = + CNcdInstallOperationProxy::NewLC( + ClientServerSession(), operationHandle, + removeHandler, &aNode, iNodeManager, aObserver, + InstallationServiceL() ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates a new install operation +// --------------------------------------------------------------------------- +// +CNcdSilentInstallOperationProxy* CNcdOperationManagerProxy::CreateSilentInstallOperationL( + CNcdNodeProxy& aNode, + MNcdInstallOperationObserver* aObserver, + const SwiUI::TInstallOptions& aInstallOptions ) + { + DLTRACEIN(("")); + + // Should get the actual object for this pointer! + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + // Create operation on the server side + // Notice, that the installation is handled in the proxy side, and only some + // basic functionality is in the server side. + // Notice, that this leaves with KErrPermissionDenied if UI does not have enough + // capabilites for silent install. + TInt operationHandle = CreateOperationL( aNode, + NcdNodeFunctionIds::ENcdOperationManagerCreateSilentInstallOperation, + removeHandler ); + + // Create operation proxy + CNcdSilentInstallOperationProxy* operation = + CNcdSilentInstallOperationProxy::NewLC( + ClientServerSession(), operationHandle, + removeHandler, &aNode, iNodeManager, aObserver, + InstallationServiceL(), + aInstallOptions ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates a DRM rights object download & install operation +// --------------------------------------------------------------------------- +// +CNcdRightsObjectOperationProxy* + CNcdOperationManagerProxy::CreateRightsObjectOperationL( + const TDesC& aDownloadUri, + const TDesC& aMimeType, + const TNcdConnectionMethod& aConnectionMethod, + MNcdRightsObjectOperationObserver& aObserver ) + { + DLTRACEIN(("")); + + // Calculate size of input data buffer. + TInt bufferLen = sizeof( TUint32 ) + aDownloadUri.Size() + // URI length + text data + sizeof( TUint32 ) + aMimeType.Size() + // mime type length + text data + sizeof( TNcdConnectionMethod ); // access point id + + // Allocate and build the input data buffer. + CBufFlat* buffer = CBufFlat::NewL( bufferLen ); + CleanupStack::PushL( buffer ); + + RBufWriteStream stream( *buffer ); + CleanupClosePushL( stream ); + + ExternalizeDesL( aDownloadUri, stream ); // Don't use << (would convert to 8-bit) + ExternalizeDesL( aMimeType, stream ); + aConnectionMethod.ExternalizeL( stream ); + + // Send the command for creating the server side operation object. + TInt operationHandle; // communication handle to the created server side object + User::LeaveIfError( ClientServerSession().SendSync( + NcdNodeFunctionIds::ENcdOperationManagerCreateRightsObjectOperation, + buffer->Ptr( 0 ), + operationHandle, + Handle() ) ); + DLINFO(( "Got server side operation object comm handle %d", operationHandle )); + + CleanupStack::PopAndDestroy( 2, buffer ); // stream-close, buffer + + // Create operation proxy + + CNcdRightsObjectOperationProxy* operation = + CNcdRightsObjectOperationProxy::NewLC( + ClientServerSession(), iNodeManager, operationHandle, + *this, aObserver ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + +CNcdSubscriptionOperationProxy* + CNcdOperationManagerProxy::CreateSubscriptionRefreshOperationL( + MNcdSubscriptionOperationObserver& aObserver ) + { + DLTRACEIN(("")); + + CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); + CleanupStack::PushL( buf ); + RBufWriteStream stream( *buf ); + CleanupClosePushL( stream ); + + // Subscription operation doesn't need any parameters to refresh all + // subscriptions. + stream.WriteInt32L( MNcdSubscriptionOperation::ERefreshSubscriptions ); + + CleanupStack::PopAndDestroy( &stream ); + TPtrC8 ptr = buf->Ptr( 0 ); + + DLTRACE(("Create server side operation")); + // Send message to server side operation manager to create the server side + // operation and to get a handle to the operation. + TInt operationHandle( 0 ); + User::LeaveIfError( + ClientServerSession(). + SendSync( + NcdNodeFunctionIds::ENcdOperationManagerCreateSubscriptionOperation, + ptr, + operationHandle, + Handle() ) ); + + CleanupStack::PopAndDestroy( buf ); + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + DLINFO(("operation handle: %d", operationHandle )); + + CNcdSubscriptionManagerProxy* subscriptionManager( NULL ); + if ( iNodeManager != NULL ) + { + subscriptionManager = &iNodeManager->SubscriptionManager(); + } + + CNcdSubscriptionOperationProxy* operation = + CNcdSubscriptionOperationProxy::NewLC( + ClientServerSession(), + MNcdSubscriptionOperation::ERefreshSubscriptions, + operationHandle, + removeHandler, + aObserver, + subscriptionManager, + iNodeManager, + iClientLocalizer ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + + + +CNcdSubscriptionOperationProxy* + CNcdOperationManagerProxy::CreateSubscriptionUnsubscribeOperationL( + const TDesC& aPurchaseOptionId, + const TDesC& aEntityId, + const TDesC& aNamespace, + const TDesC& aServerUri, + MNcdSubscriptionOperationObserver& aObserver ) + { + DLTRACEIN(("")); + + CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); + CleanupStack::PushL( buf ); + RBufWriteStream stream( *buf ); + CleanupClosePushL( stream ); + + // Write the type of subscription operation. + stream.WriteInt32L( MNcdSubscriptionOperation::EUnsubscribe ); + + ExternalizeDesL( aPurchaseOptionId, stream ); + ExternalizeDesL( aEntityId, stream ); + ExternalizeDesL( aNamespace, stream ); + ExternalizeDesL( aServerUri, stream ); + + CleanupStack::PopAndDestroy( &stream ); + TPtrC8 ptr = buf->Ptr( 0 ); + + DLTRACE(("Create server side operation")); + // Send message to server side operation manager to create the server side + // operation and to get a handle to the operation. + TInt operationHandle( 0 ); + User::LeaveIfError( + ClientServerSession(). + SendSync( + NcdNodeFunctionIds::ENcdOperationManagerCreateSubscriptionOperation, + ptr, + operationHandle, + Handle() ) ); + + CleanupStack::PopAndDestroy( buf ); + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + + DLINFO(("operation handle: %d", operationHandle )); + + CNcdSubscriptionManagerProxy* subscriptionManager( NULL ); + if ( iNodeManager != NULL ) + { + subscriptionManager = &iNodeManager->SubscriptionManager(); + } + + CNcdSubscriptionOperationProxy* operation = + CNcdSubscriptionOperationProxy::NewLC( + ClientServerSession(), + MNcdSubscriptionOperation::EUnsubscribe, + operationHandle, + removeHandler, + aObserver, + subscriptionManager, + iNodeManager, + iClientLocalizer ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates server report operation +// --------------------------------------------------------------------------- +// +CNcdServerReportOperationProxy* + CNcdOperationManagerProxy::CreateServerReportOperationL( + MNcdServerReportOperationObserver& aObserver ) + { + DLTRACEIN(("")); + // Send the command for creating the server side operation object. + TInt operationHandle( 0 ); // communication handle to the created server side object + TInt error( ClientServerSession().SendSync( + NcdNodeFunctionIds::ENcdOperationManagerCreateServerReportOperation, + KNullDesC, + operationHandle, + Handle() ) ); + User::LeaveIfError( error ); + DLINFO(( "Got server side operation object comm handle %d", operationHandle )); + + // Create operation proxy + + CNcdServerReportOperationProxy* operation = + CNcdServerReportOperationProxy::NewLC( + ClientServerSession(), iNodeManager, operationHandle, + *this, aObserver ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + } + + +// --------------------------------------------------------------------------- +// Creates an accesspoint creation operation +// --------------------------------------------------------------------------- +// +CNcdCreateAccessPointOperationProxy* + CNcdOperationManagerProxy::CreateCreateAccessPointOperationL( + const TDesC& aAccessPointData, + MNcdCreateAccessPointOperationObserver& aObserver ) + { + DLTRACEIN(("")); + if ( !aAccessPointData.Size() ) + { + DLERROR(("Accesspoint data is empty")); + User::Leave( KErrArgument ); + } + + RCatalogsBufferWriter buffer; + buffer.OpenLC(); + + ExternalizeDesL( aAccessPointData, buffer() ); + + // Send the command for creating the server side operation object. + TInt operationHandle; // communication handle to the created server side object + User::LeaveIfError( ClientServerSession().SendSync( + NcdNodeFunctionIds::ENcdOperationManagerCreateCreateAccessPointOperation, + buffer.PtrL(), + operationHandle, + Handle() ) ); + DLINFO(( "Got server side operation object comm handle %d", operationHandle )); + + CleanupStack::PopAndDestroy( &buffer ); + + // Create operation proxy + + CNcdCreateAccessPointOperationProxy* operation = + CNcdCreateAccessPointOperationProxy::NewLC( + ClientServerSession(), + iNodeManager, + operationHandle, + *this, + aObserver ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + + } + + + +// --------------------------------------------------------------------------- +// Creates a HTTP request sending operation +// --------------------------------------------------------------------------- +// +CNcdSendHttpRequestOperationProxy* + CNcdOperationManagerProxy::CreateSendHttpRequestOperationL( + const TDesC8& aUri, + const TDesC8& aRequest, + const TNcdConnectionMethod& aConnectionMethod, + MNcdSendHttpRequestOperationObserver& aObserver ) + { + DLTRACEIN(("")); + if ( !aRequest.Size() ) + { + DLERROR(("Request is empty")); + User::Leave( KErrArgument ); + } + + RCatalogsBufferWriter buffer; + buffer.OpenLC(); + + aConnectionMethod.ExternalizeL( buffer() ); + ExternalizeDesL( aUri, buffer() ); + ExternalizeDesL( aRequest, buffer() ); + + // Send the command for creating the server side operation object. + TInt operationHandle; // communication handle to the created server side object + User::LeaveIfError( ClientServerSession().SendSync( + NcdNodeFunctionIds::ENcdOperationManagerCreateSendHttpRequestOperation, + buffer.PtrL(), + operationHandle, + Handle() ) ); + DLINFO(( "Got server side operation object comm handle %d", operationHandle )); + + CleanupStack::PopAndDestroy( &buffer ); + + // Create operation proxy + + CNcdSendHttpRequestOperationProxy* operation = + CNcdSendHttpRequestOperationProxy::NewLC( + ClientServerSession(), + operationHandle, + *this, + *iNodeManager, + aObserver ); + + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + DLTRACEOUT(("")); + return operation; + + } + + +// --------------------------------------------------------------------------- +// Restore content downloads +// --------------------------------------------------------------------------- +// +void CNcdOperationManagerProxy::RestoreContentDownloadsL() + { + DLTRACEIN(("")); + + // Get operation handles from the server + HBufC8* data = NULL; + User::LeaveIfError( + ClientServerSession(). + SendSyncAlloc( + NcdNodeFunctionIds::ENcdOperationManagerRestoreContentDownloads, + KNullDesC8(), + data, + Handle(), + 0 ) ); + + MNcdOperationProxyRemoveHandler* removeHandler( this ); + CleanupStack::PushL( data ); + + RDesReadStream reader( *data ); + CleanupClosePushL( reader ); + + NcdProviderDefines::TNcdStreamDataState streamState = + NcdProviderDefines::ENcdStreamDataEnd; + do + { + InternalizeEnumL( streamState, reader ); + + if ( streamState == NcdProviderDefines::ENcdStreamDataObject ) + { + TInt32 operationHandle = reader.ReadInt32L(); + DLINFO(("Operation handle: %d", operationHandle )); + + TNcdDownloadDataType type = static_cast( + reader.ReadInt32L() ); + + CNcdNodeIdentifier* metadataId = CNcdNodeIdentifier::NewLC( + reader ); + + TInt dlIndex = reader.ReadInt32L(); + + // Use a temporary node + CNcdNodeProxy* node = &iNodeManager->CreateTemporaryOrSupplierNodeL( + *metadataId ); + + // Create operation proxy + CNcdDownloadOperationProxy* operation = + CNcdDownloadOperationProxy::NewLC( + ClientServerSession(), type, + operationHandle, removeHandler, node, + NULL, iNodeManager, dlIndex, ETrue ); + + // Add operation manager as an observer so that the operation + // is deleted correctly if it completes + operation->AddObserverL( *this ); + iOperationCache.AppendL( operation ); + + CleanupStack::Pop( operation ); + CleanupStack::PopAndDestroy( metadataId ); + } + } + while( streamState != NcdProviderDefines::ENcdStreamDataEnd ); + + CleanupStack::PopAndDestroy( 2, data ); // reader, data + DLTRACEOUT(("Downloads created")); + } + + +// --------------------------------------------------------------------------- +// Operations array getter +// --------------------------------------------------------------------------- +// +const RPointerArray& CNcdOperationManagerProxy::Operations() const + { + return iOperationCache; + } + + +// --------------------------------------------------------------------------- +// Node manager setter +// --------------------------------------------------------------------------- +// +void CNcdOperationManagerProxy::SetNodeManager(CNcdNodeManagerProxy* aNodeManager ) + { + iNodeManager = aNodeManager; + } + +// --------------------------------------------------------------------------- +// Node manager getter +// --------------------------------------------------------------------------- +// +CNcdNodeManagerProxy* CNcdOperationManagerProxy::NodeManager() + { + return iNodeManager; + } + + +// --------------------------------------------------------------------------- +// Installation service getter +// --------------------------------------------------------------------------- +// +MNcdInstallationService& CNcdOperationManagerProxy::InstallationServiceL() + { + DLTRACEIN(("")); + if ( !iInstallationService ) + { + iInstallationService = + NcdDeviceInteractionFactory::CreateInstallationServiceL(); + } + return *iInstallationService; + } + + +// --------------------------------------------------------------------------- +// Cancel all operations +// --------------------------------------------------------------------------- +// +void CNcdOperationManagerProxy::CancelAllOperations() + { + DLTRACEIN(("")); + + for ( TInt i = iOperationCache.Count() - 1; i >= 0; --i ) + { + // Add reference so that the operation is not deleted in + // CancelOperation's callbacks + iOperationCache[i]->AddRef(); + iOperationCache[i]->CancelOperation(); + + // This releases those operations that have 1 refcount such as + // restored content downloads that the client hasn't obtained + // from the manager + while( iOperationCache[i]->Release() ) + { + // empty on purpose + } + } + } + + +// --------------------------------------------------------------------------- +// Cancel all operations +// --------------------------------------------------------------------------- +// +void CNcdOperationManagerProxy::ReleaseUnusedOperations() + { + DLTRACEIN(("")); + + for ( TInt i = iOperationCache.Count() - 1; i >= 0; --i ) + { + // This releases those operations that have 1 refcount such as + // restored content downloads that the client hasn't obtained + // from the manager + iOperationCache[i]->Release(); + } + } + + +// --------------------------------------------------------------------------- +// Operation proxy remover +// --------------------------------------------------------------------------- +// +void CNcdOperationManagerProxy::RemoveOperationProxy( + CNcdBaseOperationProxy& aOperationProxy ) + { + DLTRACEIN(("")); + + // Releasing all operations so we don't want to mess with the operation cache + if ( iRemovingAllOperations ) + { + DLTRACE(("Removing all operations")); + return; + } + + MNcdOperation* operation = NULL; + TRAP_IGNORE( + operation = aOperationProxy.QueryInterfaceLC< MNcdOperation >(); + CleanupStack::Pop( operation ); + ); // TRAP_IGNORE + if( ! operation ) + { + DLINFO( ("!!!QueryInterfaceLC failed for operation! FATAL ERROR!")); + DASSERT( 0 ); + } + + // Remove operation from the cache because it will be deleted. + for ( TInt i = 0; i < iOperationCache.Count(); ++i ) + { + if ( operation == iOperationCache[ i ] ) + { + DLTRACE(("Removed the proxy")); + // Remove node from the array and delete it. + iOperationCache.Remove( i ); + break; + } + } + + // RemoveOperationProxy MUST only be called from proxy's destructor + // and therefore the operation MUST NOT be released again + DLTRACEOUT(("")); + } + + +// --------------------------------------------------------------------------- +// Download operation observer interface implementation +// --------------------------------------------------------------------------- +// +void CNcdOperationManagerProxy::DownloadProgress( + MNcdDownloadOperation& /* aOperation */, + TNcdProgress /* aProgress */ ) + { + // Do nothing + } + + +void CNcdOperationManagerProxy::QueryReceived( + MNcdDownloadOperation& /* aOperation */, + MNcdQuery* /* aQuery */) + { + // Do nothing + } + + +void CNcdOperationManagerProxy::OperationComplete( + MNcdDownloadOperation& aOperation, + TInt aError ) + { + DLTRACEIN(("aOperation: %x, error: %d", &aOperation, aError )); + (void)aError; // suppresses compiler warning + // Just release the operation because operation manager had a + // reference to it + aOperation.Release(); + } + + + +CNcdOperationManagerProxy::CNcdOperationManagerProxy( MCatalogsClientServer& aSession, + TInt aHandle ) +: CNcdBaseProxy( aSession, aHandle ) + { + } + +void CNcdOperationManagerProxy::ConstructL() + { + // Nothing to be done here + } + + +// --------------------------------------------------------------------------- +// Creates the identification stream for the given node +// --------------------------------------------------------------------------- +// +HBufC8* CNcdOperationManagerProxy::CreateNodeIdentifierDataLC( CNcdNodeProxy& aNode ) + { + DLTRACEIN(("")); + HBufC8* nodeIdentifierData( aNode.NodeIdentifier().NodeIdentifierDataL() ); + if( nodeIdentifierData == NULL ) + { + DLTRACEIN(("Null identifier data")); + User::Leave( KErrNotFound ); + } + CleanupStack::PushL( nodeIdentifierData ); + DLTRACEOUT(("")); + return nodeIdentifierData; + } + + + +// --------------------------------------------------------------------------- +// Creates an operation on the server side +// --------------------------------------------------------------------------- +// +TInt CNcdOperationManagerProxy::CreateOperationL( CNcdNodeProxy& aNode, + NcdNodeFunctionIds::TNcdOperationManagerFunctionNumber aFunction, + MNcdOperationProxyRemoveHandler*& aRemoveHandler ) + { + DLTRACEIN(( _L("Node: %S::%S"), &aNode.NodeIdentifier().NodeNameSpace(), + &aNode.NodeIdentifier().NodeId() )); + // Create id stream + HBufC8* nodeIdentifierData = CreateNodeIdentifierDataLC( aNode ); + + // Send message to server side operation manager to create the server side + // operation and to get a handle to the operation. + TInt operationHandle( 0 ); + User::LeaveIfError( + ClientServerSession(). + SendSync( aFunction, + *nodeIdentifierData, + operationHandle, + Handle() ) ); + + DLINFO(("operation handle: %d", operationHandle )); + CleanupStack::PopAndDestroy( nodeIdentifierData ); + + aRemoveHandler = this; + DLTRACEOUT(("")); + return operationHandle; + } + + +// --------------------------------------------------------------------------- +// Creates a purchase operation on the server side +// --------------------------------------------------------------------------- +// +TInt CNcdOperationManagerProxy::CreateServerSidePurchaseOperationL( + CNcdNodeProxy& aNode, + const CNcdPurchaseOptionProxy& aSelectedPurchaseOption, + NcdNodeFunctionIds::TNcdOperationManagerFunctionNumber aFunction, + MNcdOperationProxyRemoveHandler*& /*aRemoveHandler*/ ) + { + DLTRACEIN(( _L("Node: %S::%S"), &aNode.NodeIdentifier().NodeNameSpace(), + &aNode.NodeIdentifier().NodeId() )); + + CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); + CleanupStack::PushL( buf ); + RBufWriteStream stream( *buf ); + CleanupClosePushL( stream ); + + aNode.NodeIdentifier().ExternalizeL( stream ); + + ExternalizeDesL( aSelectedPurchaseOption.Id(), stream ); + + CleanupStack::PopAndDestroy( &stream ); + + TPtrC8 ptr = buf->Ptr( 0 ); + + // Send message to server side operation manager to create the server side + // operation and to get a handle to the operation. + TInt operationHandle( 0 ); + User::LeaveIfError( + ClientServerSession(). + SendSync( aFunction, + ptr, + operationHandle, + Handle() ) ); + + CleanupStack::PopAndDestroy( buf ); + + DLINFO(("operation handle: %d", operationHandle )); + + DLTRACEOUT(("")); + return operationHandle; + } + +// --------------------------------------------------------------------------- +// Creates an download operation on the server side +// --------------------------------------------------------------------------- +// +TInt CNcdOperationManagerProxy::CreateServerSideDownloadOperationL( + TNcdDownloadDataType aType, + const CNcdNodeIdentifier& aNodeId, + TInt aDownloadIndex ) + { + DLTRACEIN(("")); + // Create operation on the server side + + CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); + CleanupStack::PushL( buf ); + + RBufWriteStream stream( *buf ); + CleanupClosePushL( stream ); + + // Write type + stream.WriteInt32L( aType ); + + // Write node ID + aNodeId.ExternalizeL( stream ); + + // Write download index + stream.WriteInt32L( aDownloadIndex ); + + CleanupStack::PopAndDestroy( &stream ); + + // Send message to server side operation manager to create the server side + // operation and to get a handle to the operation. + TInt operationHandle( 0 ); + User::LeaveIfError( ClientServerSession(). + SendSync( + NcdNodeFunctionIds::ENcdOperationManagerCreateDownloadOperation, + buf->Ptr( 0 ), operationHandle, Handle() ) ); + + DLINFO(("operation handle: %d", operationHandle )); + CleanupStack::PopAndDestroy( buf ); + DLTRACEOUT(("")); + return operationHandle; + } + + + +// --------------------------------------------------------------------------- +// Searches operations for a matching download operation +// --------------------------------------------------------------------------- +// +CNcdDownloadOperationProxy* + CNcdOperationManagerProxy::FindExistingDownloadOperation( + TInt aHandle ) const + { + DLTRACEIN(("")); + + for ( TInt i = 0; i < iOperationCache.Count(); ++i ) + { + if ( iOperationCache[i]->OperationType() == ENcdDownloadOperationUid ) + { + DLTRACE(("Querying for download interface")); + MNcdDownloadOperation* dl = + iOperationCache[i]->QueryInterfaceLC(); + DASSERT( dl ); + + + CNcdDownloadOperationProxy* operation = + static_cast( dl ); + + DLTRACE(("Checking download handle")); + if ( operation->Handle() == aHandle ) + { + DLTRACE(("Found a match")); + CleanupStack::Pop( dl ); + return operation; + } + + // QueryInterfaceLC increases the ref count + CleanupStack::PopAndDestroy( dl ); + } + + } + DLTRACEOUT(("")); + return NULL; + } + +